@smarterplan/ngx-smarterplan-admin 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +24 -0
  2. package/esm2020/lib/admin/admin.component.mjs +33 -0
  3. package/esm2020/lib/chevron/chevron.component.mjs +19 -0
  4. package/esm2020/lib/guest-link/guest-link.component.mjs +62 -0
  5. package/esm2020/lib/guide.guard.mjs +25 -0
  6. package/esm2020/lib/name-from-id.pipe.mjs +29 -0
  7. package/esm2020/lib/ngx-smarterplan-admin-routing.module.mjs +47 -0
  8. package/esm2020/lib/ngx-smarterplan-admin.module.mjs +90 -0
  9. package/esm2020/lib/ngx-smarterplan-admin.service.mjs +14 -0
  10. package/esm2020/lib/organisation/organisation.component.mjs +166 -0
  11. package/esm2020/lib/sp-admin.guard.mjs +31 -0
  12. package/esm2020/lib/user/detail-organisation/detail-organisation.component.mjs +160 -0
  13. package/esm2020/lib/user/form-mission/form-mission.component.mjs +205 -0
  14. package/esm2020/lib/user/form-organisation/form-organisation.component.mjs +125 -0
  15. package/esm2020/lib/user/user-mission-form/user-mission-form.component.mjs +106 -0
  16. package/esm2020/lib/user/user.component.mjs +325 -0
  17. package/esm2020/lib/visitor/create-batch/create-batch.component.mjs +108 -0
  18. package/esm2020/lib/visitor/template/template.component.mjs +219 -0
  19. package/esm2020/lib/visitor/visitor.component.mjs +284 -0
  20. package/esm2020/public-api.mjs +6 -0
  21. package/esm2020/smarterplan-ngx-smarterplan-admin.mjs +5 -0
  22. package/fesm2015/smarterplan-ngx-smarterplan-admin.mjs +2026 -0
  23. package/fesm2015/smarterplan-ngx-smarterplan-admin.mjs.map +1 -0
  24. package/fesm2020/smarterplan-ngx-smarterplan-admin.mjs +1921 -0
  25. package/fesm2020/smarterplan-ngx-smarterplan-admin.mjs.map +1 -0
  26. package/lib/admin/admin.component.d.ts +13 -0
  27. package/lib/chevron/chevron.component.d.ts +9 -0
  28. package/lib/guest-link/guest-link.component.d.ts +20 -0
  29. package/lib/guide.guard.d.ts +11 -0
  30. package/lib/name-from-id.pipe.d.ts +11 -0
  31. package/lib/ngx-smarterplan-admin-routing.module.d.ts +7 -0
  32. package/lib/ngx-smarterplan-admin.module.d.ts +26 -0
  33. package/lib/ngx-smarterplan-admin.service.d.ts +6 -0
  34. package/lib/organisation/organisation.component.d.ts +53 -0
  35. package/lib/sp-admin.guard.d.ts +12 -0
  36. package/lib/user/detail-organisation/detail-organisation.component.d.ts +39 -0
  37. package/lib/user/form-mission/form-mission.component.d.ts +54 -0
  38. package/lib/user/form-organisation/form-organisation.component.d.ts +32 -0
  39. package/lib/user/user-mission-form/user-mission-form.component.d.ts +28 -0
  40. package/lib/user/user.component.d.ts +100 -0
  41. package/lib/visitor/create-batch/create-batch.component.d.ts +23 -0
  42. package/lib/visitor/template/template.component.d.ts +52 -0
  43. package/lib/visitor/visitor.component.d.ts +65 -0
  44. package/package.json +39 -0
  45. package/public-api.d.ts +2 -0
  46. package/smarterplan-ngx-smarterplan-admin.d.ts +5 -0
@@ -0,0 +1,1921 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Injectable, Component, Input, EventEmitter, Output, ViewChild, NgModule, Pipe } from '@angular/core';
3
+ import * as i2 from '@angular/forms';
4
+ import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
5
+ import * as i1 from 'ngx-smarterplan-core';
6
+ import { RoleStatus, ProfileEntity, removeNullKeysFromObject, stringLocaleToEnum, enumToArray, Locale, LevelStatus, EmailStatus, filterUniqueArrayByID, DomainType, sortAlphabeticallyOnName, validEmail, NgxSmarterplanCoreModule } from 'ngx-smarterplan-core';
7
+ import * as i3 from '@ngx-translate/core';
8
+ import { TranslateModule } from '@ngx-translate/core';
9
+ import * as i4 from '@angular/common';
10
+ import { CommonModule } from '@angular/common';
11
+ import { Subject, takeUntil } from 'rxjs';
12
+ import * as CryptoJS from 'crypto-js';
13
+ import * as i4$1 from '@ng-bootstrap/ng-bootstrap';
14
+ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
15
+ import * as i4$2 from 'ngx-clipboard';
16
+ import { ClipboardModule } from 'ngx-clipboard';
17
+ import { DateTime } from 'luxon';
18
+ import { v4 } from 'uuid';
19
+ import * as i2$1 from '@angular/router';
20
+ import { RouterModule } from '@angular/router';
21
+ import * as Papa from 'papaparse';
22
+
23
+ class NgxSmarterplanAdminService {
24
+ constructor() { }
25
+ }
26
+ NgxSmarterplanAdminService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NgxSmarterplanAdminService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
27
+ NgxSmarterplanAdminService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NgxSmarterplanAdminService, providedIn: 'root' });
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NgxSmarterplanAdminService, decorators: [{
29
+ type: Injectable,
30
+ args: [{
31
+ providedIn: 'root'
32
+ }]
33
+ }], ctorParameters: function () { return []; } });
34
+
35
+ class ChevronComponent {
36
+ constructor() {
37
+ this.conditionShowing = false;
38
+ }
39
+ ngOnInit() {
40
+ }
41
+ }
42
+ ChevronComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ChevronComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
43
+ ChevronComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: ChevronComponent, selector: "lib-chevron", inputs: { conditionShowing: "conditionShowing" }, ngImport: i0, template: "<div style=\"height: 30px; width: 30px;\">\r\n <span class=\"icon-container\" >\r\n <div [class]=\"conditionShowing ? 'icon-img-up' : 'icon-img-down'\"></div>\r\n </span>\r\n</div>\r\n", styles: [".icon-container{height:30px;width:30px}.icon-img-down{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-right.svg?width=28) no-repeat center center/contain}.icon-img-up{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-down.svg?width=28) no-repeat center center/contain}\n"] });
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ChevronComponent, decorators: [{
45
+ type: Component,
46
+ args: [{ selector: 'lib-chevron', template: "<div style=\"height: 30px; width: 30px;\">\r\n <span class=\"icon-container\" >\r\n <div [class]=\"conditionShowing ? 'icon-img-up' : 'icon-img-down'\"></div>\r\n </span>\r\n</div>\r\n", styles: [".icon-container{height:30px;width:30px}.icon-img-down{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-right.svg?width=28) no-repeat center center/contain}.icon-img-up{width:30px;height:100%;background:url(https://api.iconify.design/mdi-light/chevron-down.svg?width=28) no-repeat center center/contain}\n"] }]
47
+ }], ctorParameters: function () { return []; }, propDecorators: { conditionShowing: [{
48
+ type: Input
49
+ }] } });
50
+
51
+ class OrganisationComponent {
52
+ constructor(orgService, fb, userService, missionService, translate, propertyService) {
53
+ this.orgService = orgService;
54
+ this.fb = fb;
55
+ this.userService = userService;
56
+ this.missionService = missionService;
57
+ this.translate = translate;
58
+ this.propertyService = propertyService;
59
+ this.admins = [];
60
+ this.clients = [];
61
+ this.details = -1;
62
+ this.query = "";
63
+ this.error = null;
64
+ this.create = false;
65
+ this.working = false;
66
+ this.isAddingAdmin = false;
67
+ this.loading = false;
68
+ this.editing = false;
69
+ // fullAccess true gives access to all orgs
70
+ // this is reserved to Smarterplan ADMINs
71
+ this.fullAccess = false;
72
+ }
73
+ async ngOnInit() {
74
+ this.resetList();
75
+ }
76
+ /**
77
+ * resetList fetches a fresh organisation list from server
78
+ */
79
+ async resetList() {
80
+ this.loading = true;
81
+ await this.missionService
82
+ .getMissionsByOrderedOrganisation("6e28201f-4679-4c29-9d2d-8a325f57cee9")
83
+ .then(async (missions) => {
84
+ if (missions) {
85
+ const client = {};
86
+ await Promise.all(missions.map(async (m) => {
87
+ if (!client.hasOwnProperty(m.organisationID)) {
88
+ client[m.organisationID] = {
89
+ name: m.organisation.name,
90
+ organisation: m.organisation,
91
+ adminMissions: [],
92
+ properties: [],
93
+ };
94
+ }
95
+ if (m.role === RoleStatus.ADMIN && !m.deletedAt) {
96
+ const alreadyAdmin = client[m.organisationID].adminMissions.filter((mis) => mis.user.id === m.userID);
97
+ if (alreadyAdmin.length === 0) {
98
+ client[m.organisationID].adminMissions.push({
99
+ user: new ProfileEntity(m.user),
100
+ mission: m,
101
+ });
102
+ }
103
+ }
104
+ // get properties
105
+ const properties = await this.propertyService.getPropertiesForOrganisation(m.organisationID);
106
+ client[m.organisationID].properties = properties
107
+ .filter((property) => !property.deletedAt && property.space)
108
+ .map((property) => property.space.name);
109
+ }));
110
+ this.clients = Object.values(client);
111
+ }
112
+ this.loading = false;
113
+ });
114
+ }
115
+ /**
116
+ * onToggleDetail folds/unfolds details for a given organisation
117
+ * @param i index of the organisation to be toggled
118
+ */
119
+ onToggleDetail(index) {
120
+ this.details = index === this.details ? -1 : index;
121
+ }
122
+ onAdd() {
123
+ this.create = true;
124
+ this.form = this.fb.group({
125
+ name: [null, [Validators.required]],
126
+ address: [""],
127
+ city: [""],
128
+ postal: [null],
129
+ siret: [null],
130
+ });
131
+ }
132
+ onEdit(org) {
133
+ this.create = false;
134
+ this.editing = true;
135
+ this.form = this.fb.group({
136
+ id: [org.id],
137
+ name: [org.name, [Validators.required]],
138
+ address: [org.address],
139
+ city: [org.city],
140
+ postal: [org.postal],
141
+ siret: [org.siret],
142
+ });
143
+ }
144
+ onCancel() {
145
+ // this.form = null;
146
+ this.form.reset();
147
+ this.create = false;
148
+ this.editing = false;
149
+ }
150
+ get name() {
151
+ return this.form.get("name");
152
+ }
153
+ get email() {
154
+ return this.form.get("user").get("email");
155
+ }
156
+ /**
157
+ * Handle creation or update of organisation
158
+ * @see 174
159
+ */
160
+ async onSubmitOrg() {
161
+ this.working = true;
162
+ const formValue = this.form.value;
163
+ removeNullKeysFromObject(formValue);
164
+ try {
165
+ if (this.create) {
166
+ const organisation = await this.orgService.createOrganisation(formValue);
167
+ }
168
+ else {
169
+ await this.orgService.updateOrganisation(formValue);
170
+ }
171
+ }
172
+ catch (error) {
173
+ this.error = true;
174
+ console.error(error);
175
+ }
176
+ await this.resetList();
177
+ this.working = false;
178
+ this.create = false;
179
+ this.editing = false;
180
+ this.form.reset();
181
+ }
182
+ onArchive(_) {
183
+ console.log("Unimplemented");
184
+ }
185
+ onDismiss() {
186
+ this.error = null;
187
+ }
188
+ async onDeleteOrg(org) {
189
+ const message = this.translate.instant("confirm.deleteOrganisation");
190
+ if (window.confirm(message) &&
191
+ org.id !== "6e28201f-4679-4c29-9d2d-8a325f57cee9") {
192
+ const propertiesToDelete = await this.propertyService.getPropertiesForOrganisation(org.id);
193
+ await this.orgService.deleteOrganisation(org.id);
194
+ (await this.missionService.getMissionsByOrganisation(org.id)).map((m) => this.missionService.softDeleteMission(m.id));
195
+ await Promise.all(propertiesToDelete.map(async (property) => {
196
+ await this.propertyService.deleteProperty(property.id);
197
+ }));
198
+ }
199
+ }
200
+ }
201
+ OrganisationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: OrganisationComponent, deps: [{ token: i1.OrganisationService }, { token: i2.FormBuilder }, { token: i1.BaseUserService }, { token: i1.MissionService }, { token: i3.TranslateService }, { token: i1.PropertyService }], target: i0.ɵɵFactoryTarget.Component });
202
+ OrganisationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: OrganisationComponent, selector: "lib-organisation", ngImport: i0, template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\r\n <h3>{{'SmarterPlan Client Organisations' | translate}}</h3>\r\n <div class=\"row\">\r\n <div class=\"col-md-8 col-lg-6\">\r\n\r\n <div *ngIf=\"error\" class=\"alert alert-danger alert-dismissible fade show\" role=\"alert\">\r\n <strong>{{'Error' | translate}}!</strong> We haven't been able to fulfil your request.\r\n <button type=\"button\" class=\"close\" data-dismiss=\"alert\" (click)=\"onDismiss()\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div *ngIf=\"!create && !editing\">\r\n <div class=\"d-flex justify-content-between align-items-center p-1\">\r\n <input class=\"form-control search-button\" [(ngModel)]=\"query\" i18n-placeholder placeholder=\"Search\"\r\n type=\"text\">&nbsp;\r\n </div>\r\n <!-- <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAdd()\">{{'Add new client organisation' |\r\n translate}}</button> -->\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let a of clients; index as index\"\r\n (click)=\"onToggleDetail(index)\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n {{a.name}}\r\n <lib-chevron [conditionShowing]=\"index==details\"></lib-chevron>\r\n <!-- <ic-icon [icon]=\"index==details ? chevronDown : chevronRight\"></ic-icon> -->\r\n </div>\r\n\r\n <div *ngIf=\"index==details\">\r\n <ul class=\"list-group list-group-flush\">\r\n <!-- <li class=\"list-group-item bg-transparent\">{{'Activit\u00E9' | translate}}</li> -->\r\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{ a.organisation.address }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{ 'Postal Code' | translate}}: {{ a.organisation.postal }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'City' | translate}}: {{ a.organisation.city }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'SIRET' | translate}}: {{ a.organisation.siret ?\r\n a.organisation.siret : 'Not provided' | translate }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Created' | translate}}: {{ a.organisation.createdAt }}\r\n </li>\r\n <ng-container *ngIf=\"a.adminMissions.length > 0\">\r\n <li *ngIf=\"a.adminMissions.length <= 1\" class=\"list-group-item bg-transparent\">\r\n {{'Administrator User' | translate}} :</li>\r\n <li *ngIf=\"a.adminMissions.length > 1\" class=\"list-group-item bg-transparent\">\r\n {{'Administrator User(s)' | translate}} :</li>\r\n <li class=\"list-group-item list-group-item-action\"\r\n *ngFor=\"let admin of a.adminMissions; index as index\" (click)=\"onToggleDetail(index)\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"ml-4\"> {{admin.user.displayName}} ({{admin.user.email}})\r\n <!-- <button type=\"button\" class=\"btn btn-primary rounded-pill\" style=\"float: right;\"\r\n (click)=\"onRemoveAdmin(admin)\">\r\n {{'Remove'|translate}}</button> \r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Phone'}}: {{admin.user.phone}}</li> -->\r\n </ul>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"a.adminMissions.length == 0\">\r\n <li class=\"list-group-item bg-warning\"><span class=\"badge badge-warning\">\r\n {{'Warning' | translate}}</span> {{'No Administrator User'| translate}} </li>\r\n </ng-container>\r\n <ng-container *ngIf=\"a.properties.length > 0\">\r\n <li class=\"list-group-item bg-transparent\">{{'Locations' | translate}}: </li>\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let property of a.properties\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"ml-4\">{{property}}</li>\r\n </ul>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n <div class=\"action-button-container\">\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill action-button\"\r\n (click)=\"onEdit(a.organisation)\">\r\n {{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill action-button\"\r\n (click)=\"onArchive(a.organisation)\" disabled>\r\n {{'Archive' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill action-button\"\r\n (click)=\"onDeleteOrg(a.organisation)\">\r\n {{'Delete' | translate}}</button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div *ngIf=\"form && (create || editing)\">\r\n <form (ngSubmit)=\"onSubmitOrg()\" [formGroup]=\"form\">\r\n <div class=\"form-group 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\" [class.is-invalid]=\"name.invalid && name.touched\" required\r\n 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\r\n <div class=\"form-group 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=\"address\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'City' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"city\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Postal code' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"postal\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'SIRET' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"siret\">\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n [disabled]=\"working || form.invalid\">{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <!--<spOrganisationForm [model]=\" editingOrganisation\" (submit)=\"onSave($event)\" (cancel)=\"onCancel()\">\r\n </spOrganisationForm>-->\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- <div>{{'Administrator User' | translate}}</div>\r\n <div formGroupName=\"user\" *ngIf=\"create || isAddingAdmin\">\r\n <div *ngIf=\"form\" class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Email' | translate}} *</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" [class.is-invalid]=\"email.invalid && email.touched\" required\r\n formControlName=\"email\">\r\n <div class=\"invalid-feedback\">\r\n {{'An email is required' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'First name' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"firstName\">\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Last name' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"lastName\">\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Phone' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"phone\">\r\n </div>\r\n </div>\r\n </div> -->", styles: [".form-group{margin:1.5rem 0}.search-button{width:-moz-fit-content;width:fit-content}li.ml-4{margin-left:3rem}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"], components: [{ type: i1.LoaderComponent, selector: "lib-loader" }, { type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], pipes: { "translate": i3.TranslatePipe } });
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: OrganisationComponent, decorators: [{
204
+ type: Component,
205
+ args: [{ selector: 'lib-organisation', template: "<div class=\"container-fluid\" class=\"dashboard-tab\">\r\n <h3>{{'SmarterPlan Client Organisations' | translate}}</h3>\r\n <div class=\"row\">\r\n <div class=\"col-md-8 col-lg-6\">\r\n\r\n <div *ngIf=\"error\" class=\"alert alert-danger alert-dismissible fade show\" role=\"alert\">\r\n <strong>{{'Error' | translate}}!</strong> We haven't been able to fulfil your request.\r\n <button type=\"button\" class=\"close\" data-dismiss=\"alert\" (click)=\"onDismiss()\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div *ngIf=\"!create && !editing\">\r\n <div class=\"d-flex justify-content-between align-items-center p-1\">\r\n <input class=\"form-control search-button\" [(ngModel)]=\"query\" i18n-placeholder placeholder=\"Search\"\r\n type=\"text\">&nbsp;\r\n </div>\r\n <!-- <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onAdd()\">{{'Add new client organisation' |\r\n translate}}</button> -->\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let a of clients; index as index\"\r\n (click)=\"onToggleDetail(index)\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n {{a.name}}\r\n <lib-chevron [conditionShowing]=\"index==details\"></lib-chevron>\r\n <!-- <ic-icon [icon]=\"index==details ? chevronDown : chevronRight\"></ic-icon> -->\r\n </div>\r\n\r\n <div *ngIf=\"index==details\">\r\n <ul class=\"list-group list-group-flush\">\r\n <!-- <li class=\"list-group-item bg-transparent\">{{'Activit\u00E9' | translate}}</li> -->\r\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{ a.organisation.address }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{ 'Postal Code' | translate}}: {{ a.organisation.postal }}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'City' | translate}}: {{ a.organisation.city }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'SIRET' | translate}}: {{ a.organisation.siret ?\r\n a.organisation.siret : 'Not provided' | translate }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Created' | translate}}: {{ a.organisation.createdAt }}\r\n </li>\r\n <ng-container *ngIf=\"a.adminMissions.length > 0\">\r\n <li *ngIf=\"a.adminMissions.length <= 1\" class=\"list-group-item bg-transparent\">\r\n {{'Administrator User' | translate}} :</li>\r\n <li *ngIf=\"a.adminMissions.length > 1\" class=\"list-group-item bg-transparent\">\r\n {{'Administrator User(s)' | translate}} :</li>\r\n <li class=\"list-group-item list-group-item-action\"\r\n *ngFor=\"let admin of a.adminMissions; index as index\" (click)=\"onToggleDetail(index)\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"ml-4\"> {{admin.user.displayName}} ({{admin.user.email}})\r\n <!-- <button type=\"button\" class=\"btn btn-primary rounded-pill\" style=\"float: right;\"\r\n (click)=\"onRemoveAdmin(admin)\">\r\n {{'Remove'|translate}}</button> \r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Phone'}}: {{admin.user.phone}}</li> -->\r\n </ul>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"a.adminMissions.length == 0\">\r\n <li class=\"list-group-item bg-warning\"><span class=\"badge badge-warning\">\r\n {{'Warning' | translate}}</span> {{'No Administrator User'| translate}} </li>\r\n </ng-container>\r\n <ng-container *ngIf=\"a.properties.length > 0\">\r\n <li class=\"list-group-item bg-transparent\">{{'Locations' | translate}}: </li>\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let property of a.properties\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"ml-4\">{{property}}</li>\r\n </ul>\r\n </li>\r\n </ng-container>\r\n </ul>\r\n <div class=\"action-button-container\">\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill action-button\"\r\n (click)=\"onEdit(a.organisation)\">\r\n {{'Edit' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill action-button\"\r\n (click)=\"onArchive(a.organisation)\" disabled>\r\n {{'Archive' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill action-button\"\r\n (click)=\"onDeleteOrg(a.organisation)\">\r\n {{'Delete' | translate}}</button>\r\n </div>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div *ngIf=\"form && (create || editing)\">\r\n <form (ngSubmit)=\"onSubmitOrg()\" [formGroup]=\"form\">\r\n <div class=\"form-group 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\" [class.is-invalid]=\"name.invalid && name.touched\" required\r\n 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\r\n <div class=\"form-group 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=\"address\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'City' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"city\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Postal code' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"postal\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'SIRET' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"siret\">\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n [disabled]=\"working || form.invalid\">{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <!--<spOrganisationForm [model]=\" editingOrganisation\" (submit)=\"onSave($event)\" (cancel)=\"onCancel()\">\r\n </spOrganisationForm>-->\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- <div>{{'Administrator User' | translate}}</div>\r\n <div formGroupName=\"user\" *ngIf=\"create || isAddingAdmin\">\r\n <div *ngIf=\"form\" class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Email' | translate}} *</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" [class.is-invalid]=\"email.invalid && email.touched\" required\r\n formControlName=\"email\">\r\n <div class=\"invalid-feedback\">\r\n {{'An email is required' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'First name' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"firstName\">\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Last name' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"lastName\">\r\n </div>\r\n </div>\r\n \r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Phone' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"phone\">\r\n </div>\r\n </div>\r\n </div> -->", styles: [".form-group{margin:1.5rem 0}.search-button{width:-moz-fit-content;width:fit-content}li.ml-4{margin-left:3rem}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"] }]
206
+ }], ctorParameters: function () { return [{ type: i1.OrganisationService }, { type: i2.FormBuilder }, { type: i1.BaseUserService }, { type: i1.MissionService }, { type: i3.TranslateService }, { type: i1.PropertyService }]; } });
207
+
208
+ class GuestLinkComponent {
209
+ constructor(spaceService, activeModal) {
210
+ this.spaceService = spaceService;
211
+ this.activeModal = activeModal;
212
+ }
213
+ ngOnInit() {
214
+ this.setModel3D();
215
+ }
216
+ async setModel3D() {
217
+ this.model3D = await this.spaceService.getModel3DForSpace(this.spaceID);
218
+ }
219
+ async onGenerate() {
220
+ const inputElement = document.querySelector("#password");
221
+ const password = inputElement.value;
222
+ if (password.length < 8) {
223
+ this.errorMessage = "register.password.weak";
224
+ return;
225
+ }
226
+ this.errorMessage = null;
227
+ const encrypted = CryptoJS.AES.encrypt(JSON.stringify({
228
+ user: this.username,
229
+ password,
230
+ }), "EncryptedUser").toString();
231
+ const redirect = `redirect?spaceID=${this.spaceID}&model3D=${this.model3D}&user=${encrypted}`;
232
+ const { origin } = document.location;
233
+ this.link = `${origin}/${redirect}`;
234
+ setTimeout(() => {
235
+ const hyperlink = document.querySelector("#linkHref");
236
+ if (hyperlink) {
237
+ hyperlink.setAttribute("href", this.link);
238
+ }
239
+ }, 200); // wait until the element is rendered because of *ngIf
240
+ await this.spaceService.updateSpace({
241
+ id: this.spaceID,
242
+ guestLink: redirect,
243
+ });
244
+ }
245
+ onCancel() {
246
+ if (this.activeModal) {
247
+ this.activeModal.close();
248
+ }
249
+ }
250
+ }
251
+ GuestLinkComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: GuestLinkComponent, deps: [{ token: i1.SpaceService }, { token: i4$1.NgbActiveModal }], target: i0.ɵɵFactoryTarget.Component });
252
+ GuestLinkComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: GuestLinkComponent, selector: "lib-guest-link", inputs: { spaceID: "spaceID", username: "username" }, ngImport: i0, template: "<div class=\"main\">\r\n <p>{{'Current password for account:' | translate}} {{username}}</p>\r\n <input type=\"password\" class=\"form-control\" id=\"password\">\r\n <p *ngIf=\"errorMessage\">{{errorMessage}}</p>\r\n <div class=\"row ml-0 mt-3\" *ngIf=\"link\">\r\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\r\n <div ngxClipboard [cbContent]=\"link\" [style.cursor]=\"'pointer'\" style=\"margin-left: 5px; max-width: 20px;\"\r\n ngbTooltip=\"Copied!\" 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\r\n </div>\r\n <div class=\"row ml-0 mt-3\">\r\n <button class=\"btn btn-primary rounded-pill mr-2\" (click)=\"onGenerate()\">{{'Generate link' | translate\r\n }}</button>\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' | translate }}</button>\r\n </div>\r\n\r\n</div>\r\n", styles: [".main{margin:1.5rem}\n"], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$2.ClipboardDirective, selector: "[ngxClipboard]", inputs: ["ngxClipboard", "container", "cbContent", "cbSuccessMsg"], outputs: ["cbOnSuccess", "cbOnError"] }, { type: i4$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }], pipes: { "translate": i3.TranslatePipe } });
253
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: GuestLinkComponent, decorators: [{
254
+ type: Component,
255
+ args: [{ selector: 'lib-guest-link', template: "<div class=\"main\">\r\n <p>{{'Current password for account:' | translate}} {{username}}</p>\r\n <input type=\"password\" class=\"form-control\" id=\"password\">\r\n <p *ngIf=\"errorMessage\">{{errorMessage}}</p>\r\n <div class=\"row ml-0 mt-3\" *ngIf=\"link\">\r\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\r\n <div ngxClipboard [cbContent]=\"link\" [style.cursor]=\"'pointer'\" style=\"margin-left: 5px; max-width: 20px;\"\r\n ngbTooltip=\"Copied!\" 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\r\n </div>\r\n <div class=\"row ml-0 mt-3\">\r\n <button class=\"btn btn-primary rounded-pill mr-2\" (click)=\"onGenerate()\">{{'Generate link' | translate\r\n }}</button>\r\n <button class=\"btn btn-primary rounded-pill\" (click)=\"onCancel()\">{{'Cancel' | translate }}</button>\r\n </div>\r\n\r\n</div>\r\n", styles: [".main{margin:1.5rem}\n"] }]
256
+ }], ctorParameters: function () { return [{ type: i1.SpaceService }, { type: i4$1.NgbActiveModal }]; }, propDecorators: { spaceID: [{
257
+ type: Input
258
+ }], username: [{
259
+ type: Input
260
+ }] } });
261
+
262
+ class FormMissionComponent {
263
+ constructor(fb, spaceService, userService, domainService, organisationService, zoneService, hashtagService, localeService) {
264
+ this.fb = fb;
265
+ this.spaceService = spaceService;
266
+ this.userService = userService;
267
+ this.domainService = domainService;
268
+ this.organisationService = organisationService;
269
+ this.zoneService = zoneService;
270
+ this.hashtagService = hashtagService;
271
+ this.localeService = localeService;
272
+ this.addedMissionInput = new EventEmitter();
273
+ this.availableHashtags = [];
274
+ this.isGuide = false;
275
+ this.missionTimeStart = 12 * 60 * 60000; // midday in milliseconds
276
+ this.missionTimeEnd = 12 * 60 * 60000;
277
+ this.addedHashtags = [];
278
+ }
279
+ async ngOnInit() {
280
+ this.updateUserInfo();
281
+ await this.setDomains();
282
+ if (this.isSP) {
283
+ this.allOrgs = await this.organisationService.listOrganisations();
284
+ }
285
+ this.currentLocale = stringLocaleToEnum(this.localeService.getLocale()); // to match enum Locale
286
+ this.locales = enumToArray(Locale);
287
+ if (this.missionToEdit) {
288
+ this.initFormForEdit();
289
+ }
290
+ else {
291
+ this.initEmptyForm();
292
+ }
293
+ }
294
+ updateUserInfo() {
295
+ this.availableRoles =
296
+ this.userService.getAvailableRolesForCurrentUser();
297
+ this.availableLevels =
298
+ this.userService.getAvalableLevelsForCurrentUser();
299
+ this.isGuide = this.userService.isGuide();
300
+ }
301
+ async setDomains() {
302
+ if (!this.isGuide) {
303
+ const domains = await this.domainService.getDomainsForMissionsForOrg(this.currentUserOrganisation.id);
304
+ this.domains = domains;
305
+ }
306
+ }
307
+ async setHashtags(spaceID) {
308
+ this.availableHashtags = await this.hashtagService.getHashtagsForSpace(spaceID);
309
+ }
310
+ get spaceID() {
311
+ return this.missionForm.get("space");
312
+ }
313
+ get role() {
314
+ return this.missionForm.get("role");
315
+ }
316
+ async initFormForEdit() {
317
+ const m = this.missionToEdit;
318
+ this.userForMissionID = m.userID;
319
+ this.availableSpaces = await this.spaceService.getAllowedSpacesForOrg(this.missionToEdit.organisationID, this.currentUserOrganisation.id);
320
+ await this.setHashtags(m.spaceID);
321
+ this.missionForm = this.fb.group({
322
+ id: m.id,
323
+ organisation: [{ value: m.organisation.name, disabled: true }],
324
+ organisationID: m.organisationID,
325
+ orderedOrganisationID: m.orderedOrganisationID,
326
+ role: [m.role],
327
+ level: [m.level],
328
+ space: [m.spaceID],
329
+ description: [m.description],
330
+ domains: [m.domains],
331
+ zone: [m.zoneID],
332
+ locale: [m.locale],
333
+ });
334
+ if (m.hashtags && m.hashtags.length > 0) {
335
+ this.addedHashtags = this.availableHashtags.filter((hashtag) => m.hashtags.includes(hashtag.id));
336
+ }
337
+ if (m.startDateTime) {
338
+ const date = DateTime.fromISO(m.startDateTime);
339
+ this.missionTimeStart = (date.hour * 60 + date.minute) * 60 * 1000;
340
+ this.startDate = date.toMillis() - this.missionTimeStart;
341
+ }
342
+ if (m.endDateTime) {
343
+ const date = DateTime.fromISO(m.endDateTime);
344
+ this.missionTimeEnd = (date.hour * 60 + date.minute) * 60 * 1000;
345
+ this.endDate = date.toMillis() - this.missionTimeEnd;
346
+ }
347
+ this.onSpaceClick();
348
+ }
349
+ async onSpaceClick() {
350
+ const zones = await this.zoneService.getZonesBySpace(this.spaceID.value);
351
+ this.defaultZone = zones.find((zone) => !zone.parentID);
352
+ const indexOfDefaultZone = zones.indexOf(this.defaultZone);
353
+ zones.splice(indexOfDefaultZone, 1);
354
+ this.zonesForSpace = zones;
355
+ await this.setHashtags(this.spaceID.value);
356
+ }
357
+ async initEmptyForm() {
358
+ this.availableSpaces = await this.spaceService.getAllowedSpacesForOrg(this.organisationForMission.id, this.currentUserOrganisation.id);
359
+ this.missionForm = this.fb.group({
360
+ role: [null, Validators.required],
361
+ level: [LevelStatus.MINIMUM],
362
+ organisation: [
363
+ { value: this.organisationForMission.name, disabled: true },
364
+ ],
365
+ organisationID: this.organisationForMission.id,
366
+ orderedOrganisationID: this.currentUserOrganisation.id,
367
+ space: [null, Validators.required],
368
+ zone: [null],
369
+ description: [""],
370
+ domains: [null],
371
+ locale: [this.currentLocale],
372
+ });
373
+ }
374
+ onHashtagClick(hashtag) {
375
+ if (!this.hashtagAdded(hashtag)) {
376
+ this.addedHashtags.push(hashtag);
377
+ }
378
+ else {
379
+ this.addedHashtags.splice(this.addedHashtags.indexOf(hashtag), 1);
380
+ }
381
+ }
382
+ hashtagAdded(hashtag) {
383
+ return (this.addedHashtags.find((_hashtag) => _hashtag.id === hashtag.id) !== undefined);
384
+ }
385
+ removeHashtag(hashtag) {
386
+ this.addedHashtags.splice(this.addedHashtags.indexOf(hashtag), 1);
387
+ }
388
+ onSubmit() {
389
+ const formValue = this.missionForm.value;
390
+ if (!this.missionForm.valid) {
391
+ // this shows errors in the form
392
+ this.missionForm.markAllAsTouched();
393
+ return;
394
+ }
395
+ let startDateString;
396
+ let endDateString;
397
+ if (this.startDate) {
398
+ const dateHourStartNumber = this.startDate + this.missionTimeStart;
399
+ const startDate = DateTime.fromMillis(dateHourStartNumber);
400
+ startDateString = startDate.toISO();
401
+ }
402
+ if (this.endDate) {
403
+ const dateHourEndNumber = this.endDate + this.missionTimeEnd;
404
+ const endDate = DateTime.fromMillis(dateHourEndNumber);
405
+ endDateString = endDate.toISO();
406
+ }
407
+ const missionInput = {
408
+ organisationID: formValue.organisationID,
409
+ orderedOrganisationID: formValue.orderedOrganisationID,
410
+ level: formValue.level,
411
+ role: formValue.role,
412
+ description: formValue.description,
413
+ startDateTime: startDateString,
414
+ endDateTime: endDateString,
415
+ domains: formValue.domains,
416
+ userID: this.userForMissionID,
417
+ emailStatus: this.missionToEdit
418
+ ? this.missionToEdit.emailStatus
419
+ : EmailStatus.CREATION_TO_DELIVER,
420
+ locale: formValue.locale,
421
+ };
422
+ missionInput.hashtags = this.addedHashtags.map((h) => h.id);
423
+ if (formValue.space) {
424
+ missionInput.spaceID = formValue.space;
425
+ }
426
+ if (formValue.zone) {
427
+ missionInput.zoneID = formValue.zone;
428
+ }
429
+ if (this.missionToEdit) {
430
+ missionInput.id = this.missionToEdit.id;
431
+ }
432
+ this.addedMissionInput.emit(missionInput);
433
+ }
434
+ onCancel() {
435
+ this.addedMissionInput.emit(null);
436
+ }
437
+ }
438
+ FormMissionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormMissionComponent, deps: [{ token: i2.FormBuilder }, { token: i1.SpaceService }, { token: i1.BaseUserService }, { token: i1.DomainService }, { token: i1.OrganisationService }, { token: i1.ZoneService }, { token: i1.HashtagService }, { token: i1.LocaleService }], target: i0.ɵɵFactoryTarget.Component });
439
+ FormMissionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FormMissionComponent, selector: "lib-form-mission", inputs: { missionToEdit: "missionToEdit", organisationForMission: "organisationForMission", isSP: "isSP", userForMissionID: "userForMissionID", currentUserOrganisation: "currentUserOrganisation" }, outputs: { addedMissionInput: "addedMissionInput" }, ngImport: i0, template: "<div class=\"form-containter\" *ngIf=\"missionForm\">\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'Mission details' | translate }}</h4>\r\n </div>\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"missionForm\">\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Organisation' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"organisation\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\" *ngIf=\"isSP\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Ordered by' | translate }}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"orderedOrganisationID\">\r\n <option *ngFor=\"let org of allOrgs\" [ngValue]=\"org.id\">\r\n {{ org.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Description' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <textarea class=\"form-control\" formControlName=\"description\" rows=\"10\"></textarea>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Role' | translate}}*</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"role\" [class.is-invalid]=\"role.invalid && role.touched\">\r\n <option *ngFor=\"let r of availableRoles\" [ngValue]=\"r\">\r\n {{ r }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n {{'Role is required' | translate}}.\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\"\r\n *ngIf=\"missionForm.get('role').value !== 'VISITOR_MUSEUM' && missionForm.get('role').value !== 'GUIDE_MUSEUM'\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Domains' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"domains\">\r\n <select class=\"form-control\" multiple formControlName=\"domains\">\r\n <option *ngFor=\"let domain of domains\" [ngValue]=\"domain.id\">\r\n {{ domain.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Access level' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"level\">\r\n <option *ngFor=\"let level of availableLevels\" [ngValue]=\"level\">\r\n {{ level }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized location' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"availableSpaces\">\r\n <select class=\"form-control\" required formControlName=\"space\" (change)=\"onSpaceClick()\" \r\n [class.is-invalid]=\"spaceID.invalid && spaceID.touched\">\r\n <option *ngFor=\"let space of availableSpaces\" [ngValue]=\"space.id\">\r\n {{ space.name }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n {{'Location is required' | translate}}.\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!availableSpaces\">\r\n {{ 'No locations available' | translate}}\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized zone' | translate }}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace; else noSpace\">\r\n <select class=\"form-control\" formControlName=\"zone\">\r\n <option [ngValue]=\"defaultZone.id\">\r\n {{ 'All zones' | translate }}\r\n </option>\r\n <option *ngFor=\"let zone of zonesForSpace\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <ng-template #noSpace>\r\n <div class=\"col-sm-8 hint-container\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Language' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" formControlName=\"locale\">\r\n <option [ngValue]=\"null\">{{'Not applicable' | translate}}</option>\r\n <option *ngFor=\"let locale of locales\" [ngValue]=\"locale\">\r\n {{ locale }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n <!-- Hashtags are available after Space is set -->\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Hashtags' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"spaceID.value\">\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length > 0\">{{'Available hashtags' | translate}} </p>\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length === 0\">\r\n {{'No hashtags created for this location' | translate}} </p>\r\n <div *ngIf=\"availableHashtags.length > 0\">\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li *ngFor=\"let hashtag of availableHashtags\"\r\n [class]=\"hashtagAdded(hashtag) ? 'keywordsItem added' : 'keywordsItem'\"\r\n (click)=\"onHashtagClick(hashtag)\" style=\"cursor: pointer;\"\r\n ngbTooltip=\"{{hashtagAdded(hashtag) ? ('Remove'|translate) : ('Add'|translate) }}\">\r\n {{hashtag.name}}\r\n </li>\r\n </div>\r\n </ul>\r\n <p class=\"keywordsRules\">{{'Added hashtags' | translate}} </p>\r\n <ul class=\"keywordsDisplay\">\r\n <div class=\"keywordsdisplayContainer\" *ngIf=\"addedHashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of addedHashtags\">{{ hashtag.name }}\r\n <a type=\"button\" class=\"closeButton\" (click)=\"removeHashtag(hashtag)\">\r\n <span class=\"crossItem\"></span>\r\n </a>\r\n </li>\r\n </div>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8 hint-container\" *ngIf=\"!spaceID.value\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"startDate\" 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()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeStart\" [ngModelOptions]=\"{standalone: true}\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"endDate\" ngbDatepicker\r\n #d2=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d2.toggle()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeEnd\" [ngModelOptions]=\"{standalone: true}\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"btn-control-div action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n >{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n </form>\r\n</div>", styles: [".form-containter{padding:0rem 1rem;margin-bottom:2rem}.checkbox-apply{margin-top:calc(.375rem + 1px)}.keywordsDisplay{min-height:40px}.hint{margin:0!important}.hint-container{display:flex;align-items:center}.crossItem{margin:0;padding:0;border:0;background:none;position:relative;width:7px;height:20px}.crossItem:before,.crossItem:after{content:\"\";position:absolute;top:6.25px;left:0;right:0;height:1.5px;background:#fff;border-radius:1.5px}.crossItem:before{transform:rotate(45deg)}.crossItem:after{transform:rotate(-45deg)}.crossItem span{display:block}.btn-control-div .btn{width:8rem}.timeZoneContainer{align-items:center}.timeZoneContainer span{margin-left:5px}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"], components: [{ type: i4$1.NgbTimepicker, selector: "ngb-timepicker", inputs: ["meridian", "spinners", "seconds", "hourStep", "minuteStep", "secondStep", "readonlyInputs", "size"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i2.SelectMultipleControlValueAccessor, selector: "select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]", inputs: ["compareWith"] }, { type: i4$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { type: i4$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "translate": i3.TranslatePipe } });
440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormMissionComponent, decorators: [{
441
+ type: Component,
442
+ args: [{ selector: 'lib-form-mission', template: "<div class=\"form-containter\" *ngIf=\"missionForm\">\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'Mission details' | translate }}</h4>\r\n </div>\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"missionForm\">\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Organisation' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"organisation\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\" *ngIf=\"isSP\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Ordered by' | translate }}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"orderedOrganisationID\">\r\n <option *ngFor=\"let org of allOrgs\" [ngValue]=\"org.id\">\r\n {{ org.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Description' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <textarea class=\"form-control\" formControlName=\"description\" rows=\"10\"></textarea>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Role' | translate}}*</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"role\" [class.is-invalid]=\"role.invalid && role.touched\">\r\n <option *ngFor=\"let r of availableRoles\" [ngValue]=\"r\">\r\n {{ r }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n {{'Role is required' | translate}}.\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\"\r\n *ngIf=\"missionForm.get('role').value !== 'VISITOR_MUSEUM' && missionForm.get('role').value !== 'GUIDE_MUSEUM'\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Domains' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"domains\">\r\n <select class=\"form-control\" multiple formControlName=\"domains\">\r\n <option *ngFor=\"let domain of domains\" [ngValue]=\"domain.id\">\r\n {{ domain.name }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Access level' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"level\">\r\n <option *ngFor=\"let level of availableLevels\" [ngValue]=\"level\">\r\n {{ level }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized location' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"availableSpaces\">\r\n <select class=\"form-control\" required formControlName=\"space\" (change)=\"onSpaceClick()\" \r\n [class.is-invalid]=\"spaceID.invalid && spaceID.touched\">\r\n <option *ngFor=\"let space of availableSpaces\" [ngValue]=\"space.id\">\r\n {{ space.name }}\r\n </option>\r\n </select>\r\n <div class=\"invalid-feedback\">\r\n {{'Location is required' | translate}}.\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!availableSpaces\">\r\n {{ 'No locations available' | translate}}\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized zone' | translate }}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace; else noSpace\">\r\n <select class=\"form-control\" formControlName=\"zone\">\r\n <option [ngValue]=\"defaultZone.id\">\r\n {{ 'All zones' | translate }}\r\n </option>\r\n <option *ngFor=\"let zone of zonesForSpace\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <ng-template #noSpace>\r\n <div class=\"col-sm-8 hint-container\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Language' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" formControlName=\"locale\">\r\n <option [ngValue]=\"null\">{{'Not applicable' | translate}}</option>\r\n <option *ngFor=\"let locale of locales\" [ngValue]=\"locale\">\r\n {{ locale }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n <!-- Hashtags are available after Space is set -->\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Hashtags' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"spaceID.value\">\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length > 0\">{{'Available hashtags' | translate}} </p>\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length === 0\">\r\n {{'No hashtags created for this location' | translate}} </p>\r\n <div *ngIf=\"availableHashtags.length > 0\">\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li *ngFor=\"let hashtag of availableHashtags\"\r\n [class]=\"hashtagAdded(hashtag) ? 'keywordsItem added' : 'keywordsItem'\"\r\n (click)=\"onHashtagClick(hashtag)\" style=\"cursor: pointer;\"\r\n ngbTooltip=\"{{hashtagAdded(hashtag) ? ('Remove'|translate) : ('Add'|translate) }}\">\r\n {{hashtag.name}}\r\n </li>\r\n </div>\r\n </ul>\r\n <p class=\"keywordsRules\">{{'Added hashtags' | translate}} </p>\r\n <ul class=\"keywordsDisplay\">\r\n <div class=\"keywordsdisplayContainer\" *ngIf=\"addedHashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of addedHashtags\">{{ hashtag.name }}\r\n <a type=\"button\" class=\"closeButton\" (click)=\"removeHashtag(hashtag)\">\r\n <span class=\"crossItem\"></span>\r\n </a>\r\n </li>\r\n </div>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8 hint-container\" *ngIf=\"!spaceID.value\">\r\n <p class=\"hint keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"startDate\" 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()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission Start Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeStart\" [ngModelOptions]=\"{standalone: true}\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"endDate\" ngbDatepicker\r\n #d2=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d2.toggle()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Mission End Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8 timeZoneContainer\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeEnd\" [ngModelOptions]=\"{standalone: true}\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"btn-control-div action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n >{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n </form>\r\n</div>", styles: [".form-containter{padding:0rem 1rem;margin-bottom:2rem}.checkbox-apply{margin-top:calc(.375rem + 1px)}.keywordsDisplay{min-height:40px}.hint{margin:0!important}.hint-container{display:flex;align-items:center}.crossItem{margin:0;padding:0;border:0;background:none;position:relative;width:7px;height:20px}.crossItem:before,.crossItem:after{content:\"\";position:absolute;top:6.25px;left:0;right:0;height:1.5px;background:#fff;border-radius:1.5px}.crossItem:before{transform:rotate(45deg)}.crossItem:after{transform:rotate(-45deg)}.crossItem span{display:block}.btn-control-div .btn{width:8rem}.timeZoneContainer{align-items:center}.timeZoneContainer span{margin-left:5px}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"] }]
443
+ }], ctorParameters: function () { return [{ type: i2.FormBuilder }, { type: i1.SpaceService }, { type: i1.BaseUserService }, { type: i1.DomainService }, { type: i1.OrganisationService }, { type: i1.ZoneService }, { type: i1.HashtagService }, { type: i1.LocaleService }]; }, propDecorators: { missionToEdit: [{
444
+ type: Input
445
+ }], organisationForMission: [{
446
+ type: Input
447
+ }], isSP: [{
448
+ type: Input
449
+ }], userForMissionID: [{
450
+ type: Input
451
+ }], currentUserOrganisation: [{
452
+ type: Input
453
+ }], addedMissionInput: [{
454
+ type: Output
455
+ }] } });
456
+
457
+ class UserMissionFormComponent {
458
+ constructor(fb, userService, translate) {
459
+ this.fb = fb;
460
+ this.userService = userService;
461
+ this.translate = translate;
462
+ this.createForExistingUser = false;
463
+ this.added = new EventEmitter();
464
+ this.working = false;
465
+ }
466
+ ngOnInit() {
467
+ this.onAddNewUserMissionToOrg();
468
+ }
469
+ async onAddNewUserMissionToOrg() {
470
+ this.form = this.fb.group({
471
+ email: [null, [Validators.required]],
472
+ lastName: [""],
473
+ firstName: [""],
474
+ });
475
+ }
476
+ onCancel() {
477
+ this.added.emit(false);
478
+ }
479
+ get email() {
480
+ return this.form.get("email");
481
+ }
482
+ async onSubmit() {
483
+ this.working = true;
484
+ let p;
485
+ try {
486
+ const formValue = this.form.value;
487
+ p = await this.userService.profileForMail(formValue.email);
488
+ if (p) {
489
+ alert("User with this email exists already!");
490
+ this.working = false;
491
+ return;
492
+ }
493
+ try {
494
+ const profile = await this.userService.createUserAWSandProfile(formValue, true);
495
+ console.log("User created!", profile.metadata);
496
+ this.createdUser = profile;
497
+ }
498
+ catch (error) {
499
+ this.working = false;
500
+ alert(this.translate.instant(JSON.stringify(error)));
501
+ return;
502
+ }
503
+ }
504
+ catch (error) {
505
+ console.error(error);
506
+ }
507
+ this.working = false;
508
+ }
509
+ // async updateAllMissionsFromTemplate(missionInput: UpdateMissionInput) {
510
+ // // all missions of this organisation
511
+ // const missionsFromTemplate =
512
+ // await this.missionService.getMissionsByTemplate(
513
+ // this.missionToEdit.id,
514
+ // );
515
+ // await Promise.all(
516
+ // missionsFromTemplate.map(async (mission) => {
517
+ // const missionTemplate = { ...missionInput };
518
+ // if (this.sendUpdate) {
519
+ // missionTemplate.emailStatus = EmailStatus.UPDATE_TO_DELIVER;
520
+ // }
521
+ // missionTemplate.id = mission.id;
522
+ // await this.missionService.update(missionTemplate);
523
+ // }),
524
+ // );
525
+ // }
526
+ async onMissionInput(mission) {
527
+ if (mission) {
528
+ this.missionInput = mission;
529
+ await this.userService.createOrUpdateMissionForOrgWithProperty(this.missionInput, this.missionInput.organisationID);
530
+ this.added.emit(true);
531
+ }
532
+ else {
533
+ this.added.emit(false);
534
+ }
535
+ }
536
+ }
537
+ UserMissionFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UserMissionFormComponent, deps: [{ token: i2.FormBuilder }, { token: i1.BaseUserService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
538
+ UserMissionFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: UserMissionFormComponent, selector: "lib-user-mission-form", inputs: { addToOrganisation: "addToOrganisation", isSP: "isSP", createForExistingUser: "createForExistingUser", currentOrg: "currentOrg" }, outputs: { added: "added" }, ngImport: i0, template: "<div *ngIf=\"form\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n <div id=\"personalInfo\">\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'User Personal Information' | translate }}</h4>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Email' | translate}} *</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" [class.is-invalid]=\"email.invalid && email.touched\" required\r\n formControlName=\"email\">\r\n <div class=\"invalid-feedback\">\r\n {{'An email is required' | translate}}.\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Last name' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"lastName\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'First name' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"firstName\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n\r\n <div *ngIf=\"createdUser; else waitingForUser\">\r\n <div class=\"alert alert-info\">\r\n {{'User successfully created' | translate}}\r\n </div>\r\n <lib-form-mission [organisationForMission]=\"addToOrganisation\" [userForMissionID]=\"createdUser.id\"\r\n [currentUserOrganisation]=\"currentOrg\" [isSP]=\"isSP\" (addedMissionInput)=\"onMissionInput($event)\">\r\n </lib-form-mission>\r\n </div>\r\n <ng-template #waitingForUser>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n [disabled]=\"working || form.invalid\">{{'Create user' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'Mission details' | translate }}</h4>\r\n </div>\r\n <ngb-alert type=\"warning\" [dismissible]=\"false\">{{'Please create a user first' | translate}}.</ngb-alert>\r\n\r\n </ng-template>\r\n </form>\r\n</div>", styles: [".form-group{margin:1.5rem 0}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"], components: [{ type: i1.LoaderComponent, selector: "lib-loader" }, { type: FormMissionComponent, selector: "lib-form-mission", inputs: ["missionToEdit", "organisationForMission", "isSP", "userForMissionID", "currentUserOrganisation"], outputs: ["addedMissionInput"] }, { type: i4$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], pipes: { "translate": i3.TranslatePipe } });
539
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UserMissionFormComponent, decorators: [{
540
+ type: Component,
541
+ args: [{ selector: 'lib-user-mission-form', template: "<div *ngIf=\"form\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n <div id=\"personalInfo\">\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'User Personal Information' | translate }}</h4>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Email' | translate}} *</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" [class.is-invalid]=\"email.invalid && email.touched\" required\r\n formControlName=\"email\">\r\n <div class=\"invalid-feedback\">\r\n {{'An email is required' | translate}}.\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Last name' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"lastName\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'First name' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"firstName\">\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n\r\n <div *ngIf=\"createdUser; else waitingForUser\">\r\n <div class=\"alert alert-info\">\r\n {{'User successfully created' | translate}}\r\n </div>\r\n <lib-form-mission [organisationForMission]=\"addToOrganisation\" [userForMissionID]=\"createdUser.id\"\r\n [currentUserOrganisation]=\"currentOrg\" [isSP]=\"isSP\" (addedMissionInput)=\"onMissionInput($event)\">\r\n </lib-form-mission>\r\n </div>\r\n <ng-template #waitingForUser>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n [disabled]=\"working || form.invalid\">{{'Create user' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n <div style=\"margin-top: 1rem;\">\r\n <h4>{{ 'Mission details' | translate }}</h4>\r\n </div>\r\n <ngb-alert type=\"warning\" [dismissible]=\"false\">{{'Please create a user first' | translate}}.</ngb-alert>\r\n\r\n </ng-template>\r\n </form>\r\n</div>", styles: [".form-group{margin:1.5rem 0}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"] }]
542
+ }], ctorParameters: function () { return [{ type: i2.FormBuilder }, { type: i1.BaseUserService }, { type: i3.TranslateService }]; }, propDecorators: { addToOrganisation: [{
543
+ type: Input
544
+ }], isSP: [{
545
+ type: Input
546
+ }], createForExistingUser: [{
547
+ type: Input
548
+ }], currentOrg: [{
549
+ type: Input
550
+ }], added: [{
551
+ type: Output
552
+ }] } });
553
+
554
+ class FormOrganisationComponent {
555
+ constructor(orgService, fb, userService) {
556
+ this.orgService = orgService;
557
+ this.fb = fb;
558
+ this.userService = userService;
559
+ this.working = false;
560
+ this.added = new EventEmitter();
561
+ }
562
+ async ngOnInit() {
563
+ this.isSP = this.userService.isSPAdmin();
564
+ this.initForm();
565
+ }
566
+ ngAfterViewInit() {
567
+ const handlePaste = function handlePaste(event) {
568
+ const pastedData = event.clipboardData.getData("Text");
569
+ if (pastedData.length > 10) {
570
+ this.findOrgByToken(pastedData);
571
+ }
572
+ }.bind(this);
573
+ if (this.existing) {
574
+ setTimeout(() => {
575
+ const inputElement = document.querySelector("#tokenInput");
576
+ inputElement.addEventListener("paste", handlePaste);
577
+ inputElement.addEventListener("keydown", ({ key }) => {
578
+ if (key === "Backspace" || key === "Delete") {
579
+ this.initForm();
580
+ }
581
+ });
582
+ inputElement.addEventListener("keydown", ({ key }) => {
583
+ if (key === "Enter") {
584
+ const { value } = inputElement;
585
+ this.findOrgByToken(value);
586
+ }
587
+ });
588
+ }, 600);
589
+ }
590
+ }
591
+ initForm() {
592
+ this.form = this.fb.group({
593
+ name: [null, [Validators.required]],
594
+ address: [""],
595
+ city: [""],
596
+ postal: [null],
597
+ siret: [null],
598
+ });
599
+ if (this.existing) {
600
+ const orgControls = this.form;
601
+ for (const control of Object.keys(orgControls.controls)) {
602
+ orgControls.controls[control].disable();
603
+ }
604
+ }
605
+ }
606
+ onCancel() {
607
+ this.form = null;
608
+ this.added.emit(false);
609
+ }
610
+ get name() {
611
+ return this.form.get("name");
612
+ }
613
+ async onSubmit() {
614
+ this.working = true;
615
+ const formValue = this.form.value;
616
+ removeNullKeysFromObject(formValue);
617
+ try {
618
+ if (!this.existing) {
619
+ const organisation = await this.orgService.createOrganisation(formValue);
620
+ if (organisation) {
621
+ this.createdOrg = organisation;
622
+ }
623
+ }
624
+ else {
625
+ // orgID = this.existingOrgID;
626
+ }
627
+ }
628
+ catch (error) {
629
+ console.error(error);
630
+ this.added.emit(false);
631
+ }
632
+ this.working = false;
633
+ }
634
+ async findOrgByToken(token) {
635
+ const org = await this.orgService.getOrganisationByToken(token);
636
+ if (org) {
637
+ this.form.setValue({
638
+ name: [org.name],
639
+ address: [org.address],
640
+ city: [org.city],
641
+ postal: [org.postal],
642
+ siret: [org.siret],
643
+ });
644
+ this.existingOrgID = org.id;
645
+ }
646
+ else {
647
+ alert("No organisation found. Maybe token is expired?");
648
+ }
649
+ }
650
+ userAndMissionAdded(added) {
651
+ this.added.emit(added);
652
+ }
653
+ }
654
+ FormOrganisationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormOrganisationComponent, deps: [{ token: i1.OrganisationService }, { token: i2.FormBuilder }, { token: i1.BaseUserService }], target: i0.ɵɵFactoryTarget.Component });
655
+ FormOrganisationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FormOrganisationComponent, selector: "lib-form-organisation", inputs: { currentOrg: "currentOrg", currentUser: "currentUser", existing: "existing" }, outputs: { added: "added" }, ngImport: i0, template: "<div *ngIf=\"form\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n <div>\r\n <h4>{{ 'Organisation' | translate }}</h4>\r\n </div>\r\n <div class=\"form-group row\" *ngIf=\"existing\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Organisation Token' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" id=\"tokenInput\" placeholder=\"Paste organisation token here\">\r\n </div>\r\n </div>\r\n <div class=\"form-group 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\" [class.is-invalid]=\"name.invalid && name.touched\" required\r\n formControlName=\"name\">\r\n <div class=\"invalid-feedback\">\r\n {{'Name is mandatory' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group 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=\"address\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'City' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"city\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Postal Code' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"postal\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'SIRET' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"siret\">\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"createdOrg; else noOrg\">\r\n <div class=\"alert alert-info\">\r\n {{'Organisation successfully created' | translate}}\r\n </div>\r\n <lib-user-mission-form [addToOrganisation]=\"createdOrg\" [currentOrg]=\"currentOrg\" [isSP]=\"isSP\"\r\n (added)=\"userAndMissionAdded($event)\">\r\n </lib-user-mission-form>\r\n </div>\r\n <ng-template #noOrg>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n [disabled]=\"this.working || form.invalid\">{{'Create organisation' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"this.working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n <div style='margin-top: 1rem'>\r\n <h4>{{ 'User Personal Information' | translate }}</h4>\r\n </div>\r\n <ngb-alert type=\"warning\" [dismissible]=\"false\">{{'Please create new organisation first' | translate}}\r\n </ngb-alert>\r\n\r\n </ng-template>\r\n\r\n\r\n </form>\r\n</div>", styles: [".form-group{margin:1.5rem 0}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"], components: [{ type: UserMissionFormComponent, selector: "lib-user-mission-form", inputs: ["addToOrganisation", "isSP", "createForExistingUser", "currentOrg"], outputs: ["added"] }, { type: i4$1.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], pipes: { "translate": i3.TranslatePipe } });
656
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormOrganisationComponent, decorators: [{
657
+ type: Component,
658
+ args: [{ selector: 'lib-form-organisation', template: "<div *ngIf=\"form\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n <div>\r\n <h4>{{ 'Organisation' | translate }}</h4>\r\n </div>\r\n <div class=\"form-group row\" *ngIf=\"existing\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Organisation Token' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" id=\"tokenInput\" placeholder=\"Paste organisation token here\">\r\n </div>\r\n </div>\r\n <div class=\"form-group 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\" [class.is-invalid]=\"name.invalid && name.touched\" required\r\n formControlName=\"name\">\r\n <div class=\"invalid-feedback\">\r\n {{'Name is mandatory' | translate}}\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group 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=\"address\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'City' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"city\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Postal Code' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"postal\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'SIRET' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"siret\">\r\n </div>\r\n </div>\r\n\r\n\r\n <div *ngIf=\"createdOrg; else noOrg\">\r\n <div class=\"alert alert-info\">\r\n {{'Organisation successfully created' | translate}}\r\n </div>\r\n <lib-user-mission-form [addToOrganisation]=\"createdOrg\" [currentOrg]=\"currentOrg\" [isSP]=\"isSP\"\r\n (added)=\"userAndMissionAdded($event)\">\r\n </lib-user-mission-form>\r\n </div>\r\n <ng-template #noOrg>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill mr-3 action-button\"\r\n [disabled]=\"this.working || form.invalid\">{{'Create organisation' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"this.working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n <div style='margin-top: 1rem'>\r\n <h4>{{ 'User Personal Information' | translate }}</h4>\r\n </div>\r\n <ngb-alert type=\"warning\" [dismissible]=\"false\">{{'Please create new organisation first' | translate}}\r\n </ngb-alert>\r\n\r\n </ng-template>\r\n\r\n\r\n </form>\r\n</div>", styles: [".form-group{margin:1.5rem 0}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"] }]
659
+ }], ctorParameters: function () { return [{ type: i1.OrganisationService }, { type: i2.FormBuilder }, { type: i1.BaseUserService }]; }, propDecorators: { currentOrg: [{
660
+ type: Input
661
+ }], currentUser: [{
662
+ type: Input
663
+ }], existing: [{
664
+ type: Input
665
+ }], added: [{
666
+ type: Output
667
+ }] } });
668
+
669
+ class DetailOrganisationComponent {
670
+ constructor(organisationService,
671
+ // private localStripe: StripeService,
672
+ formBuilder) {
673
+ this.organisationService = organisationService;
674
+ this.formBuilder = formBuilder;
675
+ this.orgChanged = new EventEmitter();
676
+ this.loading = false;
677
+ this.connectingStripe = false;
678
+ }
679
+ ngOnInit() {
680
+ this.myOrg = this.currentOrg.id === this.org.id;
681
+ if (!this.org.connectedAccountStripeID && (this.myOrg || this.isSP)) {
682
+ this.setConnectStripeLink();
683
+ }
684
+ }
685
+ ngOnChanges() {
686
+ this.myOrg = this.currentOrg.id === this.org.id;
687
+ }
688
+ async onToken() {
689
+ const token = v4();
690
+ const expires = new Date();
691
+ expires.setDate(expires.getDate() + 7); // 7 days expiration
692
+ this.org = await this.organisationService.updateOrganisation({
693
+ id: this.org.id,
694
+ shareToken: token,
695
+ tokenExpiresAt: expires.getTime(),
696
+ });
697
+ this.orgChanged.emit(true);
698
+ }
699
+ prettifyToken() {
700
+ const expirationDate = new Date(this.org.tokenExpiresAt);
701
+ const diffTime = expirationDate.getTime() - Date.now();
702
+ const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
703
+ const expirationString = diffTime < 0 ? "expired!" : `expires in ${diffDays} days`;
704
+ return `${this.org.shareToken.slice(0, 6)}... ${expirationString}`;
705
+ }
706
+ /**
707
+ * Created New Stripe Account and launches onboarding procedure (mail, phone, business details..) by Stripe
708
+ * @returns null
709
+ */
710
+ // async onCreateStripe() {
711
+ // this.loading = true;
712
+ // // Make the request
713
+ // const responseAccount = await API.post(
714
+ // "stripeApi",
715
+ // "/create/account",
716
+ // {},
717
+ // );
718
+ // console.log(responseAccount);
719
+ // if (responseAccount.err) {
720
+ // this.handleStripeError(responseAccount);
721
+ // return;
722
+ // }
723
+ // const { account } = responseAccount;
724
+ // // save account id to organisation
725
+ // await this.organisationService.update({
726
+ // id: this.org.id,
727
+ // connectedAccountStripeID: account.id,
728
+ // stripeOnBoardingCompleted: false,
729
+ // });
730
+ // const { origin } = document.location;
731
+ // const responseAccountLinks = await this.localStripe.createAccountLink(
732
+ // account.id,
733
+ // origin,
734
+ // );
735
+ // if (responseAccountLinks.err) {
736
+ // this.handleStripeError(responseAccountLinks);
737
+ // return;
738
+ // }
739
+ // window.location.href = responseAccountLinks.accountLinks.url;
740
+ // this.loading = false;
741
+ // }
742
+ // async onCompleteOnboardingStripe() {
743
+ // this.loading = true;
744
+ // const responseAccountLinks = await this.localStripe.createAccountLink(
745
+ // this.org.connectedAccountStripeID,
746
+ // origin,
747
+ // );
748
+ // if (responseAccountLinks.err) {
749
+ // this.handleStripeError(responseAccountLinks);
750
+ // return;
751
+ // }
752
+ // window.location.href = responseAccountLinks.accountLinks.url;
753
+ // this.loading = false;
754
+ // }
755
+ // handleStripeError(stripeResponse) {
756
+ // alert(stripeResponse.err.raw.message);
757
+ // this.loading = false;
758
+ // }
759
+ /**
760
+ * Generate link for Launching OAuth connection with Stripe: https://stripe.com/docs/connect/oauth-standard-accounts#integrating-oauth
761
+ */
762
+ setConnectStripeLink() {
763
+ setTimeout(() => {
764
+ const hyperlink = document.querySelector("#linkStripe");
765
+ if (hyperlink) {
766
+ const clientID = "ca_KQhYOlgR1ipOxLBBQHfQeCLoaySRVD5P"; // TODO change for live Stripe Account
767
+ const { origin } = document.location;
768
+ const returnUrl = `${origin}/stripe/redirect`;
769
+ hyperlink.setAttribute("href", `https://connect.stripe.com/oauth/authorize?response_type=code&client_id=${clientID}&scope=read_write&redirect_uri=${returnUrl}&state=${this.org.id}`);
770
+ }
771
+ }, 200); // wait until the element is rendered
772
+ }
773
+ /** Edit */
774
+ onEdit() {
775
+ this.editForm = this.formBuilder.group({
776
+ id: this.org.id,
777
+ name: this.org.name,
778
+ siret: this.org.siret,
779
+ city: this.org.city,
780
+ address: this.org.address,
781
+ contactDetails: this.org.contactDetails,
782
+ postal: this.org.postal,
783
+ });
784
+ }
785
+ get name() {
786
+ return this.editForm.get("name");
787
+ }
788
+ async onSubmit() {
789
+ const formValue = this.editForm.value;
790
+ removeNullKeysFromObject(formValue);
791
+ try {
792
+ const updatedOrg = await this.organisationService.updateOrganisation(formValue);
793
+ this.org = updatedOrg;
794
+ }
795
+ catch (error) {
796
+ console.error(JSON.stringify(error));
797
+ }
798
+ this.editForm = null;
799
+ }
800
+ onCancel() {
801
+ this.editForm = null;
802
+ }
803
+ }
804
+ DetailOrganisationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: DetailOrganisationComponent, deps: [{ token: i1.OrganisationService }, { token: i2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component });
805
+ DetailOrganisationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: DetailOrganisationComponent, selector: "lib-detail-organisation", inputs: { org: "org", currentOrg: "currentOrg", isSP: "isSP" }, outputs: { orgChanged: "orgChanged" }, usesOnChanges: true, ngImport: i0, template: "<div>\r\n <h5>{{'Organisation Details' | translate }}</h5>\r\n <div *ngIf=\"!editForm\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{ org.name }}</li>\r\n\r\n <li class=\"list-group-item bg-transparent\">{{'SIRET' | translate }}: {{\r\n org.siret ? org.siret : (\"No data\" | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate }}: {{\r\n org.address ? org.address : (\"No data\" | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'City' | translate }}: {{org.city }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Contact information' | translate}}:\r\n {{ org.contactDetails ? org.contactDetails : (\"No data\" | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"isSP\">\r\n <div class=\"row ml-0\">\r\n <div>\r\n {{'Active token' | translate }}:\r\n {{ org.shareToken ? prettifyToken() : ('No' | translate) }}\r\n </div>\r\n <div *ngIf=\"org.shareToken && !tokenExpired\" ngxClipboard [cbContent]=\"org.shareToken\"\r\n [style.cursor]=\"'pointer'\" style=\"margin-left: 5px; max-width: 20px;\" 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 </li>\r\n </ul>\r\n <div class=\"action-button-container\">\r\n <button class=\"btn btn-outline-primary rounded-pill mt-2 ml-3 action-button\" *ngIf=\"isSP || myOrg\"\r\n (click)=\"onEdit()\">\r\n {{'Edit' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill mt-2 ml-3 action-button\" *ngIf=\"isSP\"\r\n (click)=\"onToken()\">{{'Generate\r\n token' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <!--Edit Form-->\r\n <div *ngIf=\"editForm\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"editForm\">\r\n <div class=\"form-group 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\" [class.is-invalid]=\"name.invalid && name.touched\" required\r\n 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=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Contact information' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"contactDetails\"\r\n placeholder=\"{{'Name, phone, email' | translate}}\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group 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=\"address\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'City' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"city\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Postal code' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"postal\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'SIRET' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"siret\">\r\n </div>\r\n </div>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n [disabled]=\"editForm.invalid\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <!--Loading-->\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n\r\n <!--Stripe-->\r\n <hr>\r\n <h5>{{'stripe.account' | translate }}</h5>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"(isSP || myOrg) && org.connectedAccountStripeID\">\r\n {{'stripe.connected' | translate }}: {{org.connectedAccountStripeID.substring(0, 15) }}...</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"(isSP || myOrg) && org.stripeOnBoardingCompleted !== null\">\r\n {{'stripe.completed' | translate }}: {{org.stripeOnBoardingCompleted }}</li>\r\n </ul>\r\n <!-- <a *ngIf=\"(myOrg || isSP) && !org.connectedAccountStripeID\" id=\"linkStripe\" \r\n class=\"ml-3 stripe-connect\"><span>Connect with</span>\r\n </a>\r\n <button class=\"btn btn-outline-primary rounded-pill mt-3 mb-3 ml-3 no-lowercase\"\r\n *ngIf=\"(myOrg || isSP) && org.connectedAccountStripeID && !org.stripeOnBoardingCompleted\"\r\n (click)=\"onCompleteOnboardingStripe()\">{{'stripe.toComplete' | translate}}</button> -->\r\n\r\n</div>", styles: [".form-group{margin:1.5rem 0}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"], components: [{ type: i1.LoaderComponent, selector: "lib-loader" }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4$2.ClipboardDirective, selector: "[ngxClipboard]", inputs: ["ngxClipboard", "container", "cbContent", "cbSuccessMsg"], outputs: ["cbOnSuccess", "cbOnError"] }, { type: i4$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], pipes: { "translate": i3.TranslatePipe } });
806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: DetailOrganisationComponent, decorators: [{
807
+ type: Component,
808
+ args: [{ selector: 'lib-detail-organisation', template: "<div>\r\n <h5>{{'Organisation Details' | translate }}</h5>\r\n <div *ngIf=\"!editForm\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{ org.name }}</li>\r\n\r\n <li class=\"list-group-item bg-transparent\">{{'SIRET' | translate }}: {{\r\n org.siret ? org.siret : (\"No data\" | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate }}: {{\r\n org.address ? org.address : (\"No data\" | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'City' | translate }}: {{org.city }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Contact information' | translate}}:\r\n {{ org.contactDetails ? org.contactDetails : (\"No data\" | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"isSP\">\r\n <div class=\"row ml-0\">\r\n <div>\r\n {{'Active token' | translate }}:\r\n {{ org.shareToken ? prettifyToken() : ('No' | translate) }}\r\n </div>\r\n <div *ngIf=\"org.shareToken && !tokenExpired\" ngxClipboard [cbContent]=\"org.shareToken\"\r\n [style.cursor]=\"'pointer'\" style=\"margin-left: 5px; max-width: 20px;\" 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 </li>\r\n </ul>\r\n <div class=\"action-button-container\">\r\n <button class=\"btn btn-outline-primary rounded-pill mt-2 ml-3 action-button\" *ngIf=\"isSP || myOrg\"\r\n (click)=\"onEdit()\">\r\n {{'Edit' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill mt-2 ml-3 action-button\" *ngIf=\"isSP\"\r\n (click)=\"onToken()\">{{'Generate\r\n token' | translate}}</button>\r\n </div>\r\n </div>\r\n\r\n <!--Edit Form-->\r\n <div *ngIf=\"editForm\">\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"editForm\">\r\n <div class=\"form-group 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\" [class.is-invalid]=\"name.invalid && name.touched\" required\r\n 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=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Contact information' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"contactDetails\"\r\n placeholder=\"{{'Name, phone, email' | translate}}\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group 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=\"address\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'City' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"city\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'Postal code' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"postal\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-3 col-form-label\">{{'SIRET' | translate}}</label>\r\n <div class=\"col-sm-9\">\r\n <input type=\"text\" class=\"form-control\" formControlName=\"siret\">\r\n </div>\r\n </div>\r\n <div class=\"action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n [disabled]=\"editForm.invalid\">{{'Save' |\r\n translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' |\r\n translate}}</button>\r\n </div>\r\n </form>\r\n </div>\r\n <!--Loading-->\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n\r\n <!--Stripe-->\r\n <hr>\r\n <h5>{{'stripe.account' | translate }}</h5>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"(isSP || myOrg) && org.connectedAccountStripeID\">\r\n {{'stripe.connected' | translate }}: {{org.connectedAccountStripeID.substring(0, 15) }}...</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"(isSP || myOrg) && org.stripeOnBoardingCompleted !== null\">\r\n {{'stripe.completed' | translate }}: {{org.stripeOnBoardingCompleted }}</li>\r\n </ul>\r\n <!-- <a *ngIf=\"(myOrg || isSP) && !org.connectedAccountStripeID\" id=\"linkStripe\" \r\n class=\"ml-3 stripe-connect\"><span>Connect with</span>\r\n </a>\r\n <button class=\"btn btn-outline-primary rounded-pill mt-3 mb-3 ml-3 no-lowercase\"\r\n *ngIf=\"(myOrg || isSP) && org.connectedAccountStripeID && !org.stripeOnBoardingCompleted\"\r\n (click)=\"onCompleteOnboardingStripe()\">{{'stripe.toComplete' | translate}}</button> -->\r\n\r\n</div>", styles: [".form-group{margin:1.5rem 0}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"] }]
809
+ }], ctorParameters: function () { return [{ type: i1.OrganisationService }, { type: i2.FormBuilder }]; }, propDecorators: { org: [{
810
+ type: Input
811
+ }], currentOrg: [{
812
+ type: Input
813
+ }], isSP: [{
814
+ type: Input
815
+ }], orgChanged: [{
816
+ type: Output
817
+ }] } });
818
+
819
+ class UserComponent {
820
+ constructor(userService, missionService, domainService, organisationService, modalService, translate) {
821
+ this.userService = userService;
822
+ this.missionService = missionService;
823
+ this.domainService = domainService;
824
+ this.organisationService = organisationService;
825
+ this.modalService = modalService;
826
+ this.translate = translate;
827
+ this.detailsUser = '-1';
828
+ this.detailsOrg = '-1';
829
+ this.query = '';
830
+ this.create = false;
831
+ this.edit = false;
832
+ this.working = false;
833
+ this.createForExistingUser = false;
834
+ this.isAddingOrg = false;
835
+ this.isAddingToExistingOrg = false;
836
+ this.isManager = false;
837
+ this.hideList = false;
838
+ this.orgsUsersMissions = [];
839
+ this.isSP = false;
840
+ this.isGuide = false;
841
+ this.clientsSP = [];
842
+ this.prestataireClients = [];
843
+ this.loading = false;
844
+ this.destroy$ = new Subject();
845
+ this.userService.isChanged
846
+ .pipe(takeUntil(this.destroy$))
847
+ .subscribe((isConnected) => {
848
+ if (isConnected) {
849
+ this.initInfo();
850
+ }
851
+ });
852
+ }
853
+ // @todo list my org and sub orgs
854
+ /**
855
+ * resetList fetches a fresh user list from server
856
+ */
857
+ async resetList() {
858
+ this.orgsUsersMissions = [];
859
+ let allMissions = [];
860
+ this.loading = true;
861
+ if (this.isSP) {
862
+ this.orgsUsersMissions = await this.initListForSP();
863
+ this.filteredOrgsUsersMissions = this.orgsUsersMissions;
864
+ this.loading = false;
865
+ return;
866
+ }
867
+ allMissions = await this.missionService.getMissionsByOrderedOrganisation(this.currentOrg.id);
868
+ const currentOrgMissions = await this.missionService.getMissionsByOrganisation(this.currentOrg.id);
869
+ allMissions = [...allMissions, ...currentOrgMissions];
870
+ allMissions = allMissions.filter((mission) => mission.user && !mission.user.deletedAt);
871
+ allMissions = filterUniqueArrayByID(allMissions);
872
+ if (allMissions) {
873
+ const orgs = allMissions.map((mis) => mis.organisation);
874
+ const profiles = allMissions.map((mis) => mis.user);
875
+ const uniqueOrg = filterUniqueArrayByID(orgs);
876
+ const uniqueUsers = filterUniqueArrayByID(profiles);
877
+ uniqueOrg.map((org) => {
878
+ const orgMissions = allMissions.filter((mis) => {
879
+ return mis.organisationID === org.id;
880
+ });
881
+ let users = this.getUsersForOrgMissions(uniqueUsers, orgMissions);
882
+ users = users.sort((user) => (user.user.email ? 0 : -1));
883
+ const object = {
884
+ org,
885
+ users,
886
+ };
887
+ this.orgsUsersMissions.push(object);
888
+ });
889
+ }
890
+ this.filteredOrgsUsersMissions = this.orgsUsersMissions;
891
+ this.loading = false;
892
+ }
893
+ async initInfo() {
894
+ const currentUser = this.userService.cu;
895
+ if (currentUser) {
896
+ this.me = currentUser;
897
+ this.currentOrg = this.userService.currentOrganisation();
898
+ this.isManager = this.userService.hasManagerRoleInAnyMission();
899
+ this.isSP = this.userService.isSPAdmin();
900
+ this.isGuide = this.userService.isGuide();
901
+ this.resetList();
902
+ this.setDomains();
903
+ }
904
+ }
905
+ async ngOnInit() {
906
+ this.initInfo();
907
+ }
908
+ ngOnDestroy() {
909
+ this.destroy$.next(true);
910
+ this.destroy$.complete();
911
+ }
912
+ async initListForSP() {
913
+ const results = [];
914
+ let allMissions = [];
915
+ let allOrgs = [];
916
+ allOrgs = await this.organisationService.listOrganisations();
917
+ await Promise.all(allOrgs.map(async (org) => {
918
+ const missions = await this.missionService.getMissionsByOrganisation(org.id);
919
+ allMissions = [...allMissions, ...missions];
920
+ }));
921
+ const profiles = allMissions
922
+ .map((mis) => mis.user)
923
+ .filter((user) => !user.deletedAt);
924
+ const uniqueUsers = filterUniqueArrayByID(profiles.filter((profile) => profile !== null));
925
+ allOrgs.map((org) => {
926
+ const orgMissions = allMissions.filter((mis) => {
927
+ return mis.organisationID === org.id;
928
+ });
929
+ if (orgMissions.length > 0) {
930
+ if (orgMissions.filter((m) => m.orderedOrganisationID === '6e28201f-4679-4c29-9d2d-8a325f57cee9').length > 0) {
931
+ this.clientsSP.push(org.id);
932
+ }
933
+ else {
934
+ this.prestataireClients.push({
935
+ orgOwner: orgMissions[0].orderedOrganisationID,
936
+ prestataire: org.id,
937
+ });
938
+ }
939
+ }
940
+ const users = this.getUsersForOrgMissions(uniqueUsers, orgMissions);
941
+ const object = {
942
+ org,
943
+ users,
944
+ };
945
+ results.push(object);
946
+ });
947
+ return results;
948
+ }
949
+ // eslint-disable-next-line class-methods-use-this
950
+ getUsersForOrgMissions(uniqueUsers, orgMissions) {
951
+ const users = uniqueUsers.map((user) => {
952
+ const userMissions = orgMissions.filter((m) => m.userID === user.id);
953
+ if (userMissions.length > 0) {
954
+ const userProfile = new ProfileEntity(user);
955
+ // once we got the user we check filter only active missions (not deleted)
956
+ const activeMissions = userMissions.filter((mis) => !mis.deletedAt);
957
+ return {
958
+ missions: activeMissions,
959
+ user: userProfile,
960
+ };
961
+ }
962
+ return null;
963
+ });
964
+ return users.filter((us) => us !== null);
965
+ }
966
+ async setDomains() {
967
+ const domains = await this.domainService.getDomainsForOrgExcludingTypes([DomainType.FEATURE, DomainType.BOOKING], this.currentOrg.id);
968
+ this.domains = domains;
969
+ }
970
+ /**
971
+ * onToggleDetail folds/unfolds details for a given organisation
972
+ * @param i index of the organisation to be toggled
973
+ */
974
+ onToggleDetailOrg(index, org) {
975
+ this.detailsOrg = index === this.detailsOrg ? '-1' : index;
976
+ this.orgSelectedDetails = this.detailsOrg === '-1' ? null : org;
977
+ }
978
+ onToggleDetailUser(index) {
979
+ this.detailsUser = index === this.detailsUser ? '-1' : index;
980
+ }
981
+ async onAdd(org) {
982
+ this.create = true;
983
+ this.hideList = true;
984
+ this.addToOrg = org;
985
+ }
986
+ async onEdit(m) {
987
+ this.edit = true;
988
+ this.hideList = true;
989
+ this.missionToEdit = m;
990
+ }
991
+ onCancel() {
992
+ this.working = false;
993
+ this.create = false;
994
+ this.missionToEdit = null;
995
+ this.createForExistingUser = false;
996
+ }
997
+ onAddForUser(org, user) {
998
+ this.hideList = true;
999
+ this.createForExistingUser = true;
1000
+ this.userForAddingMission = user;
1001
+ this.addToOrg = org;
1002
+ }
1003
+ onAddOrg() {
1004
+ this.hideList = true;
1005
+ this.isAddingOrg = true;
1006
+ }
1007
+ orgAdded(isAdded) {
1008
+ this.hideList = false;
1009
+ this.isAddingOrg = false;
1010
+ this.isAddingToExistingOrg = false;
1011
+ if (isAdded) {
1012
+ this.resetList();
1013
+ }
1014
+ }
1015
+ userAdded(isAdded) {
1016
+ console.log(isAdded);
1017
+ this.hideList = false;
1018
+ this.create = false;
1019
+ this.addToOrg = null;
1020
+ this.createForExistingUser = false;
1021
+ this.userForAddingMission = null;
1022
+ if (isAdded) {
1023
+ this.resetList();
1024
+ }
1025
+ }
1026
+ async onMissionEdited(mission) {
1027
+ this.edit = false;
1028
+ this.missionToEdit = null;
1029
+ if (mission) {
1030
+ await this.userService.createOrUpdateMissionForOrgWithProperty(mission, mission.organisationID, false);
1031
+ this.resetList();
1032
+ }
1033
+ this.hideList = false;
1034
+ }
1035
+ async onMissionCreated(mission) {
1036
+ this.createForExistingUser = false;
1037
+ this.userForAddingMission = null;
1038
+ if (mission) {
1039
+ await this.userService.createOrUpdateMissionForOrgWithProperty(mission, mission.organisationID);
1040
+ this.resetList();
1041
+ }
1042
+ this.hideList = false;
1043
+ }
1044
+ getOrderedOrg(orgID) {
1045
+ let name;
1046
+ this.prestataireClients.map(async (presta) => {
1047
+ if (presta.prestataire === orgID) {
1048
+ const org = this.orgsUsersMissions.filter((object) => object.org.id === presta.orgOwner);
1049
+ if (org.length > 0) {
1050
+ name = org[0].org.name;
1051
+ }
1052
+ }
1053
+ });
1054
+ return name;
1055
+ }
1056
+ domainIdsToStringForMission(mission) {
1057
+ let names = '';
1058
+ for (const domainID of mission.domains) {
1059
+ const domain = this.domains.find((dom) => dom.id === domainID);
1060
+ if (domain) {
1061
+ names = `${names} ${domain.name},`;
1062
+ }
1063
+ }
1064
+ return names.slice(0, -1); // to remove last comma
1065
+ }
1066
+ async onDeleteMission(mission) {
1067
+ const message = this.translate.instant('confirm.deleteMission');
1068
+ if (window.confirm(message)) {
1069
+ await this.missionService.softDeleteMission(mission.id);
1070
+ this.resetList();
1071
+ }
1072
+ }
1073
+ async onDeleteUser(user) {
1074
+ const message = this.translate.instant('confirm.deleteUser');
1075
+ if (window.confirm(message)) {
1076
+ const userMissions = await this.missionService.getMissionsFromUserID(user.id);
1077
+ if (userMissions.length > 0) {
1078
+ const resultDelete = [];
1079
+ await Promise.all(userMissions.map(async (mission) => {
1080
+ if (mission.orderedOrganisationID === this.currentOrg.id ||
1081
+ this.isSP) {
1082
+ const deletedMission = await this.missionService.softDeleteMission(mission.id);
1083
+ if (deletedMission) {
1084
+ resultDelete.push(deletedMission);
1085
+ }
1086
+ }
1087
+ }));
1088
+ if (resultDelete.length > 0) {
1089
+ await this.userService.softDeleteUser(user.id);
1090
+ await this.resetList();
1091
+ }
1092
+ }
1093
+ else {
1094
+ await this.userService.softDeleteUser(user.id);
1095
+ await this.resetList();
1096
+ }
1097
+ }
1098
+ }
1099
+ applyResultsSearchBar(results) {
1100
+ this.orgSelectedDetails = null;
1101
+ this.filteredOrgsUsersMissions = results || this.orgsUsersMissions;
1102
+ }
1103
+ onAddInExistingOrg() {
1104
+ this.hideList = true;
1105
+ this.isAddingToExistingOrg = true;
1106
+ }
1107
+ /**
1108
+ * Creates encypted link and sets it for guestLink for Space.
1109
+ * @param mis
1110
+ */
1111
+ onSetForShareableLink(user, mission) {
1112
+ const modalReference = this.modalService.open(GuestLinkComponent);
1113
+ modalReference.componentInstance.username = user.email;
1114
+ modalReference.componentInstance.spaceID = mission.spaceID;
1115
+ }
1116
+ async onClearToken(user) {
1117
+ await this.userService.clearUserToken(user.user.id);
1118
+ const firstMessage = this.translate.instant('firstTokenMessage');
1119
+ const secondMessage = this.translate.instant('secondTokenMessage');
1120
+ alert(firstMessage + user.user.displayName + secondMessage);
1121
+ }
1122
+ }
1123
+ UserComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UserComponent, deps: [{ token: i1.BaseUserService }, { token: i1.MissionService }, { token: i1.DomainService }, { token: i1.OrganisationService }, { token: i4$1.NgbModal }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
1124
+ UserComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: UserComponent, selector: "lib-user", ngImport: i0, template: "<div class=\"dashboard-tab\">\r\n <div class=\"header-dashboard-tab\">\r\n <h3>{{'Users' | translate}}</h3>\r\n <!-- <app-search-bar *ngIf=\"!hideList\" [searchable]=\"orgsUsersMissions\" objectType=\"USER\"\r\n (searchEvent)=\"applyResultsSearchBar($event)\">\r\n </app-search-bar> -->\r\n <hr>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-md-8 col-lg-6\">\r\n <div class=\"row ml-0 mb-2\" *ngIf=\"!hideList\">\r\n <button class=\"btn btn-outline-primary rounded-pill add-button\" *ngIf=\"isManager && !isGuide\" (click)=\"onAddOrg()\">\r\n {{'Add user to new organisation' | translate}}</button>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div *ngIf=\"!hideList\">\r\n <ul class=\"list-group list-group-flush\" *ngIf=\"filteredOrgsUsersMissions\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let o of filteredOrgsUsersMissions\">\r\n <div class=\"d-flex justify-content-between align-items-center font-weight-bold\"\r\n ngbTooltip=\"See details and users\" style=\"cursor: pointer;\" (click)=\"onToggleDetailOrg(o.org.id, o.org)\">\r\n {{o.org.name}} <small *ngIf=\"o.org.id == currentOrg.id\">({{'My organisation' | translate}})</small>\r\n <small *ngIf=\"isSP && clientsSP.includes(o.org.id)\">({{'Client of SmarterPlan' | translate}})</small>\r\n <small *ngIf=\"isSP && getOrderedOrg(o.org.id)\">({{'Client of ' | translate}}\r\n {{getOrderedOrg(o.org.id)}})</small>\r\n <lib-chevron [conditionShowing]=\"detailsOrg==o.org.id\"></lib-chevron>\r\n </div>\r\n <div class=\"missions\" *ngIf=\"detailsOrg==o.org.id\">\r\n <div class='d-flex'>\r\n <button class=\"btn btn-outline-primary rounded-pill mt-3 mb-3\" (click)=\"onAdd(o.org)\">{{'Add user' |\r\n translate}}</button>\r\n </div>\r\n\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let a of o.users\"\r\n (click)=\"onToggleDetailUser(a.user.id)\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n {{a.user.displayName}}\r\n <lib-chevron [conditionShowing]=\"detailsUser==a.user.id\"></lib-chevron>\r\n </div>\r\n\r\n <div *ngIf=\"detailsUser==a.user.id\">\r\n <div class=\"ml-3\">\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n {{'Email' | translate}}: {{a.user.email }}\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill\"\r\n (click)=\"onAddForUser(o.org, a.user)\">{{'Add new mission' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill\" (click)=\"onClearToken(a)\">\r\n {{'Clear Token' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill\"\r\n (click)=\"onDeleteUser(a.user)\">{{'Delete user' | translate}}</button>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n {{ a.missions.length > 0 ? ('Current Missions' | translate) : ('No missions' | translate)}}\r\n </div>\r\n </div>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let mis of a.missions\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.description\">\r\n {{'Description' | translate}}: {{mis.description}}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.templateMissionID\">\r\n {{'Attendee of tour' | translate}}: {{mis.templateMission.title}}</li>\r\n\r\n <li class=\"list-group-item bg-transparent\">{{'Role' | translate}}: {{ mis.role }}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.hashtags && mis.hashtags.length> 0\">\r\n {{'Hashtags' | translate}}: <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of mis.hashtags\">\r\n {{ hashtag | hashtagFromID | async }}</li>\r\n </div>\r\n </ul>\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Language' | translate }}: {{\r\n mis.locale ? mis.locale : ('Not applicable' | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate }}: {{\r\n mis.level}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Ordered by' | translate }}: {{\r\n mis.orderedOrganisation.name}}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.domains\">{{'Domains' | translate }}:\r\n {{mis.domains ?\r\n domainIdsToStringForMission(mis) : (\"No data\" | translate) }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Authorized location' | translate }}:\r\n {{ mis.space ? mis.space.name : \"No location\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Authorized zone' | translate }}:\r\n {{ mis.zone ? mis.zone.name : \"All zones allowed\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Starts' | translate }}:\r\n {{ mis.startDateTime ? (mis.startDateTime | timeDateString: \"day_time_zone\" | async) :\r\n \"No data\" | translate}}, {{'Ends' | translate}}: {{ mis.endDateTime\r\n ? (mis.endDateTime | timeDateString: \"day_time_zone\" | async)\r\n : \"No data\" | translate}}.\r\n </li>\r\n </ul>\r\n <div class=\"action-button-container\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill mr-2 action-button\"\r\n (click)=\"onEdit(mis)\">{{'Edit' |\r\n translate}}</button>\r\n <button type=\"button\" *ngIf=\"mis.role === 'VISITOR' || mis.role === 'VISITOR_MUSEUM'\"\r\n class=\"btn btn-outline-primary rounded-pill mr-2 action-button share-visitor-button\"\r\n (click)=\"onSetForShareableLink(a.user, mis)\">{{'Generate Shareable Link' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n (click)=\"onDeleteMission(mis)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div *ngIf=\"create\">\r\n <lib-user-mission-form [addToOrganisation]=\"addToOrg\" [currentOrg]=\"currentOrg\" [isSP]=\"isSP\"\r\n (added)=\"userAdded($event)\">\r\n </lib-user-mission-form>\r\n </div>\r\n <div *ngIf=\"edit\">\r\n <lib-form-mission [missionToEdit]=\"missionToEdit\" [currentUserOrganisation]=\"currentOrg\" [isSP]=\"isSP\"\r\n (addedMissionInput)=\"onMissionEdited($event)\"></lib-form-mission>\r\n </div>\r\n <div *ngIf=\"createForExistingUser\">\r\n <lib-form-mission [organisationForMission]=\"addToOrg\" [currentUserOrganisation]=\"currentOrg\" [isSP]=\"isSP\"\r\n [userForMissionID]=\"userForAddingMission.id\" (addedMissionInput)=\"onMissionCreated($event)\">\r\n </lib-form-mission>\r\n </div>\r\n <div *ngIf=\"isAddingOrg || isAddingToExistingOrg\">\r\n <lib-form-organisation [currentOrg]=\"currentOrg\" [currentUser]=\"me\" [existing]=\"isAddingToExistingOrg\"\r\n (added)=\"orgAdded($event)\"></lib-form-organisation>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4 col-lg-6\" *ngIf=\"orgSelectedDetails && !isGuide\">\r\n <lib-detail-organisation [org]=\"orgSelectedDetails\" [currentOrg]=\"currentOrg\" [isSP]=\"isSP\"\r\n (orgChanged)='orgAdded($event)'></lib-detail-organisation>\r\n </div>\r\n </div>\r\n</div>", styles: [".add-button{width:-moz-fit-content;width:fit-content;margin-left:.5rem}li.ml-4{margin-left:3rem}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}.action-button-container .share-visitor-button{width:-moz-fit-content;width:fit-content}\n"], components: [{ type: i1.LoaderComponent, selector: "lib-loader" }, { type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { type: UserMissionFormComponent, selector: "lib-user-mission-form", inputs: ["addToOrganisation", "isSP", "createForExistingUser", "currentOrg"], outputs: ["added"] }, { type: FormMissionComponent, selector: "lib-form-mission", inputs: ["missionToEdit", "organisationForMission", "isSP", "userForMissionID", "currentUserOrganisation"], outputs: ["addedMissionInput"] }, { type: FormOrganisationComponent, selector: "lib-form-organisation", inputs: ["currentOrg", "currentUser", "existing"], outputs: ["added"] }, { type: DetailOrganisationComponent, selector: "lib-detail-organisation", inputs: ["org", "currentOrg", "isSP"], outputs: ["orgChanged"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }], pipes: { "translate": i3.TranslatePipe, "async": i4.AsyncPipe, "hashtagFromID": i1.HashtagFromIdPipe, "timeDateString": i1.TimeDateToLocalStringPipe } });
1125
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: UserComponent, decorators: [{
1126
+ type: Component,
1127
+ args: [{ selector: 'lib-user', template: "<div class=\"dashboard-tab\">\r\n <div class=\"header-dashboard-tab\">\r\n <h3>{{'Users' | translate}}</h3>\r\n <!-- <app-search-bar *ngIf=\"!hideList\" [searchable]=\"orgsUsersMissions\" objectType=\"USER\"\r\n (searchEvent)=\"applyResultsSearchBar($event)\">\r\n </app-search-bar> -->\r\n <hr>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-md-8 col-lg-6\">\r\n <div class=\"row ml-0 mb-2\" *ngIf=\"!hideList\">\r\n <button class=\"btn btn-outline-primary rounded-pill add-button\" *ngIf=\"isManager && !isGuide\" (click)=\"onAddOrg()\">\r\n {{'Add user to new organisation' | translate}}</button>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div *ngIf=\"!hideList\">\r\n <ul class=\"list-group list-group-flush\" *ngIf=\"filteredOrgsUsersMissions\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let o of filteredOrgsUsersMissions\">\r\n <div class=\"d-flex justify-content-between align-items-center font-weight-bold\"\r\n ngbTooltip=\"See details and users\" style=\"cursor: pointer;\" (click)=\"onToggleDetailOrg(o.org.id, o.org)\">\r\n {{o.org.name}} <small *ngIf=\"o.org.id == currentOrg.id\">({{'My organisation' | translate}})</small>\r\n <small *ngIf=\"isSP && clientsSP.includes(o.org.id)\">({{'Client of SmarterPlan' | translate}})</small>\r\n <small *ngIf=\"isSP && getOrderedOrg(o.org.id)\">({{'Client of ' | translate}}\r\n {{getOrderedOrg(o.org.id)}})</small>\r\n <lib-chevron [conditionShowing]=\"detailsOrg==o.org.id\"></lib-chevron>\r\n </div>\r\n <div class=\"missions\" *ngIf=\"detailsOrg==o.org.id\">\r\n <div class='d-flex'>\r\n <button class=\"btn btn-outline-primary rounded-pill mt-3 mb-3\" (click)=\"onAdd(o.org)\">{{'Add user' |\r\n translate}}</button>\r\n </div>\r\n\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item list-group-item-action\" *ngFor=\"let a of o.users\"\r\n (click)=\"onToggleDetailUser(a.user.id)\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n {{a.user.displayName}}\r\n <lib-chevron [conditionShowing]=\"detailsUser==a.user.id\"></lib-chevron>\r\n </div>\r\n\r\n <div *ngIf=\"detailsUser==a.user.id\">\r\n <div class=\"ml-3\">\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n {{'Email' | translate}}: {{a.user.email }}\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill\"\r\n (click)=\"onAddForUser(o.org, a.user)\">{{'Add new mission' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill\" (click)=\"onClearToken(a)\">\r\n {{'Clear Token' | translate}}</button>\r\n <button type=\"button\" class=\"btn btn-primary rounded-pill\"\r\n (click)=\"onDeleteUser(a.user)\">{{'Delete user' | translate}}</button>\r\n </div>\r\n <div class=\"d-flex justify-content-between align-items-center mt-3\">\r\n {{ a.missions.length > 0 ? ('Current Missions' | translate) : ('No missions' | translate)}}\r\n </div>\r\n </div>\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let mis of a.missions\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.description\">\r\n {{'Description' | translate}}: {{mis.description}}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.templateMissionID\">\r\n {{'Attendee of tour' | translate}}: {{mis.templateMission.title}}</li>\r\n\r\n <li class=\"list-group-item bg-transparent\">{{'Role' | translate}}: {{ mis.role }}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.hashtags && mis.hashtags.length> 0\">\r\n {{'Hashtags' | translate}}: <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of mis.hashtags\">\r\n {{ hashtag | hashtagFromID | async }}</li>\r\n </div>\r\n </ul>\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Language' | translate }}: {{\r\n mis.locale ? mis.locale : ('Not applicable' | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate }}: {{\r\n mis.level}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Ordered by' | translate }}: {{\r\n mis.orderedOrganisation.name}}</li>\r\n <li class=\"list-group-item bg-transparent\" *ngIf=\"mis.domains\">{{'Domains' | translate }}:\r\n {{mis.domains ?\r\n domainIdsToStringForMission(mis) : (\"No data\" | translate) }}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Authorized location' | translate }}:\r\n {{ mis.space ? mis.space.name : \"No location\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Authorized zone' | translate }}:\r\n {{ mis.zone ? mis.zone.name : \"All zones allowed\" | translate}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Starts' | translate }}:\r\n {{ mis.startDateTime ? (mis.startDateTime | timeDateString: \"day_time_zone\" | async) :\r\n \"No data\" | translate}}, {{'Ends' | translate}}: {{ mis.endDateTime\r\n ? (mis.endDateTime | timeDateString: \"day_time_zone\" | async)\r\n : \"No data\" | translate}}.\r\n </li>\r\n </ul>\r\n <div class=\"action-button-container\">\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill mr-2 action-button\"\r\n (click)=\"onEdit(mis)\">{{'Edit' |\r\n translate}}</button>\r\n <button type=\"button\" *ngIf=\"mis.role === 'VISITOR' || mis.role === 'VISITOR_MUSEUM'\"\r\n class=\"btn btn-outline-primary rounded-pill mr-2 action-button share-visitor-button\"\r\n (click)=\"onSetForShareableLink(a.user, mis)\">{{'Generate Shareable Link' |\r\n translate}}</button>\r\n <button type=\"button\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n (click)=\"onDeleteMission(mis)\">{{'Delete' | translate}}</button>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div *ngIf=\"create\">\r\n <lib-user-mission-form [addToOrganisation]=\"addToOrg\" [currentOrg]=\"currentOrg\" [isSP]=\"isSP\"\r\n (added)=\"userAdded($event)\">\r\n </lib-user-mission-form>\r\n </div>\r\n <div *ngIf=\"edit\">\r\n <lib-form-mission [missionToEdit]=\"missionToEdit\" [currentUserOrganisation]=\"currentOrg\" [isSP]=\"isSP\"\r\n (addedMissionInput)=\"onMissionEdited($event)\"></lib-form-mission>\r\n </div>\r\n <div *ngIf=\"createForExistingUser\">\r\n <lib-form-mission [organisationForMission]=\"addToOrg\" [currentUserOrganisation]=\"currentOrg\" [isSP]=\"isSP\"\r\n [userForMissionID]=\"userForAddingMission.id\" (addedMissionInput)=\"onMissionCreated($event)\">\r\n </lib-form-mission>\r\n </div>\r\n <div *ngIf=\"isAddingOrg || isAddingToExistingOrg\">\r\n <lib-form-organisation [currentOrg]=\"currentOrg\" [currentUser]=\"me\" [existing]=\"isAddingToExistingOrg\"\r\n (added)=\"orgAdded($event)\"></lib-form-organisation>\r\n </div>\r\n </div>\r\n\r\n <div class=\"col-md-4 col-lg-6\" *ngIf=\"orgSelectedDetails && !isGuide\">\r\n <lib-detail-organisation [org]=\"orgSelectedDetails\" [currentOrg]=\"currentOrg\" [isSP]=\"isSP\"\r\n (orgChanged)='orgAdded($event)'></lib-detail-organisation>\r\n </div>\r\n </div>\r\n</div>", styles: [".add-button{width:-moz-fit-content;width:fit-content;margin-left:.5rem}li.ml-4{margin-left:3rem}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}.action-button-container .share-visitor-button{width:-moz-fit-content;width:fit-content}\n"] }]
1128
+ }], ctorParameters: function () { return [{ type: i1.BaseUserService }, { type: i1.MissionService }, { type: i1.DomainService }, { type: i1.OrganisationService }, { type: i4$1.NgbModal }, { type: i3.TranslateService }]; } });
1129
+
1130
+ class TemplateComponent {
1131
+ constructor(route, fb, userService, spaceService, zoneService, location, hashtagService, translate, templateService) {
1132
+ this.route = route;
1133
+ this.fb = fb;
1134
+ this.userService = userService;
1135
+ this.spaceService = spaceService;
1136
+ this.zoneService = zoneService;
1137
+ this.location = location;
1138
+ this.hashtagService = hashtagService;
1139
+ this.translate = translate;
1140
+ this.templateService = templateService;
1141
+ this.updatedTemplate = new EventEmitter();
1142
+ this.createdTemplate = new EventEmitter();
1143
+ this.working = false;
1144
+ this.missionTimeStart = 12 * 60 * 60000; // midday in milliseconds
1145
+ this.missionTimeEnd = 12 * 60 * 60000;
1146
+ this.availableHashtags = [];
1147
+ this.addedHashtags = [];
1148
+ this.userService.isChanged.subscribe(() => {
1149
+ this.updateUserInfo();
1150
+ });
1151
+ }
1152
+ ngOnInit() {
1153
+ this.setup();
1154
+ const lang = this.translate.currentLang
1155
+ ? this.translate.currentLang
1156
+ : this.translate.defaultLang;
1157
+ /** Transforme '_fr' to 'fr' */
1158
+ this.currentLocale = stringLocaleToEnum(lang.slice(1)); // to match enum Locale
1159
+ this.locales = enumToArray(Locale);
1160
+ }
1161
+ async setup() {
1162
+ this.initForm();
1163
+ if (this.zoneID) {
1164
+ this.inputZone = await this.zoneService.getZone(this.zoneID);
1165
+ await this.setHashtags(this.inputZone.spaceID);
1166
+ }
1167
+ if (this.editTemplate) {
1168
+ // we are editing a template
1169
+ this.onSpaceClick();
1170
+ }
1171
+ await this.updateUserInfo();
1172
+ }
1173
+ async updateUserInfo() {
1174
+ if (this.userService.cu) {
1175
+ this.availableLevels =
1176
+ this.userService.getAvalableLevelsForCurrentUser();
1177
+ this.currentOrg = this.userService.currentOrganisation();
1178
+ this.availableSpaces = await this.spaceService.getSpacesForOrg(this.currentOrg.id);
1179
+ }
1180
+ }
1181
+ initForm() {
1182
+ if (this.editTemplate) {
1183
+ this.form = this.fb.group({
1184
+ title: [this.editTemplate.title],
1185
+ level: [this.editTemplate.level],
1186
+ organisationID: [this.editTemplate.organisationID],
1187
+ space: [this.editTemplate.spaceID],
1188
+ description: [this.editTemplate.description],
1189
+ zone: [
1190
+ this.editTemplate.zoneID,
1191
+ Validators.required,
1192
+ ],
1193
+ locale: [this.editTemplate.locale],
1194
+ });
1195
+ if (this.editTemplate.startDateTime) {
1196
+ const date = DateTime.fromISO(this.editTemplate.startDateTime);
1197
+ this.missionTimeStart = (date.hour * 60 + date.minute) * 60 * 1000;
1198
+ this.startDate = date.toMillis() - this.missionTimeStart;
1199
+ }
1200
+ if (this.editTemplate.endDateTime) {
1201
+ const date = DateTime.fromISO(this.editTemplate.endDateTime);
1202
+ this.missionTimeEnd = (date.hour * 60 + date.minute) * 60 * 1000;
1203
+ this.endDate = date.toMillis() - this.missionTimeEnd;
1204
+ }
1205
+ }
1206
+ else {
1207
+ this.form = this.fb.group({
1208
+ title: [""],
1209
+ level: [LevelStatus.MINIMUM],
1210
+ organisationID: this.currentOrg.id,
1211
+ space: this.inputZone ? this.inputZone.spaceID : [null],
1212
+ description: [null],
1213
+ zone: [
1214
+ this.inputZone ? this.inputZone.id : null,
1215
+ Validators.required,
1216
+ ],
1217
+ locale: [this.currentLocale],
1218
+ });
1219
+ }
1220
+ }
1221
+ async onSubmit() {
1222
+ this.working = true;
1223
+ const formValue = this.form.getRawValue();
1224
+ let startDateString;
1225
+ let endDateString;
1226
+ if (this.startDate) {
1227
+ const dateHourStartNumber = this.startDate + this.missionTimeStart;
1228
+ const startDate = DateTime.fromMillis(dateHourStartNumber);
1229
+ startDateString = startDate.toISO();
1230
+ }
1231
+ if (this.endDate) {
1232
+ const dateHourEndNumber = this.endDate + this.missionTimeEnd;
1233
+ const endDate = DateTime.fromMillis(dateHourEndNumber);
1234
+ endDateString = endDate.toISO();
1235
+ }
1236
+ try {
1237
+ if (this.editTemplate) {
1238
+ // update
1239
+ const template = {
1240
+ id: this.editTemplate.id,
1241
+ title: formValue.title,
1242
+ level: formValue.level,
1243
+ description: formValue.description,
1244
+ organisationID: formValue.organisationID,
1245
+ startDateTime: startDateString,
1246
+ endDateTime: endDateString,
1247
+ hashtags: this.addedHashtags.map((hashtag) => hashtag.id),
1248
+ locale: formValue.locale,
1249
+ };
1250
+ if (formValue.space) {
1251
+ template.spaceID = formValue.space;
1252
+ }
1253
+ if (formValue.zone) {
1254
+ template.zoneID = formValue.zone;
1255
+ }
1256
+ this.updatedTemplate.emit(template);
1257
+ }
1258
+ else {
1259
+ //create
1260
+ if (this.currentOrg) {
1261
+ const template = {
1262
+ title: formValue.title,
1263
+ organisationID: this.currentOrg.id,
1264
+ level: formValue.level,
1265
+ description: formValue.description,
1266
+ startDateTime: startDateString,
1267
+ endDateTime: endDateString,
1268
+ hashtags: this.addedHashtags.map((hashtag) => hashtag.id),
1269
+ locale: formValue.locale,
1270
+ };
1271
+ if (formValue.space) {
1272
+ template.spaceID = formValue.space;
1273
+ }
1274
+ if (formValue.zone) {
1275
+ template.zoneID = formValue.zone;
1276
+ }
1277
+ this.createdTemplate.emit(template);
1278
+ }
1279
+ }
1280
+ }
1281
+ catch (error) {
1282
+ console.error(error);
1283
+ }
1284
+ }
1285
+ onCancel() {
1286
+ this.form = null;
1287
+ if (this.editTemplate) {
1288
+ this.updatedTemplate.emit(null);
1289
+ }
1290
+ else {
1291
+ this.createdTemplate.emit(null);
1292
+ }
1293
+ }
1294
+ get title() {
1295
+ return this.form.get("title");
1296
+ }
1297
+ get spaceID() {
1298
+ return this.form.get("space");
1299
+ }
1300
+ async onSpaceClick() {
1301
+ const zones = await this.zoneService.getZonesBySpace(this.spaceID.value);
1302
+ const museumZones = zones.filter((zone) => zone.isMuseumVisitZone);
1303
+ this.zonesForSpace = sortAlphabeticallyOnName(museumZones);
1304
+ await this.setHashtags(this.spaceID.value);
1305
+ }
1306
+ onHashtagClick(hashtag) {
1307
+ if (!this.addedHashtags.includes(hashtag)) {
1308
+ this.addedHashtags.push(hashtag);
1309
+ }
1310
+ else {
1311
+ this.addedHashtags.splice(this.addedHashtags.indexOf(hashtag), 1);
1312
+ }
1313
+ }
1314
+ async setHashtags(spaceID) {
1315
+ this.availableHashtags = await this.hashtagService.getHashtagsForSpace(spaceID);
1316
+ }
1317
+ }
1318
+ TemplateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TemplateComponent, deps: [{ token: i2$1.ActivatedRoute }, { token: i2.FormBuilder }, { token: i1.BaseUserService }, { token: i1.SpaceService }, { token: i1.ZoneService }, { token: i4.Location }, { token: i1.HashtagService }, { token: i3.TranslateService }, { token: i1.TemplateService }], target: i0.ɵɵFactoryTarget.Component });
1319
+ TemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: TemplateComponent, selector: "lib-template", inputs: { currentOrg: "currentOrg", editTemplate: "editTemplate", zoneID: "zoneID" }, outputs: { updatedTemplate: "updatedTemplate", createdTemplate: "createdTemplate" }, ngImport: i0, template: "<div class=\"form-container\" *ngIf=\"form\">\r\n <div>\r\n <h4>{{ 'Visit Template' | translate }}</h4>\r\n </div>\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n <div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Visit Title' | translate}} *</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\"\r\n placeholder=\"Edvard Munch - \u00AB Un po\u00E8me d\u2019amour, de vie et de mort \u00BB\"\r\n [class.is-invalid]=\"title.invalid && title.touched\" required\r\n formControlName=\"title\">\r\n </div>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Description' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <textarea class=\"form-control\" formControlName=\"description\" style=\"height:200px\"\r\n placeholder=\"Cette visite d\u20191h30 vous pr\u00E9sentera les \u0153uvres embl\u00E9matiques du c\u00E9l\u00E8bre peintre norv\u00E9gien Edvard Munch (1863-1944)...\"></textarea>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Language' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" formControlName=\"locale\">\r\n <option [ngValue]=\"null\">{{'Not applicable' | translate}}</option>\r\n <option *ngFor=\"let locale of locales\" [ngValue]=\"locale\">\r\n {{ locale }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Level' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"level\">\r\n <option *ngFor=\"let level of availableLevels\" [ngValue]=\"level\">\r\n {{ level }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized location' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"availableSpaces && !inputZone\">\r\n <select class=\"form-control\" required formControlName=\"space\" (change)=\"onSpaceClick()\">\r\n <option *ngFor=\"let space of availableSpaces\" [ngValue]=\"space.id\">\r\n {{ space.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!availableSpaces\">\r\n {{ 'No locations available' | translate}}\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"inputZone\">\r\n <input type=\"text\" class=\"form-control\" [value]=\"inputZone.space.name\" disabled>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized zone' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace && zonesForSpace.length > 0 && !inputZone\">\r\n <select class=\"form-control\" required formControlName=\"zone\">\r\n <option *ngFor=\"let zone of zonesForSpace\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace && zonesForSpace.length === 0 && !inputZone\">\r\n <p class=\"warning col-form-label\">{{\"No Museum Zones found for this location\"| translate}}</p>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"inputZone\">\r\n <input type=\"text\" class=\"form-control\" [value]=\"inputZone.name\" disabled>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Hashtags' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"spaceID.value\">\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length > 0\">{{'Available hashtags' | translate}}\r\n </p>\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length === 0\">{{'No hashtags created for this\r\n location' | translate}} </p>\r\n <div *ngIf=\"availableHashtags.length > 0\">\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li [class]=\"addedHashtags.includes(hashtag) ? 'keywordsItem added' : 'keywordsItem'\"\r\n *ngFor=\"let hashtag of availableHashtags\" (click)=\"onHashtagClick(hashtag)\"\r\n style=\"cursor: pointer;\"\r\n ngbTooltip=\"{{addedHashtags.includes(hashtag) ? ('Remove'|translate) : ('Add'|translate) }}\">\r\n {{hashtag.name}}</li>\r\n </div>\r\n </ul>\r\n <p class=\"keywordsRules\">{{'Added hashtags' | translate}} </p>\r\n <ul class=\"keywordsDisplay\">\r\n <div class=\"keywordsdisplayContainer\" *ngIf=\"addedHashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of addedHashtags\">{{ hashtag.name }}</li>\r\n </div>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!spaceID.value\">\r\n <p class=\"keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Start Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"startDate\" 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()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Start Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeStart\" [ngModelOptions]=\"{standalone: true}\">\r\n </ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'End Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"endDate\" ngbDatepicker\r\n #d2=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d2.toggle()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'End Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeEnd\" [ngModelOptions]=\"{standalone: true}\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"btn-control-div action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n [disabled]=\"this.working || form.invalid\">{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"this.working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n\r\n </form>\r\n</div>", styles: [".form-container{margin:2rem 0rem}.form-container .btn-control-div .btn{width:8rem}.warning{margin:0;color:red}.keywordsDisplay{min-height:40px}.keywordsRules{margin-bottom:2px}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px!important}\n"], components: [{ type: i4$1.NgbTimepicker, selector: "ngb-timepicker", inputs: ["meridian", "spinners", "seconds", "hourStep", "minuteStep", "secondStep", "readonlyInputs", "size"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "triggers", "container", "disableTooltip", "tooltipClass", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { type: i4$1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "translate": i3.TranslatePipe } });
1320
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: TemplateComponent, decorators: [{
1321
+ type: Component,
1322
+ args: [{ selector: 'lib-template', template: "<div class=\"form-container\" *ngIf=\"form\">\r\n <div>\r\n <h4>{{ 'Visit Template' | translate }}</h4>\r\n </div>\r\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\r\n <div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Visit Title' | translate}} *</label>\r\n <div class=\"col-sm-8\">\r\n <input type=\"text\" class=\"form-control\"\r\n placeholder=\"Edvard Munch - \u00AB Un po\u00E8me d\u2019amour, de vie et de mort \u00BB\"\r\n [class.is-invalid]=\"title.invalid && title.touched\" required\r\n formControlName=\"title\">\r\n </div>\r\n </div>\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Description' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <textarea class=\"form-control\" formControlName=\"description\" style=\"height:200px\"\r\n placeholder=\"Cette visite d\u20191h30 vous pr\u00E9sentera les \u0153uvres embl\u00E9matiques du c\u00E9l\u00E8bre peintre norv\u00E9gien Edvard Munch (1863-1944)...\"></textarea>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Language' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" formControlName=\"locale\">\r\n <option [ngValue]=\"null\">{{'Not applicable' | translate}}</option>\r\n <option *ngFor=\"let locale of locales\" [ngValue]=\"locale\">\r\n {{ locale }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Level' | translate}}</label>\r\n <div class=\"col-sm-8\">\r\n <select class=\"form-control\" required formControlName=\"level\">\r\n <option *ngFor=\"let level of availableLevels\" [ngValue]=\"level\">\r\n {{ level }}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized location' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"availableSpaces && !inputZone\">\r\n <select class=\"form-control\" required formControlName=\"space\" (change)=\"onSpaceClick()\">\r\n <option *ngFor=\"let space of availableSpaces\" [ngValue]=\"space.id\">\r\n {{ space.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!availableSpaces\">\r\n {{ 'No locations available' | translate}}\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"inputZone\">\r\n <input type=\"text\" class=\"form-control\" [value]=\"inputZone.space.name\" disabled>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{ 'Authorized zone' | translate }}*</label>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace && zonesForSpace.length > 0 && !inputZone\">\r\n <select class=\"form-control\" required formControlName=\"zone\">\r\n <option *ngFor=\"let zone of zonesForSpace\" [ngValue]=\"zone.id\">\r\n {{ zone.name }}\r\n </option>\r\n </select>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"zonesForSpace && zonesForSpace.length === 0 && !inputZone\">\r\n <p class=\"warning col-form-label\">{{\"No Museum Zones found for this location\"| translate}}</p>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"inputZone\">\r\n <input type=\"text\" class=\"form-control\" [value]=\"inputZone.name\" disabled>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Hashtags' | translate}}</label>\r\n <div class=\"col-sm-8\" *ngIf=\"spaceID.value\">\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length > 0\">{{'Available hashtags' | translate}}\r\n </p>\r\n <p class=\"keywordsRules\" *ngIf=\"availableHashtags.length === 0\">{{'No hashtags created for this\r\n location' | translate}} </p>\r\n <div *ngIf=\"availableHashtags.length > 0\">\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\">\r\n <li [class]=\"addedHashtags.includes(hashtag) ? 'keywordsItem added' : 'keywordsItem'\"\r\n *ngFor=\"let hashtag of availableHashtags\" (click)=\"onHashtagClick(hashtag)\"\r\n style=\"cursor: pointer;\"\r\n ngbTooltip=\"{{addedHashtags.includes(hashtag) ? ('Remove'|translate) : ('Add'|translate) }}\">\r\n {{hashtag.name}}</li>\r\n </div>\r\n </ul>\r\n <p class=\"keywordsRules\">{{'Added hashtags' | translate}} </p>\r\n <ul class=\"keywordsDisplay\">\r\n <div class=\"keywordsdisplayContainer\" *ngIf=\"addedHashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of addedHashtags\">{{ hashtag.name }}</li>\r\n </div>\r\n </ul>\r\n </div>\r\n </div>\r\n <div class=\"col-sm-8\" *ngIf=\"!spaceID.value\">\r\n <p class=\"keywordsRules\">{{'You need to choose the location first' | translate}} </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Start Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"startDate\" 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()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'Start Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeStart\" [ngModelOptions]=\"{standalone: true}\">\r\n </ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'End Date' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <input class=\"form-control\" placeholder=\"dd/mm/yyyy\" [(ngModel)]=\"endDate\" ngbDatepicker\r\n #d2=\"ngbDatepicker\" [ngModelOptions]=\"{standalone: true}\">\r\n <div class=\"input-group-append\">\r\n <button class=\"btn btn-outline-secondary calendar\" (click)=\"d2.toggle()\" type=\"button\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"form-group row\">\r\n <label class=\"col-sm-4 col-form-label\">{{'End Time' | translate}}</label>\r\n <div class=\"input-group col-sm-8\">\r\n <ngb-timepicker [(ngModel)]=\"missionTimeEnd\" [ngModelOptions]=\"{standalone: true}\"></ngb-timepicker>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n <div class=\"btn-control-div action-button-container\">\r\n <button type=\"submit\" class=\"btn btn-outline-primary rounded-pill action-button\"\r\n [disabled]=\"this.working || form.invalid\">{{'Save' | translate}}</button>\r\n <button type=\"button\" (click)=\"onCancel()\" [disabled]=\"this.working\"\r\n class=\"btn btn-outline-primary rounded-pill action-button\">{{'Cancel' | translate}}</button>\r\n </div>\r\n\r\n </form>\r\n</div>", styles: [".form-container{margin:2rem 0rem}.form-container .btn-control-div .btn{width:8rem}.warning{margin:0;color:red}.keywordsDisplay{min-height:40px}.keywordsRules{margin-bottom:2px}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px!important}\n"] }]
1323
+ }], ctorParameters: function () { return [{ type: i2$1.ActivatedRoute }, { type: i2.FormBuilder }, { type: i1.BaseUserService }, { type: i1.SpaceService }, { type: i1.ZoneService }, { type: i4.Location }, { type: i1.HashtagService }, { type: i3.TranslateService }, { type: i1.TemplateService }]; }, propDecorators: { currentOrg: [{
1324
+ type: Input
1325
+ }], editTemplate: [{
1326
+ type: Input
1327
+ }], zoneID: [{
1328
+ type: Input
1329
+ }], updatedTemplate: [{
1330
+ type: Output
1331
+ }], createdTemplate: [{
1332
+ type: Output
1333
+ }] } });
1334
+
1335
+ class CreateBatchComponent {
1336
+ constructor(missionService, userService, translate) {
1337
+ this.missionService = missionService;
1338
+ this.userService = userService;
1339
+ this.translate = translate;
1340
+ this.createdMissions = new EventEmitter();
1341
+ this.addedEmails = [];
1342
+ this.working = false;
1343
+ }
1344
+ ngOnInit() { }
1345
+ onAddEmail(value) {
1346
+ if (value) {
1347
+ if (validEmail(value)) {
1348
+ this.addedEmails.push(value);
1349
+ }
1350
+ else {
1351
+ alert("Please, enter a valid email address");
1352
+ }
1353
+ }
1354
+ }
1355
+ onDelete(index) {
1356
+ this.addedEmails.splice(index, 1);
1357
+ }
1358
+ onCancel() {
1359
+ this.createdMissions.emit(null);
1360
+ }
1361
+ async onCreateMissions() {
1362
+ const createdMissions = [];
1363
+ let user;
1364
+ this.working = true;
1365
+ await Promise.all(this.addedEmails.map(async (mail) => {
1366
+ user = await this.userService.profileForMail(mail);
1367
+ if (!user) {
1368
+ try {
1369
+ const profile = await this.userService.createUserAWSandProfile({
1370
+ email: mail,
1371
+ lastName: mail,
1372
+ firstName: "",
1373
+ phone: "",
1374
+ }, true);
1375
+ user = profile;
1376
+ }
1377
+ catch (error) {
1378
+ alert(`Error creating users: ${this.translate.instant(error)}`);
1379
+ this.working = false;
1380
+ return;
1381
+ }
1382
+ }
1383
+ if (user) {
1384
+ const missionInput = {
1385
+ organisationID: this.template.organisationID,
1386
+ orderedOrganisationID: this.template.organisationID,
1387
+ level: this.template.level,
1388
+ role: RoleStatus.VISITOR_MUSEUM,
1389
+ description: "Generated from template",
1390
+ userID: user.id,
1391
+ startDateTime: this.template.startDateTime,
1392
+ endDateTime: this.template.endDateTime,
1393
+ spaceID: this.template.spaceID,
1394
+ zoneID: this.template.zoneID,
1395
+ templateMissionID: this.template.id,
1396
+ hashtags: this.template.hashtags,
1397
+ };
1398
+ const mission = await this.missionService.create(missionInput);
1399
+ createdMissions.push(mission);
1400
+ }
1401
+ }));
1402
+ this.working = false;
1403
+ this.createdMissions.emit(createdMissions);
1404
+ this.addedEmails = [];
1405
+ }
1406
+ async handleFileInput(eventTarget) {
1407
+ const files = eventTarget.files;
1408
+ const uploaded = files.item(0);
1409
+ if (uploaded.name.includes(".csv")) {
1410
+ Papa.parse(uploaded, {
1411
+ complete: function onComplete(results) {
1412
+ for (const mail of results.data) {
1413
+ this.addedEmails.push(mail[0]);
1414
+ }
1415
+ console.log(this.addedEmails);
1416
+ // eslint-disable-next-line no-extra-bind
1417
+ }.bind(this),
1418
+ });
1419
+ }
1420
+ else {
1421
+ alert("Not a csv file");
1422
+ }
1423
+ }
1424
+ }
1425
+ CreateBatchComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: CreateBatchComponent, deps: [{ token: i1.MissionService }, { token: i1.BaseUserService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
1426
+ CreateBatchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: CreateBatchComponent, selector: "lib-create-batch", inputs: { template: "template" }, outputs: { createdMissions: "createdMissions" }, ngImport: i0, template: "<div>\r\n <h4>{{'Add email address' | translate}}</h4>\r\n <div class=\"row\">\r\n <input class=\"form-control custom-form\" #box (keyup.enter)=\"onAddEmail(box.value); box.value=''\"\r\n placeholder=\"me@example.com\">\r\n <div class=\"outer_circle\" style='margin-left: 1.1em;'>\r\n <button id='btn-icon' (click)=\"onAddEmail(box.value); box.value=''\"></button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mt-3\">\r\n <label for=\"file\" class=\"btn btn-label-file rounded-pill\">\r\n <input type=\"file\" id=\"file\" (change)=\"handleFileInput($event.target)\" />\r\n {{'Upload from csv' | translate}}</label>\r\n </div>\r\n\r\n <ul *ngIf=\"addedEmails.length > 0\">\r\n <li class=\"list_item\" *ngFor=\"let mail of addedEmails; index as index\">{{mail}}\r\n <div class=\"icon-container\" (click)=\"onDelete(index)\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </li>\r\n </ul>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div class=\"row action-button-container\">\r\n <button class=\"btn btn-outline-primary rounded-pill mr-2 mt-3 action-button\" (click)=\"onCreateMissions()\">\r\n {{'Create users' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill mr-2 mt-3 action-button\" (click)=\"onCancel()\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n\r\n</div>", styles: ["#btn-icon{width:30px;height:30px;background:url(../../../../assets/icons/plus.svg);border:none;vertical-align:middle}#btn-icon:hover{background:url(../../../../assets/icons/plus-over.svg)}#btn-icon[disabled]:hover{background:url(../../../../assets/icons/plus.svg)}.outer_circle{background-color:#ebebeb;border-radius:50%;width:32px;height:32px;padding:1px;margin-left:5px}.custom-form{width:80%}h4{color:var(--smarterplan-primary)}.pointer{cursor:pointer}.list_item{display:flex;font-size:1.1em}.icon-container{cursor:pointer;margin-left:5px}input[type=file]{display:none}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"], components: [{ type: i1.LoaderComponent, selector: "lib-loader" }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "translate": i3.TranslatePipe } });
1427
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: CreateBatchComponent, decorators: [{
1428
+ type: Component,
1429
+ args: [{ selector: 'lib-create-batch', template: "<div>\r\n <h4>{{'Add email address' | translate}}</h4>\r\n <div class=\"row\">\r\n <input class=\"form-control custom-form\" #box (keyup.enter)=\"onAddEmail(box.value); box.value=''\"\r\n placeholder=\"me@example.com\">\r\n <div class=\"outer_circle\" style='margin-left: 1.1em;'>\r\n <button id='btn-icon' (click)=\"onAddEmail(box.value); box.value=''\"></button>\r\n </div>\r\n </div>\r\n\r\n <div class=\"row mt-3\">\r\n <label for=\"file\" class=\"btn btn-label-file rounded-pill\">\r\n <input type=\"file\" id=\"file\" (change)=\"handleFileInput($event.target)\" />\r\n {{'Upload from csv' | translate}}</label>\r\n </div>\r\n\r\n <ul *ngIf=\"addedEmails.length > 0\">\r\n <li class=\"list_item\" *ngFor=\"let mail of addedEmails; index as index\">{{mail}}\r\n <div class=\"icon-container\" (click)=\"onDelete(index)\">\r\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\r\n </div>\r\n </li>\r\n </ul>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"working\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div class=\"row action-button-container\">\r\n <button class=\"btn btn-outline-primary rounded-pill mr-2 mt-3 action-button\" (click)=\"onCreateMissions()\">\r\n {{'Create users' | translate}}</button>\r\n <button class=\"btn btn-outline-primary rounded-pill mr-2 mt-3 action-button\" (click)=\"onCancel()\">\r\n {{'Cancel' | translate}}</button>\r\n </div>\r\n\r\n</div>", styles: ["#btn-icon{width:30px;height:30px;background:url(../../../../assets/icons/plus.svg);border:none;vertical-align:middle}#btn-icon:hover{background:url(../../../../assets/icons/plus-over.svg)}#btn-icon[disabled]:hover{background:url(../../../../assets/icons/plus.svg)}.outer_circle{background-color:#ebebeb;border-radius:50%;width:32px;height:32px;padding:1px;margin-left:5px}.custom-form{width:80%}h4{color:var(--smarterplan-primary)}.pointer{cursor:pointer}.list_item{display:flex;font-size:1.1em}.icon-container{cursor:pointer;margin-left:5px}input[type=file]{display:none}.form-group{margin:1.5rem 0}label.col-sm-4.col-form-label{width:200px;min-width:200px}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px}\n"] }]
1430
+ }], ctorParameters: function () { return [{ type: i1.MissionService }, { type: i1.BaseUserService }, { type: i3.TranslateService }]; }, propDecorators: { template: [{
1431
+ type: Input
1432
+ }], createdMissions: [{
1433
+ type: Output
1434
+ }] } });
1435
+
1436
+ class VisitorComponent {
1437
+ constructor(userService, missionService, router, translate, spaceService, zoneService, modalService, templateService) {
1438
+ this.userService = userService;
1439
+ this.missionService = missionService;
1440
+ this.router = router;
1441
+ this.translate = translate;
1442
+ this.spaceService = spaceService;
1443
+ this.zoneService = zoneService;
1444
+ this.modalService = modalService;
1445
+ this.templateService = templateService;
1446
+ this.editing = false;
1447
+ this.creating = false;
1448
+ this.isAddingBatch = false;
1449
+ this.allZoneTemplatesMap = new Map(); // zone=>its templates
1450
+ this.allTemplateMissionsMap = new Map(); // templateID, its derived Missions
1451
+ this.detailsForZones = [];
1452
+ this.csvHeaders = [
1453
+ "email",
1454
+ "user_status",
1455
+ "zone",
1456
+ "location",
1457
+ "start_date_time",
1458
+ "end_date_time",
1459
+ "access_level",
1460
+ ];
1461
+ this.loading = false;
1462
+ this.toDuplicate = false;
1463
+ this.userService.isChanged.subscribe(() => this.setup());
1464
+ }
1465
+ ngOnInit() {
1466
+ this.setup();
1467
+ }
1468
+ setup() {
1469
+ this.setupUser();
1470
+ this.setZonesTemplates();
1471
+ }
1472
+ async setZonesTemplates() {
1473
+ if (!this.currentOrg) {
1474
+ return;
1475
+ }
1476
+ this.loading = true;
1477
+ this.allZoneTemplatesMap = new Map();
1478
+ this.allTemplateMissionsMap = new Map();
1479
+ let locations = this.spaceService.locationsForUser;
1480
+ if (locations.length === 0) {
1481
+ locations = await this.spaceService.getLocationsForCurrentUser();
1482
+ }
1483
+ await Promise.all(locations.map(async (space) => {
1484
+ let zones = await this.zoneService.getZonesBySpace(space.id);
1485
+ zones = zones.filter((zone) => zone.isMuseumVisitZone);
1486
+ await Promise.all(zones.map(async (zone) => {
1487
+ const visitorsMissions = await this.missionService.getMissionsByZoneByRole(zone.id, RoleStatus.VISITOR_MUSEUM);
1488
+ let templates = await this.templateService.getTemplatesByZone(zone.id);
1489
+ templates = templates.filter((template) => !template.deletedAt);
1490
+ templates = templates.sort((a, b) =>
1491
+ // @ts-ignore
1492
+ // eslint-disable-next-line prettier/prettier
1493
+ new Date(b.startDateTime) - new Date(a.startDateTime));
1494
+ for (const template of templates) {
1495
+ const missionsFromTemplate = visitorsMissions.filter((mis) => mis.templateMissionID === template.id);
1496
+ this.allTemplateMissionsMap.set(template.id, missionsFromTemplate);
1497
+ }
1498
+ this.allZoneTemplatesMap.set(zone, templates);
1499
+ }));
1500
+ }));
1501
+ // sort list by zone name alphabetically
1502
+ this.allZoneTemplatesMapFiltered =
1503
+ new Map([...this.allZoneTemplatesMap.entries()].sort((a, b) => a[0].name.localeCompare(b[0].name)));
1504
+ this.loading = false;
1505
+ }
1506
+ setupUser() {
1507
+ this.currentOrg = this.userService.currentOrganisation();
1508
+ }
1509
+ onCreateTemplate() {
1510
+ this.creating = true;
1511
+ }
1512
+ async onDeleteMission(mission) {
1513
+ await this.missionService.softDeleteMission(mission.id);
1514
+ this.setZonesTemplates();
1515
+ }
1516
+ async onEditTemplate(template) {
1517
+ this.editing = true;
1518
+ this.templateToEdit = template;
1519
+ }
1520
+ onUpdatedEvent(isAdded) {
1521
+ this.editing = false;
1522
+ this.templateToEdit = null;
1523
+ this.isAddingBatch = false;
1524
+ this.chosenTemplate = null;
1525
+ if (isAdded) {
1526
+ this.setZonesTemplates();
1527
+ }
1528
+ }
1529
+ async onUpdatedTemplate(template) {
1530
+ this.loading = true;
1531
+ this.editing = false;
1532
+ this.templateToEdit = null;
1533
+ if (template) {
1534
+ if (this.toDuplicate) {
1535
+ // create new template
1536
+ delete template.id;
1537
+ await this.templateService.create(template);
1538
+ this.toDuplicate = false;
1539
+ await this.setZonesTemplates();
1540
+ return;
1541
+ }
1542
+ await this.templateService.update(template);
1543
+ await this.setZonesTemplates();
1544
+ // update related Missions
1545
+ const missionsForTemplate = await this.missionService.getMissionsByTemplate(template.id);
1546
+ await Promise.all(missionsForTemplate.map(async (mission) => {
1547
+ const missionUpdate = {
1548
+ id: mission.id,
1549
+ level: template.level,
1550
+ startDateTime: template.startDateTime,
1551
+ endDateTime: template.endDateTime,
1552
+ locale: template.locale,
1553
+ zoneID: template.zoneID,
1554
+ spaceID: template.spaceID,
1555
+ hashtags: template.hashtags,
1556
+ };
1557
+ await this.missionService.update(missionUpdate);
1558
+ }));
1559
+ }
1560
+ this.loading = false;
1561
+ }
1562
+ async onCreatedTemplate(template) {
1563
+ this.loading = true;
1564
+ this.creating = false;
1565
+ if (template) {
1566
+ await this.templateService.create(template);
1567
+ this.setZonesTemplates();
1568
+ }
1569
+ this.loading = false;
1570
+ }
1571
+ onToggleMissionsForZone(zoneID) {
1572
+ if (this.detailsForZones.includes(zoneID)) {
1573
+ const index = this.detailsForZones.indexOf(zoneID);
1574
+ this.detailsForZones.splice(index, 1);
1575
+ }
1576
+ else {
1577
+ this.detailsForZones.push(zoneID);
1578
+ }
1579
+ }
1580
+ onToggleTemplateDetails(template) {
1581
+ this.templateShowing =
1582
+ this.templateShowing === template.id ? null : template.id;
1583
+ }
1584
+ onAddNewTemplateToZone(zone) {
1585
+ this.zoneIDForNewTemplate = zone.id;
1586
+ this.creating = true;
1587
+ }
1588
+ async onArchiveTemplate(template) {
1589
+ const message = this.translate.instant("confirm.archiveTemplate");
1590
+ if (window.confirm(message)) {
1591
+ const missionsToDelete = this.allTemplateMissionsMap.get(template.id);
1592
+ await Promise.all(missionsToDelete.map(async (mission) => {
1593
+ await this.missionService.softDeleteMission(mission.id);
1594
+ }));
1595
+ await this.templateService.softDelete(template.id);
1596
+ this.setZonesTemplates();
1597
+ }
1598
+ }
1599
+ onGenerateBatch(template) {
1600
+ this.chosenTemplate = template;
1601
+ this.isAddingBatch = true;
1602
+ }
1603
+ generateCSVUsers(template) {
1604
+ const data = [];
1605
+ for (const mission of this.allTemplateMissionsMap.get(template.id)) {
1606
+ const user = new ProfileEntity(mission.user);
1607
+ data.push([
1608
+ user.email,
1609
+ mission.user.status,
1610
+ mission.zone.name,
1611
+ mission.space.name,
1612
+ mission.startDateTime,
1613
+ mission.endDateTime,
1614
+ mission.level,
1615
+ ]);
1616
+ }
1617
+ return data;
1618
+ }
1619
+ async onSendInvitation(template) {
1620
+ await Promise.all(this.allTemplateMissionsMap
1621
+ .get(template.id)
1622
+ .map(async (mission) => {
1623
+ if (mission.emailStatus !== EmailStatus.SENT) {
1624
+ await this.missionService.update({
1625
+ id: mission.id,
1626
+ emailStatus: EmailStatus.CREATION_TO_DELIVER,
1627
+ });
1628
+ }
1629
+ }));
1630
+ }
1631
+ async onSendUpdate(template) {
1632
+ await Promise.all(this.allTemplateMissionsMap
1633
+ .get(template.id)
1634
+ .map(async (mission) => {
1635
+ await this.missionService.update({
1636
+ id: mission.id,
1637
+ emailStatus: EmailStatus.UPDATE_TO_DELIVER,
1638
+ });
1639
+ }));
1640
+ }
1641
+ async onCancelTemplate(template) {
1642
+ const message = this.translate.instant("confirm.cancelTemplate");
1643
+ if (window.confirm(message)) {
1644
+ await Promise.all(this.allTemplateMissionsMap
1645
+ .get(template.id)
1646
+ .map(async (mission) => {
1647
+ await this.missionService.update({
1648
+ id: mission.id,
1649
+ emailStatus: EmailStatus.CANCELLATION_TO_DELIVER,
1650
+ deletedAt: Date.now(),
1651
+ });
1652
+ }));
1653
+ }
1654
+ }
1655
+ applyResultsSearchBar(results) {
1656
+ this.allZoneTemplatesMapFiltered = results || this.allZoneTemplatesMap;
1657
+ }
1658
+ onDeleteUsers(mis) {
1659
+ this.currentTemplateUsers = [];
1660
+ for (const mission of this.allTemplateMissionsMap.get(mis.id)) {
1661
+ this.currentTemplateUsers.push({
1662
+ mission,
1663
+ profile: new ProfileEntity(mission.user),
1664
+ checked: false,
1665
+ index: this.allTemplateMissionsMap.get(mis.id).indexOf(mission),
1666
+ });
1667
+ }
1668
+ this.modalRef = this.modalService.open(this.modal);
1669
+ }
1670
+ /**
1671
+ * Deletes mission of the user and checks if can hard delete the Profile (no other missions)
1672
+ */
1673
+ async onDeleteChosen() {
1674
+ const listToDelete = this.currentTemplateUsers.filter((object) => object.checked);
1675
+ await Promise.all(listToDelete.map(async (object) => {
1676
+ await this.missionService.softDeleteMission(object.mission.id);
1677
+ await this.userService.softDeleteUser(object.profile.id);
1678
+ this.allTemplateMissionsMap
1679
+ .get(object.mission.templateMissionID)
1680
+ .splice(object.index, 1);
1681
+ }));
1682
+ this.modalRef.close();
1683
+ }
1684
+ onDuplicateTemplate(template) {
1685
+ this.editing = true;
1686
+ this.templateToEdit = template;
1687
+ this.toDuplicate = true;
1688
+ }
1689
+ async onCleanTimeTemplate(template) {
1690
+ await this.templateService.update({
1691
+ id: template.id,
1692
+ realEndedAt: null,
1693
+ realStartedAt: null
1694
+ });
1695
+ await this.setZonesTemplates();
1696
+ }
1697
+ }
1698
+ VisitorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: VisitorComponent, deps: [{ token: i1.BaseUserService }, { token: i1.MissionService }, { token: i2$1.Router }, { token: i3.TranslateService }, { token: i1.SpaceService }, { token: i1.ZoneService }, { token: i4$1.NgbModal }, { token: i1.TemplateService }], target: i0.ɵɵFactoryTarget.Component });
1699
+ VisitorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: VisitorComponent, selector: "lib-visitor", viewQueries: [{ propertyName: "modal", first: true, predicate: ["deleteUsers"], descendants: true }], ngImport: i0, template: "<div class=\"dashboard-tab\">\r\n <div class=\"header-dashboard-tab\">\r\n <h3>{{'Museum Visitors' | translate}}</h3>\r\n <!-- <app-search-bar [searchable]=\"allZoneTemplatesMap\" objectType=\"TEMPLATE\"\r\n (searchEvent)=\"applyResultsSearchBar($event)\">\r\n </app-search-bar> -->\r\n <hr>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-md-8 col-lg-7\">\r\n <div class=\"row ml-0 mb-2\">\r\n <h4 class=\"header-small\">{{'Itineraries' | translate}}</h4>\r\n </div>\r\n <div class=\"row ml-0 mb-2\" *ngIf=\"!editing && !creating\">\r\n <button class=\"btn btn-outline-primary rounded-pill ml-3 add-button\" (click)=\"onCreateTemplate()\">\r\n {{'Create template for new itinerary' | translate}}</button>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div *ngIf=\"!editing && !creating\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let pair of allZoneTemplatesMapFiltered | keyvalue\">\r\n <h4>{{pair.key.name}} <span style=\"font-size:0.8em\"> - {{pair.key.space.name}}</span> </h4>\r\n <div class=\"d-flex justify-content-between align-items-center\"\r\n (click)=\"onToggleMissionsForZone(pair.key.id)\">\r\n <ng-container *ngIf=\"pair.value.length <= 1\">\r\n {{pair.value.length}} {{'visit template found' | translate}}\r\n </ng-container>\r\n <ng-container *ngIf=\"pair.value.length > 1\">\r\n {{pair.value.length}} {{'visit templates found' | translate}}\r\n </ng-container>\r\n <lib-chevron [conditionShowing]=\"detailsForZones.includes(pair.key.id)\"></lib-chevron>\r\n\r\n </div>\r\n <div *ngIf=\"detailsForZones.includes(pair.key.id)\">\r\n <button class=\"btn btn-outline-primary rounded-pill mt-3 mb-3 ml-2\"\r\n (click)=\"onAddNewTemplateToZone(pair.key)\">{{'Add new template' | translate}}</button>\r\n\r\n <ul class=\"container-fluid list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let template of pair.value\">\r\n <div class=\"d-flex justify-content-between align-items-center\"\r\n (click)=\"onToggleTemplateDetails(template)\">\r\n <h5>{{template.title}}</h5>\r\n <lib-chevron [conditionShowing]=\"templateShowing === template.id\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"templateShowing === template.id\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Description' | translate }}:\r\n {{ template.description}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Language' | translate }}:\r\n {{ template.locale ? template.locale : ('Not applicable' | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\"\r\n *ngIf=\"template.hashtags && template.hashtags.length> 0\">\r\n {{'Hashtags' | translate}}:\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\"\r\n *ngIf=\"template.hashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of template.hashtags\">{{\r\n hashtag | hashtagFromID | async }}</li>\r\n </div>\r\n </ul>\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate }}:\r\n {{ template.level}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Planned at' | translate }} :\r\n {{ template.startDateTime ? (template.startDateTime |\r\n timeDateString:\"day_time_zone\" | async) :\r\n \"No data\" | translate }} - \r\n {{ template.endDateTime ?\r\n (template.endDateTime | timeDateString:\"day_time_zone\" | async) : \"No data\" |\r\n translate}}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">\r\n {{'Effective start/end time ' | translate }}: \r\n {{ template.realStartedAt ? (template.realStartedAt |\r\n timeDateString:\"day_time_zone\" | async) : ('No data' | translate)}} / \r\n {{ template.realEndedAt ? (template.realEndedAt |\r\n timeDateString:\"day_time_zone\" | async) : ('No data' | translate)}}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\"\r\n *ngIf=\"allTemplateMissionsMap.get(template.id)\">\r\n {{'Visitors created' |\r\n translate}}:{{allTemplateMissionsMap.get(template.id).length}}\r\n <lib-csv-export [headers]=\"csvHeaders\" [title]=\"'Users'\"\r\n buttonLabel=\"Download users\" [rowsInput]=\"generateCSVUsers(template)\">\r\n </lib-csv-export>\r\n </li>\r\n \r\n </ul>\r\n <div class=\"action-button-container\">\r\n <div class=\"d-inline-block mr-2 action-button\" ngbDropdown\r\n #myDrop=\"ngbDropdown\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownManual\"\r\n ngbDropdownToggle>{{'Manage users' |\r\n translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownManual\">\r\n <button (click)=\"onGenerateBatch(template)\" ngbDropdownItem>\r\n {{'Create users from this template' | translate}}</button>\r\n <button (click)=\"onSendInvitation(template)\" ngbDropdownItem>\r\n {{'Send invitation to all users' | translate}}\r\n </button>\r\n <button (click)=\"onSendUpdate(template)\" ngbDropdownItem>\r\n {{'Send update to all users' | translate}}\r\n </button>\r\n <button (click)=\"onDeleteUsers(template)\" ngbDropdownItem>\r\n {{'Remove users' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"d-inline-block mr-2 action-button\" ngbDropdown\r\n #myDrop2=\"ngbDropdown\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdown2\"\r\n ngbDropdownToggle>{{'Manage template' |\r\n translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdown2\">\r\n <button (click)=\"onEditTemplate(template)\" ngbDropdownItem>\r\n {{'Edit template' | translate}}</button>\r\n <button (click)=\"onCleanTimeTemplate(template)\" ngbDropdownItem>\r\n {{'Clean effective times' | translate}}\r\n </button>\r\n <button (click)=\"onArchiveTemplate(template)\" ngbDropdownItem>\r\n {{'Archive template' | translate}}\r\n </button>\r\n <button (click)=\"onCancelTemplate(template)\" ngbDropdownItem>\r\n {{'Cancel visit' | translate}}\r\n </button>\r\n <button (click)=\"onDuplicateTemplate(template)\" ngbDropdownItem>\r\n {{'Duplicate' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- <button type=\"button\" class=\"btn btn-primary rounded-pill mr-2 ml-auto\"\r\n (click)=\"onEdit(mis)\">\r\n {{'Edit' | translate}}</button>\r\n <button class=\"btn btn-primary rounded-pill mt-3 mb-3 ml-auto\"\r\n (click)=\"onArchiveTemplate(mis)\">{{'Archive' | translate}}</button> -->\r\n </div>\r\n\r\n </li>\r\n </ul>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n <div *ngIf=\"editing\">\r\n <lib-template [editTemplate]=\"templateToEdit\" [currentOrg]=\"currentOrg\"\r\n (updatedTemplate)=\"onUpdatedTemplate($event)\"></lib-template>\r\n </div>\r\n <div *ngIf=\"creating\">\r\n <lib-template [currentOrg]=\"currentOrg\" [zoneID]=\"zoneIDForNewTemplate\"\r\n (createdTemplate)=\"onCreatedTemplate($event)\"></lib-template>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4 col-lg-5\" *ngIf=\"isAddingBatch\">\r\n <lib-create-batch [template]=\"chosenTemplate\" (createdMissions)=\"onUpdatedEvent($event)\"></lib-create-batch>\r\n </div>\r\n <ng-template #deleteUsers let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{\"Delete users\" | translate}}\r\n </h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modalRef.close()\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"column align-items-center\">\r\n <div class=\"row\" style=\"padding: 0 1.25rem;\">\r\n <ul class=\"container-fluid list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let object of currentTemplateUsers\">\r\n <input type=\"checkbox\" [(ngModel)]=\"object.checked\"> {{object.profile.email}}\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div class=\"row\" style=\"padding: 1.25rem;\">\r\n <button class=\"btn btn-outline-primary rounded-pill mr-4\" (click)=\"onDeleteChosen()\">{{\"Apply\" |\r\n translate}}\r\n </button>\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"modalRef.close()\">{{\"Cancel\" |\r\n translate}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</div>", styles: [".add-button{width:-moz-fit-content;width:fit-content;margin-left:.5rem}li.ml-4{margin-left:3rem}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px!important}\n"], components: [{ type: i1.LoaderComponent, selector: "lib-loader" }, { type: ChevronComponent, selector: "lib-chevron", inputs: ["conditionShowing"] }, { type: i1.CsvExportComponent, selector: "lib-csv-export", inputs: ["headers", "rowsInput", "getRows", "title", "buttonLabel"] }, { type: TemplateComponent, selector: "lib-template", inputs: ["currentOrg", "editTemplate", "zoneID"], outputs: ["updatedTemplate", "createdTemplate"] }, { type: CreateBatchComponent, selector: "lib-create-batch", inputs: ["template"], outputs: ["createdMissions"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4$1.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { type: i4$1.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { type: i4$1.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { type: i4$1.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["disabled"] }, { type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "translate": i3.TranslatePipe, "keyvalue": i4.KeyValuePipe, "async": i4.AsyncPipe, "hashtagFromID": i1.HashtagFromIdPipe, "timeDateString": i1.TimeDateToLocalStringPipe } });
1700
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: VisitorComponent, decorators: [{
1701
+ type: Component,
1702
+ args: [{ selector: 'lib-visitor', template: "<div class=\"dashboard-tab\">\r\n <div class=\"header-dashboard-tab\">\r\n <h3>{{'Museum Visitors' | translate}}</h3>\r\n <!-- <app-search-bar [searchable]=\"allZoneTemplatesMap\" objectType=\"TEMPLATE\"\r\n (searchEvent)=\"applyResultsSearchBar($event)\">\r\n </app-search-bar> -->\r\n <hr>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-md-8 col-lg-7\">\r\n <div class=\"row ml-0 mb-2\">\r\n <h4 class=\"header-small\">{{'Itineraries' | translate}}</h4>\r\n </div>\r\n <div class=\"row ml-0 mb-2\" *ngIf=\"!editing && !creating\">\r\n <button class=\"btn btn-outline-primary rounded-pill ml-3 add-button\" (click)=\"onCreateTemplate()\">\r\n {{'Create template for new itinerary' | translate}}</button>\r\n </div>\r\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\r\n <lib-loader></lib-loader>\r\n </div>\r\n <div *ngIf=\"!editing && !creating\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let pair of allZoneTemplatesMapFiltered | keyvalue\">\r\n <h4>{{pair.key.name}} <span style=\"font-size:0.8em\"> - {{pair.key.space.name}}</span> </h4>\r\n <div class=\"d-flex justify-content-between align-items-center\"\r\n (click)=\"onToggleMissionsForZone(pair.key.id)\">\r\n <ng-container *ngIf=\"pair.value.length <= 1\">\r\n {{pair.value.length}} {{'visit template found' | translate}}\r\n </ng-container>\r\n <ng-container *ngIf=\"pair.value.length > 1\">\r\n {{pair.value.length}} {{'visit templates found' | translate}}\r\n </ng-container>\r\n <lib-chevron [conditionShowing]=\"detailsForZones.includes(pair.key.id)\"></lib-chevron>\r\n\r\n </div>\r\n <div *ngIf=\"detailsForZones.includes(pair.key.id)\">\r\n <button class=\"btn btn-outline-primary rounded-pill mt-3 mb-3 ml-2\"\r\n (click)=\"onAddNewTemplateToZone(pair.key)\">{{'Add new template' | translate}}</button>\r\n\r\n <ul class=\"container-fluid list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let template of pair.value\">\r\n <div class=\"d-flex justify-content-between align-items-center\"\r\n (click)=\"onToggleTemplateDetails(template)\">\r\n <h5>{{template.title}}</h5>\r\n <lib-chevron [conditionShowing]=\"templateShowing === template.id\"></lib-chevron>\r\n </div>\r\n <div *ngIf=\"templateShowing === template.id\">\r\n <ul class=\"list-group list-group-flush\">\r\n <li class=\"list-group-item bg-transparent\">{{'Description' | translate }}:\r\n {{ template.description}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Language' | translate }}:\r\n {{ template.locale ? template.locale : ('Not applicable' | translate)}}</li>\r\n <li class=\"list-group-item bg-transparent\"\r\n *ngIf=\"template.hashtags && template.hashtags.length> 0\">\r\n {{'Hashtags' | translate}}:\r\n <ul class=\"keywordsDisplay no-border\">\r\n <div class=\"keywordsdisplayContainer\"\r\n *ngIf=\"template.hashtags.length> 0\">\r\n <li class=\"keywordsItem\" *ngFor=\"let hashtag of template.hashtags\">{{\r\n hashtag | hashtagFromID | async }}</li>\r\n </div>\r\n </ul>\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate }}:\r\n {{ template.level}}</li>\r\n <li class=\"list-group-item bg-transparent\">{{'Planned at' | translate }} :\r\n {{ template.startDateTime ? (template.startDateTime |\r\n timeDateString:\"day_time_zone\" | async) :\r\n \"No data\" | translate }} - \r\n {{ template.endDateTime ?\r\n (template.endDateTime | timeDateString:\"day_time_zone\" | async) : \"No data\" |\r\n translate}}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\">\r\n {{'Effective start/end time ' | translate }}: \r\n {{ template.realStartedAt ? (template.realStartedAt |\r\n timeDateString:\"day_time_zone\" | async) : ('No data' | translate)}} / \r\n {{ template.realEndedAt ? (template.realEndedAt |\r\n timeDateString:\"day_time_zone\" | async) : ('No data' | translate)}}\r\n </li>\r\n <li class=\"list-group-item bg-transparent\"\r\n *ngIf=\"allTemplateMissionsMap.get(template.id)\">\r\n {{'Visitors created' |\r\n translate}}:{{allTemplateMissionsMap.get(template.id).length}}\r\n <lib-csv-export [headers]=\"csvHeaders\" [title]=\"'Users'\"\r\n buttonLabel=\"Download users\" [rowsInput]=\"generateCSVUsers(template)\">\r\n </lib-csv-export>\r\n </li>\r\n \r\n </ul>\r\n <div class=\"action-button-container\">\r\n <div class=\"d-inline-block mr-2 action-button\" ngbDropdown\r\n #myDrop=\"ngbDropdown\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownManual\"\r\n ngbDropdownToggle>{{'Manage users' |\r\n translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdownManual\">\r\n <button (click)=\"onGenerateBatch(template)\" ngbDropdownItem>\r\n {{'Create users from this template' | translate}}</button>\r\n <button (click)=\"onSendInvitation(template)\" ngbDropdownItem>\r\n {{'Send invitation to all users' | translate}}\r\n </button>\r\n <button (click)=\"onSendUpdate(template)\" ngbDropdownItem>\r\n {{'Send update to all users' | translate}}\r\n </button>\r\n <button (click)=\"onDeleteUsers(template)\" ngbDropdownItem>\r\n {{'Remove users' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"d-inline-block mr-2 action-button\" ngbDropdown\r\n #myDrop2=\"ngbDropdown\">\r\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdown2\"\r\n ngbDropdownToggle>{{'Manage template' |\r\n translate}}</button>\r\n <div ngbDropdownMenu aria-labelledby=\"dropdown2\">\r\n <button (click)=\"onEditTemplate(template)\" ngbDropdownItem>\r\n {{'Edit template' | translate}}</button>\r\n <button (click)=\"onCleanTimeTemplate(template)\" ngbDropdownItem>\r\n {{'Clean effective times' | translate}}\r\n </button>\r\n <button (click)=\"onArchiveTemplate(template)\" ngbDropdownItem>\r\n {{'Archive template' | translate}}\r\n </button>\r\n <button (click)=\"onCancelTemplate(template)\" ngbDropdownItem>\r\n {{'Cancel visit' | translate}}\r\n </button>\r\n <button (click)=\"onDuplicateTemplate(template)\" ngbDropdownItem>\r\n {{'Duplicate' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <!-- <button type=\"button\" class=\"btn btn-primary rounded-pill mr-2 ml-auto\"\r\n (click)=\"onEdit(mis)\">\r\n {{'Edit' | translate}}</button>\r\n <button class=\"btn btn-primary rounded-pill mt-3 mb-3 ml-auto\"\r\n (click)=\"onArchiveTemplate(mis)\">{{'Archive' | translate}}</button> -->\r\n </div>\r\n\r\n </li>\r\n </ul>\r\n </div>\r\n </li>\r\n </ul>\r\n </div>\r\n <div *ngIf=\"editing\">\r\n <lib-template [editTemplate]=\"templateToEdit\" [currentOrg]=\"currentOrg\"\r\n (updatedTemplate)=\"onUpdatedTemplate($event)\"></lib-template>\r\n </div>\r\n <div *ngIf=\"creating\">\r\n <lib-template [currentOrg]=\"currentOrg\" [zoneID]=\"zoneIDForNewTemplate\"\r\n (createdTemplate)=\"onCreatedTemplate($event)\"></lib-template>\r\n </div>\r\n </div>\r\n <div class=\"col-md-4 col-lg-5\" *ngIf=\"isAddingBatch\">\r\n <lib-create-batch [template]=\"chosenTemplate\" (createdMissions)=\"onUpdatedEvent($event)\"></lib-create-batch>\r\n </div>\r\n <ng-template #deleteUsers let-modal>\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" id=\"modal-basic-title\">{{\"Delete users\" | translate}}\r\n </h4>\r\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modalRef.close()\">\r\n <span aria-hidden=\"true\">&times;</span>\r\n </button>\r\n </div>\r\n <div class=\"modal-body\">\r\n <div class=\"column align-items-center\">\r\n <div class=\"row\" style=\"padding: 0 1.25rem;\">\r\n <ul class=\"container-fluid list-group list-group-flush\">\r\n <li class=\"list-group-item\" *ngFor=\"let object of currentTemplateUsers\">\r\n <input type=\"checkbox\" [(ngModel)]=\"object.checked\"> {{object.profile.email}}\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div class=\"row\" style=\"padding: 1.25rem;\">\r\n <button class=\"btn btn-outline-primary rounded-pill mr-4\" (click)=\"onDeleteChosen()\">{{\"Apply\" |\r\n translate}}\r\n </button>\r\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"modalRef.close()\">{{\"Cancel\" |\r\n translate}}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n</div>", styles: [".add-button{width:-moz-fit-content;width:fit-content;margin-left:.5rem}li.ml-4{margin-left:3rem}.action-button-container{display:flex;justify-content:space-evenly}.action-button-container .action-button{width:145px!important}\n"] }]
1703
+ }], ctorParameters: function () { return [{ type: i1.BaseUserService }, { type: i1.MissionService }, { type: i2$1.Router }, { type: i3.TranslateService }, { type: i1.SpaceService }, { type: i1.ZoneService }, { type: i4$1.NgbModal }, { type: i1.TemplateService }]; }, propDecorators: { modal: [{
1704
+ type: ViewChild,
1705
+ args: ["deleteUsers"]
1706
+ }] } });
1707
+
1708
+ class AdminComponent {
1709
+ constructor(userService) {
1710
+ this.userService = userService;
1711
+ this.isSmarterPlanUser = false;
1712
+ this.isGuide = false;
1713
+ this.userService.isChanged.subscribe((isChanged) => {
1714
+ if (isChanged) {
1715
+ this.isSmarterPlanUser = this.userService.isSPAdmin();
1716
+ }
1717
+ });
1718
+ }
1719
+ ngOnInit() {
1720
+ this.isSmarterPlanUser = this.userService.isSPAdmin();
1721
+ this.isGuide = this.userService.isGuide();
1722
+ }
1723
+ getIcon(path, isActive) {
1724
+ const suffix = isActive ? "-over" : "";
1725
+ return `/icons/${path.join("/")}${suffix}.svg`;
1726
+ }
1727
+ }
1728
+ AdminComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: AdminComponent, deps: [{ token: i1.BaseUserService }], target: i0.ɵɵFactoryTarget.Component });
1729
+ AdminComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: AdminComponent, selector: "lib-admin", ngImport: i0, template: "<div class=\"container-fluid\">\n <div class=\"row\">\n <div class=\"d-none col-md-3 col-lg-2 d-md-block sidebar\">\n <ul class=\"nav nav-pills flex-column\">\n <li class=\"nav-item\"><a class=\"nav-link\" routerLink=\"/admin/users\" [routerLinkActive]=\"['active']\"\n #rlaUser=\"routerLinkActive\">\n <img class=\"big-icon\" [src]=\"getIcon(['menu', 'user'], rlaUser.isActive)\" />{{'Users' |\n translate}}</a></li>\n <li class=\"nav-item\" *ngIf=\"isSmarterPlanUser\"><a class=\"nav-link\" routerLink=\"/admin/clients\"\n [routerLinkActive]=\"['active']\" #rlaOrganization=\"routerLinkActive\">\n <img class=\"big-icon\"\n [src]=\"getIcon(['menu', 'organisation'], rlaOrganization.isActive)\" />{{'Clients' |\n translate}}</a></li>\n <li class=\"nav-item\" *ngIf=\"isSmarterPlanUser || isGuide\"><a class=\"nav-link\"\n routerLink=\"/admin/visitors\" [routerLinkActive]=\"['active']\" #rlaVisitor=\"routerLinkActive\">\n <img class=\"big-icon\" [src]=\"getIcon(['menu', 'user'], rlaVisitor.isActive)\" />\n {{'Museum Visitors' | translate }}</a></li>\n </ul>\n </div> <!-- ml-sm-auto -->\n <main role=\"main\" class=\"col-12 col-md-9 col-lg-10 px-md-4\">\n <router-outlet></router-outlet>\n </main>\n </div>\n</div>", styles: [""], directives: [{ type: i2$1.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo", "routerLink"] }, { type: i2$1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], pipes: { "translate": i3.TranslatePipe } });
1730
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: AdminComponent, decorators: [{
1731
+ type: Component,
1732
+ args: [{ selector: 'lib-admin', template: "<div class=\"container-fluid\">\n <div class=\"row\">\n <div class=\"d-none col-md-3 col-lg-2 d-md-block sidebar\">\n <ul class=\"nav nav-pills flex-column\">\n <li class=\"nav-item\"><a class=\"nav-link\" routerLink=\"/admin/users\" [routerLinkActive]=\"['active']\"\n #rlaUser=\"routerLinkActive\">\n <img class=\"big-icon\" [src]=\"getIcon(['menu', 'user'], rlaUser.isActive)\" />{{'Users' |\n translate}}</a></li>\n <li class=\"nav-item\" *ngIf=\"isSmarterPlanUser\"><a class=\"nav-link\" routerLink=\"/admin/clients\"\n [routerLinkActive]=\"['active']\" #rlaOrganization=\"routerLinkActive\">\n <img class=\"big-icon\"\n [src]=\"getIcon(['menu', 'organisation'], rlaOrganization.isActive)\" />{{'Clients' |\n translate}}</a></li>\n <li class=\"nav-item\" *ngIf=\"isSmarterPlanUser || isGuide\"><a class=\"nav-link\"\n routerLink=\"/admin/visitors\" [routerLinkActive]=\"['active']\" #rlaVisitor=\"routerLinkActive\">\n <img class=\"big-icon\" [src]=\"getIcon(['menu', 'user'], rlaVisitor.isActive)\" />\n {{'Museum Visitors' | translate }}</a></li>\n </ul>\n </div> <!-- ml-sm-auto -->\n <main role=\"main\" class=\"col-12 col-md-9 col-lg-10 px-md-4\">\n <router-outlet></router-outlet>\n </main>\n </div>\n</div>", styles: [""] }]
1733
+ }], ctorParameters: function () { return [{ type: i1.BaseUserService }]; } });
1734
+
1735
+ class GuideGuard {
1736
+ constructor(userService, router) {
1737
+ this.userService = userService;
1738
+ this.router = router;
1739
+ }
1740
+ async canActivate(route, state) {
1741
+ if (this.userService.isGuide() || this.userService.isSPAdmin()) {
1742
+ return true;
1743
+ }
1744
+ return this.router.parseUrl("/notauthorized");
1745
+ }
1746
+ }
1747
+ GuideGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: GuideGuard, deps: [{ token: i1.BaseUserService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
1748
+ GuideGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: GuideGuard, providedIn: 'root' });
1749
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: GuideGuard, decorators: [{
1750
+ type: Injectable,
1751
+ args: [{
1752
+ providedIn: 'root'
1753
+ }]
1754
+ }], ctorParameters: function () { return [{ type: i1.BaseUserService }, { type: i2$1.Router }]; } });
1755
+
1756
+ class SpAdminGuard {
1757
+ constructor(userService, router) {
1758
+ this.userService = userService;
1759
+ this.router = router;
1760
+ }
1761
+ canActivate() {
1762
+ let canGo = false;
1763
+ if (this.userService.cu) {
1764
+ canGo = this.userService.isSPAdmin();
1765
+ }
1766
+ if (canGo) {
1767
+ return true;
1768
+ }
1769
+ alert("You are not authorised to access this page");
1770
+ this.router.navigate([""]);
1771
+ return false;
1772
+ }
1773
+ }
1774
+ SpAdminGuard.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SpAdminGuard, deps: [{ token: i1.BaseUserService }, { token: i2$1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
1775
+ SpAdminGuard.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SpAdminGuard, providedIn: 'root' });
1776
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: SpAdminGuard, decorators: [{
1777
+ type: Injectable,
1778
+ args: [{
1779
+ providedIn: 'root'
1780
+ }]
1781
+ }], ctorParameters: function () { return [{ type: i1.BaseUserService }, { type: i2$1.Router }]; } });
1782
+
1783
+ const routes = [
1784
+ {
1785
+ path: "",
1786
+ component: AdminComponent,
1787
+ children: [
1788
+ { path: "users", component: UserComponent },
1789
+ {
1790
+ path: "visitors",
1791
+ children: [
1792
+ { path: "", component: VisitorComponent },
1793
+ { path: "template", component: TemplateComponent },
1794
+ ],
1795
+ canActivate: [GuideGuard]
1796
+ },
1797
+ {
1798
+ path: "clients",
1799
+ component: OrganisationComponent,
1800
+ canActivate: [SpAdminGuard]
1801
+ },
1802
+ { path: "", redirectTo: "users", pathMatch: "full" },
1803
+ ]
1804
+ },
1805
+ ];
1806
+ class AdminRoutingModule {
1807
+ }
1808
+ AdminRoutingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: AdminRoutingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1809
+ AdminRoutingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: AdminRoutingModule, imports: [i2$1.RouterModule], exports: [RouterModule] });
1810
+ AdminRoutingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: AdminRoutingModule, imports: [[RouterModule.forChild(routes)], RouterModule] });
1811
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: AdminRoutingModule, decorators: [{
1812
+ type: NgModule,
1813
+ args: [{
1814
+ imports: [RouterModule.forChild(routes)],
1815
+ exports: [RouterModule],
1816
+ }]
1817
+ }] });
1818
+
1819
+ class NameFromIdPipe {
1820
+ constructor(userService) {
1821
+ this.userService = userService;
1822
+ }
1823
+ async transform(userId) {
1824
+ if (NameFromIdPipe.cache[userId] !== undefined) {
1825
+ return new Promise((resolve) => {
1826
+ resolve(NameFromIdPipe.cache[userId]);
1827
+ });
1828
+ }
1829
+ const user = await this.userService.userFromUserID(userId);
1830
+ // @ts-ignore
1831
+ NameFromId.cache[userId] = `${user.displayName}`;
1832
+ return NameFromIdPipe.cache[userId];
1833
+ }
1834
+ }
1835
+ NameFromIdPipe.cache = {};
1836
+ NameFromIdPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NameFromIdPipe, deps: [{ token: i1.BaseUserService }], target: i0.ɵɵFactoryTarget.Pipe });
1837
+ NameFromIdPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NameFromIdPipe, name: "nameFromId" });
1838
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NameFromIdPipe, decorators: [{
1839
+ type: Pipe,
1840
+ args: [{
1841
+ name: 'nameFromId'
1842
+ }]
1843
+ }], ctorParameters: function () { return [{ type: i1.BaseUserService }]; } });
1844
+
1845
+ class NgxSmarterplanAdminModule {
1846
+ }
1847
+ NgxSmarterplanAdminModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NgxSmarterplanAdminModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1848
+ NgxSmarterplanAdminModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NgxSmarterplanAdminModule, declarations: [AdminComponent,
1849
+ UserComponent,
1850
+ VisitorComponent,
1851
+ OrganisationComponent,
1852
+ GuestLinkComponent,
1853
+ ChevronComponent,
1854
+ FormMissionComponent,
1855
+ UserMissionFormComponent,
1856
+ FormOrganisationComponent,
1857
+ DetailOrganisationComponent,
1858
+ CreateBatchComponent,
1859
+ NameFromIdPipe,
1860
+ TemplateComponent], imports: [ClipboardModule,
1861
+ NgbModule,
1862
+ CommonModule,
1863
+ FormsModule,
1864
+ ReactiveFormsModule,
1865
+ NgxSmarterplanCoreModule, i3.TranslateModule, AdminRoutingModule] });
1866
+ NgxSmarterplanAdminModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NgxSmarterplanAdminModule, imports: [[
1867
+ ClipboardModule,
1868
+ NgbModule,
1869
+ CommonModule,
1870
+ FormsModule,
1871
+ ReactiveFormsModule,
1872
+ NgxSmarterplanCoreModule,
1873
+ TranslateModule.forChild({
1874
+ extend: true
1875
+ }),
1876
+ AdminRoutingModule
1877
+ ]] });
1878
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: NgxSmarterplanAdminModule, decorators: [{
1879
+ type: NgModule,
1880
+ args: [{
1881
+ declarations: [
1882
+ AdminComponent,
1883
+ UserComponent,
1884
+ VisitorComponent,
1885
+ OrganisationComponent,
1886
+ GuestLinkComponent,
1887
+ ChevronComponent,
1888
+ FormMissionComponent,
1889
+ UserMissionFormComponent,
1890
+ FormOrganisationComponent,
1891
+ DetailOrganisationComponent,
1892
+ CreateBatchComponent,
1893
+ NameFromIdPipe,
1894
+ TemplateComponent,
1895
+ ],
1896
+ imports: [
1897
+ ClipboardModule,
1898
+ NgbModule,
1899
+ CommonModule,
1900
+ FormsModule,
1901
+ ReactiveFormsModule,
1902
+ NgxSmarterplanCoreModule,
1903
+ TranslateModule.forChild({
1904
+ extend: true
1905
+ }),
1906
+ AdminRoutingModule
1907
+ ],
1908
+ exports: []
1909
+ }]
1910
+ }] });
1911
+
1912
+ /*
1913
+ * Public API Surface of ngx-smarterplan-admin
1914
+ */
1915
+
1916
+ /**
1917
+ * Generated bundle index. Do not edit.
1918
+ */
1919
+
1920
+ export { NgxSmarterplanAdminModule, NgxSmarterplanAdminService };
1921
+ //# sourceMappingURL=smarterplan-ngx-smarterplan-admin.mjs.map