diff --git a/fonts/FMIconFont/FMIconFont.svg b/fonts/FMIconFont/FMIconFont.svg index 8181e1a..4f413e1 100644 --- a/fonts/FMIconFont/FMIconFont.svg +++ b/fonts/FMIconFont/FMIconFont.svg @@ -1,6 +1,4 @@ - - + inkscape:showpageshadow="false" + inkscape:document-rotation="0"> + + + + + + + + + font-family="FMIconFont" /> @@ -90,7 +138,55 @@ id="glyph5072" d="m 667.85901,47.05746 c 52.55976,15.6087 154.70543,85.90829 189.72033,130.57135 38.83311,49.53329 47.43676,70.27021 47.43676,114.33585 0,83.30319 -53.15465,136.93019 -142.86222,144.13094 -63.15956,5.06997 -258.40531,-18.50751 -312.41642,-37.72651 -45.26643,-16.1075 -101.96856,-78.49666 -114.86313,-126.38343 -26.17054,-97.19001 37.2249,-196.3167 146.88577,-229.674 37.02144,-11.2617 141.13659,-8.6062 186.09891,4.7458 z m -140.97354,57.3422 c -15.66204,15.66207 -13.10309,30.36665 7.83654,45.03351 26.15266,18.31778 52.21145,3.51275 48.61486,-27.61991 -2.00137,-17.32586 -8.02436,-23.68801 -24.21533,-25.5802 -11.85295,-1.38413 -26.35931,2.29052 -32.23607,8.1666 z m -47.3854,86.76183 c -6.04661,17.33426 2.97284,32.23596 19.50818,32.23596 16.16276,0 29.22849,-21.86458 21.01116,-35.16076 -7.15683,-11.58004 -36.1907,-9.48409 -40.51934,2.92409 z m -130.44714,40.05657 c -8.21734,13.29585 4.84838,35.16087 21.0114,35.16087 16.53636,0 25.55452,-14.90178 19.50792,-32.23607 -4.32865,-12.40912 -33.36251,-14.50473 -40.51932,-2.92411 z m -41.60686,-40.05657 c -10.12089,56.30281 1.05922,101.45485 39.09536,157.87409 38.33081,56.85877 87.1838,80.45971 188.78464,91.20247 43.85243,4.63656 81.31959,9.94286 83.26055,11.79148 7.33459,6.98627 -27.04025,36.21931 -70.23249,59.72769 -36.25508,19.73228 -58.54732,25.12171 -116.49026,28.16306 -62.65272,3.28831 -78.86637,0.89676 -129.0505,-19.03022 C 224.2163,489.67935 156.28985,440.87063 122.92158,391.62775 99.71184,357.37567 94.9839,342.32577 94.9839,302.69668 c 0,-62.64398 28.56794,-113.54347 74.66971,-133.03926 49.58107,-20.96665 55.1462,-22.21557 102.23893,-22.94757 l 43.66625,-0.67909 z M 180.58838,339.87834 c -9.1514,11.02701 -8.501,15.84684 3.77111,27.93792 13.96282,13.75755 15.54505,13.64769 27.05352,-1.87458 9.05824,-12.21787 9.76262,-19.45232 2.71945,-27.93768 -12.34517,-14.87514 -19.99843,-14.44732 -33.54475,1.87467 z m 192.60637,111.26259 c -2.97603,7.75926 -1.28988,18.2294 3.74641,23.26725 13.09726,13.09761 37.91295,1.1274 34.49181,-16.63797 -3.81072,-19.7873 -31.35623,-24.56297 -38.23822,-6.62928 z m 301.90918,59.22566 c -14.44791,48.00729 -5.99247,57.30525 46.46332,51.09247 34.75665,-4.1164 42.50283,-1.88436 62.34565,17.95753 24.73549,24.73573 47.25709,71.15552 38.68241,79.7303 -10.58132,10.58122 -83.93416,3.95428 -104.35792,-9.42795 -11.44256,-7.4973 -25.44468,-29.12027 -31.11673,-48.05113 -11.40888,-38.07997 -20.75061,-43.47592 -29.1967,-16.86481 -7.80601,24.59415 2.80385,83.36533 22.65776,125.50393 15.25106,32.37024 20.43806,36.15493 57.08846,41.65095 102.41079,15.35732 147.92834,74.26422 148.08563,191.64632 0.097,74.0745 -6.72768,79.9763 -66.86111,57.7958 -56.54492,-20.85687 -101.85778,-53.13352 -123.30012,-87.82812 -15.6653,-25.3466 -17.65328,-38.74179 -14.06031,-94.72857 4.22602,-65.8519 -0.59142,-80.61692 -50.91763,-156.11246 -1.23787,-1.85524 -8.37198,1.70893 -15.8557,7.91835 -7.95971,6.60588 -12.87867,22.27635 -11.85261,37.759 3.98395,60.11493 -0.85448,75.87704 -33.21785,108.24179 -31.12292,31.12293 -99.65723,60.0632 -142.23743,60.0632 -15.47455,0 -16.41386,-4.23728 -11.4546,-51.68314 10.46595,-100.13457 58.1109,-154.53189 135.40384,-154.59498 57.52736,-0.0344 71.03115,-18.2638 68.852,-92.88509 -1.41005,-48.25931 1.4881,-62.59615 16.51265,-81.69596 10.02211,-12.74085 25.29913,-23.16484 33.9492,-23.16484 14.57135,0 14.89398,2.76809 4.38779,37.67741 z m -381.76199,70.55193 c 10.33373,12.45108 12.30778,12.35498 22.13047,-1.07866 6.41021,-8.76673 16.47782,-12.56413 24.82117,-9.36254 12.3861,4.75287 11.42409,10.06106 -8.1832,45.14231 -12.22096,21.86563 -22.22004,43.38654 -22.22004,47.82436 0,4.43741 11.60502,17.83329 25.78877,29.76808 29.76327,25.04418 34.42226,64.50401 12.59886,106.70564 -11.16345,21.58814 -15.77147,24.12428 -29.99778,16.51067 -38.3045,-20.50011 -54.61177,-90.91586 -29.39293,-126.92078 10.67483,-15.24066 11.02282,-19.10527 1.71873,-19.10527 -16.59681,0 -32.2939,17.87101 -32.2939,36.76576 0,8.87394 -11.3071,27.44185 -25.1273,41.26206 -22.17329,22.17294 -31.1752,25.1273 -76.56191,25.1273 h -51.43394 l 9.52407,-31.03233 c 5.2383,-17.06788 20.41009,-42.68577 33.71496,-56.92898 22.46572,-24.0496 27.5829,-25.61523 71.75246,-21.95237 43.61529,3.61678 48.83639,2.09886 62.9279,-18.2882 29.72296,-43.00442 31.04041,-47.68105 9.10199,-32.31498 -27.25694,19.09161 -53.32579,18.15461 -78.07622,-2.80711 -19.91497,-16.86612 -19.98254,-17.42754 -3.60735,-30.08717 21.9007,-16.93111 68.48332,-16.4977 82.81492,0.77022 z" unicode="b" /> + + + + + + + + + + + @@ -104,13 +200,46 @@ + + + + + + + + diff --git a/fonts/FMIconFont/FMIconFont.ttf b/fonts/FMIconFont/FMIconFont.ttf index c8b8ea1..1375c6f 100644 Binary files a/fonts/FMIconFont/FMIconFont.ttf and b/fonts/FMIconFont/FMIconFont.ttf differ diff --git a/fonts/FMIconFont/FMIconFont.woff b/fonts/FMIconFont/FMIconFont.woff index 0b0d947..895432a 100644 Binary files a/fonts/FMIconFont/FMIconFont.woff and b/fonts/FMIconFont/FMIconFont.woff differ diff --git a/fonts/FMIconFont/FMIconFont.woff2 b/fonts/FMIconFont/FMIconFont.woff2 index ebf2f18..bb83cf4 100644 Binary files a/fonts/FMIconFont/FMIconFont.woff2 and b/fonts/FMIconFont/FMIconFont.woff2 differ diff --git a/fonts/FMIconFont/style.css b/fonts/FMIconFont/style.css index 1cc9b8c..513315b 100644 --- a/fonts/FMIconFont/style.css +++ b/fonts/FMIconFont/style.css @@ -23,6 +23,30 @@ content: "b"; } +.fm-trijntje:before { + content: "c"; +} + +.fm-satellite:before { + content: "d"; +} + +.fm-sensoterra:before { + content: "e"; +} + +.fm-blight:before { + content: "f"; +} + +.fm-agrodatacube:before { + content: "g"; +} + +.fm-app-menu:before { + content: "h"; +} + @font-face { font-family: "FarmMaps"; src: url("./FMIconFont.woff") format("woff"), /* Modern Browsers */ diff --git a/projects/common-map/src/fm-map/actions/map.actions.ts b/projects/common-map/src/fm-map/actions/map.actions.ts index 2ba6176..17c8c2a 100644 --- a/projects/common-map/src/fm-map/actions/map.actions.ts +++ b/projects/common-map/src/fm-map/actions/map.actions.ts @@ -16,6 +16,7 @@ export const STARTSEARCHSUCCESS = '[Map] StartSearchSuccess'; export const SELECTFEATURE = '[Map] SelectFeature'; export const SELECTITEM = '[Map] SelectItem'; export const SELECTITEMSUCCESS = '[Map] SelectItemSuccess'; +export const SETSELECTEDITEMLAYER = '[Map] SetSelectedItemLayer'; export const SELECTTEMPORALITEMSSUCCESS = '[Map] SelectTemporalItemsSuccess'; export const NEXTTEMPORAL = '[Map] NextTemporal'; export const PREVIOUSTEMPORAL = '[Map] PreviousTemporal'; @@ -32,6 +33,7 @@ export const SETVISIBILITY = '[Map] SetVisibility'; export const SETOPACITY = '[Map] SetOpacity'; export const SETLAYERINDEX = '[Map] SetLayerIndex'; export const REMOVELAYER = '[Map] RemoveLayer'; +export const CLEARLAYERS = '[Map] ClearLayers'; export const LOADBASELAYERS = '[Map] LoadLayers'; export const LOADBASELAYERSSUCCESS = '[Map] LoadLayersSuccess'; export const SELECTBASELAYER = '[Map] SelectBaseLayers'; @@ -42,6 +44,7 @@ export const SETSTYLE = '[Map] SetStyle'; export const SHOWLAYERSWITCHER = '[Map] ShowLayerSwitcher'; export const CLEAR = '[Map] Clear'; export const SETREPLACEURL = '[Map] SetReplaceUrl'; +export const SETFEATURES = '[Map] SetFeatures' export class Clear implements Action { readonly type = CLEAR; @@ -180,6 +183,12 @@ export class AddLayer implements Action { constructor(public item:IItem,public layerIndex=-1) { } } +export class SetSelectedItemLayer implements Action { + readonly type = SETSELECTEDITEMLAYER; + + constructor(public item:IItem,public layerIndex=-1) { } +} + export class SetVisibility implements Action { readonly type = SETVISIBILITY; @@ -204,6 +213,12 @@ export class RemoveLayer implements Action { constructor(public itemLayer: IItemLayer) { } } +export class ClearLayers implements Action { + readonly type = CLEARLAYERS; + + constructor() { } +} + export class LoadBaseLayers implements Action { readonly type = LOADBASELAYERS; @@ -256,6 +271,12 @@ export class SetReplaceUrl implements Action { constructor(public replaceUrl:boolean) {} } +export class SetFeatures implements Action { + readonly type = SETFEATURES; + + constructor(public features: Array) { } +} + export type Actions = SetMapState | Init | Clear @@ -278,6 +299,7 @@ export type Actions = SetMapState | SetTimeSpan | AddLayer | RemoveLayer + | ClearLayers | SetVisibility | SetOpacity | SetLayerIndex @@ -291,5 +313,7 @@ export type Actions = SetMapState | DoQuery | SetStyle | ShowLayerSwitcher - | SetReplaceUrl; + | SetReplaceUrl + | SetFeatures + | SetSelectedItemLayer; diff --git a/projects/common-map/src/fm-map/common-map-routing.module.ts b/projects/common-map/src/fm-map/common-map-routing.module.ts index dc30dff..7bd5811 100644 --- a/projects/common-map/src/fm-map/common-map-routing.module.ts +++ b/projects/common-map/src/fm-map/common-map-routing.module.ts @@ -8,6 +8,10 @@ const routes = [ path: '', component: MapComponent }, + { + path: ':xCenter/:yCenter/:zoom/:rotation/:baseLayer', + component: MapComponent + }, { path: ':xCenter/:yCenter/:zoom/:rotation/:baseLayer/:queryState', component: MapComponent diff --git a/projects/common-map/src/fm-map/components/map/map.component.html b/projects/common-map/src/fm-map/components/map/map.component.html index c7a11f3..f9895dc 100644 --- a/projects/common-map/src/fm-map/components/map/map.component.html +++ b/projects/common-map/src/fm-map/components/map/map.component.html @@ -19,9 +19,10 @@ period:period$|async, compassHeading:compassHeading$|async, styles:styles$|async, - selectedFeature:selectedFeature$|async + selectedFeature:selectedFeature$|async, + fullscreen:fullscreen$|async } as state"> - +
@@ -38,7 +39,7 @@ -
+
@@ -46,9 +47,11 @@
- - -
+
+ +
+ +
@@ -65,7 +68,10 @@
Cannot find tag {{state.queryState?.tags}}
-
+
+ + + diff --git a/projects/common-map/src/fm-map/components/map/map.component.scss b/projects/common-map/src/fm-map/components/map/map.component.scss index 79bf62d..41a86b4 100644 --- a/projects/common-map/src/fm-map/components/map/map.component.scss +++ b/projects/common-map/src/fm-map/components/map/map.component.scss @@ -49,6 +49,10 @@ aol-map { position:absolute;width:100%;height:calc(100vh + 4rem);} .control-container { position: absolute; right: 1em; + bottom: 8.1em; +} + +.fullscreen .control-container { bottom: 5em; } diff --git a/projects/common-map/src/fm-map/components/map/map.component.ts b/projects/common-map/src/fm-map/components/map/map.component.ts index 0368cf3..62b3f81 100644 --- a/projects/common-map/src/fm-map/components/map/map.component.ts +++ b/projects/common-map/src/fm-map/components/map/map.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit,NgZone } from '@angular/core'; +import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit,NgZone,ElementRef } from '@angular/core'; import { Location } from '@angular/common'; import { Observable, Subject, Subscription, from,of ,EMPTY } from 'rxjs'; import { withLatestFrom, switchMap,skip } from 'rxjs/operators'; @@ -79,10 +79,13 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit { public overlayLayersCollapsed: boolean = true; public extent$: Observable = this.store.select(mapReducers.selectGetExtent); public styles$:Observable = this.store.select(mapReducers.selectGetStyles); + public fullscreen$: Observable = this.store.select(commonReducers.selectGetFullScreen); private lastUrl = ""; private initialized: boolean = false; + public noContent: boolean = false; @ViewChild('map') map; + @ViewChild('contentDiv') contentDiv: ElementRef; constructor(private store: Store, private route: ActivatedRoute, @@ -162,7 +165,7 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit { this.store.dispatch(new mapActions.DoQuery(queryState)); } - ngOnInit() { + ngOnInit() { this.initialized = false; console.debug("Init"); this.store.dispatch(new mapActions.Clear()); @@ -237,23 +240,27 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit { ngAfterViewInit() { console.debug("View init"); + if(this.route.children.length == 0) { + this.noContent=true; + } + this.initCustomStyles(); // url to state let urlMapState = this.getMapStateFromUrl(this.route.snapshot.paramMap); let urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap); - if(urlQueryState && urlMapState) { + if(urlQueryState && urlMapState && this.noContent) { this.store.dispatch(new mapActions.SetState(urlMapState,urlQueryState)); window.localStorage.setItem("FarmMapsCommonMap_mapState",this.serializeMapState(urlMapState)); - } else if(urlQueryState) { + } else if(urlQueryState && this.noContent) { this.store.dispatch(new mapActions.SetQueryState(urlQueryState)); } else { this.store.dispatch(new mapActions.SetReplaceUrl(true)); } this.paramSub = this.route.paramMap.pipe(withLatestFrom(this.state$),switchMap(([params,state]) => { - if(this.initialized) { + if(this.initialized && this.noContent) { let urlQueryState = this.getQueryStateFromUrl(params); if( this.serializeService.serialize(state.queryState) != this.serializeService.serialize(urlQueryState)) { return of(new mapActions.SetState(state.mapState,urlQueryState)); @@ -318,24 +325,25 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit { } replaceUrl(mapState: IMapState, queryState: IQueryState, replace: boolean = true) { - - let newMapState = this.serializeMapState(mapState); - let newQueryState = this.serializeService.serialize(queryState); - let currentMapState = this.serializeMapState(this.getMapStateFromUrl(this.route.snapshot.paramMap)); - let urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap); - let currentQueryState = urlQueryState==null?"":this.serializeService.serialize(urlQueryState); - if(mapState.baseLayerCode!="" && ((newMapState!= currentMapState) || (newQueryState!=currentQueryState))) { - let parts =["."]; - parts.push(mapState.xCenter.toFixed(5)); - parts.push(mapState.yCenter.toFixed(5)); - parts.push( mapState.zoom.toFixed(0)); - parts.push( mapState.rotation.toFixed(2)); - parts.push(mapState.baseLayerCode); - parts.push( this.serializeService.serialize(queryState)); - - console.debug("Replace url",parts); - this.router.navigate(parts, { replaceUrl: replace,relativeTo:this.route.parent }); - } + if(this.noContent) { + let newMapState = this.serializeMapState(mapState); + let newQueryState = this.serializeService.serialize(queryState); + let currentMapState = this.serializeMapState(this.getMapStateFromUrl(this.route.snapshot.paramMap)); + let urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap); + let currentQueryState = urlQueryState==null?"":this.serializeService.serialize(urlQueryState); + if(mapState.baseLayerCode!="" && ((newMapState!= currentMapState) || (newQueryState!=currentQueryState))) { + let parts =["."]; + parts.push(mapState.xCenter.toFixed(5)); + parts.push(mapState.yCenter.toFixed(5)); + parts.push( mapState.zoom.toFixed(0)); + parts.push( mapState.rotation.toFixed(2)); + parts.push(mapState.baseLayerCode); + parts.push( this.serializeService.serialize(queryState)); + + console.debug("Replace url",parts); + this.router.navigate(parts, { replaceUrl: replace,relativeTo:this.route.parent }); + } + } } handleOnMoveEnd(event) { diff --git a/projects/common-map/src/fm-map/effects/map.effects.ts b/projects/common-map/src/fm-map/effects/map.effects.ts index 0e14bc1..a8f69f7 100644 --- a/projects/common-map/src/fm-map/effects/map.effects.ts +++ b/projects/common-map/src/fm-map/effects/map.effects.ts @@ -150,6 +150,19 @@ export class MapEffects { return actions; })); + @Effect() + zoomToExtent2$: Observable = this.actions$.pipe( + ofType(mapActions.SETFEATURES), + map((action: mapActions.SetFeatures) => { + let extent = createEmpty(); + if (extent) { + for (let f of action.features) { + extend(extent, (f as Feature).getGeometry().getExtent()); + } + } + return new mapActions.SetExtent(extent); + })); + @Effect() hideMenu$: Observable = this.actions$.pipe( ofType(mapActions.STARTSEARCHSUCCESS), @@ -181,6 +194,14 @@ export class MapEffects { } )); + @Effect() + selectItemSuccessSetLayer$: Observable = this.actions$.pipe( + ofType(mapActions.SELECTITEMSUCCESS), + map((action:mapActions.SelectItemSuccess) => + new mapActions.SetSelectedItemLayer(action.item) + ) + ); + @Effect() selectItemSuccess$: Observable = this.actions$.pipe( ofType(mapActions.SELECTITEMSUCCESS), diff --git a/projects/common-map/src/fm-map/reducers/map.reducer.ts b/projects/common-map/src/fm-map/reducers/map.reducer.ts index e6e34d1..695fb97 100644 --- a/projects/common-map/src/fm-map/reducers/map.reducer.ts +++ b/projects/common-map/src/fm-map/reducers/map.reducer.ts @@ -138,6 +138,12 @@ export function reducer(state = initialState, action: mapActions.Actions | commo inSearch:false }); } + case mapActions.SETFEATURES: { + let a = action as mapActions.SetFeatures; + return tassign(state, { + features: a.features + }); + } case mapActions.SELECTFEATURE: { let a = action as mapActions.SelectFeature; return tassign(state, { @@ -157,18 +163,10 @@ export function reducer(state = initialState, action: mapActions.Actions | commo } case mapActions.SELECTITEMSUCCESS: { let a = action as mapActions.SelectItemSuccess; - var itemLayer = null; - if (a.item && "vnd.farmmaps.itemtype.layer,vnd.farmmaps.itemtype.shape.processed,vnd.farmmaps.itemtype.geotiff.processed".indexOf(a.item.itemType) >=0 ) { - itemLayer = new ItemLayer(a.item); - itemLayer.layerIndex = a.item.data.layers?a.item.data.layers[0].index:-1; - } else if (a.item && a.item.itemType == "vnd.farmmaps.itemtype.temporal") { - itemLayer = new TemporalItemLayer(a.item); - } return tassign(state, { inSearch:false, selectedItem: a.item, parentItem: a.parentItem, - selectedItemLayer: itemLayer, panelVisible: a.item != null, clearEnabled: a.item != null, searchCollapsed: false, @@ -176,6 +174,20 @@ export function reducer(state = initialState, action: mapActions.Actions | commo queryState: tassign(state.queryState, {itemCode:a.item ? a.item.code:null}) }); } + case mapActions.SETSELECTEDITEMLAYER: { + let a = action as mapActions.SetSelectedItemLayer; + var itemLayer = null; + if (a.item && "vnd.farmmaps.itemtype.layer,vnd.farmmaps.itemtype.shape.processed,vnd.farmmaps.itemtype.geotiff.processed".indexOf(a.item.itemType) >=0 ) { + itemLayer = new ItemLayer(a.item); + itemLayer.layerIndex = a.layerIndex>=0?a.layerIndex:a.item.data.layers?a.item.data.layers[0].index:-1; + } else if (a.item && a.item.itemType == "vnd.farmmaps.itemtype.temporal") { + itemLayer = new TemporalItemLayer(a.item); + } + + return tassign(state, { + selectedItemLayer: itemLayer, + }); + } case mapActions.SELECTTEMPORALITEMSSUCCESS:{ let a = action as mapActions.SelectTemporalItemsSuccess; let selectedItemLayer=tassign(state.selectedItemLayer) as TemporalItemLayer; @@ -316,7 +328,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo case mapActions.SETEXTENT: { let a = action as mapActions.SetExtent; return tassign(state, { extent: a.extent }); - } + } case mapActions.ADDLAYER: { let a = action as mapActions.AddLayer; let itemLayers = state.overlayLayers.slice(0); @@ -343,6 +355,9 @@ export function reducer(state = initialState, action: mapActions.Actions | commo newLayers.splice(i, 1); return tassign(state, { overlayLayers: newLayers, selectedOverlayLayer: selectedOverlayLayer }); } + case mapActions.CLEARLAYERS: { + return tassign(state, {overlayLayers: [], selectedOverlayLayer: null}); + } case mapActions.SETVISIBILITY: { let a = action as mapActions.SetVisibility; let newLayers = state.overlayLayers.slice(0); @@ -436,7 +451,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo let a = action as mapActions.SelectOverlayLayer; return tassign(state, { selectedOverlayLayer: a.itemLayer }); } - + case mapActions.CLEAR: { let newQueryState = tassign(state.queryState, { query: null, tags: null, itemCode: null, parentCode: null, itemType: null }); return tassign(state, { @@ -468,7 +483,7 @@ export function reducer(state = initialState, action: mapActions.Actions | commo case mapActions.SETREPLACEURL: { let a= action as mapActions.SetReplaceUrl; return tassign(state,{replaceUrl:a.replaceUrl}); - } + } default: { return state; } diff --git a/projects/common/src/fm/actions/app-common.actions.ts b/projects/common/src/fm/actions/app-common.actions.ts index 7e1ebc5..2407bd0 100644 --- a/projects/common/src/fm/actions/app-common.actions.ts +++ b/projects/common/src/fm/actions/app-common.actions.ts @@ -60,6 +60,8 @@ export const TOGGLEMENU = '[AppCommon] ToggleMenu'; export const TOGGLEACCOUNTMENU = '[AppCommon] ToggleAccountMenu'; +export const TOGGLEAPPMENU = '[AppCommon] ToggleAppMenu'; + export const SETMENUVISIBLE = '[AppCommon] SetMenuVisible'; export const ONLINE = '[AppCommon] Online'; @@ -283,6 +285,12 @@ export class ToggleAccountMenu implements Action { constructor() { } } +export class ToggleAppMenu implements Action { + readonly type = TOGGLEAPPMENU; + + constructor() { } +} + export class SetMenuVisible implements Action { readonly type = SETMENUVISIBLE; @@ -346,6 +354,7 @@ export type Actions = OpenModal | CloseAll | Online | Offline - | SetPageMode; + | SetPageMode + | ToggleAppMenu; diff --git a/projects/common/src/fm/common.module.ts b/projects/common/src/fm/common.module.ts index 2bbebee..bd08884 100644 --- a/projects/common/src/fm/common.module.ts +++ b/projects/common/src/fm/common.module.ts @@ -55,6 +55,7 @@ import * as commonEffects from './effects/app-common.effects'; import { SecureOAuthStorage} from './shared/secureOAuthStorage'; import { GradientComponent } from './components/gradient/gradient.component'; import { GradientSelectComponent } from './components/gradient-select/gradient-select.component'; +import { AppMenuComponent } from './components/app-menu/app-menu.component'; export { SafePipe, @@ -126,7 +127,8 @@ export { HasClaimDirective, UserMenuComponent, GradientComponent, - GradientSelectComponent + GradientSelectComponent, + AppMenuComponent ], exports: [ NgbModule, diff --git a/projects/common/src/fm/components/app-menu/app-menu.component.html b/projects/common/src/fm/components/app-menu/app-menu.component.html new file mode 100644 index 0000000..e06bc26 --- /dev/null +++ b/projects/common/src/fm/components/app-menu/app-menu.component.html @@ -0,0 +1,9 @@ +
+ +
+ diff --git a/projects/common/src/fm/components/app-menu/app-menu.component.scss b/projects/common/src/fm/components/app-menu/app-menu.component.scss new file mode 100644 index 0000000..d750974 --- /dev/null +++ b/projects/common/src/fm/components/app-menu/app-menu.component.scss @@ -0,0 +1,48 @@ +.menu-button { + background-color: gray; + display: inline-block; + width: 2.5em; + height: 2.5em; + line-height: 2.5em; + text-align: center; + font-size: 1rem; + position: relative; +} + +div.menu-button > span { + color:white; +} + +.menu { + max-height: 100vh; + //transition: max-height 0.2s; + overflow: hidden; + box-shadow: 0 0 20px rgba(0,0,0,.3); + position: absolute; + top: 3rem; + right:0; + background-color: #fff; + border-radius: 0.25rem; + padding: 0.5rem; +} + +.card { + padding:0.5rem; + min-width: 10rem; +} + +.card-body { + text-align: left; +} + +.hidden { + max-height: 0; +} + +.menu.hidden { + padding: 0; +} + +.menu-button.hidden { + overflow: hidden; +} \ No newline at end of file diff --git a/projects/common/src/fm/components/app-menu/app-menu.component.spec.ts b/projects/common/src/fm/components/app-menu/app-menu.component.spec.ts new file mode 100644 index 0000000..bc5b5eb --- /dev/null +++ b/projects/common/src/fm/components/app-menu/app-menu.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AppMenuComponent } from './app-menu.component'; + +describe('AppMenuComponent', () => { + let component: AppMenuComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ AppMenuComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AppMenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/projects/common/src/fm/components/app-menu/app-menu.component.ts b/projects/common/src/fm/components/app-menu/app-menu.component.ts new file mode 100644 index 0000000..4df1e62 --- /dev/null +++ b/projects/common/src/fm/components/app-menu/app-menu.component.ts @@ -0,0 +1,29 @@ +import { Component, OnInit, Input } from '@angular/core'; + + +import { IUser } from '../../models/user'; +import {Store} from '@ngrx/store'; +import * as appReducers from '../../reducers/app-common.reducer'; +import * as appActions from '../../actions/app-common.actions'; + +@Component({ + selector: 'fm-app-menu', + templateUrl: './app-menu.component.html', + styleUrls: ['./app-menu.component.scss'] +}) +export class AppMenuComponent implements OnInit { + + @Input() user:IUser; + @Input() showMenu:boolean; + + constructor(private store: Store) { } + + ngOnInit(): void { + } + + toggle(event:MouseEvent) { + event.stopPropagation(); + this.store.dispatch(new appActions.ToggleAppMenu()); + } + +} diff --git a/projects/common/src/fm/components/app/app.component.html b/projects/common/src/fm/components/app/app.component.html index f2e7713..dc37080 100644 --- a/projects/common/src/fm/components/app/app.component.html +++ b/projects/common/src/fm/components/app/app.component.html @@ -31,7 +31,8 @@
- + +
diff --git a/projects/common/src/fm/components/app/app.component.scss b/projects/common/src/fm/components/app/app.component.scss index 8a93d54..b3c08b2 100644 --- a/projects/common/src/fm/components/app/app.component.scss +++ b/projects/common/src/fm/components/app/app.component.scss @@ -34,8 +34,8 @@ body { background: #f1f1f1; line-height: 18px; user-select:none;font-family: Lat } .app { - width:100vw; - height:100vh; + width:100%; + height:100%; } .app > .navbar { @@ -124,3 +124,8 @@ body { background: #f1f1f1; line-height: 18px; user-select:none;font-family: Lat .online { max-height:0em; } + +fm-app-menu,fm-user-menu { + display: inline-block; + margin-left: 1rem; +} diff --git a/projects/common/src/fm/components/app/app.component.ts b/projects/common/src/fm/components/app/app.component.ts index a8894c0..f11fbff 100644 --- a/projects/common/src/fm/components/app/app.component.ts +++ b/projects/common/src/fm/components/app/app.component.ts @@ -42,6 +42,7 @@ export class AppComponent implements OnInit, OnDestroy { public routeLoading: Observable = this.store$.select(appReducers.selectGetRouteLoading); public menuVisible: Observable = this.store$.select(appReducers.SelectGetMenuVisible); public accountMenuVisible: Observable = this.store$.select(appReducers.SelectGetAccountMenuVisible); + public appMenuVisible: Observable = this.store$.select(appReducers.SelectGetAppMenuVisible); public user: Observable = this.store$.select(appReducers.SelectGetUser); public isPageMode: Observable = this.store$.select(appReducers.SelectGetIsPageMode); @Input() showUploadProgress: boolean = true; @@ -101,6 +102,10 @@ export class AppComponent implements OnInit, OnDestroy { return action; } + async loadItemTypes() { + await this.itemTypeService$.load(this.appConfig$) + } + ngOnInit() { this.InstallRouteEventHandler(); this.InstallEventServiceEventHandler(); @@ -108,7 +113,7 @@ export class AppComponent implements OnInit, OnDestroy { this.InstallHealthCheck(); //load item types - this.itemTypeService$.load(this.appConfig$) + this.loadItemTypes(); } @HostListener('document:keyup', ['$event']) diff --git a/projects/common/src/fm/components/auth-callback/auth-callback.component.ts b/projects/common/src/fm/components/auth-callback/auth-callback.component.ts index 74ccef2..a51b5f0 100644 --- a/projects/common/src/fm/components/auth-callback/auth-callback.component.ts +++ b/projects/common/src/fm/components/auth-callback/auth-callback.component.ts @@ -13,6 +13,8 @@ export class AuthCallbackComponent { oauthService$.loadDiscoveryDocument().then(() => { oauthService$.tryLoginCodeFlow().then(() => { router$.navigateByUrl((oauthService$.state && oauthService$.state!="")?decodeURIComponent(oauthService$.state):""); + }).catch(() => { + router$.navigateByUrl("/"); }); }) } diff --git a/projects/common/src/fm/components/user-menu/user-menu.component.scss b/projects/common/src/fm/components/user-menu/user-menu.component.scss index 08f8d40..69e3945 100644 --- a/projects/common/src/fm/components/user-menu/user-menu.component.scss +++ b/projects/common/src/fm/components/user-menu/user-menu.component.scss @@ -7,7 +7,6 @@ text-align: center; font-size: 1rem; position: relative; - display: inline-block; } div.menu-button > span { diff --git a/projects/common/src/fm/models/user.ts b/projects/common/src/fm/models/user.ts index fd41620..e7c8144 100644 --- a/projects/common/src/fm/models/user.ts +++ b/projects/common/src/fm/models/user.ts @@ -3,4 +3,14 @@ export interface IUser { name?: string; email?: string; claims: any; -} + firstName?: string; + lastName?: string; + address?: string; + postalCode?: string; + city?: string; + country?: string; + phone?: string; + mobile?: string; + organisation?: string; + cocNumber?: string; +} \ 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 795c797..b2f561b 100644 --- a/projects/common/src/fm/reducers/app-common.reducer.ts +++ b/projects/common/src/fm/reducers/app-common.reducer.ts @@ -21,6 +21,7 @@ export interface State { userPackages: IPackages, userSettingsRoot: IItem, accountMenuVisible: boolean, + appMenuVisible: boolean, isOnline: boolean, isPageMode:boolean } @@ -37,6 +38,7 @@ export const initialState: State = { userPackages: {}, userSettingsRoot: null, accountMenuVisible: false, + appMenuVisible: false, isOnline: true, isPageMode: true } @@ -95,17 +97,20 @@ export function reducer(state = initialState, action: appCommonActions.Actions ) }); } case appCommonActions.TOGGLEMENU: { - return tassign(state, { menuVisible: !state.menuVisible,accountMenuVisible:!state.menuVisible?false:state.accountMenuVisible }); + return tassign(state, { menuVisible: !state.menuVisible,accountMenuVisible:!state.menuVisible?false:state.accountMenuVisible,appMenuVisible:!state.menuVisible?false:state.appMenuVisible }); } case appCommonActions.TOGGLEACCOUNTMENU: { - return tassign(state, { accountMenuVisible: !state.accountMenuVisible }); + return tassign(state, { accountMenuVisible: !state.accountMenuVisible,appMenuVisible:false }); + } + case appCommonActions.TOGGLEAPPMENU: { + return tassign(state, { appMenuVisible: !state.appMenuVisible,accountMenuVisible:false }); } case appCommonActions.ESCAPE: { - return tassign(state, { menuVisible: false,accountMenuVisible:false }); + return tassign(state, { menuVisible: false,accountMenuVisible:false,appMenuVisible: false }); } case appCommonActions.SETMENUVISIBLE: { let a = action as appCommonActions.SetMenuVisible; - return tassign(state, { menuVisible: a.visible,accountMenuVisible:a.visible?false:state.accountMenuVisible }); + return tassign(state, { menuVisible: a.visible,accountMenuVisible:a.visible?false:state.accountMenuVisible,appMenuVisible:a.visible?false:state.appMenuVisible }); } case appCommonActions.INITUSERPACKAGESSUCCESS:{ let a = action as appCommonActions.InitUserPackagesSuccess; @@ -124,7 +129,7 @@ export function reducer(state = initialState, action: appCommonActions.Actions ) return tassign(state,{user:null,initialized:false}); } case appCommonActions.CLOSEALL: { - return tassign(state,{accountMenuVisible:false,menuVisible:false }); + return tassign(state,{accountMenuVisible:false,appMenuVisible:false, menuVisible:false }); } case appCommonActions.ONLINE:{ return tassign(state,{isOnline:true}); @@ -153,6 +158,7 @@ export const getUser = (state: State) => state.user; export const getUserPackages = (state: State) => state.userPackages; export const getUserSettingsRoot = (state: State) => state.userSettingsRoot; export const getAccountMenuVisible = (state: State) => state.accountMenuVisible; +export const getAppMenuVisible = (state: State) => state.appMenuVisible; export const getIsOnline = (state: State) => state.isOnline; export const getIsPageMode = (state: State) => state.isPageMode; @@ -169,6 +175,7 @@ export const SelectGetUser = createSelector(selectAppCommonState,getUser); export const SelectGetUserPackages = createSelector(selectAppCommonState,getUserPackages); export const SelectGetUserSettingsRoot = createSelector(selectAppCommonState,getUserSettingsRoot); export const SelectGetAccountMenuVisible = createSelector(selectAppCommonState,getAccountMenuVisible); +export const SelectGetAppMenuVisible = createSelector(selectAppCommonState,getAppMenuVisible); export const SelectGetIsOnline = createSelector(selectAppCommonState,getIsOnline); export const SelectGetIsPageMode = createSelector(selectAppCommonState,getIsPageMode); diff --git a/projects/common/src/fm/services/user.service.ts b/projects/common/src/fm/services/user.service.ts index fd9e668..d6c7add 100644 --- a/projects/common/src/fm/services/user.service.ts +++ b/projects/common/src/fm/services/user.service.ts @@ -18,4 +18,8 @@ export class UserService { getCurrentUser(): Observable { return this.httpClient.get(`${this.ApiEndpoint()}/api/v1/currentuser`); } + + updateCurrentUser(user: IUser): Observable { + return this.httpClient.put(`${this.ApiEndpoint()}/api/v1/currentuser`, user); + } } diff --git a/src/configuration.json b/src/configuration.json index 2241895..f9a46d6 100644 --- a/src/configuration.json +++ b/src/configuration.json @@ -1,9 +1,9 @@ { - "issuer": "https://accounts.farmmaps.awtest.nl", + "issuer": "https://accounts.test.farmmaps.eu", "clientId": "farmmapsdev", - "audience": "https://farmmaps.awtest.nl/", + "audience": "https://test.farmmaps.eu/", "requireHttps": true, - "apiEndPoint": "https://farmmaps.awtest.nl", + "apiEndPoint": "https://test.farmmaps.eu", "grantType":"code" } \ No newline at end of file