From 2ea51d94ef807bb492aade19c3fdb306db66f97d Mon Sep 17 00:00:00 2001 From: Willem Dantuma Date: Wed, 13 May 2020 12:30:09 +0200 Subject: [PATCH] Add basic package managing plumbing --- .../src/fm/actions/app-common.actions.ts | 14 +++++++- projects/common/src/fm/common.module.ts | 11 +++++-- .../has-package/has-package.directive.ts | 32 +++++++++++++++++++ .../src/fm/effects/app-common.effects.ts | 12 +++++++ projects/common/src/fm/models/package.ts | 9 ++++++ .../src/fm/reducers/app-common.reducer.ts | 17 ++++++++-- .../common/src/fm/services/package.service.ts | 24 ++++++++++++++ src/app/menu/menu.component.html | 9 ++++-- 8 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 projects/common/src/fm/components/has-package/has-package.directive.ts create mode 100644 projects/common/src/fm/models/package.ts create mode 100644 projects/common/src/fm/services/package.service.ts diff --git a/projects/common/src/fm/actions/app-common.actions.ts b/projects/common/src/fm/actions/app-common.actions.ts index f7ac6e8..2bd72fc 100644 --- a/projects/common/src/fm/actions/app-common.actions.ts +++ b/projects/common/src/fm/actions/app-common.actions.ts @@ -3,10 +3,14 @@ import { Action } from '@ngrx/store'; import { IItemTypes } from '../models/item.types'; import { IListItem } from '../models/list.item'; import { IUser } from '../models/user'; +import { IItem } from '../models/item'; export const INITUSER = '[AppCommon] InitUser'; export const INITUSERSUCCESS = '[AppCommon] InitUserSuccess'; +export const INITUSERPACKAGES = '[AppCommon] InitUserPackages'; +export const INITUSERPACKAGESSUCCESS = '[AppCommon] InitUserPackagesSuccess'; + export const INITROOT = '[Explorer] InitRoot'; export const INITROOTSUCCESS = '[Explorer] InitRootSuccess'; @@ -61,6 +65,12 @@ export class InitUserSuccess implements Action { constructor(public user:IUser ) { } } +export class InitUserPackagesSuccess implements Action { + readonly type = INITUSERPACKAGESSUCCESS; + + constructor(public items:IItem[] ) { } +} + export class InitRoot implements Action { readonly type = INITROOT; @@ -250,4 +260,6 @@ export type Actions = OpenModal | TaskErrorEvent | DeviceUpdateEvent | ToggleMenu - | SetMenuVisible; + | SetMenuVisible + | InitUserPackagesSuccess; + diff --git a/projects/common/src/fm/common.module.ts b/projects/common/src/fm/common.module.ts index bee2467..34909e7 100644 --- a/projects/common/src/fm/common.module.ts +++ b/projects/common/src/fm/common.module.ts @@ -30,6 +30,7 @@ import { SidePanelComponent } from './components/side-panel/side-panel.component import { TimespanComponent } from './components/timespan/timespan.component'; import { TagInputComponent } from './components/tag-input/tag-input.component'; import { MenuBackgroundComponent } from './components/menu-background/menu-background.component'; +import { HasPackageDirective} from './components/has-package/has-package.directive'; import { Alert } from './enumerations/alert.enum'; import { IEventMessage } from './models/event.message'; import { IItem, Item } from './models/item'; @@ -39,6 +40,7 @@ import { IItemTypes } from './models/item.types'; import { IItemTask, ItemTask } from './models/itemTask'; import { IListItem } from './models/list.item'; import { ITypeaheadItem } from './models/typeahead.item'; +import { IPackage,IPackages } from './models/package'; import { IUser } from './models/user'; import { IQueryState } from './models/query.state'; import { ICodeListItem } from './models/code.list.item'; @@ -58,6 +60,7 @@ export { SidePanelComponent, TimespanComponent, TagInputComponent, + HasPackageDirective, Alert, IEventMessage, IItem, @@ -71,6 +74,8 @@ export { IUser, ICodeListItem, IQueryState, + IPackage, + IPackages, commonActions, commonReducers, IAuthconfigFactory, @@ -103,7 +108,8 @@ export { TimespanComponent, TagInputComponent, SessionClearedComponent, - MenuBackgroundComponent + MenuBackgroundComponent, + HasPackageDirective ], exports: [ NgbModule, @@ -120,7 +126,8 @@ export { TimespanComponent, TagInputComponent, SessionClearedComponent, - MenuBackgroundComponent + MenuBackgroundComponent, + HasPackageDirective ] }) export class AppCommonModule { diff --git a/projects/common/src/fm/components/has-package/has-package.directive.ts b/projects/common/src/fm/components/has-package/has-package.directive.ts new file mode 100644 index 0000000..9a4d202 --- /dev/null +++ b/projects/common/src/fm/components/has-package/has-package.directive.ts @@ -0,0 +1,32 @@ +import { Directive, ViewContainerRef,TemplateRef,OnInit,Input,OnDestroy } from '@angular/core'; +import { Store} from '@ngrx/store'; +import * as appCommonReducer from '../../reducers/app-common.reducer' +import { IPackages } from '../../models/package'; +import { Observable, Subscription } from 'rxjs'; + +@Directive({ + selector: '[fm-haspackage]', +}) +export class HasPackageDirective implements OnInit,OnDestroy{ + @Input('fm-haspackage') package:string; + + constructor(private templateRef$: TemplateRef,private viewContainerRef$: ViewContainerRef,private store$: Store) { } + private packages$:Observable = this.store$.select(appCommonReducer.SelectGetUserPackages); + private hasView = false; + private packSub:Subscription; + ngOnInit() { + this.packages$.subscribe((packages) => { + if (packages[this.package] && packages[this.package].enabled) { + this.viewContainerRef$.createEmbeddedView(this.templateRef$); + this.hasView=true; + } else if (this.hasView) { + this.viewContainerRef$.clear(); + this.hasView = false; + } + }); + } + + ngOnDestroy() { + if(this.packSub) this.packSub.unsubscribe(); + } +} \ No newline at end of file diff --git a/projects/common/src/fm/effects/app-common.effects.ts b/projects/common/src/fm/effects/app-common.effects.ts index 74d87c6..63e2bd2 100644 --- a/projects/common/src/fm/effects/app-common.effects.ts +++ b/projects/common/src/fm/effects/app-common.effects.ts @@ -53,6 +53,18 @@ export class AppCommonEffects { } } )); + + @Effect() + initUserPackages$:Observable = this.actions$.pipe( + ofType(appCommonActions.INITUSERSUCCESS), + switchMap((action) => { + let a = action as appCommonActions.InitUserSuccess; + return this.itemService$.getChildItemList(a.user.code+":USER_PACKAGES","vnd.farmmaps.itemtype.package").pipe( + switchMap((items) => of(new appCommonActions.InitUserPackagesSuccess(items))), + catchError(error => of(new appCommonActions.Fail(error))) + ) + }) + ); @Effect() initUserSuccess$: Observable = this.actions$.pipe( diff --git a/projects/common/src/fm/models/package.ts b/projects/common/src/fm/models/package.ts new file mode 100644 index 0000000..921953b --- /dev/null +++ b/projects/common/src/fm/models/package.ts @@ -0,0 +1,9 @@ +export interface IPackage { + id:string + name:string; + enabled?:boolean; +} + +export interface IPackages { + [id: string]: IPackage; +} \ No newline at end of file diff --git a/projects/common/src/fm/reducers/app-common.reducer.ts b/projects/common/src/fm/reducers/app-common.reducer.ts index 65233d6..ec74a38 100644 --- a/projects/common/src/fm/reducers/app-common.reducer.ts +++ b/projects/common/src/fm/reducers/app-common.reducer.ts @@ -2,6 +2,7 @@ import { tassign } from 'tassign'; import { IItemTypes} from '../models/item.types'; import { IListItem } from '../models/list.item'; import { IUser } from '../models/user'; +import { IPackage,IPackages} from '../models/package'; import * as appCommonActions from '../actions/app-common.actions'; import { createSelector, createFeatureSelector, ActionReducerMap } from '@ngrx/store'; @@ -16,6 +17,7 @@ export interface State { fullScreen: boolean, routeLoading:boolean, menuVisible: boolean, + userPackages: IPackages } export const initialState: State = { @@ -26,7 +28,8 @@ export const initialState: State = { user:null, fullScreen: true, routeLoading: false, - menuVisible: false + menuVisible: false, + userPackages: {} } export function reducer(state = initialState, action: appCommonActions.Actions ): State { @@ -79,6 +82,15 @@ export function reducer(state = initialState, action: appCommonActions.Actions ) let a = action as appCommonActions.SetMenuVisible; return tassign(state, { menuVisible: a.visible }); } + case appCommonActions.INITUSERPACKAGESSUCCESS:{ + let a = action as appCommonActions.InitUserPackagesSuccess; + let packages = {} + a.items.forEach((item) => { + packages[item.data.id]=item.data; + }); + + return tassign(state,{userPackages:packages}); + } default: { return state; } @@ -93,7 +105,7 @@ export const getFullScreen = (state: State) => state.fullScreen; export const getRouteLoading = (state: State) => state.routeLoading; export const getMenuVisible = (state: State) => state.menuVisible; export const getUser = (state: State) => state.user; - +export const getUserPackages = (state: State) => state.userPackages; export const selectAppCommonState = createFeatureSelector(MODULE_NAME); @@ -105,4 +117,5 @@ export const selectGetFullScreen = createSelector(selectAppCommonState, getFullS export const selectGetRouteLoading = createSelector(selectAppCommonState, getRouteLoading); export const SelectGetMenuVisible = createSelector(selectAppCommonState,getMenuVisible); export const SelectGetUser = createSelector(selectAppCommonState,getUser); +export const SelectGetUserPackages = createSelector(selectAppCommonState,getUserPackages); diff --git a/projects/common/src/fm/services/package.service.ts b/projects/common/src/fm/services/package.service.ts new file mode 100644 index 0000000..b5b1257 --- /dev/null +++ b/projects/common/src/fm/services/package.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { Store} from '@ngrx/store'; +import * as appCommonReducer from '../reducers/app-common.reducer' +import { IPackages } from '../models/package'; + + +@Injectable({ + providedIn: 'root', +}) + +export class PackageService { + private packages$:IPackages = {}; + + constructor(private store$: Store) { + store$.select(appCommonReducer.SelectGetUserPackages).subscribe((packages) => { + this.packages$ = packages; + }) + } + + hasPackage(id:string):boolean { + if(!this.packages$[id]) return false; + return this.packages$[id].enabled == true; + } +} \ No newline at end of file diff --git a/src/app/menu/menu.component.html b/src/app/menu/menu.component.html index 345c400..2828e43 100644 --- a/src/app/menu/menu.component.html +++ b/src/app/menu/menu.component.html @@ -9,6 +9,11 @@
Thematic maps
- - + + +