feat: use RoutesService in DynamicLayoutComponent

pull/4377/head
Arman Ozak 5 years ago
parent 19a405f3f7
commit 82188a0d29

@ -1,13 +1,14 @@
import { Component, OnDestroy, Type } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router, UrlSegment } from '@angular/router';
import { Component, Injector, OnDestroy, Type } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { Store } from '@ngxs/store';
import snq from 'snq';
import { eLayoutType } from '../enums/common';
import { ABP } from '../models/common';
import { ABP } from '../models';
import { ReplaceableComponents } from '../models/replaceable-components';
import { ConfigState } from '../states/config.state';
import { RoutesService } from '../services/routes.service';
import { ReplaceableComponentsState } from '../states/replaceable-components.state';
import { getRoutePath } from '../utils/route-utils';
import { takeUntilDestroy } from '../utils/rxjs-utils';
import { TreeNode } from '../utils/tree-utils';
@Component({
selector: 'abp-dynamic-layout',
@ -22,23 +23,37 @@ import { takeUntilDestroy } from '../utils/rxjs-utils';
export class DynamicLayoutComponent implements OnDestroy {
layout: Type<any>;
constructor(private router: Router, private route: ActivatedRoute, private store: Store) {
const { routes } = this.store.selectSnapshot(ConfigState.getAll);
constructor(
injector: Injector,
private route: ActivatedRoute,
private routes: RoutesService,
private store: Store,
) {
const router = injector.get(Router);
const layouts = {
application: this.getComponent('Theme.ApplicationLayoutComponent'),
account: this.getComponent('Theme.AccountLayoutComponent'),
empty: this.getComponent('Theme.EmptyLayoutComponent'),
};
router.events.pipe(takeUntilDestroy(this)).subscribe(event => {
if (event instanceof NavigationEnd) {
const segments = snq(() => router.parseUrl(event.url).root.children.primary.segments, [
{ path: router.url.replace('/', '') },
] as any);
let expectedLayout = (this.route.snapshot.data || {}).layout;
const path = getRoutePath(router);
const layouts = {
application: this.getComponent('Theme.ApplicationLayoutComponent'),
account: this.getComponent('Theme.AccountLayoutComponent'),
empty: this.getComponent('Theme.EmptyLayoutComponent'),
};
if (!expectedLayout) {
let node = { parent: this.routes.search({ path }) } as TreeNode<ABP.Route>;
while (node.parent) {
node = node.parent;
const expectedLayout =
(this.route.snapshot.data || {}).layout || findLayout(segments, routes);
if (node.layout) {
expectedLayout = node.layout;
break;
}
}
}
if (!expectedLayout) expectedLayout = eLayoutType.empty;
this.layout = layouts[expectedLayout].component;
}
@ -51,27 +66,3 @@ export class DynamicLayoutComponent implements OnDestroy {
ngOnDestroy() {}
}
function findLayout(segments: UrlSegment[], routes: ABP.FullRoute[]): eLayoutType {
let layout = eLayoutType.empty;
const route = routes
.reduce((acc, val) => (val.wrapper ? [...acc, ...val.children] : [...acc, val]), [])
.find(r => r.path === segments[0].path);
if (route) {
if (route.layout) {
layout = route.layout;
}
if (route.children && route.children.length && segments.length > 1) {
const child = route.children.find(c => c.path === segments[1].path);
if (child && child.layout) {
layout = child.layout;
}
}
}
return layout;
}

@ -1,13 +1,13 @@
import { HttpClient } from '@angular/common/http';
import { Component, NgModule } from '@angular/core';
import { ActivatedRoute, RouterModule } from '@angular/router';
import { createRoutingFactory, SpectatorRouting } from '@ngneat/spectator/jest';
import { NgxsModule, Store } from '@ngxs/store';
import { DynamicLayoutComponent, RouterOutletComponent } from '../components';
import { eLayoutType } from '../enums';
import { eLayoutType } from '../enums/common';
import { ABP } from '../models';
import { ConfigState, ReplaceableComponentsState } from '../states';
import { ApplicationConfigurationService } from '../services';
import { HttpClient } from '@angular/common/http';
import { ApplicationConfigurationService, RoutesService } from '../services';
import { ReplaceableComponentsState } from '../states';
@Component({
selector: 'abp-layout-application',
@ -48,28 +48,36 @@ class DummyComponent {
constructor(public route: ActivatedRoute) {}
}
const storeData = {
ConfigState: {
routes: [
{
path: '',
wrapper: true,
children: [
{
path: 'parentWithLayout',
layout: eLayoutType.application,
children: [
{ path: 'childWithoutLayout' },
{ path: 'childWithLayout', layout: eLayoutType.account },
],
},
],
},
{ path: 'withData', layout: eLayoutType.application },
,
] as ABP.FullRoute[],
environment: { application: {} },
const routes: ABP.Route[] = [
{
path: '',
name: 'Root',
},
{
path: '/parentWithLayout',
name: 'ParentWithLayout',
parentName: 'Root',
layout: eLayoutType.application,
},
{
path: '/parentWithLayout/childWithoutLayout',
name: 'ChildWithoutLayout',
parentName: 'ParentWithLayout',
},
{
path: '/parentWithLayout/childWithLayout',
name: 'ChildWithLayout',
parentName: 'ParentWithLayout',
layout: eLayoutType.account,
},
{
path: '/withData',
name: 'WithData',
layout: eLayoutType.application,
},
];
const storeData = {
ReplaceableComponentsState: {
replaceableComponents: [
{
@ -94,11 +102,7 @@ describe('DynamicLayoutComponent', () => {
stubsEnabled: false,
declarations: [DummyComponent, DynamicLayoutComponent],
mocks: [ApplicationConfigurationService, HttpClient],
imports: [
RouterModule,
DummyLayoutModule,
NgxsModule.forRoot([ConfigState, ReplaceableComponentsState]),
],
imports: [RouterModule, DummyLayoutModule, NgxsModule.forRoot([ReplaceableComponentsState])],
routes: [
{ path: '', component: RouterOutletComponent },
{
@ -150,6 +154,8 @@ describe('DynamicLayoutComponent', () => {
beforeEach(async () => {
spectator = createComponent();
store = spectator.get(Store);
const routesService = spectator.get(RoutesService);
routesService.add(routes);
store.reset(storeData);
});

Loading…
Cancel
Save