Compare commits

..

4 Commits

Author SHA1 Message Date
Willem Dantuma
57e0a37c78 add ifPackageListExists to packageservice
All checks were successful
FarmMaps.Develop/FarmMapsLib/pipeline/head This commit looks good
FarmMaps/FarmMapsLib/pipeline/head This commit looks good
2022-03-16 15:56:23 +01:00
Willem Dantuma
713af307cd Add fmPackageExists directive
All checks were successful
FarmMaps.Develop/FarmMapsLib/pipeline/head This commit looks good
2022-03-16 14:20:28 +01:00
Willem Dantuma
521b882798 Add gradient service 2022-03-16 14:20:08 +01:00
Willem Dantuma
b850f5d621 Add gradient service 2022-03-16 14:19:51 +01:00
12 changed files with 163 additions and 20 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "farmmaps-lib-app", "name": "farmmaps-lib-app",
"version": "2.0.3", "version": "2.0.4",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",

View File

@ -12,6 +12,9 @@ export const INITUSERSUCCESS = '[AppCommon] InitUserSuccess';
export const INITUSERPACKAGES = '[AppCommon] InitUserPackages'; export const INITUSERPACKAGES = '[AppCommon] InitUserPackages';
export const INITUSERPACKAGESSUCCESS = '[AppCommon] InitUserPackagesSuccess'; export const INITUSERPACKAGESSUCCESS = '[AppCommon] InitUserPackagesSuccess';
export const INITPACKAGES = '[AppCommon] InitPackages';
export const INITPACKAGESSUCCESS = '[AppCommon] InitPackagesSuccess';
export const INITUSERSETTINGSROOT = '[AppCommon] InitUserSettingsRoot'; export const INITUSERSETTINGSROOT = '[AppCommon] InitUserSettingsRoot';
export const INITUSERSETTINGSROOTSUCCESS = '[AppCommon] InitUserSettingsRootSuccess'; export const INITUSERSETTINGSROOTSUCCESS = '[AppCommon] InitUserSettingsRootSuccess';
@ -102,6 +105,18 @@ export class InitUserPackagesSuccess implements Action {
constructor(public items:IItem[] ) { } constructor(public items:IItem[] ) { }
} }
export class InitPackages implements Action {
readonly type = INITPACKAGES;
constructor() {}
}
export class InitPackagesSuccess implements Action {
readonly type = INITPACKAGESSUCCESS;
constructor(public items:IItem[] ) { }
}
export class InitUserSettingsRoot implements Action { export class InitUserSettingsRoot implements Action {
readonly type = INITUSERSETTINGSROOT; readonly type = INITUSERSETTINGSROOT;
@ -381,6 +396,8 @@ export type Actions = OpenModal
| SetMenuVisible | SetMenuVisible
| InitUserPackages | InitUserPackages
| InitUserPackagesSuccess | InitUserPackagesSuccess
| InitPackages
| InitPackagesSuccess
| InitUserSettingsRoot | InitUserSettingsRoot
| InitUserSettingsRootSuccess | InitUserSettingsRootSuccess
| ToggleAccountMenu | ToggleAccountMenu

View File

@ -35,6 +35,7 @@ import { PackageService } from './services/package.service';
import { PackagePreloadStrategy } from './services/package-preload-strategy.service'; import { PackagePreloadStrategy } from './services/package-preload-strategy.service';
import { SenmlService } from './services/senml-service'; import { SenmlService } from './services/senml-service';
import { DeviceService } from './services/device.service'; import { DeviceService } from './services/device.service';
import { GradientService} from './services/gradient.service';
export { export {
FolderService, FolderService,
@ -61,7 +62,8 @@ export {
PackageService, PackageService,
SenmlService, SenmlService,
PackagePreloadStrategy, PackagePreloadStrategy,
DeviceService DeviceService,
GradientService
}; };
@NgModule({ @NgModule({

View File

@ -32,6 +32,7 @@ import { TimespanComponent } from './components/timespan/timespan.component';
import { TagInputComponent } from './components/tag-input/tag-input.component'; import { TagInputComponent } from './components/tag-input/tag-input.component';
import { MenuBackgroundComponent } from './components/menu-background/menu-background.component'; import { MenuBackgroundComponent } from './components/menu-background/menu-background.component';
import { HasPackageDirective} from './components/has-package/has-package.directive'; import { HasPackageDirective} from './components/has-package/has-package.directive';
import { PackageExistsDirective} from './components/package-exists/package-exists.directive';
import { HasClaimDirective} from './components/has-claim/has-claim.directive'; import { HasClaimDirective} from './components/has-claim/has-claim.directive';
import { UserMenuComponent} from './components/user-menu/user-menu.component'; import { UserMenuComponent} from './components/user-menu/user-menu.component';
import { ThumbnailComponent } from './components/thumbnail/thumbnail.component'; import { ThumbnailComponent } from './components/thumbnail/thumbnail.component';
@ -82,6 +83,7 @@ export {
UserMenuComponent, UserMenuComponent,
ThumbnailComponent, ThumbnailComponent,
HasPackageDirective, HasPackageDirective,
PackageExistsDirective,
HasClaimDirective, HasClaimDirective,
Alert, Alert,
IEventMessage, IEventMessage,
@ -144,6 +146,7 @@ export {
SessionClearedComponent, SessionClearedComponent,
MenuBackgroundComponent, MenuBackgroundComponent,
HasPackageDirective, HasPackageDirective,
PackageExistsDirective,
HasClaimDirective, HasClaimDirective,
UserMenuComponent, UserMenuComponent,
GradientComponent, GradientComponent,
@ -174,6 +177,7 @@ export {
SessionClearedComponent, SessionClearedComponent,
MenuBackgroundComponent, MenuBackgroundComponent,
HasPackageDirective, HasPackageDirective,
PackageExistsDirective,
HasClaimDirective, HasClaimDirective,
UserMenuComponent, UserMenuComponent,
GradientComponent, GradientComponent,

View File

@ -1,6 +1,7 @@
import { Component, Input, OnInit ,OnChanges, SimpleChanges,ChangeDetectorRef} from '@angular/core'; import { Component, Input, OnInit ,OnChanges, SimpleChanges,ChangeDetectorRef} from '@angular/core';
import { IItem} from '../../models/item' import { IItem} from '../../models/item'
import { IGradientstop } from '../../models/gradient'; import { IGradientstop } from '../../models/gradient';
import { GradientService } from '../../common-service.module';
@ -14,23 +15,12 @@ export class GradientComponent implements OnInit,OnChanges {
@Input() gradientItem:IItem; @Input() gradientItem:IItem;
public gradientStyle:any = {}; public gradientStyle:any = {};
constructor(private ref: ChangeDetectorRef) { } constructor(private ref: ChangeDetectorRef,private gradientService:GradientService) { }
getGradientStyle(item:IItem):any { getGradientStyle(item:IItem):any {
if(item.data && item.data.gradient) { if(item.data && item.data.gradient) {
let gradient = item.data.gradient as IGradientstop[]; let gradient = item.data.gradient as IGradientstop[];
let gd = '{ "background": "linear-gradient(to right,'; return this.gradientService.getGradientStyle(gradient);
for(var i=0;i<gradient.length;i++) {
let gs = gradient[i];
if(i>0) gd+=",";
gd += `rgba(${gs.color.red},${gs.color.green},${gs.color.blue},${gs.color.alpha/255})`;
gd +=` ${gs.relativestop*100}%`
}
gradient.forEach((gs) => {
});
gd+=')"}';
return JSON.parse(gd);
} }
} }
@ -49,5 +39,4 @@ export class GradientComponent implements OnInit,OnChanges {
} }
} }
} }
} }

View File

@ -0,0 +1,61 @@
import {AfterViewInit, Directive, Input, OnDestroy, TemplateRef, ViewContainerRef} from '@angular/core';
import {Subscription} from 'rxjs';
import {PackageService} from '../../services/package.service';
import * as appCommonReducer from '../../reducers/app-common.reducer';
import {Store} from '@ngrx/store';
@Directive({
selector: '[fmPackageExists]',
})
export class PackageExistsDirective implements OnDestroy, AfterViewInit {
@Input()
set fmPackageExists(packageIdentifier: string) {
this.packageIdentifier = packageIdentifier;
this.updateView();
}
@Input()
set fmPackageExistsThen(thenTemplate: TemplateRef<any>) {
this.thenTemplate = thenTemplate;
this.updateView();
}
@Input()
set fmPackageExistsElse(thenTemplate: TemplateRef<any>) {
this.elseTemplate = thenTemplate;
this.updateView();
}
private packageIdentifier: string;
private thenTemplate: TemplateRef<any>;
private elseTemplate: TemplateRef<any>;
private packSub: Subscription;
constructor(private hostTemplateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef,
private store: Store<appCommonReducer.State>, private packageService: PackageService) {
this.thenTemplate = hostTemplateRef;
this.packSub = this.store.select(appCommonReducer.SelectGetPackages).subscribe((_) => {
this.updateView();
});
}
ngAfterViewInit() {
this.updateView();
}
updateView() {
this.viewContainerRef.clear();
if (this.packageService.packageExists(this.packageIdentifier)) {
this.viewContainerRef.createEmbeddedView(this.thenTemplate);
} else if (this.elseTemplate) {
this.viewContainerRef.createEmbeddedView(this.elseTemplate);
}
}
ngOnDestroy() {
if (this.packSub) {
this.packSub.unsubscribe();
}
}
}

View File

@ -62,6 +62,15 @@ export class AppCommonEffects {
) )
}) })
)); ));
initPackages$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.INITPACKAGES),
switchMap(() => {
return this.itemService$.getItemList('vnd.farmmaps.itemtype.package.template').pipe(
switchMap((items) => of(new appCommonActions.InitPackagesSuccess(items))),
catchError(error => of(new appCommonActions.Fail(error)))
)
})
));
userPackagesChanged$ = createEffect(() => this.actions$.pipe( userPackagesChanged$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.ITEMCHANGEDEVENT), ofType(appCommonActions.ITEMCHANGEDEVENT),
@ -99,7 +108,7 @@ export class AppCommonEffects {
initUserSuccess$ = createEffect(() => this.actions$.pipe( initUserSuccess$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.INITUSERSUCCESS), ofType(appCommonActions.INITUSERSUCCESS),
switchMap(() => { switchMap(() => {
return [new appCommonActions.InitRoot(),new appCommonActions.InitUserPackages(),new appCommonActions.InitUserSettingsRoot()]; return [new appCommonActions.InitRoot(),new appCommonActions.InitUserPackages(),new appCommonActions.InitPackages(),new appCommonActions.InitUserSettingsRoot()];
} }
))); )));

View File

@ -9,3 +9,8 @@ export interface IPackage {
export interface IPackages { export interface IPackages {
[id: string]: IPackage[]; [id: string]: IPackage[];
} }
export interface IPackageMap {
[id: string]: IPackage;
}

View File

@ -2,7 +2,7 @@ import { tassign } from 'tassign';
import { IItemTypes} from '../models/item.types'; import { IItemTypes} from '../models/item.types';
import { IListItem } from '../models/list.item'; import { IListItem } from '../models/list.item';
import { IUser } from '../models/user'; import { IUser } from '../models/user';
import { IPackage,IPackages} from '../models/package'; import { IPackage,IPackageMap,IPackages} from '../models/package';
import * as appCommonActions from '../actions/app-common.actions'; import * as appCommonActions from '../actions/app-common.actions';
import { createSelector, createFeatureSelector, ActionReducerMap } from '@ngrx/store'; import { createSelector, createFeatureSelector, ActionReducerMap } from '@ngrx/store';
@ -20,6 +20,7 @@ export interface State {
routeLoading:boolean, routeLoading:boolean,
menuVisible: boolean, menuVisible: boolean,
userPackages: IPackages, userPackages: IPackages,
packages: IPackageMap,
userSettingsRoot: IItem, userSettingsRoot: IItem,
accountMenuVisible: boolean, accountMenuVisible: boolean,
appMenuVisible: boolean, appMenuVisible: boolean,
@ -40,6 +41,7 @@ export const initialState: State = {
routeLoading: false, routeLoading: false,
menuVisible: false, menuVisible: false,
userPackages: {}, userPackages: {},
packages: {},
userSettingsRoot: null, userSettingsRoot: null,
accountMenuVisible: false, accountMenuVisible: false,
appMenuVisible: false, appMenuVisible: false,
@ -140,6 +142,15 @@ export function reducer(state = initialState, action: appCommonActions.Actions )
return tassign(state,{userPackages:packages}); return tassign(state,{userPackages:packages});
} }
case appCommonActions.INITPACKAGESSUCCESS:{
let a = action as appCommonActions.InitPackagesSuccess;
let packages = {}
a.items.forEach((item) => {
packages[item.data.id] = item.data;
});
return tassign(state,{packages:packages});
}
case appCommonActions.INITUSERSETTINGSROOTSUCCESS:{ case appCommonActions.INITUSERSETTINGSROOTSUCCESS:{
let a = action as appCommonActions.InitUserSettingsRootSuccess; let a = action as appCommonActions.InitUserSettingsRootSuccess;
return tassign(state, { userSettingsRoot : a.item }); return tassign(state, { userSettingsRoot : a.item });
@ -187,6 +198,7 @@ export const getRouteLoading = (state: State) => state.routeLoading;
export const getMenuVisible = (state: State) => state.menuVisible; export const getMenuVisible = (state: State) => state.menuVisible;
export const getUser = (state: State) => state.user; export const getUser = (state: State) => state.user;
export const getUserPackages = (state: State) => state.userPackages; export const getUserPackages = (state: State) => state.userPackages;
export const getPackages = (state: State) => state.packages;
export const getUserSettingsRoot = (state: State) => state.userSettingsRoot; export const getUserSettingsRoot = (state: State) => state.userSettingsRoot;
export const getAccountMenuVisible = (state: State) => state.accountMenuVisible; export const getAccountMenuVisible = (state: State) => state.accountMenuVisible;
export const getAppMenuVisible = (state: State) => state.appMenuVisible; export const getAppMenuVisible = (state: State) => state.appMenuVisible;
@ -207,6 +219,7 @@ export const selectGetRouteLoading = createSelector(selectAppCommonState, getRou
export const SelectGetMenuVisible = createSelector(selectAppCommonState,getMenuVisible); export const SelectGetMenuVisible = createSelector(selectAppCommonState,getMenuVisible);
export const SelectGetUser = createSelector(selectAppCommonState,getUser); export const SelectGetUser = createSelector(selectAppCommonState,getUser);
export const SelectGetUserPackages = createSelector(selectAppCommonState,getUserPackages); export const SelectGetUserPackages = createSelector(selectAppCommonState,getUserPackages);
export const SelectGetPackages = createSelector(selectAppCommonState,getPackages);
export const SelectGetValidUserPackages = createSelector(SelectGetUserPackages, (packageMap) => { export const SelectGetValidUserPackages = createSelector(SelectGetUserPackages, (packageMap) => {
return getValidPackages(packageMap); return getValidPackages(packageMap);
}); });

View File

@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import {IGradientstop } from '../models/gradient'
@Injectable({
providedIn: 'root',
})
export class GradientService {
constructor() {
}
getGradientStyle(gradient:IGradientstop[],portrait:boolean = false ):any {
let gd = '{ "background": "linear-gradient(to ' + (portrait?'bottom':'right') +',';
for(var i=0;i<gradient.length;i++) {
let gs = gradient[i];
if(i>0) gd+=",";
gd += `rgba(${gs.color.red},${gs.color.green},${gs.color.blue},${gs.color.alpha/255})`;
gd +=` ${gs.relativestop*100}%`
}
gradient.forEach((gs) => {
});
gd+=')"}';
return JSON.parse(gd);
}
}

View File

@ -7,17 +7,23 @@ import {IItem} from '../models/item';
import {IItemTask} from '../models/itemTask'; import {IItemTask} from '../models/itemTask';
import {HttpClient} from '@angular/common/http'; import {HttpClient} from '@angular/common/http';
import {AppConfig} from '../shared/app.config'; import {AppConfig} from '../shared/app.config';
import {Observable} from 'rxjs'; import {Observable,iif,of} from 'rxjs';
import {switchMap} from 'rxjs/operators';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class PackageService { export class PackageService {
private userPackages: { [key: string]: IPackage } = {};
private packages: { [key: string]: IPackage } = {}; private packages: { [key: string]: IPackage } = {};
private packagesObservable = this.store$.select(appCommonReducer.SelectGetPackages);
constructor(private store$: Store<appCommonReducer.State>, public httpClient: HttpClient, public appConfig: AppConfig) { constructor(private store$: Store<appCommonReducer.State>, public httpClient: HttpClient, public appConfig: AppConfig) {
store$.select(appCommonReducer.SelectGetValidUserPackages).subscribe((packages) => { store$.select(appCommonReducer.SelectGetValidUserPackages).subscribe((packages) => {
this.userPackages = packages;
});
this.packagesObservable.subscribe((packages) => {
this.packages = packages; this.packages = packages;
}); });
} }
@ -27,12 +33,24 @@ export class PackageService {
} }
hasPackage(id: string): boolean { hasPackage(id: string): boolean {
return id in this.userPackages;
}
packageExists(id: string): boolean {
return id in this.packages; return id in this.packages;
} }
postItemPackageTask(item: IItem, task: IItemTask): Observable<IItemTask> { postItemPackageTask(item: IItem, task: IItemTask): Observable<IItemTask> {
return this.httpClient.post<IItemTask>(`${this.ApiEndpoint()}/api/v1/items/${item.code}/packagetasks`, task); return this.httpClient.post<IItemTask>(`${this.ApiEndpoint()}/api/v1/items/${item.code}/packagetasks`, task);
} }
ifPackageListExists<Type>(packageList: Array<string>, ifTrue:Observable<Type>,ifFalse:Observable<Type>):Observable<Type> {
return this.packagesObservable.pipe(switchMap(packages =>
iif(( )=> Object.keys(packages).some(id => packageList.includes(id)),
ifTrue,
ifFalse)
));
}
} }
export function getValidPackages(packageMap: IPackages): {[key: string]: IPackage} { export function getValidPackages(packageMap: IPackages): {[key: string]: IPackage} {

View File

@ -2,7 +2,7 @@
<div class="row"> <div class="row">
<fm-gradient-select [gradientItems]="gradientItems|async" [showLabel]="false" [showAdd]="true"></fm-gradient-select> <fm-gradient-select [gradientItems]="gradientItems|async" [showLabel]="false" [showAdd]="true"></fm-gradient-select>
</div> </div>
<div class="row mt-3"> <div class="row mt-3" *fmPackageExists="'vnd.farmmaps.itemtype.package.dacom'">
<button class="btn btn-primary" (click)="onTest($event)">Test</button> <button class="btn btn-primary" (click)="onTest($event)">Test</button>
</div> </div>
</div> </div>