Compare commits

..

No commits in common. "80fec7ccaa5f2f552c2ef6866f4a77b0044c5a02" and "03284d26dd7cc42c49dfbb6fc1c9b615b15aeaeb" have entirely different histories.

28 changed files with 82 additions and 496 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -23,30 +23,6 @@
content: "b"; 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-face {
font-family: "FarmMaps"; font-family: "FarmMaps";
src: url("./FMIconFont.woff") format("woff"), /* Modern Browsers */ src: url("./FMIconFont.woff") format("woff"), /* Modern Browsers */

View File

@ -16,7 +16,6 @@ export const STARTSEARCHSUCCESS = '[Map] StartSearchSuccess';
export const SELECTFEATURE = '[Map] SelectFeature'; export const SELECTFEATURE = '[Map] SelectFeature';
export const SELECTITEM = '[Map] SelectItem'; export const SELECTITEM = '[Map] SelectItem';
export const SELECTITEMSUCCESS = '[Map] SelectItemSuccess'; export const SELECTITEMSUCCESS = '[Map] SelectItemSuccess';
export const SETSELECTEDITEMLAYER = '[Map] SetSelectedItemLayer';
export const SELECTTEMPORALITEMSSUCCESS = '[Map] SelectTemporalItemsSuccess'; export const SELECTTEMPORALITEMSSUCCESS = '[Map] SelectTemporalItemsSuccess';
export const NEXTTEMPORAL = '[Map] NextTemporal'; export const NEXTTEMPORAL = '[Map] NextTemporal';
export const PREVIOUSTEMPORAL = '[Map] PreviousTemporal'; export const PREVIOUSTEMPORAL = '[Map] PreviousTemporal';
@ -33,7 +32,6 @@ export const SETVISIBILITY = '[Map] SetVisibility';
export const SETOPACITY = '[Map] SetOpacity'; export const SETOPACITY = '[Map] SetOpacity';
export const SETLAYERINDEX = '[Map] SetLayerIndex'; export const SETLAYERINDEX = '[Map] SetLayerIndex';
export const REMOVELAYER = '[Map] RemoveLayer'; export const REMOVELAYER = '[Map] RemoveLayer';
export const CLEARLAYERS = '[Map] ClearLayers';
export const LOADBASELAYERS = '[Map] LoadLayers'; export const LOADBASELAYERS = '[Map] LoadLayers';
export const LOADBASELAYERSSUCCESS = '[Map] LoadLayersSuccess'; export const LOADBASELAYERSSUCCESS = '[Map] LoadLayersSuccess';
export const SELECTBASELAYER = '[Map] SelectBaseLayers'; export const SELECTBASELAYER = '[Map] SelectBaseLayers';
@ -44,7 +42,6 @@ export const SETSTYLE = '[Map] SetStyle';
export const SHOWLAYERSWITCHER = '[Map] ShowLayerSwitcher'; export const SHOWLAYERSWITCHER = '[Map] ShowLayerSwitcher';
export const CLEAR = '[Map] Clear'; export const CLEAR = '[Map] Clear';
export const SETREPLACEURL = '[Map] SetReplaceUrl'; export const SETREPLACEURL = '[Map] SetReplaceUrl';
export const SETFEATURES = '[Map] SetFeatures'
export class Clear implements Action { export class Clear implements Action {
readonly type = CLEAR; readonly type = CLEAR;
@ -183,12 +180,6 @@ export class AddLayer implements Action {
constructor(public item:IItem,public layerIndex=-1) { } 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 { export class SetVisibility implements Action {
readonly type = SETVISIBILITY; readonly type = SETVISIBILITY;
@ -213,12 +204,6 @@ export class RemoveLayer implements Action {
constructor(public itemLayer: IItemLayer) { } constructor(public itemLayer: IItemLayer) { }
} }
export class ClearLayers implements Action {
readonly type = CLEARLAYERS;
constructor() { }
}
export class LoadBaseLayers implements Action { export class LoadBaseLayers implements Action {
readonly type = LOADBASELAYERS; readonly type = LOADBASELAYERS;
@ -271,12 +256,6 @@ export class SetReplaceUrl implements Action {
constructor(public replaceUrl:boolean) {} constructor(public replaceUrl:boolean) {}
} }
export class SetFeatures implements Action {
readonly type = SETFEATURES;
constructor(public features: Array<Feature>) { }
}
export type Actions = SetMapState export type Actions = SetMapState
| Init | Init
| Clear | Clear
@ -299,7 +278,6 @@ export type Actions = SetMapState
| SetTimeSpan | SetTimeSpan
| AddLayer | AddLayer
| RemoveLayer | RemoveLayer
| ClearLayers
| SetVisibility | SetVisibility
| SetOpacity | SetOpacity
| SetLayerIndex | SetLayerIndex
@ -313,7 +291,5 @@ export type Actions = SetMapState
| DoQuery | DoQuery
| SetStyle | SetStyle
| ShowLayerSwitcher | ShowLayerSwitcher
| SetReplaceUrl | SetReplaceUrl;
| SetFeatures
| SetSelectedItemLayer;

View File

@ -8,10 +8,6 @@ const routes = [
path: '', path: '',
component: MapComponent component: MapComponent
}, },
{
path: ':xCenter/:yCenter/:zoom/:rotation/:baseLayer',
component: MapComponent
},
{ {
path: ':xCenter/:yCenter/:zoom/:rotation/:baseLayer/:queryState', path: ':xCenter/:yCenter/:zoom/:rotation/:baseLayer/:queryState',
component: MapComponent component: MapComponent

View File

@ -129,7 +129,7 @@ export class ItemLayersComponent extends LayerGroupComponent implements OnChange
source: new VectorTileSource({ source: new VectorTileSource({
maxZoom: rt.maxzoom, maxZoom: rt.maxzoom,
minZoom: rt.minzoom, minZoom: rt.minzoom,
format: new MVT({idProperty:'OBJECTID'}), format: new MVT(),
url: `${this._apiEndPoint}/api/v1/items/${item.code}/vectortiles/{z}/{x}/{y}.pbf?v=${Date.parse(item.updated)}` url: `${this._apiEndPoint}/api/v1/items/${item.code}/vectortiles/{z}/{x}/{y}.pbf?v=${Date.parse(item.updated)}`
}), }),
style: (feature) => { style: (feature) => {
@ -196,7 +196,7 @@ export class ItemLayersComponent extends LayerGroupComponent implements OnChange
}); });
} }
if(l.minzoom) { if(l.minzoom) {
layer.setMinZoom(l.minzoom); layer.setMinZoom(14);
} }
if(l.maxzoom) { if(l.maxzoom) {
layer.setMaxZoom(l.maxzoom); layer.setMaxZoom(l.maxzoom);
@ -219,9 +219,12 @@ export class ItemLayersComponent extends LayerGroupComponent implements OnChange
return new style.Style( return new style.Style(
{ {
fill: new style.Fill({
color: 'red'
}),
stroke: new style.Stroke({ stroke: new style.Stroke({
color: 'red', color: 'red',
width: 2 width: 1.25
}) })
} }
); );
@ -389,14 +392,14 @@ export class ItemLayersComponent extends LayerGroupComponent implements OnChange
//if(event.type === 'click' && !this.onFeatureSelected.observers.length) return; //if(event.type === 'click' && !this.onFeatureSelected.observers.length) return;
//if(event.type === 'pointermode' && !this.onFeatureHover.observers.length) return; //if(event.type === 'pointermode' && !this.onFeatureHover.observers.length) return;
if(this.itemLayer && this.itemLayer.layer) { if(this.itemLayer && this.itemLayer.layer) {
this.selectedFeatures = {};
this.itemLayer.layer.getFeatures(event.pixel).then((features) => { this.itemLayer.layer.getFeatures(event.pixel).then((features) => {
this.selectedFeatures = {};
if(!features.length) return; if(!features.length) return;
let fid = features[0].getId(); let fid = features[0].getId();
this.selectedFeatures[fid] = features[0]; this.selectedFeatures[fid] = features[0];
console.debug(features[0]); console.debug(features[0]);
if(this.selectionLayer) this.selectionLayer.changed();
}) })
if(this.selectionLayer) this.selectionLayer.changed();
} }
} }

View File

@ -19,10 +19,9 @@
period:period$|async, period:period$|async,
compassHeading:compassHeading$|async, compassHeading:compassHeading$|async,
styles:styles$|async, styles:styles$|async,
selectedFeature:selectedFeature$|async, selectedFeature:selectedFeature$|async
fullscreen:fullscreen$|async
} as state"> } as state">
<aol-map #map (moveEnd)="handleOnMoveEnd($event)" (click)="handleOnMouseDown($event)" [ngClass]="{'panel-visible':state.panelVisible,'fullscreen':state.fullscreen}" class="map"> <aol-map #map (moveEnd)="handleOnMoveEnd($event)" (click)="handleOnMouseDown($event)" [ngClass]="{'panel-visible':state.panelVisible}" class="map">
<div> <div>
</div> </div>
@ -39,7 +38,7 @@
<fm-map-item-source-vector [styles]="state.styles" [features]="state.features" (onFeatureSelected)="handleFeatureClick($event)" (onFeatureHover)="handleFeatureHover($event)" [selectedFeature]="state.selectedFeature" [selectedItem]="state.selectedItem"></fm-map-item-source-vector> <fm-map-item-source-vector [styles]="state.styles" [features]="state.features" (onFeatureSelected)="handleFeatureClick($event)" (onFeatureHover)="handleFeatureHover($event)" [selectedFeature]="state.selectedFeature" [selectedItem]="state.selectedItem"></fm-map-item-source-vector>
</aol-layer-vector> </aol-layer-vector>
<!-- <fm-map-gps-location [position]="state.position" [headingTolerance]="20" [showHeading]="true" [heading]="state.compassHeading"></fm-map-gps-location> --> <!-- <fm-map-gps-location [position]="state.position" [headingTolerance]="20" [showHeading]="true" [heading]="state.compassHeading"></fm-map-gps-location> -->
<div class="control-container" > <div class="control-container">
<router-outlet name="map-controls"></router-outlet> <router-outlet name="map-controls"></router-outlet>
<fm-map-layer-switcher></fm-map-layer-switcher> <fm-map-layer-switcher></fm-map-layer-switcher>
<fm-map-pan-to-location [position]="state.position" [mapState]="state.mapState" [animate]="true"></fm-map-pan-to-location> <fm-map-pan-to-location [position]="state.position" [mapState]="state.mapState" [animate]="true"></fm-map-pan-to-location>
@ -47,11 +46,9 @@
</div> </div>
<fm-map-file-drop-target [parentCode]="state.parentCode" (onFileDropped)="handleFileDropped($event)"></fm-map-file-drop-target> <fm-map-file-drop-target [parentCode]="state.parentCode" (onFileDropped)="handleFileDropped($event)"></fm-map-file-drop-target>
</aol-map> </aol-map>
<div *ngIf="noContent"> <fm-map-map-search #mapSearch [openedModalName]="state.openedModalName" (onOpenModal)="handleOpenModal($event)" (onCloseModal)="handleCloseModal()" [ngClass]="{'menuVisible':state.menuVisible}" (onToggleMenu)="handleToggleMenu($event)" (onSearchCollapse)="handleSearchCollapse($event)" (onSearchExpand)="handleSearchExpand($event)" [collapsed]="state.searchCollapsed" [searchMinified]="state.searchMinified" (onSearch)="handleSearch($event)" (onClear)="handleClearSearch($event)" [filterOptions]="state.queryState" [clearEnabled]="state.clearEnabled" [period]="state.period"></fm-map-map-search>
<fm-map-map-search #mapSearch [openedModalName]="state.openedModalName" (onOpenModal)="handleOpenModal($event)" (onCloseModal)="handleCloseModal()" [ngClass]="{'menuVisible':state.menuVisible}" (onToggleMenu)="handleToggleMenu($event)" (onSearchCollapse)="handleSearchCollapse($event)" (onSearchExpand)="handleSearchExpand($event)" [collapsed]="state.searchCollapsed" [searchMinified]="state.searchMinified" (onSearch)="handleSearch($event)" (onClear)="handleClearSearch($event)" [filterOptions]="state.queryState" [clearEnabled]="state.clearEnabled" [period]="state.period"></fm-map-map-search> <fm-side-panel [resizeable]="true" [visible]="state.panelVisible" [collapsed]="state.panelCollapsed" [collapsable]="false">
</div> <div class="panel-wrapper">
<fm-side-panel [resizeable]="true" [visible]="state.panelVisible && noContent" [collapsed]="state.panelCollapsed" [collapsable]="false">
<div class="panel-wrapper" *ngIf="noContent">
<div class="panel-top bg-secondary" *ngIf="!(state.searchMinified)"> <div class="panel-top bg-secondary" *ngIf="!(state.searchMinified)">
</div> </div>
<div class="panel-bottom"> <div class="panel-bottom">
@ -70,9 +67,6 @@
</div> </div>
</div> </div>
</fm-side-panel> </fm-side-panel>
<fm-side-panel [resizeable]="true" [visible]="!noContent">
<router-outlet></router-outlet>
</fm-side-panel>
</ng-container> </ng-container>

View File

@ -49,10 +49,6 @@ aol-map { position:absolute;width:100%;height:calc(100vh + 4rem);}
.control-container { .control-container {
position: absolute; position: absolute;
right: 1em; right: 1em;
bottom: 8.1em;
}
.fullscreen .control-container {
bottom: 5em; bottom: 5em;
} }

View File

@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit,NgZone,ElementRef } from '@angular/core'; import { Component, OnInit, OnDestroy, HostListener, ViewChild, AfterViewInit,NgZone } from '@angular/core';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { Observable, Subject, Subscription, from,of ,EMPTY } from 'rxjs'; import { Observable, Subject, Subscription, from,of ,EMPTY } from 'rxjs';
import { withLatestFrom, switchMap,skip } from 'rxjs/operators'; import { withLatestFrom, switchMap,skip } from 'rxjs/operators';
@ -79,13 +79,10 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
public overlayLayersCollapsed: boolean = true; public overlayLayersCollapsed: boolean = true;
public extent$: Observable<Extent> = this.store.select(mapReducers.selectGetExtent); public extent$: Observable<Extent> = this.store.select(mapReducers.selectGetExtent);
public styles$:Observable<IStyles> = this.store.select(mapReducers.selectGetStyles); public styles$:Observable<IStyles> = this.store.select(mapReducers.selectGetStyles);
public fullscreen$: Observable<boolean> = this.store.select(commonReducers.selectGetFullScreen);
private lastUrl = ""; private lastUrl = "";
private initialized: boolean = false; private initialized: boolean = false;
public noContent: boolean = false;
@ViewChild('map') map; @ViewChild('map') map;
@ViewChild('contentDiv') contentDiv: ElementRef;
constructor(private store: Store<mapReducers.State | commonReducers.State>, constructor(private store: Store<mapReducers.State | commonReducers.State>,
private route: ActivatedRoute, private route: ActivatedRoute,
@ -240,27 +237,23 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
ngAfterViewInit() { ngAfterViewInit() {
console.debug("View init"); console.debug("View init");
if(this.route.children.length == 0) {
this.noContent=true;
}
this.initCustomStyles(); this.initCustomStyles();
// url to state // url to state
let urlMapState = this.getMapStateFromUrl(this.route.snapshot.paramMap); let urlMapState = this.getMapStateFromUrl(this.route.snapshot.paramMap);
let urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap); let urlQueryState = this.getQueryStateFromUrl(this.route.snapshot.paramMap);
if(urlQueryState && urlMapState && this.noContent) { if(urlQueryState && urlMapState) {
this.store.dispatch(new mapActions.SetState(urlMapState,urlQueryState)); this.store.dispatch(new mapActions.SetState(urlMapState,urlQueryState));
window.localStorage.setItem("FarmMapsCommonMap_mapState",this.serializeMapState(urlMapState)); window.localStorage.setItem("FarmMapsCommonMap_mapState",this.serializeMapState(urlMapState));
} else if(urlQueryState && this.noContent) { } else if(urlQueryState) {
this.store.dispatch(new mapActions.SetQueryState(urlQueryState)); this.store.dispatch(new mapActions.SetQueryState(urlQueryState));
} else { } else {
this.store.dispatch(new mapActions.SetReplaceUrl(true)); this.store.dispatch(new mapActions.SetReplaceUrl(true));
} }
this.paramSub = this.route.paramMap.pipe(withLatestFrom(this.state$),switchMap(([params,state]) => { this.paramSub = this.route.paramMap.pipe(withLatestFrom(this.state$),switchMap(([params,state]) => {
if(this.initialized && this.noContent) { if(this.initialized) {
let urlQueryState = this.getQueryStateFromUrl(params); let urlQueryState = this.getQueryStateFromUrl(params);
if( this.serializeService.serialize(state.queryState) != this.serializeService.serialize(urlQueryState)) { if( this.serializeService.serialize(state.queryState) != this.serializeService.serialize(urlQueryState)) {
return of(new mapActions.SetState(state.mapState,urlQueryState)); return of(new mapActions.SetState(state.mapState,urlQueryState));
@ -325,24 +318,23 @@ export class MapComponent implements OnInit, OnDestroy,AfterViewInit {
} }
replaceUrl(mapState: IMapState, queryState: IQueryState, replace: boolean = true) { replaceUrl(mapState: IMapState, queryState: IQueryState, replace: boolean = true) {
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); let newMapState = this.serializeMapState(mapState);
this.router.navigate(parts, { replaceUrl: replace,relativeTo:this.route.parent }); 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 });
} }
} }

View File

@ -150,19 +150,6 @@ export class MapEffects {
return actions; return actions;
})); }));
@Effect()
zoomToExtent2$: Observable<Action> = 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() @Effect()
hideMenu$: Observable<Action> = this.actions$.pipe( hideMenu$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.STARTSEARCHSUCCESS), ofType(mapActions.STARTSEARCHSUCCESS),
@ -194,14 +181,6 @@ export class MapEffects {
} }
)); ));
@Effect()
selectItemSuccessSetLayer$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.SELECTITEMSUCCESS),
map((action:mapActions.SelectItemSuccess) =>
new mapActions.SetSelectedItemLayer(action.item)
)
);
@Effect() @Effect()
selectItemSuccess$: Observable<Action> = this.actions$.pipe( selectItemSuccess$: Observable<Action> = this.actions$.pipe(
ofType(mapActions.SELECTITEMSUCCESS), ofType(mapActions.SELECTITEMSUCCESS),

View File

@ -138,12 +138,6 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
inSearch:false inSearch:false
}); });
} }
case mapActions.SETFEATURES: {
let a = action as mapActions.SetFeatures;
return tassign(state, {
features: a.features
});
}
case mapActions.SELECTFEATURE: { case mapActions.SELECTFEATURE: {
let a = action as mapActions.SelectFeature; let a = action as mapActions.SelectFeature;
return tassign(state, { return tassign(state, {
@ -163,10 +157,18 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
} }
case mapActions.SELECTITEMSUCCESS: { case mapActions.SELECTITEMSUCCESS: {
let a = action as 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, { return tassign(state, {
inSearch:false, inSearch:false,
selectedItem: a.item, selectedItem: a.item,
parentItem: a.parentItem, parentItem: a.parentItem,
selectedItemLayer: itemLayer,
panelVisible: a.item != null, panelVisible: a.item != null,
clearEnabled: a.item != null, clearEnabled: a.item != null,
searchCollapsed: false, searchCollapsed: false,
@ -174,20 +176,6 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
queryState: tassign(state.queryState, {itemCode:a.item ? a.item.code:null}) 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:{ case mapActions.SELECTTEMPORALITEMSSUCCESS:{
let a = action as mapActions.SelectTemporalItemsSuccess; let a = action as mapActions.SelectTemporalItemsSuccess;
let selectedItemLayer=tassign(state.selectedItemLayer) as TemporalItemLayer; let selectedItemLayer=tassign(state.selectedItemLayer) as TemporalItemLayer;
@ -355,9 +343,6 @@ export function reducer(state = initialState, action: mapActions.Actions | commo
newLayers.splice(i, 1); newLayers.splice(i, 1);
return tassign(state, { overlayLayers: newLayers, selectedOverlayLayer: selectedOverlayLayer }); return tassign(state, { overlayLayers: newLayers, selectedOverlayLayer: selectedOverlayLayer });
} }
case mapActions.CLEARLAYERS: {
return tassign(state, {overlayLayers: [], selectedOverlayLayer: null});
}
case mapActions.SETVISIBILITY: { case mapActions.SETVISIBILITY: {
let a = action as mapActions.SetVisibility; let a = action as mapActions.SetVisibility;
let newLayers = state.overlayLayers.slice(0); let newLayers = state.overlayLayers.slice(0);

View File

@ -60,8 +60,6 @@ export const TOGGLEMENU = '[AppCommon] ToggleMenu';
export const TOGGLEACCOUNTMENU = '[AppCommon] ToggleAccountMenu'; export const TOGGLEACCOUNTMENU = '[AppCommon] ToggleAccountMenu';
export const TOGGLEAPPMENU = '[AppCommon] ToggleAppMenu';
export const SETMENUVISIBLE = '[AppCommon] SetMenuVisible'; export const SETMENUVISIBLE = '[AppCommon] SetMenuVisible';
export const ONLINE = '[AppCommon] Online'; export const ONLINE = '[AppCommon] Online';
@ -285,12 +283,6 @@ export class ToggleAccountMenu implements Action {
constructor() { } constructor() { }
} }
export class ToggleAppMenu implements Action {
readonly type = TOGGLEAPPMENU;
constructor() { }
}
export class SetMenuVisible implements Action { export class SetMenuVisible implements Action {
readonly type = SETMENUVISIBLE; readonly type = SETMENUVISIBLE;
@ -354,7 +346,6 @@ export type Actions = OpenModal
| CloseAll | CloseAll
| Online | Online
| Offline | Offline
| SetPageMode | SetPageMode;
| ToggleAppMenu;

View File

@ -55,7 +55,6 @@ import * as commonEffects from './effects/app-common.effects';
import { SecureOAuthStorage} from './shared/secureOAuthStorage'; import { SecureOAuthStorage} from './shared/secureOAuthStorage';
import { GradientComponent } from './components/gradient/gradient.component'; import { GradientComponent } from './components/gradient/gradient.component';
import { GradientSelectComponent } from './components/gradient-select/gradient-select.component'; import { GradientSelectComponent } from './components/gradient-select/gradient-select.component';
import { AppMenuComponent } from './components/app-menu/app-menu.component';
export { export {
SafePipe, SafePipe,
@ -127,8 +126,7 @@ export {
HasClaimDirective, HasClaimDirective,
UserMenuComponent, UserMenuComponent,
GradientComponent, GradientComponent,
GradientSelectComponent, GradientSelectComponent
AppMenuComponent
], ],
exports: [ exports: [
NgbModule, NgbModule,

View File

@ -1,9 +0,0 @@
<div>
<div (click)="toggle($event)" class="rounded-circle menu-button hidden" [ngClass]="{'hidden':!user}">
<span i18n-title title="Apps"><i class="fm fm-app-menu" aria-hidden="true"></i></span>
<div class="menu hidden" [ngClass]="{'hidden':!showMenu}">
<router-outlet name="app-menu"></router-outlet>
</div>
</div>
</div>

View File

@ -1,48 +0,0 @@
.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;
}

View File

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppMenuComponent } from './app-menu.component';
describe('AppMenuComponent', () => {
let component: AppMenuComponent;
let fixture: ComponentFixture<AppMenuComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AppMenuComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AppMenuComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,29 +0,0 @@
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<appReducers.State>) { }
ngOnInit(): void {
}
toggle(event:MouseEvent) {
event.stopPropagation();
this.store.dispatch(new appActions.ToggleAppMenu());
}
}

View File

@ -31,7 +31,6 @@
<fm-resumable-file-upload></fm-resumable-file-upload> <fm-resumable-file-upload></fm-resumable-file-upload>
</ng-container> </ng-container>
<div class="user-menu apponly"> <div class="user-menu apponly">
<fm-app-menu [user]="user|async" [showMenu]="appMenuVisible|async"></fm-app-menu>
<fm-user-menu [user]="user|async" [showMenu]="accountMenuVisible|async"></fm-user-menu> <fm-user-menu [user]="user|async" [showMenu]="accountMenuVisible|async"></fm-user-menu>
</div> </div>
<div class="healthstatus-container online apponly" [ngClass]="{'online' :(isOnline|async)}"> <div class="healthstatus-container online apponly" [ngClass]="{'online' :(isOnline|async)}">

View File

@ -34,8 +34,8 @@ body { background: #f1f1f1; line-height: 18px; user-select:none;font-family: Lat
} }
.app { .app {
width:100%; width:100vw;
height:100%; height:100vh;
} }
.app > .navbar { .app > .navbar {
@ -124,8 +124,3 @@ body { background: #f1f1f1; line-height: 18px; user-select:none;font-family: Lat
.online { .online {
max-height:0em; max-height:0em;
} }
fm-app-menu,fm-user-menu {
display: inline-block;
margin-left: 1rem;
}

View File

@ -42,7 +42,6 @@ export class AppComponent implements OnInit, OnDestroy {
public routeLoading: Observable<boolean> = this.store$.select(appReducers.selectGetRouteLoading); public routeLoading: Observable<boolean> = this.store$.select(appReducers.selectGetRouteLoading);
public menuVisible: Observable<boolean> = this.store$.select(appReducers.SelectGetMenuVisible); public menuVisible: Observable<boolean> = this.store$.select(appReducers.SelectGetMenuVisible);
public accountMenuVisible: Observable<boolean> = this.store$.select(appReducers.SelectGetAccountMenuVisible); public accountMenuVisible: Observable<boolean> = this.store$.select(appReducers.SelectGetAccountMenuVisible);
public appMenuVisible: Observable<boolean> = this.store$.select(appReducers.SelectGetAppMenuVisible);
public user: Observable<IUser> = this.store$.select(appReducers.SelectGetUser); public user: Observable<IUser> = this.store$.select(appReducers.SelectGetUser);
public isPageMode: Observable<boolean> = this.store$.select(appReducers.SelectGetIsPageMode); public isPageMode: Observable<boolean> = this.store$.select(appReducers.SelectGetIsPageMode);
@Input() showUploadProgress: boolean = true; @Input() showUploadProgress: boolean = true;
@ -102,10 +101,6 @@ export class AppComponent implements OnInit, OnDestroy {
return action; return action;
} }
async loadItemTypes() {
await this.itemTypeService$.load(this.appConfig$)
}
ngOnInit() { ngOnInit() {
this.InstallRouteEventHandler(); this.InstallRouteEventHandler();
this.InstallEventServiceEventHandler(); this.InstallEventServiceEventHandler();
@ -113,7 +108,7 @@ export class AppComponent implements OnInit, OnDestroy {
this.InstallHealthCheck(); this.InstallHealthCheck();
//load item types //load item types
this.loadItemTypes(); this.itemTypeService$.load(this.appConfig$)
} }
@HostListener('document:keyup', ['$event']) @HostListener('document:keyup', ['$event'])

View File

@ -13,8 +13,6 @@ export class AuthCallbackComponent {
oauthService$.loadDiscoveryDocument().then(() => { oauthService$.loadDiscoveryDocument().then(() => {
oauthService$.tryLoginCodeFlow().then(() => { oauthService$.tryLoginCodeFlow().then(() => {
router$.navigateByUrl((oauthService$.state && oauthService$.state!="")?decodeURIComponent(oauthService$.state):""); router$.navigateByUrl((oauthService$.state && oauthService$.state!="")?decodeURIComponent(oauthService$.state):"");
}).catch(() => {
router$.navigateByUrl("/");
}); });
}) })
} }

View File

@ -7,6 +7,7 @@
text-align: center; text-align: center;
font-size: 1rem; font-size: 1rem;
position: relative; position: relative;
display: inline-block;
} }
div.menu-button > span { div.menu-button > span {

View File

@ -3,14 +3,4 @@ export interface IUser {
name?: string; name?: string;
email?: string; email?: string;
claims: any; claims: any;
firstName?: string;
lastName?: string;
address?: string;
postalCode?: string;
city?: string;
country?: string;
phone?: string;
mobile?: string;
organisation?: string;
cocNumber?: string;
} }

View File

@ -21,7 +21,6 @@ export interface State {
userPackages: IPackages, userPackages: IPackages,
userSettingsRoot: IItem, userSettingsRoot: IItem,
accountMenuVisible: boolean, accountMenuVisible: boolean,
appMenuVisible: boolean,
isOnline: boolean, isOnline: boolean,
isPageMode:boolean isPageMode:boolean
} }
@ -38,7 +37,6 @@ export const initialState: State = {
userPackages: {}, userPackages: {},
userSettingsRoot: null, userSettingsRoot: null,
accountMenuVisible: false, accountMenuVisible: false,
appMenuVisible: false,
isOnline: true, isOnline: true,
isPageMode: true isPageMode: true
} }
@ -97,20 +95,17 @@ export function reducer(state = initialState, action: appCommonActions.Actions )
}); });
} }
case appCommonActions.TOGGLEMENU: { case appCommonActions.TOGGLEMENU: {
return tassign(state, { menuVisible: !state.menuVisible,accountMenuVisible:!state.menuVisible?false:state.accountMenuVisible,appMenuVisible:!state.menuVisible?false:state.appMenuVisible }); return tassign(state, { menuVisible: !state.menuVisible,accountMenuVisible:!state.menuVisible?false:state.accountMenuVisible });
} }
case appCommonActions.TOGGLEACCOUNTMENU: { case appCommonActions.TOGGLEACCOUNTMENU: {
return tassign(state, { accountMenuVisible: !state.accountMenuVisible,appMenuVisible:false }); return tassign(state, { accountMenuVisible: !state.accountMenuVisible });
}
case appCommonActions.TOGGLEAPPMENU: {
return tassign(state, { appMenuVisible: !state.appMenuVisible,accountMenuVisible:false });
} }
case appCommonActions.ESCAPE: { case appCommonActions.ESCAPE: {
return tassign(state, { menuVisible: false,accountMenuVisible:false,appMenuVisible: false }); return tassign(state, { menuVisible: false,accountMenuVisible:false });
} }
case appCommonActions.SETMENUVISIBLE: { case appCommonActions.SETMENUVISIBLE: {
let a = action as appCommonActions.SetMenuVisible; let a = action as appCommonActions.SetMenuVisible;
return tassign(state, { menuVisible: a.visible,accountMenuVisible:a.visible?false:state.accountMenuVisible,appMenuVisible:a.visible?false:state.appMenuVisible }); return tassign(state, { menuVisible: a.visible,accountMenuVisible:a.visible?false:state.accountMenuVisible });
} }
case appCommonActions.INITUSERPACKAGESSUCCESS:{ case appCommonActions.INITUSERPACKAGESSUCCESS:{
let a = action as appCommonActions.InitUserPackagesSuccess; let a = action as appCommonActions.InitUserPackagesSuccess;
@ -129,7 +124,7 @@ export function reducer(state = initialState, action: appCommonActions.Actions )
return tassign(state,{user:null,initialized:false}); return tassign(state,{user:null,initialized:false});
} }
case appCommonActions.CLOSEALL: { case appCommonActions.CLOSEALL: {
return tassign(state,{accountMenuVisible:false,appMenuVisible:false, menuVisible:false }); return tassign(state,{accountMenuVisible:false,menuVisible:false });
} }
case appCommonActions.ONLINE:{ case appCommonActions.ONLINE:{
return tassign(state,{isOnline:true}); return tassign(state,{isOnline:true});
@ -158,7 +153,6 @@ export const getUser = (state: State) => state.user;
export const getUserPackages = (state: State) => state.userPackages; export const getUserPackages = (state: State) => state.userPackages;
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 getIsOnline = (state: State) => state.isOnline; export const getIsOnline = (state: State) => state.isOnline;
export const getIsPageMode = (state: State) => state.isPageMode; export const getIsPageMode = (state: State) => state.isPageMode;
@ -175,7 +169,6 @@ export const SelectGetUser = createSelector(selectAppCommonState,getUser);
export const SelectGetUserPackages = createSelector(selectAppCommonState,getUserPackages); export const SelectGetUserPackages = createSelector(selectAppCommonState,getUserPackages);
export const SelectGetUserSettingsRoot = createSelector(selectAppCommonState,getUserSettingsRoot); export const SelectGetUserSettingsRoot = createSelector(selectAppCommonState,getUserSettingsRoot);
export const SelectGetAccountMenuVisible = createSelector(selectAppCommonState,getAccountMenuVisible); export const SelectGetAccountMenuVisible = createSelector(selectAppCommonState,getAccountMenuVisible);
export const SelectGetAppMenuVisible = createSelector(selectAppCommonState,getAppMenuVisible);
export const SelectGetIsOnline = createSelector(selectAppCommonState,getIsOnline); export const SelectGetIsOnline = createSelector(selectAppCommonState,getIsOnline);
export const SelectGetIsPageMode = createSelector(selectAppCommonState,getIsPageMode); export const SelectGetIsPageMode = createSelector(selectAppCommonState,getIsPageMode);

View File

@ -18,8 +18,4 @@ export class UserService {
getCurrentUser(): Observable<IUser> { getCurrentUser(): Observable<IUser> {
return this.httpClient.get<IUser>(`${this.ApiEndpoint()}/api/v1/currentuser`); return this.httpClient.get<IUser>(`${this.ApiEndpoint()}/api/v1/currentuser`);
} }
updateCurrentUser(user: IUser): Observable<IUser> {
return this.httpClient.put<IUser>(`${this.ApiEndpoint()}/api/v1/currentuser`, user);
}
} }

View File

@ -1,9 +1,9 @@
{ {
"issuer": "https://accounts.test.farmmaps.eu", "issuer": "https://accounts.farmmaps.awtest.nl",
"clientId": "farmmapsdev", "clientId": "farmmapsdev",
"audience": "https://test.farmmaps.eu/", "audience": "https://farmmaps.awtest.nl/",
"requireHttps": true, "requireHttps": true,
"apiEndPoint": "https://test.farmmaps.eu", "apiEndPoint": "https://farmmaps.awtest.nl",
"grantType":"code" "grantType":"code"
} }