Add basic package managing plumbing
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				FarmMaps.Develop/FarmMapsLib/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	FarmMaps.Develop/FarmMapsLib/pipeline/head This commit looks good
				
			This commit is contained in:
		| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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<any>,private viewContainerRef$: ViewContainerRef,private store$: Store<appCommonReducer.State>) { } | ||||
|   private packages$:Observable<IPackages> = 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(); | ||||
|   } | ||||
| } | ||||
| @@ -53,6 +53,18 @@ export class AppCommonEffects { | ||||
|       } | ||||
|     } | ||||
|   )); | ||||
|    | ||||
|   @Effect() | ||||
|   initUserPackages$:Observable<Action> = 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<Action> = this.actions$.pipe( | ||||
|   | ||||
							
								
								
									
										9
									
								
								projects/common/src/fm/models/package.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								projects/common/src/fm/models/package.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| export interface IPackage { | ||||
|     id:string | ||||
|     name:string; | ||||
|     enabled?:boolean; | ||||
| } | ||||
|  | ||||
| export interface IPackages { | ||||
|     [id: string]: IPackage; | ||||
| } | ||||
| @@ -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<State>(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); | ||||
|  | ||||
|   | ||||
							
								
								
									
										24
									
								
								projects/common/src/fm/services/package.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								projects/common/src/fm/services/package.service.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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<appCommonReducer.State>) { | ||||
|         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; | ||||
|     } | ||||
| } | ||||
| @@ -9,6 +9,11 @@ | ||||
|             <div class="icon rounded-circle thematic-maps-icon"><i class="fa fa-map" aria-hidden="true"></i></div> | ||||
|             <div class="caption" i18n>Thematic maps</div> | ||||
|           </div>    | ||||
|         </div> | ||||
|     </div>      | ||||
|         </div>        | ||||
|     </div>     | ||||
|     <div class="card menu-card"> | ||||
|       <ul class="navbar-nav"> | ||||
|         <li class="nav-item py-0" *fm-haspackage="'vnd.farmmaps.package.agriroute'"><a [routerLinkActive]="['active']" [routerLink]="['/agrirouter']" class="nav-link"><span i18n><i class="fa fa-plug" aria-hidden="true"></i> agrirouter</span></a></li> | ||||
|       </ul> | ||||
|     </div>  | ||||
| </div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user