Compare commits
	
		
			2 Commits
		
	
	
		
			16db063339
			...
			efe38aba62
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | efe38aba62 | ||
|  | 7bd5dada2b | 
| @@ -1,11 +1,11 @@ | |||||||
| # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers | ||||||
| # For additional information regarding the format and rule options, please see: | # For additional information regarding the format and rule options, please see: | ||||||
| # https://github.com/browserslist/browserslist#queries | # https://github.com/browserslist/browserslist#queries | ||||||
| # | # | ||||||
| # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed | ||||||
| 
 | 
 | ||||||
| > 0.5% | > 0.5% | ||||||
| last 2 versions | last 2 versions | ||||||
| Firefox ESR | Firefox ESR | ||||||
| not dead | not dead | ||||||
| not IE 9-11 | not IE 9-11 | ||||||
							
								
								
									
										6300
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6300
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										126
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,63 +1,63 @@ | |||||||
| { | { | ||||||
|   "name": "farmmaps-lib-app", |   "name": "farmmaps-lib-app", | ||||||
|   "version": "0.0.1", |   "version": "0.0.1", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "ng": "ng", |     "ng": "ng", | ||||||
|     "start": "ng serve", |     "start": "ng serve", | ||||||
|     "build": "ng build", |     "build": "ng build", | ||||||
|     "test": "ng test", |     "test": "ng test", | ||||||
|     "lint": "ng lint", |     "lint": "ng lint", | ||||||
|     "e2e": "ng e2e" |     "e2e": "ng e2e" | ||||||
|   }, |   }, | ||||||
|   "private": true, |   "private": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@angular/animations": "~7.2.0", |     "@angular/animations": "~8.2.14", | ||||||
|     "@angular/common": "~7.2.0", |     "@angular/common": "~8.2.14", | ||||||
|     "@angular/compiler": "~7.2.0", |     "@angular/compiler": "~8.2.14", | ||||||
|     "@angular/core": "~7.2.0", |     "@angular/core": "~8.2.14", | ||||||
|     "@angular/forms": "~7.2.0", |     "@angular/forms": "~8.2.14", | ||||||
|     "@angular/platform-browser": "~7.2.0", |     "@angular/platform-browser": "~8.2.14", | ||||||
|     "@angular/platform-browser-dynamic": "~7.2.0", |     "@angular/platform-browser-dynamic": "~8.2.14", | ||||||
|     "@angular/router": "~7.2.0", |     "@angular/router": "~8.2.14", | ||||||
|     "@aspnet/signalr": "^1.1.4", |     "@aspnet/signalr": "^1.1.4", | ||||||
|     "@farmmaps/common": ">=0.0.1-prerelease.77 <0.0.1", |     "@farmmaps/common": ">=0.0.1-prerelease.77 <0.0.1", | ||||||
|     "@farmmaps/common-map": ">=0.0.1-prerelease.77 <0.0.1", |     "@farmmaps/common-map": ">=0.0.1-prerelease.77 <0.0.1", | ||||||
|     "@ng-bootstrap/ng-bootstrap": "^4.2.1", |     "@ng-bootstrap/ng-bootstrap": "^4.2.1", | ||||||
|     "@ngrx/effects": "^7.2.0", |     "@ngrx/effects": "^7.2.0", | ||||||
|     "@ngrx/router-store": "^7.2.0", |     "@ngrx/router-store": "^7.2.0", | ||||||
|     "@ngrx/store": "^7.2.0", |     "@ngrx/store": "^7.2.0", | ||||||
|     "bootstrap": "^4.3.1", |     "bootstrap": "^4.3.1", | ||||||
|     "font-awesome": "^4.7.0", |     "font-awesome": "^4.7.0", | ||||||
|     "core-js": "^2.5.4", |     "core-js": "^2.5.4", | ||||||
|     "ngrx-store-localstorage": "^8.0.0", |     "ngrx-store-localstorage": "^8.0.0", | ||||||
|     "resumablejs": "^1.1.0", |     "resumablejs": "^1.1.0", | ||||||
|     "rxjs": "~6.3.3", |     "rxjs": "~6.5.3", | ||||||
|     "tassign": "^1.0.0", |     "tassign": "^1.0.0", | ||||||
|     "zone.js": "~0.8.26" |     "zone.js": "~0.9.1" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@angular-devkit/build-angular": "~0.13.0", |     "@angular-devkit/build-angular": "~0.803.19", | ||||||
|     "@angular-devkit/build-ng-packagr": "~0.13.0", |     "@angular-devkit/build-ng-packagr": "~0.803.19", | ||||||
|     "@angular/cli": "~7.3.8", |     "@angular/cli": "~8.3.19", | ||||||
|     "@angular/compiler-cli": "~7.2.0", |     "@angular/compiler-cli": "~8.2.14", | ||||||
|     "@angular/language-service": "~7.2.0", |     "@angular/language-service": "~8.2.14", | ||||||
|     "@types/node": "~8.9.4", |     "@types/node": "~8.9.4", | ||||||
|     "@types/jasmine": "~2.8.8", |     "@types/jasmine": "~2.8.8", | ||||||
|     "@types/jasminewd2": "~2.0.3", |     "@types/jasminewd2": "~2.0.3", | ||||||
|     "codelyzer": "~4.5.0", |     "codelyzer": "^5.0.1", | ||||||
|     "jasmine-core": "~2.99.1", |     "jasmine-core": "~2.99.1", | ||||||
|     "jasmine-spec-reporter": "~4.2.1", |     "jasmine-spec-reporter": "~4.2.1", | ||||||
|     "karma": "~4.0.0", |     "karma": "~4.0.0", | ||||||
|     "karma-chrome-launcher": "~2.2.0", |     "karma-chrome-launcher": "~2.2.0", | ||||||
|     "karma-coverage-istanbul-reporter": "~2.0.1", |     "karma-coverage-istanbul-reporter": "~2.0.1", | ||||||
|     "karma-jasmine": "~1.1.2", |     "karma-jasmine": "~1.1.2", | ||||||
|     "karma-jasmine-html-reporter": "^0.2.2", |     "karma-jasmine-html-reporter": "^0.2.2", | ||||||
|     "ng-packagr": "^4.2.0", |     "ng-packagr": "^5.4.0", | ||||||
|     "protractor": "~5.4.0", |     "protractor": "~5.4.0", | ||||||
|     "ts-node": "~7.0.0", |     "ts-node": "~7.0.0", | ||||||
|     "tsickle": ">=0.34.0", |     "tsickle": "^0.37.0", | ||||||
|     "tslib": "^1.9.0", |     "tslib": "^1.9.0", | ||||||
|     "tslint": "~5.11.0", |     "tslint": "~5.11.0", | ||||||
|     "typescript": "~3.2.2" |     "typescript": "~3.5.3" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,68 +1,68 @@ | |||||||
| import { Component, OnInit, Input, ViewChild, ElementRef, OnChanges, SimpleChanges } from '@angular/core'; | import { Component, OnInit, Input, ViewChild, ElementRef, OnChanges, SimpleChanges } from '@angular/core'; | ||||||
| import { MapComponent } from 'ngx-openlayers'; | import { MapComponent } from 'ngx-openlayers'; | ||||||
| import Overlay from 'ol/Overlay'; | import Overlay from 'ol/Overlay'; | ||||||
| import { fromLonLat, toLonLat } from 'ol/proj'; | import { fromLonLat, toLonLat } from 'ol/proj'; | ||||||
|  |  | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-gps-location', |   selector: 'fm-map-gps-location', | ||||||
|   templateUrl: './gps-location.component.html', |   templateUrl: './gps-location.component.html', | ||||||
|   styleUrls: ['./gps-location.component.scss'] |   styleUrls: ['./gps-location.component.scss'] | ||||||
| }) | }) | ||||||
| export class GpsLocation  implements OnInit,OnChanges{ | export class GpsLocation  implements OnInit,OnChanges{ | ||||||
|  |  | ||||||
|   @Input() enable:boolean; |   @Input() enable:boolean; | ||||||
|   public instance: Overlay; |   public instance: Overlay; | ||||||
|   @Input() position: Position; |   @Input() position: Position; | ||||||
|   @Input() location: number[]=[0,0]; |   @Input() location: number[]=[0,0]; | ||||||
|   @Input() locationTolerance: number = 0; |   @Input() locationTolerance: number = 0; | ||||||
|   @Input() showHeading: boolean = false; |   @Input() showHeading: boolean = false; | ||||||
|   @Input() heading: number = 0; |   @Input() heading: number = 0; | ||||||
|   @Input() headingTolerance: number = 0; |   @Input() headingTolerance: number = 0; | ||||||
|   public locTolerancePixels: number = 0; |   public locTolerancePixels: number = 0; | ||||||
|   public path: string = ""; |   public path: string = ""; | ||||||
|   public rotate: string = ""; |   public rotate: string = ""; | ||||||
|   private resolution: number = 0; |   private resolution: number = 0; | ||||||
|   @ViewChild('location') locationElement: ElementRef; |   @ViewChild('location', { static: true }) locationElement: ElementRef; | ||||||
|  |  | ||||||
|   constructor(private map: MapComponent) { |   constructor(private map: MapComponent) { | ||||||
|      |      | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   recalcLocationTolerance() { |   recalcLocationTolerance() { | ||||||
|     this.locTolerancePixels = this.resolution >0? this.locationTolerance / this.resolution:0; |     this.locTolerancePixels = this.resolution >0? this.locationTolerance / this.resolution:0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     this.instance = new Overlay({ |     this.instance = new Overlay({ | ||||||
|       stopEvent:false, |       stopEvent:false, | ||||||
|       positioning: 'center-center', |       positioning: 'center-center', | ||||||
|       position: fromLonLat( this.location), |       position: fromLonLat( this.location), | ||||||
|       element: this.locationElement.nativeElement |       element: this.locationElement.nativeElement | ||||||
|     }); |     }); | ||||||
|     var x = Math.tan(this.headingTolerance * Math.PI / 180)*40; |     var x = Math.tan(this.headingTolerance * Math.PI / 180)*40; | ||||||
|     var y = Math.cos(this.headingTolerance * Math.PI / 180) * 40; |     var y = Math.cos(this.headingTolerance * Math.PI / 180) * 40; | ||||||
|     var y1 = Math.round(500 - y); |     var y1 = Math.round(500 - y); | ||||||
|     var x1 = Math.round(500 - x); |     var x1 = Math.round(500 - x); | ||||||
|     var y2 = Math.round(y1); |     var y2 = Math.round(y1); | ||||||
|     var x2 = Math.round(500 + x); |     var x2 = Math.round(500 + x); | ||||||
|     this.path = "M " + x2 + " " + y2 + " A 45 45,0,0,0, " + x1 + " " + y1 + " L 493 500 L 507 500 Z"; |     this.path = "M " + x2 + " " + y2 + " A 45 45,0,0,0, " + x1 + " " + y1 + " L 493 500 L 507 500 Z"; | ||||||
|     this.rotate = "rotate(" + Math.round(this.heading) + " 500 500)"; |     this.rotate = "rotate(" + Math.round(this.heading) + " 500 500)"; | ||||||
|     this.locTolerancePixels = this.locationTolerance; |     this.locTolerancePixels = this.locationTolerance; | ||||||
|     this.map.instance.addOverlay(this.instance); |     this.map.instance.addOverlay(this.instance); | ||||||
|     this.map.instance.getView().on('change:resolution', (evt) => { |     this.map.instance.getView().on('change:resolution', (evt) => { | ||||||
|       this.resolution = evt.target.get('resolution'); |       this.resolution = evt.target.get('resolution'); | ||||||
|       this.recalcLocationTolerance(); |       this.recalcLocationTolerance(); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnChanges(changes: SimpleChanges) { |   ngOnChanges(changes: SimpleChanges) { | ||||||
|     if (changes.position && this.instance) { |     if (changes.position && this.instance) { | ||||||
|       var p = changes.position.currentValue as Position; |       var p = changes.position.currentValue as Position; | ||||||
|       this.instance.setPosition(fromLonLat([p.coords.longitude, p.coords.latitude])); |       this.instance.setPosition(fromLonLat([p.coords.longitude, p.coords.latitude])); | ||||||
|       this.locationTolerance = p.coords.accuracy; |       this.locationTolerance = p.coords.accuracy; | ||||||
|       this.recalcLocationTolerance(); |       this.recalcLocationTolerance(); | ||||||
|       this.heading = p.coords.heading; |       this.heading = p.coords.heading; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,59 +1,59 @@ | |||||||
| import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | ||||||
| import { Feature } from 'ol'; | import { Feature } from 'ol'; | ||||||
| import { FeatureListComponent,AbstractFeatureListComponent } from '../feature-list/feature-list.component'; | import { FeatureListComponent,AbstractFeatureListComponent } from '../feature-list/feature-list.component'; | ||||||
| import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | ||||||
| import  {IQueryState } from '../../models/query.state'; | import  {IQueryState } from '../../models/query.state'; | ||||||
| import * as mapReducers from '../../reducers/map.reducer'; | import * as mapReducers from '../../reducers/map.reducer'; | ||||||
| import * as mapActions from '../../actions/map.actions'; | import * as mapActions from '../../actions/map.actions'; | ||||||
| import { Store } from '@ngrx/store'; | import { Store } from '@ngrx/store'; | ||||||
|  |  | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-feature-list-container', |   selector: 'fm-map-feature-list-container', | ||||||
|   templateUrl: './feature-list-container.component.html', |   templateUrl: './feature-list-container.component.html', | ||||||
|   styleUrls: ['./feature-list-container.component.scss'] |   styleUrls: ['./feature-list-container.component.scss'] | ||||||
| }) | }) | ||||||
| export class FeatureListContainerComponent { | export class FeatureListContainerComponent { | ||||||
|  |  | ||||||
|   constructor(private store: Store<mapReducers.State>,private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractFeatureListComponent) public featureLists: AbstractFeatureListComponent[] ) { |   constructor(private store: Store<mapReducers.State>,private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractFeatureListComponent) public featureLists: AbstractFeatureListComponent[] ) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Input() features: Array<Feature> |   @Input() features: Array<Feature> | ||||||
|   @Input() queryState: IQueryState; |   @Input() queryState: IQueryState; | ||||||
|  |  | ||||||
|   @ViewChild(WidgetHostDirective) widgetHost: WidgetHostDirective;  |   @ViewChild(WidgetHostDirective, { static: true }) widgetHost: WidgetHostDirective;  | ||||||
|  |  | ||||||
|   loadComponent(queryState:IQueryState) { |   loadComponent(queryState:IQueryState) { | ||||||
|     var componentFactory: ComponentFactory<AbstractFeatureListComponent> = this.componentFactoryResolver.resolveComponentFactory(FeatureListComponent); // default |     var componentFactory: ComponentFactory<AbstractFeatureListComponent> = this.componentFactoryResolver.resolveComponentFactory(FeatureListComponent); // default | ||||||
|     var selected = -1; |     var selected = -1; | ||||||
|     for (var i = 0; i < this.featureLists.length; i++) { |     for (var i = 0; i < this.featureLists.length; i++) { | ||||||
|       if (this.featureLists[i]['forItemType'] == queryState.itemType && this.featureLists[i]['forChild'] && queryState.parentCode && queryState.parentCode != "") { |       if (this.featureLists[i]['forItemType'] == queryState.itemType && this.featureLists[i]['forChild'] && queryState.parentCode && queryState.parentCode != "") { | ||||||
|         selected = i; |         selected = i; | ||||||
|         break; |         break; | ||||||
|       } else if (this.featureLists[i]['forItemType'] == queryState.itemType) { |       } else if (this.featureLists[i]['forItemType'] == queryState.itemType) { | ||||||
|         selected = i;         |         selected = i;         | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     if (selected >= 0) { |     if (selected >= 0) { | ||||||
|       componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.featureLists[i]['constructor'] as any); |       componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.featureLists[i]['constructor'] as any); | ||||||
|       if (this.featureLists[selected]['collapseSearch'] === true) { |       if (this.featureLists[selected]['collapseSearch'] === true) { | ||||||
|         this.store.dispatch(new mapActions.CollapseSearch()); |         this.store.dispatch(new mapActions.CollapseSearch()); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     const viewContainerRef = this.widgetHost.viewContainerRef; |     const viewContainerRef = this.widgetHost.viewContainerRef; | ||||||
|     viewContainerRef.clear(); |     viewContainerRef.clear(); | ||||||
|  |  | ||||||
|     const componentRef = viewContainerRef.createComponent(componentFactory); |     const componentRef = viewContainerRef.createComponent(componentFactory); | ||||||
|     (<AbstractFeatureListComponent>componentRef.instance).features = this.features; |     (<AbstractFeatureListComponent>componentRef.instance).features = this.features; | ||||||
|     (<AbstractFeatureListComponent>componentRef.instance).queryState = this.queryState; |     (<AbstractFeatureListComponent>componentRef.instance).queryState = this.queryState; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnChanges(changes: SimpleChanges) { |   ngOnChanges(changes: SimpleChanges) { | ||||||
|     if (changes["features"] && changes["features"].currentValue) { |     if (changes["features"] && changes["features"].currentValue) { | ||||||
|       if (this.queryState) { |       if (this.queryState) { | ||||||
|         this.loadComponent(this.queryState); |         this.loadComponent(this.queryState); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,43 +1,43 @@ | |||||||
| import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | ||||||
| import { Feature } from 'ol'; | import { Feature } from 'ol'; | ||||||
| import { AbstractFeatureListFeatureComponent,FeatureListFeatureComponent } from '../feature-list-feature/feature-list-feature.component'; | import { AbstractFeatureListFeatureComponent,FeatureListFeatureComponent } from '../feature-list-feature/feature-list-feature.component'; | ||||||
| import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | ||||||
|  |  | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-feature-list-feature-container', |   selector: 'fm-map-feature-list-feature-container', | ||||||
|   template: ` |   template: ` | ||||||
|               <div> |               <div> | ||||||
|                  <ng-template fm-map-widget-host></ng-template> |                  <ng-template fm-map-widget-host></ng-template> | ||||||
|               </div> |               </div> | ||||||
|             ` |             ` | ||||||
| }) | }) | ||||||
| export class FeatureListFeatureContainerComponent { | export class FeatureListFeatureContainerComponent { | ||||||
|  |  | ||||||
|   constructor(private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractFeatureListFeatureComponent) public featureLists: AbstractFeatureListFeatureComponent[] ) { |   constructor(private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractFeatureListFeatureComponent) public featureLists: AbstractFeatureListFeatureComponent[] ) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Input() feature: Feature; |   @Input() feature: Feature; | ||||||
|  |  | ||||||
|   @ViewChild(WidgetHostDirective) widgetHost: WidgetHostDirective;  |   @ViewChild(WidgetHostDirective, { static: true }) widgetHost: WidgetHostDirective;  | ||||||
|  |  | ||||||
|   loadComponent() { |   loadComponent() { | ||||||
|     var componentFactory: ComponentFactory<AbstractFeatureListFeatureComponent> = this.componentFactoryResolver.resolveComponentFactory(FeatureListFeatureComponent); // default |     var componentFactory: ComponentFactory<AbstractFeatureListFeatureComponent> = this.componentFactoryResolver.resolveComponentFactory(FeatureListFeatureComponent); // default | ||||||
|     for (var i = 0; i < this.featureLists.length; i++) { |     for (var i = 0; i < this.featureLists.length; i++) { | ||||||
|       if (this.featureLists[i]['forItemType'] == this.feature.get("itemType")) { |       if (this.featureLists[i]['forItemType'] == this.feature.get("itemType")) { | ||||||
|         componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.featureLists[i]['constructor'] as any); |         componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.featureLists[i]['constructor'] as any); | ||||||
|       } |       } | ||||||
|     }     |     }     | ||||||
|     const viewContainerRef = this.widgetHost.viewContainerRef; |     const viewContainerRef = this.widgetHost.viewContainerRef; | ||||||
|     viewContainerRef.clear(); |     viewContainerRef.clear(); | ||||||
|  |  | ||||||
|     const componentRef = viewContainerRef.createComponent(componentFactory); |     const componentRef = viewContainerRef.createComponent(componentFactory); | ||||||
|     (<AbstractFeatureListFeatureComponent>componentRef.instance).feature = this.feature; |     (<AbstractFeatureListFeatureComponent>componentRef.instance).feature = this.feature; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnChanges(changes: SimpleChanges) { |   ngOnChanges(changes: SimpleChanges) { | ||||||
|     if (changes["feature"] && changes["feature"].currentValue) { |     if (changes["feature"] && changes["feature"].currentValue) { | ||||||
|         this.loadComponent(); |         this.loadComponent(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,47 +1,47 @@ | |||||||
| import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | ||||||
| import { AbstractItemListItemComponent,ItemListItemComponent } from '../item-list-item/item-list-item.component'; | import { AbstractItemListItemComponent,ItemListItemComponent } from '../item-list-item/item-list-item.component'; | ||||||
| import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | ||||||
| import { IItem, IListItem } from '@farmmaps/common'; | import { IItem, IListItem } from '@farmmaps/common'; | ||||||
|  |  | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-item-list-item-container', |   selector: 'fm-map-item-list-item-container', | ||||||
|   template: ` |   template: ` | ||||||
|               <div style="height:100%"> |               <div style="height:100%"> | ||||||
|                  <ng-template fm-map-widget-host></ng-template> |                  <ng-template fm-map-widget-host></ng-template> | ||||||
|               </div> |               </div> | ||||||
|             ` |             ` | ||||||
| }) | }) | ||||||
| export class ItemListItemContainerComponent { | export class ItemListItemContainerComponent { | ||||||
|  |  | ||||||
|   constructor(private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractItemListItemComponent) public itemComponentList: AbstractItemListItemComponent[] ) { |   constructor(private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractItemListItemComponent) public itemComponentList: AbstractItemListItemComponent[] ) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Input() item: IListItem; |   @Input() item: IListItem; | ||||||
|  |  | ||||||
|   @ViewChild(WidgetHostDirective) widgetHost: WidgetHostDirective;  |   @ViewChild(WidgetHostDirective, { static: true }) widgetHost: WidgetHostDirective;  | ||||||
|  |  | ||||||
|   loadComponent() { |   loadComponent() { | ||||||
|     var componentFactory: ComponentFactory<AbstractItemListItemComponent> = this.componentFactoryResolver.resolveComponentFactory(ItemListItemComponent); // default |     var componentFactory: ComponentFactory<AbstractItemListItemComponent> = this.componentFactoryResolver.resolveComponentFactory(ItemListItemComponent); // default | ||||||
|     for (var i = 0; i < this.itemComponentList.length; i++) { |     for (var i = 0; i < this.itemComponentList.length; i++) { | ||||||
|       if (this.itemComponentList[i]['forItemType'] && |       if (this.itemComponentList[i]['forItemType'] && | ||||||
|         this.itemComponentList[i]['forItemType'].indexOf(this.item.itemType) >= 0 && |         this.itemComponentList[i]['forItemType'].indexOf(this.item.itemType) >= 0 && | ||||||
|         this.itemComponentList[i]['forSourceTask'] && |         this.itemComponentList[i]['forSourceTask'] && | ||||||
|         this.itemComponentList[i]['forSourceTask'].indexOf(this.item.sourceTask) >= 0 ) |         this.itemComponentList[i]['forSourceTask'].indexOf(this.item.sourceTask) >= 0 ) | ||||||
|       { |       { | ||||||
|         componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.itemComponentList[i]['constructor'] as any); |         componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.itemComponentList[i]['constructor'] as any); | ||||||
|       } |       } | ||||||
|     }     |     }     | ||||||
|     const viewContainerRef = this.widgetHost.viewContainerRef; |     const viewContainerRef = this.widgetHost.viewContainerRef; | ||||||
|     viewContainerRef.clear(); |     viewContainerRef.clear(); | ||||||
|  |  | ||||||
|     const componentRef = viewContainerRef.createComponent(componentFactory); |     const componentRef = viewContainerRef.createComponent(componentFactory); | ||||||
|     (<AbstractItemListItemComponent>componentRef.instance).item = this.item; |     (<AbstractItemListItemComponent>componentRef.instance).item = this.item; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnChanges(changes: SimpleChanges) { |   ngOnChanges(changes: SimpleChanges) { | ||||||
|     if (changes["item"] && changes["item"].currentValue) { |     if (changes["item"] && changes["item"].currentValue) { | ||||||
|         this.loadComponent(); |         this.loadComponent(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,179 +1,179 @@ | |||||||
| import { Component, Input, Output, OnInit, EventEmitter, SimpleChanges, OnChanges, ViewChild } from '@angular/core'; | import { Component, Input, Output, OnInit, EventEmitter, SimpleChanges, OnChanges, ViewChild } from '@angular/core'; | ||||||
| import { Observable ,  of } from 'rxjs'; | import { Observable ,  of } from 'rxjs'; | ||||||
| import { debounceTime,distinctUntilChanged,tap,switchMap,merge,catchError} from 'rxjs/operators'; | import { debounceTime,distinctUntilChanged,tap,switchMap,merge,catchError} from 'rxjs/operators'; | ||||||
| import { TypeaheadService, TimespanService } from '@farmmaps/common'; | import { TypeaheadService, TimespanService } from '@farmmaps/common'; | ||||||
| import { IQueryState } from '../../models/query.state'; | import { IQueryState } from '../../models/query.state'; | ||||||
| import { IPeriodState } from '../../models/period.state'; | import { IPeriodState } from '../../models/period.state'; | ||||||
| import { fillProperties } from '@angular/core/src/util/property'; | import { fillProperties } from '@angular/core/src/util/property'; | ||||||
| import { tassign } from 'tassign'; | import { tassign } from 'tassign'; | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-map-search', |   selector: 'fm-map-map-search', | ||||||
|   templateUrl: './map-search.component.html', |   templateUrl: './map-search.component.html', | ||||||
|   styleUrls: ['./map-search.component.scss'] |   styleUrls: ['./map-search.component.scss'] | ||||||
| }) | }) | ||||||
| export class MapSearchComponent { | export class MapSearchComponent { | ||||||
|  |  | ||||||
|   @ViewChild('searchText') searchText; |   @ViewChild('searchText', { static: true }) searchText; | ||||||
|   @Input() clearEnabled: boolean |   @Input() clearEnabled: boolean | ||||||
|   @Input() set collapsed(collapsed: boolean) { |   @Input() set collapsed(collapsed: boolean) { | ||||||
|     this.collapsedLocal = collapsed; |     this.collapsedLocal = collapsed; | ||||||
|     if (collapsed) this.searchText.nativeElement.blur(); |     if (collapsed) this.searchText.nativeElement.blur(); | ||||||
|   } |   } | ||||||
|   @Input() set searchMinified(minified: boolean) { |   @Input() set searchMinified(minified: boolean) { | ||||||
|     this.searchMinifiedLocal = minified; |     this.searchMinifiedLocal = minified; | ||||||
|   } |   } | ||||||
|   @Input() period: IPeriodState |   @Input() period: IPeriodState | ||||||
|   @Output() onSearch = new EventEmitter<IQueryState>(); |   @Output() onSearch = new EventEmitter<IQueryState>(); | ||||||
|   @Output() onClear = new EventEmitter<any>(); |   @Output() onClear = new EventEmitter<any>(); | ||||||
|   @Output() onSearchCollapse = new EventEmitter<any>(); |   @Output() onSearchCollapse = new EventEmitter<any>(); | ||||||
|   @Output() onSearchExpand = new EventEmitter<any>(); |   @Output() onSearchExpand = new EventEmitter<any>(); | ||||||
|   @Output() onToggleMenu = new EventEmitter<any>(); |   @Output() onToggleMenu = new EventEmitter<any>(); | ||||||
|   @Output() onOpenModal = new EventEmitter<string>(); |   @Output() onOpenModal = new EventEmitter<string>(); | ||||||
|   @Output() onCloseModal = new EventEmitter<any>(); |   @Output() onCloseModal = new EventEmitter<any>(); | ||||||
|   @Input() openedModalName: string; |   @Input() openedModalName: string; | ||||||
|   @Input() set filterOptions(filterOptions: IQueryState) { |   @Input() set filterOptions(filterOptions: IQueryState) { | ||||||
|     if (filterOptions && filterOptions.query && filterOptions.query.length > 0) { |     if (filterOptions && filterOptions.query && filterOptions.query.length > 0) { | ||||||
|       this.disabled = false; |       this.disabled = false; | ||||||
|     } else { |     } else { | ||||||
|       this.disabled = true; |       this.disabled = true; | ||||||
|     }        |     }        | ||||||
|     this.filterOptionsLocal = tassign(this.filterOptionsLocal, { tags: filterOptions.tags, query: filterOptions.query,bbox:filterOptions.bbox }); |     this.filterOptionsLocal = tassign(this.filterOptionsLocal, { tags: filterOptions.tags, query: filterOptions.query,bbox:filterOptions.bbox }); | ||||||
|     if (filterOptions.tags) { |     if (filterOptions.tags) { | ||||||
|       this.searchTextLocal = { name: filterOptions.tags }; |       this.searchTextLocal = { name: filterOptions.tags }; | ||||||
|     } else { |     } else { | ||||||
|       this.searchTextLocal = { name: filterOptions.query }; |       this.searchTextLocal = { name: filterOptions.query }; | ||||||
|     } |     } | ||||||
|     if (this.dateFilter) { |     if (this.dateFilter) { | ||||||
|       this.filterOptionsLocal.startDate = this.startDate; |       this.filterOptionsLocal.startDate = this.startDate; | ||||||
|       this.filterOptionsLocal.endDate = this.endDate; |       this.filterOptionsLocal.endDate = this.endDate; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public collapsedLocal: boolean = true; |   public collapsedLocal: boolean = true; | ||||||
|   public searchMinifiedLocal: boolean = false; |   public searchMinifiedLocal: boolean = false; | ||||||
|   public filterOptionsLocal: IQueryState; |   public filterOptionsLocal: IQueryState; | ||||||
|   private extent: number[]; |   private extent: number[]; | ||||||
|   public searchTextLocal: any; |   public searchTextLocal: any; | ||||||
|   public searchTextLocalOutput: string;  |   public searchTextLocalOutput: string;  | ||||||
|   public dateFilter: boolean = true; |   public dateFilter: boolean = true; | ||||||
|   public startDate: Date = new Date(new Date(Date.now()).getFullYear(), new Date(Date.now()).getMonth() - 3, 1); |   public startDate: Date = new Date(new Date(Date.now()).getFullYear(), new Date(Date.now()).getMonth() - 3, 1); | ||||||
|   public endDate: Date = new Date(Date.now()); |   public endDate: Date = new Date(Date.now()); | ||||||
|   public startEndCaption: string = this.timespanService.getCaption(this.startDate, this.endDate, 4); |   public startEndCaption: string = this.timespanService.getCaption(this.startDate, this.endDate, 4); | ||||||
|  |  | ||||||
|   searching = false; |   searching = false; | ||||||
|   searchFailed = false; |   searchFailed = false; | ||||||
|   hideSearchingWhenUnsubscribed = new Observable(() => () => this.searching = false); |   hideSearchingWhenUnsubscribed = new Observable(() => () => this.searching = false); | ||||||
|  |  | ||||||
|   public disabled: boolean = true; |   public disabled: boolean = true; | ||||||
|  |  | ||||||
|   constructor(private typeaheadService: TypeaheadService, private timespanService: TimespanService) { |   constructor(private typeaheadService: TypeaheadService, private timespanService: TimespanService) { | ||||||
|     this.filterOptionsLocal = { query: "", tags: "", startDate: null, endDate: null, bboxFilter: true, itemType: null, itemCode:null,level:0,parentCode:null,bbox:[] };    |     this.filterOptionsLocal = { query: "", tags: "", startDate: null, endDate: null, bboxFilter: true, itemType: null, itemCode:null,level:0,parentCode:null,bbox:[] };    | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   search = (text$: Observable<string>) => |   search = (text$: Observable<string>) => | ||||||
|     text$.pipe( |     text$.pipe( | ||||||
|       debounceTime(300), |       debounceTime(300), | ||||||
|       distinctUntilChanged(), |       distinctUntilChanged(), | ||||||
|       tap(() => this.searching = true), |       tap(() => this.searching = true), | ||||||
|       switchMap(term => term.length < 1 ? of([]) : |       switchMap(term => term.length < 1 ? of([]) : | ||||||
|         this.typeaheadService.getSearchTypeaheadItems(term).pipe( |         this.typeaheadService.getSearchTypeaheadItems(term).pipe( | ||||||
|           tap(() => this.searchFailed = false), |           tap(() => this.searchFailed = false), | ||||||
|           catchError(() => { |           catchError(() => { | ||||||
|             this.searchFailed = true; |             this.searchFailed = true; | ||||||
|             return of([]); |             return of([]); | ||||||
|           })) ), |           })) ), | ||||||
|       tap(() => this.searching = false), |       tap(() => this.searching = false), | ||||||
|       merge(this.hideSearchingWhenUnsubscribed)); |       merge(this.hideSearchingWhenUnsubscribed)); | ||||||
|  |  | ||||||
|   formatter = (x: { name: string }) => x.name; |   formatter = (x: { name: string }) => x.name; | ||||||
|  |  | ||||||
|   handleSearch(event) { |   handleSearch(event) { | ||||||
|     this.filterOptionsLocal.tags = null; |     this.filterOptionsLocal.tags = null; | ||||||
|     this.filterOptionsLocal.itemType = null; |     this.filterOptionsLocal.itemType = null; | ||||||
|     this.filterOptionsLocal.itemCode = null; |     this.filterOptionsLocal.itemCode = null; | ||||||
|     this.filterOptionsLocal.parentCode = null; |     this.filterOptionsLocal.parentCode = null; | ||||||
|     this.filterOptionsLocal.query = this.searchTextLocalOutput; |     this.filterOptionsLocal.query = this.searchTextLocalOutput; | ||||||
|     if (this.dateFilter) { |     if (this.dateFilter) { | ||||||
|       this.filterOptionsLocal.startDate = this.startDate; |       this.filterOptionsLocal.startDate = this.startDate; | ||||||
|       this.filterOptionsLocal.endDate = this.endDate; |       this.filterOptionsLocal.endDate = this.endDate; | ||||||
|     } |     } | ||||||
|     this.onSearch.emit(this.filterOptionsLocal); |     this.onSearch.emit(this.filterOptionsLocal); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleOpenSelectPeriodModal(event: MouseEvent) { |   handleOpenSelectPeriodModal(event: MouseEvent) { | ||||||
|     event.preventDefault(); |     event.preventDefault(); | ||||||
|     this.onOpenModal.emit('selectPeriodModal'); |     this.onOpenModal.emit('selectPeriodModal'); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleCloseModal() { |   handleCloseModal() { | ||||||
|     this.onCloseModal.emit({}); |     this.onCloseModal.emit({}); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSelect(event) { |   handleSelect(event) { | ||||||
|     event.preventDefault(); |     event.preventDefault(); | ||||||
|     this.filterOptionsLocal.query = null; |     this.filterOptionsLocal.query = null; | ||||||
|     this.filterOptionsLocal.itemType = null; |     this.filterOptionsLocal.itemType = null; | ||||||
|     this.filterOptionsLocal.itemCode = null; |     this.filterOptionsLocal.itemCode = null; | ||||||
|     this.filterOptionsLocal.parentCode = null; |     this.filterOptionsLocal.parentCode = null; | ||||||
|     this.filterOptionsLocal.tags = event.item.name; |     this.filterOptionsLocal.tags = event.item.name; | ||||||
|     if (this.dateFilter) { |     if (this.dateFilter) { | ||||||
|       this.filterOptionsLocal.startDate = this.startDate; |       this.filterOptionsLocal.startDate = this.startDate; | ||||||
|       this.filterOptionsLocal.endDate = this.endDate; |       this.filterOptionsLocal.endDate = this.endDate; | ||||||
|     } |     } | ||||||
|     this.onSearch.emit(this.filterOptionsLocal); |     this.onSearch.emit(this.filterOptionsLocal); | ||||||
|     this.searchTextLocal = { name: this.filterOptionsLocal.tags }; |     this.searchTextLocal = { name: this.filterOptionsLocal.tags }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSelectPeriod(event: { startDate: Date, endDate: Date }) { |   handleSelectPeriod(event: { startDate: Date, endDate: Date }) { | ||||||
|     this.startDate = event.startDate; |     this.startDate = event.startDate; | ||||||
|     this.endDate = event.endDate;    |     this.endDate = event.endDate;    | ||||||
|     this.handleCloseModal(); |     this.handleCloseModal(); | ||||||
|     this.startEndCaption = this.timespanService.getCaption(event.startDate, event.endDate, 4); |     this.startEndCaption = this.timespanService.getCaption(event.startDate, event.endDate, 4); | ||||||
|     this.onSearch.emit(this.filterOptionsLocal); |     this.onSearch.emit(this.filterOptionsLocal); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleChangeEnableDateFilter(enabled) { |   handleChangeEnableDateFilter(enabled) { | ||||||
|     this.dateFilter = enabled; |     this.dateFilter = enabled; | ||||||
|     if (enabled) { |     if (enabled) { | ||||||
|       this.filterOptionsLocal.startDate = this.startDate; |       this.filterOptionsLocal.startDate = this.startDate; | ||||||
|       this.filterOptionsLocal.endDate = this.endDate; |       this.filterOptionsLocal.endDate = this.endDate; | ||||||
|     } else { |     } else { | ||||||
|       this.filterOptionsLocal.startDate = null; |       this.filterOptionsLocal.startDate = null; | ||||||
|       this.filterOptionsLocal.endDate = null; |       this.filterOptionsLocal.endDate = null; | ||||||
|     } |     } | ||||||
|     if(this.filterOptionsLocal.query || this.filterOptionsLocal.tags) |     if(this.filterOptionsLocal.query || this.filterOptionsLocal.tags) | ||||||
|       this.onSearch.emit(this.filterOptionsLocal); |       this.onSearch.emit(this.filterOptionsLocal); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleChangeEnableBBOXFilter(enabled) { |   handleChangeEnableBBOXFilter(enabled) { | ||||||
|     this.filterOptionsLocal.bboxFilter = enabled; |     this.filterOptionsLocal.bboxFilter = enabled; | ||||||
|     if (this.filterOptionsLocal.query || this.filterOptionsLocal.tags) |     if (this.filterOptionsLocal.query || this.filterOptionsLocal.tags) | ||||||
|       this.onSearch.emit(this.filterOptionsLocal); |       this.onSearch.emit(this.filterOptionsLocal); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   handleToggleMenu(event) { |   handleToggleMenu(event) { | ||||||
|     this.onToggleMenu.emit({}); |     this.onToggleMenu.emit({}); | ||||||
|   }   |   }   | ||||||
|  |  | ||||||
|   handleFocus(event) { |   handleFocus(event) { | ||||||
|     this.onSearchExpand.emit({}); |     this.onSearchExpand.emit({}); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleChange(event: string) { |   handleChange(event: string) { | ||||||
|     this.searchTextLocalOutput = event; |     this.searchTextLocalOutput = event; | ||||||
|     if (event && event.length == 1) { |     if (event && event.length == 1) { | ||||||
|       this.onSearchExpand.emit({}); |       this.onSearchExpand.emit({}); | ||||||
|     } |     } | ||||||
|     if (event && event.length > 0) |     if (event && event.length > 0) | ||||||
|       this.disabled = false; |       this.disabled = false; | ||||||
|     else |     else | ||||||
|       this.disabled = true; |       this.disabled = true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleClearClick(event) { |   handleClearClick(event) { | ||||||
|     this.onClear.emit({}); |     this.onClear.emit({}); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,307 +1,307 @@ | |||||||
| import { Component, OnInit, OnDestroy, HostListener, Inject, ViewChild, AfterViewInit } from '@angular/core'; | import { Component, OnInit, OnDestroy, HostListener, Inject, ViewChild, AfterViewInit } from '@angular/core'; | ||||||
| import { Location } from '@angular/common'; | import { Location } from '@angular/common'; | ||||||
| import { Observable, Subject, Subscription,combineLatest, from } from 'rxjs'; | import { Observable, Subject, Subscription,combineLatest, from } from 'rxjs'; | ||||||
| import { debounce, withLatestFrom, first, combineAll } from 'rxjs/operators'; | import { debounce, withLatestFrom, first, combineAll } from 'rxjs/operators'; | ||||||
| import { Router, ActivatedRoute, ParamMap, Event } from '@angular/router'; | import { Router, ActivatedRoute, ParamMap, Event } from '@angular/router'; | ||||||
| import { Store } from '@ngrx/store'; | import { Store } from '@ngrx/store'; | ||||||
| //import { proj,Map } from 'openlayers'; | //import { proj,Map } from 'openlayers'; | ||||||
|  |  | ||||||
| // Map | // Map | ||||||
| import * as mapReducers from '../../reducers/map.reducer'; | import * as mapReducers from '../../reducers/map.reducer'; | ||||||
| import * as mapActions from '../../actions/map.actions'; | import * as mapActions from '../../actions/map.actions'; | ||||||
| import { IMapState} from '../../models/map.state'; | import { IMapState} from '../../models/map.state'; | ||||||
| import { ISelectedFeatures } from '../../models/selected.features'; | import { ISelectedFeatures } from '../../models/selected.features'; | ||||||
| import { IItemLayer } from '../../models/item.layer'; | import { IItemLayer } from '../../models/item.layer'; | ||||||
| import { IQueryState } from '../../models/query.state'; | import { IQueryState } from '../../models/query.state'; | ||||||
| import { IPeriodState } from '../../models/period.state'; | import { IPeriodState } from '../../models/period.state'; | ||||||
| import { IDroppedFile } from '../aol/file-drop-target/file-drop-target.component'; | import { IDroppedFile } from '../aol/file-drop-target/file-drop-target.component'; | ||||||
| import { IMetaData } from '../meta-data-modal/meta-data-modal.component'; | import { IMetaData } from '../meta-data-modal/meta-data-modal.component'; | ||||||
| import { StateSerializerService } from '../../services/state-serializer.service'; | import { StateSerializerService } from '../../services/state-serializer.service'; | ||||||
| import { GeolocationService} from '../../services/geolocation.service'; | import { GeolocationService} from '../../services/geolocation.service'; | ||||||
|  |  | ||||||
| // AppCommon | // AppCommon | ||||||
| import { ResumableFileUploadService, ItemTypeService } from '@farmmaps/common'; | import { ResumableFileUploadService, ItemTypeService } from '@farmmaps/common'; | ||||||
| import { IItemType, IItem } from '@farmmaps/common'; | import { IItemType, IItem } from '@farmmaps/common'; | ||||||
| import {commonReducers} from '@farmmaps/common'; | import {commonReducers} from '@farmmaps/common'; | ||||||
| import {commonActions} from '@farmmaps/common'; | import {commonActions} from '@farmmaps/common'; | ||||||
|  |  | ||||||
| import {Feature} from 'ol'; | import {Feature} from 'ol'; | ||||||
| import {Extent,createEmpty,extend } from 'ol/extent'; | import {Extent,createEmpty,extend } from 'ol/extent'; | ||||||
| import {transform} from 'ol/proj'; | import {transform} from 'ol/proj'; | ||||||
| import { query } from '@angular/animations'; | import { query } from '@angular/animations'; | ||||||
| import { tassign } from 'tassign'; | import { tassign } from 'tassign'; | ||||||
|  |  | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-map', |   selector: 'fm-map-map', | ||||||
|   templateUrl: './map.component.html', |   templateUrl: './map.component.html', | ||||||
|   styleUrls: ['./map.component.scss'] |   styleUrls: ['./map.component.scss'] | ||||||
| }) | }) | ||||||
|  |  | ||||||
| export class MapComponent implements OnInit, OnDestroy,AfterViewInit { | export class MapComponent implements OnInit, OnDestroy,AfterViewInit { | ||||||
|   title: string = 'Map'; |   title: string = 'Map'; | ||||||
|   public openedModalName: Observable<string>; |   public openedModalName: Observable<string>; | ||||||
|   public itemTypes: Observable<{ [id: string]: IItemType }>; |   public itemTypes: Observable<{ [id: string]: IItemType }>; | ||||||
|   public mapState: Observable<IMapState>; |   public mapState: Observable<IMapState>; | ||||||
|   public features: Observable<Array<Feature>>; |   public features: Observable<Array<Feature>>; | ||||||
|   public overlayLayers: Observable<Array<IItemLayer>>; |   public overlayLayers: Observable<Array<IItemLayer>>; | ||||||
|   public selectedOverlayLayer: Observable<IItemLayer>; |   public selectedOverlayLayer: Observable<IItemLayer>; | ||||||
|   public selectedItemLayer: Observable<IItemLayer>; |   public selectedItemLayer: Observable<IItemLayer>; | ||||||
|   public baseLayers: Observable<Array<IItemLayer>>; |   public baseLayers: Observable<Array<IItemLayer>>; | ||||||
|   public selectedBaseLayer: Observable<IItemLayer>; |   public selectedBaseLayer: Observable<IItemLayer>; | ||||||
|   public projection: Observable<string>; |   public projection: Observable<string>; | ||||||
|   public selectedFeatures: Subject<ISelectedFeatures> = new Subject<ISelectedFeatures>(); |   public selectedFeatures: Subject<ISelectedFeatures> = new Subject<ISelectedFeatures>(); | ||||||
|   public droppedFile: Subject<IDroppedFile>  = new Subject<IDroppedFile>(); |   public droppedFile: Subject<IDroppedFile>  = new Subject<IDroppedFile>(); | ||||||
|   private paramSub: Subscription; |   private paramSub: Subscription; | ||||||
|   private itemTypeSub: Subscription; |   private itemTypeSub: Subscription; | ||||||
|   private mapStateSub: Subscription; |   private mapStateSub: Subscription; | ||||||
|   private queryStateSub: Subscription; |   private queryStateSub: Subscription; | ||||||
|   public parentCode: Observable<string>; |   public parentCode: Observable<string>; | ||||||
|   public panelVisible: Observable<boolean>; |   public panelVisible: Observable<boolean>; | ||||||
|   public panelCollapsed: Observable<boolean>; |   public panelCollapsed: Observable<boolean>; | ||||||
|   public selectedFeature: Observable<Feature>; |   public selectedFeature: Observable<Feature>; | ||||||
|   public selectedItem: Observable<IItem>; |   public selectedItem: Observable<IItem>; | ||||||
|   public queryState: Observable<IQueryState>; |   public queryState: Observable<IQueryState>; | ||||||
|   public period: Observable<IPeriodState>; |   public period: Observable<IPeriodState>; | ||||||
|   public clearEnabled: Observable<boolean>; |   public clearEnabled: Observable<boolean>; | ||||||
|   public searchCollapsed: Observable<boolean>; |   public searchCollapsed: Observable<boolean>; | ||||||
|   public searchMinified: Observable<boolean>; |   public searchMinified: Observable<boolean>; | ||||||
|   public menuVisible: Observable<boolean>; |   public menuVisible: Observable<boolean>; | ||||||
|   public query: Observable<IQueryState>; |   public query: Observable<IQueryState>; | ||||||
|   public position: Observable<Position>; |   public position: Observable<Position>; | ||||||
|   public baseLayersCollapsed:boolean = true; |   public baseLayersCollapsed:boolean = true; | ||||||
|   public overlayLayersCollapsed: boolean = true; |   public overlayLayersCollapsed: boolean = true; | ||||||
|   public extent: Observable<Extent>; |   public extent: Observable<Extent>; | ||||||
|   @ViewChild('map') map; |   @ViewChild('map', { static: true }) map; | ||||||
|    |    | ||||||
|   constructor(private store: Store<mapReducers.State | commonReducers.State>, private route: ActivatedRoute, private router: Router, private uploadService: ResumableFileUploadService, private serializeService: StateSerializerService, public itemTypeService: ItemTypeService, private location: Location, private geolocationService: GeolocationService ) { |   constructor(private store: Store<mapReducers.State | commonReducers.State>, private route: ActivatedRoute, private router: Router, private uploadService: ResumableFileUploadService, private serializeService: StateSerializerService, public itemTypeService: ItemTypeService, private location: Location, private geolocationService: GeolocationService ) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @HostListener('document:keyup', ['$event']) |   @HostListener('document:keyup', ['$event']) | ||||||
|   escapeClose(event: KeyboardEvent) { |   escapeClose(event: KeyboardEvent) { | ||||||
|     let x = event.keyCode; |     let x = event.keyCode; | ||||||
|     if (x === 27) { |     if (x === 27) { | ||||||
|       this.handleCloseModal() |       this.handleCloseModal() | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleOpenModal(modalName: string) { |   handleOpenModal(modalName: string) { | ||||||
|     this.store.dispatch(new  commonActions.OpenModal(modalName)); |     this.store.dispatch(new  commonActions.OpenModal(modalName)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleCloseModal() { |   handleCloseModal() { | ||||||
|     this.store.dispatch(new commonActions.CloseModal()); |     this.store.dispatch(new commonActions.CloseModal()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleFileDropped(droppedFile: IDroppedFile) { |   handleFileDropped(droppedFile: IDroppedFile) { | ||||||
|     this.uploadService.addFiles(droppedFile.files, droppedFile.event, { parentCode:droppedFile.parentCode, geometry:droppedFile.geometry }); |     this.uploadService.addFiles(droppedFile.files, droppedFile.event, { parentCode:droppedFile.parentCode, geometry:droppedFile.geometry }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleFeaturesSelected(feature: Feature) { |   handleFeaturesSelected(feature: Feature) { | ||||||
|     if (feature) { |     if (feature) { | ||||||
|       let newQuery = tassign(mapReducers.initialQueryState, { itemCode: feature.get('code') }); |       let newQuery = tassign(mapReducers.initialQueryState, { itemCode: feature.get('code') }); | ||||||
|       this.store.dispatch(new mapActions.DoQuery(newQuery)); |       this.store.dispatch(new mapActions.DoQuery(newQuery)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSearch(queryState: IQueryState) { |   handleSearch(queryState: IQueryState) { | ||||||
|     this.store.dispatch(new mapActions.DoQuery(queryState)); |     this.store.dispatch(new mapActions.DoQuery(queryState)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     this.store.dispatch(new mapActions.Init()); |     this.store.dispatch(new mapActions.Init()); | ||||||
|     this.selectedFeatures.next({x:0,y:0,features:[]}); |     this.selectedFeatures.next({x:0,y:0,features:[]}); | ||||||
|     this.mapState = this.store.select(mapReducers.selectGetMapState); |     this.mapState = this.store.select(mapReducers.selectGetMapState); | ||||||
|     this.parentCode = this.store.select(mapReducers.selectGetParentCode); |     this.parentCode = this.store.select(mapReducers.selectGetParentCode); | ||||||
|     this.features = this.store.select(mapReducers.selectGetFeatures); |     this.features = this.store.select(mapReducers.selectGetFeatures); | ||||||
|     this.overlayLayers = this.store.select(mapReducers.selectGetOverlayLayers); |     this.overlayLayers = this.store.select(mapReducers.selectGetOverlayLayers); | ||||||
|     this.selectedOverlayLayer = this.store.select(mapReducers.selectGetSelectedOverlayLayer); |     this.selectedOverlayLayer = this.store.select(mapReducers.selectGetSelectedOverlayLayer); | ||||||
|     this.baseLayers = this.store.select(mapReducers.selectGetBaseLayers); |     this.baseLayers = this.store.select(mapReducers.selectGetBaseLayers); | ||||||
|     this.projection = this.store.select(mapReducers.selectGetProjection); |     this.projection = this.store.select(mapReducers.selectGetProjection); | ||||||
|     this.selectedBaseLayer = this.store.select(mapReducers.selectGetSelectedBaseLayer); |     this.selectedBaseLayer = this.store.select(mapReducers.selectGetSelectedBaseLayer); | ||||||
|     this.panelVisible = this.store.select(mapReducers.selectGetPanelVisible); |     this.panelVisible = this.store.select(mapReducers.selectGetPanelVisible); | ||||||
|     this.panelCollapsed = this.store.select(mapReducers.selectGetPanelCollapsed); |     this.panelCollapsed = this.store.select(mapReducers.selectGetPanelCollapsed); | ||||||
|     this.selectedFeature = this.store.select(mapReducers.selectGetSelectedFeature); |     this.selectedFeature = this.store.select(mapReducers.selectGetSelectedFeature); | ||||||
|     this.selectedItem = this.store.select(mapReducers.selectGetSelectedItem); |     this.selectedItem = this.store.select(mapReducers.selectGetSelectedItem); | ||||||
|     this.queryState = this.store.select(mapReducers.selectGetQueryState); |     this.queryState = this.store.select(mapReducers.selectGetQueryState); | ||||||
|     this.clearEnabled = this.store.select(mapReducers.selectGetClearEnabled); |     this.clearEnabled = this.store.select(mapReducers.selectGetClearEnabled); | ||||||
|     this.searchCollapsed = this.store.select(mapReducers.selectGetSearchCollapsed); |     this.searchCollapsed = this.store.select(mapReducers.selectGetSearchCollapsed); | ||||||
|     this.searchMinified = this.store.select(mapReducers.selectGetSearchMinified); |     this.searchMinified = this.store.select(mapReducers.selectGetSearchMinified); | ||||||
|     this.menuVisible = this.store.select(mapReducers.selectGetMenuVisible); |     this.menuVisible = this.store.select(mapReducers.selectGetMenuVisible); | ||||||
|     this.openedModalName = this.store.select(commonReducers.selectOpenedModalName); |     this.openedModalName = this.store.select(commonReducers.selectOpenedModalName); | ||||||
|     this.query = this.store.select(mapReducers.selectGetQuery); |     this.query = this.store.select(mapReducers.selectGetQuery); | ||||||
|     this.extent = this.store.select(mapReducers.selectGetExtent); |     this.extent = this.store.select(mapReducers.selectGetExtent); | ||||||
|     this.selectedFeatures.next(null); |     this.selectedFeatures.next(null); | ||||||
|     this.selectedItemLayer = this.store.select(mapReducers.selectGetSelectedItemLayer); |     this.selectedItemLayer = this.store.select(mapReducers.selectGetSelectedItemLayer); | ||||||
|     this.period = this.store.select(mapReducers.selectGetPeriod); |     this.period = this.store.select(mapReducers.selectGetPeriod); | ||||||
|     this.position = this.geolocationService.getCurrentPosition(); |     this.position = this.geolocationService.getCurrentPosition(); | ||||||
|  |  | ||||||
|     this.mapState.pipe(withLatestFrom(this.queryState)).subscribe((state) => { |     this.mapState.pipe(withLatestFrom(this.queryState)).subscribe((state) => { | ||||||
|       this.replaceUrl(state[0], state[1], true); |       this.replaceUrl(state[0], state[1], true); | ||||||
|     }); |     }); | ||||||
|     this.query.pipe(withLatestFrom(this.mapState)).subscribe((state) => { |     this.query.pipe(withLatestFrom(this.mapState)).subscribe((state) => { | ||||||
|       this.replaceUrl(state[1], state[0],false); |       this.replaceUrl(state[1], state[0],false); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private stateSetCount: number = 0; |   private stateSetCount: number = 0; | ||||||
|   private lastQueryState: string = this.serializeService.serialize(mapReducers.initialQueryState); |   private lastQueryState: string = this.serializeService.serialize(mapReducers.initialQueryState); | ||||||
|   private lastMapState: string = ""; |   private lastMapState: string = ""; | ||||||
|   ngAfterViewInit() { |   ngAfterViewInit() { | ||||||
|     this.paramSub = this.route.paramMap.subscribe((params: ParamMap) => { |     this.paramSub = this.route.paramMap.subscribe((params: ParamMap) => { | ||||||
|       //console.log("Param sub"); |       //console.log("Param sub"); | ||||||
|       var newMapState: IMapState = null; |       var newMapState: IMapState = null; | ||||||
|       var newQueryState: IQueryState = null; |       var newQueryState: IQueryState = null; | ||||||
|       var mapStateChanged = false; |       var mapStateChanged = false; | ||||||
|       var queryStateChanged = false; |       var queryStateChanged = false; | ||||||
|       if (params.has("xCenter") && params.has("yCenter")) { |       if (params.has("xCenter") && params.has("yCenter")) { | ||||||
|         let xCenter = parseFloat(params.get("xCenter")); |         let xCenter = parseFloat(params.get("xCenter")); | ||||||
|         let yCenter = parseFloat(params.get("yCenter")); |         let yCenter = parseFloat(params.get("yCenter")); | ||||||
|         let zoom = parseFloat(params.get("zoom")); |         let zoom = parseFloat(params.get("zoom")); | ||||||
|         let rotation = parseFloat(params.get("rotation")); |         let rotation = parseFloat(params.get("rotation")); | ||||||
|         let baseLayer = params.get("baseLayer")?params.get("baseLayer"):""; |         let baseLayer = params.get("baseLayer")?params.get("baseLayer"):""; | ||||||
|         newMapState = { xCenter: xCenter, yCenter: yCenter, zoom: zoom, rotation: rotation, baseLayerCode: baseLayer } |         newMapState = { xCenter: xCenter, yCenter: yCenter, zoom: zoom, rotation: rotation, baseLayerCode: baseLayer } | ||||||
|         mapStateChanged = this.lastMapState != JSON.stringify(newMapState) && this.stateSetCount == 0; |         mapStateChanged = this.lastMapState != JSON.stringify(newMapState) && this.stateSetCount == 0; | ||||||
|         this.lastMapState = JSON.stringify(newMapState); |         this.lastMapState = JSON.stringify(newMapState); | ||||||
|       } |       } | ||||||
|       if (params.has("queryState")) { |       if (params.has("queryState")) { | ||||||
|         let queryState = params.get("queryState"); |         let queryState = params.get("queryState"); | ||||||
|         newQueryState = tassign(mapReducers.initialQueryState); |         newQueryState = tassign(mapReducers.initialQueryState); | ||||||
|         if (queryState != "") { |         if (queryState != "") { | ||||||
|           newQueryState = this.serializeService.deserialize(queryState); |           newQueryState = this.serializeService.deserialize(queryState); | ||||||
|         } |         } | ||||||
|         queryStateChanged = this.lastQueryState != queryState; |         queryStateChanged = this.lastQueryState != queryState; | ||||||
|         this.lastQueryState = queryState; |         this.lastQueryState = queryState; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (mapStateChanged && queryStateChanged) { |       if (mapStateChanged && queryStateChanged) { | ||||||
|         //console.log("Both states"); |         //console.log("Both states"); | ||||||
|         this.store.dispatch(new mapActions.SetState(newMapState, newQueryState)); |         this.store.dispatch(new mapActions.SetState(newMapState, newQueryState)); | ||||||
|       } else if (mapStateChanged) { |       } else if (mapStateChanged) { | ||||||
|         //console.log("Map state"); |         //console.log("Map state"); | ||||||
|         this.store.dispatch(new mapActions.SetMapState(newMapState)); |         this.store.dispatch(new mapActions.SetMapState(newMapState)); | ||||||
|       } else if (queryStateChanged) { |       } else if (queryStateChanged) { | ||||||
|         //console.log("Query state"); |         //console.log("Query state"); | ||||||
|         this.store.dispatch(new mapActions.SetQueryState(newQueryState)); |         this.store.dispatch(new mapActions.SetQueryState(newQueryState)); | ||||||
|       } |       } | ||||||
|       this.stateSetCount += 1; |       this.stateSetCount += 1; | ||||||
|     }); |     }); | ||||||
|     setTimeout(() => { |     setTimeout(() => { | ||||||
|       this.map.instance.updateSize(); |       this.map.instance.updateSize(); | ||||||
|     }, 500); |     }, 500); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSearchCollapse(event) { |   handleSearchCollapse(event) { | ||||||
|     this.store.dispatch(new mapActions.CollapseSearch()); |     this.store.dispatch(new mapActions.CollapseSearch()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSearchExpand(event) { |   handleSearchExpand(event) { | ||||||
|     this.store.dispatch(new mapActions.ExpandSearch()); |     this.store.dispatch(new mapActions.ExpandSearch()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleToggleMenu(event) { |   handleToggleMenu(event) { | ||||||
|     this.store.dispatch(new mapActions.ToggleMenu()); |     this.store.dispatch(new mapActions.ToggleMenu()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleToggleBaseLayers(event:MouseEvent) { |   handleToggleBaseLayers(event:MouseEvent) { | ||||||
|     this.baseLayersCollapsed = !this.baseLayersCollapsed; |     this.baseLayersCollapsed = !this.baseLayersCollapsed; | ||||||
|     event.preventDefault(); |     event.preventDefault(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleToggleOverlayLayers(event: MouseEvent) { |   handleToggleOverlayLayers(event: MouseEvent) { | ||||||
|     this.overlayLayersCollapsed = !this.overlayLayersCollapsed; |     this.overlayLayersCollapsed = !this.overlayLayersCollapsed; | ||||||
|     event.preventDefault(); |     event.preventDefault(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handlePredefinedQuery(event: MouseEvent, query: any) { |   handlePredefinedQuery(event: MouseEvent, query: any) { | ||||||
|     event.preventDefault(); |     event.preventDefault(); | ||||||
|     var queryState = tassign(mapReducers.initialQueryState, query); |     var queryState = tassign(mapReducers.initialQueryState, query); | ||||||
|     this.store.dispatch(new mapActions.DoQuery(queryState)); |     this.store.dispatch(new mapActions.DoQuery(queryState)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleTrijntjeClick(event: MouseEvent, query: any) { |   handleTrijntjeClick(event: MouseEvent, query: any) { | ||||||
|     event.preventDefault(); |     event.preventDefault(); | ||||||
|     var queryState = tassign(mapReducers.initialQueryState, query); |     var queryState = tassign(mapReducers.initialQueryState, query); | ||||||
|     var mapState = JSON.parse(this.lastMapState); |     var mapState = JSON.parse(this.lastMapState); | ||||||
|     this.router.navigate(["app","trijntje" , mapState.xCenter.toFixed(5), mapState.yCenter.toFixed(5), mapState.zoom, mapState.rotation.toFixed(2), mapState.baseLayerCode, this.serializeService.serialize(queryState)], { replaceUrl: false }); |     this.router.navigate(["app","trijntje" , mapState.xCenter.toFixed(5), mapState.yCenter.toFixed(5), mapState.zoom, mapState.rotation.toFixed(2), mapState.baseLayerCode, this.serializeService.serialize(queryState)], { replaceUrl: false }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   replaceUrl(mapState: IMapState, queryState: IQueryState, replace: boolean = true) { |   replaceUrl(mapState: IMapState, queryState: IQueryState, replace: boolean = true) { | ||||||
|       console.debug(`Replace url : Baselayer(${mapState.baseLayerCode}) Querystate(${this.serializeService.serialize(queryState)})`); |       console.debug(`Replace url : Baselayer(${mapState.baseLayerCode}) Querystate(${this.serializeService.serialize(queryState)})`); | ||||||
|       let parts =["."]; |       let parts =["."]; | ||||||
|       parts.push(mapState.xCenter.toFixed(5)); |       parts.push(mapState.xCenter.toFixed(5)); | ||||||
|       parts.push(mapState.yCenter.toFixed(5)); |       parts.push(mapState.yCenter.toFixed(5)); | ||||||
|       parts.push( mapState.zoom.toFixed(0)); |       parts.push( mapState.zoom.toFixed(0)); | ||||||
|       parts.push( mapState.rotation.toFixed(2)); |       parts.push( mapState.rotation.toFixed(2)); | ||||||
|       if(mapState.baseLayerCode!="") { |       if(mapState.baseLayerCode!="") { | ||||||
|         parts.push(mapState.baseLayerCode); |         parts.push(mapState.baseLayerCode); | ||||||
|         parts.push( this.serializeService.serialize(queryState)); |         parts.push( this.serializeService.serialize(queryState)); | ||||||
|         this.router.navigate(parts, { replaceUrl: replace,relativeTo:this.route.parent }); |         this.router.navigate(parts, { replaceUrl: replace,relativeTo:this.route.parent }); | ||||||
|       }       |       }       | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleOnMoveEnd(event) { |   handleOnMoveEnd(event) { | ||||||
|     var map = event.map; |     var map = event.map; | ||||||
|     var view = map.getView(); |     var view = map.getView(); | ||||||
|     var rotation = view.getRotation(); |     var rotation = view.getRotation(); | ||||||
|     var zoom = view.getZoom(); |     var zoom = view.getZoom(); | ||||||
|     var center = transform(view.getCenter(), view.getProjection(), "EPSG:4326"); |     var center = transform(view.getCenter(), view.getProjection(), "EPSG:4326"); | ||||||
|     var extent = view.calculateExtent(this.map.instance.getSize()); |     var extent = view.calculateExtent(this.map.instance.getSize()); | ||||||
|     let mapState: IMapState = { xCenter: center[0], yCenter: center[1], zoom: zoom, rotation: rotation, baseLayerCode: null }; |     let mapState: IMapState = { xCenter: center[0], yCenter: center[1], zoom: zoom, rotation: rotation, baseLayerCode: null }; | ||||||
|     let state = { mapState: mapState, extent: extent }; |     let state = { mapState: mapState, extent: extent }; | ||||||
|     let source = from([state]); |     let source = from([state]); | ||||||
|     source.pipe(withLatestFrom(this.selectedBaseLayer), withLatestFrom(this.queryState)).subscribe(([[state, baselayer], queryState]) => { |     source.pipe(withLatestFrom(this.selectedBaseLayer), withLatestFrom(this.queryState)).subscribe(([[state, baselayer], queryState]) => { | ||||||
|       if (mapState && baselayer && queryState) { |       if (mapState && baselayer && queryState) { | ||||||
|         let newMapState = tassign(state.mapState, { baseLayerCode: baselayer.item.code }); |         let newMapState = tassign(state.mapState, { baseLayerCode: baselayer.item.code }); | ||||||
|         this.replaceUrl(newMapState, tassign(queryState, { bbox: queryState.bboxFilter ? state.extent : queryState.bbox })); |         this.replaceUrl(newMapState, tassign(queryState, { bbox: queryState.bboxFilter ? state.extent : queryState.bbox })); | ||||||
|         this.store.dispatch(new mapActions.SetViewExtent(state.extent)); |         this.store.dispatch(new mapActions.SetViewExtent(state.extent)); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleOnMouseDown(event: MouseEvent) { |   handleOnMouseDown(event: MouseEvent) { | ||||||
|     this.store.dispatch(new mapActions.CollapseSearch()); |     this.store.dispatch(new mapActions.CollapseSearch()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleOnDownload(event) { |   handleOnDownload(event) { | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleClearSearch(event) { |   handleClearSearch(event) { | ||||||
|     this.store.dispatch(new commonActions.Escape(true, false)); |     this.store.dispatch(new commonActions.Escape(true, false)); | ||||||
|   }   |   }   | ||||||
|  |  | ||||||
|   handleOnDelete(itemLayer: IItemLayer) { |   handleOnDelete(itemLayer: IItemLayer) { | ||||||
|     this.store.dispatch(new mapActions.RemoveLayer(itemLayer)); |     this.store.dispatch(new mapActions.RemoveLayer(itemLayer)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleOnToggleVisibility(itemLayer: IItemLayer) { |   handleOnToggleVisibility(itemLayer: IItemLayer) { | ||||||
|     this.store.dispatch(new mapActions.SetVisibility(itemLayer,!itemLayer.visible)); |     this.store.dispatch(new mapActions.SetVisibility(itemLayer,!itemLayer.visible)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleOnSetOpacity(event:{ layer: IItemLayer,opacity:number }) { |   handleOnSetOpacity(event:{ layer: IItemLayer,opacity:number }) { | ||||||
|     this.store.dispatch(new mapActions.SetOpacity(event.layer, event.opacity)); |     this.store.dispatch(new mapActions.SetOpacity(event.layer, event.opacity)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleZoomToExtent(itemLayer: IItemLayer) { |   handleZoomToExtent(itemLayer: IItemLayer) { | ||||||
|     var extent =  createEmpty(); |     var extent =  createEmpty(); | ||||||
|     extend(extent, itemLayer.layer.getExtent()); |     extend(extent, itemLayer.layer.getExtent()); | ||||||
|     if (extent) { |     if (extent) { | ||||||
|       this.store.dispatch(new mapActions.SetExtent(extent)); |       this.store.dispatch(new mapActions.SetExtent(extent)); | ||||||
|     }     |     }     | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSelectBaseLayer(itemLayer: IItemLayer) { |   handleSelectBaseLayer(itemLayer: IItemLayer) { | ||||||
|     this.store.dispatch(new mapActions.SelectBaseLayer(itemLayer)); |     this.store.dispatch(new mapActions.SelectBaseLayer(itemLayer)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSelectOverlayLayer(itemLayer: IItemLayer) { |   handleSelectOverlayLayer(itemLayer: IItemLayer) { | ||||||
|     this.store.dispatch(new mapActions.SelectOverlayLayer(itemLayer)); |     this.store.dispatch(new mapActions.SelectOverlayLayer(itemLayer)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnDestroy() { |   ngOnDestroy() { | ||||||
|     this.paramSub.unsubscribe(); |     this.paramSub.unsubscribe(); | ||||||
|     if (this.itemTypeSub) this.itemTypeSub.unsubscribe(); |     if (this.itemTypeSub) this.itemTypeSub.unsubscribe(); | ||||||
|     if (this.mapStateSub) this.mapStateSub.unsubscribe(); |     if (this.mapStateSub) this.mapStateSub.unsubscribe(); | ||||||
|     if (this.queryStateSub) this.queryStateSub.unsubscribe();  } |     if (this.queryStateSub) this.queryStateSub.unsubscribe();  } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,61 +1,61 @@ | |||||||
| import { Component, Output, ViewChild, EventEmitter, Input, ElementRef, HostListener } from '@angular/core'; | import { Component, Output, ViewChild, EventEmitter, Input, ElementRef, HostListener } from '@angular/core'; | ||||||
| import { FormGroup,FormBuilder, Validators } from '@angular/forms'; | import { FormGroup,FormBuilder, Validators } from '@angular/forms'; | ||||||
| import { IListItem } from '@farmmaps/common'; | import { IListItem } from '@farmmaps/common'; | ||||||
| import { IDroppedFile } from '../aol/file-drop-target/file-drop-target.component'; | import { IDroppedFile } from '../aol/file-drop-target/file-drop-target.component'; | ||||||
| import {NgbModal, NgbModalRef} from "@ng-bootstrap/ng-bootstrap"; | import {NgbModal, NgbModalRef} from "@ng-bootstrap/ng-bootstrap"; | ||||||
|  |  | ||||||
| export interface IMetaData { | export interface IMetaData { | ||||||
|   droppedFile: IDroppedFile, |   droppedFile: IDroppedFile, | ||||||
|   attributes: any |   attributes: any | ||||||
| } | } | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-meta-data-modal', |   selector: 'fm-map-meta-data-modal', | ||||||
|   templateUrl: 'meta-data-modal.component.html' |   templateUrl: 'meta-data-modal.component.html' | ||||||
| }) | }) | ||||||
| export class MetaDataModalComponent { | export class MetaDataModalComponent { | ||||||
|  |  | ||||||
|   private modalName: string = 'metaDataModal'; |   private modalName: string = 'metaDataModal'; | ||||||
|   private modalRef: NgbModalRef; |   private modalRef: NgbModalRef; | ||||||
|  |  | ||||||
|   @ViewChild('content') _templateModal:ElementRef; |   @ViewChild('content', { static: true }) _templateModal:ElementRef; | ||||||
|   @Input() droppedFile: IDroppedFile; |   @Input() droppedFile: IDroppedFile; | ||||||
|   @Input() set modalState(_modalState:any) {; |   @Input() set modalState(_modalState:any) {; | ||||||
|     if(_modalState == this.modalName) { |     if(_modalState == this.modalName) { | ||||||
|       this.openModal() |       this.openModal() | ||||||
|     } else if(this.modalRef) { |     } else if(this.modalRef) { | ||||||
|       this.closeModal(); |       this.closeModal(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Input() event: IListItem; |   @Input() event: IListItem; | ||||||
|  |  | ||||||
|   @Output() onCloseModal = new EventEmitter<any>(); |   @Output() onCloseModal = new EventEmitter<any>(); | ||||||
|   @Output() onAddFilesWithMetaData = new EventEmitter<IMetaData>(); |   @Output() onAddFilesWithMetaData = new EventEmitter<IMetaData>(); | ||||||
|  |  | ||||||
|   constructor(private modalService: NgbModal, public fb: FormBuilder) { } |   constructor(private modalService: NgbModal, public fb: FormBuilder) { } | ||||||
|  |  | ||||||
|   public metaDataForm: FormGroup; |   public metaDataForm: FormGroup; | ||||||
|  |  | ||||||
|   handleMetaDataEntered(event) { |   handleMetaDataEntered(event) { | ||||||
|     if (this.metaDataForm.valid) { |     if (this.metaDataForm.valid) { | ||||||
|       this.onAddFilesWithMetaData.emit({ droppedFile: this.droppedFile, attributes: { name: this.metaDataForm.value.name } }); |       this.onAddFilesWithMetaData.emit({ droppedFile: this.droppedFile, attributes: { name: this.metaDataForm.value.name } }); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   openModal() { |   openModal() { | ||||||
|       //Timeout trick to avoid ExpressionChangedAfterItHasBeenCheckedError  |       //Timeout trick to avoid ExpressionChangedAfterItHasBeenCheckedError  | ||||||
|       setTimeout(() => this.modalRef = this.modalService.open(this._templateModal, { backdrop: 'static', keyboard: false }));      |       setTimeout(() => this.modalRef = this.modalService.open(this._templateModal, { backdrop: 'static', keyboard: false }));      | ||||||
|   }   |   }   | ||||||
|  |  | ||||||
|   closeModal()  { |   closeModal()  { | ||||||
|       this.modalRef.close(); |       this.modalRef.close(); | ||||||
|       this.metaDataForm.patchValue({ name: "" }); |       this.metaDataForm.patchValue({ name: "" }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|    ngOnInit(): void { |    ngOnInit(): void { | ||||||
|       this.metaDataForm = this.fb.group({ |       this.metaDataForm = this.fb.group({ | ||||||
|       name: ["", Validators.compose([Validators.required, Validators.pattern("[a-zA-Z0-9_].*")])] |       name: ["", Validators.compose([Validators.required, Validators.pattern("[a-zA-Z0-9_].*")])] | ||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,93 +1,93 @@ | |||||||
| import { Component, Output, ViewChild, EventEmitter, Input, ElementRef, HostListener } from '@angular/core'; | import { Component, Output, ViewChild, EventEmitter, Input, ElementRef, HostListener } from '@angular/core'; | ||||||
| import { FormGroup, FormBuilder, Validators } from '@angular/forms'; | import { FormGroup, FormBuilder, Validators } from '@angular/forms'; | ||||||
| import { NgbModal, NgbModalRef, NgbDateStruct, NgbCalendar, NgbDateAdapter } from "@ng-bootstrap/ng-bootstrap"; | import { NgbModal, NgbModalRef, NgbDateStruct, NgbCalendar, NgbDateAdapter } from "@ng-bootstrap/ng-bootstrap"; | ||||||
| import { NgbDateNativeAdapter } from '@farmmaps/common'; | import { NgbDateNativeAdapter } from '@farmmaps/common'; | ||||||
|  |  | ||||||
|  |  | ||||||
| const equals = (one: NgbDateStruct, two: NgbDateStruct) => | const equals = (one: NgbDateStruct, two: NgbDateStruct) => | ||||||
|   one && two && two.year === one.year && two.month === one.month && two.day === one.day; |   one && two && two.year === one.year && two.month === one.month && two.day === one.day; | ||||||
|  |  | ||||||
| const before = (one: NgbDateStruct, two: NgbDateStruct) => | const before = (one: NgbDateStruct, two: NgbDateStruct) => | ||||||
|   !one || !two ? false : one.year === two.year ? one.month === two.month ? one.day === two.day |   !one || !two ? false : one.year === two.year ? one.month === two.month ? one.day === two.day | ||||||
|     ? false : one.day < two.day : one.month < two.month : one.year < two.year; |     ? false : one.day < two.day : one.month < two.month : one.year < two.year; | ||||||
|  |  | ||||||
| const after = (one: NgbDateStruct, two: NgbDateStruct) => | const after = (one: NgbDateStruct, two: NgbDateStruct) => | ||||||
|   !one || !two ? false : one.year === two.year ? one.month === two.month ? one.day === two.day |   !one || !two ? false : one.year === two.year ? one.month === two.month ? one.day === two.day | ||||||
|     ? false : one.day > two.day : one.month > two.month : one.year > two.year; |     ? false : one.day > two.day : one.month > two.month : one.year > two.year; | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-select-period-modal', |   selector: 'fm-map-select-period-modal', | ||||||
|   templateUrl: 'select-period-modal.component.html', |   templateUrl: 'select-period-modal.component.html', | ||||||
|   styleUrls: ['select-period-modal.component.scss']   |   styleUrls: ['select-period-modal.component.scss']   | ||||||
| }) | }) | ||||||
| export class SelectPeriodModalComponent { | export class SelectPeriodModalComponent { | ||||||
|  |  | ||||||
|   private modalName: string = 'selectPeriodModal'; |   private modalName: string = 'selectPeriodModal'; | ||||||
|   private modalRef: NgbModalRef; |   private modalRef: NgbModalRef; | ||||||
|   private dateAdapter = new NgbDateNativeAdapter(); |   private dateAdapter = new NgbDateNativeAdapter(); | ||||||
|   hoveredDate: NgbDateStruct; |   hoveredDate: NgbDateStruct; | ||||||
|   fromDate: NgbDateStruct; |   fromDate: NgbDateStruct; | ||||||
|   toDate: NgbDateStruct; |   toDate: NgbDateStruct; | ||||||
|  |  | ||||||
|   @ViewChild('content') _templateModal:ElementRef; |   @ViewChild('content', { static: true }) _templateModal:ElementRef; | ||||||
|  |  | ||||||
|   @Input() set modalState(_modalState:any) {; |   @Input() set modalState(_modalState:any) {; | ||||||
|     if(_modalState == this.modalName) { |     if(_modalState == this.modalName) { | ||||||
|       this.openModal() |       this.openModal() | ||||||
|     } else if(this.modalRef) { |     } else if(this.modalRef) { | ||||||
|       this.closeModal(); |       this.closeModal(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Input() set startDate(_modalState: Date) { |   @Input() set startDate(_modalState: Date) { | ||||||
|     this.fromDate = this.dateAdapter.fromModel(_modalState); |     this.fromDate = this.dateAdapter.fromModel(_modalState); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Input() set endDate(_modalState: Date) { |   @Input() set endDate(_modalState: Date) { | ||||||
|     var d = new Date(_modalState); |     var d = new Date(_modalState); | ||||||
|     d.setDate(d.getDate() - 1); |     d.setDate(d.getDate() - 1); | ||||||
|     this.toDate = this.dateAdapter.fromModel(d); |     this.toDate = this.dateAdapter.fromModel(d); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Output() onCloseModal = new EventEmitter<any>(); |   @Output() onCloseModal = new EventEmitter<any>(); | ||||||
|   @Output() onSelect = new EventEmitter<{ startDate: Date, endDate: Date }>(); |   @Output() onSelect = new EventEmitter<{ startDate: Date, endDate: Date }>(); | ||||||
|    |    | ||||||
|   constructor(private modalService: NgbModal, private calendar: NgbCalendar) { } |   constructor(private modalService: NgbModal, private calendar: NgbCalendar) { } | ||||||
|  |  | ||||||
|   openModal() { |   openModal() { | ||||||
|       //Timeout trick to avoid ExpressionChangedAfterItHasBeenCheckedError  |       //Timeout trick to avoid ExpressionChangedAfterItHasBeenCheckedError  | ||||||
|       setTimeout(() => this.modalRef = this.modalService.open(this._templateModal, { backdrop: 'static', keyboard: false}));      |       setTimeout(() => this.modalRef = this.modalService.open(this._templateModal, { backdrop: 'static', keyboard: false}));      | ||||||
|   }   |   }   | ||||||
|  |  | ||||||
|   closeModal()  { |   closeModal()  { | ||||||
|       this.modalRef.close();     |       this.modalRef.close();     | ||||||
|   } |   } | ||||||
|  |  | ||||||
|    ngOnInit(): void {      |    ngOnInit(): void {      | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    onDateChange(date: NgbDateStruct) { |    onDateChange(date: NgbDateStruct) { | ||||||
|      if (!this.fromDate && !this.toDate) { |      if (!this.fromDate && !this.toDate) { | ||||||
|        this.fromDate = date; |        this.fromDate = date; | ||||||
|      } else if (this.fromDate && !this.toDate && after(date, this.fromDate)) { |      } else if (this.fromDate && !this.toDate && after(date, this.fromDate)) { | ||||||
|        this.toDate = date; |        this.toDate = date; | ||||||
|      } else { |      } else { | ||||||
|        this.toDate = null; |        this.toDate = null; | ||||||
|        this.fromDate = date; |        this.fromDate = date; | ||||||
|      } |      } | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    handleSelect(event:MouseEvent) { |    handleSelect(event:MouseEvent) { | ||||||
|      event.preventDefault(); |      event.preventDefault(); | ||||||
|      if (this.fromDate && this.toDate && before(this.fromDate, this.toDate)) { |      if (this.fromDate && this.toDate && before(this.fromDate, this.toDate)) { | ||||||
|        var endDate = new Date(this.dateAdapter.toModel(this.toDate)); |        var endDate = new Date(this.dateAdapter.toModel(this.toDate)); | ||||||
|        endDate.setDate(endDate.getDate() + 1); |        endDate.setDate(endDate.getDate() + 1); | ||||||
|        this.onSelect.emit({startDate:this.dateAdapter.toModel(this.fromDate),endDate:endDate}) |        this.onSelect.emit({startDate:this.dateAdapter.toModel(this.fromDate),endDate:endDate}) | ||||||
|      } |      } | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    isHovered = date => this.fromDate && !this.toDate && this.hoveredDate && after(date, this.fromDate) && before(date, this.hoveredDate); |    isHovered = date => this.fromDate && !this.toDate && this.hoveredDate && after(date, this.fromDate) && before(date, this.hoveredDate); | ||||||
|    isInside = date => after(date, this.fromDate) && before(date, this.toDate); |    isInside = date => after(date, this.fromDate) && before(date, this.toDate); | ||||||
|    isFrom = date => equals(date, this.fromDate); |    isFrom = date => equals(date, this.fromDate); | ||||||
|    isTo = date => equals(date, this.toDate); |    isTo = date => equals(date, this.toDate); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,40 +1,40 @@ | |||||||
| import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | import { Component, Input, OnInit, ComponentFactoryResolver, ViewChild, SimpleChanges, ComponentFactory, Inject, Type} from '@angular/core'; | ||||||
| import { IItem } from '@farmmaps/common'; | import { IItem } from '@farmmaps/common'; | ||||||
| import { AbstractSelectedItemComponent, SelectedItemComponent  } from '../selected-item/selected-item.component'; | import { AbstractSelectedItemComponent, SelectedItemComponent  } from '../selected-item/selected-item.component'; | ||||||
| import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | import { WidgetHostDirective } from '../widget-host/widget-host.directive'; | ||||||
|  |  | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-map-selected-item-container', |   selector: 'fm-map-selected-item-container', | ||||||
|   templateUrl: './selected-item-container.component.html', |   templateUrl: './selected-item-container.component.html', | ||||||
|   styleUrls: ['./selected-item-container.component.scss']  |   styleUrls: ['./selected-item-container.component.scss']  | ||||||
| }) | }) | ||||||
| export class SelectedItemContainerComponent { | export class SelectedItemContainerComponent { | ||||||
|  |  | ||||||
|   constructor(private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractSelectedItemComponent) public selectedItemComponents: AbstractSelectedItemComponent[] ) { |   constructor(private componentFactoryResolver: ComponentFactoryResolver, @Inject(AbstractSelectedItemComponent) public selectedItemComponents: AbstractSelectedItemComponent[] ) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Input() item: IItem; |   @Input() item: IItem; | ||||||
|  |  | ||||||
|   @ViewChild(WidgetHostDirective) widgetHost: WidgetHostDirective;  |   @ViewChild(WidgetHostDirective, { static: true }) widgetHost: WidgetHostDirective;  | ||||||
|  |  | ||||||
|   loadComponent() { |   loadComponent() { | ||||||
|     var componentFactory: ComponentFactory<AbstractSelectedItemComponent> = this.componentFactoryResolver.resolveComponentFactory(SelectedItemComponent); // default |     var componentFactory: ComponentFactory<AbstractSelectedItemComponent> = this.componentFactoryResolver.resolveComponentFactory(SelectedItemComponent); // default | ||||||
|     for (var i = 0; i < this.selectedItemComponents.length; i++) { |     for (var i = 0; i < this.selectedItemComponents.length; i++) { | ||||||
|       if (this.selectedItemComponents[i]['forItemType'] == this.item.itemType) { |       if (this.selectedItemComponents[i]['forItemType'] == this.item.itemType) { | ||||||
|         componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.selectedItemComponents[i]['constructor'] as any); |         componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.selectedItemComponents[i]['constructor'] as any); | ||||||
|       } |       } | ||||||
|     }     |     }     | ||||||
|     const viewContainerRef = this.widgetHost.viewContainerRef; |     const viewContainerRef = this.widgetHost.viewContainerRef; | ||||||
|     viewContainerRef.clear(); |     viewContainerRef.clear(); | ||||||
|  |  | ||||||
|     const componentRef = viewContainerRef.createComponent(componentFactory); |     const componentRef = viewContainerRef.createComponent(componentFactory); | ||||||
|     (<AbstractSelectedItemComponent>componentRef.instance).item = this.item; |     (<AbstractSelectedItemComponent>componentRef.instance).item = this.item; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnChanges(changes: SimpleChanges) { |   ngOnChanges(changes: SimpleChanges) { | ||||||
|     if (changes["item"] && changes["item"].currentValue) { |     if (changes["item"] && changes["item"].currentValue) { | ||||||
|         this.loadComponent(); |         this.loadComponent(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | import { Injectable } from '@angular/core'; | ||||||
|  | import { Observer, Observable } from 'rxjs'; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @Injectable() | ||||||
|  | export class DeviceOrientationService { | ||||||
|  |  | ||||||
|  |    /** | ||||||
|  |    * Tries HTML5 geolocation. | ||||||
|  |    * | ||||||
|  |    * Wraps the Geolocation API into an observable. | ||||||
|  |    * | ||||||
|  |    * @return An observable of Bearing | ||||||
|  |    */ | ||||||
|  |   getCurrentBearing(): Observable<number> { | ||||||
|  |     return Observable.create((observer: Observer<number>) => {              | ||||||
|  |         let sensor = new Magnetometer(); | ||||||
|  |         sensor.onreading= (ev:Event) => { | ||||||
|  |              observer.next(Math.atan2(sensor.y, sensor.x) * (180 / Math.PI)); | ||||||
|  |         }; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								projects/common/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										70
									
								
								projects/common/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,35 +1,35 @@ | |||||||
| { | { | ||||||
|   "name": "@farmmaps/common", |   "name": "@farmmaps/common", | ||||||
|   "version": "0.0.1", |   "version": "0.0.1", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "angular-oauth2-oidc": { |     "angular-oauth2-oidc": { | ||||||
|       "version": "5.0.2", |       "version": "8.0.4", | ||||||
|       "resolved": "https://registry.npmjs.org/angular-oauth2-oidc/-/angular-oauth2-oidc-5.0.2.tgz", |       "resolved": "https://registry.npmjs.org/angular-oauth2-oidc/-/angular-oauth2-oidc-8.0.4.tgz", | ||||||
|       "integrity": "sha512-jtOv4IWEjSFfBHVE4seWGWT/ZfWJ95QJ1JaFhVVGJEF64ibGuPwV3ztwTOUl98QHi/Yg4PXXDAisb31JnIbxBw==", |       "integrity": "sha512-7/3niJBqD7rnElcW+SudE36g7zMWChW4gSq7NpJSzDA4aQadBgvg0hn317MfPm9tpYGrpE3G/z2NMnbzek4TMA==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "jsrsasign": "^8.0.12", |         "jsrsasign": "^8.0.12", | ||||||
|         "tslib": "^1.9.0" |         "tslib": "^1.9.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "jsrsasign": { |     "jsrsasign": { | ||||||
|       "version": "8.0.12", |       "version": "8.0.12", | ||||||
|       "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.12.tgz", |       "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-8.0.12.tgz", | ||||||
|       "integrity": "sha1-Iqu5ZW00owuVMENnIINeicLlwxY=" |       "integrity": "sha1-Iqu5ZW00owuVMENnIINeicLlwxY=" | ||||||
|     }, |     }, | ||||||
|     "ngx-uploadx": { |     "ngx-uploadx": { | ||||||
|       "version": "3.1.3", |       "version": "3.3.2", | ||||||
|       "resolved": "https://registry.npmjs.org/ngx-uploadx/-/ngx-uploadx-3.1.3.tgz", |       "resolved": "https://registry.npmjs.org/ngx-uploadx/-/ngx-uploadx-3.3.2.tgz", | ||||||
|       "integrity": "sha512-RX3uEaqMTpjTv5mtdnTQYsDOED3Qg5V3OBU5ohOyL35uL+dllF7I0y+kojJprm9thzHNAWih1DLeTlVWZKo+hQ==", |       "integrity": "sha512-gRdXXq2cRU9HE6dj65qay9GV8NRC7n8y5LtMzJWqsfu2k3CHMQxo2TqZwA9/l/PqJ76RoO7sTPy1OenFQ+krkQ==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "tslib": "^1.9.0" |         "tslib": "^1.9.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "tslib": { |     "tslib": { | ||||||
|       "version": "1.10.0", |       "version": "1.10.0", | ||||||
|       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", |       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", | ||||||
|       "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" |       "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,24 +1,24 @@ | |||||||
| { | { | ||||||
|   "name": "@farmmaps/common", |   "name": "@farmmaps/common", | ||||||
|   "version": "0.0.1", |   "version": "0.0.1", | ||||||
|   "publishConfig": { |   "publishConfig": { | ||||||
|     "registry": "https://repository.akkerweb.nl/repository/npm-hosted/" |     "registry": "https://repository.akkerweb.nl/repository/npm-hosted/" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "angular-oauth2-oidc": "^5.0.2", |     "angular-oauth2-oidc": "^8.0.2", | ||||||
|     "ngx-uploadx": "^3.1.3" |     "ngx-uploadx": "^3.3.2" | ||||||
|   }, |   }, | ||||||
|   "peerDependencies": { |   "peerDependencies": { | ||||||
|     "@ng-bootstrap/ng-bootstrap": "^4.2.1", |     "@ng-bootstrap/ng-bootstrap": "^4.2.1", | ||||||
|     "@angular/common": "^7.2.0", |     "@angular/common": "^8.2.0", | ||||||
|     "@angular/core": "^7.2.0", |     "@angular/core": "^8.2.0", | ||||||
|     "@angular/forms": "^7.2.0", |     "@angular/forms": "^8.2.0", | ||||||
|     "@ngrx/effects": "^7.2", |     "@ngrx/effects": "^8.2", | ||||||
|     "@ngrx/router-store": "^7.2", |     "@ngrx/router-store": "^8.2", | ||||||
|     "@ngrx/store": "^7.2", |     "@ngrx/store": "^8.2", | ||||||
|     "tassign": "^1.0.0", |     "tassign": "^1.0.0", | ||||||
|     "bootstrap": "^4.3.1", |     "bootstrap": "^4.3.1", | ||||||
|     "@aspnet/signalr": "^1.1.4", |     "@aspnet/signalr": "^1.1.4", | ||||||
|     "font-awesome": "^4.7.0" |     "font-awesome": "^4.7.0" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,129 +1,129 @@ | |||||||
| import { Component, OnInit, OnDestroy, Inject, ViewEncapsulation, RendererFactory2, PLATFORM_ID, ChangeDetectionStrategy, HostListener } from '@angular/core'; | import { Component, OnInit, OnDestroy, Inject, ViewEncapsulation, RendererFactory2, PLATFORM_ID, ChangeDetectionStrategy, HostListener } from '@angular/core'; | ||||||
| import { Router, NavigationEnd, RouteConfigLoadStart, RouteConfigLoadEnd, ActivatedRoute, PRIMARY_OUTLET } from '@angular/router'; | import { Router, NavigationEnd, RouteConfigLoadStart, RouteConfigLoadEnd, ActivatedRoute, PRIMARY_OUTLET } from '@angular/router'; | ||||||
| import { Meta, Title, DOCUMENT, MetaDefinition } from '@angular/platform-browser'; | import { Meta, Title, MetaDefinition } from '@angular/platform-browser';import { DOCUMENT } from "@angular/common"; | ||||||
| import { Subscription ,  Observable } from 'rxjs'; | import { Subscription ,  Observable } from 'rxjs'; | ||||||
| import { Store, Action } from '@ngrx/store'; | import { Store, Action } from '@ngrx/store'; | ||||||
|  |  | ||||||
| //AppCommon | //AppCommon | ||||||
| import { IEventMessage } from '../../models/event.message'; | import { IEventMessage } from '../../models/event.message'; | ||||||
| import { IListItem} from '../../models/list.item'; | import { IListItem} from '../../models/list.item'; | ||||||
| import { EventService } from '../../services/event.service'; | import { EventService } from '../../services/event.service'; | ||||||
| import * as  commonActions  from '../../actions/app-common.actions'; | import * as  commonActions  from '../../actions/app-common.actions'; | ||||||
|  |  | ||||||
| import * as appReducers from '../../reducers/app-common.reducer'; | import * as appReducers from '../../reducers/app-common.reducer'; | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-app', |   selector: 'fm-app', | ||||||
|   templateUrl: './app.component.html', |   templateUrl: './app.component.html', | ||||||
|   styleUrls: ['./app.component.scss'], |   styleUrls: ['./app.component.scss'], | ||||||
|   encapsulation: ViewEncapsulation.None, |   encapsulation: ViewEncapsulation.None, | ||||||
|   changeDetection: ChangeDetectionStrategy.OnPush |   changeDetection: ChangeDetectionStrategy.OnPush | ||||||
| }) | }) | ||||||
| export class AppComponent implements OnInit, OnDestroy { | export class AppComponent implements OnInit, OnDestroy { | ||||||
|  |  | ||||||
|   // This will go at the END of your title for example "Home - Angular Universal..." <-- after the dash (-) |   // This will go at the END of your title for example "Home - Angular Universal..." <-- after the dash (-) | ||||||
|   private endPageTitle: string = 'Farmmaps'; |   private endPageTitle: string = 'Farmmaps'; | ||||||
|   // If no Title is provided, we'll use a default one before the dash(-) |   // If no Title is provided, we'll use a default one before the dash(-) | ||||||
|   private defaultPageTitle: string = 'Farmmaps'; |   private defaultPageTitle: string = 'Farmmaps'; | ||||||
|  |  | ||||||
|   private routerSub$: Subscription; |   private routerSub$: Subscription; | ||||||
|   private eventSub$: Subscription; |   private eventSub$: Subscription; | ||||||
|  |  | ||||||
|   public currentFolder: Observable<IListItem>; |   public currentFolder: Observable<IListItem>; | ||||||
|   public folderParents: Observable<IListItem[]>; |   public folderParents: Observable<IListItem[]>; | ||||||
|   public browseFileElement: any; |   public browseFileElement: any; | ||||||
|   public browseDirectoryElement: any; |   public browseDirectoryElement: any; | ||||||
|   public fileDroptarget: any; |   public fileDroptarget: any; | ||||||
|   public fullScreen: Observable<boolean>; |   public fullScreen: Observable<boolean>; | ||||||
|   public routeLoading: Observable<boolean>; |   public routeLoading: Observable<boolean>; | ||||||
|  |  | ||||||
|   constructor( |   constructor( | ||||||
|     private router: Router, |     private router: Router, | ||||||
|     private activatedRoute: ActivatedRoute, |     private activatedRoute: ActivatedRoute, | ||||||
|     private title: Title, |     private title: Title, | ||||||
|     private meta: Meta, |     private meta: Meta, | ||||||
|     private store: Store<appReducers.State>, |     private store: Store<appReducers.State>, | ||||||
|     private eventService: EventService, |     private eventService: EventService, | ||||||
|   ) {     |   ) {     | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   |   | ||||||
|  |  | ||||||
|   getActionFromEvent(event: IEventMessage): Action { |   getActionFromEvent(event: IEventMessage): Action { | ||||||
|     var action: Action = null; |     var action: Action = null; | ||||||
|     console.debug(`${event.eventType} Event received`); |     console.debug(`${event.eventType} Event received`); | ||||||
|     switch (event.eventType) { |     switch (event.eventType) { | ||||||
|       case "ItemChanged": { |       case "ItemChanged": { | ||||||
|         action = new commonActions.ItemChangedEvent(event.itemCode, event.attributes); |         action = new commonActions.ItemChangedEvent(event.itemCode, event.attributes); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case "ItemAdded": { |       case "ItemAdded": { | ||||||
|         action = new commonActions.ItemAddedEvent(event.itemCode, event.attributes); |         action = new commonActions.ItemAddedEvent(event.itemCode, event.attributes); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case "ItemDeleted": { |       case "ItemDeleted": { | ||||||
|         action = new commonActions.ItemDeletedEvent(event.itemCode, event.attributes); |         action = new commonActions.ItemDeletedEvent(event.itemCode, event.attributes); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case "taskStart": { |       case "taskStart": { | ||||||
|         action = new commonActions.TaskStartEvent(event.itemCode, event.attributes); |         action = new commonActions.TaskStartEvent(event.itemCode, event.attributes); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case "taskEnd": { |       case "taskEnd": { | ||||||
|         action = new commonActions.TaskEndEvent(event.itemCode, event.attributes); |         action = new commonActions.TaskEndEvent(event.itemCode, event.attributes); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|       case "taskError": { |       case "taskError": { | ||||||
|         action = new commonActions.TaskErrorEvent(event.itemCode, event.attributes); |         action = new commonActions.TaskErrorEvent(event.itemCode, event.attributes); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     return action; |     return action; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnInit() { |   ngOnInit() { | ||||||
|     this.fullScreen = this.store.select(appReducers.selectGetFullScreen); |     this.fullScreen = this.store.select(appReducers.selectGetFullScreen); | ||||||
|     this.routeLoading = this.store.select(appReducers.selectGetRouteLoading); |     this.routeLoading = this.store.select(appReducers.selectGetRouteLoading); | ||||||
|     this.InstallRouteEventHandler(); |     this.InstallRouteEventHandler(); | ||||||
|     this.InstallEventServiceEventHandler(); |     this.InstallEventServiceEventHandler(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @HostListener('document:keyup', ['$event']) |   @HostListener('document:keyup', ['$event']) | ||||||
|   keyUp(event: KeyboardEvent) { |   keyUp(event: KeyboardEvent) { | ||||||
|     let x = event.keyCode; |     let x = event.keyCode; | ||||||
|     if (x === 27) { |     if (x === 27) { | ||||||
|       this.store.dispatch(new commonActions.Escape(true,false)); |       this.store.dispatch(new commonActions.Escape(true,false)); | ||||||
|     }     |     }     | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnDestroy() { |   ngOnDestroy() { | ||||||
|     // Subscription clean-up |     // Subscription clean-up | ||||||
|     if(this.routerSub$) this.routerSub$.unsubscribe(); |     if(this.routerSub$) this.routerSub$.unsubscribe(); | ||||||
|     if(this.eventSub$) this.eventSub$.unsubscribe(); |     if(this.eventSub$) this.eventSub$.unsubscribe(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private InstallRouteEventHandler() { |   private InstallRouteEventHandler() { | ||||||
|     var other = this; |     var other = this; | ||||||
|     this.routerSub$ = this.router.events.subscribe(event => { |     this.routerSub$ = this.router.events.subscribe(event => { | ||||||
|       if (event instanceof RouteConfigLoadStart) { |       if (event instanceof RouteConfigLoadStart) { | ||||||
|         other.store.dispatch(new commonActions.StartRouteLoading()); |         other.store.dispatch(new commonActions.StartRouteLoading()); | ||||||
|       } |       } | ||||||
|       if (event instanceof RouteConfigLoadEnd) { |       if (event instanceof RouteConfigLoadEnd) { | ||||||
|         other.store.dispatch(new commonActions.EndRouteLoading()); |         other.store.dispatch(new commonActions.EndRouteLoading()); | ||||||
|       }       |       }       | ||||||
|     });      |     });      | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private InstallEventServiceEventHandler() { |   private InstallEventServiceEventHandler() { | ||||||
|     var other = this; |     var other = this; | ||||||
|     this.eventSub$ = this.eventService.event.subscribe(event => { |     this.eventSub$ = this.eventService.event.subscribe(event => { | ||||||
|       var action = other.getActionFromEvent(event); |       var action = other.getActionFromEvent(event); | ||||||
|       if (action) other.store.dispatch(action); |       if (action) other.store.dispatch(action); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleClick(event: MouseEvent) { |   handleClick(event: MouseEvent) { | ||||||
|     this.store.dispatch(new commonActions.Escape(false,true)); |     this.store.dispatch(new commonActions.Escape(false,true)); | ||||||
|   }   |   }   | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,85 +1,85 @@ | |||||||
| import { Component, Input,ViewChild,ElementRef,OnChanges,SimpleChanges,HostListener,ChangeDetectorRef  } from '@angular/core'; | import { Component, Input,ViewChild,ElementRef,OnChanges,SimpleChanges,HostListener,ChangeDetectorRef  } from '@angular/core'; | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-side-panel', |   selector: 'fm-side-panel', | ||||||
|   templateUrl: 'side-panel.component.html', |   templateUrl: 'side-panel.component.html', | ||||||
|   styleUrls: ['side-panel.component.scss'] |   styleUrls: ['side-panel.component.scss'] | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  |  | ||||||
| export class SidePanelComponent  implements OnChanges { | export class SidePanelComponent  implements OnChanges { | ||||||
|   @Input() public visible: boolean; |   @Input() public visible: boolean; | ||||||
|   @Input() public collapsed: boolean; |   @Input() public collapsed: boolean; | ||||||
|   @Input() public collapsable: boolean; |   @Input() public collapsable: boolean; | ||||||
|   @Input() public resizeable: boolean = false; |   @Input() public resizeable: boolean = false; | ||||||
|   @ViewChild("resizeGrip") elementView: ElementRef; |   @ViewChild("resizeGrip", { static: false }) elementView: ElementRef; | ||||||
|   public mobile:boolean = true; |   public mobile:boolean = true; | ||||||
|   private parentHeight:number = 0; |   private parentHeight:number = 0; | ||||||
|   public top = "100%"; |   public top = "100%"; | ||||||
|   private resizeTop:number=50; |   private resizeTop:number=50; | ||||||
|   public resizing:boolean=false; |   public resizing:boolean=false; | ||||||
|  |  | ||||||
|   constructor(private element: ElementRef,private ref: ChangeDetectorRef) { |   constructor(private element: ElementRef,private ref: ChangeDetectorRef) { | ||||||
|     this.collapsable = false; |     this.collapsable = false; | ||||||
|     this.setTop(); |     this.setTop(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   checkMobile():boolean { |   checkMobile():boolean { | ||||||
|     let size = parseFloat(getComputedStyle(document.documentElement).width); |     let size = parseFloat(getComputedStyle(document.documentElement).width); | ||||||
|     let rem = parseFloat(getComputedStyle(document.documentElement).fontSize); |     let rem = parseFloat(getComputedStyle(document.documentElement).fontSize); | ||||||
|     let threshold = 44 * rem; |     let threshold = 44 * rem; | ||||||
|     return !(size>threshold); |     return !(size>threshold); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   setTop() { |   setTop() { | ||||||
|     this.mobile = this.checkMobile(); |     this.mobile = this.checkMobile(); | ||||||
|     this.resizeTop = this.mobile?50:0; |     this.resizeTop = this.mobile?50:0; | ||||||
|     this.top =  (this.visible?this.resizeTop: (this.mobile? 100:0)) + "%"; |     this.top =  (this.visible?this.resizeTop: (this.mobile? 100:0)) + "%"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngAfterViewInit() { |   ngAfterViewInit() { | ||||||
|     this.parentHeight = this.element.nativeElement.offsetParent.clientHeight; |     this.parentHeight = this.element.nativeElement.offsetParent.clientHeight; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleToggleClick(event) { |   handleToggleClick(event) { | ||||||
|     if (this.collapsable) { |     if (this.collapsable) { | ||||||
|       this.collapsed = !this.collapsed;      |       this.collapsed = !this.collapsed;      | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleStartGripDrag(event:DragEvent|TouchEvent) { |   handleStartGripDrag(event:DragEvent|TouchEvent) { | ||||||
|     this.resizing=true; |     this.resizing=true; | ||||||
|     if(event instanceof DragEvent) { |     if(event instanceof DragEvent) { | ||||||
|       var crt = new Image(); |       var crt = new Image(); | ||||||
|       crt.style.display = "none";  |       crt.style.display = "none";  | ||||||
|       document.body.appendChild(crt); |       document.body.appendChild(crt); | ||||||
|       event.dataTransfer.setDragImage(crt,0,0); |       event.dataTransfer.setDragImage(crt,0,0); | ||||||
|     }    |     }    | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleEndGripDrag() { |   handleEndGripDrag() { | ||||||
|     this.resizing = false; |     this.resizing = false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleGripDrag(event:DragEvent|TouchEvent) { |   handleGripDrag(event:DragEvent|TouchEvent) { | ||||||
|     var clientY = 0; |     var clientY = 0; | ||||||
|     if((event instanceof TouchEvent)) { |     if((event instanceof TouchEvent)) { | ||||||
|       clientY = (event as TouchEvent).changedTouches[0].clientY; |       clientY = (event as TouchEvent).changedTouches[0].clientY; | ||||||
|     } else { |     } else { | ||||||
|       clientY=(event as DragEvent).clientY; |       clientY=(event as DragEvent).clientY; | ||||||
|     } |     } | ||||||
|     this.resizeTop =  Math.min(98, Math.max(0, clientY / (this.parentHeight  / 100))); |     this.resizeTop =  Math.min(98, Math.max(0, clientY / (this.parentHeight  / 100))); | ||||||
|     this.top =  (this.visible? this.resizeTop:(this.mobile? 100:0)) + "%"; |     this.top =  (this.visible? this.resizeTop:(this.mobile? 100:0)) + "%"; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnChanges(changes: SimpleChanges) { |   ngOnChanges(changes: SimpleChanges) { | ||||||
|     if(changes.visible) { |     if(changes.visible) { | ||||||
|       this.top =  (changes.visible.currentValue?this.resizeTop:(this.mobile? 100:0)) + "%"; |       this.top =  (changes.visible.currentValue?this.resizeTop:(this.mobile? 100:0)) + "%"; | ||||||
|     }     |     }     | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @HostListener('window:resize', ['$event']) |   @HostListener('window:resize', ['$event']) | ||||||
|   onResize(event) { |   onResize(event) { | ||||||
|     this.setTop(); |     this.setTop(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,104 +1,104 @@ | |||||||
| import { Component, Input, forwardRef,ElementRef,ViewChild } from '@angular/core'; | import { Component, Input, forwardRef,ElementRef,ViewChild } from '@angular/core'; | ||||||
| import { ControlValueAccessor, NG_VALUE_ACCESSOR,NgModel } from '@angular/forms'; | import { ControlValueAccessor, NG_VALUE_ACCESSOR,NgModel } from '@angular/forms'; | ||||||
| import { Observable,of } from 'rxjs'; | import { Observable,of } from 'rxjs'; | ||||||
| import { tap,catchError,debounceTime,distinctUntilChanged,switchMap } from 'rxjs/operators' | import { tap,catchError,debounceTime,distinctUntilChanged,switchMap } from 'rxjs/operators' | ||||||
| import { TypeaheadService } from '../../services/typeahead.service'; | import { TypeaheadService } from '../../services/typeahead.service'; | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'fm-tag-input', |   selector: 'fm-tag-input', | ||||||
|   templateUrl: 'tag-input.component.html', |   templateUrl: 'tag-input.component.html', | ||||||
|   styleUrls: ['tag-input.component.scss'], |   styleUrls: ['tag-input.component.scss'], | ||||||
|   providers: [ |   providers: [ | ||||||
|     { |     { | ||||||
|       provide: NG_VALUE_ACCESSOR, |       provide: NG_VALUE_ACCESSOR, | ||||||
|       useExisting: forwardRef(() => TagInputComponent), |       useExisting: forwardRef(() => TagInputComponent), | ||||||
|       multi: true |       multi: true | ||||||
|     } |     } | ||||||
|   ] |   ] | ||||||
| }) | }) | ||||||
|  |  | ||||||
| export class TagInputComponent implements ControlValueAccessor  { | export class TagInputComponent implements ControlValueAccessor  { | ||||||
|   @Input() tags: string[] |   @Input() tags: string[] | ||||||
|   @ViewChild('taginput') tagInputElement: ElementRef; |   @ViewChild('taginput', { static: true }) tagInputElement: ElementRef; | ||||||
|   public tag: string; |   public tag: string; | ||||||
|   searching = false; |   searching = false; | ||||||
|   searchFailed = false; |   searchFailed = false; | ||||||
|  |  | ||||||
|   constructor(private typeaheadService: TypeaheadService) { |   constructor(private typeaheadService: TypeaheadService) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   tagExists(tag) { |   tagExists(tag) { | ||||||
|     if (tag.length == 0) return true; |     if (tag.length == 0) return true; | ||||||
|     for (let t of this.tags) { |     for (let t of this.tags) { | ||||||
|       if (t.toLowerCase() == tag.toLowerCase()) return true; |       if (t.toLowerCase() == tag.toLowerCase()) return true; | ||||||
|     } |     } | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleDeleteTag(tag) { |   handleDeleteTag(tag) { | ||||||
|     let tags = []; |     let tags = []; | ||||||
|     for (let t of this.tags) { |     for (let t of this.tags) { | ||||||
|       if (t != tag) tags.push(t); |       if (t != tag) tags.push(t); | ||||||
|     } |     } | ||||||
|     this.tags = tags; |     this.tags = tags; | ||||||
|     this.propagateChange(tags); |     this.propagateChange(tags); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleAddTag(event) { |   handleAddTag(event) { | ||||||
|     if (!this.tagExists(this.tag)) { |     if (!this.tagExists(this.tag)) { | ||||||
|       this.tags.push(this.tag); |       this.tags.push(this.tag); | ||||||
|       this.propagateChange(this.tags); |       this.propagateChange(this.tags); | ||||||
|     } |     } | ||||||
|     this.tag = ""; |     this.tag = ""; | ||||||
|     this.tagInputElement.nativeElement.focus(); |     this.tagInputElement.nativeElement.focus(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleCheckAddTag(event: KeyboardEvent) { |   handleCheckAddTag(event: KeyboardEvent) { | ||||||
|     if (event.keyCode == 188) { |     if (event.keyCode == 188) { | ||||||
|       let tag = this.tag.substr(0, this.tag.length - 1); // strip , |       let tag = this.tag.substr(0, this.tag.length - 1); // strip , | ||||||
|       if (!this.tagExists(tag)) { |       if (!this.tagExists(tag)) { | ||||||
|         this.tags.push(tag); |         this.tags.push(tag); | ||||||
|         this.propagateChange(this.tags); |         this.propagateChange(this.tags); | ||||||
|       } |       } | ||||||
|       this.tag = ""; |       this.tag = ""; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   handleSelect(event) { |   handleSelect(event) { | ||||||
|     if (!this.tagExists(event.item)) { |     if (!this.tagExists(event.item)) { | ||||||
|       this.tags.push(event.item); |       this.tags.push(event.item); | ||||||
|       this.propagateChange(this.tags); |       this.propagateChange(this.tags); | ||||||
|     } |     } | ||||||
|     event.preventDefault(); |     event.preventDefault(); | ||||||
|     this.tag = ""; |     this.tag = ""; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   propagateChange = (_: any) => { }; |   propagateChange = (_: any) => { }; | ||||||
|  |  | ||||||
|   registerOnChange(fn) { |   registerOnChange(fn) { | ||||||
|     this.propagateChange = fn; |     this.propagateChange = fn; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   findTag = (text$: Observable<string>) => |   findTag = (text$: Observable<string>) => | ||||||
|   text$.pipe( |   text$.pipe( | ||||||
|         debounceTime(200), |         debounceTime(200), | ||||||
|         distinctUntilChanged(),  |         distinctUntilChanged(),  | ||||||
|         tap(() => this.searching = true), |         tap(() => this.searching = true), | ||||||
|         switchMap(term => term.length < 1 ? of([]) : |         switchMap(term => term.length < 1 ? of([]) : | ||||||
|            this.typeaheadService.getTagTypeaheadItems(term).pipe( |            this.typeaheadService.getTagTypeaheadItems(term).pipe( | ||||||
|             tap(() => this.searchFailed = false), |             tap(() => this.searchFailed = false), | ||||||
|             catchError(() => { |             catchError(() => { | ||||||
|                 this.searchFailed = true; |                 this.searchFailed = true; | ||||||
|                 return of([]); |                 return of([]); | ||||||
|             })) |             })) | ||||||
|          ), |          ), | ||||||
|          tap(() => this.searching = false) |          tap(() => this.searching = false) | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   writeValue(value: any) { |   writeValue(value: any) { | ||||||
|     this.tags = value; |     this.tags = value; | ||||||
|     this.tag = ""; |     this.tag = ""; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   registerOnTouched() { } |   registerOnTouched() { } | ||||||
| } | } | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -43,7 +43,7 @@ | |||||||
|  * |  * | ||||||
|  * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame |  * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame | ||||||
|  * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick |  * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick | ||||||
|  * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames |  * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames | ||||||
|  * |  * | ||||||
|  *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js |  *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js | ||||||
|  *  with the following flag, it will bypass `zone.js` patch for IE/Edge |  *  with the following flag, it will bypass `zone.js` patch for IE/Edge | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| { | { | ||||||
|   "extends": "../tsconfig.json", |   "extends": "../tsconfig.json", | ||||||
|   "compilerOptions": { |   "compilerOptions": { | ||||||
|     "outDir": "../out-tsc/app", |     "outDir": "../out-tsc/app", | ||||||
|     "types": [] |     "types": [] | ||||||
|   }, |   }, | ||||||
|   "exclude": [ |   "exclude": [ | ||||||
|     "test.ts", |     "test.ts", | ||||||
|     "**/*.spec.ts" |     "**/*.spec.ts" | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,18 +1,18 @@ | |||||||
| { | { | ||||||
|   "extends": "../tsconfig.json", |   "extends": "../tsconfig.json", | ||||||
|   "compilerOptions": { |   "compilerOptions": { | ||||||
|     "outDir": "../out-tsc/spec", |     "outDir": "../out-tsc/spec", | ||||||
|     "types": [ |     "types": [ | ||||||
|       "jasmine", |       "jasmine", | ||||||
|       "node" |       "node" | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|   "files": [ |   "files": [ | ||||||
|     "test.ts", |     "test.ts", | ||||||
|     "polyfills.ts" |     "polyfills.ts" | ||||||
|   ], |   ], | ||||||
|   "include": [ |   "include": [ | ||||||
|     "**/*.spec.ts", |     "**/*.spec.ts", | ||||||
|     "**/*.d.ts" |     "**/*.d.ts" | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,15 +2,16 @@ | |||||||
|   "compileOnSave": false, |   "compileOnSave": false, | ||||||
|   "compilerOptions": { |   "compilerOptions": { | ||||||
|     "baseUrl": "./", |     "baseUrl": "./", | ||||||
|  |     "downlevelIteration": true, | ||||||
|     "outDir": "./dist/out-tsc", |     "outDir": "./dist/out-tsc", | ||||||
|     "sourceMap": true, |     "sourceMap": true, | ||||||
|     "declaration": false, |     "declaration": false, | ||||||
|     "module": "es2015", |     "module": "esnext", | ||||||
|     "moduleResolution": "node", |     "moduleResolution": "node", | ||||||
|     "emitDecoratorMetadata": true, |     "emitDecoratorMetadata": true, | ||||||
|     "experimentalDecorators": true, |     "experimentalDecorators": true, | ||||||
|     "importHelpers": true, |     "importHelpers": true, | ||||||
|     "target": "es5", |     "target": "es2015", | ||||||
|     "typeRoots": [ |     "typeRoots": [ | ||||||
|       "node_modules/@types" |       "node_modules/@types" | ||||||
|     ], |     ], | ||||||
|   | |||||||
							
								
								
									
										150
									
								
								tslint.json
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								tslint.json
									
									
									
									
									
								
							| @@ -1,75 +1,75 @@ | |||||||
| { | { | ||||||
|   "extends": "tslint:recommended", |   "extends": "tslint:recommended", | ||||||
|   "rulesDirectory": [ |   "rulesDirectory": [ | ||||||
|     "codelyzer" |     "codelyzer" | ||||||
|   ], |   ], | ||||||
|   "rules": { |   "rules": { | ||||||
|     "array-type": false, |     "array-type": false, | ||||||
|     "arrow-parens": false, |     "arrow-parens": false, | ||||||
|     "deprecation": { |     "deprecation": { | ||||||
|       "severity": "warn" |       "severity": "warn" | ||||||
|     }, |     }, | ||||||
|     "import-blacklist": [ |     "import-blacklist": [ | ||||||
|       true, |       true, | ||||||
|       "rxjs/Rx" |       "rxjs/Rx" | ||||||
|     ], |     ], | ||||||
|     "interface-name": false, |     "interface-name": false, | ||||||
|     "max-classes-per-file": false, |     "max-classes-per-file": false, | ||||||
|     "max-line-length": [ |     "max-line-length": [ | ||||||
|       true, |       true, | ||||||
|       140 |       140 | ||||||
|     ], |     ], | ||||||
|     "member-access": false, |     "member-access": false, | ||||||
|     "member-ordering": [ |     "member-ordering": [ | ||||||
|       true, |       true, | ||||||
|       { |       { | ||||||
|         "order": [ |         "order": [ | ||||||
|           "static-field", |           "static-field", | ||||||
|           "instance-field", |           "instance-field", | ||||||
|           "static-method", |           "static-method", | ||||||
|           "instance-method" |           "instance-method" | ||||||
|         ] |         ] | ||||||
|       } |       } | ||||||
|     ], |     ], | ||||||
|     "no-consecutive-blank-lines": false, |     "no-consecutive-blank-lines": false, | ||||||
|     "no-console": [ |     "no-console": [ | ||||||
|       true, |       true, | ||||||
|       "debug", |       "debug", | ||||||
|       "info", |       "info", | ||||||
|       "time", |       "time", | ||||||
|       "timeEnd", |       "timeEnd", | ||||||
|       "trace" |       "trace" | ||||||
|     ], |     ], | ||||||
|     "no-empty": false, |     "no-empty": false, | ||||||
|     "no-inferrable-types": [ |     "no-inferrable-types": [ | ||||||
|       true, |       true, | ||||||
|       "ignore-params" |       "ignore-params" | ||||||
|     ], |     ], | ||||||
|     "no-non-null-assertion": true, |     "no-non-null-assertion": true, | ||||||
|     "no-redundant-jsdoc": true, |     "no-redundant-jsdoc": true, | ||||||
|     "no-switch-case-fall-through": true, |     "no-switch-case-fall-through": true, | ||||||
|     "no-use-before-declare": true, |     "no-use-before-declare": true, | ||||||
|     "no-var-requires": false, |     "no-var-requires": false, | ||||||
|     "object-literal-key-quotes": [ |     "object-literal-key-quotes": [ | ||||||
|       true, |       true, | ||||||
|       "as-needed" |       "as-needed" | ||||||
|     ], |     ], | ||||||
|     "object-literal-sort-keys": false, |     "object-literal-sort-keys": false, | ||||||
|     "ordered-imports": false, |     "ordered-imports": false, | ||||||
|     "quotemark": [ |     "quotemark": [ | ||||||
|       true, |       true, | ||||||
|       "single" |       "single" | ||||||
|     ], |     ], | ||||||
|     "trailing-comma": false, |     "trailing-comma": false, | ||||||
|     "no-output-on-prefix": true, |     "no-output-on-prefix": true, | ||||||
|     "use-input-property-decorator": true, |     "no-inputs-metadata-property": true, | ||||||
|     "use-output-property-decorator": true, |     "no-outputs-metadata-property": true, | ||||||
|     "use-host-property-decorator": true, |     "no-host-metadata-property": true, | ||||||
|     "no-input-rename": true, |     "no-input-rename": true, | ||||||
|     "no-output-rename": true, |     "no-output-rename": true, | ||||||
|     "use-life-cycle-interface": true, |     "use-lifecycle-interface": true, | ||||||
|     "use-pipe-transform-interface": true, |     "use-pipe-transform-interface": true, | ||||||
|     "component-class-suffix": true, |     "component-class-suffix": true, | ||||||
|     "directive-class-suffix": true |     "directive-class-suffix": true | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user