@smarterplan/ngx-smarterplan-locations 0.4.19 → 0.4.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +24 -24
  2. package/esm2022/lib/components/carousel/carousel.component.mjs +3 -3
  3. package/esm2022/lib/components/chevron/chevron.component.mjs +3 -3
  4. package/esm2022/lib/components/detail-location/detail-location.component.mjs +40 -4
  5. package/esm2022/lib/components/form-location/form-location.component.mjs +3 -3
  6. package/esm2022/lib/components/images/images.component.mjs +3 -3
  7. package/esm2022/lib/components/landmark-picker/landmark-picker.component.mjs +3 -3
  8. package/esm2022/lib/components/locations/locations.component.mjs +19 -4
  9. package/esm2022/lib/components/locations/map/map-popup/map-popup.component.mjs +3 -3
  10. package/esm2022/lib/components/locations/map/map.component.mjs +3 -3
  11. package/esm2022/lib/components/models3d/models3d.component.mjs +295 -0
  12. package/esm2022/lib/components/plan-legend/plan-legend.component.mjs +3 -3
  13. package/esm2022/lib/components/plans/calibration/calibration.component.mjs +3 -3
  14. package/esm2022/lib/components/plans/edit-plan/edit-plan.component.mjs +3 -3
  15. package/esm2022/lib/components/plans/plans.component.mjs +3 -3
  16. package/esm2022/lib/components/tab-navigation/tab-navigation.component.mjs +3 -3
  17. package/esm2022/lib/components/visits/visits.component.mjs +45 -12
  18. package/esm2022/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +3 -3
  19. package/esm2022/lib/components/zones/add-zone/add-zone.component.mjs +3 -3
  20. package/esm2022/lib/components/zones/add-zone/selection/selection.component.mjs +3 -3
  21. package/esm2022/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +3 -3
  22. package/esm2022/lib/components/zones/zones.component.mjs +3 -3
  23. package/esm2022/lib/helper.service.mjs +1 -1
  24. package/esm2022/lib/ngx-smarterplan-location-routing.module.mjs +3 -1
  25. package/esm2022/lib/ngx-smarterplan-locations.module.mjs +4 -1
  26. package/esm2022/lib/ngx-smarterplan-locations.service.mjs +1 -1
  27. package/esm2022/lib/pipes/count-audio-sweeps.pipe.mjs +1 -1
  28. package/esm2022/lib/radio-button/radio-button.component.mjs +3 -3
  29. package/esm2022/public-api.mjs +1 -1
  30. package/fesm2022/smarterplan-ngx-smarterplan-locations.mjs +424 -56
  31. package/fesm2022/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
  32. package/lib/components/detail-location/detail-location.component.d.ts +13 -0
  33. package/lib/components/locations/locations.component.d.ts +10 -0
  34. package/lib/components/locations/map/map.component.d.ts +2 -2
  35. package/lib/components/models3d/models3d.component.d.ts +84 -0
  36. package/lib/components/visits/visits.component.d.ts +8 -3
  37. package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +0 -1
  38. package/lib/ngx-smarterplan-locations.module.d.ts +27 -26
  39. package/package.json +2 -2
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Injectable, EventEmitter, Input, Output, Component, ViewContainerRef, ViewChild, Inject, Pipe, HostListener, NgModule } from '@angular/core';
3
3
  import * as i2 from '@smarterplan/ngx-smarterplan-core';
4
- import { enumToArray, LevelStatus, textValidator, noEmptyValidator, floatValidator, uploadFileToS3, deleteFromS3, PropertyType, getSignedImageUrlForSpace, SearchObjectType, SpaceStatus, distance, MATTERPORT_SDK_KEY, getMetaForImage, getSignedFile, downloadFileAsObject, downloadBlob, CaptureViewer, showScanPointsOnPlanInDiv, getCoefficientsForImage, CommentType, SpModule, wait, InventoryStatus, NgxSmarterplanCoreModule } from '@smarterplan/ngx-smarterplan-core';
4
+ import { enumToArray, LevelStatus, textValidator, noEmptyValidator, floatValidator, uploadFileToS3, deleteFromS3, PropertyType, getSignedImageUrlForSpace, CaptureViewer, SearchObjectType, SpaceStatus, distance, MATTERPORT_SDK_KEY, getMetaForImage, getSignedFile, downloadFileAsObject, downloadBlob, uploadFileToS3WithProgress, showScanPointsOnPlanInDiv, getCoefficientsForImage, CommentType, SpModule, wait, InventoryStatus, NgxSmarterplanCoreModule } from '@smarterplan/ngx-smarterplan-core';
5
5
  import * as i1 from '@angular/router';
6
6
  import { RouterModule } from '@angular/router';
7
- import * as i4$1 from '@ng-bootstrap/ng-bootstrap';
7
+ import * as i3$1 from '@ng-bootstrap/ng-bootstrap';
8
8
  import { ModalDismissReasons, NgbModule, NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
9
9
  import * as i4 from '@angular/common';
10
10
  import { CommonModule } from '@angular/common';
@@ -16,7 +16,7 @@ import { LeafletModule } from '@asymmetrik/ngx-leaflet';
16
16
  import * as i1$2 from '@angular/forms';
17
17
  import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
18
18
  import { Subject, takeUntil } from 'rxjs';
19
- import * as i4$2 from '@angular/cdk/clipboard';
19
+ import * as i4$1 from '@angular/cdk/clipboard';
20
20
  import { ClipboardModule } from '@angular/cdk/clipboard';
21
21
  import { getDocument } from 'pdfjs-dist';
22
22
  import panzoom from 'panzoom';
@@ -60,11 +60,11 @@ class TabNavigationComponent {
60
60
  }
61
61
  }
62
62
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabNavigationComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
63
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: { menuItems: "menuItems" }, outputs: { onGoBack: "onGoBack" }, ngImport: i0, template: "<span class=\"menu\">\r\n <span *ngFor=\"let item of menuItems; let index = index;\">\r\n <span class=\"item\" [ngClass]=\"{'current':index === menuItems.length - 1}\"\r\n (click)=\"onClick(item.url,item.back, index)\">{{item.label | translate}}</span> <span\r\n *ngIf=\"index !== menuItems.length - 1\" class=\"separator\">></span>\r\n </span>\r\n</span>\r\n", styles: [".item{font-size:1.35em;color:var(--smarterplan-primary);cursor:pointer}.current{color:var(--smarterplan-primary)!important;cursor:default!important;text-decoration:none!important}.separator{font-size:1.4em;margin-left:10px;margin-right:10px;color:var(--smarterplan-primary)}.item:hover{text-decoration:underline}.menu{margin-top:15px;margin-bottom:20px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
63
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: { menuItems: "menuItems" }, outputs: { onGoBack: "onGoBack" }, ngImport: i0, template: "<span class=\"menu\">\n <span *ngFor=\"let item of menuItems; let index = index;\">\n <span class=\"item\" [ngClass]=\"{'current':index === menuItems.length - 1}\"\n (click)=\"onClick(item.url,item.back, index)\">{{item.label | translate}}</span> <span\n *ngIf=\"index !== menuItems.length - 1\" class=\"separator\">></span>\n </span>\n</span>\n", styles: [".item{font-size:1.35em;color:var(--smarterplan-primary);cursor:pointer}.current{color:var(--smarterplan-primary)!important;cursor:default!important;text-decoration:none!important}.separator{font-size:1.4em;margin-left:10px;margin-right:10px;color:var(--smarterplan-primary)}.item:hover{text-decoration:underline}.menu{margin-top:15px;margin-bottom:20px}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
64
64
  }
65
65
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TabNavigationComponent, decorators: [{
66
66
  type: Component,
67
- args: [{ selector: 'lib-tab-navigation', template: "<span class=\"menu\">\r\n <span *ngFor=\"let item of menuItems; let index = index;\">\r\n <span class=\"item\" [ngClass]=\"{'current':index === menuItems.length - 1}\"\r\n (click)=\"onClick(item.url,item.back, index)\">{{item.label | translate}}</span> <span\r\n *ngIf=\"index !== menuItems.length - 1\" class=\"separator\">></span>\r\n </span>\r\n</span>\r\n", styles: [".item{font-size:1.35em;color:var(--smarterplan-primary);cursor:pointer}.current{color:var(--smarterplan-primary)!important;cursor:default!important;text-decoration:none!important}.separator{font-size:1.4em;margin-left:10px;margin-right:10px;color:var(--smarterplan-primary)}.item:hover{text-decoration:underline}.menu{margin-top:15px;margin-bottom:20px}\n"] }]
67
+ args: [{ selector: 'lib-tab-navigation', template: "<span class=\"menu\">\n <span *ngFor=\"let item of menuItems; let index = index;\">\n <span class=\"item\" [ngClass]=\"{'current':index === menuItems.length - 1}\"\n (click)=\"onClick(item.url,item.back, index)\">{{item.label | translate}}</span> <span\n *ngIf=\"index !== menuItems.length - 1\" class=\"separator\">></span>\n </span>\n</span>\n", styles: [".item{font-size:1.35em;color:var(--smarterplan-primary);cursor:pointer}.current{color:var(--smarterplan-primary)!important;cursor:default!important;text-decoration:none!important}.separator{font-size:1.4em;margin-left:10px;margin-right:10px;color:var(--smarterplan-primary)}.item:hover{text-decoration:underline}.menu{margin-top:15px;margin-bottom:20px}\n"] }]
68
68
  }], ctorParameters: () => [{ type: i1.Router }], propDecorators: { onGoBack: [{
69
69
  type: Output
70
70
  }], menuItems: [{
@@ -133,11 +133,11 @@ class MapPopupComponent {
133
133
  });
134
134
  }
135
135
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapPopupComponent, deps: [{ token: i1.Router }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
136
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MapPopupComponent, selector: "lib-map-popup", ngImport: i0, template: "<div id=\"map-popup\">\r\n <div class=\"map-popup-header\" (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">\r\n <img [src]=\"space.annexes\" />\r\n </div>\r\n <div class=\"map-popup-details\">\r\n <h1 (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">{{space.name}}</h1>\r\n <span class=\"map-popup-address\">{{space.addresses}}</span>\r\n <span *ngFor=\"let visit of space.visits\" class=\"map-popup-visit\" (click)=\"onVisitClick(visit)\"\r\n [style.cursor]=\"'pointer'\">\u27A4 {{ visit.name ? visit.name : space.name}}</span>\r\n </div>\r\n</div>\r\n", styles: [":host{display:none!important}:host-context(.leaflet-popup-content){display:block!important}.map-popup-header{height:120px;overflow:hidden;border-top-right-radius:20px;border-top-left-radius:20px}.map-popup-header img{width:100%;position:relative;top:50%;transform:translateY(-50%)}.map-popup-details{padding:5px 10px 10px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;background-color:#fff;color:#000}.map-popup-details{display:flex;flex-direction:column}.map-popup-details h1{font-size:1.5rem;font-weight:700;margin-bottom:0;color:var(--smarterplan-primary)}.map-popup-address{align-self:flex-end;margin-bottom:10px}.map-popup-visit{color:var(--smarterplan-primary);font-size:1.15rem}.map-popup-visit:hover{color:var(--smarterplan-primary)}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
136
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MapPopupComponent, selector: "lib-map-popup", ngImport: i0, template: "<div id=\"map-popup\">\n <div class=\"map-popup-header\" (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">\n <img [src]=\"space.annexes\" />\n </div>\n <div class=\"map-popup-details\">\n <h1 (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">{{space.name}}</h1>\n <span class=\"map-popup-address\">{{space.addresses}}</span>\n <span *ngFor=\"let visit of space.visits\" class=\"map-popup-visit\" (click)=\"onVisitClick(visit)\"\n [style.cursor]=\"'pointer'\">\u27A4 {{ visit.name ? visit.name : space.name}}</span>\n </div>\n</div>\n", styles: [":host{display:none!important}:host-context(.leaflet-popup-content){display:block!important}.map-popup-header{height:120px;overflow:hidden;border-top-right-radius:20px;border-top-left-radius:20px}.map-popup-header img{width:100%;position:relative;top:50%;transform:translateY(-50%)}.map-popup-details{padding:5px 10px 10px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;background-color:#fff;color:#000}.map-popup-details{display:flex;flex-direction:column}.map-popup-details h1{font-size:1.5rem;font-weight:700;margin-bottom:0;color:var(--smarterplan-primary)}.map-popup-address{align-self:flex-end;margin-bottom:10px}.map-popup-visit{color:var(--smarterplan-primary);font-size:1.15rem}.map-popup-visit:hover{color:var(--smarterplan-primary)}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
137
137
  }
138
138
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapPopupComponent, decorators: [{
139
139
  type: Component,
140
- args: [{ selector: 'lib-map-popup', template: "<div id=\"map-popup\">\r\n <div class=\"map-popup-header\" (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">\r\n <img [src]=\"space.annexes\" />\r\n </div>\r\n <div class=\"map-popup-details\">\r\n <h1 (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">{{space.name}}</h1>\r\n <span class=\"map-popup-address\">{{space.addresses}}</span>\r\n <span *ngFor=\"let visit of space.visits\" class=\"map-popup-visit\" (click)=\"onVisitClick(visit)\"\r\n [style.cursor]=\"'pointer'\">\u27A4 {{ visit.name ? visit.name : space.name}}</span>\r\n </div>\r\n</div>\r\n", styles: [":host{display:none!important}:host-context(.leaflet-popup-content){display:block!important}.map-popup-header{height:120px;overflow:hidden;border-top-right-radius:20px;border-top-left-radius:20px}.map-popup-header img{width:100%;position:relative;top:50%;transform:translateY(-50%)}.map-popup-details{padding:5px 10px 10px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;background-color:#fff;color:#000}.map-popup-details{display:flex;flex-direction:column}.map-popup-details h1{font-size:1.5rem;font-weight:700;margin-bottom:0;color:var(--smarterplan-primary)}.map-popup-address{align-self:flex-end;margin-bottom:10px}.map-popup-visit{color:var(--smarterplan-primary);font-size:1.15rem}.map-popup-visit:hover{color:var(--smarterplan-primary)}\n"] }]
140
+ args: [{ selector: 'lib-map-popup', template: "<div id=\"map-popup\">\n <div class=\"map-popup-header\" (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">\n <img [src]=\"space.annexes\" />\n </div>\n <div class=\"map-popup-details\">\n <h1 (click)=\"onClickVisitFirst()\" [style.cursor]=\"'pointer'\">{{space.name}}</h1>\n <span class=\"map-popup-address\">{{space.addresses}}</span>\n <span *ngFor=\"let visit of space.visits\" class=\"map-popup-visit\" (click)=\"onVisitClick(visit)\"\n [style.cursor]=\"'pointer'\">\u27A4 {{ visit.name ? visit.name : space.name}}</span>\n </div>\n</div>\n", styles: [":host{display:none!important}:host-context(.leaflet-popup-content){display:block!important}.map-popup-header{height:120px;overflow:hidden;border-top-right-radius:20px;border-top-left-radius:20px}.map-popup-header img{width:100%;position:relative;top:50%;transform:translateY(-50%)}.map-popup-details{padding:5px 10px 10px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;background-color:#fff;color:#000}.map-popup-details{display:flex;flex-direction:column}.map-popup-details h1{font-size:1.5rem;font-weight:700;margin-bottom:0;color:var(--smarterplan-primary)}.map-popup-address{align-self:flex-end;margin-bottom:10px}.map-popup-visit{color:var(--smarterplan-primary);font-size:1.15rem}.map-popup-visit:hover{color:var(--smarterplan-primary)}\n"] }]
141
141
  }], ctorParameters: () => [{ type: i1.Router }, { type: i0.NgZone }] });
142
142
 
143
143
  const iconRetinaUrl = "assets/marker-icon-2x.png";
@@ -235,11 +235,11 @@ class MapComponent {
235
235
  return comp.location.nativeElement;
236
236
  }
237
237
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
238
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MapComponent, selector: "lib-map", inputs: { spaces: "spaces" }, viewQueries: [{ propertyName: "popupContainer", first: true, predicate: ["popupContainer"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: "<div [leafletLayers]=\"layers\" [leafletOptions]=\"options\" (leafletMapReady)=\"onMapReady($any($event))\" id=\"map\" leaflet\r\n style=\"height: 500px; margin-top: 30px; z-index: 195\"></div>\r\n\r\n<!-- Hidden container for popup components to avoid display leakage and manage lifecycle -->\r\n<div style=\"display: none\">\r\n <div #popupContainer></div>\r\n</div>", styles: [":host ::ng-deep lib-map-popup{display:none!important}:host ::ng-deep .leaflet-popup-content lib-map-popup{display:block!important}\n"], dependencies: [{ kind: "directive", type: i1$1.LeafletDirective, selector: "[leaflet]", inputs: ["leafletFitBoundsOptions", "leafletPanOptions", "leafletZoomOptions", "leafletZoomPanOptions", "leafletOptions", "leafletZoom", "leafletCenter", "leafletFitBounds", "leafletMaxBounds", "leafletMinZoom", "leafletMaxZoom"], outputs: ["leafletMapReady", "leafletZoomChange", "leafletCenterChange", "leafletClick", "leafletDoubleClick", "leafletMouseDown", "leafletMouseUp", "leafletMouseMove", "leafletMouseOver", "leafletMouseOut", "leafletMapMove", "leafletMapMoveStart", "leafletMapMoveEnd", "leafletMapZoom", "leafletMapZoomStart", "leafletMapZoomEnd"] }, { kind: "directive", type: i1$1.LeafletLayersDirective, selector: "[leafletLayers]", inputs: ["leafletLayers"] }] });
238
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MapComponent, selector: "lib-map", inputs: { spaces: "spaces" }, viewQueries: [{ propertyName: "popupContainer", first: true, predicate: ["popupContainer"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: "<div [leafletLayers]=\"layers\" [leafletOptions]=\"options\" (leafletMapReady)=\"onMapReady($any($event))\" id=\"map\" leaflet\n style=\"height: 500px; margin-top: 30px; z-index: 195\"></div>\n\n<!-- Hidden container for popup components to avoid display leakage and manage lifecycle -->\n<div style=\"display: none\">\n <div #popupContainer></div>\n</div>", styles: [":host ::ng-deep lib-map-popup{display:none!important}:host ::ng-deep .leaflet-popup-content lib-map-popup{display:block!important}\n"], dependencies: [{ kind: "directive", type: i1$1.LeafletDirective, selector: "[leaflet]", inputs: ["leafletFitBoundsOptions", "leafletPanOptions", "leafletZoomOptions", "leafletZoomPanOptions", "leafletOptions", "leafletZoom", "leafletCenter", "leafletFitBounds", "leafletMaxBounds", "leafletMinZoom", "leafletMaxZoom"], outputs: ["leafletMapReady", "leafletZoomChange", "leafletCenterChange", "leafletClick", "leafletDoubleClick", "leafletMouseDown", "leafletMouseUp", "leafletMouseMove", "leafletMouseOver", "leafletMouseOut", "leafletMapMove", "leafletMapMoveStart", "leafletMapMoveEnd", "leafletMapZoom", "leafletMapZoomStart", "leafletMapZoomEnd"] }, { kind: "directive", type: i1$1.LeafletLayersDirective, selector: "[leafletLayers]", inputs: ["leafletLayers"] }] });
239
239
  }
240
240
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MapComponent, decorators: [{
241
241
  type: Component,
242
- args: [{ selector: 'lib-map', template: "<div [leafletLayers]=\"layers\" [leafletOptions]=\"options\" (leafletMapReady)=\"onMapReady($any($event))\" id=\"map\" leaflet\r\n style=\"height: 500px; margin-top: 30px; z-index: 195\"></div>\r\n\r\n<!-- Hidden container for popup components to avoid display leakage and manage lifecycle -->\r\n<div style=\"display: none\">\r\n <div #popupContainer></div>\r\n</div>", styles: [":host ::ng-deep lib-map-popup{display:none!important}:host ::ng-deep .leaflet-popup-content lib-map-popup{display:block!important}\n"] }]
242
+ args: [{ selector: 'lib-map', template: "<div [leafletLayers]=\"layers\" [leafletOptions]=\"options\" (leafletMapReady)=\"onMapReady($any($event))\" id=\"map\" leaflet\n style=\"height: 500px; margin-top: 30px; z-index: 195\"></div>\n\n<!-- Hidden container for popup components to avoid display leakage and manage lifecycle -->\n<div style=\"display: none\">\n <div #popupContainer></div>\n</div>", styles: [":host ::ng-deep lib-map-popup{display:none!important}:host ::ng-deep .leaflet-popup-content lib-map-popup{display:block!important}\n"] }]
243
243
  }], ctorParameters: () => [], propDecorators: { spaces: [{
244
244
  type: Input
245
245
  }], popupContainer: [{
@@ -470,11 +470,11 @@ class FormLocationComponent {
470
470
  }
471
471
  }
472
472
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormLocationComponent, deps: [{ token: i2.SpaceService }, { token: i2.PropertyService }, { token: i2.BaseUserService }, { token: i1$2.UntypedFormBuilder }, { token: i2.MissionService }, { token: i2.LayerService }, { token: i2.ValidatorsService }], target: i0.ɵɵFactoryTarget.Component });
473
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FormLocationComponent, selector: "lib-form-location", inputs: { location: "location" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "imageInputContainer", first: true, predicate: ["imageInputContainer"], descendants: true }, { propertyName: "imageInput", first: true, predicate: ["imageInput"], descendants: true }, { propertyName: "imageBasePreview", first: true, predicate: ["imageBasePreview"], descendants: true }], ngImport: i0, template: "<div class=\"col-md-6 form-new-loc\" *ngIf=\"form\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" data-testid=\"new-location-name\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['name'])|| isFormError(form.controls['name'])}\"\r\n required formControlName=\"name\">\r\n\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\"validatorsService.isControlError(form.controls['name']) \r\n || isFormError(form.controls['name'])\">\r\n {{validatorsService.getError(form.controls['name']) | translate}}\r\n </ngb-alert>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Address' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"addresses\" data-testid=\"new-location-address\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['addresses']) || isFormError(form.controls['addresses'])}\">\r\n <div class=\"invalid-feedback\">\r\n <span data-testid=\"\" [translate]=\"validatorsService.getError(form.controls['addresses'])\"\r\n *ngIf=\" validatorsService.isControlError(form.controls['addresses'])\"></span>\r\n\r\n <ngb-alert data-testid=\"new-location-address-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['addresses']) \">\r\n\r\n {{validatorsService.getError(form.controls['addresses']) | translate}}\r\n </ngb-alert>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Construction year' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"constructionYear\"\r\n data-testid=\"new-location-constructionYear\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-constructionYear-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])\">\r\n {{validatorsService.getError(form.controls['constructionYear']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Latitude' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"latitude\" data-testid=\"new-location-latitude\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['latitude'])|| isFormError(form.controls['latitude'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-latitude-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['latitude']) || isFormError(form.controls['latitude'])\">\r\n {{validatorsService.getError(form.controls['latitude']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Longitude' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"longitude\" data-testid=\"new-location-longitude\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['longitude'])|| isFormError(form.controls['longitude'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-longitude-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['longitude']) || isFormError(form.controls['longitude'])\">\r\n {{validatorsService.getError(form.controls['longitude']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Access level' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <select class=\"d-inline-block custom-select rounded-pill\" formControlName=\"level\">\r\n <option *ngFor=\"let level of levels\" [value]=\"level\">{{level | translate}}</option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Energy Class' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"classEnergyConsumption\"\r\n data-testid=\"new-location-classEnergyConsumption\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-classEnergyConsumption-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])\">\r\n {{validatorsService.getError(form.controls['classEnergyConsumption']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Greenhouse gas emission Class' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"classGes\" data-testid=\"new-location-classGes\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classGes'])|| isFormError(form.controls['classGes'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-classGes-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['classGes']) || isFormError(form.controls['classGes'])\">\r\n {{validatorsService.getError(form.controls['classGes']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Cover picture' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <img #imageBasePreview *ngIf=\"currentImage\" class=\"image-preview\" [src]=\"currentImage\">\r\n <label #imageInputContainer for=\"image\"\r\n class=\"btn btn-label-file btn-outline-primary rounded-pill imageInputContainer\">\r\n <input #imageInput type=\"file\" id=\"image\" (change)=\"handleImageInput($event.target)\" />\r\n {{ imageInputText | translate}}</label>\r\n <button *ngIf=\"currentImage && !imageToUpload\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"imageToBeDeleted=true;clearImageFile()\">{{'Delete picture' | translate }}</button>\r\n <div class=\"image-name\" *ngIf=\"imageToUpload\">\r\n <p>{{ imageToUpload.name}}</p>\r\n <div (click)=\"clearImageFile()\" [style.cursor]=\"'pointer'\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\" *ngIf=\"!location\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Create mission for this space' | translate}}</label>\r\n <div class=\"col-sm-3\">\r\n <input type=\"checkbox\" [(ngModel)]=\"addMissionForNewSpace\" [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div>\r\n\r\n <button data-testid=\"new-location-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\" type=\"submit\"\r\n class=\"btn btn-outline-primary rounded-pill me-3\">{{'Save' | translate}}</button>\r\n\r\n <button data-testid=\"new-location-close-btn\" type=\"button\" (click)=\"onCancel()\"\r\n class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n\r\n </ngb-alert>\r\n </div>\r\n </form>\r\n</div>", styles: ["input[type=file]{display:none}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}.image-preview{object-fit:cover;max-height:400px;max-width:400px;display:flex;margin-bottom:15px}.imageInputContainer{width:fit-content;height:fit-content}.image-name{display:flex}.col-form-label{margin-bottom:1rem;width:230px}.form-new-loc{background-color:#d3d3d3;margin-bottom:15px;padding:10px;width:80%;border-radius:10px}.col-sm-9 select{width:100%;height:31.25px;padding-left:10px}.btn-outline-primary{width:200px;margin-bottom:1rem;margin-right:1rem}.is-invalid,.btn-outline-primary.is-invalid{border-color:red!important}\n"], dependencies: [{ kind: "component", type: i4$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
473
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FormLocationComponent, selector: "lib-form-location", inputs: { location: "location" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "imageInputContainer", first: true, predicate: ["imageInputContainer"], descendants: true }, { propertyName: "imageInput", first: true, predicate: ["imageInput"], descendants: true }, { propertyName: "imageBasePreview", first: true, predicate: ["imageBasePreview"], descendants: true }], ngImport: i0, template: "<div class=\"col-md-6 form-new-loc\" *ngIf=\"form\">\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" data-testid=\"new-location-name\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['name'])|| isFormError(form.controls['name'])}\"\n required formControlName=\"name\">\n\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\"validatorsService.isControlError(form.controls['name']) \n || isFormError(form.controls['name'])\">\n {{validatorsService.getError(form.controls['name']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Address' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"addresses\" data-testid=\"new-location-address\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['addresses']) || isFormError(form.controls['addresses'])}\">\n <div class=\"invalid-feedback\">\n <span data-testid=\"\" [translate]=\"validatorsService.getError(form.controls['addresses'])\"\n *ngIf=\" validatorsService.isControlError(form.controls['addresses'])\"></span>\n\n <ngb-alert data-testid=\"new-location-address-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['addresses']) \">\n\n {{validatorsService.getError(form.controls['addresses']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Construction year' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"constructionYear\"\n data-testid=\"new-location-constructionYear\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-constructionYear-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])\">\n {{validatorsService.getError(form.controls['constructionYear']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Latitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"latitude\" data-testid=\"new-location-latitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['latitude'])|| isFormError(form.controls['latitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-latitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['latitude']) || isFormError(form.controls['latitude'])\">\n {{validatorsService.getError(form.controls['latitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Longitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"longitude\" data-testid=\"new-location-longitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['longitude'])|| isFormError(form.controls['longitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-longitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['longitude']) || isFormError(form.controls['longitude'])\">\n {{validatorsService.getError(form.controls['longitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Access level' | translate}}</label>\n <div class=\"col-sm-9\">\n <select class=\"d-inline-block custom-select rounded-pill\" formControlName=\"level\">\n <option *ngFor=\"let level of levels\" [value]=\"level\">{{level | translate}}</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Energy Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classEnergyConsumption\"\n data-testid=\"new-location-classEnergyConsumption\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classEnergyConsumption-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])\">\n {{validatorsService.getError(form.controls['classEnergyConsumption']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Greenhouse gas emission Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classGes\" data-testid=\"new-location-classGes\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classGes'])|| isFormError(form.controls['classGes'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classGes-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classGes']) || isFormError(form.controls['classGes'])\">\n {{validatorsService.getError(form.controls['classGes']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Cover picture' | translate}}</label>\n <div class=\"col-sm-9\">\n <img #imageBasePreview *ngIf=\"currentImage\" class=\"image-preview\" [src]=\"currentImage\">\n <label #imageInputContainer for=\"image\"\n class=\"btn btn-label-file btn-outline-primary rounded-pill imageInputContainer\">\n <input #imageInput type=\"file\" id=\"image\" (change)=\"handleImageInput($event.target)\" />\n {{ imageInputText | translate}}</label>\n <button *ngIf=\"currentImage && !imageToUpload\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"imageToBeDeleted=true;clearImageFile()\">{{'Delete picture' | translate }}</button>\n <div class=\"image-name\" *ngIf=\"imageToUpload\">\n <p>{{ imageToUpload.name}}</p>\n <div (click)=\"clearImageFile()\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"mb-3 row\" *ngIf=\"!location\">\n <label class=\"col-sm-3 col-form-label\">{{'Create mission for this space' | translate}}</label>\n <div class=\"col-sm-3\">\n <input type=\"checkbox\" [(ngModel)]=\"addMissionForNewSpace\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <button data-testid=\"new-location-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\" type=\"submit\"\n class=\"btn btn-outline-primary rounded-pill me-3\">{{'Save' | translate}}</button>\n\n <button data-testid=\"new-location-close-btn\" type=\"button\" (click)=\"onCancel()\"\n class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n\n </ngb-alert>\n </div>\n </form>\n</div>", styles: ["input[type=file]{display:none}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}.image-preview{object-fit:cover;max-height:400px;max-width:400px;display:flex;margin-bottom:15px}.imageInputContainer{width:fit-content;height:fit-content}.image-name{display:flex}.col-form-label{margin-bottom:1rem;width:230px}.form-new-loc{background-color:#d3d3d3;margin-bottom:15px;padding:10px;width:80%;border-radius:10px}.col-sm-9 select{width:100%;height:31.25px;padding-left:10px}.btn-outline-primary{width:200px;margin-bottom:1rem;margin-right:1rem}.is-invalid,.btn-outline-primary.is-invalid{border-color:red!important}\n"], dependencies: [{ kind: "component", type: i3$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
474
474
  }
475
475
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormLocationComponent, decorators: [{
476
476
  type: Component,
477
- args: [{ selector: 'lib-form-location', template: "<div class=\"col-md-6 form-new-loc\" *ngIf=\"form\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" data-testid=\"new-location-name\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['name'])|| isFormError(form.controls['name'])}\"\r\n required formControlName=\"name\">\r\n\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\"validatorsService.isControlError(form.controls['name']) \r\n || isFormError(form.controls['name'])\">\r\n {{validatorsService.getError(form.controls['name']) | translate}}\r\n </ngb-alert>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Address' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"addresses\" data-testid=\"new-location-address\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['addresses']) || isFormError(form.controls['addresses'])}\">\r\n <div class=\"invalid-feedback\">\r\n <span data-testid=\"\" [translate]=\"validatorsService.getError(form.controls['addresses'])\"\r\n *ngIf=\" validatorsService.isControlError(form.controls['addresses'])\"></span>\r\n\r\n <ngb-alert data-testid=\"new-location-address-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['addresses']) \">\r\n\r\n {{validatorsService.getError(form.controls['addresses']) | translate}}\r\n </ngb-alert>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Construction year' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"constructionYear\"\r\n data-testid=\"new-location-constructionYear\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-constructionYear-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])\">\r\n {{validatorsService.getError(form.controls['constructionYear']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Latitude' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"latitude\" data-testid=\"new-location-latitude\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['latitude'])|| isFormError(form.controls['latitude'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-latitude-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['latitude']) || isFormError(form.controls['latitude'])\">\r\n {{validatorsService.getError(form.controls['latitude']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Longitude' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"longitude\" data-testid=\"new-location-longitude\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['longitude'])|| isFormError(form.controls['longitude'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-longitude-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['longitude']) || isFormError(form.controls['longitude'])\">\r\n {{validatorsService.getError(form.controls['longitude']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Access level' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <select class=\"d-inline-block custom-select rounded-pill\" formControlName=\"level\">\r\n <option *ngFor=\"let level of levels\" [value]=\"level\">{{level | translate}}</option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Energy Class' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"classEnergyConsumption\"\r\n data-testid=\"new-location-classEnergyConsumption\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-classEnergyConsumption-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])\">\r\n {{validatorsService.getError(form.controls['classEnergyConsumption']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Greenhouse gas emission Class' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"classGes\" data-testid=\"new-location-classGes\" (ngModelChange)=\"onFormChange()\"\r\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classGes'])|| isFormError(form.controls['classGes'])}\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-classGes-invalid\" [dismissible]=\"false\" type=\"danger\"\r\n *ngIf=\"validatorsService.isControlError(form.controls['classGes']) || isFormError(form.controls['classGes'])\">\r\n {{validatorsService.getError(form.controls['classGes']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Cover picture' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <img #imageBasePreview *ngIf=\"currentImage\" class=\"image-preview\" [src]=\"currentImage\">\r\n <label #imageInputContainer for=\"image\"\r\n class=\"btn btn-label-file btn-outline-primary rounded-pill imageInputContainer\">\r\n <input #imageInput type=\"file\" id=\"image\" (change)=\"handleImageInput($event.target)\" />\r\n {{ imageInputText | translate}}</label>\r\n <button *ngIf=\"currentImage && !imageToUpload\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"imageToBeDeleted=true;clearImageFile()\">{{'Delete picture' | translate }}</button>\r\n <div class=\"image-name\" *ngIf=\"imageToUpload\">\r\n <p>{{ imageToUpload.name}}</p>\r\n <div (click)=\"clearImageFile()\" [style.cursor]=\"'pointer'\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\" *ngIf=\"!location\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Create mission for this space' | translate}}</label>\r\n <div class=\"col-sm-3\">\r\n <input type=\"checkbox\" [(ngModel)]=\"addMissionForNewSpace\" [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div>\r\n\r\n <button data-testid=\"new-location-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\" type=\"submit\"\r\n class=\"btn btn-outline-primary rounded-pill me-3\">{{'Save' | translate}}</button>\r\n\r\n <button data-testid=\"new-location-close-btn\" type=\"button\" (click)=\"onCancel()\"\r\n class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n\r\n </ngb-alert>\r\n </div>\r\n </form>\r\n</div>", styles: ["input[type=file]{display:none}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}.image-preview{object-fit:cover;max-height:400px;max-width:400px;display:flex;margin-bottom:15px}.imageInputContainer{width:fit-content;height:fit-content}.image-name{display:flex}.col-form-label{margin-bottom:1rem;width:230px}.form-new-loc{background-color:#d3d3d3;margin-bottom:15px;padding:10px;width:80%;border-radius:10px}.col-sm-9 select{width:100%;height:31.25px;padding-left:10px}.btn-outline-primary{width:200px;margin-bottom:1rem;margin-right:1rem}.is-invalid,.btn-outline-primary.is-invalid{border-color:red!important}\n"] }]
477
+ args: [{ selector: 'lib-form-location', template: "<div class=\"col-md-6 form-new-loc\" *ngIf=\"form\">\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" data-testid=\"new-location-name\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['name'])|| isFormError(form.controls['name'])}\"\n required formControlName=\"name\">\n\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\"validatorsService.isControlError(form.controls['name']) \n || isFormError(form.controls['name'])\">\n {{validatorsService.getError(form.controls['name']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Address' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"addresses\" data-testid=\"new-location-address\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['addresses']) || isFormError(form.controls['addresses'])}\">\n <div class=\"invalid-feedback\">\n <span data-testid=\"\" [translate]=\"validatorsService.getError(form.controls['addresses'])\"\n *ngIf=\" validatorsService.isControlError(form.controls['addresses'])\"></span>\n\n <ngb-alert data-testid=\"new-location-address-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['addresses']) \">\n\n {{validatorsService.getError(form.controls['addresses']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Construction year' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"constructionYear\"\n data-testid=\"new-location-constructionYear\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-constructionYear-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])\">\n {{validatorsService.getError(form.controls['constructionYear']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Latitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"latitude\" data-testid=\"new-location-latitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['latitude'])|| isFormError(form.controls['latitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-latitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['latitude']) || isFormError(form.controls['latitude'])\">\n {{validatorsService.getError(form.controls['latitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Longitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"longitude\" data-testid=\"new-location-longitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['longitude'])|| isFormError(form.controls['longitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-longitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['longitude']) || isFormError(form.controls['longitude'])\">\n {{validatorsService.getError(form.controls['longitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Access level' | translate}}</label>\n <div class=\"col-sm-9\">\n <select class=\"d-inline-block custom-select rounded-pill\" formControlName=\"level\">\n <option *ngFor=\"let level of levels\" [value]=\"level\">{{level | translate}}</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Energy Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classEnergyConsumption\"\n data-testid=\"new-location-classEnergyConsumption\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classEnergyConsumption-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])\">\n {{validatorsService.getError(form.controls['classEnergyConsumption']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Greenhouse gas emission Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classGes\" data-testid=\"new-location-classGes\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classGes'])|| isFormError(form.controls['classGes'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classGes-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classGes']) || isFormError(form.controls['classGes'])\">\n {{validatorsService.getError(form.controls['classGes']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Cover picture' | translate}}</label>\n <div class=\"col-sm-9\">\n <img #imageBasePreview *ngIf=\"currentImage\" class=\"image-preview\" [src]=\"currentImage\">\n <label #imageInputContainer for=\"image\"\n class=\"btn btn-label-file btn-outline-primary rounded-pill imageInputContainer\">\n <input #imageInput type=\"file\" id=\"image\" (change)=\"handleImageInput($event.target)\" />\n {{ imageInputText | translate}}</label>\n <button *ngIf=\"currentImage && !imageToUpload\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"imageToBeDeleted=true;clearImageFile()\">{{'Delete picture' | translate }}</button>\n <div class=\"image-name\" *ngIf=\"imageToUpload\">\n <p>{{ imageToUpload.name}}</p>\n <div (click)=\"clearImageFile()\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"mb-3 row\" *ngIf=\"!location\">\n <label class=\"col-sm-3 col-form-label\">{{'Create mission for this space' | translate}}</label>\n <div class=\"col-sm-3\">\n <input type=\"checkbox\" [(ngModel)]=\"addMissionForNewSpace\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <button data-testid=\"new-location-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\" type=\"submit\"\n class=\"btn btn-outline-primary rounded-pill me-3\">{{'Save' | translate}}</button>\n\n <button data-testid=\"new-location-close-btn\" type=\"button\" (click)=\"onCancel()\"\n class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n\n </ngb-alert>\n </div>\n </form>\n</div>", styles: ["input[type=file]{display:none}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}.image-preview{object-fit:cover;max-height:400px;max-width:400px;display:flex;margin-bottom:15px}.imageInputContainer{width:fit-content;height:fit-content}.image-name{display:flex}.col-form-label{margin-bottom:1rem;width:230px}.form-new-loc{background-color:#d3d3d3;margin-bottom:15px;padding:10px;width:80%;border-radius:10px}.col-sm-9 select{width:100%;height:31.25px;padding-left:10px}.btn-outline-primary{width:200px;margin-bottom:1rem;margin-right:1rem}.is-invalid,.btn-outline-primary.is-invalid{border-color:red!important}\n"] }]
478
478
  }], ctorParameters: () => [{ type: i2.SpaceService }, { type: i2.PropertyService }, { type: i2.BaseUserService }, { type: i1$2.UntypedFormBuilder }, { type: i2.MissionService }, { type: i2.LayerService }, { type: i2.ValidatorsService }], propDecorators: { imageInputContainer: [{
479
479
  type: ViewChild,
480
480
  args: ["imageInputContainer"]
@@ -596,6 +596,21 @@ class LocationsComponent {
596
596
  }
597
597
  this.setupMenuItems();
598
598
  }
599
+ /**
600
+ * The visits shown under a location.
601
+ *
602
+ * Everyone gets the first one, which is the location's main entry point. Managers also get the
603
+ * rest, so a site carrying both a Matterport tour and one or more 3D models can be opened in
604
+ * either without going through the admin screens.
605
+ */
606
+ visitsToShow(loc) {
607
+ const visits = loc.visits ?? [];
608
+ return this.isManagerForSpace(loc.id) ? visits : visits.slice(0, 1);
609
+ }
610
+ /** True when this visit opens in the Three.js viewer rather than Matterport. */
611
+ isThreeJsVisit(visit) {
612
+ return visit?.viewer === CaptureViewer.THREEJS;
613
+ }
599
614
  async onVisitClick(loc, visit) {
600
615
  if (!this.userService.userHasAccessToAllZonesInSpace(loc.id)) {
601
616
  // get allowed sweep for the user
@@ -628,11 +643,11 @@ class LocationsComponent {
628
643
  this.router.navigate(["dashboard/localisation", spaceID]);
629
644
  }
630
645
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocationsComponent, deps: [{ token: i2.SpaceService }, { token: i1.Router }, { token: i2.BaseUserService }, { token: i2.ViewerService }, { token: i2.NavigationService }, { token: i2.NavigatorService }], target: i0.ɵɵFactoryTarget.Component });
631
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: LocationsComponent, selector: "lib-locations", ngImport: i0, template: "<div class=\"dashboard-tab\">\r\n <div class=\"header-dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation (onGoBack)=\"onFormChange(null)\" [menuItems]='menuItems'></lib-tab-navigation>\r\n <span class=\"ml-3 refreshIcon\" (click)=\"refresh()\" *ngIf=\"!(isAdding)\" ngbTooltip=\"Refresh list\">\r\n <span class=\"iconify refreshIcon\" data-icon=\"ion:refresh-circle\" data-width=\"35\" data-rotate=\"90deg\"></span>\r\n </span>\r\n </div> \r\n <lib-search-bar *ngIf=\"!isAdding && !isMuseumUser\" [searchable]=\"locations\" [objectType]=\"getSearchType()\"\r\n (searchEvent)=\"applyResultsSearchBar($event)\"></lib-search-bar>\r\n \r\n <div class=\"col-md-8\">\r\n <div class=\"sp-row\" *ngIf=\"!isAdding && isManager\">\r\n <button data-testid=\"new-location-btn\" class=\"btn btn-outline-primary rounded-pill add-location\" (click)=\"onAddLocation()\">\r\n {{'Add location' | translate}}</button>\r\n <!-- <div class=\"outer_circle\">\r\n <button id='btn-icon' (click)=\"onAddLocation()\"></button>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n <hr>\r\n <div class=\"row\" *ngIf=\"isAdding\">\r\n <div class=\"col-md-6\">\r\n <h4>{{'New location' | translate}}</h4>\r\n </div>\r\n </div>\r\n <section *ngIf=\"!isAdding\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-12 col-lg-6\" *ngIf=\"filteredLocations\">\r\n <ul data-testid=\"location-list-container\" class=\"list-group list-group-flush\">\r\n <li class=\"d-flex justify-content-between list-group-item\"\r\n *ngFor=\"let loc of filteredLocations; index as index\">\r\n <div class=\"d-flex\">\r\n <div class=\"col-md-5 img-main-container\">\r\n <div id=\"img_container\">\r\n <img class=\"location-img\" *ngIf=\"loc.annexes; else elseBlock\" [src]=\"loc.annexes\">\r\n <ng-template #elseBlock><img class=\"location-img\"\r\n src=\"./../../../../assets/images/visuel-off-big.jpg\" />\r\n </ng-template>\r\n <button [ngClass]=\"['open-btn-'+getStringNoSpace(loc.name)]\" *ngIf=\"isManagerForSpace(loc.id)\" class=\"btn-details\" (click)=\"onDetailViewClick(loc.id)\">\r\n {{'View details' | translate}}</button>\r\n </div>\r\n \r\n </div>\r\n <div class=\"col-md-7 location-info\">\r\n <p>{{loc.name}}</p>\r\n <p>{{loc.addresses}}</p>\r\n <p [ngClass]=\"['view-btn-'+getStringNoSpace(loc.name)]\" *ngFor=\"let visit of loc.visits\" (click)=\"onVisitClick(loc, visit)\" class=\"visit-name\"\r\n [style.cursor]=\"'pointer'\" ngbTooltip=\"Visit\">{{ visit.name ? visit.name : loc.name}}</p>\r\n </div>\r\n </div>\r\n </li>\r\n \r\n </ul>\r\n </div>\r\n <div class=\"col-sm-12 col-md-12 col-lg-6\">\r\n <lib-map [spaces]=\"filteredLocations\"></lib-map>\r\n </div>\r\n </div>\r\n </section>\r\n <lib-form-location *ngIf=\"isAdding\" (onChange)=\"onFormChange($event)\"></lib-form-location>\r\n</div>\r\n", styles: [".searchbar{margin-bottom:10px}input[type=file]{display:none}.form-control{border-radius:var(--form-control-border-radius)}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}section .list-group{margin-top:15px}section .list-group-item{padding:5px 0}section .location-info{font-size:1.1em}section .location-img{width:100%;object-fit:cover;object-position:center bottom;height:165px}#img_container{position:relative;display:inline-block;text-align:center;width:250px}.img-main-container{max-width:250px;width:250px!important;margin-right:10px}.visit-name{color:var(--smarterplan-primary);font-weight:600}.btn-details{background-color:var(--smarterplan-primary-transparent);position:absolute;color:#fff;bottom:0;right:0;width:100%;height:30%;border:none;font-size:1em;text-transform:lowercase}#btn-icon{width:30px;height:30px;background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0D%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0D%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0D%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0D%0A<style type=\"text/css\">%0D%0A%09.st0{fill:%23565656;}%0D%0A<\\/style>%0D%0A<g>%0D%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0D%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0D%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0D%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0D%0A</g>%0D%0A</svg>%0D%0A');border:none;vertical-align:middle}#btn-icon:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0D%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0D%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0D%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0D%0A<style type=\"text/css\">%0D%0A%09.st0{fill:%234BA4A8;}%0D%0A<\\/style>%0D%0A<g>%0D%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0D%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0D%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0D%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0D%0A</g>%0D%0A</svg>%0D%0A')}#btn-icon[disabled]:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0D%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0D%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0D%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0D%0A<style type=\"text/css\">%0D%0A%09.st0{fill:%23565656;}%0D%0A<\\/style>%0D%0A<g>%0D%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0D%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0D%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0D%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0D%0A</g>%0D%0A</svg>%0D%0A')}.outer_circle{background-color:#ebebeb;border-radius:50%;width:32px;height:32px;padding:1px;margin-left:5px}.refreshIcon{color:var(--smarterplan-primary);cursor:pointer}.refreshIcon svg{vertical-align:middle!important}.add-location{width:fit-content}.sp-row{display:flex;flex-direction:row}\n"], dependencies: [{ kind: "directive", type: i4$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.SearchBarComponent, selector: "lib-search-bar", inputs: ["searchable", "objectType"], outputs: ["searchEvent"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: MapComponent, selector: "lib-map", inputs: ["spaces"] }, { kind: "component", type: FormLocationComponent, selector: "lib-form-location", inputs: ["location"], outputs: ["onChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
646
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: LocationsComponent, selector: "lib-locations", ngImport: i0, template: "<div class=\"dashboard-tab\">\n <div class=\"header-dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation (onGoBack)=\"onFormChange(null)\" [menuItems]='menuItems'></lib-tab-navigation>\n <span class=\"ml-3 refreshIcon\" (click)=\"refresh()\" *ngIf=\"!(isAdding)\" ngbTooltip=\"Refresh list\">\n <span class=\"iconify refreshIcon\" data-icon=\"ion:refresh-circle\" data-width=\"35\" data-rotate=\"90deg\"></span>\n </span>\n </div> \n <lib-search-bar *ngIf=\"!isAdding && !isMuseumUser\" [searchable]=\"locations\" [objectType]=\"getSearchType()\"\n (searchEvent)=\"applyResultsSearchBar($event)\"></lib-search-bar>\n \n <div class=\"col-md-8\">\n <div class=\"sp-row\" *ngIf=\"!isAdding && isManager\">\n <button data-testid=\"new-location-btn\" class=\"btn btn-outline-primary rounded-pill add-location\" (click)=\"onAddLocation()\">\n {{'Add location' | translate}}</button>\n <!-- <div class=\"outer_circle\">\n <button id='btn-icon' (click)=\"onAddLocation()\"></button>\n </div> -->\n </div>\n </div>\n </div>\n <hr>\n <div class=\"row\" *ngIf=\"isAdding\">\n <div class=\"col-md-6\">\n <h4>{{'New location' | translate}}</h4>\n </div>\n </div>\n <section *ngIf=\"!isAdding\">\n <div class=\"row\">\n <div class=\"col-sm-12 col-md-12 col-lg-6\" *ngIf=\"filteredLocations\">\n <ul data-testid=\"location-list-container\" class=\"list-group list-group-flush\">\n <li class=\"d-flex justify-content-between list-group-item\"\n *ngFor=\"let loc of filteredLocations; index as index\">\n <div class=\"d-flex\">\n <div class=\"col-md-5 img-main-container\">\n <div id=\"img_container\">\n <img class=\"location-img\" *ngIf=\"loc.annexes; else elseBlock\" [src]=\"loc.annexes\">\n <ng-template #elseBlock><img class=\"location-img\"\n src=\"./../../../../assets/images/visuel-off-big.jpg\" />\n </ng-template>\n <button [ngClass]=\"['open-btn-'+getStringNoSpace(loc.name)]\" *ngIf=\"isManagerForSpace(loc.id)\" class=\"btn-details\" (click)=\"onDetailViewClick(loc.id)\">\n {{'View details' | translate}}</button>\n </div>\n \n </div>\n <div class=\"col-md-7 location-info\">\n <p>{{loc.name}}</p>\n <p>{{loc.addresses}}</p>\n <!-- One entry per visit, labelled with the name the admin gave it. Everyone sees\n the first; managers also see the others, plus an icon telling the viewers\n apart - a visitor opens whichever they are given and does not need to know. -->\n <p [ngClass]=\"['view-btn-'+getStringNoSpace(loc.name)]\" *ngFor=\"let visit of visitsToShow(loc)\"\n (click)=\"onVisitClick(loc, visit)\" class=\"visit-name\" [style.cursor]=\"'pointer'\"\n [ngbTooltip]=\"isManagerForSpace(loc.id)\n ? (isThreeJsVisit(visit) ? ('3D model' | translate) : ('Matterport tour' | translate))\n : ''\">\n <span class=\"iconify visit-viewer-icon\" *ngIf=\"isManagerForSpace(loc.id)\"\n [attr.data-icon]=\"isThreeJsVisit(visit) ? 'mdi:cube-scan' : 'mdi:rotate-360'\"\n data-inline=\"false\"></span>\n {{ visit.name ? visit.name : loc.name }}\n </p>\n </div>\n </div>\n </li>\n \n </ul>\n </div>\n <div class=\"col-sm-12 col-md-12 col-lg-6\">\n <lib-map [spaces]=\"filteredLocations\"></lib-map>\n </div>\n </div>\n </section>\n <lib-form-location *ngIf=\"isAdding\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>\n", styles: [".searchbar{margin-bottom:10px}input[type=file]{display:none}.form-control{border-radius:var(--form-control-border-radius)}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}section .list-group{margin-top:15px}section .list-group-item{padding:5px 0}section .location-info{font-size:1.1em}section .location-img{width:100%;object-fit:cover;object-position:center bottom;height:165px}#img_container{position:relative;display:inline-block;text-align:center;width:250px}.img-main-container{max-width:250px;width:250px!important;margin-right:10px}.visit-name{color:var(--smarterplan-primary);font-weight:600}.visit-viewer-icon{margin-right:6px;vertical-align:-2px;opacity:.75}.btn-details{background-color:var(--smarterplan-primary-transparent);position:absolute;color:#fff;bottom:0;right:0;width:100%;height:30%;border:none;font-size:1em;text-transform:lowercase}#btn-icon{width:30px;height:30px;background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:%23565656;}%0A<\\/style>%0A<g>%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0A</g>%0A</svg>%0A');border:none;vertical-align:middle}#btn-icon:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:%234BA4A8;}%0A<\\/style>%0A<g>%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0A</g>%0A</svg>%0A')}#btn-icon[disabled]:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:%23565656;}%0A<\\/style>%0A<g>%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0A</g>%0A</svg>%0A')}.outer_circle{background-color:#ebebeb;border-radius:50%;width:32px;height:32px;padding:1px;margin-left:5px}.refreshIcon{color:var(--smarterplan-primary);cursor:pointer}.refreshIcon svg{vertical-align:middle!important}.add-location{width:fit-content}.sp-row{display:flex;flex-direction:row}\n"], dependencies: [{ kind: "directive", type: i3$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.SearchBarComponent, selector: "lib-search-bar", inputs: ["searchable", "objectType"], outputs: ["searchEvent"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: MapComponent, selector: "lib-map", inputs: ["spaces"] }, { kind: "component", type: FormLocationComponent, selector: "lib-form-location", inputs: ["location"], outputs: ["onChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
632
647
  }
633
648
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LocationsComponent, decorators: [{
634
649
  type: Component,
635
- args: [{ selector: 'lib-locations', template: "<div class=\"dashboard-tab\">\r\n <div class=\"header-dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation (onGoBack)=\"onFormChange(null)\" [menuItems]='menuItems'></lib-tab-navigation>\r\n <span class=\"ml-3 refreshIcon\" (click)=\"refresh()\" *ngIf=\"!(isAdding)\" ngbTooltip=\"Refresh list\">\r\n <span class=\"iconify refreshIcon\" data-icon=\"ion:refresh-circle\" data-width=\"35\" data-rotate=\"90deg\"></span>\r\n </span>\r\n </div> \r\n <lib-search-bar *ngIf=\"!isAdding && !isMuseumUser\" [searchable]=\"locations\" [objectType]=\"getSearchType()\"\r\n (searchEvent)=\"applyResultsSearchBar($event)\"></lib-search-bar>\r\n \r\n <div class=\"col-md-8\">\r\n <div class=\"sp-row\" *ngIf=\"!isAdding && isManager\">\r\n <button data-testid=\"new-location-btn\" class=\"btn btn-outline-primary rounded-pill add-location\" (click)=\"onAddLocation()\">\r\n {{'Add location' | translate}}</button>\r\n <!-- <div class=\"outer_circle\">\r\n <button id='btn-icon' (click)=\"onAddLocation()\"></button>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n <hr>\r\n <div class=\"row\" *ngIf=\"isAdding\">\r\n <div class=\"col-md-6\">\r\n <h4>{{'New location' | translate}}</h4>\r\n </div>\r\n </div>\r\n <section *ngIf=\"!isAdding\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-12 col-md-12 col-lg-6\" *ngIf=\"filteredLocations\">\r\n <ul data-testid=\"location-list-container\" class=\"list-group list-group-flush\">\r\n <li class=\"d-flex justify-content-between list-group-item\"\r\n *ngFor=\"let loc of filteredLocations; index as index\">\r\n <div class=\"d-flex\">\r\n <div class=\"col-md-5 img-main-container\">\r\n <div id=\"img_container\">\r\n <img class=\"location-img\" *ngIf=\"loc.annexes; else elseBlock\" [src]=\"loc.annexes\">\r\n <ng-template #elseBlock><img class=\"location-img\"\r\n src=\"./../../../../assets/images/visuel-off-big.jpg\" />\r\n </ng-template>\r\n <button [ngClass]=\"['open-btn-'+getStringNoSpace(loc.name)]\" *ngIf=\"isManagerForSpace(loc.id)\" class=\"btn-details\" (click)=\"onDetailViewClick(loc.id)\">\r\n {{'View details' | translate}}</button>\r\n </div>\r\n \r\n </div>\r\n <div class=\"col-md-7 location-info\">\r\n <p>{{loc.name}}</p>\r\n <p>{{loc.addresses}}</p>\r\n <p [ngClass]=\"['view-btn-'+getStringNoSpace(loc.name)]\" *ngFor=\"let visit of loc.visits\" (click)=\"onVisitClick(loc, visit)\" class=\"visit-name\"\r\n [style.cursor]=\"'pointer'\" ngbTooltip=\"Visit\">{{ visit.name ? visit.name : loc.name}}</p>\r\n </div>\r\n </div>\r\n </li>\r\n \r\n </ul>\r\n </div>\r\n <div class=\"col-sm-12 col-md-12 col-lg-6\">\r\n <lib-map [spaces]=\"filteredLocations\"></lib-map>\r\n </div>\r\n </div>\r\n </section>\r\n <lib-form-location *ngIf=\"isAdding\" (onChange)=\"onFormChange($event)\"></lib-form-location>\r\n</div>\r\n", styles: [".searchbar{margin-bottom:10px}input[type=file]{display:none}.form-control{border-radius:var(--form-control-border-radius)}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}section .list-group{margin-top:15px}section .list-group-item{padding:5px 0}section .location-info{font-size:1.1em}section .location-img{width:100%;object-fit:cover;object-position:center bottom;height:165px}#img_container{position:relative;display:inline-block;text-align:center;width:250px}.img-main-container{max-width:250px;width:250px!important;margin-right:10px}.visit-name{color:var(--smarterplan-primary);font-weight:600}.btn-details{background-color:var(--smarterplan-primary-transparent);position:absolute;color:#fff;bottom:0;right:0;width:100%;height:30%;border:none;font-size:1em;text-transform:lowercase}#btn-icon{width:30px;height:30px;background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0D%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0D%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0D%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0D%0A<style type=\"text/css\">%0D%0A%09.st0{fill:%23565656;}%0D%0A<\\/style>%0D%0A<g>%0D%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0D%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0D%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0D%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0D%0A</g>%0D%0A</svg>%0D%0A');border:none;vertical-align:middle}#btn-icon:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0D%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0D%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0D%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0D%0A<style type=\"text/css\">%0D%0A%09.st0{fill:%234BA4A8;}%0D%0A<\\/style>%0D%0A<g>%0D%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0D%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0D%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0D%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0D%0A</g>%0D%0A</svg>%0D%0A')}#btn-icon[disabled]:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0D%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0D%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0D%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0D%0A<style type=\"text/css\">%0D%0A%09.st0{fill:%23565656;}%0D%0A<\\/style>%0D%0A<g>%0D%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0D%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0D%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0D%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0D%0A</g>%0D%0A</svg>%0D%0A')}.outer_circle{background-color:#ebebeb;border-radius:50%;width:32px;height:32px;padding:1px;margin-left:5px}.refreshIcon{color:var(--smarterplan-primary);cursor:pointer}.refreshIcon svg{vertical-align:middle!important}.add-location{width:fit-content}.sp-row{display:flex;flex-direction:row}\n"] }]
650
+ args: [{ selector: 'lib-locations', template: "<div class=\"dashboard-tab\">\n <div class=\"header-dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation (onGoBack)=\"onFormChange(null)\" [menuItems]='menuItems'></lib-tab-navigation>\n <span class=\"ml-3 refreshIcon\" (click)=\"refresh()\" *ngIf=\"!(isAdding)\" ngbTooltip=\"Refresh list\">\n <span class=\"iconify refreshIcon\" data-icon=\"ion:refresh-circle\" data-width=\"35\" data-rotate=\"90deg\"></span>\n </span>\n </div> \n <lib-search-bar *ngIf=\"!isAdding && !isMuseumUser\" [searchable]=\"locations\" [objectType]=\"getSearchType()\"\n (searchEvent)=\"applyResultsSearchBar($event)\"></lib-search-bar>\n \n <div class=\"col-md-8\">\n <div class=\"sp-row\" *ngIf=\"!isAdding && isManager\">\n <button data-testid=\"new-location-btn\" class=\"btn btn-outline-primary rounded-pill add-location\" (click)=\"onAddLocation()\">\n {{'Add location' | translate}}</button>\n <!-- <div class=\"outer_circle\">\n <button id='btn-icon' (click)=\"onAddLocation()\"></button>\n </div> -->\n </div>\n </div>\n </div>\n <hr>\n <div class=\"row\" *ngIf=\"isAdding\">\n <div class=\"col-md-6\">\n <h4>{{'New location' | translate}}</h4>\n </div>\n </div>\n <section *ngIf=\"!isAdding\">\n <div class=\"row\">\n <div class=\"col-sm-12 col-md-12 col-lg-6\" *ngIf=\"filteredLocations\">\n <ul data-testid=\"location-list-container\" class=\"list-group list-group-flush\">\n <li class=\"d-flex justify-content-between list-group-item\"\n *ngFor=\"let loc of filteredLocations; index as index\">\n <div class=\"d-flex\">\n <div class=\"col-md-5 img-main-container\">\n <div id=\"img_container\">\n <img class=\"location-img\" *ngIf=\"loc.annexes; else elseBlock\" [src]=\"loc.annexes\">\n <ng-template #elseBlock><img class=\"location-img\"\n src=\"./../../../../assets/images/visuel-off-big.jpg\" />\n </ng-template>\n <button [ngClass]=\"['open-btn-'+getStringNoSpace(loc.name)]\" *ngIf=\"isManagerForSpace(loc.id)\" class=\"btn-details\" (click)=\"onDetailViewClick(loc.id)\">\n {{'View details' | translate}}</button>\n </div>\n \n </div>\n <div class=\"col-md-7 location-info\">\n <p>{{loc.name}}</p>\n <p>{{loc.addresses}}</p>\n <!-- One entry per visit, labelled with the name the admin gave it. Everyone sees\n the first; managers also see the others, plus an icon telling the viewers\n apart - a visitor opens whichever they are given and does not need to know. -->\n <p [ngClass]=\"['view-btn-'+getStringNoSpace(loc.name)]\" *ngFor=\"let visit of visitsToShow(loc)\"\n (click)=\"onVisitClick(loc, visit)\" class=\"visit-name\" [style.cursor]=\"'pointer'\"\n [ngbTooltip]=\"isManagerForSpace(loc.id)\n ? (isThreeJsVisit(visit) ? ('3D model' | translate) : ('Matterport tour' | translate))\n : ''\">\n <span class=\"iconify visit-viewer-icon\" *ngIf=\"isManagerForSpace(loc.id)\"\n [attr.data-icon]=\"isThreeJsVisit(visit) ? 'mdi:cube-scan' : 'mdi:rotate-360'\"\n data-inline=\"false\"></span>\n {{ visit.name ? visit.name : loc.name }}\n </p>\n </div>\n </div>\n </li>\n \n </ul>\n </div>\n <div class=\"col-sm-12 col-md-12 col-lg-6\">\n <lib-map [spaces]=\"filteredLocations\"></lib-map>\n </div>\n </div>\n </section>\n <lib-form-location *ngIf=\"isAdding\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>\n", styles: [".searchbar{margin-bottom:10px}input[type=file]{display:none}.form-control{border-radius:var(--form-control-border-radius)}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}section .list-group{margin-top:15px}section .list-group-item{padding:5px 0}section .location-info{font-size:1.1em}section .location-img{width:100%;object-fit:cover;object-position:center bottom;height:165px}#img_container{position:relative;display:inline-block;text-align:center;width:250px}.img-main-container{max-width:250px;width:250px!important;margin-right:10px}.visit-name{color:var(--smarterplan-primary);font-weight:600}.visit-viewer-icon{margin-right:6px;vertical-align:-2px;opacity:.75}.btn-details{background-color:var(--smarterplan-primary-transparent);position:absolute;color:#fff;bottom:0;right:0;width:100%;height:30%;border:none;font-size:1em;text-transform:lowercase}#btn-icon{width:30px;height:30px;background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:%23565656;}%0A<\\/style>%0A<g>%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0A</g>%0A</svg>%0A');border:none;vertical-align:middle}#btn-icon:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:%234BA4A8;}%0A<\\/style>%0A<g>%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0A</g>%0A</svg>%0A')}#btn-icon[disabled]:hover{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?>%0A<!-- Generator: Adobe Illustrator 25.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->%0A<svg version=\"1.1\" id=\"Calque_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"%0A%09 viewBox=\"0 0 60 60\" style=\"enable-background:new 0 0 60 60;\" xml:space=\"preserve\">%0A<style type=\"text/css\">%0A%09.st0{fill:%23565656;}%0A<\\/style>%0A<g>%0A%09<path class=\"st0\" d=\"M30,47.6c-0.7,0-1.2-0.2-1.6-0.6c-0.4-0.4-0.6-1-0.6-1.6V32.3h-13c-0.7,0-1.2-0.2-1.6-0.6%0A%09%09c-0.4-0.4-0.6-1-0.6-1.6c0-0.7,0.2-1.2,0.6-1.6s1-0.6,1.6-0.6h13V14.6c0-0.7,0.2-1.2,0.6-1.6c0.4-0.4,1-0.6,1.6-0.6%0A%09%09c0.7,0,1.3,0.2,1.7,0.6c0.4,0.4,0.6,1,0.6,1.6v13.1h13c0.7,0,1.2,0.2,1.6,0.6c0.4,0.4,0.6,1,0.6,1.6c0,0.7-0.2,1.2-0.6,1.6%0A%09%09c-0.4,0.4-1,0.6-1.6,0.6h-13v13.1c0,0.7-0.2,1.2-0.6,1.6C31.2,47.4,30.7,47.6,30,47.6z\"/>%0A</g>%0A</svg>%0A')}.outer_circle{background-color:#ebebeb;border-radius:50%;width:32px;height:32px;padding:1px;margin-left:5px}.refreshIcon{color:var(--smarterplan-primary);cursor:pointer}.refreshIcon svg{vertical-align:middle!important}.add-location{width:fit-content}.sp-row{display:flex;flex-direction:row}\n"] }]
636
651
  }], ctorParameters: () => [{ type: i2.SpaceService }, { type: i1.Router }, { type: i2.BaseUserService }, { type: i2.ViewerService }, { type: i2.NavigationService }, { type: i2.NavigatorService }] });
637
652
 
638
653
  class LandmarkPickerComponent {
@@ -800,11 +815,11 @@ class LandmarkPickerComponent {
800
815
  }
801
816
  }
802
817
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LandmarkPickerComponent, deps: [{ token: i2.ViewerService }, { token: i3.TranslateService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
803
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: LandmarkPickerComponent, selector: "lib-landmark-picker", inputs: { visit3dModel: "visit3dModel", sdkKey: "sdkKey", title: "title", value: "value" }, outputs: { pointPicked: "pointPicked" }, viewQueries: [{ propertyName: "iframeRef", first: true, predicate: ["mpFrame"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"landmark-picker border rounded p-2\">\r\n <p *ngIf=\"title\" class=\"fw-bold small mb-1\">{{ title }}</p>\r\n\r\n <iframe #mpFrame width=\"100%\" height=\"380\" frameborder=\"0\" allow=\"xr-spatial-tracking\" allowfullscreen></iframe>\r\n\r\n <div *ngIf=\"loadError\" class=\"text-danger small mt-1\">{{ loadError }}</div>\r\n\r\n <div class=\"d-flex align-items-center mt-2 mb-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary me-3\" [disabled]=\"!isReady\"\r\n (click)=\"startPicking()\">\r\n {{ (isPicking ? 'landmarkPicker.pickButtonPicking' : (lastPicked ? 'landmarkPicker.pickButtonAgain' :\r\n 'landmarkPicker.pickButtonInitial')) | translate }}\r\n </button>\r\n </div>\r\n\r\n <!-- Manual coordinate entry -->\r\n <div class=\"row g-1 align-items-center\">\r\n <div class=\"col-3\">\r\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\r\n [placeholder]=\"'landmarkPicker.placeholderX' | translate\" [(ngModel)]=\"manualX\">\r\n </div>\r\n <div class=\"col-3\">\r\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\r\n [placeholder]=\"'landmarkPicker.placeholderY' | translate\" [(ngModel)]=\"manualY\">\r\n </div>\r\n <div class=\"col-3\">\r\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\r\n [placeholder]=\"'landmarkPicker.placeholderZ' | translate\" [(ngModel)]=\"manualZ\">\r\n </div>\r\n <div class=\"col-3\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary w-100\" (click)=\"applyManualCoordinates()\">\r\n {{ 'landmarkPicker.apply' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <span *ngIf=\"lastPicked\" class=\"text-success small d-block mt-1\">\r\n {{ 'landmarkPicker.confirmed' | translate: { x: lastPicked.x.toFixed(3), y: lastPicked.y.toFixed(3), z:\r\n lastPicked.z.toFixed(3) } }}\r\n </span>\r\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
818
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: LandmarkPickerComponent, selector: "lib-landmark-picker", inputs: { visit3dModel: "visit3dModel", sdkKey: "sdkKey", title: "title", value: "value" }, outputs: { pointPicked: "pointPicked" }, viewQueries: [{ propertyName: "iframeRef", first: true, predicate: ["mpFrame"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"landmark-picker border rounded p-2\">\n <p *ngIf=\"title\" class=\"fw-bold small mb-1\">{{ title }}</p>\n\n <iframe #mpFrame width=\"100%\" height=\"380\" frameborder=\"0\" allow=\"xr-spatial-tracking\" allowfullscreen></iframe>\n\n <div *ngIf=\"loadError\" class=\"text-danger small mt-1\">{{ loadError }}</div>\n\n <div class=\"d-flex align-items-center mt-2 mb-2\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary me-3\" [disabled]=\"!isReady\"\n (click)=\"startPicking()\">\n {{ (isPicking ? 'landmarkPicker.pickButtonPicking' : (lastPicked ? 'landmarkPicker.pickButtonAgain' :\n 'landmarkPicker.pickButtonInitial')) | translate }}\n </button>\n </div>\n\n <!-- Manual coordinate entry -->\n <div class=\"row g-1 align-items-center\">\n <div class=\"col-3\">\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\n [placeholder]=\"'landmarkPicker.placeholderX' | translate\" [(ngModel)]=\"manualX\">\n </div>\n <div class=\"col-3\">\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\n [placeholder]=\"'landmarkPicker.placeholderY' | translate\" [(ngModel)]=\"manualY\">\n </div>\n <div class=\"col-3\">\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\n [placeholder]=\"'landmarkPicker.placeholderZ' | translate\" [(ngModel)]=\"manualZ\">\n </div>\n <div class=\"col-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary w-100\" (click)=\"applyManualCoordinates()\">\n {{ 'landmarkPicker.apply' | translate }}\n </button>\n </div>\n </div>\n\n <span *ngIf=\"lastPicked\" class=\"text-success small d-block mt-1\">\n {{ 'landmarkPicker.confirmed' | translate: { x: lastPicked.x.toFixed(3), y: lastPicked.y.toFixed(3), z:\n lastPicked.z.toFixed(3) } }}\n </span>\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
804
819
  }
805
820
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LandmarkPickerComponent, decorators: [{
806
821
  type: Component,
807
- args: [{ selector: 'lib-landmark-picker', template: "<div class=\"landmark-picker border rounded p-2\">\r\n <p *ngIf=\"title\" class=\"fw-bold small mb-1\">{{ title }}</p>\r\n\r\n <iframe #mpFrame width=\"100%\" height=\"380\" frameborder=\"0\" allow=\"xr-spatial-tracking\" allowfullscreen></iframe>\r\n\r\n <div *ngIf=\"loadError\" class=\"text-danger small mt-1\">{{ loadError }}</div>\r\n\r\n <div class=\"d-flex align-items-center mt-2 mb-2\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary me-3\" [disabled]=\"!isReady\"\r\n (click)=\"startPicking()\">\r\n {{ (isPicking ? 'landmarkPicker.pickButtonPicking' : (lastPicked ? 'landmarkPicker.pickButtonAgain' :\r\n 'landmarkPicker.pickButtonInitial')) | translate }}\r\n </button>\r\n </div>\r\n\r\n <!-- Manual coordinate entry -->\r\n <div class=\"row g-1 align-items-center\">\r\n <div class=\"col-3\">\r\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\r\n [placeholder]=\"'landmarkPicker.placeholderX' | translate\" [(ngModel)]=\"manualX\">\r\n </div>\r\n <div class=\"col-3\">\r\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\r\n [placeholder]=\"'landmarkPicker.placeholderY' | translate\" [(ngModel)]=\"manualY\">\r\n </div>\r\n <div class=\"col-3\">\r\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\r\n [placeholder]=\"'landmarkPicker.placeholderZ' | translate\" [(ngModel)]=\"manualZ\">\r\n </div>\r\n <div class=\"col-3\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary w-100\" (click)=\"applyManualCoordinates()\">\r\n {{ 'landmarkPicker.apply' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <span *ngIf=\"lastPicked\" class=\"text-success small d-block mt-1\">\r\n {{ 'landmarkPicker.confirmed' | translate: { x: lastPicked.x.toFixed(3), y: lastPicked.y.toFixed(3), z:\r\n lastPicked.z.toFixed(3) } }}\r\n </span>\r\n</div>" }]
822
+ args: [{ selector: 'lib-landmark-picker', template: "<div class=\"landmark-picker border rounded p-2\">\n <p *ngIf=\"title\" class=\"fw-bold small mb-1\">{{ title }}</p>\n\n <iframe #mpFrame width=\"100%\" height=\"380\" frameborder=\"0\" allow=\"xr-spatial-tracking\" allowfullscreen></iframe>\n\n <div *ngIf=\"loadError\" class=\"text-danger small mt-1\">{{ loadError }}</div>\n\n <div class=\"d-flex align-items-center mt-2 mb-2\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary me-3\" [disabled]=\"!isReady\"\n (click)=\"startPicking()\">\n {{ (isPicking ? 'landmarkPicker.pickButtonPicking' : (lastPicked ? 'landmarkPicker.pickButtonAgain' :\n 'landmarkPicker.pickButtonInitial')) | translate }}\n </button>\n </div>\n\n <!-- Manual coordinate entry -->\n <div class=\"row g-1 align-items-center\">\n <div class=\"col-3\">\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\n [placeholder]=\"'landmarkPicker.placeholderX' | translate\" [(ngModel)]=\"manualX\">\n </div>\n <div class=\"col-3\">\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\n [placeholder]=\"'landmarkPicker.placeholderY' | translate\" [(ngModel)]=\"manualY\">\n </div>\n <div class=\"col-3\">\n <input type=\"number\" step=\"0.001\" class=\"form-control form-control-sm\"\n [placeholder]=\"'landmarkPicker.placeholderZ' | translate\" [(ngModel)]=\"manualZ\">\n </div>\n <div class=\"col-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary w-100\" (click)=\"applyManualCoordinates()\">\n {{ 'landmarkPicker.apply' | translate }}\n </button>\n </div>\n </div>\n\n <span *ngIf=\"lastPicked\" class=\"text-success small d-block mt-1\">\n {{ 'landmarkPicker.confirmed' | translate: { x: lastPicked.x.toFixed(3), y: lastPicked.y.toFixed(3), z:\n lastPicked.z.toFixed(3) } }}\n </span>\n</div>" }]
808
823
  }], ctorParameters: () => [{ type: i2.ViewerService }, { type: i3.TranslateService }, { type: i0.NgZone }], propDecorators: { visit3dModel: [{
809
824
  type: Input
810
825
  }], sdkKey: [{
@@ -860,6 +875,10 @@ class DetailLocationComponent {
860
875
  // Visits available for the selected source space, and for the current (target) space
861
876
  sourceVisits = [];
862
877
  visits = [];
878
+ /** The capture a visitor opens by default, of any viewer type. Null means none chosen. */
879
+ defaultCaptureID = null;
880
+ savingDefaultCapture = false;
881
+ defaultCaptureError = null;
863
882
  // 3D landmark points picked directly in each viewer (source and target)
864
883
  landmarkSourceA = null;
865
884
  landmarkTargetA = null;
@@ -922,6 +941,7 @@ class DetailLocationComponent {
922
941
  }
923
942
  // Visits (3D models) belonging to the CURRENT space, used as copy targets
924
943
  this.visits = await this.visitService.getVisitsForSpaceForUser(this.id);
944
+ this.defaultCaptureID = this.space?.defaultCaptureID ?? null;
925
945
  }
926
946
  setupMenuItems() {
927
947
  this.menuItems = [
@@ -1041,6 +1061,37 @@ class DetailLocationComponent {
1041
1061
  }, 1500);
1042
1062
  }
1043
1063
  //
1064
+ /**
1065
+ * Stores which capture a visitor opens by default.
1066
+ *
1067
+ * One field on the space, not a flag per capture, so the two admin screens cannot disagree:
1068
+ * setting it from either one writes the same place, and there is nothing to clear elsewhere.
1069
+ */
1070
+ async onDefaultCaptureChange() {
1071
+ this.savingDefaultCapture = true;
1072
+ this.defaultCaptureError = null;
1073
+ try {
1074
+ await this.spaceService.setDefaultCapture(this.id, this.defaultCaptureID || null);
1075
+ this.space.defaultCaptureID = this.defaultCaptureID || null;
1076
+ }
1077
+ catch (error) {
1078
+ // Until the schema change is deployed, AppSync rejects the field outright. Say so
1079
+ // rather than leaving the picker looking as though it saved.
1080
+ const graphQl = error?.errors;
1081
+ this.defaultCaptureError = Array.isArray(graphQl) && graphQl.length > 0
1082
+ ? graphQl.map((e) => e?.message ?? JSON.stringify(e)).join(' | ')
1083
+ : (error?.message ?? String(error));
1084
+ this.defaultCaptureID = this.space?.defaultCaptureID ?? null;
1085
+ }
1086
+ finally {
1087
+ this.savingDefaultCapture = false;
1088
+ }
1089
+ }
1090
+ /** Label for a visit in the default picker, naming the viewer it opens in. */
1091
+ visitLabel(visit) {
1092
+ const name = visit?.name || visit?.model3d || '';
1093
+ return visit?.viewer === CaptureViewer.THREEJS ? `${name} (3D)` : `${name} (Matterport)`;
1094
+ }
1044
1095
  // ---------- Copy POIs between visits ----------
1045
1096
  //
1046
1097
  /** Toggles visibility of the admin "copy POIs from another location" form. */
@@ -1185,11 +1236,11 @@ class DetailLocationComponent {
1185
1236
  }
1186
1237
  }
1187
1238
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DetailLocationComponent, deps: [{ token: MATTERPORT_SDK_KEY }, { token: i1.ActivatedRoute }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i1.Router }, { token: i2.BaseUserService }, { token: i3.TranslateService }, { token: i2.NavigatorService }, { token: i2.MatterportTagCopyService }], target: i0.ɵɵFactoryTarget.Component });
1188
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DetailLocationComponent, selector: "lib-detail-location", ngImport: i0, template: "<div class=\"container-fluid\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\r\n </div>\r\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\r\n translate}}</button>\r\n <div class=\"row\" *ngIf=\"!isEditing && space\">\r\n <div class=\"col-md-5\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\r\n {{space.constructionYear ?\r\n space.constructionYear : \"No data\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\r\n {{space.latitude ?\r\n space.latitude : \"No data\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\r\n space.longitude : \"No data\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\r\n }} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\r\n {{space.classEnergyConsumption ?\r\n space.classEnergyConsumption : \"No data\" | translate}}\r\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\r\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\r\n {{'Get data from API DPE' | translate}}</button>\r\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\r\n style=\"cursor: pointer;\">\r\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\r\n data-height=\"25\"></span>\r\n {{'DPE data found. Click to validate' | translate}}\r\n </a>\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\r\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\r\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\r\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\r\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\r\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\r\n triggers=\"click:blur\">\r\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\r\n data-height=\"20\"></span>\r\n </div>\r\n </div>\r\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\r\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\r\n </p>\r\n </li>\r\n\r\n </ul>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n <hr>\r\n <div class=\"d-flex\">\r\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\r\n data-testid=\"location-edit-btn\">{{'Edit' |\r\n translate}}</button>\r\n <div class=\"tooltip-wrapper\"\r\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\r\n {{'Archive' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n\r\n </div>\r\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\r\n <h6>{{'Most relevant results for' | translate}} :\r\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\r\n </h6>\r\n <table class=\"table table-striped\">\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">#</th>\r\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\r\n <th scope=\"col\">{{'Address' | translate}}</th>\r\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\r\n <th scope=\"col\">{{'Construction year' | translate}}</th>\r\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\r\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\r\n <th scope=\"row\">{{ i + 1 }}</th>\r\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\r\n (change)=\"onSelectChange(result)\"></td>\r\n <td>{{result.geo_adresse}}</td>\r\n <td>{{result.secteur_activite}}</td>\r\n <td>{{ result.annee_construction }}</td>\r\n <td>{{ result.classe_consommation_energie }}</td>\r\n <td>{{ result.classe_estimation_ges }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\r\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\r\n translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\r\n {{'No match (erase data)' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Toggle button for the admin \"Copy POIs\" form -->\r\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\r\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\r\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\r\n </button>\r\n </div>\r\n\r\n <!-- Admin Form to Copy POIs -->\r\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\r\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\r\n\r\n <div class=\"mb-3 col-md-5\">\r\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\r\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\r\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\r\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\r\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\r\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\r\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\r\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-3 col-md-5\">\r\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\r\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\r\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\r\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\r\n </select>\r\n </div>\r\n\r\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\r\n class=\"border rounded p-3 mb-3 bg-white\">\r\n <p class=\"small text-muted mb-2\">\r\n {{ 'matterportCopy.landmarkInstructions' | translate }}\r\n </p>\r\n\r\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\r\n <div class=\"row mb-4\">\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\r\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\r\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n </div>\r\n\r\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\r\n <div class=\"row\">\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\r\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\r\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center pt-2\">\r\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\r\n (click)=\"onCopyPois()\">\r\n {{ 'matterportCopy.copyButton' | translate }}\r\n </button>\r\n <div class=\"d-flex align-items-center gap-2 mb-3\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\r\n {{ 'matterportCopy.exportLandmarks' | translate }}\r\n </button>\r\n\r\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\r\n {{ 'matterportCopy.importLandmarks' | translate }}\r\n <input type=\"file\" accept=\"application/json\" hidden\r\n (change)=\"onImportLandmarkConfigSelected($event)\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\r\n {{ copyPoisResultMsg }}\r\n </div>\r\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\r\n <div class=\"d-flex justify-content-between small mb-1\">\r\n <span>\r\n <ng-container [ngSwitch]=\"copyProgress.phase\">\r\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\r\n }}</span>\r\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\r\n </ng-container>\r\n </span>\r\n <span>{{ copyProgress.percent }}%</span>\r\n </div>\r\n <div class=\"progress\" style=\"height: 6px;\">\r\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\r\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\r\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\r\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\r\n </div>\r\n </div>\r\n\r\n <!-- Detailed step-by-step log -->\r\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\r\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\r\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\r\n [class.text-warning]=\"entry.type === 'healed'\">\r\n {{ entry.text }}\r\n </div>\r\n </div>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\r\n (click)=\"downloadCopyLog()\">\r\n {{ 'matterportCopy.downloadLog' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\r\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i4$2.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "directive", type: i4$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LandmarkPickerComponent, selector: "lib-landmark-picker", inputs: ["visit3dModel", "sdkKey", "title", "value"], outputs: ["pointPicked"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: FormLocationComponent, selector: "lib-form-location", inputs: ["location"], outputs: ["onChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
1239
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DetailLocationComponent, selector: "lib-detail-location", ngImport: i0, template: "<div class=\"container-fluid\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\n </div>\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\n translate}}</button>\n <div class=\"row\" *ngIf=\"!isEditing && space\">\n <div class=\"col-md-5\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\n {{space.constructionYear ?\n space.constructionYear : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\n {{space.latitude ?\n space.latitude : \"No data\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\n space.longitude : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\n }} </li>\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\n {{space.classEnergyConsumption ?\n space.classEnergyConsumption : \"No data\" | translate}}\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\n {{'Get data from API DPE' | translate}}</button>\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\n style=\"cursor: pointer;\">\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\n data-height=\"25\"></span>\n {{'DPE data found. Click to validate' | translate}}\n </a>\n </li>\n <!-- One picker for both viewers: the default lives on the space, so Matterport\n captures and 3D models compete for the same single slot. -->\n <li class=\"list-group-item bg-transparent\" *ngIf=\"visits.length > 1\">\n {{'Default visit' | translate}}:\n <select class=\"form-select d-inline-block ms-2\" style=\"width: auto;\"\n [(ngModel)]=\"defaultCaptureID\" (ngModelChange)=\"onDefaultCaptureChange()\"\n [disabled]=\"savingDefaultCapture\">\n <option [ngValue]=\"null\">{{'First available' | translate}}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.captureID\">\n {{ visitLabel(visit) }}\n </option>\n </select>\n <span class=\"form-text d-block\">\n {{'What a visitor opens when they enter this location.' | translate}}\n </span>\n <span class=\"text-danger d-block\" *ngIf=\"defaultCaptureError\">\n {{ defaultCaptureError }}\n </span>\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\n triggers=\"click:blur\">\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\n data-height=\"20\"></span>\n </div>\n </div>\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\n </p>\n </li>\n\n </ul>\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <hr>\n <div class=\"d-flex\">\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\n data-testid=\"location-edit-btn\">{{'Edit' |\n translate}}</button>\n <div class=\"tooltip-wrapper\"\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\n {{'Archive' | translate}}</button>\n </div>\n </div>\n\n\n </div>\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\n <h6>{{'Most relevant results for' | translate}} :\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\n </h6>\n <table class=\"table table-striped\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\n <th scope=\"col\">{{'Address' | translate}}</th>\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\n <th scope=\"col\">{{'Construction year' | translate}}</th>\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\n (change)=\"onSelectChange(result)\"></td>\n <td>{{result.geo_adresse}}</td>\n <td>{{result.secteur_activite}}</td>\n <td>{{ result.annee_construction }}</td>\n <td>{{ result.classe_consommation_energie }}</td>\n <td>{{ result.classe_estimation_ges }}</td>\n </tr>\n </tbody>\n </table>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\n {{'No match (erase data)' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n\n <!-- Toggle button for the admin \"Copy POIs\" form -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\n </button>\n </div>\n\n <!-- Admin Form to Copy POIs -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\n class=\"border rounded p-3 mb-3 bg-white\">\n <p class=\"small text-muted mb-2\">\n {{ 'matterportCopy.landmarkInstructions' | translate }}\n </p>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\n <div class=\"row mb-4\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\n <div class=\"row\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex align-items-center pt-2\">\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\n (click)=\"onCopyPois()\">\n {{ 'matterportCopy.copyButton' | translate }}\n </button>\n <div class=\"d-flex align-items-center gap-2 mb-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\n {{ 'matterportCopy.exportLandmarks' | translate }}\n </button>\n\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\n {{ 'matterportCopy.importLandmarks' | translate }}\n <input type=\"file\" accept=\"application/json\" hidden\n (change)=\"onImportLandmarkConfigSelected($event)\">\n </label>\n </div>\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\n {{ copyPoisResultMsg }}\n </div>\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\n <div class=\"d-flex justify-content-between small mb-1\">\n <span>\n <ng-container [ngSwitch]=\"copyProgress.phase\">\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\n }}</span>\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\n </ng-container>\n </span>\n <span>{{ copyProgress.percent }}%</span>\n </div>\n <div class=\"progress\" style=\"height: 6px;\">\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\n </div>\n </div>\n\n <!-- Detailed step-by-step log -->\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\n [class.text-warning]=\"entry.type === 'healed'\">\n {{ entry.text }}\n </div>\n </div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\n (click)=\"downloadCopyLog()\">\n {{ 'matterportCopy.downloadLog' | translate }}\n </button>\n </div>\n </div>\n\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i4$1.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "directive", type: i3$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LandmarkPickerComponent, selector: "lib-landmark-picker", inputs: ["visit3dModel", "sdkKey", "title", "value"], outputs: ["pointPicked"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: FormLocationComponent, selector: "lib-form-location", inputs: ["location"], outputs: ["onChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
1189
1240
  }
1190
1241
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DetailLocationComponent, decorators: [{
1191
1242
  type: Component,
1192
- args: [{ selector: 'lib-detail-location', template: "<div class=\"container-fluid\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\r\n </div>\r\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\r\n translate}}</button>\r\n <div class=\"row\" *ngIf=\"!isEditing && space\">\r\n <div class=\"col-md-5\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\r\n {{space.constructionYear ?\r\n space.constructionYear : \"No data\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\r\n {{space.latitude ?\r\n space.latitude : \"No data\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\r\n space.longitude : \"No data\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\r\n }} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\r\n {{space.classEnergyConsumption ?\r\n space.classEnergyConsumption : \"No data\" | translate}}\r\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\r\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\r\n {{'Get data from API DPE' | translate}}</button>\r\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\r\n style=\"cursor: pointer;\">\r\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\r\n data-height=\"25\"></span>\r\n {{'DPE data found. Click to validate' | translate}}\r\n </a>\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\r\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\r\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\r\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\r\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\r\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\r\n triggers=\"click:blur\">\r\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\r\n data-height=\"20\"></span>\r\n </div>\r\n </div>\r\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\r\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\r\n </p>\r\n </li>\r\n\r\n </ul>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n <hr>\r\n <div class=\"d-flex\">\r\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\r\n data-testid=\"location-edit-btn\">{{'Edit' |\r\n translate}}</button>\r\n <div class=\"tooltip-wrapper\"\r\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\r\n {{'Archive' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n\r\n </div>\r\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\r\n <h6>{{'Most relevant results for' | translate}} :\r\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\r\n </h6>\r\n <table class=\"table table-striped\">\r\n <thead>\r\n <tr>\r\n <th scope=\"col\">#</th>\r\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\r\n <th scope=\"col\">{{'Address' | translate}}</th>\r\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\r\n <th scope=\"col\">{{'Construction year' | translate}}</th>\r\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\r\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\r\n <th scope=\"row\">{{ i + 1 }}</th>\r\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\r\n (change)=\"onSelectChange(result)\"></td>\r\n <td>{{result.geo_adresse}}</td>\r\n <td>{{result.secteur_activite}}</td>\r\n <td>{{ result.annee_construction }}</td>\r\n <td>{{ result.classe_consommation_energie }}</td>\r\n <td>{{ result.classe_estimation_ges }}</td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\r\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\r\n translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\r\n {{'No match (erase data)' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Toggle button for the admin \"Copy POIs\" form -->\r\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\r\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\r\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\r\n </button>\r\n </div>\r\n\r\n <!-- Admin Form to Copy POIs -->\r\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\r\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\r\n\r\n <div class=\"mb-3 col-md-5\">\r\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\r\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\r\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\r\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\r\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\r\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\r\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\r\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\r\n </select>\r\n </div>\r\n\r\n <div class=\"mb-3 col-md-5\">\r\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\r\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\r\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\r\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\r\n </select>\r\n </div>\r\n\r\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\r\n class=\"border rounded p-3 mb-3 bg-white\">\r\n <p class=\"small text-muted mb-2\">\r\n {{ 'matterportCopy.landmarkInstructions' | translate }}\r\n </p>\r\n\r\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\r\n <div class=\"row mb-4\">\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\r\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\r\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n </div>\r\n\r\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\r\n <div class=\"row\">\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\r\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n <div class=\"col-6\">\r\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\r\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\r\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\r\n </lib-landmark-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex align-items-center pt-2\">\r\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\r\n (click)=\"onCopyPois()\">\r\n {{ 'matterportCopy.copyButton' | translate }}\r\n </button>\r\n <div class=\"d-flex align-items-center gap-2 mb-3\">\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\r\n {{ 'matterportCopy.exportLandmarks' | translate }}\r\n </button>\r\n\r\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\r\n {{ 'matterportCopy.importLandmarks' | translate }}\r\n <input type=\"file\" accept=\"application/json\" hidden\r\n (change)=\"onImportLandmarkConfigSelected($event)\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\r\n {{ copyPoisResultMsg }}\r\n </div>\r\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\r\n <div class=\"d-flex justify-content-between small mb-1\">\r\n <span>\r\n <ng-container [ngSwitch]=\"copyProgress.phase\">\r\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\r\n }}</span>\r\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\r\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\r\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\r\n </ng-container>\r\n </span>\r\n <span>{{ copyProgress.percent }}%</span>\r\n </div>\r\n <div class=\"progress\" style=\"height: 6px;\">\r\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\r\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\r\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\r\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\r\n </div>\r\n </div>\r\n\r\n <!-- Detailed step-by-step log -->\r\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\r\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\r\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\r\n [class.text-warning]=\"entry.type === 'healed'\">\r\n {{ entry.text }}\r\n </div>\r\n </div>\r\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\r\n (click)=\"downloadCopyLog()\">\r\n {{ 'matterportCopy.downloadLog' | translate }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\r\n</div>" }]
1243
+ args: [{ selector: 'lib-detail-location', template: "<div class=\"container-fluid\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\n </div>\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\n translate}}</button>\n <div class=\"row\" *ngIf=\"!isEditing && space\">\n <div class=\"col-md-5\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\n {{space.constructionYear ?\n space.constructionYear : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\n {{space.latitude ?\n space.latitude : \"No data\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\n space.longitude : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\n }} </li>\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\n {{space.classEnergyConsumption ?\n space.classEnergyConsumption : \"No data\" | translate}}\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\n {{'Get data from API DPE' | translate}}</button>\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\n style=\"cursor: pointer;\">\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\n data-height=\"25\"></span>\n {{'DPE data found. Click to validate' | translate}}\n </a>\n </li>\n <!-- One picker for both viewers: the default lives on the space, so Matterport\n captures and 3D models compete for the same single slot. -->\n <li class=\"list-group-item bg-transparent\" *ngIf=\"visits.length > 1\">\n {{'Default visit' | translate}}:\n <select class=\"form-select d-inline-block ms-2\" style=\"width: auto;\"\n [(ngModel)]=\"defaultCaptureID\" (ngModelChange)=\"onDefaultCaptureChange()\"\n [disabled]=\"savingDefaultCapture\">\n <option [ngValue]=\"null\">{{'First available' | translate}}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.captureID\">\n {{ visitLabel(visit) }}\n </option>\n </select>\n <span class=\"form-text d-block\">\n {{'What a visitor opens when they enter this location.' | translate}}\n </span>\n <span class=\"text-danger d-block\" *ngIf=\"defaultCaptureError\">\n {{ defaultCaptureError }}\n </span>\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\n triggers=\"click:blur\">\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\n data-height=\"20\"></span>\n </div>\n </div>\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\n </p>\n </li>\n\n </ul>\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <hr>\n <div class=\"d-flex\">\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\n data-testid=\"location-edit-btn\">{{'Edit' |\n translate}}</button>\n <div class=\"tooltip-wrapper\"\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\n {{'Archive' | translate}}</button>\n </div>\n </div>\n\n\n </div>\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\n <h6>{{'Most relevant results for' | translate}} :\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\n </h6>\n <table class=\"table table-striped\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\n <th scope=\"col\">{{'Address' | translate}}</th>\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\n <th scope=\"col\">{{'Construction year' | translate}}</th>\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\n (change)=\"onSelectChange(result)\"></td>\n <td>{{result.geo_adresse}}</td>\n <td>{{result.secteur_activite}}</td>\n <td>{{ result.annee_construction }}</td>\n <td>{{ result.classe_consommation_energie }}</td>\n <td>{{ result.classe_estimation_ges }}</td>\n </tr>\n </tbody>\n </table>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\n {{'No match (erase data)' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n\n <!-- Toggle button for the admin \"Copy POIs\" form -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\n </button>\n </div>\n\n <!-- Admin Form to Copy POIs -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\n class=\"border rounded p-3 mb-3 bg-white\">\n <p class=\"small text-muted mb-2\">\n {{ 'matterportCopy.landmarkInstructions' | translate }}\n </p>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\n <div class=\"row mb-4\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\n <div class=\"row\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex align-items-center pt-2\">\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\n (click)=\"onCopyPois()\">\n {{ 'matterportCopy.copyButton' | translate }}\n </button>\n <div class=\"d-flex align-items-center gap-2 mb-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\n {{ 'matterportCopy.exportLandmarks' | translate }}\n </button>\n\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\n {{ 'matterportCopy.importLandmarks' | translate }}\n <input type=\"file\" accept=\"application/json\" hidden\n (change)=\"onImportLandmarkConfigSelected($event)\">\n </label>\n </div>\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\n {{ copyPoisResultMsg }}\n </div>\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\n <div class=\"d-flex justify-content-between small mb-1\">\n <span>\n <ng-container [ngSwitch]=\"copyProgress.phase\">\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\n }}</span>\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\n </ng-container>\n </span>\n <span>{{ copyProgress.percent }}%</span>\n </div>\n <div class=\"progress\" style=\"height: 6px;\">\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\n </div>\n </div>\n\n <!-- Detailed step-by-step log -->\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\n [class.text-warning]=\"entry.type === 'healed'\">\n {{ entry.text }}\n </div>\n </div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\n (click)=\"downloadCopyLog()\">\n {{ 'matterportCopy.downloadLog' | translate }}\n </button>\n </div>\n </div>\n\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>" }]
1193
1244
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1194
1245
  type: Inject,
1195
1246
  args: [MATTERPORT_SDK_KEY]
@@ -1664,11 +1715,11 @@ class CalibrationComponent {
1664
1715
  }
1665
1716
  }
1666
1717
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalibrationComponent, deps: [{ token: i2.MatterportImportService }, { token: i2.PlanService }, { token: i1.ActivatedRoute }, { token: i1.Router }, { token: i2.ZoneService }, { token: i2.SpaceService }, { token: i2.NavigationService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
1667
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CalibrationComponent, selector: "lib-calibration", viewQueries: [{ propertyName: "canvasDiv", first: true, predicate: ["canvasDiv"], descendants: true }], ngImport: i0, template: "<div class=\"row mt-3\">\r\n <div class=\"col\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div id=\"rowCanvas\">\r\n <div #canvasDiv id=\"canvasDiv\">\r\n\r\n <div id=\"viewer-frame\" [style.pointer-events]=\"zoomCanBeChanged?'auto':'none'\">\r\n <!-- <div class=\"blur\"></div> -->\r\n </div>\r\n <canvas id=\"canvas\" [ngStyle]=\"{'opacity': (preview||loading) ? '1' : 'calc(' + opacity + '/ 100)'}\"></canvas>\r\n </div>\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"!(preview || loading)\">\r\n <h1>{{'Calibration tool' | translate}}</h1>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 legend\">\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (-(opacity-100)+10) + '/ 100)'}\">\r\n {{'Less' | translate}}</div>\r\n <div class=\"legend-title\">{{'Plan Opacity' | translate }}</div>\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (opacity+10) + '/ 100)'}\">{{'More' |\r\n translate}}</div>\r\n </div>\r\n <div class=\"row ms-0 me-0 \">\r\n <input [disabled]=\"false\" [ngModelOptions]=\"{standalone: true}\" [(ngModel)]=\"opacity\" type=\"range\"\r\n class=\"form-range\" min=\"0\" max=\"100\" value=\"50\" id=\"opacity\">\r\n </div>\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"label-legend\">{{'Change Visit Floor' | translate}}</div>\r\n <div ngbDropdown class=\"d-inline-block ms-3\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>\r\n {{currentFloor ? currentFloor.id : ('Floor' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let floor of floors\" (click)=\"onFloorClick(floor)\">\r\n {{ floor.name.length > 0 ? floor.name : ('Floor ' + floor.id) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"tool-checkbox-container\">\r\n <div class=\"tool-checkbox-subcontainer\">\r\n <div class=\"label-legend me-3\">{{'Pan/Zoom Visit' | translate}} {{zoomCanBeChanged ? \"ON\" :\r\n \"OFF\"}}\r\n </div>\r\n <input type=\"checkbox\" (change)=\"onActivateZoomChange()\" style=\"margin-top: 5px;\">\r\n </div>\r\n <div class=\"card border-warning mb-3 mt-3\" *ngIf=\"zoomCanBeChanged\">\r\n <div class=\"card-body text-warning\">\r\n <h5 class=\"card-title\">{{\"calibration.wait-message\" | translate}}</h5>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onPreview()\"\r\n [disabled]=\"zoomCanBeChanged\">{{'Preview' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n\r\n </div>\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"preview\">\r\n <h1>{{'Validation' | translate}}</h1>\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onSave()\">{{'Validate' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onReset()\">{{'Reset' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"loading\">\r\n <h3>{{\"Waiting for Matterport\" | translate}}...</h3>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n</div>", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}#rowCanvas{display:flex}#canvasDiv{height:100%;width:100%;position:relative}#canvas{width:100%;height:100%;opacity:.5}#viewer-frame{top:0;position:absolute;width:100%;height:100%}.calibration-tools{margin-left:20px;width:400px;background-color:#fff;z-index:11;border:1px solid var(--smarterplan-primary);padding:7px}.form-range{width:100%}.tool{margin-top:20px}.tool .legend{justify-content:space-between;position:relative;margin-bottom:5px}.tool .legend-title{font-size:1.2rem;color:var(--smarterplan-primary);margin:auto;width:100%;font-weight:700;display:flex;justify-content:center}.tool .legend-bar-indicator{width:15%!important}.tool .label-legend{color:var(--smarterplan-primary);font-size:1.1rem;max-width:55%}.tool .tool-checkbox-container{display:flex;flex-direction:column}.tool .tool-checkbox-container .tool-checkbox-subcontainer{display:flex}.blur{width:150px;height:52px;position:absolute;background-color:#1e2023;bottom:0}.symmetry{padding:5px;border:solid 2px;border-radius:10px;color:var(--smarterplan-primary);margin:25px 10px;cursor:pointer}.symmetry:hover{color:var(--smarterplan-primary)}.symmetry-row{justify-content:center}.action{margin-top:30px;display:flex;justify-content:space-evenly}h1{color:var(--smarterplan-primary);text-align:center;margin-bottom:20px}h3{color:var(--smarterplan-primary);text-align:center;margin-bottom:10px}.btn-outline-primary.disabled{background-color:var(--smarterplan-orange)!important}\n"], dependencies: [{ kind: "directive", type: i4$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i4$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i4$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i4$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i4$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
1718
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CalibrationComponent, selector: "lib-calibration", viewQueries: [{ propertyName: "canvasDiv", first: true, predicate: ["canvasDiv"], descendants: true }], ngImport: i0, template: "<div class=\"row mt-3\">\n <div class=\"col\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\n </div>\n </div>\n</div>\n\n<div id=\"rowCanvas\">\n <div #canvasDiv id=\"canvasDiv\">\n\n <div id=\"viewer-frame\" [style.pointer-events]=\"zoomCanBeChanged?'auto':'none'\">\n <!-- <div class=\"blur\"></div> -->\n </div>\n <canvas id=\"canvas\" [ngStyle]=\"{'opacity': (preview||loading) ? '1' : 'calc(' + opacity + '/ 100)'}\"></canvas>\n </div>\n\n <div class=\"calibration-tools container-fluid\" *ngIf=\"!(preview || loading)\">\n <h1>{{'Calibration tool' | translate}}</h1>\n <div class=\"tool\">\n <div class=\"row ms-0 me-0 legend\">\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (-(opacity-100)+10) + '/ 100)'}\">\n {{'Less' | translate}}</div>\n <div class=\"legend-title\">{{'Plan Opacity' | translate }}</div>\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (opacity+10) + '/ 100)'}\">{{'More' |\n translate}}</div>\n </div>\n <div class=\"row ms-0 me-0 \">\n <input [disabled]=\"false\" [ngModelOptions]=\"{standalone: true}\" [(ngModel)]=\"opacity\" type=\"range\"\n class=\"form-range\" min=\"0\" max=\"100\" value=\"50\" id=\"opacity\">\n </div>\n </div>\n <div class=\"tool\">\n <div class=\"row ms-0 me-0 \">\n <div class=\"label-legend\">{{'Change Visit Floor' | translate}}</div>\n <div ngbDropdown class=\"d-inline-block ms-3\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>\n {{currentFloor ? currentFloor.id : ('Floor' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let floor of floors\" (click)=\"onFloorClick(floor)\">\n {{ floor.name.length > 0 ? floor.name : ('Floor ' + floor.id) }}\n </button>\n </div>\n </div>\n </div>\n\n </div>\n <div class=\"tool\">\n <div class=\"row ms-0 me-0 \">\n <div class=\"tool-checkbox-container\">\n <div class=\"tool-checkbox-subcontainer\">\n <div class=\"label-legend me-3\">{{'Pan/Zoom Visit' | translate}} {{zoomCanBeChanged ? \"ON\" :\n \"OFF\"}}\n </div>\n <input type=\"checkbox\" (change)=\"onActivateZoomChange()\" style=\"margin-top: 5px;\">\n </div>\n <div class=\"card border-warning mb-3 mt-3\" *ngIf=\"zoomCanBeChanged\">\n <div class=\"card-body text-warning\">\n <h5 class=\"card-title\">{{\"calibration.wait-message\" | translate}}</h5>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"action\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onPreview()\"\n [disabled]=\"zoomCanBeChanged\">{{'Preview' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\n translate}}</button>\n\n </div>\n\n </div>\n <div class=\"calibration-tools container-fluid\" *ngIf=\"preview\">\n <h1>{{'Validation' | translate}}</h1>\n <div class=\"action\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onSave()\">{{'Validate' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onReset()\">{{'Reset' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\n translate}}</button>\n\n </div>\n </div>\n\n\n <div class=\"calibration-tools container-fluid\" *ngIf=\"loading\">\n <h3>{{\"Waiting for Matterport\" | translate}}...</h3>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n </div>\n</div>", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}#rowCanvas{display:flex}#canvasDiv{height:100%;width:100%;position:relative}#canvas{width:100%;height:100%;opacity:.5}#viewer-frame{top:0;position:absolute;width:100%;height:100%}.calibration-tools{margin-left:20px;width:400px;background-color:#fff;z-index:11;border:1px solid var(--smarterplan-primary);padding:7px}.form-range{width:100%}.tool{margin-top:20px}.tool .legend{justify-content:space-between;position:relative;margin-bottom:5px}.tool .legend-title{font-size:1.2rem;color:var(--smarterplan-primary);margin:auto;width:100%;font-weight:700;display:flex;justify-content:center}.tool .legend-bar-indicator{width:15%!important}.tool .label-legend{color:var(--smarterplan-primary);font-size:1.1rem;max-width:55%}.tool .tool-checkbox-container{display:flex;flex-direction:column}.tool .tool-checkbox-container .tool-checkbox-subcontainer{display:flex}.blur{width:150px;height:52px;position:absolute;background-color:#1e2023;bottom:0}.symmetry{padding:5px;border:solid 2px;border-radius:10px;color:var(--smarterplan-primary);margin:25px 10px;cursor:pointer}.symmetry:hover{color:var(--smarterplan-primary)}.symmetry-row{justify-content:center}.action{margin-top:30px;display:flex;justify-content:space-evenly}h1{color:var(--smarterplan-primary);text-align:center;margin-bottom:20px}h3{color:var(--smarterplan-primary);text-align:center;margin-bottom:10px}.btn-outline-primary.disabled{background-color:var(--smarterplan-orange)!important}\n"], dependencies: [{ kind: "directive", type: i3$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i3$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i3$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i3$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i3$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
1668
1719
  }
1669
1720
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CalibrationComponent, decorators: [{
1670
1721
  type: Component,
1671
- args: [{ selector: 'lib-calibration', template: "<div class=\"row mt-3\">\r\n <div class=\"col\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div id=\"rowCanvas\">\r\n <div #canvasDiv id=\"canvasDiv\">\r\n\r\n <div id=\"viewer-frame\" [style.pointer-events]=\"zoomCanBeChanged?'auto':'none'\">\r\n <!-- <div class=\"blur\"></div> -->\r\n </div>\r\n <canvas id=\"canvas\" [ngStyle]=\"{'opacity': (preview||loading) ? '1' : 'calc(' + opacity + '/ 100)'}\"></canvas>\r\n </div>\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"!(preview || loading)\">\r\n <h1>{{'Calibration tool' | translate}}</h1>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 legend\">\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (-(opacity-100)+10) + '/ 100)'}\">\r\n {{'Less' | translate}}</div>\r\n <div class=\"legend-title\">{{'Plan Opacity' | translate }}</div>\r\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (opacity+10) + '/ 100)'}\">{{'More' |\r\n translate}}</div>\r\n </div>\r\n <div class=\"row ms-0 me-0 \">\r\n <input [disabled]=\"false\" [ngModelOptions]=\"{standalone: true}\" [(ngModel)]=\"opacity\" type=\"range\"\r\n class=\"form-range\" min=\"0\" max=\"100\" value=\"50\" id=\"opacity\">\r\n </div>\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"label-legend\">{{'Change Visit Floor' | translate}}</div>\r\n <div ngbDropdown class=\"d-inline-block ms-3\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>\r\n {{currentFloor ? currentFloor.id : ('Floor' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let floor of floors\" (click)=\"onFloorClick(floor)\">\r\n {{ floor.name.length > 0 ? floor.name : ('Floor ' + floor.id) }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"tool\">\r\n <div class=\"row ms-0 me-0 \">\r\n <div class=\"tool-checkbox-container\">\r\n <div class=\"tool-checkbox-subcontainer\">\r\n <div class=\"label-legend me-3\">{{'Pan/Zoom Visit' | translate}} {{zoomCanBeChanged ? \"ON\" :\r\n \"OFF\"}}\r\n </div>\r\n <input type=\"checkbox\" (change)=\"onActivateZoomChange()\" style=\"margin-top: 5px;\">\r\n </div>\r\n <div class=\"card border-warning mb-3 mt-3\" *ngIf=\"zoomCanBeChanged\">\r\n <div class=\"card-body text-warning\">\r\n <h5 class=\"card-title\">{{\"calibration.wait-message\" | translate}}</h5>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onPreview()\"\r\n [disabled]=\"zoomCanBeChanged\">{{'Preview' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n\r\n </div>\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"preview\">\r\n <h1>{{'Validation' | translate}}</h1>\r\n <div class=\"action\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onSave()\">{{'Validate' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onReset()\">{{'Reset' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\r\n translate}}</button>\r\n\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"calibration-tools container-fluid\" *ngIf=\"loading\">\r\n <h3>{{\"Waiting for Matterport\" | translate}}...</h3>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n</div>", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}#rowCanvas{display:flex}#canvasDiv{height:100%;width:100%;position:relative}#canvas{width:100%;height:100%;opacity:.5}#viewer-frame{top:0;position:absolute;width:100%;height:100%}.calibration-tools{margin-left:20px;width:400px;background-color:#fff;z-index:11;border:1px solid var(--smarterplan-primary);padding:7px}.form-range{width:100%}.tool{margin-top:20px}.tool .legend{justify-content:space-between;position:relative;margin-bottom:5px}.tool .legend-title{font-size:1.2rem;color:var(--smarterplan-primary);margin:auto;width:100%;font-weight:700;display:flex;justify-content:center}.tool .legend-bar-indicator{width:15%!important}.tool .label-legend{color:var(--smarterplan-primary);font-size:1.1rem;max-width:55%}.tool .tool-checkbox-container{display:flex;flex-direction:column}.tool .tool-checkbox-container .tool-checkbox-subcontainer{display:flex}.blur{width:150px;height:52px;position:absolute;background-color:#1e2023;bottom:0}.symmetry{padding:5px;border:solid 2px;border-radius:10px;color:var(--smarterplan-primary);margin:25px 10px;cursor:pointer}.symmetry:hover{color:var(--smarterplan-primary)}.symmetry-row{justify-content:center}.action{margin-top:30px;display:flex;justify-content:space-evenly}h1{color:var(--smarterplan-primary);text-align:center;margin-bottom:20px}h3{color:var(--smarterplan-primary);text-align:center;margin-bottom:10px}.btn-outline-primary.disabled{background-color:var(--smarterplan-orange)!important}\n"] }]
1722
+ args: [{ selector: 'lib-calibration', template: "<div class=\"row mt-3\">\n <div class=\"col\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\n </div>\n </div>\n</div>\n\n<div id=\"rowCanvas\">\n <div #canvasDiv id=\"canvasDiv\">\n\n <div id=\"viewer-frame\" [style.pointer-events]=\"zoomCanBeChanged?'auto':'none'\">\n <!-- <div class=\"blur\"></div> -->\n </div>\n <canvas id=\"canvas\" [ngStyle]=\"{'opacity': (preview||loading) ? '1' : 'calc(' + opacity + '/ 100)'}\"></canvas>\n </div>\n\n <div class=\"calibration-tools container-fluid\" *ngIf=\"!(preview || loading)\">\n <h1>{{'Calibration tool' | translate}}</h1>\n <div class=\"tool\">\n <div class=\"row ms-0 me-0 legend\">\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (-(opacity-100)+10) + '/ 100)'}\">\n {{'Less' | translate}}</div>\n <div class=\"legend-title\">{{'Plan Opacity' | translate }}</div>\n <div class=\"legend-bar-indicator\" [ngStyle]=\"{'opacity': 'calc(' + (opacity+10) + '/ 100)'}\">{{'More' |\n translate}}</div>\n </div>\n <div class=\"row ms-0 me-0 \">\n <input [disabled]=\"false\" [ngModelOptions]=\"{standalone: true}\" [(ngModel)]=\"opacity\" type=\"range\"\n class=\"form-range\" min=\"0\" max=\"100\" value=\"50\" id=\"opacity\">\n </div>\n </div>\n <div class=\"tool\">\n <div class=\"row ms-0 me-0 \">\n <div class=\"label-legend\">{{'Change Visit Floor' | translate}}</div>\n <div ngbDropdown class=\"d-inline-block ms-3\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>\n {{currentFloor ? currentFloor.id : ('Floor' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let floor of floors\" (click)=\"onFloorClick(floor)\">\n {{ floor.name.length > 0 ? floor.name : ('Floor ' + floor.id) }}\n </button>\n </div>\n </div>\n </div>\n\n </div>\n <div class=\"tool\">\n <div class=\"row ms-0 me-0 \">\n <div class=\"tool-checkbox-container\">\n <div class=\"tool-checkbox-subcontainer\">\n <div class=\"label-legend me-3\">{{'Pan/Zoom Visit' | translate}} {{zoomCanBeChanged ? \"ON\" :\n \"OFF\"}}\n </div>\n <input type=\"checkbox\" (change)=\"onActivateZoomChange()\" style=\"margin-top: 5px;\">\n </div>\n <div class=\"card border-warning mb-3 mt-3\" *ngIf=\"zoomCanBeChanged\">\n <div class=\"card-body text-warning\">\n <h5 class=\"card-title\">{{\"calibration.wait-message\" | translate}}</h5>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"action\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onPreview()\"\n [disabled]=\"zoomCanBeChanged\">{{'Preview' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\n translate}}</button>\n\n </div>\n\n </div>\n <div class=\"calibration-tools container-fluid\" *ngIf=\"preview\">\n <h1>{{'Validation' | translate}}</h1>\n <div class=\"action\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onSave()\">{{'Validate' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onReset()\">{{'Reset' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' |\n translate}}</button>\n\n </div>\n </div>\n\n\n <div class=\"calibration-tools container-fluid\" *ngIf=\"loading\">\n <h3>{{\"Waiting for Matterport\" | translate}}...</h3>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n </div>\n</div>", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}#rowCanvas{display:flex}#canvasDiv{height:100%;width:100%;position:relative}#canvas{width:100%;height:100%;opacity:.5}#viewer-frame{top:0;position:absolute;width:100%;height:100%}.calibration-tools{margin-left:20px;width:400px;background-color:#fff;z-index:11;border:1px solid var(--smarterplan-primary);padding:7px}.form-range{width:100%}.tool{margin-top:20px}.tool .legend{justify-content:space-between;position:relative;margin-bottom:5px}.tool .legend-title{font-size:1.2rem;color:var(--smarterplan-primary);margin:auto;width:100%;font-weight:700;display:flex;justify-content:center}.tool .legend-bar-indicator{width:15%!important}.tool .label-legend{color:var(--smarterplan-primary);font-size:1.1rem;max-width:55%}.tool .tool-checkbox-container{display:flex;flex-direction:column}.tool .tool-checkbox-container .tool-checkbox-subcontainer{display:flex}.blur{width:150px;height:52px;position:absolute;background-color:#1e2023;bottom:0}.symmetry{padding:5px;border:solid 2px;border-radius:10px;color:var(--smarterplan-primary);margin:25px 10px;cursor:pointer}.symmetry:hover{color:var(--smarterplan-primary)}.symmetry-row{justify-content:center}.action{margin-top:30px;display:flex;justify-content:space-evenly}h1{color:var(--smarterplan-primary);text-align:center;margin-bottom:20px}h3{color:var(--smarterplan-primary);text-align:center;margin-bottom:10px}.btn-outline-primary.disabled{background-color:var(--smarterplan-orange)!important}\n"] }]
1672
1723
  }], ctorParameters: () => [{ type: i2.MatterportImportService }, { type: i2.PlanService }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i2.ZoneService }, { type: i2.SpaceService }, { type: i2.NavigationService }, { type: i3.TranslateService }], propDecorators: { canvasDiv: [{
1673
1724
  type: ViewChild,
1674
1725
  args: ['canvasDiv']
@@ -1896,11 +1947,11 @@ class PlansComponent {
1896
1947
  }
1897
1948
  }
1898
1949
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PlansComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: i2.SpaceService }, { token: i2.PlanService }, { token: i1$2.UntypedFormBuilder }, { token: i3.TranslateService }, { token: i2.NavigatorService }], target: i0.ɵɵFactoryTarget.Component });
1899
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PlansComponent, selector: "lib-plans", ngImport: i0, template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\" class=\"dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n <div class=\"mt-3\" *ngIf=\"!plans && !loading\">\r\n <h4 style=\"font-weight: bold;\">{{'No imported plans' | translate }}</h4>\r\n <p>{{'For import from 3D visit: go Virtual Visits => Import Images' | translate}}</p>\r\n </div>\r\n <div class=\"row ms-1\">\r\n <div ngbDropdown class=\"d-inline-block me-3\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>{{getChoosenPlan() ?\r\n getChoosenPlan().name: ('Choose Plan' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\">{{plan.name }}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"d-inline-block\" ngbDropdown #myDrop=\"ngbDropdown\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownManual\" ngbDropdownToggle>{{'Choose action' |\r\n translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownManual\">\r\n <button (click)=\"onCalibrateClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Calibrate' |\r\n translate}}</button>\r\n <button (click)=\"onEditClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Edit plan' |\r\n translate}}\r\n </button>\r\n <button (click)=\"onUploadClick()\" ngbDropdownItem>{{'Upload new plan' | translate}}</button>\r\n <button (click)=\"onDownloadClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Download plan' |\r\n translate}}</button>\r\n <button (click)=\"onRemoveClick()\" ngbDropdownItem\r\n [disabled]=\"!getChoosenPlan() || getChoosenPlan().isImportedMatterport\">{{'Delete plan' |\r\n translate}}</button>\r\n <!-- <button (click)=\"onDownloadAsPng()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">\r\n {{'Download plan as PNG' | translate}}</button> -->\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row mt-3 ms-0\">\r\n <h4 *ngIf=\"fileToUpload\">{{'New plan' | translate }}</h4>\r\n <input class=\"hidden\" type=\"file\" id=\"upload-file\" name=\"upload-file\" accept=\"image/png, image/jpeg, .pdf, .svg\"\r\n ngf-max-size=\"6MB\" (change)=\"addPlan($event.target)\">\r\n </div>\r\n <div class=\"col-md-6 mt-3\" *ngIf=\"planForm\">\r\n <form (ngSubmit)=\"onSavePlan()\" [formGroup]=\"planForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3\">{{'Name' | translate}} </label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3\">{{'Zone' | translate}} </label>\r\n <div class=\"col-sm-9\">\r\n <select class=\"form-control\" formControlName=\"zoneID\">\r\n <option *ngFor=\"let zone of zones\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3\">{{'Set as current plan for zone' | translate}}</label>\r\n <div class=\"col-sm-3\">\r\n <input type=\"checkbox\" [(ngModel)]=\"isCurrentPlanForZone\" [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div>\r\n <button [disabled]=\"planForm.invalid\" type='submit' class=\"btn btn-label-file rounded-pill\">{{'Save' |\r\n translate}}</button>\r\n <button class=\"btn btn-label-file rounded-pill ms-3\" type=\"button\" (click)=\"onCancelUpload()\">{{'Cancel' |\r\n translate}}</button>\r\n </form>\r\n </div>\r\n <ul class=\"col-md-6 list-group list-group-flush\" *ngIf=\"getChoosenPlan()\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate }} : {{getChoosenPlan().name}} </li>\r\n <li class=\"list-group-item bg-transparent\"> {{'Plan is ' | translate }} :\r\n {{getChoosenPlan().calibration ? ('Calibrated' | translate) : ('Not calibrated' | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Attributed to zone ' | translate }} :\r\n {{getChoosenPlan().zone ? getChoosenPlan().zone.name : 'None'}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Is current plan for zone ' | translate }} :\r\n <input type=\"checkbox\" [(ngModel)]=\"getChoosenPlan().isCurrentForZone\" (change)=\"onCurrentPlanClick()\">\r\n </li>\r\n\r\n </ul>\r\n\r\n <div class=\"row mt-4\">\r\n <div class=\"col-md-10\">\r\n <embed *ngIf=\"getChoosenPlan() && chosenPlanIsPdf\" [src]=\"getChoosenPlan().filepath | safeUrl\"\r\n type=\"application/pdf\" frameBorder=\"0\" scrolling=\"auto\" height=\"650px;\" width=\"100%\" />\r\n <div *ngIf=\"!chosenPlanIsPdf\" class=\"row\" style=\"height: 500px; overflow: hidden;\" id=\"canvasDiv\">\r\n <canvas id=\"canvas\" width=\"4096px\" height=\"4096px\">\r\n <!-- <img *ngIf=\"chosenPlan\" id=\"plan-image\" [src]=\"chosenPlan.filepath\" style=\"width: 100%;\"> -->\r\n </canvas>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}.hidden{visibility:hidden;width:1px;height:1px}\n"], dependencies: [{ kind: "directive", type: i4$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i4$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i4$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i4$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i4$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.SafeUrlPipe, name: "safeUrl" }] });
1950
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PlansComponent, selector: "lib-plans", ngImport: i0, template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <div class=\"mt-3\" *ngIf=\"!plans && !loading\">\n <h4 style=\"font-weight: bold;\">{{'No imported plans' | translate }}</h4>\n <p>{{'For import from 3D visit: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <div class=\"row ms-1\">\n <div ngbDropdown class=\"d-inline-block me-3\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>{{getChoosenPlan() ?\n getChoosenPlan().name: ('Choose Plan' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\">{{plan.name }}\n </button>\n </div>\n </div>\n <div class=\"d-inline-block\" ngbDropdown #myDrop=\"ngbDropdown\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownManual\" ngbDropdownToggle>{{'Choose action' |\n translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownManual\">\n <button (click)=\"onCalibrateClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Calibrate' |\n translate}}</button>\n <button (click)=\"onEditClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Edit plan' |\n translate}}\n </button>\n <button (click)=\"onUploadClick()\" ngbDropdownItem>{{'Upload new plan' | translate}}</button>\n <button (click)=\"onDownloadClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Download plan' |\n translate}}</button>\n <button (click)=\"onRemoveClick()\" ngbDropdownItem\n [disabled]=\"!getChoosenPlan() || getChoosenPlan().isImportedMatterport\">{{'Delete plan' |\n translate}}</button>\n <!-- <button (click)=\"onDownloadAsPng()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">\n {{'Download plan as PNG' | translate}}</button> -->\n </div>\n </div>\n </div>\n <div class=\"row mt-3 ms-0\">\n <h4 *ngIf=\"fileToUpload\">{{'New plan' | translate }}</h4>\n <input class=\"hidden\" type=\"file\" id=\"upload-file\" name=\"upload-file\" accept=\"image/png, image/jpeg, .pdf, .svg\"\n ngf-max-size=\"6MB\" (change)=\"addPlan($event.target)\">\n </div>\n <div class=\"col-md-6 mt-3\" *ngIf=\"planForm\">\n <form (ngSubmit)=\"onSavePlan()\" [formGroup]=\"planForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3\">{{'Name' | translate}} </label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3\">{{'Zone' | translate}} </label>\n <div class=\"col-sm-9\">\n <select class=\"form-control\" formControlName=\"zoneID\">\n <option *ngFor=\"let zone of zones\" [ngValue]=\"zone.id\">\n {{ zone.name }}\n </option>\n </select>\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3\">{{'Set as current plan for zone' | translate}}</label>\n <div class=\"col-sm-3\">\n <input type=\"checkbox\" [(ngModel)]=\"isCurrentPlanForZone\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n <button [disabled]=\"planForm.invalid\" type='submit' class=\"btn btn-label-file rounded-pill\">{{'Save' |\n translate}}</button>\n <button class=\"btn btn-label-file rounded-pill ms-3\" type=\"button\" (click)=\"onCancelUpload()\">{{'Cancel' |\n translate}}</button>\n </form>\n </div>\n <ul class=\"col-md-6 list-group list-group-flush\" *ngIf=\"getChoosenPlan()\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate }} : {{getChoosenPlan().name}} </li>\n <li class=\"list-group-item bg-transparent\"> {{'Plan is ' | translate }} :\n {{getChoosenPlan().calibration ? ('Calibrated' | translate) : ('Not calibrated' | translate)}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Attributed to zone ' | translate }} :\n {{getChoosenPlan().zone ? getChoosenPlan().zone.name : 'None'}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Is current plan for zone ' | translate }} :\n <input type=\"checkbox\" [(ngModel)]=\"getChoosenPlan().isCurrentForZone\" (change)=\"onCurrentPlanClick()\">\n </li>\n\n </ul>\n\n <div class=\"row mt-4\">\n <div class=\"col-md-10\">\n <embed *ngIf=\"getChoosenPlan() && chosenPlanIsPdf\" [src]=\"getChoosenPlan().filepath | safeUrl\"\n type=\"application/pdf\" frameBorder=\"0\" scrolling=\"auto\" height=\"650px;\" width=\"100%\" />\n <div *ngIf=\"!chosenPlanIsPdf\" class=\"row\" style=\"height: 500px; overflow: hidden;\" id=\"canvasDiv\">\n <canvas id=\"canvas\" width=\"4096px\" height=\"4096px\">\n <!-- <img *ngIf=\"chosenPlan\" id=\"plan-image\" [src]=\"chosenPlan.filepath\" style=\"width: 100%;\"> -->\n </canvas>\n\n </div>\n </div>\n </div>\n</div>\n", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}.hidden{visibility:hidden;width:1px;height:1px}\n"], dependencies: [{ kind: "directive", type: i3$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i3$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i3$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i3$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i3$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.SafeUrlPipe, name: "safeUrl" }] });
1900
1951
  }
1901
1952
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PlansComponent, decorators: [{
1902
1953
  type: Component,
1903
- args: [{ selector: 'lib-plans', template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\" class=\"dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n <div class=\"mt-3\" *ngIf=\"!plans && !loading\">\r\n <h4 style=\"font-weight: bold;\">{{'No imported plans' | translate }}</h4>\r\n <p>{{'For import from 3D visit: go Virtual Visits => Import Images' | translate}}</p>\r\n </div>\r\n <div class=\"row ms-1\">\r\n <div ngbDropdown class=\"d-inline-block me-3\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>{{getChoosenPlan() ?\r\n getChoosenPlan().name: ('Choose Plan' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\">{{plan.name }}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"d-inline-block\" ngbDropdown #myDrop=\"ngbDropdown\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownManual\" ngbDropdownToggle>{{'Choose action' |\r\n translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownManual\">\r\n <button (click)=\"onCalibrateClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Calibrate' |\r\n translate}}</button>\r\n <button (click)=\"onEditClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Edit plan' |\r\n translate}}\r\n </button>\r\n <button (click)=\"onUploadClick()\" ngbDropdownItem>{{'Upload new plan' | translate}}</button>\r\n <button (click)=\"onDownloadClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Download plan' |\r\n translate}}</button>\r\n <button (click)=\"onRemoveClick()\" ngbDropdownItem\r\n [disabled]=\"!getChoosenPlan() || getChoosenPlan().isImportedMatterport\">{{'Delete plan' |\r\n translate}}</button>\r\n <!-- <button (click)=\"onDownloadAsPng()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">\r\n {{'Download plan as PNG' | translate}}</button> -->\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"row mt-3 ms-0\">\r\n <h4 *ngIf=\"fileToUpload\">{{'New plan' | translate }}</h4>\r\n <input class=\"hidden\" type=\"file\" id=\"upload-file\" name=\"upload-file\" accept=\"image/png, image/jpeg, .pdf, .svg\"\r\n ngf-max-size=\"6MB\" (change)=\"addPlan($event.target)\">\r\n </div>\r\n <div class=\"col-md-6 mt-3\" *ngIf=\"planForm\">\r\n <form (ngSubmit)=\"onSavePlan()\" [formGroup]=\"planForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3\">{{'Name' | translate}} </label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3\">{{'Zone' | translate}} </label>\r\n <div class=\"col-sm-9\">\r\n <select class=\"form-control\" formControlName=\"zoneID\">\r\n <option *ngFor=\"let zone of zones\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3\">{{'Set as current plan for zone' | translate}}</label>\r\n <div class=\"col-sm-3\">\r\n <input type=\"checkbox\" [(ngModel)]=\"isCurrentPlanForZone\" [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div>\r\n <button [disabled]=\"planForm.invalid\" type='submit' class=\"btn btn-label-file rounded-pill\">{{'Save' |\r\n translate}}</button>\r\n <button class=\"btn btn-label-file rounded-pill ms-3\" type=\"button\" (click)=\"onCancelUpload()\">{{'Cancel' |\r\n translate}}</button>\r\n </form>\r\n </div>\r\n <ul class=\"col-md-6 list-group list-group-flush\" *ngIf=\"getChoosenPlan()\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate }} : {{getChoosenPlan().name}} </li>\r\n <li class=\"list-group-item bg-transparent\"> {{'Plan is ' | translate }} :\r\n {{getChoosenPlan().calibration ? ('Calibrated' | translate) : ('Not calibrated' | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Attributed to zone ' | translate }} :\r\n {{getChoosenPlan().zone ? getChoosenPlan().zone.name : 'None'}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Is current plan for zone ' | translate }} :\r\n <input type=\"checkbox\" [(ngModel)]=\"getChoosenPlan().isCurrentForZone\" (change)=\"onCurrentPlanClick()\">\r\n </li>\r\n\r\n </ul>\r\n\r\n <div class=\"row mt-4\">\r\n <div class=\"col-md-10\">\r\n <embed *ngIf=\"getChoosenPlan() && chosenPlanIsPdf\" [src]=\"getChoosenPlan().filepath | safeUrl\"\r\n type=\"application/pdf\" frameBorder=\"0\" scrolling=\"auto\" height=\"650px;\" width=\"100%\" />\r\n <div *ngIf=\"!chosenPlanIsPdf\" class=\"row\" style=\"height: 500px; overflow: hidden;\" id=\"canvasDiv\">\r\n <canvas id=\"canvas\" width=\"4096px\" height=\"4096px\">\r\n <!-- <img *ngIf=\"chosenPlan\" id=\"plan-image\" [src]=\"chosenPlan.filepath\" style=\"width: 100%;\"> -->\r\n </canvas>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}.hidden{visibility:hidden;width:1px;height:1px}\n"] }]
1954
+ args: [{ selector: 'lib-plans', template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <div class=\"mt-3\" *ngIf=\"!plans && !loading\">\n <h4 style=\"font-weight: bold;\">{{'No imported plans' | translate }}</h4>\n <p>{{'For import from 3D visit: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <div class=\"row ms-1\">\n <div ngbDropdown class=\"d-inline-block me-3\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" ngbDropdownToggle>{{getChoosenPlan() ?\n getChoosenPlan().name: ('Choose Plan' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\">{{plan.name }}\n </button>\n </div>\n </div>\n <div class=\"d-inline-block\" ngbDropdown #myDrop=\"ngbDropdown\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownManual\" ngbDropdownToggle>{{'Choose action' |\n translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownManual\">\n <button (click)=\"onCalibrateClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Calibrate' |\n translate}}</button>\n <button (click)=\"onEditClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Edit plan' |\n translate}}\n </button>\n <button (click)=\"onUploadClick()\" ngbDropdownItem>{{'Upload new plan' | translate}}</button>\n <button (click)=\"onDownloadClick()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">{{'Download plan' |\n translate}}</button>\n <button (click)=\"onRemoveClick()\" ngbDropdownItem\n [disabled]=\"!getChoosenPlan() || getChoosenPlan().isImportedMatterport\">{{'Delete plan' |\n translate}}</button>\n <!-- <button (click)=\"onDownloadAsPng()\" ngbDropdownItem [disabled]=\"!getChoosenPlan()\">\n {{'Download plan as PNG' | translate}}</button> -->\n </div>\n </div>\n </div>\n <div class=\"row mt-3 ms-0\">\n <h4 *ngIf=\"fileToUpload\">{{'New plan' | translate }}</h4>\n <input class=\"hidden\" type=\"file\" id=\"upload-file\" name=\"upload-file\" accept=\"image/png, image/jpeg, .pdf, .svg\"\n ngf-max-size=\"6MB\" (change)=\"addPlan($event.target)\">\n </div>\n <div class=\"col-md-6 mt-3\" *ngIf=\"planForm\">\n <form (ngSubmit)=\"onSavePlan()\" [formGroup]=\"planForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3\">{{'Name' | translate}} </label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3\">{{'Zone' | translate}} </label>\n <div class=\"col-sm-9\">\n <select class=\"form-control\" formControlName=\"zoneID\">\n <option *ngFor=\"let zone of zones\" [ngValue]=\"zone.id\">\n {{ zone.name }}\n </option>\n </select>\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3\">{{'Set as current plan for zone' | translate}}</label>\n <div class=\"col-sm-3\">\n <input type=\"checkbox\" [(ngModel)]=\"isCurrentPlanForZone\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n <button [disabled]=\"planForm.invalid\" type='submit' class=\"btn btn-label-file rounded-pill\">{{'Save' |\n translate}}</button>\n <button class=\"btn btn-label-file rounded-pill ms-3\" type=\"button\" (click)=\"onCancelUpload()\">{{'Cancel' |\n translate}}</button>\n </form>\n </div>\n <ul class=\"col-md-6 list-group list-group-flush\" *ngIf=\"getChoosenPlan()\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate }} : {{getChoosenPlan().name}} </li>\n <li class=\"list-group-item bg-transparent\"> {{'Plan is ' | translate }} :\n {{getChoosenPlan().calibration ? ('Calibrated' | translate) : ('Not calibrated' | translate)}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Attributed to zone ' | translate }} :\n {{getChoosenPlan().zone ? getChoosenPlan().zone.name : 'None'}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Is current plan for zone ' | translate }} :\n <input type=\"checkbox\" [(ngModel)]=\"getChoosenPlan().isCurrentForZone\" (change)=\"onCurrentPlanClick()\">\n </li>\n\n </ul>\n\n <div class=\"row mt-4\">\n <div class=\"col-md-10\">\n <embed *ngIf=\"getChoosenPlan() && chosenPlanIsPdf\" [src]=\"getChoosenPlan().filepath | safeUrl\"\n type=\"application/pdf\" frameBorder=\"0\" scrolling=\"auto\" height=\"650px;\" width=\"100%\" />\n <div *ngIf=\"!chosenPlanIsPdf\" class=\"row\" style=\"height: 500px; overflow: hidden;\" id=\"canvasDiv\">\n <canvas id=\"canvas\" width=\"4096px\" height=\"4096px\">\n <!-- <img *ngIf=\"chosenPlan\" id=\"plan-image\" [src]=\"chosenPlan.filepath\" style=\"width: 100%;\"> -->\n </canvas>\n\n </div>\n </div>\n </div>\n</div>\n", styles: [".button-visit{display:none;height:30px;width:30px;position:absolute;background:url(https://api.iconify.design/mdi:map-marker-check.svg?color=red&height=30) no-repeat scroll 0 0 transparent;border:none}#button-visit-left{left:350px;top:550px}#button-visit-right{left:500px;top:600px}.hidden{visibility:hidden;width:1px;height:1px}\n"] }]
1904
1955
  }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i2.SpaceService }, { type: i2.PlanService }, { type: i1$2.UntypedFormBuilder }, { type: i3.TranslateService }, { type: i2.NavigatorService }] });
1905
1956
 
1906
1957
  class ChevronComponent {
@@ -1909,11 +1960,11 @@ class ChevronComponent {
1909
1960
  ngOnInit() {
1910
1961
  }
1911
1962
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChevronComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1912
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ChevronComponent, selector: "lib-chevron", inputs: { conditionShowing: "conditionShowing" }, ngImport: i0, template: "<div style=\"height: 30px; width: 30px;\">\r\n <span class=\"icon-container\" >\r\n <div [class]=\"conditionShowing ? 'icon-img-up' : 'icon-img-down'\"></div>\r\n </span>\r\n</div>\r\n", styles: [".icon-container{height:30px;width:30px}.icon-img-down{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-right.svg?width=28) no-repeat center center/contain}.icon-img-up{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-down.svg?width=28) no-repeat center center/contain}\n"] });
1963
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ChevronComponent, selector: "lib-chevron", inputs: { conditionShowing: "conditionShowing" }, ngImport: i0, template: "<div style=\"height: 30px; width: 30px;\">\n <span class=\"icon-container\" >\n <div [class]=\"conditionShowing ? 'icon-img-up' : 'icon-img-down'\"></div>\n </span>\n</div>\n", styles: [".icon-container{height:30px;width:30px}.icon-img-down{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-right.svg?width=28) no-repeat center center/contain}.icon-img-up{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-down.svg?width=28) no-repeat center center/contain}\n"] });
1913
1964
  }
1914
1965
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChevronComponent, decorators: [{
1915
1966
  type: Component,
1916
- args: [{ selector: 'lib-chevron', template: "<div style=\"height: 30px; width: 30px;\">\r\n <span class=\"icon-container\" >\r\n <div [class]=\"conditionShowing ? 'icon-img-up' : 'icon-img-down'\"></div>\r\n </span>\r\n</div>\r\n", styles: [".icon-container{height:30px;width:30px}.icon-img-down{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-right.svg?width=28) no-repeat center center/contain}.icon-img-up{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-down.svg?width=28) no-repeat center center/contain}\n"] }]
1967
+ args: [{ selector: 'lib-chevron', template: "<div style=\"height: 30px; width: 30px;\">\n <span class=\"icon-container\" >\n <div [class]=\"conditionShowing ? 'icon-img-up' : 'icon-img-down'\"></div>\n </span>\n</div>\n", styles: [".icon-container{height:30px;width:30px}.icon-img-down{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-right.svg?width=28) no-repeat center center/contain}.icon-img-up{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-down.svg?width=28) no-repeat center center/contain}\n"] }]
1917
1968
  }], ctorParameters: () => [], propDecorators: { conditionShowing: [{
1918
1969
  type: Input
1919
1970
  }] } });
@@ -1921,6 +1972,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
1921
1972
  class VisitsComponent {
1922
1973
  fb;
1923
1974
  matterportImportService;
1975
+ threejsImportService;
1924
1976
  captureService;
1925
1977
  nodeService;
1926
1978
  spaceService;
@@ -1950,9 +2002,10 @@ class VisitsComponent {
1950
2002
  errorForm = false;
1951
2003
  isProcessing = false;
1952
2004
  destroy$ = new Subject();
1953
- constructor(fb, matterportImportService, captureService, nodeService, spaceService, route, modalService, visitService, validatorsService, translate, navigatorService, router) {
2005
+ constructor(fb, matterportImportService, threejsImportService, captureService, nodeService, spaceService, route, modalService, visitService, validatorsService, translate, navigatorService, router) {
1954
2006
  this.fb = fb;
1955
2007
  this.matterportImportService = matterportImportService;
2008
+ this.threejsImportService = threejsImportService;
1956
2009
  this.captureService = captureService;
1957
2010
  this.nodeService = nodeService;
1958
2011
  this.spaceService = spaceService;
@@ -2026,7 +2079,10 @@ class VisitsComponent {
2026
2079
  .getVisitsForSpaceForUser(this.spaceId)
2027
2080
  .then((visits) => {
2028
2081
  if (visits) {
2029
- this.visits = visits;
2082
+ // 3D models share this storage but have their own screen, so listing them here
2083
+ // too showed every model twice. They can still be created from this form; they
2084
+ // just belong to the other tab once they exist.
2085
+ this.visits = visits.filter((visit) => visit.viewer !== CaptureViewer.THREEJS);
2030
2086
  }
2031
2087
  });
2032
2088
  }
@@ -2039,6 +2095,7 @@ class VisitsComponent {
2039
2095
  model3D: [input.model3d, [Validators.required]],
2040
2096
  viewer: input.viewer ? input.viewer : CaptureViewer.MATTERPORT,
2041
2097
  surface: input.surface ? input.surface : null,
2098
+ threeJsPlacement: input.captureMetadata ?? null,
2042
2099
  });
2043
2100
  this.captureDate = input.takenAt;
2044
2101
  }
@@ -2048,9 +2105,21 @@ class VisitsComponent {
2048
2105
  viewer: CaptureViewer.MATTERPORT,
2049
2106
  surface: null,
2050
2107
  name: [null, [Validators.required]],
2108
+ threeJsPlacement: null,
2051
2109
  });
2052
2110
  }
2053
2111
  }
2112
+ /** True while the form is set to create a Three.js visit, which asks for different fields. */
2113
+ get isThreeJsVisit() {
2114
+ return this.visitForm?.value.viewer === CaptureViewer.THREEJS;
2115
+ }
2116
+ /** Validation error for the 3D model field, or null. Only meaningful for Three.js visits. */
2117
+ get modelKeyError() {
2118
+ if (!this.isThreeJsVisit) {
2119
+ return null;
2120
+ }
2121
+ return this.threejsImportService.validateModelKey(this.visitForm.value.model3D);
2122
+ }
2054
2123
  async onToggleDetail(index) {
2055
2124
  this.visitIndexDetails = index === this.visitIndexDetails ? -1 : index;
2056
2125
  this.imagesUploaded = await this.matterportImportService.getUploadedImageCount(this.visits[index].model3d);
@@ -2070,6 +2139,13 @@ class VisitsComponent {
2070
2139
  this.errorForm = true;
2071
2140
  return;
2072
2141
  }
2142
+ // A Three.js visit points at a file rather than a Matterport model, so the reference is
2143
+ // checked before anything is written - otherwise a typo creates zones and navigation for a
2144
+ // model that 404s the first time someone opens the visit.
2145
+ if (this.modelKeyError) {
2146
+ this.errorForm = true;
2147
+ return;
2148
+ }
2073
2149
  this.errorForm = false;
2074
2150
  const formValue = this.visitForm.value;
2075
2151
  const capture = {
@@ -2077,6 +2153,7 @@ class VisitsComponent {
2077
2153
  takenAt: this.captureDate,
2078
2154
  surface: formValue.surface,
2079
2155
  spaceID: this.currentSpace.id,
2156
+ metadata: this.isThreeJsVisit ? formValue.threeJsPlacement : null,
2080
2157
  };
2081
2158
  if (this.isEditing) {
2082
2159
  capture.id = formValue.captureID;
@@ -2100,7 +2177,7 @@ class VisitsComponent {
2100
2177
  createdNode = await this.nodeService.createNode(node);
2101
2178
  }
2102
2179
  });
2103
- this.launchImport(formValue.model3D, formValue.surface, createdNode, false)
2180
+ this.launchImport(formValue.model3D, formValue.surface, createdNode, formValue.viewer, false, false, formValue.threeJsPlacement)
2104
2181
  .then((success) => {
2105
2182
  this.modalReference.close('import ended with success');
2106
2183
  })
@@ -2152,7 +2229,7 @@ class VisitsComponent {
2152
2229
  }
2153
2230
  return `with: ${reason}`;
2154
2231
  }
2155
- async launchImport(model3D, surface, node, imagesOnly = false, overrideExisting = false) {
2232
+ async launchImport(model3D, surface, node, viewerType, imagesOnly = false, overrideExisting = false, placementMetadata = null) {
2156
2233
  this.modalReference = this.modalService.open(this.content, {
2157
2234
  ariaLabelledBy: "modal-basic-title",
2158
2235
  });
@@ -2166,8 +2243,15 @@ class VisitsComponent {
2166
2243
  this.cancelImport();
2167
2244
  });
2168
2245
  try {
2169
- await this.matterportImportService.initSdkForModel(model3D);
2170
- await this.matterportImportService.importData(this.spaceId, surface, imagesOnly, node, overrideExisting);
2246
+ if (viewerType === CaptureViewer.THREEJS) {
2247
+ // Route the import to the new Three.js Import Service
2248
+ await this.threejsImportService.importData(this.spaceId, surface, imagesOnly, node, overrideExisting, placementMetadata);
2249
+ }
2250
+ else {
2251
+ // Route the import to the existing Matterport Import Service
2252
+ await this.matterportImportService.initSdkForModel(model3D);
2253
+ await this.matterportImportService.importData(this.spaceId, surface, imagesOnly, node, overrideExisting);
2254
+ }
2171
2255
  this.modalReference.close();
2172
2256
  }
2173
2257
  catch (error) {
@@ -2181,22 +2265,303 @@ class VisitsComponent {
2181
2265
  this.resetVisits();
2182
2266
  }
2183
2267
  onImportImages(visit, overrideExisting) {
2184
- this.launchImport(visit.model3d, null, visit.node.id, true, overrideExisting);
2268
+ this.launchImport(visit.model3d, null, visit.node.id, visit.viewer, true, overrideExisting, visit.captureMetadata);
2185
2269
  }
2186
2270
  isFormError(control) {
2187
2271
  return control && control.invalid && this.errorForm;
2188
2272
  }
2189
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VisitsComponent, deps: [{ token: i1$2.UntypedFormBuilder }, { token: i2.MatterportImportService }, { token: i2.CaptureService }, { token: i2.NodeService }, { token: i2.SpaceService }, { token: i1.ActivatedRoute }, { token: i4$1.NgbModal }, { token: i2.VisitService }, { token: i2.ValidatorsService }, { token: i3.TranslateService }, { token: i2.NavigatorService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
2190
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: VisitsComponent, selector: "lib-visits", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n\r\n <div class=\"row main-form-container\">\r\n <div class=\"col-md-6 form-container\">\r\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\r\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\r\n {{visit.name ? visit.name : visit.model3d }}\r\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"index==visitIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\r\n visit.name : \"Not provided\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\r\n visit.surface ?\r\n visit.surface : 'Not provided' | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\r\n visit.takenAt | timeDateString | async}}\r\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\r\n imagesUploaded }}\r\n </li>\r\n </ul>\r\n \r\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\r\n\r\n <div class=\"action-button-container mt-3\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\r\n translate}}</button>\r\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\r\n translate}} {{imagesUploaded}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\r\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\r\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n <div *ngIf=\"visitForm\">\r\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\r\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\r\n formControlName=\"model3D\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \r\n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \r\n || isFormError(visitForm.controls['name'])\">\r\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n <div *ngIf=\"isEditing\" class=\"text-danger\">\r\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"viewer\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\r\n <div class=\"input-group\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\r\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\r\n type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\r\n translate}}</button>\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n \r\n </ngb-alert>\r\n </div>\r\n </form>\r\n </div>\r\n <div *ngIf=\"!visitForm\">\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\r\n translate}}</button>\r\n </div>\r\n </div>\r\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\r\n </div>\r\n <ng-template #content let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">\u00D7</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'Please do not leave or refresh this page...' | translate}}\r\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\r\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\r\n </div>\r\n </ng-template>\r\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"], dependencies: [{ kind: "component", type: i4$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i4$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.TimeDateToLocalStringPipe, name: "timeDateString" }] });
2273
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VisitsComponent, deps: [{ token: i1$2.UntypedFormBuilder }, { token: i2.MatterportImportService }, { token: i2.ThreeJsImportService }, { token: i2.CaptureService }, { token: i2.NodeService }, { token: i2.SpaceService }, { token: i1.ActivatedRoute }, { token: i3$1.NgbModal }, { token: i2.VisitService }, { token: i2.ValidatorsService }, { token: i3.TranslateService }, { token: i2.NavigatorService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
2274
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: VisitsComponent, selector: "lib-visits", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true }], ngImport: i0, template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n\n <div class=\"row main-form-container\">\n <div class=\"col-md-6 form-container\">\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{visit.name ? visit.name : visit.model3d }}\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index==visitIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\n visit.name : \"Not provided\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\n visit.surface ?\n visit.surface : 'Not provided' | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\n visit.takenAt | timeDateString | async}}\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\n imagesUploaded }}\n </li>\n </ul>\n \n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\n translate}}</button>\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\n translate}} {{imagesUploaded}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\n </div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"visitForm\">\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\n formControlName=\"model3D\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \n || isFormError(visitForm.controls['name'])\">\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\n </ngb-alert>\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\n </div>\n <!-- A Three.js visit stores an S3 key here instead of a Matterport model ID,\n so the field means something different depending on the viewer above. -->\n <div *ngIf=\"isThreeJsVisit\" class=\"form-text\">\n {{'S3 key of the .glb file, for example visits/my-model.glb' | translate}}\n </div>\n <div *ngIf=\"modelKeyError && visitSubmitted\" class=\"text-danger\">\n {{modelKeyError | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\n <div class=\"col-sm-10\">\n <select class=\"form-select\" formControlName=\"viewer\">\n <option value=\"MATTERPORT\">Matterport</option>\n <option value=\"THREEJS\">Mod\u00E8le 3D (Three.js)</option>\n <option value=\"CUPIX\">Cupix</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"isThreeJsVisit\">\n <label class=\"col-sm-2 col-form-label\">{{'Initial placement' | translate}}</label>\n <div class=\"col-sm-10\">\n <textarea class=\"form-control\" rows=\"3\" formControlName=\"threeJsPlacement\"\n placeholder='{\"cameraPosition\": {\"x\": 0, \"y\": 5, \"z\": 15}, \"rotation\": {\"x\": 0, \"y\": 0, \"z\": 0}}'></textarea>\n <div class=\"form-text\">\n {{'Optional. Leave empty to frame the model automatically.' | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\n <div class=\"input-group\">\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\n type=\"button\"></button>\n </div>\n </div>\n </div>\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\n translate}}</button>\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n \n </ngb-alert>\n </div>\n </form>\n </div>\n <div *ngIf=\"!visitForm\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\n translate}}</button>\n </div>\n </div>\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\n </div>\n <ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'Please do not leave or refresh this page...' | translate}}\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\n </div>\n </ng-template>\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"], dependencies: [{ kind: "component", type: i3$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i3$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.TimeDateToLocalStringPipe, name: "timeDateString" }] });
2191
2275
  }
2192
2276
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: VisitsComponent, decorators: [{
2193
2277
  type: Component,
2194
- args: [{ selector: 'lib-visits', template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n\r\n <div class=\"row main-form-container\">\r\n <div class=\"col-md-6 form-container\">\r\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\r\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\r\n {{visit.name ? visit.name : visit.model3d }}\r\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"index==visitIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\r\n visit.name : \"Not provided\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\r\n visit.surface ?\r\n visit.surface : 'Not provided' | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\r\n visit.takenAt | timeDateString | async}}\r\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\r\n imagesUploaded }}\r\n </li>\r\n </ul>\r\n \r\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\r\n\r\n <div class=\"action-button-container mt-3\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\r\n translate}}</button>\r\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\r\n translate}} {{imagesUploaded}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\r\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\r\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n <div *ngIf=\"visitForm\">\r\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\r\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\r\n formControlName=\"model3D\">\r\n <div class=\"invalid-feedback\">\r\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \r\n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \r\n || isFormError(visitForm.controls['name'])\">\r\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\r\n </ngb-alert>\r\n </div>\r\n <div *ngIf=\"isEditing\" class=\"text-danger\">\r\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"viewer\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\r\n <div class=\"input-group\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\r\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\r\n type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\r\n translate}}</button>\r\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\r\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\r\n {{'errorForm.infoBtn' |translate}}\r\n \r\n </ngb-alert>\r\n </div>\r\n </form>\r\n </div>\r\n <div *ngIf=\"!visitForm\">\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\r\n translate}}</button>\r\n </div>\r\n </div>\r\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\r\n </div>\r\n <ng-template #content let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">\u00D7</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'Please do not leave or refresh this page...' | translate}}\r\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\r\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\r\n </div>\r\n </ng-template>\r\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"] }]
2195
- }], ctorParameters: () => [{ type: i1$2.UntypedFormBuilder }, { type: i2.MatterportImportService }, { type: i2.CaptureService }, { type: i2.NodeService }, { type: i2.SpaceService }, { type: i1.ActivatedRoute }, { type: i4$1.NgbModal }, { type: i2.VisitService }, { type: i2.ValidatorsService }, { type: i3.TranslateService }, { type: i2.NavigatorService }, { type: i1.Router }], propDecorators: { content: [{
2278
+ args: [{ selector: 'lib-visits', template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n\n <div class=\"row main-form-container\">\n <div class=\"col-md-6 form-container\">\n <ul class=\"list-group list-group-flush\" *ngIf=\"!visitForm\">\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let visit of visits; index as index\">\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{visit.name ? visit.name : visit.model3d }}\n <lib-chevron [conditionShowing]=\"index==visitIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index==visitIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} : {{ visit.name ?\n visit.name : \"Not provided\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D Model' | translate}} : {{ visit.model3d }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup>: {{\n visit.surface ?\n visit.surface : 'Not provided' | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Viewer' | translate}} : {{ visit.viewer }}\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Date of capture' | translate}} : {{\n visit.takenAt | timeDateString | async}}\n <li class=\"list-group-item bg-transparent\">{{'Images are imported' | translate}} : {{\n imagesUploaded }}\n </li>\n </ul>\n \n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, true)\" [disabled]=\"isProcessing\">{{'Import all images' |\n translate}}</button>\n <button type=\"button\" *ngIf=\"imagesUploaded > 0\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onImportImages(visit, false)\" [disabled]=\"isProcessing\">{{'Import from image' |\n translate}} {{imagesUploaded}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" [disabled]=\"isProcessing\"\n (click)=\"onEdit(visit)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\" [disabled]=\"isProcessing\"\n (click)=\"onDelete(visit)\">{{'Delete' | translate}}</button>\n </div>\n </div>\n </li>\n </ul>\n <div *ngIf=\"visitForm\">\n <form (ngSubmit)=\"onSubmitVisit()\" [formGroup]=\"visitForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\">\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Reference 3D model' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" [readonly]=\"isEditing\"\n [class.is-invalid]=\"model3D.invalid && visitSubmitted\" required\n formControlName=\"model3D\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" \n *ngIf=\"validatorsService.isControlError(visitForm.controls['name']) \n || isFormError(visitForm.controls['name'])\">\n {{validatorsService.getError(visitForm.controls['name']) | translate}}\n </ngb-alert>\n </div>\n <div *ngIf=\"isEditing\" class=\"text-danger\">\n {{'Cannot change 3D model reference. Please add new model.' | translate}}\n </div>\n <!-- A Three.js visit stores an S3 key here instead of a Matterport model ID,\n so the field means something different depending on the viewer above. -->\n <div *ngIf=\"isThreeJsVisit\" class=\"form-text\">\n {{'S3 key of the .glb file, for example visits/my-model.glb' | translate}}\n </div>\n <div *ngIf=\"modelKeyError && visitSubmitted\" class=\"text-danger\">\n {{modelKeyError | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Viewer' | translate}}</label>\n <div class=\"col-sm-10\">\n <select class=\"form-select\" formControlName=\"viewer\">\n <option value=\"MATTERPORT\">Matterport</option>\n <option value=\"THREEJS\">Mod\u00E8le 3D (Three.js)</option>\n <option value=\"CUPIX\">Cupix</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"isThreeJsVisit\">\n <label class=\"col-sm-2 col-form-label\">{{'Initial placement' | translate}}</label>\n <div class=\"col-sm-10\">\n <textarea class=\"form-control\" rows=\"3\" formControlName=\"threeJsPlacement\"\n placeholder='{\"cameraPosition\": {\"x\": 0, \"y\": 5, \"z\": 15}, \"rotation\": {\"x\": 0, \"y\": 0, \"z\": 0}}'></textarea>\n <div class=\"form-text\">\n {{'Optional. Leave empty to frame the model automatically.' | translate}}\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Capture Date' | translate}}</label>\n <div class=\"input-group\">\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"captureDate\" ngbDatepicker\n #d1=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\n <div class=\"input-group-append\">\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d1.toggle()\"\n type=\"button\"></button>\n </div>\n </div>\n </div>\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\">{{'Save' |\n translate}}</button>\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n \n </ngb-alert>\n </div>\n </form>\n </div>\n <div *ngIf=\"!visitForm\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAddVisit()\">{{'Add 3D visit' |\n translate}}</button>\n </div>\n </div>\n <div id=\"viewer-frame\" style=\"width: 100%; aspect-ratio: 2/1;\"></div>\n </div>\n <ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{'Importing Data' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'Please do not leave or refresh this page...' | translate}}\n <div *ngIf=\"totalImages != 0\">Imported {{imagesProcessed}} out of {{totalImages}} images.</div>\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" [disabled]=\"!canCancelImport\"\n (click)=\"modal.close('Cancel click')\">{{'Cancel import of images' | translate}}</button>\n </div>\n </ng-template>\n</div>", styles: [".col-form-label{width:180px;margin-bottom:1rem}.btn-outline-primary{width:200px;margin-right:1rem}.input-group{width:83%;height:fit-content}.main-form-container{width:60vw;display:flex;flex-direction:column}@media screen and (max-width: 765px){.main-form-container{width:90vw}}.main-form-container .form-container{width:100%}\n"] }]
2279
+ }], ctorParameters: () => [{ type: i1$2.UntypedFormBuilder }, { type: i2.MatterportImportService }, { type: i2.ThreeJsImportService }, { type: i2.CaptureService }, { type: i2.NodeService }, { type: i2.SpaceService }, { type: i1.ActivatedRoute }, { type: i3$1.NgbModal }, { type: i2.VisitService }, { type: i2.ValidatorsService }, { type: i3.TranslateService }, { type: i2.NavigatorService }, { type: i1.Router }], propDecorators: { content: [{
2196
2280
  type: ViewChild,
2197
2281
  args: ['content', { static: false }]
2198
2282
  }] } });
2199
2283
 
2284
+ /**
2285
+ * Admin screen for the 3D models a site can be visited with.
2286
+ *
2287
+ * These are stored the same way Matterport visits are - a Capture plus a Node - with the viewer set
2288
+ * to THREEJS and the .glb's S3 key in the node's model3D. Sharing the storage is what lets a site
2289
+ * carry several models and what makes tags follow the same POI records in either viewer; the split
2290
+ * here is only in the form: a 3D model is a name and a file, where a Matterport visit is a model ID
2291
+ * and capture details. Placement and alignment are not asked for here - the viewer's alignment tool
2292
+ * writes them into the capture's metadata once someone calibrates against a real scene.
2293
+ */
2294
+ class Models3dComponent {
2295
+ fb;
2296
+ route;
2297
+ router;
2298
+ modalService;
2299
+ spaceService;
2300
+ visitService;
2301
+ captureService;
2302
+ nodeService;
2303
+ threejsImportService;
2304
+ validatorsService;
2305
+ translate;
2306
+ content;
2307
+ menuItems = [];
2308
+ currentSpace;
2309
+ spaceId;
2310
+ /** Only the visits captured as 3D models; Matterport ones stay on the Virtual Visits screen. */
2311
+ models = [];
2312
+ modelForm;
2313
+ modelIndexDetails = -1;
2314
+ isEditing = false;
2315
+ isProcessing = false;
2316
+ submitted = false;
2317
+ errorMessage = null;
2318
+ modalReference;
2319
+ destroy$ = new Subject();
2320
+ constructor(fb, route, router, modalService, spaceService, visitService, captureService, nodeService, threejsImportService, validatorsService, translate) {
2321
+ this.fb = fb;
2322
+ this.route = route;
2323
+ this.router = router;
2324
+ this.modalService = modalService;
2325
+ this.spaceService = spaceService;
2326
+ this.visitService = visitService;
2327
+ this.captureService = captureService;
2328
+ this.nodeService = nodeService;
2329
+ this.threejsImportService = threejsImportService;
2330
+ this.validatorsService = validatorsService;
2331
+ this.translate = translate;
2332
+ }
2333
+ async ngOnInit() {
2334
+ this.spaceId = this.route.snapshot.paramMap.get('id');
2335
+ await this.reload();
2336
+ }
2337
+ ngOnDestroy() {
2338
+ this.destroy$.next(true);
2339
+ this.destroy$.complete();
2340
+ }
2341
+ async reload() {
2342
+ this.currentSpace = await this.spaceService.getSpace(this.spaceId);
2343
+ this.setupMenuItems();
2344
+ const visits = await this.visitService.getVisitsForSpaceForUser(this.spaceId);
2345
+ this.models = (visits ?? []).filter((visit) => visit.viewer === CaptureViewer.THREEJS);
2346
+ }
2347
+ setupMenuItems() {
2348
+ this.menuItems = [
2349
+ { label: 'Locations', url: '/localisation' },
2350
+ { label: this.currentSpace.name, url: `/localisation/${this.currentSpace.id}` },
2351
+ { label: '3D Models', url: `/localisation/${this.currentSpace.id}/models3d` },
2352
+ ];
2353
+ }
2354
+ onGoBack() {
2355
+ this.router.navigate(['/dashboard/localisation', this.spaceId]);
2356
+ }
2357
+ onToggleDetail(index) {
2358
+ this.modelIndexDetails = index === this.modelIndexDetails ? -1 : index;
2359
+ }
2360
+ onAdd() {
2361
+ this.initForm();
2362
+ this.menuItems.push({ label: 'New' });
2363
+ }
2364
+ onEdit(model) {
2365
+ this.initForm(model);
2366
+ this.isEditing = true;
2367
+ this.menuItems.push({ label: model.name });
2368
+ }
2369
+ onCancel() {
2370
+ this.modelForm = null;
2371
+ this.isEditing = false;
2372
+ this.submitted = false;
2373
+ this.errorMessage = null;
2374
+ this.setupMenuItems();
2375
+ }
2376
+ initForm(input = null) {
2377
+ this.submitted = false;
2378
+ this.errorMessage = null;
2379
+ if (input) {
2380
+ this.modelForm = this.fb.group({
2381
+ captureID: input.captureID,
2382
+ nodeID: input.node.id,
2383
+ name: [input.name, [Validators.required]],
2384
+ modelKey: [input.model3d, [Validators.required]],
2385
+ });
2386
+ }
2387
+ else {
2388
+ this.modelForm = this.fb.group({
2389
+ name: [null, [Validators.required]],
2390
+ modelKey: [null, [Validators.required]],
2391
+ });
2392
+ }
2393
+ }
2394
+ /** Upload progress as a percentage, or null when nothing is uploading. */
2395
+ uploadPercent = null;
2396
+ uploadedFileName = null;
2397
+ /**
2398
+ * Uploads the chosen .glb and puts the resulting key on the form.
2399
+ *
2400
+ * Storage.put authenticates with the signed-in user's session rather than separate S3
2401
+ * credentials, so anyone who can reach this screen can upload - which is what makes picking a
2402
+ * file a better ask than typing a key someone else had to produce.
2403
+ */
2404
+ async onFileSelected(event) {
2405
+ const input = event.target;
2406
+ const file = input.files?.[0];
2407
+ if (!file) {
2408
+ return;
2409
+ }
2410
+ const name = file.name.toLowerCase();
2411
+ if (!name.endsWith('.glb') && !name.endsWith('.gltf')) {
2412
+ this.errorMessage = this.translate.instant('Only .glb or .gltf files can be used as a 3D model.');
2413
+ input.value = '';
2414
+ return;
2415
+ }
2416
+ this.errorMessage = null;
2417
+ this.uploadPercent = 0;
2418
+ this.uploadedFileName = file.name;
2419
+ try {
2420
+ const key = await uploadFileToS3WithProgress(`models3d/${this.spaceId}/`, file, (fraction) => {
2421
+ this.uploadPercent = Math.round(fraction * 100);
2422
+ });
2423
+ this.modelForm.patchValue({ modelKey: key });
2424
+ // Name the model after the file when the field is still empty, so the common case needs
2425
+ // no extra typing.
2426
+ if (!this.modelForm.value.name) {
2427
+ this.modelForm.patchValue({ name: file.name.replace(/\.(glb|gltf)$/i, '') });
2428
+ }
2429
+ }
2430
+ catch (error) {
2431
+ this.errorMessage = this.describeError(error);
2432
+ this.uploadedFileName = null;
2433
+ }
2434
+ finally {
2435
+ this.uploadPercent = null;
2436
+ }
2437
+ }
2438
+ /** Validation error for the .glb key, or null. */
2439
+ get modelKeyError() {
2440
+ return this.threejsImportService.validateModelKey(this.modelForm?.value.modelKey);
2441
+ }
2442
+ async onSubmit() {
2443
+ this.submitted = true;
2444
+ this.errorMessage = null;
2445
+ if (!this.modelForm.valid || this.modelKeyError) {
2446
+ return;
2447
+ }
2448
+ const formValue = this.modelForm.value;
2449
+ const capture = {
2450
+ viewer: CaptureViewer.THREEJS,
2451
+ takenAt: Date.now(),
2452
+ spaceID: this.currentSpace.id,
2453
+ };
2454
+ this.isProcessing = true;
2455
+ try {
2456
+ if (this.isEditing) {
2457
+ capture.id = formValue.captureID;
2458
+ // metadata is left untouched on edit: the alignment tool writes the visit's tag
2459
+ // transform there, and resending the form's idea of it would wipe that.
2460
+ await this.captureService.updateCapture(capture);
2461
+ await this.nodeService.updateNode({
2462
+ id: formValue.nodeID,
2463
+ model3D: formValue.modelKey,
2464
+ metadata: formValue.name,
2465
+ });
2466
+ }
2467
+ else {
2468
+ await this.createModel(formValue);
2469
+ }
2470
+ await this.reload();
2471
+ this.onCancel();
2472
+ }
2473
+ catch (error) {
2474
+ // The most likely failure is the backend rejecting the THREEJS enum value, which has not
2475
+ // shipped yet - say so rather than leaving an empty screen.
2476
+ this.errorMessage = this.describeError(error);
2477
+ }
2478
+ finally {
2479
+ this.isProcessing = false;
2480
+ }
2481
+ }
2482
+ /** Creates the capture, its node, and the zone/plan/navigation the viewer needs. */
2483
+ async createModel(formValue) {
2484
+ const capture = await this.captureService.createCapture({
2485
+ viewer: CaptureViewer.THREEJS,
2486
+ takenAt: Date.now(),
2487
+ spaceID: this.currentSpace.id,
2488
+ });
2489
+ if (!capture) {
2490
+ throw new Error('Could not create the capture for this 3D model.');
2491
+ }
2492
+ const node = await this.nodeService.createNode({
2493
+ model3D: formValue.modelKey,
2494
+ captureID: capture.id,
2495
+ metadata: formValue.name,
2496
+ });
2497
+ await this.threejsImportService.importData(this.spaceId, null, false, node, true);
2498
+ }
2499
+ async onDelete(model) {
2500
+ this.modalReference = this.modalService.open(this.content);
2501
+ try {
2502
+ await this.modalReference.result;
2503
+ }
2504
+ catch {
2505
+ return; // dismissed
2506
+ }
2507
+ this.isProcessing = true;
2508
+ try {
2509
+ await this.nodeService.deleteNode(model.node.id);
2510
+ await this.captureService.deleteCapture(model.captureID);
2511
+ await this.reload();
2512
+ }
2513
+ catch (error) {
2514
+ this.errorMessage = this.describeError(error);
2515
+ }
2516
+ finally {
2517
+ this.isProcessing = false;
2518
+ }
2519
+ }
2520
+ /**
2521
+ * Turns whatever was thrown into something readable.
2522
+ *
2523
+ * AppSync rejections arrive as { errors: [{ message }] } with no `message` of their own, so the
2524
+ * obvious `error.message ?? String(error)` renders them as "[object Object]" - which hides
2525
+ * exactly the cases worth reading, like the backend refusing an enum value it does not know.
2526
+ */
2527
+ describeError(error) {
2528
+ if (typeof error === 'string') {
2529
+ return error;
2530
+ }
2531
+ const graphQlErrors = error?.errors;
2532
+ if (Array.isArray(graphQlErrors) && graphQlErrors.length > 0) {
2533
+ return graphQlErrors.map((e) => e?.message ?? JSON.stringify(e)).join(' | ');
2534
+ }
2535
+ if (error?.message) {
2536
+ return error.message;
2537
+ }
2538
+ try {
2539
+ return JSON.stringify(error);
2540
+ }
2541
+ catch {
2542
+ return String(error);
2543
+ }
2544
+ }
2545
+ getDismissReason(reason) {
2546
+ if (reason === ModalDismissReasons.ESC) {
2547
+ return 'by pressing ESC';
2548
+ }
2549
+ if (reason === ModalDismissReasons.BACKDROP_CLICK) {
2550
+ return 'by clicking on a backdrop';
2551
+ }
2552
+ return `with: ${reason}`;
2553
+ }
2554
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: Models3dComponent, deps: [{ token: i1$2.UntypedFormBuilder }, { token: i1.ActivatedRoute }, { token: i1.Router }, { token: i3$1.NgbModal }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i2.CaptureService }, { token: i2.NodeService }, { token: i2.ThreeJsImportService }, { token: i2.ValidatorsService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
2555
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: Models3dComponent, selector: "lib-models3d", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n\n <div class=\"row main-form-container\">\n <div class=\"col-md-6 form-container\">\n\n <!-- List -->\n <ul class=\"list-group list-group-flush\" *ngIf=\"!modelForm\">\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let model of models; index as index\">\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{ model.name ? model.name : model.model3d }}\n <lib-chevron [conditionShowing]=\"index == modelIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index == modelIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} :\n {{ model.name ? model.name : ('Not provided' | translate) }}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D model file' | translate}} :\n {{ model.model3d }}</li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup> :\n {{ model.surface ? model.surface : ('Not provided' | translate) }}</li>\n <li class=\"list-group-item bg-transparent\">{{'Initial placement' | translate}} :\n {{ model.captureMetadata ? model.captureMetadata : ('Automatic' | translate) }}</li>\n </ul>\n\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n [disabled]=\"isProcessing\" (click)=\"onEdit(model)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n [disabled]=\"isProcessing\" (click)=\"onDelete(model)\">{{'Delete' | translate}}</button>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- An empty list with a button under it reads as \"nothing here\" and the button gets\n missed. With nothing to list, the action is the whole screen. -->\n <div *ngIf=\"!modelForm && models.length === 0\" class=\"text-center py-5\">\n <p class=\"text-muted\">{{'No 3D model yet for this location.' | translate}}</p>\n <button type=\"button\" class=\"btn btn-primary rounded-pill\"\n (click)=\"onAdd()\">{{'Add a 3D model' | translate}}</button>\n </div>\n\n <div class=\"action-button-container mt-3\" *ngIf=\"!modelForm && models.length > 0\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onAdd()\">{{'Add a 3D model' | translate}}</button>\n </div>\n\n <!-- Form -->\n <form *ngIf=\"modelForm\" [formGroup]=\"modelForm\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\"\n [class.is-invalid]=\"submitted && modelForm.controls['name'].invalid\">\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'3D model file' | translate}} *</label>\n <div class=\"col-sm-9\">\n <!-- styles.scss hides every input[type=file] app-wide; the convention here is a\n styled label wrapping the hidden input, as on the profile screen. -->\n <label for=\"model3d-file\" class=\"btn btn-outline-primary rounded-pill\">\n <input type=\"file\" id=\"model3d-file\" accept=\".glb,.gltf\"\n [disabled]=\"uploadPercent !== null\" (change)=\"onFileSelected($event)\">\n {{'Choose a file' | translate}}\n </label>\n <span *ngIf=\"uploadedFileName && uploadPercent === null\" class=\"ms-2\">{{uploadedFileName}}</span>\n\n <div *ngIf=\"uploadPercent !== null\" class=\"mt-2\">\n <div class=\"progress\" style=\"height: 6px;\" role=\"progressbar\"\n [attr.aria-valuenow]=\"uploadPercent\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n <div class=\"progress-bar\" style=\"transition: none;\"\n [style.width.%]=\"uploadPercent\"></div>\n </div>\n <div class=\"form-text\">{{'Uploading' | translate}} {{uploadedFileName}} \u2014 {{uploadPercent}}%</div>\n </div>\n\n <div *ngIf=\"uploadPercent === null && modelForm.value.modelKey\" class=\"form-text text-success\">\n {{ modelForm.value.modelKey }}\n </div>\n\n <div *ngIf=\"submitted && modelKeyError\" class=\"text-danger\">\n {{ modelKeyError | translate }}\n </div>\n </div>\n </div>\n\n <ngb-alert *ngIf=\"errorMessage\" type=\"danger\" [dismissible]=\"false\">\n {{ errorMessage }}\n </ngb-alert>\n\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\"\n [disabled]=\"isProcessing\">{{'Save' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-secondary rounded-pill\"\n [disabled]=\"isProcessing\" (click)=\"onCancel()\">{{'Cancel' | translate}}</button>\n </div>\n </form>\n </div>\n </div>\n</div>\n\n<ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Delete' | translate}}</h4>\n </div>\n <div class=\"modal-body\">\n <p>{{'This 3D model will be removed from this location.' | translate}}</p>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-secondary rounded-pill\"\n (click)=\"modal.dismiss()\">{{'Cancel' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"modal.close('confirmed')\">{{'Delete' | translate}}</button>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: i3$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
2556
+ }
2557
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: Models3dComponent, decorators: [{
2558
+ type: Component,
2559
+ args: [{ selector: 'lib-models3d', template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n\n <div class=\"row main-form-container\">\n <div class=\"col-md-6 form-container\">\n\n <!-- List -->\n <ul class=\"list-group list-group-flush\" *ngIf=\"!modelForm\">\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let model of models; index as index\">\n <div class=\"d-flex justify-content-between align-items-center\" (click)=\"onToggleDetail(index)\">\n {{ model.name ? model.name : model.model3d }}\n <lib-chevron [conditionShowing]=\"index == modelIndexDetails\"></lib-chevron>\n </div>\n <div *ngIf=\"index == modelIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}} :\n {{ model.name ? model.name : ('Not provided' | translate) }}</li>\n <li class=\"list-group-item bg-transparent\">{{'3D model file' | translate}} :\n {{ model.model3d }}</li>\n <li class=\"list-group-item bg-transparent\">{{'Surface' | translate}}, m<sup>2</sup> :\n {{ model.surface ? model.surface : ('Not provided' | translate) }}</li>\n <li class=\"list-group-item bg-transparent\">{{'Initial placement' | translate}} :\n {{ model.captureMetadata ? model.captureMetadata : ('Automatic' | translate) }}</li>\n </ul>\n\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n [disabled]=\"isProcessing\" (click)=\"onEdit(model)\">{{'Edit' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n [disabled]=\"isProcessing\" (click)=\"onDelete(model)\">{{'Delete' | translate}}</button>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- An empty list with a button under it reads as \"nothing here\" and the button gets\n missed. With nothing to list, the action is the whole screen. -->\n <div *ngIf=\"!modelForm && models.length === 0\" class=\"text-center py-5\">\n <p class=\"text-muted\">{{'No 3D model yet for this location.' | translate}}</p>\n <button type=\"button\" class=\"btn btn-primary rounded-pill\"\n (click)=\"onAdd()\">{{'Add a 3D model' | translate}}</button>\n </div>\n\n <div class=\"action-button-container mt-3\" *ngIf=\"!modelForm && models.length > 0\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onAdd()\">{{'Add a 3D model' | translate}}</button>\n </div>\n\n <!-- Form -->\n <form *ngIf=\"modelForm\" [formGroup]=\"modelForm\" (ngSubmit)=\"onSubmit()\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"name\"\n [class.is-invalid]=\"submitted && modelForm.controls['name'].invalid\">\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'3D model file' | translate}} *</label>\n <div class=\"col-sm-9\">\n <!-- styles.scss hides every input[type=file] app-wide; the convention here is a\n styled label wrapping the hidden input, as on the profile screen. -->\n <label for=\"model3d-file\" class=\"btn btn-outline-primary rounded-pill\">\n <input type=\"file\" id=\"model3d-file\" accept=\".glb,.gltf\"\n [disabled]=\"uploadPercent !== null\" (change)=\"onFileSelected($event)\">\n {{'Choose a file' | translate}}\n </label>\n <span *ngIf=\"uploadedFileName && uploadPercent === null\" class=\"ms-2\">{{uploadedFileName}}</span>\n\n <div *ngIf=\"uploadPercent !== null\" class=\"mt-2\">\n <div class=\"progress\" style=\"height: 6px;\" role=\"progressbar\"\n [attr.aria-valuenow]=\"uploadPercent\" aria-valuemin=\"0\" aria-valuemax=\"100\">\n <div class=\"progress-bar\" style=\"transition: none;\"\n [style.width.%]=\"uploadPercent\"></div>\n </div>\n <div class=\"form-text\">{{'Uploading' | translate}} {{uploadedFileName}} \u2014 {{uploadPercent}}%</div>\n </div>\n\n <div *ngIf=\"uploadPercent === null && modelForm.value.modelKey\" class=\"form-text text-success\">\n {{ modelForm.value.modelKey }}\n </div>\n\n <div *ngIf=\"submitted && modelKeyError\" class=\"text-danger\">\n {{ modelKeyError | translate }}\n </div>\n </div>\n </div>\n\n <ngb-alert *ngIf=\"errorMessage\" type=\"danger\" [dismissible]=\"false\">\n {{ errorMessage }}\n </ngb-alert>\n\n <lib-loader *ngIf=\"isProcessing\"></lib-loader>\n\n <div class=\"action-button-container mt-3\">\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill me-2\"\n [disabled]=\"isProcessing\">{{'Save' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-secondary rounded-pill\"\n [disabled]=\"isProcessing\" (click)=\"onCancel()\">{{'Cancel' | translate}}</button>\n </div>\n </form>\n </div>\n </div>\n</div>\n\n<ng-template #content let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Delete' | translate}}</h4>\n </div>\n <div class=\"modal-body\">\n <p>{{'This 3D model will be removed from this location.' | translate}}</p>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-secondary rounded-pill\"\n (click)=\"modal.dismiss()\">{{'Cancel' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"modal.close('confirmed')\">{{'Delete' | translate}}</button>\n </div>\n</ng-template>\n" }]
2560
+ }], ctorParameters: () => [{ type: i1$2.UntypedFormBuilder }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i3$1.NgbModal }, { type: i2.SpaceService }, { type: i2.VisitService }, { type: i2.CaptureService }, { type: i2.NodeService }, { type: i2.ThreeJsImportService }, { type: i2.ValidatorsService }, { type: i3.TranslateService }], propDecorators: { content: [{
2561
+ type: ViewChild,
2562
+ args: ['content', { static: true }]
2563
+ }] } });
2564
+
2200
2565
  class CarouselComponent {
2201
2566
  images;
2202
2567
  currentScan = new EventEmitter();
@@ -2211,11 +2576,11 @@ class CarouselComponent {
2211
2576
  this.currentScan.emit(imageIndex);
2212
2577
  }
2213
2578
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CarouselComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2214
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CarouselComponent, selector: "lib-carousel", inputs: { images: "images" }, outputs: { currentScan: "currentScan" }, ngImport: i0, template: "<ngb-carousel [interval]=\"5000\" *ngIf=\"images && images.length > 1\" (slide)=\"onSlide($event)\">\r\n <ng-template *ngFor=\"let image of images; let i = index\" ngbSlide [id]=\"'slideId_' + i\">\r\n <div class=\"picsum-img-wrapper\">\r\n <img [src]=\"image.path\" alt=\"Scan\" class=\"d-block w-100\">\r\n </div>\r\n <div class=\"carousel-caption\">\r\n <h3>{{image.title}}</h3>\r\n <p>{{image.description}}</p>\r\n </div>\r\n </ng-template>\r\n</ngb-carousel>\r\n\r\n<img *ngIf=\"images.length === 1\" [src]=\"images[0].path\" alt=\"Scan\" class=\"d-block w-100\">\r\n", styles: [""], dependencies: [{ kind: "component", type: i4$1.NgbCarousel, selector: "ngb-carousel", inputs: ["animation", "activeId", "interval", "wrap", "keyboard", "pauseOnHover", "pauseOnFocus", "showNavigationArrows", "showNavigationIndicators"], outputs: ["slide", "slid"], exportAs: ["ngbCarousel"] }, { kind: "directive", type: i4$1.NgbSlide, selector: "ng-template[ngbSlide]", inputs: ["id"], outputs: ["slid"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2579
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CarouselComponent, selector: "lib-carousel", inputs: { images: "images" }, outputs: { currentScan: "currentScan" }, ngImport: i0, template: "<ngb-carousel [interval]=\"5000\" *ngIf=\"images && images.length > 1\" (slide)=\"onSlide($event)\">\n <ng-template *ngFor=\"let image of images; let i = index\" ngbSlide [id]=\"'slideId_' + i\">\n <div class=\"picsum-img-wrapper\">\n <img [src]=\"image.path\" alt=\"Scan\" class=\"d-block w-100\">\n </div>\n <div class=\"carousel-caption\">\n <h3>{{image.title}}</h3>\n <p>{{image.description}}</p>\n </div>\n </ng-template>\n</ngb-carousel>\n\n<img *ngIf=\"images.length === 1\" [src]=\"images[0].path\" alt=\"Scan\" class=\"d-block w-100\">\n", styles: [""], dependencies: [{ kind: "component", type: i3$1.NgbCarousel, selector: "ngb-carousel", inputs: ["animation", "activeId", "interval", "wrap", "keyboard", "pauseOnHover", "pauseOnFocus", "showNavigationArrows", "showNavigationIndicators"], outputs: ["slide", "slid"], exportAs: ["ngbCarousel"] }, { kind: "directive", type: i3$1.NgbSlide, selector: "ng-template[ngbSlide]", inputs: ["id"], outputs: ["slid"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2215
2580
  }
2216
2581
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CarouselComponent, decorators: [{
2217
2582
  type: Component,
2218
- args: [{ selector: 'lib-carousel', template: "<ngb-carousel [interval]=\"5000\" *ngIf=\"images && images.length > 1\" (slide)=\"onSlide($event)\">\r\n <ng-template *ngFor=\"let image of images; let i = index\" ngbSlide [id]=\"'slideId_' + i\">\r\n <div class=\"picsum-img-wrapper\">\r\n <img [src]=\"image.path\" alt=\"Scan\" class=\"d-block w-100\">\r\n </div>\r\n <div class=\"carousel-caption\">\r\n <h3>{{image.title}}</h3>\r\n <p>{{image.description}}</p>\r\n </div>\r\n </ng-template>\r\n</ngb-carousel>\r\n\r\n<img *ngIf=\"images.length === 1\" [src]=\"images[0].path\" alt=\"Scan\" class=\"d-block w-100\">\r\n" }]
2583
+ args: [{ selector: 'lib-carousel', template: "<ngb-carousel [interval]=\"5000\" *ngIf=\"images && images.length > 1\" (slide)=\"onSlide($event)\">\n <ng-template *ngFor=\"let image of images; let i = index\" ngbSlide [id]=\"'slideId_' + i\">\n <div class=\"picsum-img-wrapper\">\n <img [src]=\"image.path\" alt=\"Scan\" class=\"d-block w-100\">\n </div>\n <div class=\"carousel-caption\">\n <h3>{{image.title}}</h3>\n <p>{{image.description}}</p>\n </div>\n </ng-template>\n</ngb-carousel>\n\n<img *ngIf=\"images.length === 1\" [src]=\"images[0].path\" alt=\"Scan\" class=\"d-block w-100\">\n" }]
2219
2584
  }], ctorParameters: () => [], propDecorators: { images: [{
2220
2585
  type: Input
2221
2586
  }], currentScan: [{
@@ -2425,11 +2790,11 @@ class SelectionComponent {
2425
2790
  }
2426
2791
  }
2427
2792
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2428
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SelectionComponent, selector: "lib-selection", outputs: { onSelectionChanged: "onSelectionChanged" }, ngImport: i0, template: "<ng-content></ng-content>\r\n\r\n<div id=\"selection\"></div>", styles: ["#selection{will-change:top,left,width,height;top:0;left:0;position:fixed;display:block;margin-top:0;margin-left:0;width:0px;height:0px;background:#53b6bb4d;border-radius:.15em;border:.15em solid rgba(83,182,187,.8);pointer-events:none}\n"] });
2793
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SelectionComponent, selector: "lib-selection", outputs: { onSelectionChanged: "onSelectionChanged" }, ngImport: i0, template: "<ng-content></ng-content>\n\n<div id=\"selection\"></div>", styles: ["#selection{will-change:top,left,width,height;top:0;left:0;position:fixed;display:block;margin-top:0;margin-left:0;width:0px;height:0px;background:#53b6bb4d;border-radius:.15em;border:.15em solid rgba(83,182,187,.8);pointer-events:none}\n"] });
2429
2794
  }
2430
2795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SelectionComponent, decorators: [{
2431
2796
  type: Component,
2432
- args: [{ selector: 'lib-selection', template: "<ng-content></ng-content>\r\n\r\n<div id=\"selection\"></div>", styles: ["#selection{will-change:top,left,width,height;top:0;left:0;position:fixed;display:block;margin-top:0;margin-left:0;width:0px;height:0px;background:#53b6bb4d;border-radius:.15em;border:.15em solid rgba(83,182,187,.8);pointer-events:none}\n"] }]
2797
+ args: [{ selector: 'lib-selection', template: "<ng-content></ng-content>\n\n<div id=\"selection\"></div>", styles: ["#selection{will-change:top,left,width,height;top:0;left:0;position:fixed;display:block;margin-top:0;margin-left:0;width:0px;height:0px;background:#53b6bb4d;border-radius:.15em;border:.15em solid rgba(83,182,187,.8);pointer-events:none}\n"] }]
2433
2798
  }], ctorParameters: () => [], propDecorators: { onSelectionChanged: [{
2434
2799
  type: Output
2435
2800
  }] } });
@@ -2446,11 +2811,11 @@ class RadioButtonComponent {
2446
2811
  this.isCheckedEvent.emit(this.isChecked);
2447
2812
  }
2448
2813
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RadioButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2449
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RadioButtonComponent, selector: "lib-radio-button", inputs: { label: "label" }, outputs: { isCheckedEvent: "isCheckedEvent" }, ngImport: i0, template: "<div class=\"checkboxContainer\">\r\n <div class=\"switchContainer\">\r\n <label class=\"switch switch-success\">\r\n <input type=\"checkbox\" [(ngModel)]=\"isChecked\" (change)=\"onChecked()\">\r\n <span class=\"slider round\"></span>\r\n </label>\r\n </div>\r\n <span class=\"label right\">{{label | translate}}</span>\r\n</div>", styles: [".checkboxContainer{display:flex;flex-direction:row;align-items:center;width:calc(20vw + 1rem)}.checkboxContainer .label{margin-left:1rem}.checkboxContainer .switch{position:relative;display:inline-block;cursor:pointer;width:60px;height:34px;border-radius:34px}.checkboxContainer .switch input{opacity:0;width:0;height:0}.checkboxContainer .switch input:checked+.slider{background-color:#404660;box-shadow:4px 4px 10px #40466080}.checkboxContainer .switch input:checked+.slider:before{background:#fff;transform:translate(26px)}.checkboxContainer .switch .label{position:absolute;top:7px}.checkboxContainer .switch .label.right{left:60px;margin-left:10px}.checkboxContainer .switch .slider{position:absolute;cursor:pointer;inset:0;border:1px solid #404660;-webkit-transition:.3s;transition:.3s;border-radius:34px}.checkboxContainer .switch .slider:before:hover{background-color:#fff}.checkboxContainer .switch .slider:before{position:absolute;content:\"\";height:26px;width:26px;left:4px;bottom:3px;background-color:#404660;transition:.3s;border-radius:50%}.checkboxContainer .switch.switch-success input:checked+.slider{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider{border:1px solid var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider:before{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-default input:checked+.slider{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-default .slider{border:1px solid #636983}.checkboxContainer .switch.switch-default .slider:before{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-warning input:checked+.slider{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-warning .slider{border:1px solid #973c3c}.checkboxContainer .switch.switch-warning .slider:before{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-dark input:checked+.slider{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}.checkboxContainer .switch.switch-dark .slider{border:1px solid #505050}.checkboxContainer .switch.switch-dark .slider:before{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}\n"], dependencies: [{ kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
2814
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RadioButtonComponent, selector: "lib-radio-button", inputs: { label: "label" }, outputs: { isCheckedEvent: "isCheckedEvent" }, ngImport: i0, template: "<div class=\"checkboxContainer\">\n <div class=\"switchContainer\">\n <label class=\"switch switch-success\">\n <input type=\"checkbox\" [(ngModel)]=\"isChecked\" (change)=\"onChecked()\">\n <span class=\"slider round\"></span>\n </label>\n </div>\n <span class=\"label right\">{{label | translate}}</span>\n</div>", styles: [".checkboxContainer{display:flex;flex-direction:row;align-items:center;width:calc(20vw + 1rem)}.checkboxContainer .label{margin-left:1rem}.checkboxContainer .switch{position:relative;display:inline-block;cursor:pointer;width:60px;height:34px;border-radius:34px}.checkboxContainer .switch input{opacity:0;width:0;height:0}.checkboxContainer .switch input:checked+.slider{background-color:#404660;box-shadow:4px 4px 10px #40466080}.checkboxContainer .switch input:checked+.slider:before{background:#fff;transform:translate(26px)}.checkboxContainer .switch .label{position:absolute;top:7px}.checkboxContainer .switch .label.right{left:60px;margin-left:10px}.checkboxContainer .switch .slider{position:absolute;cursor:pointer;inset:0;border:1px solid #404660;-webkit-transition:.3s;transition:.3s;border-radius:34px}.checkboxContainer .switch .slider:before:hover{background-color:#fff}.checkboxContainer .switch .slider:before{position:absolute;content:\"\";height:26px;width:26px;left:4px;bottom:3px;background-color:#404660;transition:.3s;border-radius:50%}.checkboxContainer .switch.switch-success input:checked+.slider{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider{border:1px solid var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider:before{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-default input:checked+.slider{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-default .slider{border:1px solid #636983}.checkboxContainer .switch.switch-default .slider:before{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-warning input:checked+.slider{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-warning .slider{border:1px solid #973c3c}.checkboxContainer .switch.switch-warning .slider:before{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-dark input:checked+.slider{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}.checkboxContainer .switch.switch-dark .slider{border:1px solid #505050}.checkboxContainer .switch.switch-dark .slider:before{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}\n"], dependencies: [{ kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
2450
2815
  }
2451
2816
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RadioButtonComponent, decorators: [{
2452
2817
  type: Component,
2453
- args: [{ selector: 'lib-radio-button', template: "<div class=\"checkboxContainer\">\r\n <div class=\"switchContainer\">\r\n <label class=\"switch switch-success\">\r\n <input type=\"checkbox\" [(ngModel)]=\"isChecked\" (change)=\"onChecked()\">\r\n <span class=\"slider round\"></span>\r\n </label>\r\n </div>\r\n <span class=\"label right\">{{label | translate}}</span>\r\n</div>", styles: [".checkboxContainer{display:flex;flex-direction:row;align-items:center;width:calc(20vw + 1rem)}.checkboxContainer .label{margin-left:1rem}.checkboxContainer .switch{position:relative;display:inline-block;cursor:pointer;width:60px;height:34px;border-radius:34px}.checkboxContainer .switch input{opacity:0;width:0;height:0}.checkboxContainer .switch input:checked+.slider{background-color:#404660;box-shadow:4px 4px 10px #40466080}.checkboxContainer .switch input:checked+.slider:before{background:#fff;transform:translate(26px)}.checkboxContainer .switch .label{position:absolute;top:7px}.checkboxContainer .switch .label.right{left:60px;margin-left:10px}.checkboxContainer .switch .slider{position:absolute;cursor:pointer;inset:0;border:1px solid #404660;-webkit-transition:.3s;transition:.3s;border-radius:34px}.checkboxContainer .switch .slider:before:hover{background-color:#fff}.checkboxContainer .switch .slider:before{position:absolute;content:\"\";height:26px;width:26px;left:4px;bottom:3px;background-color:#404660;transition:.3s;border-radius:50%}.checkboxContainer .switch.switch-success input:checked+.slider{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider{border:1px solid var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider:before{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-default input:checked+.slider{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-default .slider{border:1px solid #636983}.checkboxContainer .switch.switch-default .slider:before{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-warning input:checked+.slider{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-warning .slider{border:1px solid #973c3c}.checkboxContainer .switch.switch-warning .slider:before{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-dark input:checked+.slider{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}.checkboxContainer .switch.switch-dark .slider{border:1px solid #505050}.checkboxContainer .switch.switch-dark .slider:before{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}\n"] }]
2818
+ args: [{ selector: 'lib-radio-button', template: "<div class=\"checkboxContainer\">\n <div class=\"switchContainer\">\n <label class=\"switch switch-success\">\n <input type=\"checkbox\" [(ngModel)]=\"isChecked\" (change)=\"onChecked()\">\n <span class=\"slider round\"></span>\n </label>\n </div>\n <span class=\"label right\">{{label | translate}}</span>\n</div>", styles: [".checkboxContainer{display:flex;flex-direction:row;align-items:center;width:calc(20vw + 1rem)}.checkboxContainer .label{margin-left:1rem}.checkboxContainer .switch{position:relative;display:inline-block;cursor:pointer;width:60px;height:34px;border-radius:34px}.checkboxContainer .switch input{opacity:0;width:0;height:0}.checkboxContainer .switch input:checked+.slider{background-color:#404660;box-shadow:4px 4px 10px #40466080}.checkboxContainer .switch input:checked+.slider:before{background:#fff;transform:translate(26px)}.checkboxContainer .switch .label{position:absolute;top:7px}.checkboxContainer .switch .label.right{left:60px;margin-left:10px}.checkboxContainer .switch .slider{position:absolute;cursor:pointer;inset:0;border:1px solid #404660;-webkit-transition:.3s;transition:.3s;border-radius:34px}.checkboxContainer .switch .slider:before:hover{background-color:#fff}.checkboxContainer .switch .slider:before{position:absolute;content:\"\";height:26px;width:26px;left:4px;bottom:3px;background-color:#404660;transition:.3s;border-radius:50%}.checkboxContainer .switch.switch-success input:checked+.slider{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider{border:1px solid var(--smarterplan-primary)}.checkboxContainer .switch.switch-success .slider:before{background-color:var(--smarterplan-primary);box-shadow:2px 2px 10px 0 var(--smarterplan-primary)}.checkboxContainer .switch.switch-default input:checked+.slider{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-default .slider{border:1px solid #636983}.checkboxContainer .switch.switch-default .slider:before{background-color:#636983;box-shadow:2px 2px 10px #636983}.checkboxContainer .switch.switch-warning input:checked+.slider{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-warning .slider{border:1px solid #973c3c}.checkboxContainer .switch.switch-warning .slider:before{background-color:#973c3c;box-shadow:2px 2px 10px #ff9898}.checkboxContainer .switch.switch-dark input:checked+.slider{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}.checkboxContainer .switch.switch-dark .slider{border:1px solid #505050}.checkboxContainer .switch.switch-dark .slider:before{background-color:#505050;box-shadow:2px 2px 10px #9d9d9d}\n"] }]
2454
2819
  }], ctorParameters: () => [], propDecorators: { label: [{
2455
2820
  type: Input
2456
2821
  }], isCheckedEvent: [{
@@ -2492,11 +2857,11 @@ class PlanLegendComponent {
2492
2857
  }
2493
2858
  }
2494
2859
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PlanLegendComponent, deps: [{ token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
2495
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PlanLegendComponent, selector: "lib-plan-legend", inputs: { isAudioZone: "isAudioZone" }, ngImport: i0, template: "<div class=\"mt-3 ms-3\" class=\"legendContainer\">\r\n <h5>{{\"legend.title\" | translate}}</h5>\r\n <div class=\"legendBox\">\r\n <div class=\"legendRow\" *ngFor=\"let elemnt of buttonsToRender\">\r\n <button class=\"legendIcon\" [ngStyle] = \"{'background-image': elemnt.url}\"></button>\r\n <span>{{elemnt.text}}</span>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".legendContainer{padding:1rem;border:solid var(--smarterplan-primary) 2px;border-radius:6px;width:100%;margin-bottom:.5rem;background:#fff}.legendContainer .legendBox{display:flex;flex-direction:row;justify-content:center;flex-wrap:wrap}.legendContainer .legendBox .legendRow{display:flex;flex-direction:row;align-items:center}.legendContainer .legendBox .legendRow .legendIcon{width:2.5rem;height:2.5rem;background-repeat:no-repeat;background-size:cover;border:none;background-color:transparent;margin-right:.5rem;cursor:auto}.legendContainer .legendBox .legendRow span{margin-right:1rem;cursor:auto}.legendContainer .legendBox .legendRow h5{cursor:auto}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
2860
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: PlanLegendComponent, selector: "lib-plan-legend", inputs: { isAudioZone: "isAudioZone" }, ngImport: i0, template: "<div class=\"mt-3 ms-3\" class=\"legendContainer\">\n <h5>{{\"legend.title\" | translate}}</h5>\n <div class=\"legendBox\">\n <div class=\"legendRow\" *ngFor=\"let elemnt of buttonsToRender\">\n <button class=\"legendIcon\" [ngStyle] = \"{'background-image': elemnt.url}\"></button>\n <span>{{elemnt.text}}</span>\n </div>\n </div>\n</div>\n", styles: [".legendContainer{padding:1rem;border:solid var(--smarterplan-primary) 2px;border-radius:6px;width:100%;margin-bottom:.5rem;background:#fff}.legendContainer .legendBox{display:flex;flex-direction:row;justify-content:center;flex-wrap:wrap}.legendContainer .legendBox .legendRow{display:flex;flex-direction:row;align-items:center}.legendContainer .legendBox .legendRow .legendIcon{width:2.5rem;height:2.5rem;background-repeat:no-repeat;background-size:cover;border:none;background-color:transparent;margin-right:.5rem;cursor:auto}.legendContainer .legendBox .legendRow span{margin-right:1rem;cursor:auto}.legendContainer .legendBox .legendRow h5{cursor:auto}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
2496
2861
  }
2497
2862
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PlanLegendComponent, decorators: [{
2498
2863
  type: Component,
2499
- args: [{ selector: 'lib-plan-legend', template: "<div class=\"mt-3 ms-3\" class=\"legendContainer\">\r\n <h5>{{\"legend.title\" | translate}}</h5>\r\n <div class=\"legendBox\">\r\n <div class=\"legendRow\" *ngFor=\"let elemnt of buttonsToRender\">\r\n <button class=\"legendIcon\" [ngStyle] = \"{'background-image': elemnt.url}\"></button>\r\n <span>{{elemnt.text}}</span>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".legendContainer{padding:1rem;border:solid var(--smarterplan-primary) 2px;border-radius:6px;width:100%;margin-bottom:.5rem;background:#fff}.legendContainer .legendBox{display:flex;flex-direction:row;justify-content:center;flex-wrap:wrap}.legendContainer .legendBox .legendRow{display:flex;flex-direction:row;align-items:center}.legendContainer .legendBox .legendRow .legendIcon{width:2.5rem;height:2.5rem;background-repeat:no-repeat;background-size:cover;border:none;background-color:transparent;margin-right:.5rem;cursor:auto}.legendContainer .legendBox .legendRow span{margin-right:1rem;cursor:auto}.legendContainer .legendBox .legendRow h5{cursor:auto}\n"] }]
2864
+ args: [{ selector: 'lib-plan-legend', template: "<div class=\"mt-3 ms-3\" class=\"legendContainer\">\n <h5>{{\"legend.title\" | translate}}</h5>\n <div class=\"legendBox\">\n <div class=\"legendRow\" *ngFor=\"let elemnt of buttonsToRender\">\n <button class=\"legendIcon\" [ngStyle] = \"{'background-image': elemnt.url}\"></button>\n <span>{{elemnt.text}}</span>\n </div>\n </div>\n</div>\n", styles: [".legendContainer{padding:1rem;border:solid var(--smarterplan-primary) 2px;border-radius:6px;width:100%;margin-bottom:.5rem;background:#fff}.legendContainer .legendBox{display:flex;flex-direction:row;justify-content:center;flex-wrap:wrap}.legendContainer .legendBox .legendRow{display:flex;flex-direction:row;align-items:center}.legendContainer .legendBox .legendRow .legendIcon{width:2.5rem;height:2.5rem;background-repeat:no-repeat;background-size:cover;border:none;background-color:transparent;margin-right:.5rem;cursor:auto}.legendContainer .legendBox .legendRow span{margin-right:1rem;cursor:auto}.legendContainer .legendBox .legendRow h5{cursor:auto}\n"] }]
2500
2865
  }], ctorParameters: () => [{ type: i3.TranslateService }], propDecorators: { isAudioZone: [{
2501
2866
  type: Input
2502
2867
  }] } });
@@ -2981,11 +3346,11 @@ class SweepPlanSelectionComponent {
2981
3346
  }
2982
3347
  }
2983
3348
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SweepPlanSelectionComponent, deps: [{ token: i2.ZoneService }, { token: i2.NavigationService }, { token: i2.PlanService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
2984
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SweepPlanSelectionComponent, selector: "lib-sweep-plan-selection", inputs: { spaceID: "spaceID", chosenScansOnPlan: "chosenScansOnPlan", newZoneData: "newZoneData", occupiedSweeps: "occupiedSweeps", unavailableSweeps: "unavailableSweeps", editingAudioZone: "editingAudioZone", inputZone: "inputZone", multipleFloors: "multipleFloors" }, outputs: { sweepsSelected: "sweepsSelected" }, usesOnChanges: true, ngImport: i0, template: "<div ngbDropdown class=\"sp-row d-inline-block\">\r\n <div class=\"col-sm-3\" *ngIf=\"plans\">\r\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\r\n ngbDropdownToggle>{{chosenPlan ?\r\n chosenPlan.name : ('Choose Plan' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button type=\"button\" ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\"\r\n [disabled]=\"!plan.calibration\">{{ plan.name }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"sp-row\">\r\n <lib-selection class=\"col-md-8\" (onSelectionChanged)=\"onSelectionChanged($event)\">\r\n <lib-plan-legend [isAudioZone]=\"editingAudioZone\" *ngIf=\"buttonElements.length > 0\"></lib-plan-legend>\r\n <div class=\"selectZone\" oncontextmenu=\"return false;\">\r\n <div class=\"sp-row\">\r\n <div style=\"overflow: hidden;width:100%;\">\r\n <div style=\"height: 400px; width: 100%;\" id=\"planDiv\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </lib-selection>\r\n \r\n <div class=\"col-md-4 scanTool\" *ngIf=\"buttonElements.length > 0\">\r\n <div class=\"sp-row d-inline-block\">\r\n <h2>{{'selectTool.title' | translate}}</h2>\r\n <div class=\"protip\">{{'selectTool.tip' | translate}}.</div>\r\n </div>\r\n \r\n <div class=\"sp-row\">\r\n <div class=\"col-3\" style=\"padding:0px\">\r\n <label class=\"tool-label\" for=\"scanSize\">{{'selectTool.size' | translate}}</label>\r\n </div>\r\n <div class=\"col-9\">\r\n <input type=\"range\" class=\"form-range\" min=\"0.001\" max=\"5\" step=\"0.01\" value=\"1\"\r\n id=\"scanSize\" (input)=\"onChangeScanSize($event)\">\r\n </div>\r\n </div>\r\n \r\n <div class=\"sp-row\">\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectAll()\">{{'selectTool.selectAll' | translate}}</button>\r\n </div>\r\n \r\n <div *ngIf=\"buttonsInSelection.length > 0\" class=\"edit-selected\">\r\n <span class=\"tool-label\">{{'selectTool.edit' | translate}} : </span>\r\n <div class=\"sp-row\">\r\n <button class=\"btn rounded-pill btn-primary ms-3 me-2\" (click)=\"onSelectionAdd()\">{{'selectTool.add' | translate}}</button>\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectionRemove()\">{{'selectTool.undo' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"sp-row\">\r\n <div *ngIf=\"multipleFloors\"> \r\n {{ chosenSweepsPerFloor.get(chosenPlan.zoneID) ? chosenSweepsPerFloor.get(chosenPlan.zoneID).length : \"0\"}} {{'scan points selected on this floor' | translate}} \r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onValidateForFloor()\" [disabled]=\"!selectionChanged\">{{'Update selection for this floor' | translate}}</button>\r\n </div>\r\n <div *ngIf=\"!multipleFloors\">\r\n {{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}} \r\n </div>\r\n </div>\r\n <div *ngIf=\"!editingAudioZone\" class=\"sp-row\">\r\n <lib-radio-button label=\"{{ 'selectTool.chooseStartPoint' | translate }}\" (isCheckedEvent)=\"isSettingStartSweep=!isSettingStartSweep\"></lib-radio-button>\r\n </div>\r\n <div class=\"sp-row\">\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSaveSelection()\">{{'selectTool.saveSelection' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'selectTool.cancelSelection' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n \r\n", styles: [".sp-row{display:flex;margin-bottom:1rem}.selectZone{border-radius:6px;overflow:hidden;background-color:var(--smarterplan-secondary)}.scanTool{margin:0px 1rem}.protip{color:gray;padding:0}.tool-label{font-size:1rem}\n"], dependencies: [{ kind: "directive", type: i4$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i4$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i4$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i4$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i4$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SelectionComponent, selector: "lib-selection", outputs: ["onSelectionChanged"] }, { kind: "component", type: RadioButtonComponent, selector: "lib-radio-button", inputs: ["label"], outputs: ["isCheckedEvent"] }, { kind: "component", type: PlanLegendComponent, selector: "lib-plan-legend", inputs: ["isAudioZone"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
3349
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: SweepPlanSelectionComponent, selector: "lib-sweep-plan-selection", inputs: { spaceID: "spaceID", chosenScansOnPlan: "chosenScansOnPlan", newZoneData: "newZoneData", occupiedSweeps: "occupiedSweeps", unavailableSweeps: "unavailableSweeps", editingAudioZone: "editingAudioZone", inputZone: "inputZone", multipleFloors: "multipleFloors" }, outputs: { sweepsSelected: "sweepsSelected" }, usesOnChanges: true, ngImport: i0, template: "<div ngbDropdown class=\"sp-row d-inline-block\">\n <div class=\"col-sm-3\" *ngIf=\"plans\">\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\n ngbDropdownToggle>{{chosenPlan ?\n chosenPlan.name : ('Choose Plan' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button type=\"button\" ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\"\n [disabled]=\"!plan.calibration\">{{ plan.name }}\n </button>\n </div>\n </div>\n</div>\n<div class=\"sp-row\">\n <lib-selection class=\"col-md-8\" (onSelectionChanged)=\"onSelectionChanged($event)\">\n <lib-plan-legend [isAudioZone]=\"editingAudioZone\" *ngIf=\"buttonElements.length > 0\"></lib-plan-legend>\n <div class=\"selectZone\" oncontextmenu=\"return false;\">\n <div class=\"sp-row\">\n <div style=\"overflow: hidden;width:100%;\">\n <div style=\"height: 400px; width: 100%;\" id=\"planDiv\">\n </div>\n </div>\n </div>\n </div>\n </lib-selection>\n \n <div class=\"col-md-4 scanTool\" *ngIf=\"buttonElements.length > 0\">\n <div class=\"sp-row d-inline-block\">\n <h2>{{'selectTool.title' | translate}}</h2>\n <div class=\"protip\">{{'selectTool.tip' | translate}}.</div>\n </div>\n \n <div class=\"sp-row\">\n <div class=\"col-3\" style=\"padding:0px\">\n <label class=\"tool-label\" for=\"scanSize\">{{'selectTool.size' | translate}}</label>\n </div>\n <div class=\"col-9\">\n <input type=\"range\" class=\"form-range\" min=\"0.001\" max=\"5\" step=\"0.01\" value=\"1\"\n id=\"scanSize\" (input)=\"onChangeScanSize($event)\">\n </div>\n </div>\n \n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectAll()\">{{'selectTool.selectAll' | translate}}</button>\n </div>\n \n <div *ngIf=\"buttonsInSelection.length > 0\" class=\"edit-selected\">\n <span class=\"tool-label\">{{'selectTool.edit' | translate}} : </span>\n <div class=\"sp-row\">\n <button class=\"btn rounded-pill btn-primary ms-3 me-2\" (click)=\"onSelectionAdd()\">{{'selectTool.add' | translate}}</button>\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectionRemove()\">{{'selectTool.undo' | translate}}</button>\n </div>\n </div>\n\n <div class=\"sp-row\">\n <div *ngIf=\"multipleFloors\"> \n {{ chosenSweepsPerFloor.get(chosenPlan.zoneID) ? chosenSweepsPerFloor.get(chosenPlan.zoneID).length : \"0\"}} {{'scan points selected on this floor' | translate}} \n <button class=\"btn btn-primary rounded-pill\" (click)=\"onValidateForFloor()\" [disabled]=\"!selectionChanged\">{{'Update selection for this floor' | translate}}</button>\n </div>\n <div *ngIf=\"!multipleFloors\">\n {{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}} \n </div>\n </div>\n <div *ngIf=\"!editingAudioZone\" class=\"sp-row\">\n <lib-radio-button label=\"{{ 'selectTool.chooseStartPoint' | translate }}\" (isCheckedEvent)=\"isSettingStartSweep=!isSettingStartSweep\"></lib-radio-button>\n </div>\n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSaveSelection()\">{{'selectTool.saveSelection' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'selectTool.cancelSelection' | translate}}</button>\n </div>\n </div>\n\n</div>\n \n", styles: [".sp-row{display:flex;margin-bottom:1rem}.selectZone{border-radius:6px;overflow:hidden;background-color:var(--smarterplan-secondary)}.scanTool{margin:0px 1rem}.protip{color:gray;padding:0}.tool-label{font-size:1rem}\n"], dependencies: [{ kind: "directive", type: i3$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i3$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i3$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i3$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i3$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SelectionComponent, selector: "lib-selection", outputs: ["onSelectionChanged"] }, { kind: "component", type: RadioButtonComponent, selector: "lib-radio-button", inputs: ["label"], outputs: ["isCheckedEvent"] }, { kind: "component", type: PlanLegendComponent, selector: "lib-plan-legend", inputs: ["isAudioZone"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
2985
3350
  }
2986
3351
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SweepPlanSelectionComponent, decorators: [{
2987
3352
  type: Component,
2988
- args: [{ selector: 'lib-sweep-plan-selection', template: "<div ngbDropdown class=\"sp-row d-inline-block\">\r\n <div class=\"col-sm-3\" *ngIf=\"plans\">\r\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\r\n ngbDropdownToggle>{{chosenPlan ?\r\n chosenPlan.name : ('Choose Plan' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button type=\"button\" ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\"\r\n [disabled]=\"!plan.calibration\">{{ plan.name }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n<div class=\"sp-row\">\r\n <lib-selection class=\"col-md-8\" (onSelectionChanged)=\"onSelectionChanged($event)\">\r\n <lib-plan-legend [isAudioZone]=\"editingAudioZone\" *ngIf=\"buttonElements.length > 0\"></lib-plan-legend>\r\n <div class=\"selectZone\" oncontextmenu=\"return false;\">\r\n <div class=\"sp-row\">\r\n <div style=\"overflow: hidden;width:100%;\">\r\n <div style=\"height: 400px; width: 100%;\" id=\"planDiv\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </lib-selection>\r\n \r\n <div class=\"col-md-4 scanTool\" *ngIf=\"buttonElements.length > 0\">\r\n <div class=\"sp-row d-inline-block\">\r\n <h2>{{'selectTool.title' | translate}}</h2>\r\n <div class=\"protip\">{{'selectTool.tip' | translate}}.</div>\r\n </div>\r\n \r\n <div class=\"sp-row\">\r\n <div class=\"col-3\" style=\"padding:0px\">\r\n <label class=\"tool-label\" for=\"scanSize\">{{'selectTool.size' | translate}}</label>\r\n </div>\r\n <div class=\"col-9\">\r\n <input type=\"range\" class=\"form-range\" min=\"0.001\" max=\"5\" step=\"0.01\" value=\"1\"\r\n id=\"scanSize\" (input)=\"onChangeScanSize($event)\">\r\n </div>\r\n </div>\r\n \r\n <div class=\"sp-row\">\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectAll()\">{{'selectTool.selectAll' | translate}}</button>\r\n </div>\r\n \r\n <div *ngIf=\"buttonsInSelection.length > 0\" class=\"edit-selected\">\r\n <span class=\"tool-label\">{{'selectTool.edit' | translate}} : </span>\r\n <div class=\"sp-row\">\r\n <button class=\"btn rounded-pill btn-primary ms-3 me-2\" (click)=\"onSelectionAdd()\">{{'selectTool.add' | translate}}</button>\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectionRemove()\">{{'selectTool.undo' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"sp-row\">\r\n <div *ngIf=\"multipleFloors\"> \r\n {{ chosenSweepsPerFloor.get(chosenPlan.zoneID) ? chosenSweepsPerFloor.get(chosenPlan.zoneID).length : \"0\"}} {{'scan points selected on this floor' | translate}} \r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onValidateForFloor()\" [disabled]=\"!selectionChanged\">{{'Update selection for this floor' | translate}}</button>\r\n </div>\r\n <div *ngIf=\"!multipleFloors\">\r\n {{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}} \r\n </div>\r\n </div>\r\n <div *ngIf=\"!editingAudioZone\" class=\"sp-row\">\r\n <lib-radio-button label=\"{{ 'selectTool.chooseStartPoint' | translate }}\" (isCheckedEvent)=\"isSettingStartSweep=!isSettingStartSweep\"></lib-radio-button>\r\n </div>\r\n <div class=\"sp-row\">\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSaveSelection()\">{{'selectTool.saveSelection' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'selectTool.cancelSelection' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n</div>\r\n \r\n", styles: [".sp-row{display:flex;margin-bottom:1rem}.selectZone{border-radius:6px;overflow:hidden;background-color:var(--smarterplan-secondary)}.scanTool{margin:0px 1rem}.protip{color:gray;padding:0}.tool-label{font-size:1rem}\n"] }]
3353
+ args: [{ selector: 'lib-sweep-plan-selection', template: "<div ngbDropdown class=\"sp-row d-inline-block\">\n <div class=\"col-sm-3\" *ngIf=\"plans\">\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\n ngbDropdownToggle>{{chosenPlan ?\n chosenPlan.name : ('Choose Plan' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button type=\"button\" ngbDropdownItem *ngFor=\"let plan of plans\" (click)=\"onPlanClick(plan)\"\n [disabled]=\"!plan.calibration\">{{ plan.name }}\n </button>\n </div>\n </div>\n</div>\n<div class=\"sp-row\">\n <lib-selection class=\"col-md-8\" (onSelectionChanged)=\"onSelectionChanged($event)\">\n <lib-plan-legend [isAudioZone]=\"editingAudioZone\" *ngIf=\"buttonElements.length > 0\"></lib-plan-legend>\n <div class=\"selectZone\" oncontextmenu=\"return false;\">\n <div class=\"sp-row\">\n <div style=\"overflow: hidden;width:100%;\">\n <div style=\"height: 400px; width: 100%;\" id=\"planDiv\">\n </div>\n </div>\n </div>\n </div>\n </lib-selection>\n \n <div class=\"col-md-4 scanTool\" *ngIf=\"buttonElements.length > 0\">\n <div class=\"sp-row d-inline-block\">\n <h2>{{'selectTool.title' | translate}}</h2>\n <div class=\"protip\">{{'selectTool.tip' | translate}}.</div>\n </div>\n \n <div class=\"sp-row\">\n <div class=\"col-3\" style=\"padding:0px\">\n <label class=\"tool-label\" for=\"scanSize\">{{'selectTool.size' | translate}}</label>\n </div>\n <div class=\"col-9\">\n <input type=\"range\" class=\"form-range\" min=\"0.001\" max=\"5\" step=\"0.01\" value=\"1\"\n id=\"scanSize\" (input)=\"onChangeScanSize($event)\">\n </div>\n </div>\n \n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectAll()\">{{'selectTool.selectAll' | translate}}</button>\n </div>\n \n <div *ngIf=\"buttonsInSelection.length > 0\" class=\"edit-selected\">\n <span class=\"tool-label\">{{'selectTool.edit' | translate}} : </span>\n <div class=\"sp-row\">\n <button class=\"btn rounded-pill btn-primary ms-3 me-2\" (click)=\"onSelectionAdd()\">{{'selectTool.add' | translate}}</button>\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSelectionRemove()\">{{'selectTool.undo' | translate}}</button>\n </div>\n </div>\n\n <div class=\"sp-row\">\n <div *ngIf=\"multipleFloors\"> \n {{ chosenSweepsPerFloor.get(chosenPlan.zoneID) ? chosenSweepsPerFloor.get(chosenPlan.zoneID).length : \"0\"}} {{'scan points selected on this floor' | translate}} \n <button class=\"btn btn-primary rounded-pill\" (click)=\"onValidateForFloor()\" [disabled]=\"!selectionChanged\">{{'Update selection for this floor' | translate}}</button>\n </div>\n <div *ngIf=\"!multipleFloors\">\n {{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}} \n </div>\n </div>\n <div *ngIf=\"!editingAudioZone\" class=\"sp-row\">\n <lib-radio-button label=\"{{ 'selectTool.chooseStartPoint' | translate }}\" (isCheckedEvent)=\"isSettingStartSweep=!isSettingStartSweep\"></lib-radio-button>\n </div>\n <div class=\"sp-row\">\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onSaveSelection()\">{{'selectTool.saveSelection' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onCancel()\">{{'selectTool.cancelSelection' | translate}}</button>\n </div>\n </div>\n\n</div>\n \n", styles: [".sp-row{display:flex;margin-bottom:1rem}.selectZone{border-radius:6px;overflow:hidden;background-color:var(--smarterplan-secondary)}.scanTool{margin:0px 1rem}.protip{color:gray;padding:0}.tool-label{font-size:1rem}\n"] }]
2989
3354
  }], ctorParameters: () => [{ type: i2.ZoneService }, { type: i2.NavigationService }, { type: i2.PlanService }, { type: i3.TranslateService }], propDecorators: { spaceID: [{
2990
3355
  type: Input
2991
3356
  }], chosenScansOnPlan: [{
@@ -3302,11 +3667,11 @@ class AddZoneComponent {
3302
3667
  };
3303
3668
  }
3304
3669
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AddZoneComponent, deps: [{ token: i1$2.UntypedFormBuilder }, { token: i2.ZoneService }, { token: i2.LayerService }, { token: i2.BaseUserService }, { token: i2.NavigationService }], target: i0.ɵɵFactoryTarget.Component });
3305
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AddZoneComponent, selector: "lib-add-zone", inputs: { zoneEdit: "zoneEdit", spaceID: "spaceID", images360: "images360", navigationIDs: "navigationIDs", zones: "zones", newZoneDataFromEditor: "newZoneDataFromEditor", chosenPlan: "chosenPlan", isMuseumVisit: "isMuseumVisit", defaultZone: "defaultZone" }, outputs: { updatedZone: "updatedZone" }, ngImport: i0, template: "<div class=\"main-container\" *ngIf=\"zoneForm\">\r\n <div class=\"col-7\">\r\n <form (ngSubmit)=\"onSubmitZone()\" [formGroup]=\"zoneForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" required formControlName=\"name\">\r\n <!-- <div class=\"invalid-feedback\">\r\n {{'A name is required' | translate}}\r\n </div> -->\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'codeRef' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"code_ref\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\" *ngIf=\"!isMuseumVisit && !zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Type of zone' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <select class=\"form-control\" formControlName=\"layerID\">\r\n <option value=\"null\" selected disabled hidden> {{ zoneEdit && zoneEdit.layer ?\r\n zoneEdit.layer.name : 'Choose type'}}</option>\r\n <option *ngFor=\"let layer of layers\" [value]=\"layer.id\">\r\n {{ layer.name }}\r\n </option>\r\n </select>\r\n <p class=\"mt-1 new-type-text\">{{'or add new type of zone' | translate }}</p>\r\n <input type=\"text\" class=\"form-control new-type-input\" formControlName=\"newLayer\">\r\n <div *ngIf=\"newLayer.invalid && (newLayer.dirty || newLayer.touched)\" class=\"text-danger\">\r\n <div *ngIf=\"newLayer.errors?.['forbiddenName']\">\r\n {{'Layer exists already' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!--If Editing Zone possibility to assign it to museum itinerary-->\r\n <div class=\"mb-3 row\" *ngIf=\"zoneEdit && !zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{ 'Museum Itinerary' | translate }}</label>\r\n <div class=\"col-sm-10\">\r\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"isMuseumVisit\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\" *ngIf=\"!zoneEdit || zoneEdit.isMultipleFloorZone\">\r\n <label class=\"col-sm-2 col-form-label\">{{ 'Multiple Floors' | translate }}</label>\r\n <div class=\"col-sm-10\">\r\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"multipleFloors\"\r\n [disabled]=\"zoneEdit !== undefined && zoneEdit !== null\" (change)=\"onChangeMultipleFloors()\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n <div class='text-danger' *ngIf=\"zoneEdit\">\r\n {{'cannotChangeMultifloor' | translate}}\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\" *ngIf=\"!zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Parent zone' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input *ngIf=\"zoneEdit\" type=\"text\" class=\"form-control\" formControlName=\"parent\">\r\n <div class=\"text-danger\" *ngIf=\"zoneEdit\">\r\n {{'cannotChangeParent' | translate}}\r\n </div>\r\n <select *ngIf=\"!zoneEdit\" class=\"form-control\" formControlName=\"parentID\">\r\n <option *ngFor=\"let zone of parentZones\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\" style=\"max-height: 200px; overflow: auto;\" *ngIf=\"!zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Scan Points' | translate}}</label>\r\n <!-- <p class=\"col-sm-2\" *ngIf=\"zoneEdit\">{{ zoneEdit.sweepIDs.length }} scans</p> -->\r\n <p class=\"col\" *ngIf=\"chosenScansOnPlan.length === 0 && chosenScans.length === 0\">\r\n {{'No scan points chosen' | translate}}</p>\r\n <div class=\"col-sm-5\" *ngIf=\"chosenScansOnPlan && chosenScansOnPlan.length > 0\">\r\n <p>{{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}}</p>\r\n <!-- <div *ngFor=\"let scan of chosenScansOnPlan\">\r\n <div class=\"row\">\r\n <p class=\"me-2\">{{ scan | slice:0:8 }}</p>\r\n <div (click)=\"onRemoveScanPlan(scan)\" [style.cursor]=\"'pointer'\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </div>\r\n <div class=\"col-sm-5\" *ngIf=\"carouselIsVisible && chosenScans && chosenScans.length > 0\">\r\n <p>{{ chosenScans.length }} {{'scan points chosen' | translate}}</p>\r\n <div *ngFor=\"let scan of chosenScans\">\r\n <div class=\"row\">\r\n <p class=\"me-2\">{{ images360[scan].filename }}</p>\r\n <div (click)=\"onRemoveScanImage(scan)\" [style.cursor]=\"'pointer'\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3 mt-3\" *ngIf=\"!zoneIsMatterportFloor\">\r\n <div class=\"col\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"togglePlan()\">{{'Choose scan points on plan' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"toggleCarousel()\"\r\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\r\n {{'Choose scan points from gallery' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAll()\"\r\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\r\n {{'add-all-scans' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <!-- <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'No visible scan points' | translate}}</label>\r\n <div class=\"col-sm-3\">\r\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"noScanPoints\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div> -->\r\n\r\n <div *ngIf=\"carouselIsVisible\" class=\"mb-2\">\r\n <lib-carousel *ngIf=\"images360 && images360.length > 0\" [images]=\"images360\"\r\n (currentScan)=\"currentScanShowing=$event\"></lib-carousel>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2 mt-3\"\r\n (click)=\"onAddScan()\">{{'Add to zone' | translate}}</button>\r\n </div>\r\n <div class=\"mt-3\">\r\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\"\r\n [disabled]=\"fromPlan || !zoneForm.valid\">{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\r\n <lib-sweep-plan-selection style=\"width: 100%;\" [newZoneData]=\"newZoneDataFromEditor\" [spaceID]=\"spaceID\"\r\n [multipleFloors]=\"multipleFloors\" [inputZone]=\"zoneEdit\"\r\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\r\n </div>\r\n</div>", styles: [".main-container{display:flex;flex-direction:column}.edit-plan{display:flex;margin:8px 0}.form-range{width:100%}h2{color:var(--smarterplan-primary);padding:0}.col-form-label{margin-bottom:1rem}.btn-outline-primary{margin-right:1rem}.new-type-input{margin-bottom:1rem}.new-type-text{margin-bottom:.5rem}.row{margin:0}p{margin:0;padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px)}button{min-width:80px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CarouselComponent, selector: "lib-carousel", inputs: ["images"], outputs: ["currentScan"] }, { kind: "component", type: SweepPlanSelectionComponent, selector: "lib-sweep-plan-selection", inputs: ["spaceID", "chosenScansOnPlan", "newZoneData", "occupiedSweeps", "unavailableSweeps", "editingAudioZone", "inputZone", "multipleFloors"], outputs: ["sweepsSelected"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
3670
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AddZoneComponent, selector: "lib-add-zone", inputs: { zoneEdit: "zoneEdit", spaceID: "spaceID", images360: "images360", navigationIDs: "navigationIDs", zones: "zones", newZoneDataFromEditor: "newZoneDataFromEditor", chosenPlan: "chosenPlan", isMuseumVisit: "isMuseumVisit", defaultZone: "defaultZone" }, outputs: { updatedZone: "updatedZone" }, ngImport: i0, template: "<div class=\"main-container\" *ngIf=\"zoneForm\">\n <div class=\"col-7\">\n <form (ngSubmit)=\"onSubmitZone()\" [formGroup]=\"zoneForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" required formControlName=\"name\">\n <!-- <div class=\"invalid-feedback\">\n {{'A name is required' | translate}}\n </div> -->\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'codeRef' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"code_ref\">\n </div>\n </div>\n <div class=\"mb-3 row\" *ngIf=\"!isMuseumVisit && !zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{'Type of zone' | translate}}</label>\n <div class=\"col-sm-10\">\n <select class=\"form-control\" formControlName=\"layerID\">\n <option value=\"null\" selected disabled hidden> {{ zoneEdit && zoneEdit.layer ?\n zoneEdit.layer.name : 'Choose type'}}</option>\n <option *ngFor=\"let layer of layers\" [value]=\"layer.id\">\n {{ layer.name }}\n </option>\n </select>\n <p class=\"mt-1 new-type-text\">{{'or add new type of zone' | translate }}</p>\n <input type=\"text\" class=\"form-control new-type-input\" formControlName=\"newLayer\">\n <div *ngIf=\"newLayer.invalid && (newLayer.dirty || newLayer.touched)\" class=\"text-danger\">\n <div *ngIf=\"newLayer.errors?.['forbiddenName']\">\n {{'Layer exists already' | translate}}\n </div>\n </div>\n </div>\n </div>\n <!--If Editing Zone possibility to assign it to museum itinerary-->\n <div class=\"mb-3 row\" *ngIf=\"zoneEdit && !zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{ 'Museum Itinerary' | translate }}</label>\n <div class=\"col-sm-10\">\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"isMuseumVisit\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"!zoneEdit || zoneEdit.isMultipleFloorZone\">\n <label class=\"col-sm-2 col-form-label\">{{ 'Multiple Floors' | translate }}</label>\n <div class=\"col-sm-10\">\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"multipleFloors\"\n [disabled]=\"zoneEdit !== undefined && zoneEdit !== null\" (change)=\"onChangeMultipleFloors()\"\n [ngModelOptions]=\"{standalone: true}\">\n <div class='text-danger' *ngIf=\"zoneEdit\">\n {{'cannotChangeMultifloor' | translate}}\n </div>\n </div>\n\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"!zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{'Parent zone' | translate}}</label>\n <div class=\"col-sm-10\">\n <input *ngIf=\"zoneEdit\" type=\"text\" class=\"form-control\" formControlName=\"parent\">\n <div class=\"text-danger\" *ngIf=\"zoneEdit\">\n {{'cannotChangeParent' | translate}}\n </div>\n <select *ngIf=\"!zoneEdit\" class=\"form-control\" formControlName=\"parentID\">\n <option *ngFor=\"let zone of parentZones\" [ngValue]=\"zone.id\">\n {{ zone.name }}\n </option>\n </select>\n\n </div>\n </div>\n\n <div class=\"mb-3 row\" style=\"max-height: 200px; overflow: auto;\" *ngIf=\"!zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{'Scan Points' | translate}}</label>\n <!-- <p class=\"col-sm-2\" *ngIf=\"zoneEdit\">{{ zoneEdit.sweepIDs.length }} scans</p> -->\n <p class=\"col\" *ngIf=\"chosenScansOnPlan.length === 0 && chosenScans.length === 0\">\n {{'No scan points chosen' | translate}}</p>\n <div class=\"col-sm-5\" *ngIf=\"chosenScansOnPlan && chosenScansOnPlan.length > 0\">\n <p>{{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}}</p>\n <!-- <div *ngFor=\"let scan of chosenScansOnPlan\">\n <div class=\"row\">\n <p class=\"me-2\">{{ scan | slice:0:8 }}</p>\n <div (click)=\"onRemoveScanPlan(scan)\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n </div> -->\n </div>\n <div class=\"col-sm-5\" *ngIf=\"carouselIsVisible && chosenScans && chosenScans.length > 0\">\n <p>{{ chosenScans.length }} {{'scan points chosen' | translate}}</p>\n <div *ngFor=\"let scan of chosenScans\">\n <div class=\"row\">\n <p class=\"me-2\">{{ images360[scan].filename }}</p>\n <div (click)=\"onRemoveScanImage(scan)\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"row mb-3 mt-3\" *ngIf=\"!zoneIsMatterportFloor\">\n <div class=\"col\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"togglePlan()\">{{'Choose scan points on plan' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"toggleCarousel()\"\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\n {{'Choose scan points from gallery' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAll()\"\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\n {{'add-all-scans' | translate}}</button>\n </div>\n </div>\n\n <!-- <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'No visible scan points' | translate}}</label>\n <div class=\"col-sm-3\">\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"noScanPoints\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div> -->\n\n <div *ngIf=\"carouselIsVisible\" class=\"mb-2\">\n <lib-carousel *ngIf=\"images360 && images360.length > 0\" [images]=\"images360\"\n (currentScan)=\"currentScanShowing=$event\"></lib-carousel>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2 mt-3\"\n (click)=\"onAddScan()\">{{'Add to zone' | translate}}</button>\n </div>\n <div class=\"mt-3\">\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\"\n [disabled]=\"fromPlan || !zoneForm.valid\">{{'Save' | translate}}</button>\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\n {{'Cancel' | translate}}</button>\n </div>\n </form>\n </div>\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\n <lib-sweep-plan-selection style=\"width: 100%;\" [newZoneData]=\"newZoneDataFromEditor\" [spaceID]=\"spaceID\"\n [multipleFloors]=\"multipleFloors\" [inputZone]=\"zoneEdit\"\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\n </div>\n</div>", styles: [".main-container{display:flex;flex-direction:column}.edit-plan{display:flex;margin:8px 0}.form-range{width:100%}h2{color:var(--smarterplan-primary);padding:0}.col-form-label{margin-bottom:1rem}.btn-outline-primary{margin-right:1rem}.new-type-input{margin-bottom:1rem}.new-type-text{margin-bottom:.5rem}.row{margin:0}p{margin:0;padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px)}button{min-width:80px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CarouselComponent, selector: "lib-carousel", inputs: ["images"], outputs: ["currentScan"] }, { kind: "component", type: SweepPlanSelectionComponent, selector: "lib-sweep-plan-selection", inputs: ["spaceID", "chosenScansOnPlan", "newZoneData", "occupiedSweeps", "unavailableSweeps", "editingAudioZone", "inputZone", "multipleFloors"], outputs: ["sweepsSelected"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
3306
3671
  }
3307
3672
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AddZoneComponent, decorators: [{
3308
3673
  type: Component,
3309
- args: [{ selector: 'lib-add-zone', template: "<div class=\"main-container\" *ngIf=\"zoneForm\">\r\n <div class=\"col-7\">\r\n <form (ngSubmit)=\"onSubmitZone()\" [formGroup]=\"zoneForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" required formControlName=\"name\">\r\n <!-- <div class=\"invalid-feedback\">\r\n {{'A name is required' | translate}}\r\n </div> -->\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'codeRef' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"code_ref\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3 row\" *ngIf=\"!isMuseumVisit && !zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Type of zone' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <select class=\"form-control\" formControlName=\"layerID\">\r\n <option value=\"null\" selected disabled hidden> {{ zoneEdit && zoneEdit.layer ?\r\n zoneEdit.layer.name : 'Choose type'}}</option>\r\n <option *ngFor=\"let layer of layers\" [value]=\"layer.id\">\r\n {{ layer.name }}\r\n </option>\r\n </select>\r\n <p class=\"mt-1 new-type-text\">{{'or add new type of zone' | translate }}</p>\r\n <input type=\"text\" class=\"form-control new-type-input\" formControlName=\"newLayer\">\r\n <div *ngIf=\"newLayer.invalid && (newLayer.dirty || newLayer.touched)\" class=\"text-danger\">\r\n <div *ngIf=\"newLayer.errors?.['forbiddenName']\">\r\n {{'Layer exists already' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <!--If Editing Zone possibility to assign it to museum itinerary-->\r\n <div class=\"mb-3 row\" *ngIf=\"zoneEdit && !zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{ 'Museum Itinerary' | translate }}</label>\r\n <div class=\"col-sm-10\">\r\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"isMuseumVisit\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\" *ngIf=\"!zoneEdit || zoneEdit.isMultipleFloorZone\">\r\n <label class=\"col-sm-2 col-form-label\">{{ 'Multiple Floors' | translate }}</label>\r\n <div class=\"col-sm-10\">\r\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"multipleFloors\"\r\n [disabled]=\"zoneEdit !== undefined && zoneEdit !== null\" (change)=\"onChangeMultipleFloors()\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n <div class='text-danger' *ngIf=\"zoneEdit\">\r\n {{'cannotChangeMultifloor' | translate}}\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\" *ngIf=\"!zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Parent zone' | translate}}</label>\r\n <div class=\"col-sm-10\">\r\n <input *ngIf=\"zoneEdit\" type=\"text\" class=\"form-control\" formControlName=\"parent\">\r\n <div class=\"text-danger\" *ngIf=\"zoneEdit\">\r\n {{'cannotChangeParent' | translate}}\r\n </div>\r\n <select *ngIf=\"!zoneEdit\" class=\"form-control\" formControlName=\"parentID\">\r\n <option *ngFor=\"let zone of parentZones\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n\r\n </div>\r\n </div>\r\n\r\n <div class=\"mb-3 row\" style=\"max-height: 200px; overflow: auto;\" *ngIf=\"!zoneIsMatterportFloor\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Scan Points' | translate}}</label>\r\n <!-- <p class=\"col-sm-2\" *ngIf=\"zoneEdit\">{{ zoneEdit.sweepIDs.length }} scans</p> -->\r\n <p class=\"col\" *ngIf=\"chosenScansOnPlan.length === 0 && chosenScans.length === 0\">\r\n {{'No scan points chosen' | translate}}</p>\r\n <div class=\"col-sm-5\" *ngIf=\"chosenScansOnPlan && chosenScansOnPlan.length > 0\">\r\n <p>{{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}}</p>\r\n <!-- <div *ngFor=\"let scan of chosenScansOnPlan\">\r\n <div class=\"row\">\r\n <p class=\"me-2\">{{ scan | slice:0:8 }}</p>\r\n <div (click)=\"onRemoveScanPlan(scan)\" [style.cursor]=\"'pointer'\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </div>\r\n </div> -->\r\n </div>\r\n <div class=\"col-sm-5\" *ngIf=\"carouselIsVisible && chosenScans && chosenScans.length > 0\">\r\n <p>{{ chosenScans.length }} {{'scan points chosen' | translate}}</p>\r\n <div *ngFor=\"let scan of chosenScans\">\r\n <div class=\"row\">\r\n <p class=\"me-2\">{{ images360[scan].filename }}</p>\r\n <div (click)=\"onRemoveScanImage(scan)\" [style.cursor]=\"'pointer'\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mb-3 mt-3\" *ngIf=\"!zoneIsMatterportFloor\">\r\n <div class=\"col\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"togglePlan()\">{{'Choose scan points on plan' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"toggleCarousel()\"\r\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\r\n {{'Choose scan points from gallery' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAll()\"\r\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\r\n {{'add-all-scans' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <!-- <div class=\"mb-3 row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'No visible scan points' | translate}}</label>\r\n <div class=\"col-sm-3\">\r\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"noScanPoints\"\r\n [ngModelOptions]=\"{standalone: true}\">\r\n </div>\r\n </div> -->\r\n\r\n <div *ngIf=\"carouselIsVisible\" class=\"mb-2\">\r\n <lib-carousel *ngIf=\"images360 && images360.length > 0\" [images]=\"images360\"\r\n (currentScan)=\"currentScanShowing=$event\"></lib-carousel>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2 mt-3\"\r\n (click)=\"onAddScan()\">{{'Add to zone' | translate}}</button>\r\n </div>\r\n <div class=\"mt-3\">\r\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\"\r\n [disabled]=\"fromPlan || !zoneForm.valid\">{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\r\n <lib-sweep-plan-selection style=\"width: 100%;\" [newZoneData]=\"newZoneDataFromEditor\" [spaceID]=\"spaceID\"\r\n [multipleFloors]=\"multipleFloors\" [inputZone]=\"zoneEdit\"\r\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\r\n </div>\r\n</div>", styles: [".main-container{display:flex;flex-direction:column}.edit-plan{display:flex;margin:8px 0}.form-range{width:100%}h2{color:var(--smarterplan-primary);padding:0}.col-form-label{margin-bottom:1rem}.btn-outline-primary{margin-right:1rem}.new-type-input{margin-bottom:1rem}.new-type-text{margin-bottom:.5rem}.row{margin:0}p{margin:0;padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px)}button{min-width:80px}\n"] }]
3674
+ args: [{ selector: 'lib-add-zone', template: "<div class=\"main-container\" *ngIf=\"zoneForm\">\n <div class=\"col-7\">\n <form (ngSubmit)=\"onSubmitZone()\" [formGroup]=\"zoneForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" required formControlName=\"name\">\n <!-- <div class=\"invalid-feedback\">\n {{'A name is required' | translate}}\n </div> -->\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'codeRef' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"code_ref\">\n </div>\n </div>\n <div class=\"mb-3 row\" *ngIf=\"!isMuseumVisit && !zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{'Type of zone' | translate}}</label>\n <div class=\"col-sm-10\">\n <select class=\"form-control\" formControlName=\"layerID\">\n <option value=\"null\" selected disabled hidden> {{ zoneEdit && zoneEdit.layer ?\n zoneEdit.layer.name : 'Choose type'}}</option>\n <option *ngFor=\"let layer of layers\" [value]=\"layer.id\">\n {{ layer.name }}\n </option>\n </select>\n <p class=\"mt-1 new-type-text\">{{'or add new type of zone' | translate }}</p>\n <input type=\"text\" class=\"form-control new-type-input\" formControlName=\"newLayer\">\n <div *ngIf=\"newLayer.invalid && (newLayer.dirty || newLayer.touched)\" class=\"text-danger\">\n <div *ngIf=\"newLayer.errors?.['forbiddenName']\">\n {{'Layer exists already' | translate}}\n </div>\n </div>\n </div>\n </div>\n <!--If Editing Zone possibility to assign it to museum itinerary-->\n <div class=\"mb-3 row\" *ngIf=\"zoneEdit && !zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{ 'Museum Itinerary' | translate }}</label>\n <div class=\"col-sm-10\">\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"isMuseumVisit\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"!zoneEdit || zoneEdit.isMultipleFloorZone\">\n <label class=\"col-sm-2 col-form-label\">{{ 'Multiple Floors' | translate }}</label>\n <div class=\"col-sm-10\">\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"multipleFloors\"\n [disabled]=\"zoneEdit !== undefined && zoneEdit !== null\" (change)=\"onChangeMultipleFloors()\"\n [ngModelOptions]=\"{standalone: true}\">\n <div class='text-danger' *ngIf=\"zoneEdit\">\n {{'cannotChangeMultifloor' | translate}}\n </div>\n </div>\n\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Surface' | translate}}</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" formControlName=\"surface\">\n </div>\n </div>\n\n <div class=\"mb-3 row\" *ngIf=\"!zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{'Parent zone' | translate}}</label>\n <div class=\"col-sm-10\">\n <input *ngIf=\"zoneEdit\" type=\"text\" class=\"form-control\" formControlName=\"parent\">\n <div class=\"text-danger\" *ngIf=\"zoneEdit\">\n {{'cannotChangeParent' | translate}}\n </div>\n <select *ngIf=\"!zoneEdit\" class=\"form-control\" formControlName=\"parentID\">\n <option *ngFor=\"let zone of parentZones\" [ngValue]=\"zone.id\">\n {{ zone.name }}\n </option>\n </select>\n\n </div>\n </div>\n\n <div class=\"mb-3 row\" style=\"max-height: 200px; overflow: auto;\" *ngIf=\"!zoneIsMatterportFloor\">\n <label class=\"col-sm-2 col-form-label\">{{'Scan Points' | translate}}</label>\n <!-- <p class=\"col-sm-2\" *ngIf=\"zoneEdit\">{{ zoneEdit.sweepIDs.length }} scans</p> -->\n <p class=\"col\" *ngIf=\"chosenScansOnPlan.length === 0 && chosenScans.length === 0\">\n {{'No scan points chosen' | translate}}</p>\n <div class=\"col-sm-5\" *ngIf=\"chosenScansOnPlan && chosenScansOnPlan.length > 0\">\n <p>{{ chosenScansOnPlan.length }} {{'scan points chosen' | translate}}</p>\n <!-- <div *ngFor=\"let scan of chosenScansOnPlan\">\n <div class=\"row\">\n <p class=\"me-2\">{{ scan | slice:0:8 }}</p>\n <div (click)=\"onRemoveScanPlan(scan)\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n </div> -->\n </div>\n <div class=\"col-sm-5\" *ngIf=\"carouselIsVisible && chosenScans && chosenScans.length > 0\">\n <p>{{ chosenScans.length }} {{'scan points chosen' | translate}}</p>\n <div *ngFor=\"let scan of chosenScans\">\n <div class=\"row\">\n <p class=\"me-2\">{{ images360[scan].filename }}</p>\n <div (click)=\"onRemoveScanImage(scan)\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"row mb-3 mt-3\" *ngIf=\"!zoneIsMatterportFloor\">\n <div class=\"col\">\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"togglePlan()\">{{'Choose scan points on plan' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"toggleCarousel()\"\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\n {{'Choose scan points from gallery' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAll()\"\n [disabled]=\"fromPlan || !images360 || images360.length === 0\">\n {{'add-all-scans' | translate}}</button>\n </div>\n </div>\n\n <!-- <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'No visible scan points' | translate}}</label>\n <div class=\"col-sm-3\">\n <input class=\"checkbox-apply mt-3\" type=\"checkbox\" [(ngModel)]=\"noScanPoints\"\n [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div> -->\n\n <div *ngIf=\"carouselIsVisible\" class=\"mb-2\">\n <lib-carousel *ngIf=\"images360 && images360.length > 0\" [images]=\"images360\"\n (currentScan)=\"currentScanShowing=$event\"></lib-carousel>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2 mt-3\"\n (click)=\"onAddScan()\">{{'Add to zone' | translate}}</button>\n </div>\n <div class=\"mt-3\">\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\"\n [disabled]=\"fromPlan || !zoneForm.valid\">{{'Save' | translate}}</button>\n <button type=\"button\" (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\n {{'Cancel' | translate}}</button>\n </div>\n </form>\n </div>\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\n <lib-sweep-plan-selection style=\"width: 100%;\" [newZoneData]=\"newZoneDataFromEditor\" [spaceID]=\"spaceID\"\n [multipleFloors]=\"multipleFloors\" [inputZone]=\"zoneEdit\"\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\n </div>\n</div>", styles: [".main-container{display:flex;flex-direction:column}.edit-plan{display:flex;margin:8px 0}.form-range{width:100%}h2{color:var(--smarterplan-primary);padding:0}.col-form-label{margin-bottom:1rem}.btn-outline-primary{margin-right:1rem}.new-type-input{margin-bottom:1rem}.new-type-text{margin-bottom:.5rem}.row{margin:0}p{margin:0;padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px)}button{min-width:80px}\n"] }]
3310
3675
  }], ctorParameters: () => [{ type: i1$2.UntypedFormBuilder }, { type: i2.ZoneService }, { type: i2.LayerService }, { type: i2.BaseUserService }, { type: i2.NavigationService }], propDecorators: { zoneEdit: [{
3311
3676
  type: Input
3312
3677
  }], spaceID: [{
@@ -3549,11 +3914,11 @@ class AddAudioZoneComponent {
3549
3914
  }
3550
3915
  }
3551
3916
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AddAudioZoneComponent, deps: [{ token: i1$2.UntypedFormBuilder }, { token: i2.ZoneService }, { token: i2.LayerService }, { token: i2.BaseUserService }, { token: i2.NavigationService }, { token: i2.CommentService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
3552
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AddAudioZoneComponent, selector: "lib-add-audio-zone", inputs: { spaceID: "spaceID", defaultZone: "defaultZone", zones: "zones", parentZone: "parentZone", currentAudioZone: "currentAudioZone" }, outputs: { updatedZone: "updatedZone" }, ngImport: i0, template: "<div class=\"main-container\">\r\n <div class=\"col-lg-6 col-md-6 col-sm-7\" *ngIf=\"isAddingAudio\">\r\n <form (ngSubmit)=\"onUploadAudio()\" [formGroup]=\"commentForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" required formControlName=\"title\">\r\n </div>\r\n </div>\r\n <div>\r\n <label for=\"file\" class=\"btn btn-label-file rounded-pill\">\r\n <input type=\"file\" id=\"file\" (change)=\"handleFileInput($event)\" />\r\n {{'Choose File' | translate}}</label>\r\n <p *ngIf=\"fileToUpload\">{{ fileToUpload.name}}</p>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n \r\n <div class=\"mt-3\">\r\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || working\">{{'Upload' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancelAudioUpload()\" class=\"btn btn-outline-primary rounded-pill me-2\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <ngb-alert type=\"success\" [dismissible]=\"true\" *ngIf=\"!working && audioUploaded\" (closed)=\"audioUploaded=false\">\r\n {{ 'add-audio.success' | translate }} !\r\n </ngb-alert>\r\n <div class=\"col-7\" *ngIf=\"!isAddingAudio && audiosForSpace\">\r\n \r\n <div class=\"instruction-row\" >\r\n <p>1.</p>\r\n <div ngbDropdown class=\"d-inline-block\">\r\n <div>\r\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\r\n ngbDropdownToggle>{{chosenAudio ?\r\n chosenAudio.title : ('choose-audio' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button type=\"button\" ngbDropdownItem *ngFor=\"let audio of audiosForSpace\" \r\n (click)=\"onChooseAudio(audio)\">{{ audio.title }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <p>{{'or' | translate}}</p>\r\n <button (click)=\"isAddingAudio=true\" class=\"btn btn-primary rounded-pill me-2\"> {{'add-audio.add' | translate}}</button>\r\n </div>\r\n <div class=\"instruction-row\">\r\n <p>2.</p>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"togglePlan()\" [disabled]=\"!chosenAudio\">\r\n {{'Choose scan points on plan' | translate}}</button>\r\n\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onDeleteAudio()\" [disabled]=\"!chosenAudio\">\r\n {{'Delete audio' | translate}}</button>\r\n \r\n </div>\r\n <div class=\"instruction-row\" *ngIf=\"chosenAudio\">\r\n <p>{{ chosenScansOnPlan.length }} {{'scans-chosen-audio' | translate}}</p>\r\n </div>\r\n\r\n <div class=\"mt-3\">\r\n <button class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || !this.chosenAudio\" (click)=\"onSubmit()\">{{'Save' | translate}}</button>\r\n <button (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </div>\r\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\r\n <lib-sweep-plan-selection style=\"width: 100%;\" [inputZone]=\"currentAudioZone\" [spaceID]=\"spaceID\" \r\n [occupiedSweeps]=\"occupiedSweeps\" [unavailableSweeps]=\"unavailableSweeps\" [editingAudioZone]=\"true\"\r\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\r\n </div>\r\n</div>\r\n", styles: [".instruction-row{display:flex;align-items:center;margin-top:1rem}.instruction-row button{margin-bottom:0}.instruction-row p{margin-bottom:0;margin-left:5px;margin-right:5px}\n"], dependencies: [{ kind: "component", type: i4$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i4$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i4$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i4$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i4$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i4$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { kind: "component", type: SweepPlanSelectionComponent, selector: "lib-sweep-plan-selection", inputs: ["spaceID", "chosenScansOnPlan", "newZoneData", "occupiedSweeps", "unavailableSweeps", "editingAudioZone", "inputZone", "multipleFloors"], outputs: ["sweepsSelected"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
3917
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: AddAudioZoneComponent, selector: "lib-add-audio-zone", inputs: { spaceID: "spaceID", defaultZone: "defaultZone", zones: "zones", parentZone: "parentZone", currentAudioZone: "currentAudioZone" }, outputs: { updatedZone: "updatedZone" }, ngImport: i0, template: "<div class=\"main-container\">\n <div class=\"col-lg-6 col-md-6 col-sm-7\" *ngIf=\"isAddingAudio\">\n <form (ngSubmit)=\"onUploadAudio()\" [formGroup]=\"commentForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" required formControlName=\"title\">\n </div>\n </div>\n <div>\n <label for=\"file\" class=\"btn btn-label-file rounded-pill\">\n <input type=\"file\" id=\"file\" (change)=\"handleFileInput($event)\" />\n {{'Choose File' | translate}}</label>\n <p *ngIf=\"fileToUpload\">{{ fileToUpload.name}}</p>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\n <lib-loader></lib-loader>\n </div>\n \n <div class=\"mt-3\">\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || working\">{{'Upload' | translate}}</button>\n <button type=\"button\" (click)=\"onCancelAudioUpload()\" class=\"btn btn-outline-primary rounded-pill me-2\">\n {{'Cancel' | translate}}</button>\n </div>\n </form>\n </div>\n <ngb-alert type=\"success\" [dismissible]=\"true\" *ngIf=\"!working && audioUploaded\" (closed)=\"audioUploaded=false\">\n {{ 'add-audio.success' | translate }} !\n </ngb-alert>\n <div class=\"col-7\" *ngIf=\"!isAddingAudio && audiosForSpace\">\n \n <div class=\"instruction-row\" >\n <p>1.</p>\n <div ngbDropdown class=\"d-inline-block\">\n <div>\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\n ngbDropdownToggle>{{chosenAudio ?\n chosenAudio.title : ('choose-audio' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button type=\"button\" ngbDropdownItem *ngFor=\"let audio of audiosForSpace\" \n (click)=\"onChooseAudio(audio)\">{{ audio.title }}\n </button>\n </div>\n </div>\n </div>\n <p>{{'or' | translate}}</p>\n <button (click)=\"isAddingAudio=true\" class=\"btn btn-primary rounded-pill me-2\"> {{'add-audio.add' | translate}}</button>\n </div>\n <div class=\"instruction-row\">\n <p>2.</p>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"togglePlan()\" [disabled]=\"!chosenAudio\">\n {{'Choose scan points on plan' | translate}}</button>\n\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onDeleteAudio()\" [disabled]=\"!chosenAudio\">\n {{'Delete audio' | translate}}</button>\n \n </div>\n <div class=\"instruction-row\" *ngIf=\"chosenAudio\">\n <p>{{ chosenScansOnPlan.length }} {{'scans-chosen-audio' | translate}}</p>\n </div>\n\n <div class=\"mt-3\">\n <button class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || !this.chosenAudio\" (click)=\"onSubmit()\">{{'Save' | translate}}</button>\n <button (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\n <lib-sweep-plan-selection style=\"width: 100%;\" [inputZone]=\"currentAudioZone\" [spaceID]=\"spaceID\" \n [occupiedSweeps]=\"occupiedSweeps\" [unavailableSweeps]=\"unavailableSweeps\" [editingAudioZone]=\"true\"\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\n </div>\n</div>\n", styles: [".instruction-row{display:flex;align-items:center;margin-top:1rem}.instruction-row button{margin-bottom:0}.instruction-row p{margin-bottom:0;margin-left:5px;margin-right:5px}\n"], dependencies: [{ kind: "component", type: i3$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }, { kind: "directive", type: i3$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i3$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i3$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i3$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i3$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i2.LoaderComponent, selector: "lib-loader", inputs: ["useLogo", "color"] }, { kind: "component", type: SweepPlanSelectionComponent, selector: "lib-sweep-plan-selection", inputs: ["spaceID", "chosenScansOnPlan", "newZoneData", "occupiedSweeps", "unavailableSweeps", "editingAudioZone", "inputZone", "multipleFloors"], outputs: ["sweepsSelected"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
3553
3918
  }
3554
3919
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AddAudioZoneComponent, decorators: [{
3555
3920
  type: Component,
3556
- args: [{ selector: 'lib-add-audio-zone', template: "<div class=\"main-container\">\r\n <div class=\"col-lg-6 col-md-6 col-sm-7\" *ngIf=\"isAddingAudio\">\r\n <form (ngSubmit)=\"onUploadAudio()\" [formGroup]=\"commentForm\">\r\n <div class=\"mb-3 row\">\r\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\r\n <div class=\"col-sm-10\">\r\n <input type=\"text\" class=\"form-control\" required formControlName=\"title\">\r\n </div>\r\n </div>\r\n <div>\r\n <label for=\"file\" class=\"btn btn-label-file rounded-pill\">\r\n <input type=\"file\" id=\"file\" (change)=\"handleFileInput($event)\" />\r\n {{'Choose File' | translate}}</label>\r\n <p *ngIf=\"fileToUpload\">{{ fileToUpload.name}}</p>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n \r\n <div class=\"mt-3\">\r\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || working\">{{'Upload' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancelAudioUpload()\" class=\"btn btn-outline-primary rounded-pill me-2\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <ngb-alert type=\"success\" [dismissible]=\"true\" *ngIf=\"!working && audioUploaded\" (closed)=\"audioUploaded=false\">\r\n {{ 'add-audio.success' | translate }} !\r\n </ngb-alert>\r\n <div class=\"col-7\" *ngIf=\"!isAddingAudio && audiosForSpace\">\r\n \r\n <div class=\"instruction-row\" >\r\n <p>1.</p>\r\n <div ngbDropdown class=\"d-inline-block\">\r\n <div>\r\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\r\n ngbDropdownToggle>{{chosenAudio ?\r\n chosenAudio.title : ('choose-audio' | translate) }}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button type=\"button\" ngbDropdownItem *ngFor=\"let audio of audiosForSpace\" \r\n (click)=\"onChooseAudio(audio)\">{{ audio.title }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <p>{{'or' | translate}}</p>\r\n <button (click)=\"isAddingAudio=true\" class=\"btn btn-primary rounded-pill me-2\"> {{'add-audio.add' | translate}}</button>\r\n </div>\r\n <div class=\"instruction-row\">\r\n <p>2.</p>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"togglePlan()\" [disabled]=\"!chosenAudio\">\r\n {{'Choose scan points on plan' | translate}}</button>\r\n\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onDeleteAudio()\" [disabled]=\"!chosenAudio\">\r\n {{'Delete audio' | translate}}</button>\r\n \r\n </div>\r\n <div class=\"instruction-row\" *ngIf=\"chosenAudio\">\r\n <p>{{ chosenScansOnPlan.length }} {{'scans-chosen-audio' | translate}}</p>\r\n </div>\r\n\r\n <div class=\"mt-3\">\r\n <button class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || !this.chosenAudio\" (click)=\"onSubmit()\">{{'Save' | translate}}</button>\r\n <button (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n </div>\r\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\r\n <lib-sweep-plan-selection style=\"width: 100%;\" [inputZone]=\"currentAudioZone\" [spaceID]=\"spaceID\" \r\n [occupiedSweeps]=\"occupiedSweeps\" [unavailableSweeps]=\"unavailableSweeps\" [editingAudioZone]=\"true\"\r\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\r\n </div>\r\n</div>\r\n", styles: [".instruction-row{display:flex;align-items:center;margin-top:1rem}.instruction-row button{margin-bottom:0}.instruction-row p{margin-bottom:0;margin-left:5px;margin-right:5px}\n"] }]
3921
+ args: [{ selector: 'lib-add-audio-zone', template: "<div class=\"main-container\">\n <div class=\"col-lg-6 col-md-6 col-sm-7\" *ngIf=\"isAddingAudio\">\n <form (ngSubmit)=\"onUploadAudio()\" [formGroup]=\"commentForm\">\n <div class=\"mb-3 row\">\n <label class=\"col-sm-2 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-10\">\n <input type=\"text\" class=\"form-control\" required formControlName=\"title\">\n </div>\n </div>\n <div>\n <label for=\"file\" class=\"btn btn-label-file rounded-pill\">\n <input type=\"file\" id=\"file\" (change)=\"handleFileInput($event)\" />\n {{'Choose File' | translate}}</label>\n <p *ngIf=\"fileToUpload\">{{ fileToUpload.name}}</p>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\n <lib-loader></lib-loader>\n </div>\n \n <div class=\"mt-3\">\n <button type=\"submit\" class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || working\">{{'Upload' | translate}}</button>\n <button type=\"button\" (click)=\"onCancelAudioUpload()\" class=\"btn btn-outline-primary rounded-pill me-2\">\n {{'Cancel' | translate}}</button>\n </div>\n </form>\n </div>\n <ngb-alert type=\"success\" [dismissible]=\"true\" *ngIf=\"!working && audioUploaded\" (closed)=\"audioUploaded=false\">\n {{ 'add-audio.success' | translate }} !\n </ngb-alert>\n <div class=\"col-7\" *ngIf=\"!isAddingAudio && audiosForSpace\">\n \n <div class=\"instruction-row\" >\n <p>1.</p>\n <div ngbDropdown class=\"d-inline-block\">\n <div>\n <button type=\"button\" class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\"\n ngbDropdownToggle>{{chosenAudio ?\n chosenAudio.title : ('choose-audio' | translate) }}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button type=\"button\" ngbDropdownItem *ngFor=\"let audio of audiosForSpace\" \n (click)=\"onChooseAudio(audio)\">{{ audio.title }}\n </button>\n </div>\n </div>\n </div>\n <p>{{'or' | translate}}</p>\n <button (click)=\"isAddingAudio=true\" class=\"btn btn-primary rounded-pill me-2\"> {{'add-audio.add' | translate}}</button>\n </div>\n <div class=\"instruction-row\">\n <p>2.</p>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"togglePlan()\" [disabled]=\"!chosenAudio\">\n {{'Choose scan points on plan' | translate}}</button>\n\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onDeleteAudio()\" [disabled]=\"!chosenAudio\">\n {{'Delete audio' | translate}}</button>\n \n </div>\n <div class=\"instruction-row\" *ngIf=\"chosenAudio\">\n <p>{{ chosenScansOnPlan.length }} {{'scans-chosen-audio' | translate}}</p>\n </div>\n\n <div class=\"mt-3\">\n <button class=\"btn btn-primary rounded-pill me-2\" [disabled]=\"fromPlan || !this.chosenAudio\" (click)=\"onSubmit()\">{{'Save' | translate}}</button>\n <button (click)=\"onCancel()\" class=\"btn btn-outline-primary rounded-pill me-2\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n <div class=\"edit-plan\" *ngIf=\"fromPlan\">\n <lib-sweep-plan-selection style=\"width: 100%;\" [inputZone]=\"currentAudioZone\" [spaceID]=\"spaceID\" \n [occupiedSweeps]=\"occupiedSweeps\" [unavailableSweeps]=\"unavailableSweeps\" [editingAudioZone]=\"true\"\n (sweepsSelected)=\"onSelectedSweepsFromPlan($event)\"></lib-sweep-plan-selection>\n </div>\n</div>\n", styles: [".instruction-row{display:flex;align-items:center;margin-top:1rem}.instruction-row button{margin-bottom:0}.instruction-row p{margin-bottom:0;margin-left:5px;margin-right:5px}\n"] }]
3557
3922
  }], ctorParameters: () => [{ type: i1$2.UntypedFormBuilder }, { type: i2.ZoneService }, { type: i2.LayerService }, { type: i2.BaseUserService }, { type: i2.NavigationService }, { type: i2.CommentService }, { type: i3.TranslateService }], propDecorators: { spaceID: [{
3558
3923
  type: Input
3559
3924
  }], updatedZone: [{
@@ -3859,11 +4224,11 @@ class ZonesComponent {
3859
4224
  }
3860
4225
  }
3861
4226
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ZonesComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.ZoneService }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i2.NavigationService }, { token: i2.BaseUserService }, { token: i2.PlanService }, { token: i3.TranslateService }, { token: i2.NavigatorService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
3862
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ZonesComponent, selector: "lib-zones", outputs: { updatedZone: "updatedZone" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n <div class=\"row\" *ngIf=\"!isEditingZone && !isAddingAudioTrack\">\r\n <div class=\"col-md-6\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item default-zone-line-item\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\" *ngIf=\"defaultZone\">\r\n {{defaultZone.name}}\r\n <div class=\"default-zone-label\">{{ \"whole space\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"defaultShowing\" (click)=\"onToggleDefaultZone()\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"defaultShowing\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}:\r\n {{defaultZone.layer ? defaultZone.layer.name : \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"defaultZone.surface\">\r\n {{'Surface' | translate}}, m<sup>2</sup>: {{defaultZone.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!defaultZone.virtual\">{{'Scan Points' | translate}}:\r\n {{defaultZone.sweepIDs ? defaultZone.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n </ul>\r\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\r\n <div *ngIf=\"pair.key == defaultZone.id\">\r\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-flush list-group-item-action\"\r\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\r\n {{lot.name}}\r\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\r\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\r\n\r\n </div>\r\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\r\n translate}}: {{lot.layer ? lot.layer.name :\r\n \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">\r\n {{'Surface' | translate}},m<sup>2</sup>: {{lot.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\r\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\r\n {{'Zone not visible in 3D visit' | translate}}</li>\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\r\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </li>\r\n\r\n <li class=\"list-group-item\" *ngFor=\"let floor of floorZones; index as index\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\r\n {{floor.name}}\r\n <!-- <small>({{ lot.metadata ? ('Calibrated' | translate) : ('Not calibrated' | translate)}})</small> -->\r\n <div class=\"museum-label\" *ngIf=\"floor.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"index==floorDetails\"\r\n (click)=\"onToggleDetailFloor(index, floor)\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"index==floorDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}: {{floor.layer ?\r\n floor.layer.name :\r\n \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.surface\">{{'Surface' | translate}}, m<sup>2</sup>:\r\n {{floor.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!floor.virtual\">{{'Scan Points' | translate}}:\r\n {{floor.sweepIDs ? floor.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.virtual\">{{'Zone not visible in 3D visit' |\r\n translate}}</li>\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onEdit(floor)\">{{'Edit' |\r\n translate}}</button>\r\n\r\n <!-- List of children zones -->\r\n\r\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\r\n <div *ngIf=\"pair.key == floor.id\">\r\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-flush list-group-item-action\"\r\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\r\n <div><span *ngIf=\"lot.code_ref\">{{lot.code_ref}}_</span>{{lot.name}}</div>\r\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\r\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\r\n\r\n </div>\r\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\r\n translate}}: {{lot.layer ? lot.layer.name :\r\n \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">{{'Surface' | translate}},\r\n m<sup>2</sup>:\r\n {{lot.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\r\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual && lot.isMuseumVisitZone\">\r\n {{'Scan Points with audio' | translate}}: {{ lot | countAudioSweeps | async}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\r\n {{'Zone not visible in 3D visit' | translate}}</li> dist\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\r\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n <div>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddLot()\">{{'Add zone' |\r\n translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddMuseumZone()\" *ngIf=\"isMuseumModule\">\r\n {{'Add museum itinerary' | translate}}</button>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"planIsVisible\">\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loadingPlan\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n <div class=\"row\" style=\"overflow: hidden; flex-direction: column;\">\r\n <div *ngIf=\"currentPlan\">\r\n <lib-plan-legend [isAudioZone]=\"false\"></lib-plan-legend>\r\n <div class=\"planContainer\">\r\n <div class=\"mt-3 ms-3\" style=\"height: 500px; width: 100%;\" id=\"planDiv\"></div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"!currentPlan && plans && !loadingPlan && currentZone\">\r\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"!currentZone.virtual && !currentZone.isMultipleFloorZone\">\r\n {{ 'Plan is not calibrated' | translate}}\r\n </div>\r\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.virtual\">\r\n {{ 'No scan points chosen' | translate}}\r\n </div>\r\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.isMultipleFloorZone\">\r\n {{ 'The zone is on several floors' | translate}}\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mb-3\" *ngIf=\"isEditingZone\">\r\n <lib-add-zone [zoneEdit]=\"zoneForEdit\" [spaceID]=\"spaceID\" [images360]=\"images360\" [navigationIDs]=\"navigations\"\r\n [zones]=\"allZones\" [defaultZone]=\"defaultZone\" (updatedZone)=\"editCompleted($event)\"\r\n [isMuseumVisit]=\"isMuseumVisit\"></lib-add-zone>\r\n </div>\r\n <div class=\"mb-3\" *ngIf=\"isAddingAudioTrack\">\r\n <lib-add-audio-zone [spaceID]=\"spaceID\" [defaultZone]=\"defaultZone\" [parentZone]=\"parentZoneForAudio\"\r\n [zones]=\"allZones\" [currentAudioZone]=\"zoneForEdit\" (updatedZone)=\"editCompleted($event)\"></lib-add-audio-zone>\r\n </div>\r\n</div>", styles: [".museum-label{background-color:#6f3974;font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.default-zone-line-item{border-bottom-width:3px}.default-zone-label{background-color:var(--smarterplan-primary);font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.planContainer{overflow:hidden;border-radius:6px;background-color:var(--smarterplan-secondary);height:500px}button{min-width:80px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { kind: "component", type: AddZoneComponent, selector: "lib-add-zone", inputs: ["zoneEdit", "spaceID", "images360", "navigationIDs", "zones", "newZoneDataFromEditor", "chosenPlan", "isMuseumVisit", "defaultZone"], outputs: ["updatedZone"] }, { kind: "component", type: AddAudioZoneComponent, selector: "lib-add-audio-zone", inputs: ["spaceID", "defaultZone", "zones", "parentZone", "currentAudioZone"], outputs: ["updatedZone"] }, { kind: "component", type: PlanLegendComponent, selector: "lib-plan-legend", inputs: ["isAudioZone"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: CountAudioSweepsPipe, name: "countAudioSweeps" }] });
4227
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ZonesComponent, selector: "lib-zones", outputs: { updatedZone: "updatedZone" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"row\" *ngIf=\"!isEditingZone && !isAddingAudioTrack\">\n <div class=\"col-md-6\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item default-zone-line-item\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\" *ngIf=\"defaultZone\">\n {{defaultZone.name}}\n <div class=\"default-zone-label\">{{ \"whole space\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"defaultShowing\" (click)=\"onToggleDefaultZone()\"></lib-chevron>\n </div>\n <div *ngIf=\"defaultShowing\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}:\n {{defaultZone.layer ? defaultZone.layer.name : \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"defaultZone.surface\">\n {{'Surface' | translate}}, m<sup>2</sup>: {{defaultZone.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!defaultZone.virtual\">{{'Scan Points' | translate}}:\n {{defaultZone.sweepIDs ? defaultZone.sweepIDs.length : \"No scan points\" | translate}} </li>\n </ul>\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\n <div *ngIf=\"pair.key == defaultZone.id\">\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item list-group-flush list-group-item-action\"\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\n {{lot.name}}\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\n\n </div>\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\n translate}}: {{lot.layer ? lot.layer.name :\n \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">\n {{'Surface' | translate}},m<sup>2</sup>: {{lot.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\n {{'Zone not visible in 3D visit' | translate}}</li>\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\n </div>\n </li>\n </ul>\n\n </div>\n </div>\n </div>\n </li>\n\n <li class=\"list-group-item\" *ngFor=\"let floor of floorZones; index as index\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\n {{floor.name}}\n <!-- <small>({{ lot.metadata ? ('Calibrated' | translate) : ('Not calibrated' | translate)}})</small> -->\n <div class=\"museum-label\" *ngIf=\"floor.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"index==floorDetails\"\n (click)=\"onToggleDetailFloor(index, floor)\"></lib-chevron>\n </div>\n <div *ngIf=\"index==floorDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}: {{floor.layer ?\n floor.layer.name :\n \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.surface\">{{'Surface' | translate}}, m<sup>2</sup>:\n {{floor.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!floor.virtual\">{{'Scan Points' | translate}}:\n {{floor.sweepIDs ? floor.sweepIDs.length : \"No scan points\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.virtual\">{{'Zone not visible in 3D visit' |\n translate}}</li>\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onEdit(floor)\">{{'Edit' |\n translate}}</button>\n\n <!-- List of children zones -->\n\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\n <div *ngIf=\"pair.key == floor.id\">\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item list-group-flush list-group-item-action\"\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\n <div><span *ngIf=\"lot.code_ref\">{{lot.code_ref}}_</span>{{lot.name}}</div>\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\n\n </div>\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\n translate}}: {{lot.layer ? lot.layer.name :\n \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">{{'Surface' | translate}},\n m<sup>2</sup>:\n {{lot.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual && lot.isMuseumVisitZone\">\n {{'Scan Points with audio' | translate}}: {{ lot | countAudioSweeps | async}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\n {{'Zone not visible in 3D visit' | translate}}</li> dist\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\n </div>\n </li>\n </ul>\n\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <div>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddLot()\">{{'Add zone' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddMuseumZone()\" *ngIf=\"isMuseumModule\">\n {{'Add museum itinerary' | translate}}</button>\n </div>\n </div>\n <div class=\"col-md-6\" *ngIf=\"planIsVisible\">\n <div class=\"d-flex justify-content-center\" *ngIf=\"loadingPlan\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <div class=\"row\" style=\"overflow: hidden; flex-direction: column;\">\n <div *ngIf=\"currentPlan\">\n <lib-plan-legend [isAudioZone]=\"false\"></lib-plan-legend>\n <div class=\"planContainer\">\n <div class=\"mt-3 ms-3\" style=\"height: 500px; width: 100%;\" id=\"planDiv\"></div>\n </div>\n </div>\n\n <div *ngIf=\"!currentPlan && plans && !loadingPlan && currentZone\">\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"!currentZone.virtual && !currentZone.isMultipleFloorZone\">\n {{ 'Plan is not calibrated' | translate}}\n </div>\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.virtual\">\n {{ 'No scan points chosen' | translate}}\n </div>\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.isMultipleFloorZone\">\n {{ 'The zone is on several floors' | translate}}\n </div>\n </div>\n\n </div>\n </div>\n </div>\n <div class=\"mb-3\" *ngIf=\"isEditingZone\">\n <lib-add-zone [zoneEdit]=\"zoneForEdit\" [spaceID]=\"spaceID\" [images360]=\"images360\" [navigationIDs]=\"navigations\"\n [zones]=\"allZones\" [defaultZone]=\"defaultZone\" (updatedZone)=\"editCompleted($event)\"\n [isMuseumVisit]=\"isMuseumVisit\"></lib-add-zone>\n </div>\n <div class=\"mb-3\" *ngIf=\"isAddingAudioTrack\">\n <lib-add-audio-zone [spaceID]=\"spaceID\" [defaultZone]=\"defaultZone\" [parentZone]=\"parentZoneForAudio\"\n [zones]=\"allZones\" [currentAudioZone]=\"zoneForEdit\" (updatedZone)=\"editCompleted($event)\"></lib-add-audio-zone>\n </div>\n</div>", styles: [".museum-label{background-color:#6f3974;font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.default-zone-line-item{border-bottom-width:3px}.default-zone-label{background-color:var(--smarterplan-primary);font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.planContainer{overflow:hidden;border-radius:6px;background-color:var(--smarterplan-secondary);height:500px}button{min-width:80px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { kind: "component", type: AddZoneComponent, selector: "lib-add-zone", inputs: ["zoneEdit", "spaceID", "images360", "navigationIDs", "zones", "newZoneDataFromEditor", "chosenPlan", "isMuseumVisit", "defaultZone"], outputs: ["updatedZone"] }, { kind: "component", type: AddAudioZoneComponent, selector: "lib-add-audio-zone", inputs: ["spaceID", "defaultZone", "zones", "parentZone", "currentAudioZone"], outputs: ["updatedZone"] }, { kind: "component", type: PlanLegendComponent, selector: "lib-plan-legend", inputs: ["isAudioZone"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: CountAudioSweepsPipe, name: "countAudioSweeps" }] });
3863
4228
  }
3864
4229
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ZonesComponent, decorators: [{
3865
4230
  type: Component,
3866
- args: [{ selector: 'lib-zones', template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n <div class=\"row\" *ngIf=\"!isEditingZone && !isAddingAudioTrack\">\r\n <div class=\"col-md-6\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item default-zone-line-item\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\" *ngIf=\"defaultZone\">\r\n {{defaultZone.name}}\r\n <div class=\"default-zone-label\">{{ \"whole space\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"defaultShowing\" (click)=\"onToggleDefaultZone()\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"defaultShowing\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}:\r\n {{defaultZone.layer ? defaultZone.layer.name : \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"defaultZone.surface\">\r\n {{'Surface' | translate}}, m<sup>2</sup>: {{defaultZone.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!defaultZone.virtual\">{{'Scan Points' | translate}}:\r\n {{defaultZone.sweepIDs ? defaultZone.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n </ul>\r\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\r\n <div *ngIf=\"pair.key == defaultZone.id\">\r\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-flush list-group-item-action\"\r\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\r\n {{lot.name}}\r\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\r\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\r\n\r\n </div>\r\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\r\n translate}}: {{lot.layer ? lot.layer.name :\r\n \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">\r\n {{'Surface' | translate}},m<sup>2</sup>: {{lot.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\r\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\r\n {{'Zone not visible in 3D visit' | translate}}</li>\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\r\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </li>\r\n\r\n <li class=\"list-group-item\" *ngFor=\"let floor of floorZones; index as index\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\r\n {{floor.name}}\r\n <!-- <small>({{ lot.metadata ? ('Calibrated' | translate) : ('Not calibrated' | translate)}})</small> -->\r\n <div class=\"museum-label\" *ngIf=\"floor.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"index==floorDetails\"\r\n (click)=\"onToggleDetailFloor(index, floor)\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"index==floorDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}: {{floor.layer ?\r\n floor.layer.name :\r\n \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.surface\">{{'Surface' | translate}}, m<sup>2</sup>:\r\n {{floor.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!floor.virtual\">{{'Scan Points' | translate}}:\r\n {{floor.sweepIDs ? floor.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.virtual\">{{'Zone not visible in 3D visit' |\r\n translate}}</li>\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onEdit(floor)\">{{'Edit' |\r\n translate}}</button>\r\n\r\n <!-- List of children zones -->\r\n\r\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\r\n <div *ngIf=\"pair.key == floor.id\">\r\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-flush list-group-item-action\"\r\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\r\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\r\n <div><span *ngIf=\"lot.code_ref\">{{lot.code_ref}}_</span>{{lot.name}}</div>\r\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\r\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\r\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\r\n\r\n </div>\r\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\r\n translate}}: {{lot.layer ? lot.layer.name :\r\n \"No type\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">{{'Surface' | translate}},\r\n m<sup>2</sup>:\r\n {{lot.surface }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\r\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual && lot.isMuseumVisitZone\">\r\n {{'Scan Points with audio' | translate}}: {{ lot | countAudioSweeps | async}} </li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\r\n {{'Zone not visible in 3D visit' | translate}}</li> dist\r\n </ul>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\r\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\r\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\r\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n\r\n <div>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddLot()\">{{'Add zone' |\r\n translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddMuseumZone()\" *ngIf=\"isMuseumModule\">\r\n {{'Add museum itinerary' | translate}}</button>\r\n </div>\r\n </div>\r\n <div class=\"col-md-6\" *ngIf=\"planIsVisible\">\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loadingPlan\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n <div class=\"row\" style=\"overflow: hidden; flex-direction: column;\">\r\n <div *ngIf=\"currentPlan\">\r\n <lib-plan-legend [isAudioZone]=\"false\"></lib-plan-legend>\r\n <div class=\"planContainer\">\r\n <div class=\"mt-3 ms-3\" style=\"height: 500px; width: 100%;\" id=\"planDiv\"></div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"!currentPlan && plans && !loadingPlan && currentZone\">\r\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"!currentZone.virtual && !currentZone.isMultipleFloorZone\">\r\n {{ 'Plan is not calibrated' | translate}}\r\n </div>\r\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.virtual\">\r\n {{ 'No scan points chosen' | translate}}\r\n </div>\r\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.isMultipleFloorZone\">\r\n {{ 'The zone is on several floors' | translate}}\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"mb-3\" *ngIf=\"isEditingZone\">\r\n <lib-add-zone [zoneEdit]=\"zoneForEdit\" [spaceID]=\"spaceID\" [images360]=\"images360\" [navigationIDs]=\"navigations\"\r\n [zones]=\"allZones\" [defaultZone]=\"defaultZone\" (updatedZone)=\"editCompleted($event)\"\r\n [isMuseumVisit]=\"isMuseumVisit\"></lib-add-zone>\r\n </div>\r\n <div class=\"mb-3\" *ngIf=\"isAddingAudioTrack\">\r\n <lib-add-audio-zone [spaceID]=\"spaceID\" [defaultZone]=\"defaultZone\" [parentZone]=\"parentZoneForAudio\"\r\n [zones]=\"allZones\" [currentAudioZone]=\"zoneForEdit\" (updatedZone)=\"editCompleted($event)\"></lib-add-audio-zone>\r\n </div>\r\n</div>", styles: [".museum-label{background-color:#6f3974;font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.default-zone-line-item{border-bottom-width:3px}.default-zone-label{background-color:var(--smarterplan-primary);font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.planContainer{overflow:hidden;border-radius:6px;background-color:var(--smarterplan-secondary);height:500px}button{min-width:80px}\n"] }]
4231
+ args: [{ selector: 'lib-zones', template: "<div class=\"container-fluid\" *ngIf=\"currentSpace\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"row\" *ngIf=\"!isEditingZone && !isAddingAudioTrack\">\n <div class=\"col-md-6\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item default-zone-line-item\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\" *ngIf=\"defaultZone\">\n {{defaultZone.name}}\n <div class=\"default-zone-label\">{{ \"whole space\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"defaultShowing\" (click)=\"onToggleDefaultZone()\"></lib-chevron>\n </div>\n <div *ngIf=\"defaultShowing\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}:\n {{defaultZone.layer ? defaultZone.layer.name : \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"defaultZone.surface\">\n {{'Surface' | translate}}, m<sup>2</sup>: {{defaultZone.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!defaultZone.virtual\">{{'Scan Points' | translate}}:\n {{defaultZone.sweepIDs ? defaultZone.sweepIDs.length : \"No scan points\" | translate}} </li>\n </ul>\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\n <div *ngIf=\"pair.key == defaultZone.id\">\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item list-group-flush list-group-item-action\"\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\n {{lot.name}}\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\n\n </div>\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\n translate}}: {{lot.layer ? lot.layer.name :\n \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">\n {{'Surface' | translate}},m<sup>2</sup>: {{lot.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\n {{'Zone not visible in 3D visit' | translate}}</li>\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\n </div>\n </li>\n </ul>\n\n </div>\n </div>\n </div>\n </li>\n\n <li class=\"list-group-item\" *ngFor=\"let floor of floorZones; index as index\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\n {{floor.name}}\n <!-- <small>({{ lot.metadata ? ('Calibrated' | translate) : ('Not calibrated' | translate)}})</small> -->\n <div class=\"museum-label\" *ngIf=\"floor.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"index==floorDetails\"\n (click)=\"onToggleDetailFloor(index, floor)\"></lib-chevron>\n </div>\n <div *ngIf=\"index==floorDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Type of zone' | translate}}: {{floor.layer ?\n floor.layer.name :\n \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.surface\">{{'Surface' | translate}}, m<sup>2</sup>:\n {{floor.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!floor.virtual\">{{'Scan Points' | translate}}:\n {{floor.sweepIDs ? floor.sweepIDs.length : \"No scan points\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"floor.virtual\">{{'Zone not visible in 3D visit' |\n translate}}</li>\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onEdit(floor)\">{{'Edit' |\n translate}}</button>\n\n <!-- List of children zones -->\n\n <div *ngFor=\"let pair of zonesMap | keyvalue\">\n <div *ngIf=\"pair.key == floor.id\">\n <h5 style=\"margin: 8px;\" *ngIf=\"pair.value.length > 0\">{{'Children zones'|translate}}</h5>\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item list-group-flush list-group-item-action\"\n *ngFor=\"let lot of pair.value; index as zoneIndex\">\n <div class=\"d-flex justify-content-between align-items-center zone-name\">\n <div><span *ngIf=\"lot.code_ref\">{{lot.code_ref}}_</span>{{lot.name}}</div>\n <div class=\"museum-label\" *ngIf=\"lot.isMuseumVisitZone\">{{ \"itinerary\" | translate }}</div>\n <lib-chevron [conditionShowing]=\"zoneIndex==lotIndexDetails\"\n (click)=\"onToggleDetail(zoneIndex, lot)\"></lib-chevron>\n\n </div>\n <div *ngIf=\"zoneIndex==lotIndexDetails\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.isMuseumVisitZone\">{{'Type of zone' |\n translate}}: {{lot.layer ? lot.layer.name :\n \"No type\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.surface\">{{'Surface' | translate}},\n m<sup>2</sup>:\n {{lot.surface }}\n </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual\">{{'Scan Points' | translate}}:\n {{lot.sweepIDs ? lot.sweepIDs.length : \"No scan points\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"!lot.virtual && lot.isMuseumVisitZone\">\n {{'Scan Points with audio' | translate}}: {{ lot | countAudioSweeps | async}} </li>\n <li class=\"list-group-item bg-transparent\" *ngIf=\"lot.virtual\">\n {{'Zone not visible in 3D visit' | translate}}</li> dist\n </ul>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill me-2\"\n (click)=\"onEdit(lot)\">{{'Edit' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddAudioZone(lot)\"\n *ngIf=\"isMuseumModule\"> {{'add-audio.add' | translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"onDelete(lot)\">{{'Delete' | translate}}</button>\n </div>\n </li>\n </ul>\n\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <div>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddLot()\">{{'Add zone' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onAddMuseumZone()\" *ngIf=\"isMuseumModule\">\n {{'Add museum itinerary' | translate}}</button>\n </div>\n </div>\n <div class=\"col-md-6\" *ngIf=\"planIsVisible\">\n <div class=\"d-flex justify-content-center\" *ngIf=\"loadingPlan\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <div class=\"row\" style=\"overflow: hidden; flex-direction: column;\">\n <div *ngIf=\"currentPlan\">\n <lib-plan-legend [isAudioZone]=\"false\"></lib-plan-legend>\n <div class=\"planContainer\">\n <div class=\"mt-3 ms-3\" style=\"height: 500px; width: 100%;\" id=\"planDiv\"></div>\n </div>\n </div>\n\n <div *ngIf=\"!currentPlan && plans && !loadingPlan && currentZone\">\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"!currentZone.virtual && !currentZone.isMultipleFloorZone\">\n {{ 'Plan is not calibrated' | translate}}\n </div>\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.virtual\">\n {{ 'No scan points chosen' | translate}}\n </div>\n <div class=\"mt-3 ms-3\" id=\"no-plan\" *ngIf=\"currentZone.isMultipleFloorZone\">\n {{ 'The zone is on several floors' | translate}}\n </div>\n </div>\n\n </div>\n </div>\n </div>\n <div class=\"mb-3\" *ngIf=\"isEditingZone\">\n <lib-add-zone [zoneEdit]=\"zoneForEdit\" [spaceID]=\"spaceID\" [images360]=\"images360\" [navigationIDs]=\"navigations\"\n [zones]=\"allZones\" [defaultZone]=\"defaultZone\" (updatedZone)=\"editCompleted($event)\"\n [isMuseumVisit]=\"isMuseumVisit\"></lib-add-zone>\n </div>\n <div class=\"mb-3\" *ngIf=\"isAddingAudioTrack\">\n <lib-add-audio-zone [spaceID]=\"spaceID\" [defaultZone]=\"defaultZone\" [parentZone]=\"parentZoneForAudio\"\n [zones]=\"allZones\" [currentAudioZone]=\"zoneForEdit\" (updatedZone)=\"editCompleted($event)\"></lib-add-audio-zone>\n </div>\n</div>", styles: [".museum-label{background-color:#6f3974;font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.default-zone-line-item{border-bottom-width:3px}.default-zone-label{background-color:var(--smarterplan-primary);font-size:.95rem;border-radius:10px;padding:5px 10px;color:#fff;text-transform:uppercase;margin-left:auto;margin-right:8px}.planContainer{overflow:hidden;border-radius:6px;background-color:var(--smarterplan-secondary);height:500px}button{min-width:80px}\n"] }]
3867
4232
  }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.ZoneService }, { type: i2.SpaceService }, { type: i2.VisitService }, { type: i2.NavigationService }, { type: i2.BaseUserService }, { type: i2.PlanService }, { type: i3.TranslateService }, { type: i2.NavigatorService }, { type: i1.Router }], propDecorators: { updatedZone: [{
3868
4233
  type: Output
3869
4234
  }] } });
@@ -3969,11 +4334,11 @@ class ImagesComponent {
3969
4334
  }
3970
4335
  }
3971
4336
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImagesComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i2.NodeService }, { token: i2.NavigatorService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
3972
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ImagesComponent, selector: "lib-images", ngImport: i0, template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\r\n </div>\r\n </div>\r\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\r\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\r\n </button>\r\n </div>\r\n </div>\r\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\r\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\r\n <h4>{{'No imported images' | translate }}</h4>\r\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\r\n </div>\r\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\r\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\r\n {{'Run AI inventory on this image' | translate}}</button>\r\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\r\n </div>", styles: [""], dependencies: [{ kind: "directive", type: i4$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i4$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i4$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i4$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i4$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: CarouselComponent, selector: "lib-carousel", inputs: ["images"], outputs: ["currentScan"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
4337
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ImagesComponent, selector: "lib-images", ngImport: i0, template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>", styles: [""], dependencies: [{ kind: "directive", type: i3$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "popperOptions", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { kind: "directive", type: i3$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { kind: "directive", type: i3$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { kind: "directive", type: i3$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["tabindex", "disabled"] }, { kind: "directive", type: i3$1.NgbDropdownButtonItem, selector: "button[ngbDropdownItem]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: CarouselComponent, selector: "lib-carousel", inputs: ["images"], outputs: ["currentScan"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
3973
4338
  }
3974
4339
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ImagesComponent, decorators: [{
3975
4340
  type: Component,
3976
- args: [{ selector: 'lib-images', template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\r\n </div>\r\n </div>\r\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\r\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\r\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\r\n </button>\r\n </div>\r\n </div>\r\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\r\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\r\n <h4>{{'No imported images' | translate }}</h4>\r\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\r\n </div>\r\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\r\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\r\n {{'Run AI inventory on this image' | translate}}</button>\r\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\r\n </div>" }]
4341
+ args: [{ selector: 'lib-images', template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>" }]
3977
4342
  }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.SpaceService }, { type: i2.VisitService }, { type: i2.NodeService }, { type: i2.NavigatorService }, { type: i1.Router }] });
3978
4343
 
3979
4344
  class EditPlanComponent {
@@ -4292,13 +4657,13 @@ class EditPlanComponent {
4292
4657
  this.svgEditorIframe.contentWindow.postMessage({ action: "cancel-layer" }, "*");
4293
4658
  }
4294
4659
  }
4295
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditPlanComponent, deps: [{ token: i2.PlanService }, { token: i1.ActivatedRoute }, { token: i1.Router }, { token: i4$1.NgbModal }, { token: i2.ZoneService }, { token: i2.VisitService }, { token: i2.SpaceService }, { token: i3.TranslateService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
4296
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EditPlanComponent, selector: "lib-edit-plan", host: { listeners: { "window:message": "switchAction($event)" } }, viewQueries: [{ propertyName: "dialog", first: true, predicate: ["dialog"], descendants: true }, { propertyName: "dialogZone", first: true, predicate: ["dialogZone"], descendants: true }, { propertyName: "loadingModal", first: true, predicate: ["preparing"], descendants: true }], ngImport: i0, template: "<div class=\"row mt-3\">\r\n <div class=\"col\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\r\n </div>\r\n </div>\r\n</div>\r\n<lib-add-zone *ngIf=\"isNewZone\" [images360]=\"images360\" [spaceID]=\"spaceID\" [navigationIDs]=\"navigations\"\r\n [zoneEdit]=\"editedZone\" [zones]=\"zones\" (updatedZone)=\"onNewZone($event)\" [chosenPlan]=\"editedPlan\"\r\n [newZoneDataFromEditor]=\"newZoneData\"></lib-add-zone>\r\n<iframe *ngIf=\"editorUrl\" #svgEditor [src]=\"editorUrl | safeUrl\" frameborder=\"0\"\r\n style=\"height:100%;width:100%;min-height:550px;max-height:750px\" (load)=\"onLoad(svgEditor)\"></iframe>\r\n<!-- chosenPlan && -->\r\n<!-- ./../../../../../../assets/svgeditor/index.html -->\r\n\r\n<img #imgPng *ngIf=\"chosenPlan && chosenPlan.extension !== 'svg' && svgEditor\" [src]=\"chosenPlan.filepath\"\r\n (load)=\"onLoadImg(imgPng)\" style=\"display: none;\">\r\n\r\n<canvas id=\"canvas4pdf\" style=\"display: none;\"></canvas>\r\n\r\n<ng-template #dialog let-modal>\r\n\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'save plan edited' | translate}}\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"newSvg();modal.close('Close click')\">{{'Yes' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"updateSvg();modal.close('Close click')\">{{'No' |\r\n translate}}</button>\r\n </div>\r\n\r\n</ng-template>\r\n\r\n<ng-template #dialogZone let-modal>\r\n\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'confirm.new-zone-from-plan' | translate}}\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\"\r\n (click)=\"isNewZone = true;modal.close('Close click')\">{{'Validate' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"modal.close('Close click')\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n\r\n</ng-template>\r\n\r\n<ng-template #preparing let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">{{'Processing' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-template>", styles: ["app-add-zone{position:absolute;top:0;left:0;background-color:#fff;width:100%;height:100%;padding:30px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: AddZoneComponent, selector: "lib-add-zone", inputs: ["zoneEdit", "spaceID", "images360", "navigationIDs", "zones", "newZoneDataFromEditor", "chosenPlan", "isMuseumVisit", "defaultZone"], outputs: ["updatedZone"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.SafeUrlPipe, name: "safeUrl" }] });
4660
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditPlanComponent, deps: [{ token: i2.PlanService }, { token: i1.ActivatedRoute }, { token: i1.Router }, { token: i3$1.NgbModal }, { token: i2.ZoneService }, { token: i2.VisitService }, { token: i2.SpaceService }, { token: i3.TranslateService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
4661
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EditPlanComponent, selector: "lib-edit-plan", host: { listeners: { "window:message": "switchAction($event)" } }, viewQueries: [{ propertyName: "dialog", first: true, predicate: ["dialog"], descendants: true }, { propertyName: "dialogZone", first: true, predicate: ["dialogZone"], descendants: true }, { propertyName: "loadingModal", first: true, predicate: ["preparing"], descendants: true }], ngImport: i0, template: "<div class=\"row mt-3\">\n <div class=\"col\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\n </div>\n </div>\n</div>\n<lib-add-zone *ngIf=\"isNewZone\" [images360]=\"images360\" [spaceID]=\"spaceID\" [navigationIDs]=\"navigations\"\n [zoneEdit]=\"editedZone\" [zones]=\"zones\" (updatedZone)=\"onNewZone($event)\" [chosenPlan]=\"editedPlan\"\n [newZoneDataFromEditor]=\"newZoneData\"></lib-add-zone>\n<iframe *ngIf=\"editorUrl\" #svgEditor [src]=\"editorUrl | safeUrl\" frameborder=\"0\"\n style=\"height:100%;width:100%;min-height:550px;max-height:750px\" (load)=\"onLoad(svgEditor)\"></iframe>\n<!-- chosenPlan && -->\n<!-- ./../../../../../../assets/svgeditor/index.html -->\n\n<img #imgPng *ngIf=\"chosenPlan && chosenPlan.extension !== 'svg' && svgEditor\" [src]=\"chosenPlan.filepath\"\n (load)=\"onLoadImg(imgPng)\" style=\"display: none;\">\n\n<canvas id=\"canvas4pdf\" style=\"display: none;\"></canvas>\n\n<ng-template #dialog let-modal>\n\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'save plan edited' | translate}}\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"newSvg();modal.close('Close click')\">{{'Yes' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"updateSvg();modal.close('Close click')\">{{'No' |\n translate}}</button>\n </div>\n\n</ng-template>\n\n<ng-template #dialogZone let-modal>\n\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'confirm.new-zone-from-plan' | translate}}\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\"\n (click)=\"isNewZone = true;modal.close('Close click')\">{{'Validate' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"modal.close('Close click')\">{{'Cancel' |\n translate}}</button>\n </div>\n\n</ng-template>\n\n<ng-template #preparing let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Processing' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n </div>\n\n</ng-template>", styles: ["app-add-zone{position:absolute;top:0;left:0;background-color:#fff;width:100%;height:100%;padding:30px}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: AddZoneComponent, selector: "lib-add-zone", inputs: ["zoneEdit", "spaceID", "images360", "navigationIDs", "zones", "newZoneDataFromEditor", "chosenPlan", "isMuseumVisit", "defaultZone"], outputs: ["updatedZone"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "pipe", type: i2.SafeUrlPipe, name: "safeUrl" }] });
4297
4662
  }
4298
4663
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditPlanComponent, decorators: [{
4299
4664
  type: Component,
4300
- args: [{ selector: 'lib-edit-plan', template: "<div class=\"row mt-3\">\r\n <div class=\"col\">\r\n <div class=\"m-3\">\r\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\r\n </div>\r\n </div>\r\n</div>\r\n<lib-add-zone *ngIf=\"isNewZone\" [images360]=\"images360\" [spaceID]=\"spaceID\" [navigationIDs]=\"navigations\"\r\n [zoneEdit]=\"editedZone\" [zones]=\"zones\" (updatedZone)=\"onNewZone($event)\" [chosenPlan]=\"editedPlan\"\r\n [newZoneDataFromEditor]=\"newZoneData\"></lib-add-zone>\r\n<iframe *ngIf=\"editorUrl\" #svgEditor [src]=\"editorUrl | safeUrl\" frameborder=\"0\"\r\n style=\"height:100%;width:100%;min-height:550px;max-height:750px\" (load)=\"onLoad(svgEditor)\"></iframe>\r\n<!-- chosenPlan && -->\r\n<!-- ./../../../../../../assets/svgeditor/index.html -->\r\n\r\n<img #imgPng *ngIf=\"chosenPlan && chosenPlan.extension !== 'svg' && svgEditor\" [src]=\"chosenPlan.filepath\"\r\n (load)=\"onLoadImg(imgPng)\" style=\"display: none;\">\r\n\r\n<canvas id=\"canvas4pdf\" style=\"display: none;\"></canvas>\r\n\r\n<ng-template #dialog let-modal>\r\n\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'save plan edited' | translate}}\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"newSvg();modal.close('Close click')\">{{'Yes' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"updateSvg();modal.close('Close click')\">{{'No' |\r\n translate}}</button>\r\n </div>\r\n\r\n</ng-template>\r\n\r\n<ng-template #dialogZone let-modal>\r\n\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n {{'confirm.new-zone-from-plan' | translate}}\r\n </div>\r\n <div class=\"modal-footer\">\r\n <button type=\"button\" class=\"btn btn-outline-dark\"\r\n (click)=\"isNewZone = true;modal.close('Close click')\">{{'Validate' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"modal.close('Close click')\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n\r\n</ng-template>\r\n\r\n<ng-template #preparing let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\">{{'Processing' | translate}}</h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border\" role=\"status\">\r\n <span class=\"visually-hidden\">Loading...</span>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n</ng-template>", styles: ["app-add-zone{position:absolute;top:0;left:0;background-color:#fff;width:100%;height:100%;padding:30px}\n"] }]
4301
- }], ctorParameters: () => [{ type: i2.PlanService }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i4$1.NgbModal }, { type: i2.ZoneService }, { type: i2.VisitService }, { type: i2.SpaceService }, { type: i3.TranslateService }, { type: i0.NgZone }], propDecorators: { dialog: [{
4665
+ args: [{ selector: 'lib-edit-plan', template: "<div class=\"row mt-3\">\n <div class=\"col\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems'></lib-tab-navigation>\n </div>\n </div>\n</div>\n<lib-add-zone *ngIf=\"isNewZone\" [images360]=\"images360\" [spaceID]=\"spaceID\" [navigationIDs]=\"navigations\"\n [zoneEdit]=\"editedZone\" [zones]=\"zones\" (updatedZone)=\"onNewZone($event)\" [chosenPlan]=\"editedPlan\"\n [newZoneDataFromEditor]=\"newZoneData\"></lib-add-zone>\n<iframe *ngIf=\"editorUrl\" #svgEditor [src]=\"editorUrl | safeUrl\" frameborder=\"0\"\n style=\"height:100%;width:100%;min-height:550px;max-height:750px\" (load)=\"onLoad(svgEditor)\"></iframe>\n<!-- chosenPlan && -->\n<!-- ./../../../../../../assets/svgeditor/index.html -->\n\n<img #imgPng *ngIf=\"chosenPlan && chosenPlan.extension !== 'svg' && svgEditor\" [src]=\"chosenPlan.filepath\"\n (load)=\"onLoadImg(imgPng)\" style=\"display: none;\">\n\n<canvas id=\"canvas4pdf\" style=\"display: none;\"></canvas>\n\n<ng-template #dialog let-modal>\n\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'save plan edited' | translate}}\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"newSvg();modal.close('Close click')\">{{'Yes' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"updateSvg();modal.close('Close click')\">{{'No' |\n translate}}</button>\n </div>\n\n</ng-template>\n\n<ng-template #dialogZone let-modal>\n\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Submit' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n {{'confirm.new-zone-from-plan' | translate}}\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-outline-dark\"\n (click)=\"isNewZone = true;modal.close('Close click')\">{{'Validate' |\n translate}}</button>\n <button type=\"button\" class=\"btn btn-outline-dark\" (click)=\"modal.close('Close click')\">{{'Cancel' |\n translate}}</button>\n </div>\n\n</ng-template>\n\n<ng-template #preparing let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\">{{'Processing' | translate}}</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"d-flex justify-content-center\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n </div>\n\n</ng-template>", styles: ["app-add-zone{position:absolute;top:0;left:0;background-color:#fff;width:100%;height:100%;padding:30px}\n"] }]
4666
+ }], ctorParameters: () => [{ type: i2.PlanService }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type: i3$1.NgbModal }, { type: i2.ZoneService }, { type: i2.VisitService }, { type: i2.SpaceService }, { type: i3.TranslateService }, { type: i0.NgZone }], propDecorators: { dialog: [{
4302
4667
  type: ViewChild,
4303
4668
  args: ["dialog"]
4304
4669
  }], dialogZone: [{
@@ -4323,6 +4688,7 @@ const routes = [
4323
4688
  { path: "", component: DetailLocationComponent },
4324
4689
  { path: "zones", component: ZonesComponent },
4325
4690
  { path: "visits", component: VisitsComponent },
4691
+ { path: "models3d", component: Models3dComponent },
4326
4692
  { path: "plans", component: PlansComponent },
4327
4693
  {
4328
4694
  path: "plan-calibration",
@@ -4357,6 +4723,7 @@ class NgxSmarterplanLocationsModule {
4357
4723
  CalibrationComponent,
4358
4724
  PlansComponent,
4359
4725
  VisitsComponent,
4726
+ Models3dComponent,
4360
4727
  ZonesComponent,
4361
4728
  ImagesComponent,
4362
4729
  EditPlanComponent,
@@ -4405,6 +4772,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
4405
4772
  CalibrationComponent,
4406
4773
  PlansComponent,
4407
4774
  VisitsComponent,
4775
+ Models3dComponent,
4408
4776
  ZonesComponent,
4409
4777
  ImagesComponent,
4410
4778
  EditPlanComponent,