Browse Source

feat: implement the new service to project

pull/5333/head
mehmet-erim 6 years ago
parent
commit
7e7d86a745
  1. 9
      npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts
  2. 9
      npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts
  3. 9
      npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts
  4. 63
      npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts
  5. 39
      npm/ng-packs/packages/theme-basic/src/lib/providers/styles.provider.ts

9
npm/ng-packs/packages/core/src/lib/components/dynamic-layout.component.ts

@ -1,13 +1,12 @@
import { Component, Injector, Optional, SkipSelf, Type } from '@angular/core'; import { Component, Injector, Optional, SkipSelf, Type } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { Store } from '@ngxs/store';
import { eLayoutType } from '../enums/common'; import { eLayoutType } from '../enums/common';
import { ABP } from '../models'; import { ABP } from '../models';
import { ReplaceableComponents } from '../models/replaceable-components'; import { ReplaceableComponents } from '../models/replaceable-components';
import { LocalizationService } from '../services/localization.service'; import { LocalizationService } from '../services/localization.service';
import { ReplaceableComponentsService } from '../services/replaceable-components.service';
import { RoutesService } from '../services/routes.service'; import { RoutesService } from '../services/routes.service';
import { SubscriptionService } from '../services/subscription.service'; import { SubscriptionService } from '../services/subscription.service';
import { ReplaceableComponentsState } from '../states/replaceable-components.state';
import { findRoute, getRoutePath } from '../utils/route-utils'; import { findRoute, getRoutePath } from '../utils/route-utils';
import { TreeNode } from '../utils/tree-utils'; import { TreeNode } from '../utils/tree-utils';
@ -37,7 +36,7 @@ export class DynamicLayoutComponent {
constructor( constructor(
injector: Injector, injector: Injector,
private localizationService: LocalizationService, private localizationService: LocalizationService,
private store: Store, private replaceableComponents: ReplaceableComponentsService,
private subscription: SubscriptionService, private subscription: SubscriptionService,
@Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent, @Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent,
) { ) {
@ -67,7 +66,7 @@ export class DynamicLayoutComponent {
if (!expectedLayout) expectedLayout = eLayoutType.empty; if (!expectedLayout) expectedLayout = eLayoutType.empty;
const key = this.layouts.get(expectedLayout); const key = this.layouts.get(expectedLayout);
this.layout = this.getComponent(key).component; this.layout = this.getComponent(key)?.component;
} }
}); });
@ -82,6 +81,6 @@ export class DynamicLayoutComponent {
} }
private getComponent(key: string): ReplaceableComponents.ReplaceableComponent { private getComponent(key: string): ReplaceableComponents.ReplaceableComponent {
return this.store.selectSnapshot(ReplaceableComponentsState.getComponent(key)); return this.replaceableComponents.get(key);
} }
} }

9
npm/ng-packs/packages/core/src/lib/components/replaceable-route-container.component.ts

@ -1,10 +1,9 @@
import { Component, OnInit, Type } from '@angular/core'; import { Component, OnInit, Type } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Store } from '@ngxs/store';
import { distinctUntilChanged } from 'rxjs/operators'; import { distinctUntilChanged } from 'rxjs/operators';
import { ReplaceableComponents } from '../models/replaceable-components'; import { ReplaceableComponents } from '../models/replaceable-components';
import { ReplaceableComponentsService } from '../services/replaceable-components.service';
import { SubscriptionService } from '../services/subscription.service'; import { SubscriptionService } from '../services/subscription.service';
import { ReplaceableComponentsState } from '../states/replaceable-components.state';
@Component({ @Component({
selector: 'abp-replaceable-route-container', selector: 'abp-replaceable-route-container',
@ -22,7 +21,7 @@ export class ReplaceableRouteContainerComponent implements OnInit {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private store: Store, private replaceableComponents: ReplaceableComponentsService,
private subscription: SubscriptionService, private subscription: SubscriptionService,
) {} ) {}
@ -31,8 +30,8 @@ export class ReplaceableRouteContainerComponent implements OnInit {
this.componentKey = (this.route.snapshot.data this.componentKey = (this.route.snapshot.data
.replaceableComponent as ReplaceableComponents.RouteData).key; .replaceableComponent as ReplaceableComponents.RouteData).key;
const component$ = this.store const component$ = this.replaceableComponents
.select(ReplaceableComponentsState.getComponent(this.componentKey)) .get$(this.componentKey)
.pipe(distinctUntilChanged()); .pipe(distinctUntilChanged());
this.subscription.addOne( this.subscription.addOne(

9
npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts

@ -10,15 +10,14 @@ import {
Type, Type,
ViewContainerRef, ViewContainerRef,
} from '@angular/core'; } from '@angular/core';
import { Store } from '@ngxs/store';
import compare from 'just-compare'; import compare from 'just-compare';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { filter } from 'rxjs/operators'; import { filter } from 'rxjs/operators';
import snq from 'snq'; import snq from 'snq';
import { ABP } from '../models/common'; import { ABP } from '../models/common';
import { ReplaceableComponents } from '../models/replaceable-components'; import { ReplaceableComponents } from '../models/replaceable-components';
import { ReplaceableComponentsService } from '../services/replaceable-components.service';
import { SubscriptionService } from '../services/subscription.service'; import { SubscriptionService } from '../services/subscription.service';
import { ReplaceableComponentsState } from '../states/replaceable-components.state';
@Directive({ selector: '[abpReplaceableTemplate]', providers: [SubscriptionService] }) @Directive({ selector: '[abpReplaceableTemplate]', providers: [SubscriptionService] })
export class ReplaceableTemplateDirective implements OnInit, OnChanges { export class ReplaceableTemplateDirective implements OnInit, OnChanges {
@ -45,7 +44,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
private templateRef: TemplateRef<any>, private templateRef: TemplateRef<any>,
private cfRes: ComponentFactoryResolver, private cfRes: ComponentFactoryResolver,
private vcRef: ViewContainerRef, private vcRef: ViewContainerRef,
private store: Store, private replaceableComponents: ReplaceableComponentsService,
private subscription: SubscriptionService, private subscription: SubscriptionService,
) { ) {
this.context = { this.context = {
@ -58,8 +57,8 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
} }
ngOnInit() { ngOnInit() {
const component$ = this.store const component$ = this.replaceableComponents
.select(ReplaceableComponentsState.getComponent(this.data.componentKey)) .get$(this.data.componentKey)
.pipe( .pipe(
filter( filter(
(res = {} as ReplaceableComponents.ReplaceableComponent) => (res = {} as ReplaceableComponents.ReplaceableComponent) =>

63
npm/ng-packs/packages/core/src/lib/tests/dynamic-layout.component.spec.ts

@ -7,7 +7,11 @@ import { NEVER } from 'rxjs';
import { DynamicLayoutComponent, RouterOutletComponent } from '../components'; import { DynamicLayoutComponent, RouterOutletComponent } from '../components';
import { eLayoutType } from '../enums/common'; import { eLayoutType } from '../enums/common';
import { ABP } from '../models'; import { ABP } from '../models';
import { ApplicationConfigurationService, RoutesService } from '../services'; import {
ApplicationConfigurationService,
RoutesService,
ReplaceableComponentsService,
} from '../services';
import { ReplaceableComponentsState } from '../states'; import { ReplaceableComponentsState } from '../states';
@Component({ @Component({
@ -78,33 +82,7 @@ const routes: ABP.Route[] = [
}, },
]; ];
const storeData = {
ReplaceableComponentsState: {
replaceableComponents: [
{
key: 'Theme.ApplicationLayoutComponent',
component: DummyApplicationLayoutComponent,
},
{
key: 'Theme.AccountLayoutComponent',
component: DummyAccountLayoutComponent,
},
{
key: 'Theme.EmptyLayoutComponent',
component: DummyEmptyLayoutComponent,
},
],
},
};
describe('DynamicLayoutComponent', () => { describe('DynamicLayoutComponent', () => {
const mockActions: Actions = NEVER;
const mockStore = ({
selectSnapshot() {
return true;
},
} as unknown) as Store;
const createComponent = createRoutingFactory({ const createComponent = createRoutingFactory({
component: RouterOutletComponent, component: RouterOutletComponent,
stubsEnabled: false, stubsEnabled: false,
@ -113,10 +91,16 @@ describe('DynamicLayoutComponent', () => {
providers: [ providers: [
{ {
provide: RoutesService, provide: RoutesService,
useFactory: () => new RoutesService(mockActions, mockStore), useFactory: () =>
new RoutesService(NEVER, ({
selectSnapshot() {
return true;
},
} as unknown) as Store),
}, },
ReplaceableComponentsService,
], ],
imports: [RouterModule, DummyLayoutModule, NgxsModule.forRoot([ReplaceableComponentsState])], imports: [RouterModule, DummyLayoutModule, NgxsModule.forRoot()],
routes: [ routes: [
{ path: '', component: RouterOutletComponent }, { path: '', component: RouterOutletComponent },
{ {
@ -163,15 +147,26 @@ describe('DynamicLayoutComponent', () => {
}); });
let spectator: SpectatorRouting<RouterOutletComponent>; let spectator: SpectatorRouting<RouterOutletComponent>;
let store: Store; let replaceableComponents: ReplaceableComponentsService;
beforeEach(async () => { beforeEach(async () => {
spectator = createComponent(); spectator = createComponent();
store = spectator.inject(Store); replaceableComponents = spectator.inject(ReplaceableComponentsService);
const routesService = spectator.inject(RoutesService); const routesService = spectator.inject(RoutesService);
routesService.add(routes); routesService.add(routes);
store.reset(storeData); replaceableComponents.add({
key: 'Theme.ApplicationLayoutComponent',
component: DummyApplicationLayoutComponent,
});
replaceableComponents.add({
key: 'Theme.AccountLayoutComponent',
component: DummyAccountLayoutComponent,
});
replaceableComponents.add({
key: 'Theme.EmptyLayoutComponent',
component: DummyEmptyLayoutComponent,
});
}); });
it('should handle application layout from parent abp route and display it', async () => { it('should handle application layout from parent abp route and display it', async () => {
@ -204,8 +199,8 @@ describe('DynamicLayoutComponent', () => {
}); });
it('should not display any layout when layouts are empty', async () => { it('should not display any layout when layouts are empty', async () => {
store.reset({ ...storeData, ReplaceableComponentsState: {} }); const spy = jest.spyOn(replaceableComponents, 'get');
spy.mockReturnValue(null);
spectator.detectChanges(); spectator.detectChanges();
spectator.router.navigateByUrl('/withoutLayout'); spectator.router.navigateByUrl('/withoutLayout');

39
npm/ng-packs/packages/theme-basic/src/lib/providers/styles.provider.ts

@ -1,4 +1,4 @@
import { AddReplaceableComponent, CONTENT_STRATEGY, DomInsertionService } from '@abp/ng.core'; import { ReplaceableComponentsService, CONTENT_STRATEGY, DomInsertionService } from '@abp/ng.core';
import { APP_INITIALIZER } from '@angular/core'; import { APP_INITIALIZER } from '@angular/core';
import { Store } from '@ngxs/store'; import { Store } from '@ngxs/store';
import { AccountLayoutComponent } from '../components/account-layout/account-layout.component'; import { AccountLayoutComponent } from '../components/account-layout/account-layout.component';
@ -11,32 +11,33 @@ export const BASIC_THEME_STYLES_PROVIDERS = [
{ {
provide: APP_INITIALIZER, provide: APP_INITIALIZER,
useFactory: configureStyles, useFactory: configureStyles,
deps: [DomInsertionService, Store], deps: [DomInsertionService, ReplaceableComponentsService],
multi: true, multi: true,
}, },
]; ];
export function configureStyles(domInsertion: DomInsertionService, store: Store) { export function configureStyles(
domInsertion: DomInsertionService,
replaceableComponents: ReplaceableComponentsService,
) {
return () => { return () => {
domInsertion.insertContent(CONTENT_STRATEGY.AppendStyleToHead(styles)); domInsertion.insertContent(CONTENT_STRATEGY.AppendStyleToHead(styles));
initLayouts(store); initLayouts(replaceableComponents);
}; };
} }
function initLayouts(store: Store) { function initLayouts(replaceableComponents: ReplaceableComponentsService) {
store.dispatch([ replaceableComponents.add({
new AddReplaceableComponent({ key: eThemeBasicComponents.ApplicationLayout,
key: eThemeBasicComponents.ApplicationLayout, component: ApplicationLayoutComponent,
component: ApplicationLayoutComponent, });
}), replaceableComponents.add({
new AddReplaceableComponent({ key: eThemeBasicComponents.AccountLayout,
key: eThemeBasicComponents.AccountLayout, component: AccountLayoutComponent,
component: AccountLayoutComponent, });
}), replaceableComponents.add({
new AddReplaceableComponent({ key: eThemeBasicComponents.EmptyLayout,
key: eThemeBasicComponents.EmptyLayout, component: EmptyLayoutComponent,
component: EmptyLayoutComponent, });
}),
]);
} }

Loading…
Cancel
Save