mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 04:21:06 +08:00
Update forkJoin rxjs operator
This commit is contained in:
parent
d6b19bc733
commit
8b21f03bf3
20 changed files with 137 additions and 102 deletions
|
@ -21,7 +21,9 @@
|
|||
"main": "core/app/shell/src/main.ts",
|
||||
"polyfills": "core/app/shell/src/polyfills.ts",
|
||||
"tsConfig": "core/app/shell/tsconfig.app.json",
|
||||
"scripts": [],
|
||||
"scripts": [
|
||||
"node_modules/tinymce/tinymce.min.js"
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/bootstrap-css-only/css/bootstrap.min.css",
|
||||
"core/app/shell/src/themes/suite8/css/style.scss"
|
||||
|
@ -41,11 +43,6 @@
|
|||
],
|
||||
"output": "/themes/"
|
||||
},
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "node_modules/tinymce",
|
||||
"output": "/tinymce/"
|
||||
},
|
||||
{ "glob": "**/*", "input": "node_modules/tinymce", "output": "/tinymce/" }
|
||||
],
|
||||
"allowedCommonJsDependencies": [
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {combineLatest, Observable} from 'rxjs';
|
||||
import {Observable} from 'rxjs';
|
||||
import {map} from 'rxjs/operators';
|
||||
import {ThemeImage, ThemeImageMap, ThemeImagesStore} from '../../store/theme-images/theme-images.store';
|
||||
|
||||
|
@ -42,8 +42,8 @@ export class ImageComponent {
|
|||
|
||||
images$: Observable<ThemeImageMap> = this.themeImagesStore.images$;
|
||||
|
||||
vm$ = combineLatest([this.images$]).pipe(
|
||||
map(([images]) => ({
|
||||
vm$ = this.images$.pipe(
|
||||
map((images) => ({
|
||||
images
|
||||
})));
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
*/
|
||||
|
||||
import {AfterViewInit, Component, ElementRef, HostListener, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {combineLatest, Observable, Subscription} from 'rxjs';
|
||||
import {map, take} from 'rxjs/operators';
|
||||
import {combineLatestWith, Observable, Subscription} from 'rxjs';
|
||||
import {map, tap} from 'rxjs/operators';
|
||||
import {NavbarModel} from '../navbar-model';
|
||||
import {NavbarAbstract} from '../navbar.abstract';
|
||||
import {transition, trigger, useAnimation} from '@angular/animations';
|
||||
|
@ -97,14 +97,14 @@ export class BaseNavbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
|
||||
notificationCount$: Observable<number>;
|
||||
|
||||
vm$ = combineLatest([
|
||||
this.navigation$,
|
||||
this.userPreferences$,
|
||||
this.currentUser$,
|
||||
this.appState$,
|
||||
this.screenSize.screenSize$,
|
||||
this.languages$,
|
||||
]).pipe(
|
||||
vm$ = this.navigation$.pipe(
|
||||
combineLatestWith(
|
||||
this.userPreferences$,
|
||||
this.currentUser$,
|
||||
this.appState$,
|
||||
this.screenSize.screenSize$,
|
||||
this.languages$,
|
||||
),
|
||||
map(([navigation, userPreferences, currentUser, appState, screenSize, language]) => {
|
||||
|
||||
if (screenSize) {
|
||||
|
|
|
@ -293,10 +293,10 @@ export class SavedFilterStore implements StateStore {
|
|||
*/
|
||||
public validate(): Observable<boolean> {
|
||||
|
||||
return forkJoin({
|
||||
fields: this.recordStore.validate(),
|
||||
criteria: this.validateCriteria()
|
||||
}).pipe(map(({fields, criteria}) => fields && criteria));
|
||||
return forkJoin([
|
||||
this.recordStore.validate(),
|
||||
this.validateCriteria()
|
||||
]).pipe(map(([fields, criteria]) => fields && criteria));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -300,19 +300,19 @@ export class SubpanelStore implements StateStore {
|
|||
* @param {boolean} useCache if to use cache
|
||||
* @returns {object} Observable<Statistic>
|
||||
*/
|
||||
public loadAllStatistics(useCache = true): Observable<StatisticsMap> {
|
||||
public loadAllStatistics(useCache = true): Observable<Statistic[]> {
|
||||
if (!this.statistics || !Object.keys(this.statistics).length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const stats$ = {};
|
||||
|
||||
const stats$ = [];
|
||||
Object.keys(this.statistics).forEach(statisticKey => {
|
||||
|
||||
if (!this.statistics[statisticKey]) {
|
||||
return;
|
||||
}
|
||||
stats$[statisticKey] = this.loadStatistics(statisticKey, useCache);
|
||||
stats$.push(this.loadStatistics(statisticKey, useCache));
|
||||
});
|
||||
|
||||
return forkJoin(stats$);
|
||||
|
|
|
@ -86,16 +86,18 @@ export class AuthGuard {
|
|||
return session && acl;
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorize user acl
|
||||
*
|
||||
* @returns {object} Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
|
||||
* @returns {object} Observable<boolean | UrlTree>
|
||||
* @param {ActivatedRouteSnapshot} activatedRoute information about the current route
|
||||
*/
|
||||
protected authorizeUserACL(activatedRoute: ActivatedRouteSnapshot):
|
||||
Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||
Observable<boolean | UrlTree> {
|
||||
|
||||
const routeInfo: RouteInfo = this.routeConverter.parseRouteURL(activatedRoute.url);
|
||||
|
||||
|
@ -120,7 +122,6 @@ export class AuthGuard {
|
|||
queryParams: activatedRoute?.queryParams ?? []
|
||||
}
|
||||
} as AsyncActionInput;
|
||||
|
||||
return this.asyncActionService.run(actionName, asyncData)
|
||||
.pipe(take(1),
|
||||
map((process: Process) => {
|
||||
|
@ -142,8 +143,7 @@ export class AuthGuard {
|
|||
|
||||
return false;
|
||||
}),
|
||||
catchError(() => of(homeUrlTree)),
|
||||
tap((result: boolean | UrlTree) => result)
|
||||
catchError(() => of(homeUrlTree))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ export class AuthGuard {
|
|||
* @param snapshot
|
||||
*/
|
||||
protected authorizeUserSession(route: ActivatedRouteSnapshot, snapshot: RouterStateSnapshot):
|
||||
Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||
Observable<boolean | UrlTree> {
|
||||
|
||||
if (this.authService.isUserLoggedIn.value && route.data.checkSession !== true) {
|
||||
return of(true);
|
||||
|
|
|
@ -87,6 +87,8 @@ export class ExtensionLoader {
|
|||
return of({});
|
||||
}
|
||||
|
||||
//TODO: Correct here
|
||||
|
||||
return forkJoin(extensionModules$);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,19 +79,17 @@ export class BaseModuleResolver extends BaseMetadataResolver {
|
|||
if (!routeModule) {
|
||||
routeModule = route.data.module;
|
||||
}
|
||||
|
||||
return super.resolve(route).pipe(
|
||||
concatMap(() => {
|
||||
return forkJoin({
|
||||
metadata: this.metadataStore.load(routeModule, this.metadataStore.getMetadataTypes()),
|
||||
savedSearchMeta: this.metadataStore.getMetadata('saved-search', ['recordView']),
|
||||
});
|
||||
}),
|
||||
concatMap(
|
||||
() => forkJoin([
|
||||
this.metadataStore.load(routeModule, this.metadataStore.getMetadataTypes()),
|
||||
this.metadataStore.getMetadata('saved-search', ['recordView'])
|
||||
]),
|
||||
),
|
||||
map(value => {
|
||||
return {
|
||||
base: value[0] ?? {},
|
||||
metadata: value[1] ?? {},
|
||||
savedSearchMeta: value[2] ?? {},
|
||||
metadata: value[0] ?? {},
|
||||
savedSearchMeta: value[1] ?? {},
|
||||
}
|
||||
}),
|
||||
tap(
|
||||
|
|
|
@ -89,9 +89,9 @@ export class BaseRecordResolver extends BaseModuleResolver {
|
|||
|
||||
return super.resolve(route).pipe(
|
||||
concatMap(() => {
|
||||
return forkJoin({
|
||||
metadata: this.metadataStore.load(routeModule, this.metadataStore.getMetadataTypes()),
|
||||
});
|
||||
return forkJoin([
|
||||
this.metadataStore.load(routeModule, this.metadataStore.getMetadataTypes()),
|
||||
]);
|
||||
}),
|
||||
tap(() => {
|
||||
if (this.auth.isLoggedIn()) {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Observable} from 'rxjs';
|
||||
import {Observable, of} from 'rxjs';
|
||||
import {catchError, take, tap} from 'rxjs/operators';
|
||||
import {Process, ProcessService} from '../../process.service';
|
||||
import {AppStateStore} from '../../../../store/app-state/app-state.store';
|
||||
|
@ -132,17 +132,17 @@ export class AsyncActionService {
|
|||
actionHandler.run(process.data.params);
|
||||
|
||||
}),
|
||||
catchError(err => {
|
||||
catchError((err) => {
|
||||
const errorMessage = err?.message ?? ''
|
||||
|
||||
if (errorMessage === 'Access Denied.') {
|
||||
this.appStateStore.updateLoading(actionName, false);
|
||||
throw err;
|
||||
return of(null);
|
||||
}
|
||||
|
||||
this.message.addDangerMessageByKey('LBL_ACTION_ERROR');
|
||||
this.appStateStore.updateLoading(actionName, false);
|
||||
throw err;
|
||||
return of(null);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
*/
|
||||
|
||||
import {Injectable} from '@angular/core';
|
||||
import {BehaviorSubject, combineLatest, Observable, Subscription, timer} from 'rxjs';
|
||||
import {distinctUntilChanged, map, take, tap} from 'rxjs/operators';
|
||||
import {BehaviorSubject, combineLatestWith, Observable, Subscription} from 'rxjs';
|
||||
import {distinctUntilChanged, map} from 'rxjs/operators';
|
||||
import {deepClone, isVoid, User} from 'common';
|
||||
import {StateStore} from '../state';
|
||||
import {LoadingBufferFactory} from '../../services/ui/loading-buffer/loading-buffer.factory';
|
||||
|
@ -95,7 +95,8 @@ export class AppStateStore implements StateStore {
|
|||
this.initialAppLoading$ = this.state$.pipe(map(state => state.initialAppLoading), distinctUntilChanged());
|
||||
this.activeRequests$ = this.state$.pipe(map(state => state.activeRequests), distinctUntilChanged());
|
||||
|
||||
this.vm$ = combineLatest([this.loading$, this.module$, this.view$, this.initialAppLoading$]).pipe(
|
||||
this.vm$ = this.loading$.pipe(
|
||||
combineLatestWith(this.module$, this.view$, this.initialAppLoading$),
|
||||
map(([loading, module, view, initialAppLoading]) => ({
|
||||
loading,
|
||||
module,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
import {BehaviorSubject, combineLatest, forkJoin, Observable, of} from 'rxjs';
|
||||
import {BehaviorSubject, combineLatest, combineLatestWith, forkJoin, Observable, of} from 'rxjs';
|
||||
import {distinctUntilChanged, first, map, shareReplay, take, tap} from 'rxjs/operators';
|
||||
import {EntityGQL} from '../../services/api/graphql-api/api.entity.get';
|
||||
import {deepClone, emptyObject, StringMap} from 'common';
|
||||
|
@ -159,14 +159,13 @@ export class LanguageStore implements StateStore {
|
|||
this.modStrings$ = this.state$.pipe(map(state => state.modStrings), distinctUntilChanged());
|
||||
this.languageKey$ = this.state$.pipe(map(state => state.languageKey), distinctUntilChanged());
|
||||
|
||||
this.vm$ = combineLatest(
|
||||
[
|
||||
this.appStrings$,
|
||||
this.appListStrings$,
|
||||
this.modStrings$,
|
||||
this.languageKey$
|
||||
])
|
||||
this.vm$ = this.appStrings$
|
||||
.pipe(
|
||||
combineLatestWith(
|
||||
this.appListStrings$,
|
||||
this.modStrings$,
|
||||
this.languageKey$
|
||||
),
|
||||
map((
|
||||
[
|
||||
appStrings,
|
||||
|
@ -461,20 +460,21 @@ export class LanguageStore implements StateStore {
|
|||
*/
|
||||
public load(languageKey: string, types: string[], reload = false): Observable<any> {
|
||||
|
||||
const streams$ = {};
|
||||
const streams$: Array<Observable<any>> = [];
|
||||
|
||||
types.forEach(type => streams$[type] = this.getStrings(languageKey, type, reload));
|
||||
types.forEach(type => streams$.push(this.getStrings(languageKey, type, reload)));
|
||||
|
||||
return forkJoin(streams$).pipe(
|
||||
first(),
|
||||
tap(result => {
|
||||
const stateUpdate = {...internalState, languageKey};
|
||||
|
||||
types.forEach(type => {
|
||||
stateUpdate[type] = result[type];
|
||||
types.forEach((type, index) => {
|
||||
stateUpdate[type] = result[index];
|
||||
loadedLanguages[type] = true;
|
||||
});
|
||||
|
||||
|
||||
this.updateState(stateUpdate);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -246,7 +246,7 @@ export class MetadataStore implements StateStore {
|
|||
* @param useCache
|
||||
* @returns any data
|
||||
*/
|
||||
public load(moduleID: string, types: string[], useCache: boolean = true): any {
|
||||
public load(moduleID: string, types: string[], useCache: boolean = true): Observable<any> {
|
||||
|
||||
if (!types) {
|
||||
types = this.getMetadataTypes();
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* the words "Supercharged by SuiteCRM".
|
||||
*/
|
||||
|
||||
import {BehaviorSubject, combineLatest, combineLatestWith, forkJoin, Observable, of, Subscription} from 'rxjs';
|
||||
import {BehaviorSubject, forkJoin, Observable, of, Subscription} from 'rxjs';
|
||||
import {deepClone, Record, ViewContext, ViewFieldDefinition, ViewMode} from 'common';
|
||||
import {catchError, distinctUntilChanged, finalize, map, take, tap} from 'rxjs/operators';
|
||||
import {RecordStore} from '../record/record.store';
|
||||
|
|
|
@ -79,9 +79,9 @@ export class ClassicViewResolver extends BaseMetadataResolver {
|
|||
const module = this.calculateActiveModule(route);
|
||||
return super.resolve(route).pipe(
|
||||
concatMap(() => {
|
||||
return forkJoin({
|
||||
metadata: this.metadataStore.load(module, this.metadataStore.getMetadataTypes()),
|
||||
});
|
||||
return forkJoin([
|
||||
this.metadataStore.load(module, this.metadataStore.getMetadataTypes()),
|
||||
]);
|
||||
}),
|
||||
map(() => this.routeConverter.toLegacy(route.params, route.queryParams)),
|
||||
tap(
|
||||
|
|
|
@ -47,10 +47,8 @@ export class ActionMenuComponent implements OnInit {
|
|||
configState = new BehaviorSubject<ButtonGroupInterface>({buttons: []});
|
||||
config$ = this.configState.asObservable();
|
||||
|
||||
vm$ = combineLatest([
|
||||
this.screenSize.screenSize$
|
||||
]).pipe(
|
||||
map(([screenSize]) => {
|
||||
vm$ = this.screenSize.screenSize$.pipe(
|
||||
map((screenSize) => {
|
||||
if (screenSize) {
|
||||
this.screen = screenSize;
|
||||
}
|
||||
|
|
|
@ -50,3 +50,32 @@
|
|||
background: $nepal-grey;
|
||||
}
|
||||
}
|
||||
.tooltip-class {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
z-index: 1500!important;
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
||||
::ng-deep .tooltip-class .arrow::before {
|
||||
border-top-color: black;
|
||||
}
|
||||
|
||||
.popover-arrow {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin: 0 2px;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: "";
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@
|
|||
|
||||
.modal-backdrop {
|
||||
background-color: $light-grey;
|
||||
z-index: 1050!important;
|
||||
}
|
||||
|
||||
.modal-backdrop.show {
|
||||
|
|
|
@ -1,12 +1,29 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {UKPhoneEditFieldComponent} from './fields/uk-phone/templates/edit/uk-phone.component';
|
||||
import {UkPhoneEditFieldModule} from './fields/uk-phone/templates/edit/uk-phone.module';
|
||||
import {FieldRegistry} from 'core';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [],
|
||||
imports: [
|
||||
CommonModule,
|
||||
HttpClientModule,
|
||||
UkPhoneEditFieldModule
|
||||
],
|
||||
providers: []
|
||||
})
|
||||
export class ExtensionModule {
|
||||
constructor() {
|
||||
constructor(
|
||||
protected fieldRegistry: FieldRegistry
|
||||
) {
|
||||
// Override the edit mode phone field component for all modules
|
||||
fieldRegistry.register('default', 'phone', 'edit', UKPhoneEditFieldComponent);
|
||||
|
||||
// Override the edit mode phone field component just for accounts
|
||||
// fieldRegistry.register('accounts', 'phone', 'edit', UKPhoneEditFieldComponent);
|
||||
}
|
||||
|
||||
init(): void {
|
||||
|
|
|
@ -24,55 +24,47 @@ module.exports = {
|
|||
shared: {
|
||||
'@angular/core': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.3'
|
||||
},
|
||||
'@angular/common': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.3'
|
||||
},
|
||||
'@angular/common/http': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.3'
|
||||
},
|
||||
'@angular/router': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.3'
|
||||
},
|
||||
'@angular/animations': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.3'
|
||||
},
|
||||
'@angular/cdk': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.3'
|
||||
},
|
||||
'@angular/forms': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.3'
|
||||
},
|
||||
'@apollo/client': {
|
||||
singleton: true,
|
||||
requiredVersion: '^3.3.7'
|
||||
},
|
||||
'@apollo/link-error': {
|
||||
singleton: true,
|
||||
requiredVersion: '^2.0.0-beta.3'
|
||||
requiredVersion: '^3.7.14'
|
||||
},
|
||||
'angular-svg-icon': {
|
||||
singleton: true,
|
||||
requiredVersion: '^12.0.0'
|
||||
requiredVersion: '^16.0.0'
|
||||
},
|
||||
'apollo-angular': {
|
||||
singleton: true,
|
||||
requiredVersion: '^2.2.0'
|
||||
requiredVersion: '^5.0.0'
|
||||
},
|
||||
graphql: {
|
||||
singleton: true,
|
||||
requiredVersion: '^14.7.0'
|
||||
},
|
||||
'graphql-tag': {
|
||||
singleton: true,
|
||||
requiredVersion: '^2.11.0'
|
||||
requiredVersion: '^16.6.0'
|
||||
},
|
||||
'lodash-es': {
|
||||
singleton: true,
|
||||
|
@ -80,40 +72,40 @@ module.exports = {
|
|||
},
|
||||
luxon: {
|
||||
singleton: true,
|
||||
requiredVersion: '^1.25.0'
|
||||
requiredVersion: '^3.3.0'
|
||||
},
|
||||
'ng-animate': {
|
||||
singleton: true,
|
||||
requiredVersion: '^1.0.0'
|
||||
requiredVersion: '^2.0.1'
|
||||
},
|
||||
'ngx-chips': {
|
||||
singleton: true,
|
||||
requiredVersion: '^2.2.2'
|
||||
requiredVersion: '^3.0.0'
|
||||
},
|
||||
|
||||
'@swimlane/ngx-charts': {
|
||||
singleton: true,
|
||||
requiredVersion: '^17.0.0'
|
||||
requiredVersion: '^20.3.0'
|
||||
},
|
||||
|
||||
'@ng-bootstrap/ng-bootstrap': {
|
||||
singleton: true,
|
||||
requiredVersion: '^9.0.2'
|
||||
requiredVersion: '^15.0.0'
|
||||
},
|
||||
|
||||
'bn-ng-idle': {
|
||||
singleton: true,
|
||||
requiredVersion: '^1.0.1'
|
||||
requiredVersion: '^2.0.5'
|
||||
},
|
||||
|
||||
'rxjs': {
|
||||
singleton: true,
|
||||
requiredVersion: '^6.6.3'
|
||||
requiredVersion: '^7.8.1'
|
||||
},
|
||||
|
||||
'rxjs/operators': {
|
||||
singleton: true,
|
||||
requiredVersion: '^6.6.3'
|
||||
requiredVersion: '^7.8.1'
|
||||
},
|
||||
|
||||
common: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue