@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.
- package/README.md +24 -24
- package/esm2022/lib/components/carousel/carousel.component.mjs +3 -3
- package/esm2022/lib/components/chevron/chevron.component.mjs +3 -3
- package/esm2022/lib/components/detail-location/detail-location.component.mjs +40 -4
- package/esm2022/lib/components/form-location/form-location.component.mjs +3 -3
- package/esm2022/lib/components/images/images.component.mjs +3 -3
- package/esm2022/lib/components/landmark-picker/landmark-picker.component.mjs +3 -3
- package/esm2022/lib/components/locations/locations.component.mjs +19 -4
- package/esm2022/lib/components/locations/map/map-popup/map-popup.component.mjs +3 -3
- package/esm2022/lib/components/locations/map/map.component.mjs +3 -3
- package/esm2022/lib/components/models3d/models3d.component.mjs +295 -0
- package/esm2022/lib/components/plan-legend/plan-legend.component.mjs +3 -3
- package/esm2022/lib/components/plans/calibration/calibration.component.mjs +3 -3
- package/esm2022/lib/components/plans/edit-plan/edit-plan.component.mjs +3 -3
- package/esm2022/lib/components/plans/plans.component.mjs +3 -3
- package/esm2022/lib/components/tab-navigation/tab-navigation.component.mjs +3 -3
- package/esm2022/lib/components/visits/visits.component.mjs +45 -12
- package/esm2022/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +3 -3
- package/esm2022/lib/components/zones/add-zone/add-zone.component.mjs +3 -3
- package/esm2022/lib/components/zones/add-zone/selection/selection.component.mjs +3 -3
- package/esm2022/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +3 -3
- package/esm2022/lib/components/zones/zones.component.mjs +3 -3
- package/esm2022/lib/helper.service.mjs +1 -1
- package/esm2022/lib/ngx-smarterplan-location-routing.module.mjs +3 -1
- package/esm2022/lib/ngx-smarterplan-locations.module.mjs +4 -1
- package/esm2022/lib/ngx-smarterplan-locations.service.mjs +1 -1
- package/esm2022/lib/pipes/count-audio-sweeps.pipe.mjs +1 -1
- package/esm2022/lib/radio-button/radio-button.component.mjs +3 -3
- package/esm2022/public-api.mjs +1 -1
- package/fesm2022/smarterplan-ngx-smarterplan-locations.mjs +424 -56
- package/fesm2022/smarterplan-ngx-smarterplan-locations.mjs.map +1 -1
- package/lib/components/detail-location/detail-location.component.d.ts +13 -0
- package/lib/components/locations/locations.component.d.ts +10 -0
- package/lib/components/locations/map/map.component.d.ts +2 -2
- package/lib/components/models3d/models3d.component.d.ts +84 -0
- package/lib/components/visits/visits.component.d.ts +8 -3
- package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +0 -1
- package/lib/ngx-smarterplan-locations.module.d.ts +27 -26
- 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,
|
|
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
|
|
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$
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\
|
|
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\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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;\">\
|
|
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;\">\
|
|
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
|
|
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
|
-
|
|
2170
|
-
|
|
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:
|
|
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:
|
|
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)\">\
|
|
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)\">\
|
|
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>\
|
|
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>\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\">\
|
|
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\" >\
|
|
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\" >\
|
|
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:
|
|
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\">\
|
|
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\">×</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\">×</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\">×</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\">\
|
|
4301
|
-
}], ctorParameters: () => [{ type: i2.PlanService }, { type: i1.ActivatedRoute }, { type: i1.Router }, { type:
|
|
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\">×</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\">×</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\">×</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,
|