diff --git a/npm/ng-packs/packages/core/ng-package.json b/npm/ng-packs/packages/core/ng-package.json index c38f8aa834..5a23ee2ce7 100644 --- a/npm/ng-packs/packages/core/ng-package.json +++ b/npm/ng-packs/packages/core/ng-package.json @@ -11,6 +11,7 @@ "@ngxs/store", "angular-oauth2-oidc", "just-compare", + "just-clone", "snq" ] } diff --git a/npm/ng-packs/packages/core/package.json b/npm/ng-packs/packages/core/package.json index 8e23805784..c97d36644c 100644 --- a/npm/ng-packs/packages/core/package.json +++ b/npm/ng-packs/packages/core/package.json @@ -7,6 +7,7 @@ "@ngxs/store": "^3.5.0", "angular-oauth2-oidc": "^8.0.1", "just-compare": "^1.3.0", + "just-clone": "3.1.0", "snq": "^1.0.3" }, "peerDependencies": { diff --git a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts index d89d486c57..876c476d5f 100644 --- a/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts +++ b/npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts @@ -33,7 +33,7 @@ export class DynamicLayoutComponent implements OnDestroy { if ((this.route.snapshot.data || {}).layout) { this.layout = layouts .filter(l => !!l) - .find(l => snq(() => l.type.toLowerCase().indexOf(this.route.snapshot.data.layout), -1) > -1); + .find((l: any) => snq(() => l.type.toLowerCase().indexOf(this.route.snapshot.data.layout), -1) > -1); } this.router.events.pipe(takeUntilDestroy(this)).subscribe(event => { @@ -42,7 +42,9 @@ export class DynamicLayoutComponent implements OnDestroy { const layout = (this.route.snapshot.data || {}).layout || findLayout(segments, routes); - this.layout = layouts.filter(l => !!l).find(l => snq(() => l.type.toLowerCase().indexOf(layout), -1) > -1); + this.layout = layouts + .filter(l => !!l) + .find((l: any) => snq(() => l.type.toLowerCase().indexOf(layout), -1) > -1); } }); } diff --git a/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts b/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts index 24769b325d..604f7a8660 100644 --- a/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts +++ b/npm/ng-packs/packages/core/src/lib/directives/for.directive.ts @@ -12,6 +12,7 @@ import { ViewContainerRef, } from '@angular/core'; import compare from 'just-compare'; +import clone from 'just-clone'; export type CompareFn = (value: T, comparison: T) => boolean; @@ -146,7 +147,7 @@ export class ForDirective implements OnChanges { } ngOnChanges() { - let items = [...this.items] as any[]; + let items = clone(this.items) as any[]; if (!Array.isArray(items)) return; const compareFn = this.compareFn; diff --git a/npm/ng-packs/packages/core/src/lib/models/config.ts b/npm/ng-packs/packages/core/src/lib/models/config.ts index 00ef1c5126..8238864b2f 100644 --- a/npm/ng-packs/packages/core/src/lib/models/config.ts +++ b/npm/ng-packs/packages/core/src/lib/models/config.ts @@ -1,16 +1,21 @@ import { AuthConfig } from 'angular-oauth2-oidc'; import { Type } from '@angular/core'; +import { ApplicationConfiguration } from './application-configuration'; +import { ABP } from './common'; export namespace Config { - export interface State { - [key: string]: any; - } + export type State = ApplicationConfiguration.Response & + ABP.Root & { environment: Environment } & { + routes: ABP.FullRoute[]; + flattedRoutes: ABP.FullRoute[]; + }; export interface Environment { application: Application; production: boolean; oAuthConfig: AuthConfig; apis: Apis; + localization: { defaultResourceName: string }; } export interface Application { diff --git a/npm/ng-packs/packages/core/src/lib/plugins/config/config.plugin.ts b/npm/ng-packs/packages/core/src/lib/plugins/config/config.plugin.ts index 9064461f53..97fa0461bf 100644 --- a/npm/ng-packs/packages/core/src/lib/plugins/config/config.plugin.ts +++ b/npm/ng-packs/packages/core/src/lib/plugins/config/config.plugin.ts @@ -4,6 +4,7 @@ import { actionMatcher, InitState, NgxsNextPluginFn, NgxsPlugin, setValue, Updat import snq from 'snq'; import { ABP } from '../../models'; import { organizeRoutes } from '../../utils/route-utils'; +import clone from 'just-clone'; export const NGXS_CONFIG_PLUGIN_OPTIONS = new InjectionToken('NGXS_CONFIG_PLUGIN_OPTIONS'); @@ -21,11 +22,12 @@ export class ConfigPlugin implements NgxsPlugin { if (isInitAction && !this.initialized) { let { routes, wrappers } = transformRoutes(this.router.config); routes = organizeRoutes(routes, wrappers); - + const flattedRoutes = flatRoutes(clone(routes)); state = setValue(state, 'ConfigState', { ...(state.ConfigState && { ...state.ConfigState }), ...this.options, routes, + flattedRoutes, }); this.initialized = true; @@ -92,3 +94,20 @@ function setUrls(routes: ABP.FullRoute[], parentUrl?: string): ABP.FullRoute[] { }), })); } + +function flatRoutes(routes: ABP.FullRoute[]): ABP.FullRoute[] { + const flat = (r: ABP.FullRoute[]) => { + return r.reduce((acc, val) => { + let value: ABP.FullRoute[] = [val]; + if (val.children) { + const { children } = val; + delete val.children; + value = [val, ...flat(children)]; + } + + return [...acc, ...value]; + }, []); + }; + + return flat(routes); +} diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts index d263440dea..8225aaea2a 100644 --- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts @@ -20,8 +20,8 @@ export class ConfigState { } @Selector() - static getApplicationInfo(state: Config.State) { - return state.environment.application || {}; + static getApplicationInfo(state: Config.State): Config.Application { + return state.environment.application || ({} as Config.Application); } static getOne(key: string) { @@ -64,7 +64,14 @@ export class ConfigState { const selector = createSelector( [ConfigState], function(state: Config.State) { - return findRoute(state.routes, path, name); + const { flattedRoutes } = state; + return (flattedRoutes as ABP.FullRoute[]).find(route => { + if (path && route.path === path) { + return route; + } else if (name && route.name === name) { + return route; + } + }); }, ); @@ -131,7 +138,7 @@ export class ConfigState { keys[0] = snq(() => defaultResourceName); } - let copy = keys.reduce((acc, val) => { + let copy = (keys as any).reduce((acc, val) => { if (acc) { return acc[val]; } @@ -223,22 +230,3 @@ function patchRouteDeep( return organizeRoutes(routes); } - -function findRoute(routes: ABP.FullRoute[], path?: string, name?: string) { - let foundRoute; - routes.forEach(route => { - if (foundRoute) return; - - if (path && route.path === path) { - foundRoute = route; - } else if (name && route.name === name) { - foundRoute = route; - return; - } else if (route.children && route.children.length) { - foundRoute = findRoute(route.children, path, name); - return; - } - }); - - return foundRoute; -}