@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.
- package/README.md +24 -0
- package/esm2020/lib/admin/admin.component.mjs +33 -0
- package/esm2020/lib/chevron/chevron.component.mjs +19 -0
- package/esm2020/lib/guest-link/guest-link.component.mjs +62 -0
- package/esm2020/lib/guide.guard.mjs +25 -0
- package/esm2020/lib/name-from-id.pipe.mjs +29 -0
- package/esm2020/lib/ngx-smarterplan-admin-routing.module.mjs +47 -0
- package/esm2020/lib/ngx-smarterplan-admin.module.mjs +90 -0
- package/esm2020/lib/ngx-smarterplan-admin.service.mjs +14 -0
- package/esm2020/lib/organisation/organisation.component.mjs +166 -0
- package/esm2020/lib/sp-admin.guard.mjs +31 -0
- package/esm2020/lib/user/detail-organisation/detail-organisation.component.mjs +160 -0
- package/esm2020/lib/user/form-mission/form-mission.component.mjs +205 -0
- package/esm2020/lib/user/form-organisation/form-organisation.component.mjs +125 -0
- package/esm2020/lib/user/user-mission-form/user-mission-form.component.mjs +106 -0
- package/esm2020/lib/user/user.component.mjs +325 -0
- package/esm2020/lib/visitor/create-batch/create-batch.component.mjs +108 -0
- package/esm2020/lib/visitor/template/template.component.mjs +219 -0
- package/esm2020/lib/visitor/visitor.component.mjs +284 -0
- package/esm2020/public-api.mjs +6 -0
- package/esm2020/smarterplan-ngx-smarterplan-admin.mjs +5 -0
- package/fesm2015/smarterplan-ngx-smarterplan-admin.mjs +2026 -0
- package/fesm2015/smarterplan-ngx-smarterplan-admin.mjs.map +1 -0
- package/fesm2020/smarterplan-ngx-smarterplan-admin.mjs +1921 -0
- package/fesm2020/smarterplan-ngx-smarterplan-admin.mjs.map +1 -0
- package/lib/admin/admin.component.d.ts +13 -0
- package/lib/chevron/chevron.component.d.ts +9 -0
- package/lib/guest-link/guest-link.component.d.ts +20 -0
- package/lib/guide.guard.d.ts +11 -0
- package/lib/name-from-id.pipe.d.ts +11 -0
- package/lib/ngx-smarterplan-admin-routing.module.d.ts +7 -0
- package/lib/ngx-smarterplan-admin.module.d.ts +26 -0
- package/lib/ngx-smarterplan-admin.service.d.ts +6 -0
- package/lib/organisation/organisation.component.d.ts +53 -0
- package/lib/sp-admin.guard.d.ts +12 -0
- package/lib/user/detail-organisation/detail-organisation.component.d.ts +39 -0
- package/lib/user/form-mission/form-mission.component.d.ts +54 -0
- package/lib/user/form-organisation/form-organisation.component.d.ts +32 -0
- package/lib/user/user-mission-form/user-mission-form.component.d.ts +28 -0
- package/lib/user/user.component.d.ts +100 -0
- package/lib/visitor/create-batch/create-batch.component.d.ts +23 -0
- package/lib/visitor/template/template.component.d.ts +52 -0
- package/lib/visitor/visitor.component.d.ts +65 -0
- package/package.json +39 -0
- package/public-api.d.ts +2 -0
- 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\">×</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\"> \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\">×</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\"> \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\">×</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\">×</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
|