@edifice.io/client 2.0.0-develop-b2school.20250109175008 → 2.0.1-develop-hotfix.1736762895570

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/dist/index.js CHANGED
@@ -1,9 +1,14 @@
1
- var v = Object.defineProperty;
2
- var T = (o, e, t) => e in o ? v(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
- var n = (o, e, t) => T(o, typeof e != "symbol" ? e + "" : e, t);
1
+ var T = Object.defineProperty;
2
+ var F = (n, e, t) => e in n ? T(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
3
+ var u = (n, e, t) => F(n, typeof e != "symbol" ? e + "" : e, t);
4
4
  import axios from "axios";
5
5
  import { MimeTypeUtils } from "@edifice.io/utilities";
6
- const ERROR_CODE = {
6
+ const ReactionTypes = [
7
+ "REACTION_1",
8
+ "REACTION_2",
9
+ "REACTION_3",
10
+ "REACTION_4"
11
+ ], ERROR_CODE = {
7
12
  SUCCESS: "0000",
8
13
  UNKNOWN: "0010",
9
14
  NOT_INITIALIZED: "0020",
@@ -14,7 +19,7 @@ const ERROR_CODE = {
14
19
  TIME_OUT: "0070",
15
20
  MALFORMED_DATA: "0080",
16
21
  NOT_LOGGED_IN: "0090"
17
- }, APP$1 = {
22
+ }, APP$2 = {
18
23
  ADMIN: "admin",
19
24
  ARCHIVE: "archive",
20
25
  AUTH: "auth",
@@ -30,6 +35,7 @@ const ERROR_CODE = {
30
35
  WORKSPACE: "workspace",
31
36
  // -- a few others commonly used apps
32
37
  EXPLORER: "explorer",
38
+ HOMEWORKS: "homeworks",
33
39
  VIDEO: "video",
34
40
  MINDMAP: "mindmap",
35
41
  SCRAPBOOK: "scrapbook",
@@ -97,7 +103,7 @@ const ERROR_CODE = {
97
103
  };
98
104
  class Subscription {
99
105
  constructor(e, t) {
100
- n(this, "revoke");
106
+ u(this, "revoke");
101
107
  this._channel = e, this.revoke = this.setReceiver(
102
108
  (s) => t == null ? void 0 : t(s.data)
103
109
  );
@@ -115,7 +121,7 @@ class Subject {
115
121
  * => We maintain here channels for *sending* messages.
116
122
  * *Receiving* channels will be instantiated while subscribing.
117
123
  */
118
- n(this, "publishChannels", /* @__PURE__ */ new Map());
124
+ u(this, "publishChannels", /* @__PURE__ */ new Map());
119
125
  }
120
126
  getChannelName(e) {
121
127
  return "Subject:" + e;
@@ -150,9 +156,9 @@ const ASYNC_DATA_NAME = {
150
156
  class Promisified {
151
157
  constructor() {
152
158
  //-------------------------------------
153
- n(this, "_resolution");
154
- n(this, "_rejection");
155
- n(this, "_promise", new Promise((e, t) => {
159
+ u(this, "_resolution");
160
+ u(this, "_rejection");
161
+ u(this, "_promise", new Promise((e, t) => {
156
162
  this._resolution = e, this._rejection = t;
157
163
  }));
158
164
  }
@@ -169,8 +175,8 @@ class Promisified {
169
175
  class NotifyFramework {
170
176
  constructor() {
171
177
  //-------------------------------------
172
- n(this, "promises", {});
173
- n(this, "subject", new Subject());
178
+ u(this, "promises", {});
179
+ u(this, "subject", new Subject());
174
180
  }
175
181
  asyncData(e) {
176
182
  return typeof this.promises[e] > "u" && (this.promises[e] = new Promisified()), this.promises[e];
@@ -197,1241 +203,180 @@ class NotifyFramework {
197
203
  return this.subject;
198
204
  }
199
205
  }
200
- const notify = new NotifyFramework(), loadedScripts$1 = {};
201
- class Http {
202
- constructor(e) {
203
- // Axios automatically manages the XSRF-TOKEN cookie and the X-XSRF-TOKEN HTTP header.
204
- n(this, "axios");
205
- n(this, "_latestResponse");
206
- this.axios = axios.create(e);
207
- }
208
- setCdn(e) {
209
- e && XMLHttpRequest && !XMLHttpRequest.prototype.cdnUrl && (XMLHttpRequest.prototype.cdnUrl = e, XMLHttpRequest.prototype.baseOpen = XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.open = function() {
210
- const t = arguments[1];
211
- return t.startsWith("/infra/public") && (arguments[1] = e + t), /^\/([^\/]*)\/public/.test(t) && (arguments[1] = e + t), t.startsWith("/assets") && (arguments[1] = e + t), t == "/conf/public" && (arguments[1] = t), t.startsWith("http") && (arguments[1] = t), this.baseOpen.apply(this, arguments);
212
- });
213
- }
214
- // private toAxiosConfig(params?: IHttpParams): AxiosRequestConfig {
215
- toAxiosConfig(e) {
216
- if (e) {
217
- const t = Object.assign({}, this.axios.defaults);
218
- return e.headers && (t.headers && (t.headers = Object.assign({}, this.axios.defaults.headers)), Object.assign(t.headers, e.headers)), e.responseType && (t.responseType = e.responseType), e.queryParams && (t.params = Object.assign({}, e.queryParams)), t;
219
- } else
220
- return this.axios.defaults;
221
- }
222
- toCdnUrl(e) {
223
- const t = ConfigurationFrameworkFactory.instance().Platform.cdnDomain;
224
- if ((t == null ? void 0 : t.length) > 0 && e !== "/conf/public") {
225
- const s = "" + e;
226
- (s.startsWith("/infra/public") || s.startsWith("/assets") || /^\/([^\/]*)\/public/.test(s)) && (e = t + s);
227
- }
228
- return e;
229
- }
230
- mapAxiosError(e, t) {
231
- return e.response ? this._latestResponse = e.response : e.request ? this._latestResponse = {
232
- status: 408,
233
- statusText: ERROR_CODE.TIME_OUT
234
- } : this._latestResponse = {
235
- status: 500,
236
- statusText: ERROR_CODE.UNKNOWN
237
- }, !t || t.disableNotifications, this._latestResponse;
238
- }
239
- mapAxiosResponse(e, t) {
240
- return this._latestResponse = e, e.data;
241
- }
242
- get latestResponse() {
243
- return this._latestResponse;
244
- }
245
- isResponseError() {
246
- return this.latestResponse.status < 200 || this.latestResponse.status >= 300;
247
- }
248
- get(e, t) {
249
- return this.axios.get(this.toCdnUrl(e), this.toAxiosConfig(t)).then((s) => this.mapAxiosResponse(s, t)).catch((s) => this.mapAxiosError(s, t));
250
- }
251
- post(e, t, s) {
252
- return this.axios.post(e, t, this.toAxiosConfig(s)).then((r) => this.mapAxiosResponse(r, s)).catch((r) => this.mapAxiosError(r, s));
253
- }
254
- postFile(e, t, s) {
255
- const r = this.toAxiosConfig(s);
256
- return r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"], this.axios.post(e, t, r).then((i) => this.mapAxiosResponse(i, s)).catch((i) => this.mapAxiosError(i, s));
257
- }
258
- postJson(e, t, s) {
259
- const r = this.toAxiosConfig();
260
- return r.headers && (r.headers["Content-Type"] = "application/json"), this.axios.post(e, t, this.toAxiosConfig(s)).then((i) => this.mapAxiosResponse(i, s)).catch((i) => this.mapAxiosError(i, s));
261
- }
262
- put(e, t, s) {
263
- return this.axios.put(e, t, this.toAxiosConfig(s)).then((r) => this.mapAxiosResponse(r, s)).catch((r) => this.mapAxiosError(r, s));
264
- }
265
- /*
266
- putFile(url: string, data:FormData, opt?:any) {
267
- //TODO
268
- return this.axios.putFile(url, data, opt).then( r => this.mapAxiosResponse(r,params));
269
- }
270
- */
271
- putJson(e, t, s) {
272
- const r = this.toAxiosConfig(s);
273
- return r.headers && (r.headers["Content-Type"] = "application/json"), this.axios.put(e, t, r).then((i) => this.mapAxiosResponse(i, s)).catch((i) => this.mapAxiosError(i, s));
274
- }
275
- delete(e, t) {
276
- return this.axios.delete(e, this.toAxiosConfig(t)).then((s) => this.mapAxiosResponse(s, t)).catch((s) => this.mapAxiosError(s, t));
277
- }
278
- deleteJson(e, t) {
279
- return this.axios.delete(e, { data: t }).then((s) => this.mapAxiosResponse(s)).catch((s) => this.mapAxiosError(s));
280
- }
281
- getScript(e, t, s) {
282
- const r = s ?? "exports", i = this.toAxiosConfig(t);
283
- return i.headers && (i.headers.Accept = "application/javascript"), this.axios.get(this.toCdnUrl(e), i).then((u) => this.mapAxiosResponse(u, t)).then((u) => {
284
- try {
285
- const a = `"use strict";var ${r.split(".")[0]}={};${u};return ${r};`;
286
- return Function(a)();
287
- } catch {
288
- return u;
289
- }
290
- }).catch((u) => {
291
- throw this.mapAxiosError(u, t), u;
292
- });
293
- }
294
- loadScript(e, t) {
295
- return loadedScripts$1[e] ? Promise.resolve() : this.getScript(e, t).then((s) => {
296
- loadedScripts$1[e] = !0;
297
- });
298
- }
299
- }
300
- class TransportFramework {
301
- constructor() {
302
- n(this, "_http", new Http());
303
- }
304
- get http() {
305
- return this._http;
306
- }
307
- newHttpInstance(e) {
308
- return new Http(e);
309
- }
310
- }
311
- const transport = new TransportFramework();
312
- class ConfigurationFrameworkFactory {
313
- //-------------------------------------
206
+ const notify = new NotifyFramework();
207
+ class NotifyFrameworkFactory {
314
208
  static instance() {
315
- return configure;
209
+ return notify;
316
210
  }
317
211
  }
318
- const http$2 = transport.http;
319
- class Session {
320
- constructor() {
321
- n(this, "_me", null);
322
- n(this, "_currentLanguage", "");
323
- n(this, "_notLoggedIn", !0);
324
- n(this, "_description");
325
- n(this, "_profile");
326
- }
327
- get currentLanguage() {
328
- return this._currentLanguage;
329
- }
330
- get notLoggedIn() {
331
- return this._notLoggedIn;
212
+ const LAYER_NAME = {
213
+ WIDGETS: "widgets",
214
+ EXPLORER: "explorer",
215
+ TRANSPORT: "transport",
216
+ WEB_DATA: "webDataPipeline"
217
+ }, EVENT_NAME = {
218
+ USERPREF_CHANGED: "userprefChanged",
219
+ SEARCH_RESULTED: "searchResulted",
220
+ ERROR_OCCURED: "error",
221
+ DATA_TRACKED: "track"
222
+ };
223
+ class ServiceRegistry extends Map {
224
+ /** Register a service */
225
+ register({
226
+ application: e,
227
+ resourceType: t
228
+ }, s) {
229
+ this.set(`${e}:main`, s), this.set(`${e}:${t}`, s);
332
230
  }
333
- get description() {
334
- return this._description;
231
+ /** Lookup for a service */
232
+ findService(e, t) {
233
+ return this.lookupService(e, t);
335
234
  }
336
- get avatarUrl() {
337
- let e = this.description.photo;
338
- return (!e || e === "no-avatar.jpg" || e === "no-avatar.svg") && (e = ConfigurationFrameworkFactory.instance().Platform.theme.basePath + "/img/illustrations/no-avatar.svg"), e;
235
+ /** Lookup for a main service */
236
+ findMainService({ application: e }, t) {
237
+ return this.lookupService({ application: e, resourceType: "main" }, t);
339
238
  }
340
- get user() {
341
- return this._me;
239
+ /** Check if a service is registered. */
240
+ isRegistered({
241
+ application: e,
242
+ resourceType: t
243
+ }) {
244
+ return this.get(`${e}:${t}`) !== void 0;
342
245
  }
343
- get currentApp() {
344
- return configure.Platform.apps.currentApp;
246
+ /** Private lookup for a service */
247
+ lookupService({
248
+ application: e,
249
+ resourceType: t
250
+ }, s) {
251
+ const r = this.get(`${e}:${t}`);
252
+ if (r === void 0)
253
+ throw `Service not found: ${e}:${t}`;
254
+ return r(s);
345
255
  }
346
- async initialize() {
347
- return http$2.get("/auth/oauth2/userinfo").then((e) => {
348
- if (http$2.isResponseError() || typeof e == "string")
349
- throw ERROR_CODE.NOT_LOGGED_IN;
350
- return this.setCurrentModel(e), this._notLoggedIn ? this.loadDefaultLanguage() : this.loadUserLanguage();
351
- }).then((e) => (this.setCurrentLanguage(e), this.loadDescription())).then(() => this.getUserProfile()).then(() => {
352
- notify.onSessionReady().resolve(this._me);
353
- }).catch((e) => {
354
- if (e === ERROR_CODE.NOT_LOGGED_IN)
355
- return Promise.resolve();
356
- notify.onSessionReady().reject(e);
256
+ }
257
+ const f = class f {
258
+ //
259
+ // IMPLEMENTATION
260
+ //
261
+ constructor(e) {
262
+ //
263
+ // PROTECTED HELPERS
264
+ //
265
+ u(this, "checkHttpResponse", (e) => {
266
+ if (this.http.latestResponse.status >= 300)
267
+ throw this.http.latestResponse.statusText;
268
+ return e;
357
269
  });
270
+ this.context = e;
358
271
  }
359
- setCurrentModel(e) {
360
- this._me = e, this._notLoggedIn = !(e && e.sessionMetadata && e.sessionMetadata.userId);
361
- }
362
- ////////////////////////////////////////////////////////// Rights management
363
- hasWorkflow(e) {
364
- var t;
365
- return e === void 0 || ((t = this._me) == null ? void 0 : t.authorizedActions.findIndex((s) => s.name === e)) !== -1;
366
- }
367
- hasRight(e, t) {
368
- if (t === "owner")
369
- return e.owner && e.owner.userId === this._me.userId;
370
- const s = t.right || t, i = e.shared.filter((a) => (this._me.groupsIds || []).indexOf(a.groupId) !== -1 || a.userId === this._me.userId).find((a) => a[s] || a.manager) !== void 0, u = t.workflow ? this.hasWorkflow(t.workflow) : !0;
371
- return i && u;
372
- }
373
- ////////////////////////////////////////////////////////// Storage management
374
- get latestQuotaAndUsage() {
375
- return http$2.get(`/workspace/quota/user/${this._me.userId}`).then((e) => (this._description && (this._description.quota = e.quota, this._description.storage = e.storage), e)).catch(() => ({ quota: 0, storage: 0 }));
376
- }
377
- ////////////////////////////////////////////////////////// Language management
378
- setCurrentLanguage(e) {
379
- this._currentLanguage = e, notify.onLangReady().resolve(e);
380
- }
381
- loadDefaultLanguage() {
382
- return http$2.get("/locale").then((e) => e.locale).catch(() => this._currentLanguage);
383
- }
384
- ////////////////////////////////////////////////////////// Description management
385
- loadDescription() {
386
- return Promise.all([
387
- // FIXME The full user's description should be obtainable from a single endpoint in the backend.
388
- http$2.get("/userbook/api/person", {
389
- requestName: "refreshAvatar"
390
- }),
391
- http$2.get("/directory/userbook/" + this._me.userId)
392
- ]).then((e) => (e[0].status === "ok" && e[0].result && e[0].result.length > 0 ? this._description = e[0].result[0] : this._description = {}, this._description.type && !this._description.profiles && (this._description.profiles = this._description.type), Object.assign(this._description, e[1]), this._description));
393
- }
394
- get profile() {
395
- return this._profile;
396
- }
397
- getUserProfile() {
398
- return http$2.get("/userbook/api/person").then((e) => e.result).then((e) => this._profile = e[0].type);
399
- }
400
- loadUserLanguage() {
401
- return http$2.get("/userbook/preference/language").then((e) => {
402
- try {
403
- return JSON.parse(e.preference)["default-domain"];
404
- } catch {
405
- return this.loadDefaultLanguage();
406
- }
407
- }).catch(() => this.loadDefaultLanguage());
408
- }
409
- ////////////////////////////////////////////////////////// Email management
410
- getEmailValidationInfos() {
411
- return http$2.get("/directory/user/mailstate");
412
- }
413
- checkEmail(e) {
414
- return http$2.put("/directory/user/mailstate", { email: e });
272
+ get http() {
273
+ return this.context.http();
415
274
  }
416
- tryEmailValidation(e) {
417
- return http$2.post("/directory/user/mailstate", {
418
- key: e
275
+ async copy(e) {
276
+ const t = await this.http.post("/archive/duplicate", {
277
+ application: e.application,
278
+ resourceId: e.resourceId
419
279
  });
280
+ return this.checkHttpResponse(t);
420
281
  }
421
- ////////////////////////////////////////////////////////// Mobile management
422
- getMobileValidationInfos() {
423
- return http$2.get("/directory/user/mobilestate");
424
- }
425
- checkMobile(e) {
426
- return http$2.put("/directory/user/mobilestate", { mobile: e });
282
+ async publish(e) {
283
+ const t = new FormData();
284
+ return t.append("title", e.title), t.append("cover", e.cover), t.append("coverName", e.cover.name), t.append("coverType", e.cover.type), t.append("teacherAvatar", e.teacherAvatar), t.append(
285
+ "teacherAvatarName",
286
+ e.teacherAvatar.name || `teacherAvatar_${e.userId}`
287
+ ), t.append(
288
+ "teacherAvatarType",
289
+ e.teacherAvatar.type
290
+ ), t.append("language", e.language), e.activityType.forEach((i) => {
291
+ t.append("activityType[]", i);
292
+ }), e.subjectArea.forEach((i) => {
293
+ t.append("subjectArea[]", i);
294
+ }), e.age.forEach((i) => {
295
+ t.append("age[]", i.toString());
296
+ }), t.append("description", e.description), e.keyWords.split(",").forEach((i) => {
297
+ t.append("keyWords[]", i.trim());
298
+ }), t.append("licence", e.licence), t.append(
299
+ "pdfUri",
300
+ `${window.location.origin}${this.getPrintUrl(e.resourceEntId)}`
301
+ ), t.append(
302
+ "application",
303
+ e.application ? e.application : ""
304
+ ), t.append("resourceId", e.resourceId), t.append("teacherSchool", e.userStructureName), await this.http.post(
305
+ "/appregistry/library/resource",
306
+ t,
307
+ {
308
+ headers: { "Content-Type": "multipart/form-data" }
309
+ }
310
+ );
427
311
  }
428
- tryMobileValidation(e) {
429
- return http$2.post("/directory/user/mobilestate", {
430
- key: e
312
+ //
313
+ // FOLDER METHODS
314
+ //
315
+ async createContext(e) {
316
+ const t = await this.http.get("/explorer/context", {
317
+ queryParams: this.toQueryParams(e)
431
318
  });
319
+ return this.checkHttpResponse(t);
432
320
  }
433
- ////////////////////////////////////////////////////////// MFA management
434
- getMfaInfos() {
435
- return http$2.get("/auth/user/mfa/code");
436
- }
437
- tryMfaCode(e) {
438
- return http$2.post("/auth/user/mfa/code", { key: e });
439
- }
440
- }
441
- class SessionFramework {
442
- constructor() {
443
- n(this, "session", new Session());
444
- }
445
- initialize() {
446
- return this.session.initialize();
447
- }
448
- login(e, t, s, r) {
449
- const i = new FormData();
450
- return i.append("email", e), i.append("password", t), typeof s < "u" && i.append("rememberMe", "" + s), typeof r < "u" && i.append("secureLocation", "" + r), transport.http.post("/auth/login", i, {
451
- headers: { "content-type": "application/x-www-form-urlencoded" }
452
- }).finally(() => {
453
- switch (transport.http.latestResponse.status) {
454
- case 200:
455
- throw ERROR_CODE.MALFORMED_DATA;
321
+ async searchContext(e) {
322
+ const t = await this.http.get(
323
+ "/explorer/resources",
324
+ {
325
+ queryParams: this.toQueryParams(e)
456
326
  }
457
- });
327
+ );
328
+ return this.checkHttpResponse(t);
458
329
  }
459
- logout() {
460
- return transport.http.get("/auth/logout").finally(() => {
461
- });
330
+ async searchResource(e) {
331
+ const t = await this.http.get(
332
+ `/explorer/resources/${e.id}`,
333
+ {
334
+ queryParams: this.getResourceParams(e)
335
+ }
336
+ );
337
+ return this.checkHttpResponse(t);
462
338
  }
463
- }
464
- const session = new SessionFramework();
465
- class Theme {
466
- constructor() {
467
- n(this, "_conf");
468
- n(this, "_loaded");
469
- // legacy (readonly)
470
- n(this, "skinName", "");
471
- n(this, "themeName", "");
472
- n(this, "skin", "raw");
473
- n(this, "themeUrl", "/assets/themes/raw/default/");
474
- n(this, "templateOverrides", {});
475
- n(this, "portalTemplate", "/assets/themes/raw/portal.html");
476
- n(this, "basePath", "");
477
- n(this, "logoutCallback", "/");
478
- n(this, "skins", []);
479
- n(this, "is1D", !1);
480
- n(this, "is2D", !1);
481
- n(this, "_onSkinReady", notify.onSkinReady());
482
- n(this, "_onOverrideReady", notify.onOverridesReady());
339
+ async createFolder(e) {
340
+ const t = await this.http.post(
341
+ "/explorer/folders",
342
+ this.createFolderToBodyParams(e)
343
+ );
344
+ return this.checkHttpResponse(t);
483
345
  }
484
- initialize(e) {
485
- return notify.onSessionReady().promise.then(() => this.load(e));
346
+ async updateFolder(e) {
347
+ const t = await this.http.put(
348
+ `/explorer/folders/${e.folderId}`,
349
+ this.createFolderToBodyParams(e)
350
+ );
351
+ return this.checkHttpResponse(t);
486
352
  }
487
- get version() {
488
- return configure.Platform.deploymentTag;
353
+ async moveToFolder(e, t = !1) {
354
+ e.resourceIds = t ? await this.mapAssetIdToIds({
355
+ application: e.application,
356
+ assetIds: e.resourceIds
357
+ }) : e.resourceIds;
358
+ const s = await this.http.post(
359
+ `/explorer/folders/${e.folderId}/move`,
360
+ this.moveToBodyParams(e)
361
+ );
362
+ return this.checkHttpResponse(s);
489
363
  }
490
- get cdnDomain() {
491
- return configure.Platform.cdnDomain;
364
+ async listSubfolders(e) {
365
+ const t = await this.http.get(
366
+ `/explorer/folders/${e}`
367
+ );
368
+ return this.checkHttpResponse(t);
492
369
  }
493
- async onFullyReady() {
494
- return await this._loaded, this;
495
- }
496
- onSkinReady() {
497
- return this._onSkinReady.promise;
498
- }
499
- onOverrideReady() {
500
- return this._onOverrideReady.promise;
501
- }
502
- async getConf(e) {
503
- return this._conf = this._conf ?? await transport.http.getScript(
504
- "/assets/theme-conf.js",
505
- { queryParams: { v: e ?? this.version } },
506
- "exports.conf"
507
- ), this._conf;
508
- }
509
- load(e) {
510
- return e = e ?? this.version, this._loaded || (this._loaded = (session.session.notLoggedIn ? this.loadDisconnected(e) : this.loadConnected(e)).then(async () => {
511
- var s, r;
512
- const t = await this.listSkins();
513
- this.is1D = ((s = t.find((i) => i.child === this.skin)) == null ? void 0 : s.parent) === "panda", this.is2D = ((r = t.find((i) => i.child === this.skin)) == null ? void 0 : r.parent) === "theme-open-ent";
514
- })), this._loaded;
515
- }
516
- loadDisconnected(e) {
517
- return new Promise((t, s) => {
518
- transport.http.get("/skin", { queryParams: { v: this.version } }).then((r) => {
519
- this.skin = r.skin, this.themeUrl = `${this.cdnDomain}/assets/themes/${r.skin}/skins/default/`, this.basePath = this.themeUrl + "../../", this._onSkinReady.resolve(this), transport.http.get(`/assets/themes/${r.skin}/template/override.json`, {
520
- disableNotifications: !0,
521
- queryParams: { v: e }
522
- }).then((i) => {
523
- this.templateOverrides = i, this._onOverrideReady.resolve(i), t();
524
- }).catch((i) => {
525
- if (transport.http.latestResponse.status === 404)
526
- t();
527
- else
528
- throw i;
529
- });
530
- }).catch((r) => {
531
- this._onSkinReady.reject(r), this._onOverrideReady.reject(r), s();
532
- });
533
- });
534
- }
535
- loadConnected(e) {
536
- return new Promise((t, s) => {
537
- this.loadDefaultTheme(e).then(() => {
538
- this._onSkinReady.resolve(this), transport.http.get(`/assets/themes/${this.skin}/template/override.json`, {
539
- disableNotifications: !0,
540
- queryParams: { v: e }
541
- }).then((r) => {
542
- this.templateOverrides = r, this._onOverrideReady.resolve(r), t();
543
- }).catch((r) => {
544
- if (transport.http.latestResponse.status === 404)
545
- t(), this._onSkinReady.reject(r), this._onOverrideReady.reject(r);
546
- else
547
- throw r;
548
- });
549
- });
550
- });
551
- }
552
- /** Load the user's configured theme. */
553
- async loadDefaultTheme(e) {
554
- return session.session.notLoggedIn ? Promise.reject() : transport.http.get("/theme", { queryParams: { _: e } }).then((t) => {
555
- this.skinName = t.skinName, this.themeName = t.themeName, this.themeUrl = t.skin, this.basePath = `${this.cdnDomain}${this.themeUrl}../../`, this.skin = this.themeUrl.split("/assets/themes/")[1].split("/")[0], this.portalTemplate = `${this.cdnDomain}/assets/themes/${this.skin}/portal.html`, this.logoutCallback = t.logoutCallback;
556
- });
557
- }
558
- listThemes() {
559
- return transport.http.get("/themes");
560
- }
561
- async setDefaultTheme(e) {
562
- await transport.http.get(
563
- "/userbook/api/edit-userbook-info?prop=theme-" + this.skin + "&value=" + e._id
564
- ), await this.loadDefaultTheme(this.version);
565
- }
566
- listSkins() {
567
- return this.skins.length > 0 ? Promise.resolve(this.skins) : this.getConf().then((e) => {
568
- const t = e.overriding.find(
569
- (s) => s.child === this.skin
570
- );
571
- return t != null && t.group ? this.skins = this.skins.concat(
572
- e.overriding.filter((s) => s.group === t.group)
573
- ) : this.skins = this.skins.concat(e.overriding), this.skins;
574
- });
575
- }
576
- async getHelpPath() {
577
- const t = (await this.listSkins()).find((s) => s.child === this.skin);
578
- return (t == null ? void 0 : t.help) ?? "/help";
579
- }
580
- }
581
- const bundle$1 = {}, promises$1 = {}, defaultDiacriticsRemovalMap$1 = [
582
- {
583
- base: "A",
584
- letters: /[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g
585
- },
586
- { base: "AA", letters: /[\uA732]/g },
587
- { base: "AE", letters: /[\u00C6\u01FC\u01E2]/g },
588
- { base: "AO", letters: /[\uA734]/g },
589
- { base: "AU", letters: /[\uA736]/g },
590
- { base: "AV", letters: /[\uA738\uA73A]/g },
591
- { base: "AY", letters: /[\uA73C]/g },
592
- {
593
- base: "B",
594
- letters: /[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g
595
- },
596
- {
597
- base: "C",
598
- letters: /[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g
599
- },
600
- {
601
- base: "D",
602
- letters: /[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g
603
- },
604
- { base: "DZ", letters: /[\u01F1\u01C4]/g },
605
- { base: "Dz", letters: /[\u01F2\u01C5]/g },
606
- {
607
- base: "E",
608
- letters: /[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g
609
- },
610
- { base: "F", letters: /[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g },
611
- {
612
- base: "G",
613
- letters: /[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g
614
- },
615
- {
616
- base: "H",
617
- letters: /[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g
618
- },
619
- {
620
- base: "I",
621
- letters: /[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g
622
- },
623
- { base: "J", letters: /[\u004A\u24BF\uFF2A\u0134\u0248]/g },
624
- {
625
- base: "K",
626
- letters: /[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g
627
- },
628
- {
629
- base: "L",
630
- letters: /[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g
631
- },
632
- { base: "LJ", letters: /[\u01C7]/g },
633
- { base: "Lj", letters: /[\u01C8]/g },
634
- { base: "M", letters: /[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g },
635
- {
636
- base: "N",
637
- letters: /[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g
638
- },
639
- { base: "NJ", letters: /[\u01CA]/g },
640
- { base: "Nj", letters: /[\u01CB]/g },
641
- {
642
- base: "O",
643
- letters: /[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g
644
- },
645
- { base: "OI", letters: /[\u01A2]/g },
646
- { base: "OO", letters: /[\uA74E]/g },
647
- { base: "OU", letters: /[\u0222]/g },
648
- {
649
- base: "P",
650
- letters: /[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g
651
- },
652
- { base: "Q", letters: /[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g },
653
- {
654
- base: "R",
655
- letters: /[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g
656
- },
657
- {
658
- base: "S",
659
- letters: /[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g
660
- },
661
- {
662
- base: "T",
663
- letters: /[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g
664
- },
665
- { base: "TZ", letters: /[\uA728]/g },
666
- {
667
- base: "U",
668
- letters: /[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g
669
- },
670
- { base: "V", letters: /[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g },
671
- { base: "VY", letters: /[\uA760]/g },
672
- {
673
- base: "W",
674
- letters: /[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g
675
- },
676
- { base: "X", letters: /[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g },
677
- {
678
- base: "Y",
679
- letters: /[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g
680
- },
681
- {
682
- base: "Z",
683
- letters: /[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g
684
- },
685
- {
686
- base: "a",
687
- letters: /[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250]/g
688
- },
689
- { base: "aa", letters: /[\uA733]/g },
690
- { base: "ae", letters: /[\u00E6\u01FD\u01E3]/g },
691
- { base: "ao", letters: /[\uA735]/g },
692
- { base: "au", letters: /[\uA737]/g },
693
- { base: "av", letters: /[\uA739\uA73B]/g },
694
- { base: "ay", letters: /[\uA73D]/g },
695
- {
696
- base: "b",
697
- letters: /[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g
698
- },
699
- {
700
- base: "c",
701
- letters: /[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g
702
- },
703
- {
704
- base: "d",
705
- letters: /[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g
706
- },
707
- { base: "dz", letters: /[\u01F3\u01C6]/g },
708
- {
709
- base: "e",
710
- letters: /[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD]/g
711
- },
712
- { base: "f", letters: /[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g },
713
- {
714
- base: "g",
715
- letters: /[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g
716
- },
717
- {
718
- base: "h",
719
- letters: /[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g
720
- },
721
- { base: "hv", letters: /[\u0195]/g },
722
- {
723
- base: "i",
724
- letters: /[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g
725
- },
726
- { base: "j", letters: /[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g },
727
- {
728
- base: "k",
729
- letters: /[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g
730
- },
731
- {
732
- base: "l",
733
- letters: /[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g
734
- },
735
- { base: "lj", letters: /[\u01C9]/g },
736
- { base: "m", letters: /[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g },
737
- {
738
- base: "n",
739
- letters: /[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g
740
- },
741
- { base: "nj", letters: /[\u01CC]/g },
742
- {
743
- base: "o",
744
- letters: /[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g
745
- },
746
- { base: "oi", letters: /[\u01A3]/g },
747
- { base: "ou", letters: /[\u0223]/g },
748
- { base: "oo", letters: /[\uA74F]/g },
749
- {
750
- base: "p",
751
- letters: /[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g
752
- },
753
- { base: "q", letters: /[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g },
754
- {
755
- base: "r",
756
- letters: /[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g
757
- },
758
- {
759
- base: "s",
760
- letters: /[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g
761
- },
762
- {
763
- base: "t",
764
- letters: /[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g
765
- },
766
- { base: "tz", letters: /[\uA729]/g },
767
- {
768
- base: "u",
769
- letters: /[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g
770
- },
771
- { base: "v", letters: /[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g },
772
- { base: "vy", letters: /[\uA761]/g },
773
- {
774
- base: "w",
775
- letters: /[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g
776
- },
777
- { base: "x", letters: /[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g },
778
- {
779
- base: "y",
780
- letters: /[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g
781
- },
782
- {
783
- base: "z",
784
- letters: /[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g
785
- }
786
- ];
787
- class Idiom {
788
- translate(e, t) {
789
- e = e ?? "";
790
- let s = bundle$1[e] === void 0 ? e : bundle$1[e];
791
- if (t && typeof t == "object")
792
- for (let r in t)
793
- typeof t[r] < "u" && (s = s.replace(
794
- new RegExp("\\${" + r + "}", "g"),
795
- "" + t[r]
796
- ));
797
- return s;
798
- }
799
- addBundlePromise(e) {
800
- return this.loadBundlePromise(session.session.currentLanguage, e);
801
- }
802
- addBundle(e, t) {
803
- this.loadBundle(session.session.currentLanguage, e, t);
804
- }
805
- loadBundlePromise(e, t) {
806
- return this.loadBundle(e, t), promises$1[t];
807
- }
808
- loadBundle(e, t, s) {
809
- const r = promises$1[t];
810
- if (r)
811
- s && r.then(s).catch(s);
812
- else {
813
- const i = new Promisified();
814
- promises$1[t] = i.promise;
815
- const u = {};
816
- e && (u["Accept-Language"] = e), transport.http.get(t, { headers: u }).then((a) => {
817
- Object.assign(bundle$1, a), typeof s == "function" && s(), i.resolve();
818
- }).catch((a) => {
819
- typeof s == "function" && s(), i.reject();
820
- });
821
- }
822
- }
823
- addTranslations(e, t) {
824
- notify.onLangReady().promise.then((s) => {
825
- this.loadBundle(s, e + "/" + s + ".json", t);
826
- });
827
- }
828
- addAllTranslations(e) {
829
- return e && e.length > 0 ? notify.onLangReady().promise.then(
830
- (t) => Promise.all(
831
- e.map(
832
- (s) => this.loadBundlePromise(t, s + "/" + t + ".json")
833
- )
834
- )
835
- ).then(() => {
836
- }) : Promise.reject();
837
- }
838
- addKeys(e) {
839
- for (var t in e)
840
- typeof bundle$1[t] != "string" && (bundle$1[t] = e[t]);
841
- }
842
- removeAccents(e) {
843
- for (var t = 0; t < defaultDiacriticsRemovalMap$1.length; t++)
844
- e = e.replace(
845
- defaultDiacriticsRemovalMap$1[t].letters,
846
- defaultDiacriticsRemovalMap$1[t].base
847
- );
848
- return e;
849
- }
850
- }
851
- class UserPreferences {
852
- constructor() {
853
- //-------------------------------------
854
- n(this, "data", {});
855
- }
856
- get(e) {
857
- return this.data[e];
858
- }
859
- load(e, t) {
860
- return transport.http.get("/userbook/preference/" + e).then((s) => {
861
- try {
862
- return JSON.parse(s.preference);
863
- } catch {
864
- return t ?? {};
865
- }
866
- }).then((s) => (this.data[e] = s ?? {}, s));
867
- }
868
- update(e, t) {
869
- return t !== void 0 && (this.data[e] = t), this;
870
- }
871
- save(e) {
872
- return transport.http.putJson(
873
- "/userbook/preference/" + e,
874
- this.data[e]
875
- );
876
- }
877
- }
878
- class User {
879
- constructor() {
880
- //-------------------------------------
881
- n(this, "_me", null);
882
- n(this, "_keepOpenOnLogout", !1);
883
- n(this, "_preferences", new UserPreferences());
884
- n(this, "_bookmarkedApps", []);
885
- }
886
- get keepOpenOnLogout() {
887
- return this._keepOpenOnLogout;
888
- }
889
- get preferences() {
890
- return this._preferences;
891
- }
892
- get bookmarkedApps() {
893
- return this._bookmarkedApps;
894
- }
895
- initialize(e) {
896
- return this.loadPublicConf(), notify.onSessionReady().promise.then((t) => {
897
- t && this.setCurrentModel(t);
898
- });
899
- }
900
- setCurrentModel(e) {
901
- this._me = e, this._preferences = new UserPreferences(), this.loadBookmarks();
902
- }
903
- loadPublicConf() {
904
- return transport.http.get("/conf/public").then((e) => (this._keepOpenOnLogout = (e == null ? void 0 : e.keepOpenOnLogout) || !1, e));
905
- }
906
- /** Bookmarks : pinned apps */
907
- async loadBookmarks() {
908
- await transport.http.get("/userbook/preference/apps").then((e) => {
909
- e.preference || (e.preference = null);
910
- const t = JSON.parse(
911
- e.preference
912
- );
913
- let s;
914
- if (t && t.length && typeof t.concat == "function") {
915
- this._bookmarkedApps = t, s = {
916
- bookmarks: t.map((u) => u.name),
917
- applications: []
918
- }, transport.http.putJson("/userbook/preference/apps", s);
919
- return;
920
- } else
921
- s = t;
922
- s || (s = {
923
- bookmarks: [],
924
- applications: []
925
- });
926
- let r = !0;
927
- const i = [];
928
- s.bookmarks.forEach((u, a) => {
929
- const c = this._me.apps.find((h) => h.name === u);
930
- if (c) {
931
- let h = Object.assign({}, c);
932
- this._bookmarkedApps.push(h);
933
- } else
934
- i.push(u), r = !1;
935
- }), i.forEach((u) => {
936
- let a = s.bookmarks.indexOf(u);
937
- a !== -1 && s.bookmarks.splice(a, 1);
938
- }), r || transport.http.putJson("/userbook/preference/apps", s);
939
- });
940
- }
941
- loadAppPrefs(e) {
942
- return this.preferences.load(e, {});
943
- }
944
- saveAppPrefs(e) {
945
- return this.preferences.save(e);
946
- }
947
- loadLanguage() {
948
- return this.preferences.load("language", { "default-domain": session.session.currentLanguage }).then((e) => e["default-domain"]);
949
- }
950
- saveLanguage(e) {
951
- return this.preferences.update("language", { "default-domain": e }).save("language");
952
- }
953
- }
954
- const http$1 = transport == null ? void 0 : transport.http;
955
- class AppConf {
956
- constructor() {
957
- //-------------------------------------
958
- n(this, "_publicConf", {});
959
- n(this, "_currentApp");
960
- n(this, "_appConf", {});
961
- }
962
- /**
963
- * Get the currently initialized App.
964
- * @see getter SessionFramework.currentApp
965
- */
966
- get currentApp() {
967
- return this._currentApp ?? null;
968
- }
969
- setCurrentApp(e) {
970
- return this._currentApp = e, this;
971
- }
972
- async initialize(e, t = !1) {
973
- t || this.setCurrentApp(e), await Promise.all([this.getPublicConf(e), this.loadI18n(e)]);
974
- }
975
- async getPublicConf(e) {
976
- return this._publicConf[e] || (this._publicConf[e] = await http$1.get(`/${e}/conf/public`, {
977
- queryParams: { _: configure.Platform.deploymentTag }
978
- })), this._publicConf[e];
979
- }
980
- async getWebAppConf(e) {
981
- let t;
982
- return this._appConf[e] || (await http$1.get(
983
- "/applications-list"
984
- )).apps.forEach((r) => {
985
- if (r != null && r.prefix) {
986
- const i = r.prefix.replace("/", "");
987
- this._appConf[i] = r;
988
- } else r != null && r.name && r.name.toLowerCase() == e && (t = r);
989
- }), this._appConf[e] ?? t;
990
- }
991
- async loadI18n(e) {
992
- return await notify.onLangReady().promise, configure.Platform.idiom.addBundlePromise(`/${e}/i18n`);
993
- }
994
- }
995
- class Analytics {
996
- constructor() {
997
- //-------------------------------------
998
- n(this, "_status", "void");
999
- n(this, "_params");
1000
- }
1001
- get status() {
1002
- return this._status;
1003
- }
1004
- xiti() {
1005
- return this.parametersWithCheck("xiti", !1);
1006
- }
1007
- parameters(e) {
1008
- return this.parametersWithCheck(e, !0);
1009
- }
1010
- async parametersWithCheck(e, t) {
1011
- return this.initialize().promise.then((s) => !t || s.type === e || s.type === "multiple" ? s[e] : void 0);
1012
- }
1013
- /**
1014
- * This method loads the conf and waits for the user session to start.
1015
- * It can be called ASAP, but it will be automatically called if needed.
1016
- * @returns A promise of the end of the init process (it may throw errors)
1017
- * @throws ERROR_CODE.MALFORMED_DATA when config cannot be read.
1018
- */
1019
- initialize() {
1020
- return this._params || (this._params = notify.promisify(), this._status = "pending", Promise.all([
1021
- transport.http.get("/analyticsConf"),
1022
- //FIXME change servers config to only keep the "all-in-one" query to /analyticsConf.
1023
- transport.http.get("/xiti/config")
1024
- ]).then(async (e) => {
1025
- var t;
1026
- if (!e || !e[0] || !e[0].type)
1027
- throw ERROR_CODE.MALFORMED_DATA;
1028
- e[1] && e[1].active && (e[0].xiti = await this.initializeXiti(e[1])), (t = this._params) == null || t.resolve(e[0]), this._status = "ready";
1029
- }).catch((e) => {
1030
- var t;
1031
- throw this._status = "failed", (t = this._params) == null || t.reject(), e;
1032
- })), this._params;
1033
- }
1034
- /** 2021 implementation of XiTi. */
1035
- async initializeXiti(e) {
1036
- if (!e.structureMap || !configure.Platform.apps.currentApp) return;
1037
- const t = await notify.onSessionReady().promise, s = session.session.description;
1038
- let r;
1039
- for (let h of t.structures) {
1040
- const l = e.structureMap[h];
1041
- if (l && l.collectiviteId && l.UAI) {
1042
- r = l;
1043
- break;
1044
- }
1045
- }
1046
- if (!r || !r.active) return;
1047
- const i = await configure.Platform.apps.getPublicConf(
1048
- configure.Platform.apps.currentApp
1049
- );
1050
- if (!i) return;
1051
- const u = i.xiti;
1052
- if (!u || !u.LIBELLE_SERVICE || !r.UAI) return;
1053
- function a(h) {
1054
- let l = "";
1055
- for (let E = 0; E < h.length; E++)
1056
- l += h.charCodeAt(E);
1057
- return l;
1058
- }
1059
- const c = {
1060
- Student: "ELEVE",
1061
- Teacher: "ENSEIGNANT",
1062
- Relative: "PARENT",
1063
- Personnel: "ADMIN_VIE_SCOL_TECH",
1064
- Guest: "AUTRE"
1065
- };
1066
- return {
1067
- LIBELLE_SERVICE: u.LIBELLE_SERVICE,
1068
- // Which property of LIBELLE_SERVICE to use depends on the frontend.
1069
- TYPE: u.OUTIL ? "TIERS" : "NATIF",
1070
- OUTIL: u.OUTIL ? u.OUTIL : "",
1071
- STRUCT_ID: r.collectiviteId,
1072
- STRUCT_UAI: r.UAI,
1073
- PROJET: r.projetId ? r.projetId : e.ID_PROJET,
1074
- EXPLOITANT: e.ID_EXPLOITANT,
1075
- PLATFORME: r.plateformeId ? r.plateformeId : e.ID_PLATEFORME,
1076
- ID_PERSO: a(t.userId),
1077
- PROFILE: s.profiles && s.profiles.length > 0 ? c[s.profiles[0]] ?? "" : ""
1078
- };
1079
- }
1080
- }
1081
- class ConfigurationFramework {
1082
- constructor() {
1083
- //-------------------------------------
1084
- n(this, "Platform", {
1085
- deploymentTag: "",
1086
- cdnDomain: "",
1087
- apps: new AppConf(),
1088
- theme: new Theme(),
1089
- analytics: new Analytics(),
1090
- idiom: new Idiom(),
1091
- listLanguages: () => transport.http.get("/languages")
1092
- });
1093
- n(this, "School", {
1094
- //apps; -> pinnedApps;
1095
- });
1096
- n(this, "User", new User());
1097
- }
1098
- async initialize(e, t) {
1099
- if (!e) {
1100
- const r = (h) => (h < 10 ? "0" : "") + h.toFixed(0), i = /* @__PURE__ */ new Date(), u = i.getFullYear(), a = i.getMonth() + 1, c = i.getDate();
1101
- e = `${u}${r(a)}${r(c)}`;
1102
- }
1103
- const s = e;
1104
- this.Platform.deploymentTag = e, typeof t == "string" && t.length > 0 && (this.Platform.cdnDomain = t), transport.http.setCdn(this.Platform.cdnDomain), await Promise.all([
1105
- this.Platform.theme.initialize(s),
1106
- notify.onSessionReady().promise.then(
1107
- (r) => this.Platform.idiom.addBundlePromise("/i18n")
1108
- ),
1109
- //TODO this.School.initialize( v ),
1110
- this.User.initialize(s)
1111
- ]);
1112
- }
1113
- // async mount(
1114
- // version?: string | null,
1115
- // cdnDomain?: string | null,
1116
- // ): Promise<void> {
1117
- // // If version is undefined, default to a new tag every day.
1118
- // if (!version) {
1119
- // const padWith0 = (val: number): string =>
1120
- // (val < 10 ? "0" : "") + val.toFixed(0);
1121
- // const now = new Date();
1122
- // const y = now.getFullYear();
1123
- // const m = now.getMonth() + 1;
1124
- // const d = now.getDate();
1125
- // version = `${y}${padWith0(m)}${padWith0(d)}`; //FIXME add ${h.toFixed(0)} to change the tag every 10 minutes
1126
- // }
1127
- // const v = version;
1128
- // this.Platform.deploymentTag = version;
1129
- // // Don't overwrite the CDN domain with a null or empty value.
1130
- // if (typeof cdnDomain === "string" && cdnDomain.length > 0) {
1131
- // this.Platform.cdnDomain = cdnDomain;
1132
- // }
1133
- // transport.http.setCdn(this.Platform.cdnDomain);
1134
- // //
1135
- // await this.Platform.idiom.addBundlePromise("/i18n");
1136
- // }
1137
- }
1138
- const configure = new ConfigurationFramework(), http = transport == null ? void 0 : transport.http;
1139
- var _;
1140
- const me = (_ = session == null ? void 0 : session.session) == null ? void 0 : _.user;
1141
- class Notification {
1142
- constructor(e) {
1143
- n(this, "_id");
1144
- n(this, "model");
1145
- e.reported = e.reporters && e.reporters.length > 0, this._id = e._id, this.model = e;
1146
- }
1147
- isUnread() {
1148
- var e;
1149
- return ((e = this.model.recipients) == null ? void 0 : e.find((t) => t.userId === me.userId)) !== void 0;
1150
- }
1151
- delete() {
1152
- return http.delete("/timeline/" + this._id);
1153
- }
1154
- discard() {
1155
- return http.put("/timeline/" + this._id);
1156
- }
1157
- report() {
1158
- return http.put("/timeline/" + this._id + "/report");
1159
- }
1160
- }
1161
- class TimelineApp {
1162
- constructor() {
1163
- //-------------------------------------
1164
- n(this, "_notifications", []);
1165
- n(this, "_notificationTypes", []);
1166
- // ex: ["BLOG"]
1167
- n(this, "_flashMessages", []);
1168
- n(this, "_pageNumber", 0);
1169
- n(this, "_lastPage", !1);
1170
- n(this, "_loading", !1);
1171
- n(this, "showMine", !1);
1172
- }
1173
- get notifications() {
1174
- return this._notifications;
1175
- }
1176
- get isLoading() {
1177
- return this._loading;
1178
- }
1179
- get page() {
1180
- return this._pageNumber;
1181
- }
1182
- get hasMorePage() {
1183
- return !this._lastPage;
1184
- }
1185
- get notificationTypes() {
1186
- return this._notificationTypes;
1187
- }
1188
- get selectedNotificationTypes() {
1189
- return this.preferences.type = this.preferences.type || [], this.preferences.type;
1190
- }
1191
- get preferences() {
1192
- return configure.User.preferences.get(APP$1.TIMELINE);
1193
- }
1194
- get flashMessages() {
1195
- return this._flashMessages;
1196
- }
1197
- savePreferences() {
1198
- return configure.User.saveAppPrefs(APP$1.TIMELINE);
1199
- }
1200
- resetPagination() {
1201
- this._pageNumber = 0, this._lastPage = !1, this._loading = !1;
1202
- }
1203
- initialize() {
1204
- return Promise.all([
1205
- configure.User.loadAppPrefs(APP$1.TIMELINE),
1206
- transport.http.get("/timeline/types")
1207
- ]).then((e) => {
1208
- this._notificationTypes = e[1];
1209
- });
1210
- }
1211
- loadNotifications(e) {
1212
- if (this._loading || this._lastPage)
1213
- return Promise.resolve();
1214
- e && (this._pageNumber++, this._lastPage = !1);
1215
- let t = this.selectedNotificationTypes;
1216
- if (t.length === 0)
1217
- return this._lastPage = !0, Promise.resolve();
1218
- let s = {
1219
- page: this.page,
1220
- mine: 1
1221
- };
1222
- return this.showMine || delete s.mine, this._loading = !0, transport.http.get(`/timeline/lastNotifications?type=${t.join("&type=")}`, {
1223
- queryParams: s
1224
- }).then(
1225
- (r) => {
1226
- if (this._loading = !1, r.status === "ok")
1227
- if (r.number && r.results) {
1228
- const i = r.results.filter(
1229
- (u) => this._notifications.findIndex(
1230
- (a) => a._id === u._id
1231
- ) === -1
1232
- ).map((u) => new Notification(u));
1233
- this._notifications = this._notifications.concat(i), this._pageNumber++;
1234
- } else
1235
- this._lastPage = !0;
1236
- }
1237
- ).catch((r) => {
1238
- this._loading = !1;
1239
- });
1240
- }
1241
- loadFlashMessages() {
1242
- return transport.http.get("/timeline/flashmsg/listuser").then((e) => {
1243
- this._flashMessages = e;
1244
- });
1245
- }
1246
- markAsRead(e) {
1247
- return transport.http.put("/timeline/flashmsg/" + e.id + "/markasread");
1248
- }
1249
- }
1250
- class ITimelineFactory {
1251
- //-------------------------------------
1252
- static createInstance() {
1253
- return new TimelineApp();
1254
- }
1255
- }
1256
- const ReactionTypes = [
1257
- "REACTION_1",
1258
- "REACTION_2",
1259
- "REACTION_3",
1260
- "REACTION_4"
1261
- ];
1262
- class NotifyFrameworkFactory {
1263
- static instance() {
1264
- return notify;
1265
- }
1266
- }
1267
- const LAYER_NAME = {
1268
- WIDGETS: "widgets",
1269
- EXPLORER: "explorer",
1270
- TRANSPORT: "transport",
1271
- WEB_DATA: "webDataPipeline"
1272
- }, EVENT_NAME = {
1273
- USERPREF_CHANGED: "userprefChanged",
1274
- SEARCH_RESULTED: "searchResulted",
1275
- ERROR_OCCURED: "error",
1276
- DATA_TRACKED: "track"
1277
- };
1278
- class ServiceRegistry extends Map {
1279
- /** Register a service */
1280
- register({
1281
- application: e,
1282
- resourceType: t
1283
- }, s) {
1284
- this.set(`${e}:main`, s), this.set(`${e}:${t}`, s);
1285
- }
1286
- /** Lookup for a service */
1287
- findService(e, t) {
1288
- return this.lookupService(e, t);
1289
- }
1290
- /** Lookup for a main service */
1291
- findMainService({ application: e }, t) {
1292
- return this.lookupService({ application: e, resourceType: "main" }, t);
1293
- }
1294
- /** Check if a service is registered. */
1295
- isRegistered({
1296
- application: e,
1297
- resourceType: t
1298
- }) {
1299
- return this.get(`${e}:${t}`) !== void 0;
1300
- }
1301
- /** Private lookup for a service */
1302
- lookupService({
1303
- application: e,
1304
- resourceType: t
1305
- }, s) {
1306
- const r = this.get(`${e}:${t}`);
1307
- if (r === void 0)
1308
- throw `Service not found: ${e}:${t}`;
1309
- return r(s);
1310
- }
1311
- }
1312
- const f = class f {
1313
- //
1314
- // IMPLEMENTATION
1315
- //
1316
- constructor(e) {
1317
- //
1318
- // PROTECTED HELPERS
1319
- //
1320
- n(this, "checkHttpResponse", (e) => {
1321
- if (this.http.latestResponse.status >= 300)
1322
- throw this.http.latestResponse.statusText;
1323
- return e;
1324
- });
1325
- this.context = e;
1326
- }
1327
- get http() {
1328
- return this.context.http();
1329
- }
1330
- async copy(e) {
1331
- const t = await this.http.post("/archive/duplicate", {
1332
- application: e.application,
1333
- resourceId: e.resourceId
1334
- });
1335
- return this.checkHttpResponse(t);
1336
- }
1337
- async publish(e) {
1338
- const t = new FormData();
1339
- return t.append("title", e.title), t.append("cover", e.cover), t.append("coverName", e.cover.name), t.append("coverType", e.cover.type), t.append("teacherAvatar", e.teacherAvatar), t.append(
1340
- "teacherAvatarName",
1341
- e.teacherAvatar.name || `teacherAvatar_${e.userId}`
1342
- ), t.append(
1343
- "teacherAvatarType",
1344
- e.teacherAvatar.type
1345
- ), t.append("language", e.language), e.activityType.forEach((i) => {
1346
- t.append("activityType[]", i);
1347
- }), e.subjectArea.forEach((i) => {
1348
- t.append("subjectArea[]", i);
1349
- }), e.age.forEach((i) => {
1350
- t.append("age[]", i.toString());
1351
- }), t.append("description", e.description), e.keyWords.split(",").forEach((i) => {
1352
- t.append("keyWords[]", i.trim());
1353
- }), t.append("licence", e.licence), t.append(
1354
- "pdfUri",
1355
- `${window.location.origin}${this.getPrintUrl(e.resourceEntId)}`
1356
- ), t.append(
1357
- "application",
1358
- e.application ? e.application : ""
1359
- ), t.append("resourceId", e.resourceId), t.append("teacherSchool", e.userStructureName), await this.http.post(
1360
- "/appregistry/library/resource",
1361
- t,
1362
- {
1363
- headers: { "Content-Type": "multipart/form-data" }
1364
- }
1365
- );
1366
- }
1367
- //
1368
- // FOLDER METHODS
1369
- //
1370
- async createContext(e) {
1371
- const t = await this.http.get("/explorer/context", {
1372
- queryParams: this.toQueryParams(e)
1373
- });
1374
- return this.checkHttpResponse(t);
1375
- }
1376
- async searchContext(e) {
1377
- const t = await this.http.get(
1378
- "/explorer/resources",
1379
- {
1380
- queryParams: this.toQueryParams(e)
1381
- }
1382
- );
1383
- return this.checkHttpResponse(t);
1384
- }
1385
- async searchResource(e) {
1386
- const t = await this.http.get(
1387
- `/explorer/resources/${e.id}`,
1388
- {
1389
- queryParams: this.getResourceParams(e)
1390
- }
1391
- );
1392
- return this.checkHttpResponse(t);
1393
- }
1394
- async createFolder(e) {
1395
- const t = await this.http.post(
1396
- "/explorer/folders",
1397
- this.createFolderToBodyParams(e)
1398
- );
1399
- return this.checkHttpResponse(t);
1400
- }
1401
- async updateFolder(e) {
1402
- const t = await this.http.put(
1403
- `/explorer/folders/${e.folderId}`,
1404
- this.createFolderToBodyParams(e)
1405
- );
1406
- return this.checkHttpResponse(t);
1407
- }
1408
- async moveToFolder(e, t = !1) {
1409
- e.resourceIds = t ? await this.mapAssetIdToIds({
1410
- application: e.application,
1411
- assetIds: e.resourceIds
1412
- }) : e.resourceIds;
1413
- const s = await this.http.post(
1414
- `/explorer/folders/${e.folderId}/move`,
1415
- this.moveToBodyParams(e)
1416
- );
1417
- return this.checkHttpResponse(s);
1418
- }
1419
- async listSubfolders(e) {
1420
- const t = await this.http.get(
1421
- `/explorer/folders/${e}`
1422
- );
1423
- return this.checkHttpResponse(t);
1424
- }
1425
- async deleteAll(e, t = !1) {
1426
- e.resourceIds = t ? await this.mapAssetIdToIds({
1427
- application: e.application,
1428
- assetIds: e.resourceIds
1429
- }) : e.resourceIds;
1430
- const s = await this.http.deleteJson(
1431
- "/explorer",
1432
- e
1433
- );
1434
- return this.checkHttpResponse(s);
370
+ async deleteAll(e, t = !1) {
371
+ e.resourceIds = t ? await this.mapAssetIdToIds({
372
+ application: e.application,
373
+ assetIds: e.resourceIds
374
+ }) : e.resourceIds;
375
+ const s = await this.http.deleteJson(
376
+ "/explorer",
377
+ e
378
+ );
379
+ return this.checkHttpResponse(s);
1435
380
  }
1436
381
  async trashAll({ resourceType: e, ...t }, s = !1) {
1437
382
  t.resourceIds = s ? await this.mapAssetIdToIds({
@@ -1469,7 +414,7 @@ const f = class f {
1469
414
  });
1470
415
  return t.map((r) => {
1471
416
  const i = s.resources.find(
1472
- (u) => u.assetId === r
417
+ (o) => o.assetId === r
1473
418
  );
1474
419
  if (i === void 0)
1475
420
  throw "explorer.assetid.notfound";
@@ -1535,10 +480,10 @@ const f = class f {
1535
480
  //
1536
481
  // STATIC REGISTRY
1537
482
  //
1538
- n(f, "registry", new ServiceRegistry()), // Expose some useful functions
1539
- n(f, "register", f.registry.register.bind(f.registry)), n(f, "findService", f.registry.findService.bind(f.registry)), n(f, "findMainService", f.registry.findMainService.bind(f.registry)), n(f, "isRegistered", f.registry.isRegistered.bind(f.registry));
483
+ u(f, "registry", new ServiceRegistry()), // Expose some useful functions
484
+ u(f, "register", f.registry.register.bind(f.registry)), u(f, "findService", f.registry.findService.bind(f.registry)), u(f, "findMainService", f.registry.findMainService.bind(f.registry)), u(f, "isRegistered", f.registry.isRegistered.bind(f.registry));
1540
485
  let ResourceService = f;
1541
- const APP = "scrapbook", RESOURCE = "scrapbook";
486
+ const APP$1 = "scrapbook", RESOURCE$1 = "scrapbook";
1542
487
  class ScrapbookResourceService extends ResourceService {
1543
488
  create(e) {
1544
489
  throw new Error("Method not implemented.");
@@ -1556,10 +501,10 @@ class ScrapbookResourceService extends ResourceService {
1556
501
  return this.checkHttpResponse(s), { thumbnail: t, entId: e.entId };
1557
502
  }
1558
503
  getResourceType() {
1559
- return RESOURCE;
504
+ return RESOURCE$1;
1560
505
  }
1561
506
  getApplication() {
1562
- return APP;
507
+ return APP$1;
1563
508
  }
1564
509
  getFormUrl(e) {
1565
510
  return e ? `/scrapbook?folderid=${e}#/create-scrapbook/` : "/scrapbook#/create-scrapbook/";
@@ -1578,1139 +523,827 @@ class ScrapbookResourceService extends ResourceService {
1578
523
  }
1579
524
  }
1580
525
  ResourceService.register(
1581
- { application: RESOURCE, resourceType: RESOURCE },
1582
- (o) => new ScrapbookResourceService(o)
526
+ { application: RESOURCE$1, resourceType: RESOURCE$1 },
527
+ (n) => new ScrapbookResourceService(n)
1583
528
  );
1584
- const globalCache = {}, mutexPromise = {};
1585
- class CacheService {
1586
- constructor(e) {
1587
- this.context = e;
1588
- }
1589
- get http() {
1590
- return this.context.http();
1591
- }
1592
- async fromCacheIfPossible(e, t, s) {
1593
- if (mutexPromise[e] && await mutexPromise[e], globalCache[e])
1594
- return globalCache[e];
1595
- try {
1596
- const r = t();
1597
- mutexPromise[e] = r;
1598
- const i = await r;
1599
- return s(i) && (globalCache[e] = i), i;
1600
- } catch (r) {
1601
- throw console.error(`Failed to retrieve value for: ${e}`, r), r;
1602
- }
1603
- }
1604
- clearCache(e) {
1605
- if (e)
1606
- delete globalCache[e];
1607
- else
1608
- for (const t in globalCache)
1609
- globalCache.hasOwnProperty(t) && delete globalCache[t];
1610
- }
1611
- async httpGet(e, t) {
1612
- return this.fromCacheIfPossible(
1613
- e,
1614
- async () => {
1615
- const s = await this.http.get(e, t), r = { ...this.http.latestResponse };
1616
- return { value: s, response: r };
1617
- },
1618
- ({ response: s }) => !(s.status < 200 || s.status >= 300)
1619
- );
1620
- }
1621
- async httpGetJson(e, t) {
1622
- const { response: s, value: r } = await this.httpGet(e, t);
1623
- if (s.status < 200 || s.status >= 300)
1624
- throw `Bad http status (${s.status}) for url: ${e}`;
1625
- return r;
1626
- }
1627
- }
1628
- class ConfService {
1629
- constructor(e) {
1630
- this.context = e;
1631
- }
1632
- get http() {
1633
- return this.context.http();
1634
- }
1635
- get cache() {
1636
- return this.context.cache();
1637
- }
1638
- get cdnDomain() {
1639
- return configure.Platform.cdnDomain;
1640
- }
1641
- get notify() {
1642
- return this.context.notify();
1643
- }
1644
- async getConf(e) {
1645
- const [t, s] = await Promise.all([
1646
- this.getThemeConf(),
1647
- this.getApplicationsList()
1648
- ]), [r, i] = await Promise.all([
1649
- this.getTheme({ conf: t, publicTheme: s === void 0 }),
1650
- this.getWebAppConf({ app: e, applications: s ?? [] })
1651
- ]), u = {
1652
- app: e,
1653
- applications: s ?? [],
1654
- conf: t,
1655
- currentApp: i,
1656
- theme: r
1657
- };
1658
- return this.notify.onAppConfReady().resolve(u), u;
529
+ const APP = "homeworks", RESOURCE = "homeworks";
530
+ class HomeworksResourceService extends ResourceService {
531
+ async create(e) {
532
+ const t = await this.getThumbnailPath(e.thumbnail), s = await this.http.post("/homeworks", {
533
+ title: e.name,
534
+ thumbnail: t,
535
+ description: e.description,
536
+ repeats: e.repeats
537
+ });
538
+ return this.checkHttpResponse(s), { thumbnail: t, entId: s._id };
1659
539
  }
1660
- async getPublicConf(e) {
1661
- const { response: t, value: s } = await this.cache.httpGet(
1662
- `/${e}/conf/public`,
540
+ async update(e) {
541
+ const t = await this.getThumbnailPath(e.thumbnail), s = await this.http.put(
542
+ `/homeworks/${e.entId}`,
1663
543
  {
1664
- queryParams: { _: configure.Platform.deploymentTag }
544
+ title: e.name,
545
+ thumbnail: t,
546
+ repeats: e.repeats
1665
547
  }
1666
548
  );
1667
- if (t.status < 200 || t.status >= 300)
1668
- throw ERROR_CODE.APP_NOT_FOUND;
1669
- return s;
1670
- }
1671
- getCdnUrl() {
1672
- }
1673
- async savePreference(e, t) {
1674
- this.http.putJson(`/userbook/preference/${e}`, t);
1675
- }
1676
- async getPreference(e) {
1677
- const t = await this.http.get(
1678
- `/userbook/preference/${e}`
1679
- );
1680
- return this.http.isResponseError() || typeof t == "string" ? {} : JSON.parse(t.preference);
1681
- }
1682
- async getThemeConf(e) {
1683
- return await this.http.getScript(
1684
- "/assets/theme-conf.js",
1685
- { queryParams: { v: e } },
1686
- "exports.conf"
1687
- );
1688
- }
1689
- async getApplicationsList() {
1690
- const e = await this.http.get(
1691
- "/applications-list"
1692
- );
1693
- if (!(this.http.isResponseError() || typeof e == "string"))
1694
- return e.apps;
1695
- }
1696
- async getWebAppConf({
1697
- app: e,
1698
- applications: t
1699
- }) {
1700
- return t.find((r) => {
1701
- if (r != null && r.prefix)
1702
- return (r == null ? void 0 : r.prefix.replace("/", "")) === e;
1703
- });
1704
- }
1705
- async getTheme({
1706
- version: e,
1707
- conf: t,
1708
- publicTheme: s
1709
- }) {
1710
- const { value: r } = await this.cache.httpGet("/theme", {
1711
- queryParams: { _: e }
1712
- }), i = s ? null : r, u = t == null ? void 0 : t.overriding.find(
1713
- (p) => (
1714
- // Public access => simply use the 1st override
1715
- i === null || p.child === i.themeName
1716
- )
1717
- ), a = (i == null ? void 0 : i.skinName) || u.skins[0], c = (i == null ? void 0 : i.skin) || `/assets/themes/${u.child}/skins/${a}/`, h = u.skins, l = u.bootstrapVersion.split("-").slice(-1)[0], E = u.parent === "panda";
1718
- return {
1719
- basePath: `${this.cdnDomain}${c}../../`,
1720
- bootstrapVersion: l,
1721
- is1d: E,
1722
- logoutCallback: (i == null ? void 0 : i.logoutCallback) || "/",
1723
- skin: u.child,
1724
- skinName: a,
1725
- skins: h,
1726
- themeName: u.child,
1727
- themeUrl: c,
1728
- npmTheme: u.npmTheme ?? void 0
1729
- };
1730
- }
1731
- async getLogoutCallback(e) {
1732
- const { response: t, value: s } = await this.cache.httpGet("/theme", {
1733
- queryParams: { _: e }
1734
- });
1735
- if (t.status < 200 || t.status >= 300)
1736
- throw ERROR_CODE.NOT_LOGGED_IN;
1737
- return s.logoutCallback;
1738
- }
1739
- }
1740
- class DirectoryService {
1741
- constructor(e) {
1742
- this.odeServices = e;
1743
- }
1744
- get http() {
1745
- return this.odeServices.http();
1746
- }
1747
- get cache() {
1748
- return this.odeServices.cache();
1749
- }
1750
- getAvatarUrl(e, t, s = "100x100") {
1751
- return t === "user" ? `/userbook/avatar/${e}?thumbnail=${s}` : "/assets/img/illustrations/group-avatar.svg";
1752
- }
1753
- getDirectoryUrl(e, t) {
1754
- return t === "user" ? `/userbook/annuaire#/${e}` : `/userbook/annuaire#/group-view/${e}`;
1755
- }
1756
- async getBookMarks() {
1757
- return (await this.cache.httpGetJson(
1758
- "/directory/sharebookmark/all"
1759
- )).map(({ id: t, name: s }) => ({
1760
- id: t,
1761
- displayName: s,
1762
- members: []
1763
- // this api does not return members
1764
- }));
1765
- }
1766
- async getBookMarkById(e) {
1767
- const { groups: t, id: s, name: r, users: i } = await this.http.get(
1768
- `/directory/sharebookmark/${e}`
1769
- );
1770
- return {
1771
- id: s,
1772
- displayName: r,
1773
- groups: t.map(({ name: u, id: a }) => ({
1774
- displayName: u,
1775
- id: a
1776
- })),
1777
- users: i.map(({ displayName: u, id: a, profile: c }) => ({
1778
- profile: c,
1779
- displayName: u,
1780
- // these info are missing from api
1781
- firstName: "",
1782
- lastName: "",
1783
- login: "",
1784
- id: a
1785
- }))
1786
- };
1787
- }
1788
- async saveBookmarks(e, {
1789
- bookmarks: t,
1790
- groups: s,
1791
- users: r
1792
- }) {
1793
- this.cache.clearCache("/directory/sharebookmark/all");
1794
- const i = r.map((p) => typeof p == "string" ? p : p.id), u = s.map((p) => typeof p == "string" ? p : p.id), a = t.map(async (p) => {
1795
- if (typeof p == "string") {
1796
- const { displayName: d, groups: g, id: A, users: m } = await this.getBookMarkById(p), b = m.map((F) => F.id), R = g.map((F) => F.id);
1797
- return {
1798
- displayName: d,
1799
- id: A,
1800
- members: [...R, ...b]
1801
- };
1802
- } else
1803
- return Promise.resolve(p);
1804
- }), h = (await Promise.all(a)).map((p) => p.members).reduce((p, d) => [...p, ...d], []), l = {
1805
- name: e,
1806
- members: [...i, ...u, ...h]
1807
- }, { id: E } = await this.http.postJson(
1808
- "/directory/sharebookmark",
1809
- l
1810
- );
1811
- return {
1812
- id: E,
1813
- displayName: e,
1814
- members: l.members
1815
- };
1816
- }
1817
- }
1818
- const loadedScripts = {};
1819
- class HttpService {
1820
- constructor(e, t) {
1821
- // Axios automatically manages the XSRF-TOKEN cookie and the X-XSRF-TOKEN HTTP header.
1822
- n(this, "axios");
1823
- n(this, "baseUrl");
1824
- n(this, "headers", {});
1825
- n(this, "_latestResponse");
1826
- this.context = e, this.axios = axios.create(t);
1827
- }
1828
- fixBaseUrl(e) {
1829
- return e.startsWith("http://") || e.startsWith("https://") ? e : this.baseUrl ? this.baseUrl.endsWith("/") || e.startsWith("/") ? `${this.baseUrl}${e}` : `${this.baseUrl}/${e}` : e;
1830
- }
1831
- useBaseUrl(e) {
1832
- return this.baseUrl = e, this;
549
+ return this.checkHttpResponse(s), { thumbnail: t, entId: e.entId };
1833
550
  }
1834
- useHeaders(e) {
1835
- return this.headers = e, this;
551
+ getResourceType() {
552
+ return RESOURCE;
1836
553
  }
1837
- setCdn(e) {
1838
- e && XMLHttpRequest && !XMLHttpRequest.prototype.cdnUrl && (XMLHttpRequest.prototype.cdnUrl = e, XMLHttpRequest.prototype.baseOpen = XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.open = function() {
1839
- const t = arguments[1];
1840
- return t.startsWith("/infra/public") && (arguments[1] = e + t), /^\/([^\/]*)\/public/.test(t) && (arguments[1] = e + t), t.startsWith("/assets") && (arguments[1] = e + t), t == "/conf/public" && (arguments[1] = t), t.startsWith("http") && (arguments[1] = t), this.baseOpen.apply(this, arguments);
1841
- });
554
+ getApplication() {
555
+ return APP;
1842
556
  }
1843
- // private toAxiosConfig(params?: IHttpParams): AxiosRequestConfig {
1844
- toAxiosConfig(e) {
1845
- if (e) {
1846
- const t = Object.assign({}, this.axios.defaults);
1847
- e.headers && (t.headers = Object.assign({}, this.axios.defaults.headers), Object.assign(t.headers, e.headers)), e.responseType && (t.responseType = e.responseType), e.queryParams && (t.params = Object.assign({}, e.queryParams));
1848
- const s = t.headers ?? {};
1849
- return t.headers = { ...s, ...this.headers }, t;
1850
- } else
1851
- return this.axios.defaults;
557
+ getFormUrl(e) {
558
+ return e ? `/homeworks?folderid=${e}#/create-homeworks/` : "/homeworks#/create-homeworks/";
1852
559
  }
1853
- toCdnUrl(e) {
1854
- e = this.fixBaseUrl(e);
1855
- const t = this.context.conf().getCdnUrl() || "";
1856
- if (t.length > 0 && e !== "/conf/public") {
1857
- const s = "" + e;
1858
- (s.startsWith("/infra/public") || s.startsWith("/assets") || /^\/([^\/]*)\/public/.test(s)) && (e = t + s);
1859
- }
1860
- return e;
560
+ getViewUrl(e) {
561
+ return `/homeworks#/view-homeworks/${e}`;
1861
562
  }
1862
- mapAxiosError(e, t) {
1863
- e.response ? this._latestResponse = e.response : e.request ? this._latestResponse = {
1864
- status: 408,
1865
- statusText: ERROR_CODE.TIME_OUT
1866
- } : this._latestResponse = {
1867
- status: 500,
1868
- statusText: ERROR_CODE.UNKNOWN
1869
- };
1870
- const { status: s, statusText: r, headers: i, data: u } = this._latestResponse;
1871
- return t != null && t.disableNotifications || notify.events().publish(LAYER_NAME.TRANSPORT, {
1872
- name: EVENT_NAME.ERROR_OCCURED,
1873
- data: {
1874
- params: t,
1875
- response: { status: s, statusText: r, headers: i },
1876
- payload: u
1877
- }
1878
- }), u;
563
+ getPrintUrl(e) {
564
+ return `/homeworks/print#/print-homeworks/${e}`;
1879
565
  }
1880
- mapAxiosResponse(e, t) {
1881
- return this._latestResponse = e, e.data;
566
+ getEditUrl(e) {
567
+ return `/homeworks#/edit-homeworks/${e}`;
1882
568
  }
1883
- get latestResponse() {
1884
- return this._latestResponse;
569
+ getExportUrl() {
570
+ throw new Error("Export not implemented.");
1885
571
  }
1886
- isResponseError() {
1887
- return this.latestResponse.status < 200 || this.latestResponse.status >= 300;
572
+ }
573
+ ResourceService.register(
574
+ { application: RESOURCE, resourceType: RESOURCE },
575
+ (n) => new HomeworksResourceService(n)
576
+ );
577
+ const globalCache = {}, mutexPromise = {};
578
+ class CacheService {
579
+ constructor(e) {
580
+ this.context = e;
1888
581
  }
1889
- async get(e, t) {
1890
- try {
1891
- const s = await this.axios.get(
1892
- this.toCdnUrl(e),
1893
- this.toAxiosConfig(t)
1894
- );
1895
- return this.mapAxiosResponse(s, t);
1896
- } catch (s) {
1897
- throw this.mapAxiosError(s, t);
1898
- }
582
+ get http() {
583
+ return this.context.http();
1899
584
  }
1900
- async post(e, t, s) {
585
+ async fromCacheIfPossible(e, t, s) {
586
+ if (mutexPromise[e] && await mutexPromise[e], globalCache[e])
587
+ return globalCache[e];
1901
588
  try {
1902
- const r = await this.axios.post(
1903
- this.fixBaseUrl(e),
1904
- t,
1905
- this.toAxiosConfig(s)
1906
- );
1907
- return this.mapAxiosResponse(r, s);
589
+ const r = t();
590
+ mutexPromise[e] = r;
591
+ const i = await r;
592
+ return s(i) && (globalCache[e] = i), i;
1908
593
  } catch (r) {
1909
- throw this.mapAxiosError(r, s);
594
+ throw console.error(`Failed to retrieve value for: ${e}`, r), r;
1910
595
  }
1911
596
  }
1912
- async postFile(e, t, s) {
1913
- const r = this.toAxiosConfig(s);
1914
- r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
1915
- try {
1916
- const i = await this.axios.post(this.fixBaseUrl(e), t, {
1917
- ...r,
1918
- headers: {
1919
- "Content-Type": "multipart/form-data"
1920
- }
1921
- });
1922
- return this.mapAxiosResponse(i, s);
1923
- } catch (i) {
1924
- throw this.mapAxiosError(i, s);
1925
- }
597
+ clearCache(e) {
598
+ if (e)
599
+ delete globalCache[e];
600
+ else
601
+ for (const t in globalCache)
602
+ globalCache.hasOwnProperty(t) && delete globalCache[t];
1926
603
  }
1927
- async postJson(e, t, s) {
1928
- const r = this.toAxiosConfig();
1929
- r.headers && (r.headers["Content-Type"] = "application/json");
1930
- try {
1931
- const i = await this.axios.post(
1932
- this.fixBaseUrl(e),
1933
- t,
1934
- this.toAxiosConfig(s)
1935
- );
1936
- return this.mapAxiosResponse(i, s);
1937
- } catch (i) {
1938
- throw this.mapAxiosError(i, s);
1939
- }
604
+ async httpGet(e, t) {
605
+ return this.fromCacheIfPossible(
606
+ e,
607
+ async () => {
608
+ const s = await this.http.get(e, t), r = { ...this.http.latestResponse };
609
+ return { value: s, response: r };
610
+ },
611
+ ({ response: s }) => !(s.status < 200 || s.status >= 300)
612
+ );
1940
613
  }
1941
- async put(e, t, s) {
1942
- try {
1943
- const r = await this.axios.put(
1944
- this.fixBaseUrl(e),
1945
- t,
1946
- this.toAxiosConfig(s)
1947
- );
1948
- return this.mapAxiosResponse(r, s);
1949
- } catch (r) {
1950
- throw this.mapAxiosError(r, s);
1951
- }
614
+ async httpGetJson(e, t) {
615
+ const { response: s, value: r } = await this.httpGet(e, t);
616
+ if (s.status < 200 || s.status >= 300)
617
+ throw `Bad http status (${s.status}) for url: ${e}`;
618
+ return r;
1952
619
  }
1953
- async putFile(e, t, s) {
1954
- try {
1955
- const r = this.toAxiosConfig(s);
1956
- r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
1957
- const i = await this.axios.put(this.fixBaseUrl(e), t, {
1958
- ...r,
1959
- headers: {
1960
- "Content-Type": "multipart/form-data"
1961
- }
1962
- });
1963
- return this.mapAxiosResponse(i, s);
1964
- } catch (r) {
1965
- throw this.mapAxiosError(r, s);
1966
- }
620
+ }
621
+ class ConfService {
622
+ constructor(e) {
623
+ u(this, "Platform", {
624
+ deploymentTag: "",
625
+ cdnDomain: ""
626
+ });
627
+ this.context = e;
1967
628
  }
1968
- async putJson(e, t, s) {
1969
- const r = this.toAxiosConfig(s);
1970
- r.headers && (r.headers["Content-Type"] = "application/json");
1971
- try {
1972
- const i = await this.axios.put(this.fixBaseUrl(e), t, r);
1973
- return this.mapAxiosResponse(i, s);
1974
- } catch (i) {
1975
- throw this.mapAxiosError(i, s);
1976
- }
629
+ get http() {
630
+ return this.context.http();
1977
631
  }
1978
- async delete(e, t) {
1979
- try {
1980
- const s = await this.axios.delete(
1981
- this.fixBaseUrl(e),
1982
- this.toAxiosConfig(t)
1983
- );
1984
- return this.mapAxiosResponse(s, t);
1985
- } catch (s) {
1986
- throw this.mapAxiosError(s, t);
1987
- }
632
+ get cache() {
633
+ return this.context.cache();
1988
634
  }
1989
- async deleteJson(e, t) {
1990
- try {
1991
- const s = await this.axios.delete(this.fixBaseUrl(e), {
1992
- data: t
1993
- });
1994
- return this.mapAxiosResponse(s);
1995
- } catch (s) {
1996
- throw this.mapAxiosError(s);
1997
- }
635
+ get cdnDomain() {
636
+ return this.Platform.cdnDomain;
1998
637
  }
1999
- getScript(e, t, s) {
2000
- const r = s ?? "exports", i = this.toAxiosConfig(t);
2001
- return i.headers && (i.headers.Accept = "application/javascript"), this.axios.get(this.toCdnUrl(e), i).then((u) => this.mapAxiosResponse(u, t)).then((u) => {
2002
- try {
2003
- const a = `"use strict";var ${r.split(".")[0]}={};${u};return ${r};`;
2004
- return Function(a)();
2005
- } catch {
2006
- return u;
638
+ get notify() {
639
+ return this.context.notify();
640
+ }
641
+ async getConf(e) {
642
+ const [t, s] = await Promise.all([
643
+ this.getThemeConf(),
644
+ this.getApplicationsList()
645
+ ]), [r, i] = await Promise.all([
646
+ this.getTheme({ conf: t, publicTheme: s === void 0 }),
647
+ this.getWebAppConf({ app: e, applications: s ?? [] })
648
+ ]), o = {
649
+ app: e,
650
+ applications: s ?? [],
651
+ conf: t,
652
+ currentApp: i,
653
+ theme: r
654
+ };
655
+ return this.notify.onAppConfReady().resolve(o), o;
656
+ }
657
+ async getPublicConf(e) {
658
+ const { response: t, value: s } = await this.cache.httpGet(
659
+ `/${e}/conf/public`,
660
+ {
661
+ queryParams: { _: this.Platform.deploymentTag }
2007
662
  }
2008
- }).catch((u) => {
2009
- throw this.mapAxiosError(u, t), u;
663
+ );
664
+ if (t.status < 200 || t.status >= 300)
665
+ throw ERROR_CODE.APP_NOT_FOUND;
666
+ return s;
667
+ }
668
+ getCdnUrl() {
669
+ }
670
+ async savePreference(e, t) {
671
+ this.http.putJson(`/userbook/preference/${e}`, t);
672
+ }
673
+ async getPreference(e) {
674
+ const t = await this.http.get(
675
+ `/userbook/preference/${e}`
676
+ );
677
+ return this.http.isResponseError() || typeof t == "string" ? {} : JSON.parse(t.preference);
678
+ }
679
+ async getThemeConf(e) {
680
+ return await this.http.getScript(
681
+ "/assets/theme-conf.js",
682
+ { queryParams: { v: e } },
683
+ "exports.conf"
684
+ );
685
+ }
686
+ async getApplicationsList() {
687
+ const e = await this.http.get(
688
+ "/applications-list"
689
+ );
690
+ if (!(this.http.isResponseError() || typeof e == "string"))
691
+ return e.apps;
692
+ }
693
+ async getWebAppConf({
694
+ app: e,
695
+ applications: t
696
+ }) {
697
+ return t.find((r) => {
698
+ if (r != null && r.prefix)
699
+ return (r == null ? void 0 : r.prefix.replace("/", "")) === e;
2010
700
  });
2011
701
  }
2012
- loadScript(e, t) {
2013
- return loadedScripts[e] ? Promise.resolve() : this.getScript(e, t).then((s) => {
2014
- loadedScripts[e] = !0;
702
+ async getTheme({
703
+ version: e,
704
+ conf: t,
705
+ publicTheme: s
706
+ }) {
707
+ const { value: r } = await this.cache.httpGet("/theme", {
708
+ queryParams: { _: e }
709
+ }), i = s ? null : r, o = t == null ? void 0 : t.overriding.find(
710
+ (p) => (
711
+ // Public access => simply use the 1st override
712
+ i === null || p.child === i.themeName
713
+ )
714
+ ), a = (i == null ? void 0 : i.skinName) || o.skins[0], c = (i == null ? void 0 : i.skin) || `/assets/themes/${o.child}/skins/${a}/`, l = o.skins, h = o.bootstrapVersion.split("-").slice(-1)[0], E = o.parent === "panda";
715
+ return {
716
+ basePath: `${this.cdnDomain}${c}../../`,
717
+ bootstrapVersion: h,
718
+ is1d: E,
719
+ logoutCallback: (i == null ? void 0 : i.logoutCallback) || "/",
720
+ skin: o.child,
721
+ skinName: a,
722
+ skins: l,
723
+ themeName: o.child,
724
+ themeUrl: c,
725
+ npmTheme: o.npmTheme ?? void 0
726
+ };
727
+ }
728
+ async getLogoutCallback(e) {
729
+ const { response: t, value: s } = await this.cache.httpGet("/theme", {
730
+ queryParams: { _: e }
2015
731
  });
732
+ if (t.status < 200 || t.status >= 300)
733
+ throw ERROR_CODE.NOT_LOGGED_IN;
734
+ return s.logoutCallback;
2016
735
  }
2017
736
  }
2018
- class RightService {
737
+ class DirectoryService {
2019
738
  constructor(e) {
2020
- this.context = e;
2021
- }
2022
- get session() {
2023
- return this.context.session();
2024
- }
2025
- /**
2026
- * Parse right concat as "$TYPE:$ID:$RIGHT"
2027
- * $TYPE = user | group | creator
2028
- * $ID: id of the resource
2029
- * $RIGHT: read | contrib | manage
2030
- *
2031
- * @param right a concat right
2032
- * @returns Right parsed
2033
- */
2034
- parseResourceRight(e) {
2035
- const t = e.split(":");
2036
- if (t.length === 2) {
2037
- if (t[0] === "creator")
2038
- return {
2039
- id: t[1],
2040
- right: "creator",
2041
- type: "creator"
2042
- };
2043
- } else return t.length === 3 ? {
2044
- id: t[1],
2045
- right: t[2],
2046
- type: t[0]
2047
- } : void 0;
2048
- }
2049
- /**
2050
- * Parse an array of rights concat as "$TYPE:$ID:$RIGHT"
2051
- * $TYPE = user | group | creator
2052
- * $ID: id of the resource
2053
- * $RIGHT: read | contrib | manage
2054
- *
2055
- * @param rights a list of concat rights
2056
- * @returns Array of Right parsed
2057
- */
2058
- parseResourceRights(e) {
2059
- return e.map((s) => this.parseResourceRight(s)).filter((s) => s !== void 0);
2060
- }
2061
- /**
2062
- * Check wether a user has the expected right for a ressource
2063
- * @param user the userId and groupId concerned by the check
2064
- * @param expect the expected right to check
2065
- * @param rights array of Right for the resource
2066
- * @returns true if has rights
2067
- */
2068
- hasResourceRight({ id: e, groupIds: t }, s, r) {
2069
- const i = r.map((u) => typeof u == "string" ? this.parseResourceRight(u) : u).filter((u) => u !== void 0);
2070
- for (const u of i) {
2071
- if (u.id === e && u.type === "creator")
2072
- return !0;
2073
- if (u.id === e && u.type === "user" && u.right === s)
2074
- return !0;
2075
- if (t.includes(u.id) && u.type === "group" && u.right === s)
2076
- return !0;
2077
- }
2078
- return !1;
739
+ this.odeServices = e;
2079
740
  }
2080
- /**
2081
- * Check wether the current user have resource right
2082
- * @param expect the expected right to check
2083
- * @param rights array of Right for the resource
2084
- * @returns true if has rights
2085
- */
2086
- async sessionHasResourceRight(e, t) {
2087
- try {
2088
- const s = await this.session.getUser();
2089
- return !!s && this.hasResourceRight(
2090
- { groupIds: s.groupsIds, id: s.userId },
2091
- e,
2092
- t
2093
- );
2094
- } catch (s) {
2095
- return console.error(`Unexpected error ${s} in sessionHasResourceRight()`), !1;
2096
- }
741
+ get http() {
742
+ return this.odeServices.http();
2097
743
  }
2098
- /**
2099
- * Check wether the current user have at least one of resource right expected
2100
- * @param expects array of expected right to check
2101
- * @param rights array of Right for the resource
2102
- * @returns true if has rights
2103
- */
2104
- async sessionHasAtLeastOneResourceRight(e, t) {
2105
- for (const s of e)
2106
- if (await this.sessionHasResourceRight(s, t))
2107
- return !0;
2108
- return !1;
744
+ get cache() {
745
+ return this.odeServices.cache();
2109
746
  }
2110
- /**
2111
- * Check wether the current user has resource right for each right list
2112
- * @param expect expected right to check
2113
- * @param rightsArray array of array of Right for multiple resources
2114
- * @returns true if has rights
2115
- */
2116
- async sessionHasResourceRightForEachList(e, t) {
2117
- let s = 0;
2118
- for (const r of t)
2119
- await this.sessionHasResourceRight(e, r) && s++;
2120
- return s === t.length;
747
+ getAvatarUrl(e, t, s = "100x100") {
748
+ return t === "user" ? `/userbook/avatar/${e}?thumbnail=${s}` : "/assets/img/illustrations/group-avatar.svg";
2121
749
  }
2122
- /**
2123
- * Check wether the current user have at least one of resource right for each right list
2124
- * @param expects array of expected right to check
2125
- * @param rightsArray array of array of Right for multiple resources
2126
- * @returns true if has rights
2127
- */
2128
- async sessionHasAtLeastOneResourceRightForEachList(e, t) {
2129
- for (const s of e) {
2130
- let r = 0;
2131
- for (const i of t)
2132
- await this.sessionHasResourceRight(s, i) && r++;
2133
- if (r === t.length)
2134
- return !0;
2135
- }
2136
- return !1;
750
+ getDirectoryUrl(e, t) {
751
+ return t === "user" ? `/userbook/annuaire#/${e}` : `/userbook/annuaire#/group-view/${e}`;
2137
752
  }
2138
- hasWorkflowRight(e, t) {
2139
- return t.findIndex((s) => s === e) !== -1;
753
+ async getBookMarks() {
754
+ return (await this.cache.httpGetJson(
755
+ "/directory/sharebookmark/all"
756
+ )).map(({ id: t, name: s }) => ({
757
+ id: t,
758
+ displayName: s,
759
+ members: []
760
+ // this api does not return members
761
+ }));
2140
762
  }
2141
- /**
2142
- * @param expect a workflow right
2143
- * @returns true if current session has right on it
2144
- */
2145
- async sessionHasWorkflowRight(e) {
2146
- try {
2147
- const t = await this.session.getUser();
2148
- return !!t && this.hasWorkflowRight(
2149
- e,
2150
- t.authorizedActions.map(
2151
- (s) => s.name
2152
- )
2153
- );
2154
- } catch (t) {
2155
- return console.error(`Unexpected error ${t} in sessionHasWorkflowRight()`), !1;
2156
- }
763
+ async getBookMarkById(e) {
764
+ const { groups: t, id: s, name: r, users: i } = await this.http.get(
765
+ `/directory/sharebookmark/${e}`
766
+ );
767
+ return {
768
+ id: s,
769
+ displayName: r,
770
+ groups: t.map(({ name: o, id: a }) => ({
771
+ displayName: o,
772
+ id: a
773
+ })),
774
+ users: i.map(({ displayName: o, id: a, profile: c }) => ({
775
+ profile: c,
776
+ displayName: o,
777
+ // these info are missing from api
778
+ firstName: "",
779
+ lastName: "",
780
+ login: "",
781
+ id: a
782
+ }))
783
+ };
2157
784
  }
2158
- /**
2159
- * @param expect a workflow right
2160
- * @returns a record with right as key and boolean as value if current session has right on it
2161
- */
2162
- async sessionHasWorkflowRights(e) {
2163
- const t = {};
2164
- try {
2165
- const s = await this.session.getUser();
2166
- for (const r of e)
2167
- t[r] = !!s && this.hasWorkflowRight(
2168
- r,
2169
- s.authorizedActions.map(
2170
- (i) => i.name
2171
- )
2172
- );
2173
- } catch (s) {
2174
- console.error(`Unexpected error ${s} in sessionHasWorkflowRights()`);
2175
- for (const r of e)
2176
- t[r] = !1;
2177
- }
2178
- return t;
785
+ async saveBookmarks(e, {
786
+ bookmarks: t,
787
+ groups: s,
788
+ users: r
789
+ }) {
790
+ this.cache.clearCache("/directory/sharebookmark/all");
791
+ const i = r.map((p) => typeof p == "string" ? p : p.id), o = s.map((p) => typeof p == "string" ? p : p.id), a = t.map(async (p) => {
792
+ if (typeof p == "string") {
793
+ const { displayName: d, groups: g, id: A, users: m } = await this.getBookMarkById(p), R = m.map((C) => C.id), v = g.map((C) => C.id);
794
+ return {
795
+ displayName: d,
796
+ id: A,
797
+ members: [...v, ...R]
798
+ };
799
+ } else
800
+ return Promise.resolve(p);
801
+ }), l = (await Promise.all(a)).map((p) => p.members).reduce((p, d) => [...p, ...d], []), h = {
802
+ name: e,
803
+ members: [...i, ...o, ...l]
804
+ }, { id: E } = await this.http.postJson(
805
+ "/directory/sharebookmark",
806
+ h
807
+ );
808
+ return {
809
+ id: E,
810
+ displayName: e,
811
+ members: h.members
812
+ };
2179
813
  }
2180
814
  }
2181
- class SessionService {
2182
- constructor(e) {
2183
- this.context = e;
815
+ const loadedScripts = {};
816
+ class HttpService {
817
+ constructor(e, t) {
818
+ // Axios automatically manages the XSRF-TOKEN cookie and the X-XSRF-TOKEN HTTP header.
819
+ u(this, "axios");
820
+ u(this, "baseUrl");
821
+ u(this, "headers", {});
822
+ u(this, "_latestResponse");
823
+ this.context = e, this.axios = axios.create(t);
2184
824
  }
2185
- get http() {
2186
- return this.context.http();
825
+ fixBaseUrl(e) {
826
+ return e.startsWith("http://") || e.startsWith("https://") ? e : this.baseUrl ? this.baseUrl.endsWith("/") || e.startsWith("/") ? `${this.baseUrl}${e}` : `${this.baseUrl}/${e}` : e;
2187
827
  }
2188
- get cache() {
2189
- return this.context.cache();
828
+ useBaseUrl(e) {
829
+ return this.baseUrl = e, this;
830
+ }
831
+ useHeaders(e) {
832
+ return this.headers = e, this;
2190
833
  }
2191
- get conf() {
2192
- return this.context.conf();
834
+ setCdn(e) {
835
+ e && XMLHttpRequest && !XMLHttpRequest.prototype.cdnUrl && (XMLHttpRequest.prototype.cdnUrl = e, XMLHttpRequest.prototype.baseOpen = XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.open = function() {
836
+ const t = arguments[1];
837
+ return t.startsWith("/infra/public") && (arguments[1] = e + t), /^\/([^\/]*)\/public/.test(t) && (arguments[1] = e + t), t.startsWith("/assets") && (arguments[1] = e + t), t == "/conf/public" && (arguments[1] = t), t.startsWith("http") && (arguments[1] = t), this.baseOpen.apply(this, arguments);
838
+ });
2193
839
  }
2194
- /**
2195
- * Callback to call when user logout
2196
- */
2197
- onLogout() {
2198
- this.cache.clearCache();
840
+ // private toAxiosConfig(params?: IHttpParams): AxiosRequestConfig {
841
+ toAxiosConfig(e) {
842
+ if (e) {
843
+ const t = Object.assign({}, this.axios.defaults);
844
+ e.headers && (t.headers = Object.assign({}, this.axios.defaults.headers), Object.assign(t.headers, e.headers)), e.responseType && (t.responseType = e.responseType), e.queryParams && (t.params = Object.assign({}, e.queryParams));
845
+ const s = t.headers ?? {};
846
+ return t.headers = { ...s, ...this.headers }, t;
847
+ } else
848
+ return this.axios.defaults;
2199
849
  }
2200
- /**
2201
- * Callback to call when session change
2202
- */
2203
- onRefreshSession() {
2204
- this.cache.clearCache();
850
+ toCdnUrl(e) {
851
+ e = this.fixBaseUrl(e);
852
+ const t = this.context.conf().getCdnUrl() || "";
853
+ if (t.length > 0 && e !== "/conf/public") {
854
+ const s = "" + e;
855
+ (s.startsWith("/infra/public") || s.startsWith("/assets") || /^\/([^\/]*)\/public/.test(s)) && (e = t + s);
856
+ }
857
+ return e;
2205
858
  }
2206
- async getSession() {
2207
- const e = await this.getUser(), [
2208
- t,
2209
- s,
2210
- r,
2211
- i,
2212
- u
2213
- ] = await Promise.all([
2214
- this.getCurrentLanguage(e),
2215
- this.latestQuotaAndUsage(e),
2216
- this.loadDescription(e),
2217
- this.getUserProfile(),
2218
- this.getBookmarks(e)
2219
- ]);
2220
- return {
2221
- user: e,
2222
- quotaAndUsage: s,
2223
- currentLanguage: t,
2224
- userDescription: r,
2225
- userProfile: i,
2226
- bookmarkedApps: u
859
+ mapAxiosError(e, t) {
860
+ e.response ? this._latestResponse = e.response : e.request ? this._latestResponse = {
861
+ status: 408,
862
+ statusText: ERROR_CODE.TIME_OUT
863
+ } : this._latestResponse = {
864
+ status: 500,
865
+ statusText: ERROR_CODE.UNKNOWN
2227
866
  };
2228
- }
2229
- login(e, t, s, r) {
2230
- const i = new FormData();
2231
- return i.append("email", e), i.append("password", t), typeof s < "u" && i.append("rememberMe", "" + s), typeof r < "u" && i.append("secureLocation", "" + r), this.http.post("/auth/login", i, {
2232
- headers: { "content-type": "application/x-www-form-urlencoded" }
2233
- }).finally(() => {
2234
- switch (this.http.latestResponse.status) {
2235
- case 200:
2236
- throw ERROR_CODE.MALFORMED_DATA;
867
+ const { status: s, statusText: r, headers: i, data: o } = this._latestResponse;
868
+ return t != null && t.disableNotifications || notify.events().publish(LAYER_NAME.TRANSPORT, {
869
+ name: EVENT_NAME.ERROR_OCCURED,
870
+ data: {
871
+ params: t,
872
+ response: { status: s, statusText: r, headers: i },
873
+ payload: o
2237
874
  }
2238
- });
875
+ }), o;
2239
876
  }
2240
- async logout() {
2241
- const e = await this.conf.getLogoutCallback();
2242
- return this.http.get("/auth/logout?callback=" + e).finally(() => {
2243
- });
877
+ mapAxiosResponse(e, t) {
878
+ return this._latestResponse = e, e.data;
2244
879
  }
2245
- async latestQuotaAndUsage(e) {
2246
- const t = { quota: 0, storage: 0 };
2247
- if (!e) return t;
880
+ get latestResponse() {
881
+ return this._latestResponse;
882
+ }
883
+ isResponseError() {
884
+ return this.latestResponse.status < 200 || this.latestResponse.status >= 300;
885
+ }
886
+ async get(e, t) {
2248
887
  try {
2249
- return await this.http.get(
2250
- `/workspace/quota/user/${e == null ? void 0 : e.userId}`
888
+ const s = await this.axios.get(
889
+ this.toCdnUrl(e),
890
+ this.toAxiosConfig(t)
2251
891
  );
892
+ return this.mapAxiosResponse(s, t);
2252
893
  } catch (s) {
2253
- return console.error(s), t;
894
+ throw this.mapAxiosError(s, t);
2254
895
  }
2255
896
  }
2256
- async getCurrentLanguage(e) {
2257
- const t = (e == null ? void 0 : e.sessionMetadata) && (e == null ? void 0 : e.sessionMetadata.userId);
897
+ async post(e, t, s) {
2258
898
  try {
2259
- let s;
2260
- return t ? s = await this.loadUserLanguage() : s = await this.loadDefaultLanguage(), s;
2261
- } catch (s) {
2262
- console.error(s);
899
+ const r = await this.axios.post(
900
+ this.fixBaseUrl(e),
901
+ t,
902
+ this.toAxiosConfig(s)
903
+ );
904
+ return this.mapAxiosResponse(r, s);
905
+ } catch (r) {
906
+ throw this.mapAxiosError(r, s);
2263
907
  }
2264
908
  }
2265
- async loadUserLanguage() {
909
+ async postFile(e, t, s) {
910
+ const r = this.toAxiosConfig(s);
911
+ r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
2266
912
  try {
2267
- const e = await this.http.get(
2268
- "/userbook/preference/language"
2269
- );
2270
- return JSON.parse(e.preference)["default-domain"];
2271
- } catch {
2272
- return await this.loadDefaultLanguage();
913
+ const i = await this.axios.post(this.fixBaseUrl(e), t, {
914
+ ...r,
915
+ headers: {
916
+ "Content-Type": "multipart/form-data"
917
+ }
918
+ });
919
+ return this.mapAxiosResponse(i, s);
920
+ } catch (i) {
921
+ throw this.mapAxiosError(i, s);
2273
922
  }
2274
923
  }
2275
- async loadDefaultLanguage() {
2276
- return (await this.cache.httpGetJson(
2277
- "/locale"
2278
- )).locale;
924
+ async postJson(e, t, s) {
925
+ const r = this.toAxiosConfig();
926
+ r.headers && (r.headers["Content-Type"] = "application/json");
927
+ try {
928
+ const i = await this.axios.post(
929
+ this.fixBaseUrl(e),
930
+ t,
931
+ this.toAxiosConfig(s)
932
+ );
933
+ return this.mapAxiosResponse(i, s);
934
+ } catch (i) {
935
+ throw this.mapAxiosError(i, s);
936
+ }
2279
937
  }
2280
- async getUser() {
2281
- const { response: e, value: t } = await this.cache.httpGet(
2282
- "/auth/oauth2/userinfo"
2283
- );
2284
- if (!(e.status < 200 || e.status >= 300) && typeof t == "object")
2285
- return t;
2286
- throw ERROR_CODE.NOT_LOGGED_IN;
938
+ async put(e, t, s) {
939
+ try {
940
+ const r = await this.axios.put(
941
+ this.fixBaseUrl(e),
942
+ t,
943
+ this.toAxiosConfig(s)
944
+ );
945
+ return this.mapAxiosResponse(r, s);
946
+ } catch (r) {
947
+ throw this.mapAxiosError(r, s);
948
+ }
2287
949
  }
2288
- hasWorkflow({
2289
- workflowName: e,
2290
- user: t
2291
- }) {
2292
- return e === void 0 || (t == null ? void 0 : t.authorizedActions.findIndex((s) => s.name === e)) !== -1;
950
+ async putFile(e, t, s) {
951
+ try {
952
+ const r = this.toAxiosConfig(s);
953
+ r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
954
+ const i = await this.axios.put(this.fixBaseUrl(e), t, {
955
+ ...r,
956
+ headers: {
957
+ "Content-Type": "multipart/form-data"
958
+ }
959
+ });
960
+ return this.mapAxiosResponse(i, s);
961
+ } catch (r) {
962
+ throw this.mapAxiosError(r, s);
963
+ }
2293
964
  }
2294
- async loadDescription(e) {
2295
- if (!e) return {};
965
+ async putJson(e, t, s) {
966
+ const r = this.toAxiosConfig(s);
967
+ r.headers && (r.headers["Content-Type"] = "application/json");
2296
968
  try {
2297
- const [t, s] = await Promise.all([
2298
- // FIXME The full user's description should be obtainable from a single endpoint in the backend.
2299
- this.getUserProfile({
2300
- options: { requestName: "refreshAvatar" }
2301
- }),
2302
- this.http.get("/directory/userbook/" + (e == null ? void 0 : e.userId))
2303
- ]);
2304
- return { ...s, profiles: t };
2305
- } catch (t) {
2306
- return console.error(t), {};
969
+ const i = await this.axios.put(this.fixBaseUrl(e), t, r);
970
+ return this.mapAxiosResponse(i, s);
971
+ } catch (i) {
972
+ throw this.mapAxiosError(i, s);
2307
973
  }
2308
974
  }
2309
- async getBookmarks(e) {
2310
- if (!e) return [];
2311
- const t = await this.http.get("/userbook/preference/apps");
2312
- t.preference || (t.preference = null);
2313
- const s = JSON.parse(t.preference);
2314
- let r;
2315
- r = s, r || (r = {
2316
- bookmarks: [],
2317
- applications: []
2318
- });
2319
- const i = [];
2320
- return r.bookmarks.forEach((u, a) => {
2321
- const c = ((e == null ? void 0 : e.apps) || []).find(
2322
- (h) => h.name === u
975
+ async delete(e, t) {
976
+ try {
977
+ const s = await this.axios.delete(
978
+ this.fixBaseUrl(e),
979
+ this.toAxiosConfig(t)
2323
980
  );
2324
- if (c) {
2325
- const h = Object.assign({}, c);
2326
- i.push(h);
2327
- }
2328
- }), i;
2329
- }
2330
- async getUserProfile(e = {}) {
2331
- var c, h;
2332
- const { options: t = {}, params: s = {} } = e, r = new URLSearchParams(s).toString(), i = `/userbook/api/person${r ? `?${r}` : ""}`, { response: u, value: a } = await this.cache.httpGet(i, t);
2333
- return u.status < 200 || u.status >= 300 || typeof a == "string" ? ["Guest"] : ((h = (c = a == null ? void 0 : a.result) == null ? void 0 : c[0]) == null ? void 0 : h.type) || ["Guest"];
2334
- }
2335
- async isAdml() {
2336
- const e = await this.getUser();
2337
- return (e == null ? void 0 : e.functions.ADMIN_LOCAL) !== void 0;
981
+ return this.mapAxiosResponse(s, t);
982
+ } catch (s) {
983
+ throw this.mapAxiosError(s, t);
984
+ }
2338
985
  }
2339
- /**
2340
- * Get details of an application if the user can access it.
2341
- * @return undefined if no access, or app not found
2342
- */
2343
- async getWebApp(e) {
2344
- const t = await this.getUser();
2345
- return t == null ? void 0 : t.apps.find((s) => {
2346
- var r;
2347
- return s != null && s.prefix ? (s == null ? void 0 : s.prefix.replace("/", "")) === e || !1 : s != null && s.address && ((r = s.address) == null ? void 0 : r.split("/")[1]) === e || !1;
986
+ async deleteJson(e, t) {
987
+ try {
988
+ const s = await this.axios.delete(this.fixBaseUrl(e), {
989
+ data: t
990
+ });
991
+ return this.mapAxiosResponse(s);
992
+ } catch (s) {
993
+ throw this.mapAxiosError(s);
994
+ }
995
+ }
996
+ getScript(e, t, s) {
997
+ const r = s ?? "exports", i = this.toAxiosConfig(t);
998
+ return i.headers && (i.headers.Accept = "application/javascript"), this.axios.get(this.toCdnUrl(e), i).then((o) => this.mapAxiosResponse(o, t)).then((o) => {
999
+ try {
1000
+ const a = `"use strict";var ${r.split(".")[0]}={};${o};return ${r};`;
1001
+ return Function(a)();
1002
+ } catch {
1003
+ return o;
1004
+ }
1005
+ }).catch((o) => {
1006
+ throw this.mapAxiosError(o, t), o;
2348
1007
  });
2349
1008
  }
2350
- }
2351
- class StringUtils {
2352
- static removeAccents(e) {
2353
- for (let t = 0; t < defaultDiacriticsRemovalMap$1.length; t++)
2354
- e = e.replace(
2355
- defaultDiacriticsRemovalMap$1[t].letters,
2356
- defaultDiacriticsRemovalMap$1[t].base
2357
- );
2358
- return e;
1009
+ loadScript(e, t) {
1010
+ return loadedScripts[e] ? Promise.resolve() : this.getScript(e, t).then((s) => {
1011
+ loadedScripts[e] = !0;
1012
+ });
2359
1013
  }
2360
1014
  }
2361
- class ShareService {
2362
- //
2363
- // IMPLEMENTATION
2364
- //
1015
+ class RightService {
2365
1016
  constructor(e) {
2366
1017
  this.context = e;
2367
1018
  }
2368
- get directory() {
2369
- return this.context.directory();
1019
+ get session() {
1020
+ return this.context.session();
2370
1021
  }
2371
- get http() {
2372
- return this.context.http();
1022
+ /**
1023
+ * Parse right concat as "$TYPE:$ID:$RIGHT"
1024
+ * $TYPE = user | group | creator
1025
+ * $ID: id of the resource
1026
+ * $RIGHT: read | contrib | manage
1027
+ *
1028
+ * @param right a concat right
1029
+ * @returns Right parsed
1030
+ */
1031
+ parseResourceRight(e) {
1032
+ const t = e.split(":");
1033
+ if (t.length === 2) {
1034
+ if (t[0] === "creator")
1035
+ return {
1036
+ id: t[1],
1037
+ right: "creator",
1038
+ type: "creator"
1039
+ };
1040
+ } else return t.length === 3 ? {
1041
+ id: t[1],
1042
+ right: t[2],
1043
+ type: t[0]
1044
+ } : void 0;
2373
1045
  }
2374
- get cache() {
2375
- return this.context.cache();
1046
+ /**
1047
+ * Parse an array of rights concat as "$TYPE:$ID:$RIGHT"
1048
+ * $TYPE = user | group | creator
1049
+ * $ID: id of the resource
1050
+ * $RIGHT: read | contrib | manage
1051
+ *
1052
+ * @param rights a list of concat rights
1053
+ * @returns Array of Right parsed
1054
+ */
1055
+ parseResourceRights(e) {
1056
+ return e.map((s) => this.parseResourceRight(s)).filter((s) => s !== void 0);
2376
1057
  }
2377
- async searchShareSubjects(e, t, s) {
2378
- const r = StringUtils.removeAccents(s).toLowerCase(), i = await this.cache.httpGetJson(
2379
- `/${e}/share/json/${t}?search=${s}`
2380
- ), u = i.users.visibles.filter(({ username: l, firstName: E, lastName: p, login: d }) => {
2381
- const g = StringUtils.removeAccents(
2382
- p || ""
2383
- ).toLowerCase(), A = StringUtils.removeAccents(
2384
- E || ""
2385
- ).toLowerCase(), m = StringUtils.removeAccents(
2386
- l || ""
2387
- ).toLowerCase(), b = StringUtils.removeAccents(d || "").toLowerCase();
2388
- return m.includes(r) || A.includes(r) || g.includes(r) || b.includes(r);
2389
- }).map((l) => ({
2390
- avatarUrl: this.directory.getAvatarUrl(l.id, "user"),
2391
- directoryUrl: this.directory.getDirectoryUrl(l.id, "user"),
2392
- displayName: l.username,
2393
- id: l.id,
2394
- profile: l.profile,
2395
- type: "user"
2396
- })), a = i.groups.visibles.filter(({ name: l }) => StringUtils.removeAccents(l || "").toLowerCase().includes(r)).map((l) => ({
2397
- avatarUrl: this.directory.getAvatarUrl(l.id, "group"),
2398
- directoryUrl: this.directory.getDirectoryUrl(l.id, "group"),
2399
- displayName: l.name,
2400
- id: l.id,
2401
- type: "group",
2402
- structureName: l.structureName
2403
- }));
2404
- return [...(await this.directory.getBookMarks()).filter(({ displayName: l }) => StringUtils.removeAccents(
2405
- l || ""
2406
- ).toLowerCase().includes(r)).map((l) => ({
2407
- avatarUrl: "",
2408
- directoryUrl: "",
2409
- profile: "",
2410
- displayName: l.displayName,
2411
- id: l.id,
2412
- type: "sharebookmark"
2413
- })), ...u, ...a];
1058
+ /**
1059
+ * Check wether a user has the expected right for a ressource
1060
+ * @param user the userId and groupId concerned by the check
1061
+ * @param expect the expected right to check
1062
+ * @param rights array of Right for the resource
1063
+ * @returns true if has rights
1064
+ */
1065
+ hasResourceRight({ id: e, groupIds: t }, s, r) {
1066
+ const i = r.map((o) => typeof o == "string" ? this.parseResourceRight(o) : o).filter((o) => o !== void 0);
1067
+ for (const o of i) {
1068
+ if (o.id === e && o.type === "creator")
1069
+ return !0;
1070
+ if (o.id === e && o.type === "user" && o.right === s)
1071
+ return !0;
1072
+ if (t.includes(o.id) && o.type === "group" && o.right === s)
1073
+ return !0;
1074
+ }
1075
+ return !1;
2414
1076
  }
2415
- async getShareMapping(e) {
2416
- const t = await this.cache.httpGetJson(
2417
- `/${e}/rights/sharing`
2418
- );
2419
- for (const s of Object.keys(t))
2420
- if (s.includes(".")) {
2421
- const r = s.split(".")[1], i = t[s];
2422
- delete t[s], t[r] = i;
2423
- }
2424
- return t;
1077
+ /**
1078
+ * Check wether the current user have resource right
1079
+ * @param expect the expected right to check
1080
+ * @param rights array of Right for the resource
1081
+ * @returns true if has rights
1082
+ */
1083
+ async sessionHasResourceRight(e, t) {
1084
+ try {
1085
+ const s = await this.session.getUser();
1086
+ return !!s && this.hasResourceRight(
1087
+ { groupIds: s.groupsIds, id: s.userId },
1088
+ e,
1089
+ t
1090
+ );
1091
+ } catch (s) {
1092
+ return console.error(`Unexpected error ${s} in sessionHasResourceRight()`), !1;
1093
+ }
2425
1094
  }
2426
- getActionsAvailableFor({ id: e, type: t }, s, r) {
2427
- const u = (t === "user" ? s.users.checked[e] : s.groups.checked[e]) || [], a = Object.keys(r), c = [];
2428
- for (const h of a)
2429
- r[h].filter(
2430
- (p) => u.includes(p)
2431
- ).length > 0 && c.push(h);
2432
- return c;
1095
+ /**
1096
+ * Check wether the current user have at least one of resource right expected
1097
+ * @param expects array of expected right to check
1098
+ * @param rights array of Right for the resource
1099
+ * @returns true if has rights
1100
+ */
1101
+ async sessionHasAtLeastOneResourceRight(e, t) {
1102
+ for (const s of e)
1103
+ if (await this.sessionHasResourceRight(s, t))
1104
+ return !0;
1105
+ return !1;
2433
1106
  }
2434
- async getRightsForResource(e, t) {
2435
- const s = await this.directory.getBookMarks(), r = `/${e}/share/json/${t}?search=`, i = await this.cache.httpGetJson(r), u = await this.getShareMapping(e), a = await this.cache.httpGetJson(
2436
- "/infra/public/json/sharing-rights.json"
2437
- ), c = Object.keys(i.users.checked).map((d) => i.users.visibles.find(
2438
- (A) => A.id === d
2439
- )).filter((d) => d !== void 0).map((d) => {
2440
- const g = this.getActionsAvailableFor(
2441
- { id: d.id, type: "user" },
2442
- i,
2443
- u
2444
- );
2445
- return {
2446
- id: d.id,
2447
- type: "user",
2448
- displayName: d.username,
2449
- profile: d.profile,
2450
- avatarUrl: this.directory.getAvatarUrl(d.id, "user"),
2451
- directoryUrl: this.directory.getDirectoryUrl(d.id, "user"),
2452
- actions: g.map((m) => {
2453
- const b = a[m];
2454
- return {
2455
- displayName: m,
2456
- id: m,
2457
- priority: b.priority
2458
- };
2459
- })
2460
- };
2461
- }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), h = Object.keys(i.groups.checked).map((d) => i.groups.visibles.find(
2462
- (A) => A.id === d
2463
- )).filter((d) => d !== void 0).map((d) => {
2464
- const g = this.getActionsAvailableFor(
2465
- { id: d.id, type: "group" },
2466
- i,
2467
- u
2468
- );
2469
- return {
2470
- id: d.id,
2471
- type: "group",
2472
- displayName: d.name,
2473
- profile: void 0,
2474
- avatarUrl: this.directory.getAvatarUrl(d.id, "group"),
2475
- directoryUrl: this.directory.getDirectoryUrl(d.id, "group"),
2476
- actions: g.map((m) => {
2477
- const b = a[m];
2478
- return {
2479
- displayName: m,
2480
- id: m,
2481
- priority: b.priority
2482
- };
2483
- })
2484
- };
2485
- }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), l = [...c, ...h], E = i.groups.visibles.map(
2486
- ({ groupDisplayName: d, id: g, name: A }) => ({
2487
- displayName: d || A,
2488
- id: g
2489
- })
2490
- ), p = i.users.visibles.map(
2491
- ({ id: d, profile: g, username: A, firstName: m, lastName: b, login: R }) => ({
2492
- displayName: A,
2493
- firstName: m,
2494
- lastName: b,
2495
- login: R,
2496
- profile: g,
2497
- id: d
2498
- })
2499
- );
2500
- return {
2501
- rights: l,
2502
- visibleBookmarks: s,
2503
- visibleGroups: E,
2504
- visibleUsers: p
2505
- };
1107
+ /**
1108
+ * Check wether the current user has resource right for each right list
1109
+ * @param expect expected right to check
1110
+ * @param rightsArray array of array of Right for multiple resources
1111
+ * @returns true if has rights
1112
+ */
1113
+ async sessionHasResourceRightForEachList(e, t) {
1114
+ let s = 0;
1115
+ for (const r of t)
1116
+ await this.sessionHasResourceRight(e, r) && s++;
1117
+ return s === t.length;
2506
1118
  }
2507
- async saveRights(e, t, s) {
2508
- const r = await this.getShareMapping(e), i = {
2509
- bookmarks: {},
2510
- groups: {},
2511
- users: {}
2512
- };
2513
- for (const c of s) {
2514
- const h = c.actions.map((E) => r[E.id]).reduce((E, p) => Array.isArray(p) ? [...E, ...p] : E, []), l = [...new Set(h)];
2515
- l.length > 0 && (c.type === "user" ? i.users[c.id] = l : c.type === "group" ? i.groups[c.id] = l : i.bookmarks[c.id] = l);
1119
+ /**
1120
+ * Check wether the current user have at least one of resource right for each right list
1121
+ * @param expects array of expected right to check
1122
+ * @param rightsArray array of array of Right for multiple resources
1123
+ * @returns true if has rights
1124
+ */
1125
+ async sessionHasAtLeastOneResourceRightForEachList(e, t) {
1126
+ for (const s of e) {
1127
+ let r = 0;
1128
+ for (const i of t)
1129
+ await this.sessionHasResourceRight(s, i) && r++;
1130
+ if (r === t.length)
1131
+ return !0;
2516
1132
  }
2517
- const u = `/${e}/share/resource/${t}`;
2518
- return this.cache.clearCache(`/${e}/share/json/${t}?search=`), await this.http.putJson(u, i);
2519
- }
2520
- async getActionsForApp(e) {
2521
- const t = await this.cache.httpGetJson(
2522
- "/infra/public/json/sharing-rights.json"
2523
- ), s = await this.getShareMapping(e);
2524
- return Object.keys(t).map((i) => {
2525
- const u = t[i];
2526
- return {
2527
- displayName: i,
2528
- id: i,
2529
- priority: u.priority,
2530
- requires: u.requires
2531
- };
2532
- }).filter((i) => {
2533
- var u;
2534
- return ((u = s[i.id]) == null ? void 0 : u.length) > 0;
2535
- }).sort((i, u) => i.priority - u.priority);
1133
+ return !1;
2536
1134
  }
2537
- }
2538
- const defaultMappers = {
2539
- csv: function({ type: o, extension: e }) {
2540
- return MimeTypeUtils.INSTANCE.isCsvLike(o, e);
2541
- },
2542
- doc: function({ type: o, extension: e }) {
2543
- return MimeTypeUtils.INSTANCE.isWordLike(o, e) ? !0 : o.indexOf("document") !== -1 && o.indexOf("wordprocessing") !== -1;
2544
- },
2545
- xls: function({ type: o, extension: e }) {
2546
- return MimeTypeUtils.INSTANCE.isExcelLike(o, e) ? !0 : o.indexOf("document") !== -1 && o.indexOf("spreadsheet") !== -1 || o.indexOf("ms-excel") !== -1;
2547
- },
2548
- img: function({ type: o }) {
2549
- return o.indexOf("image") !== -1;
2550
- },
2551
- pdf: function({ type: o }) {
2552
- return o.indexOf("pdf") !== -1 || o === "application/x-download";
2553
- },
2554
- ppt: function({ type: o, extension: e }) {
2555
- return MimeTypeUtils.INSTANCE.isPowerpointLike(o, e) ? !0 : o.indexOf("document") !== -1 && o.indexOf("presentation") !== -1 || o.indexOf("powerpoint") !== -1;
2556
- },
2557
- txt: function({ type: o, extension: e }) {
2558
- return MimeTypeUtils.INSTANCE.isTxtLike(o, e);
2559
- },
2560
- md: function({ type: o, extension: e }) {
2561
- return MimeTypeUtils.INSTANCE.isMdLike(o, e);
2562
- },
2563
- video: function({ type: o }) {
2564
- return o.indexOf("video") !== -1;
2565
- },
2566
- audio: function({ type: o }) {
2567
- return o.indexOf("audio") !== -1;
2568
- },
2569
- zip: function({ type: o }) {
2570
- return o.indexOf("zip") !== -1 || o.indexOf("rar") !== -1 || o.indexOf("tar") !== -1 || o.indexOf("7z") !== -1;
1135
+ hasWorkflowRight(e, t) {
1136
+ return t.findIndex((s) => s === e) !== -1;
2571
1137
  }
2572
- }, w = class w {
2573
- /* Similar role notion as in infra-front > workspace > Model.ts */
2574
- static getRole(e) {
2575
- var t, s;
2576
- return w.role(
2577
- (t = e.metadata) == null ? void 0 : t["content-type"],
2578
- !1,
2579
- (s = e.metadata) == null ? void 0 : s.extension
2580
- );
1138
+ /**
1139
+ * @param expect a workflow right
1140
+ * @returns true if current session has right on it
1141
+ */
1142
+ async sessionHasWorkflowRight(e) {
1143
+ try {
1144
+ const t = await this.session.getUser();
1145
+ return !!t && this.hasWorkflowRight(
1146
+ e,
1147
+ t.authorizedActions.map(
1148
+ (s) => s.name
1149
+ )
1150
+ );
1151
+ } catch (t) {
1152
+ return console.error(`Unexpected error ${t} in sessionHasWorkflowRight()`), !1;
1153
+ }
2581
1154
  }
2582
- /* Similar role notion as in infra-front > workspace > Model.ts */
2583
- static role(e, t = !1, s) {
2584
- if (s && (s = s.trim()), !e) return "unknown";
2585
- this.roleMappers || console.warn("[DocumentHelper.role] should not have empty roles", this);
2586
- const r = { type: e, previewRole: t, extension: s };
2587
- for (const i of this.roleMappers) {
2588
- const u = i(r);
2589
- if (u)
2590
- return u;
1155
+ /**
1156
+ * @param expect a workflow right
1157
+ * @returns a record with right as key and boolean as value if current session has right on it
1158
+ */
1159
+ async sessionHasWorkflowRights(e) {
1160
+ const t = {};
1161
+ try {
1162
+ const s = await this.session.getUser();
1163
+ for (const r of e)
1164
+ t[r] = !!s && this.hasWorkflowRight(
1165
+ r,
1166
+ s.authorizedActions.map(
1167
+ (i) => i.name
1168
+ )
1169
+ );
1170
+ } catch (s) {
1171
+ console.error(`Unexpected error ${s} in sessionHasWorkflowRights()`);
1172
+ for (const r of e)
1173
+ t[r] = !1;
2591
1174
  }
2592
- return "unknown";
1175
+ return t;
2593
1176
  }
2594
- };
2595
- // FIXME add edumedia support
2596
- n(w, "roleMappers", [
2597
- (e) => Object.keys(defaultMappers).find((s) => defaultMappers[s](e))
2598
- ]);
2599
- let DocumentHelper = w;
2600
- class WorkspaceService {
1177
+ }
1178
+ class SessionService {
2601
1179
  constructor(e) {
2602
1180
  this.context = e;
2603
1181
  }
2604
1182
  get http() {
2605
1183
  return this.context.http();
2606
1184
  }
2607
- extractMetadata(e) {
2608
- const t = e.name || "", s = t.split("."), r = e.type || "application/octet-stream", i = s.length > 1 ? s[s.length - 1] : "", u = {
2609
- "content-type": r,
2610
- filename: t,
2611
- size: e.size,
2612
- extension: i,
2613
- role: DocumentHelper.role(r, !1, i)
2614
- }, a = t.replace("." + u.extension, ""), c = u.extension ? a + "." + u.extension : a;
2615
- return { basename: a, fullname: c, metadata: u };
1185
+ get cache() {
1186
+ return this.context.cache();
2616
1187
  }
2617
- async saveFile(e, t) {
2618
- const { fullname: s, metadata: r } = this.extractMetadata(e), i = new FormData();
2619
- i.append("file", e, s);
2620
- const u = [];
2621
- ((t == null ? void 0 : t.visibility) === "public" || (t == null ? void 0 : t.visibility) === "protected") && u.push(`${t.visibility}=true`), t != null && t.application && u.push(`application=${t.application}`), r.role === "img" && u.push("quality=1"), t != null && t.parentId && u.push(`parentId=${t.parentId}`);
2622
- const a = await this.http.postFile(
2623
- `/workspace/document?${u.join("&")}`,
2624
- i
2625
- );
2626
- if (this.http.isResponseError())
2627
- throw this.http.latestResponse.statusText;
2628
- return a;
1188
+ get conf() {
1189
+ return this.context.conf();
2629
1190
  }
2630
- async updateFile(e, t, s) {
2631
- const { fullname: r, metadata: i } = this.extractMetadata(t), u = new FormData();
2632
- u.append("file", t, r);
2633
- const a = [];
2634
- i.role === "img" && a.push("quality=1"), s != null && s.alt && a.push(`alt=${s.alt}`), s != null && s.legend && a.push(`legend=${s.legend}`), s != null && s.name && a.push(`name=${s.name}`);
2635
- const c = await this.http.putFile(
2636
- `/workspace/document/${e}?${a.join("&")}`,
2637
- u
2638
- );
2639
- if (this.http.isResponseError())
2640
- throw this.http.latestResponse.statusText;
2641
- return c;
1191
+ /**
1192
+ * Callback to call when user logout
1193
+ */
1194
+ onLogout() {
1195
+ this.cache.clearCache();
2642
1196
  }
2643
- async deleteFile(e) {
2644
- const t = e.map((s) => s._id);
2645
- if (t.length == 0)
2646
- Promise.resolve(null);
2647
- else if (await this.http.deleteJson("/workspace/documents", {
2648
- ids: t
2649
- }), this.http.isResponseError())
2650
- throw this.http.latestResponse.statusText;
1197
+ /**
1198
+ * Callback to call when session change
1199
+ */
1200
+ onRefreshSession() {
1201
+ this.cache.clearCache();
2651
1202
  }
2652
- async acceptDocuments(e) {
2653
- const t = await this.context.session().getUser();
2654
- return (s) => s.deleted && s.trasher ? (t == null ? void 0 : t.userId) == s.trasher : !0;
1203
+ async getSession() {
1204
+ const e = await this.getUser(), [
1205
+ t,
1206
+ s,
1207
+ r,
1208
+ i,
1209
+ o
1210
+ ] = await Promise.all([
1211
+ this.getCurrentLanguage(e),
1212
+ this.latestQuotaAndUsage(e),
1213
+ this.loadDescription(e),
1214
+ this.getUserProfile(),
1215
+ this.getBookmarks(e)
1216
+ ]);
1217
+ return {
1218
+ user: e,
1219
+ quotaAndUsage: s,
1220
+ currentLanguage: t,
1221
+ userDescription: r,
1222
+ userProfile: i,
1223
+ bookmarkedApps: o
1224
+ };
2655
1225
  }
2656
- async searchDocuments(e) {
2657
- const t = e.filter !== "external" || e.parentId ? await this.http.get("/workspace/documents", {
2658
- queryParams: { ...e, _: (/* @__PURE__ */ new Date()).getTime() }
2659
- }) : [], s = await this.acceptDocuments(e);
2660
- return t.filter(s);
1226
+ login(e, t, s, r) {
1227
+ const i = new FormData();
1228
+ return i.append("email", e), i.append("password", t), typeof s < "u" && i.append("rememberMe", "" + s), typeof r < "u" && i.append("secureLocation", "" + r), this.http.post("/auth/login", i, {
1229
+ headers: { "content-type": "application/x-www-form-urlencoded" }
1230
+ }).finally(() => {
1231
+ switch (this.http.latestResponse.status) {
1232
+ case 200:
1233
+ throw ERROR_CODE.MALFORMED_DATA;
1234
+ }
1235
+ });
2661
1236
  }
2662
- async listDocuments(e, t) {
2663
- return this.searchDocuments({ filter: e, parentId: t, includeall: !0 });
1237
+ async logout() {
1238
+ const e = await this.conf.getLogoutCallback();
1239
+ return this.http.get("/auth/logout?callback=" + e).finally(() => {
1240
+ });
2664
1241
  }
2665
- /**
2666
- * Duplicate and transfers documents if needed to a different folder with the specified application and visibility.
2667
- * @param documents - The array of documents to transfer.
2668
- * @param application - The application to associate with the transferred documents.
2669
- * @param visibility - The visibility of the transferred documents. Defaults to "protected".
2670
- * @returns A Promise that resolves to an array of transferred WorkspaceElements.
2671
- */
2672
- async transferDocuments(e, t, s = "protected") {
2673
- const r = [];
2674
- if (e.forEach((i) => {
2675
- (s === "public" && !i.public || !i.public && !i.protected) && r.push(i);
2676
- }), r.length > 0) {
2677
- const i = await this.http.post(
2678
- "/workspace/documents/transfer",
2679
- {
2680
- application: t,
2681
- visibility: s,
2682
- ids: r.map((u) => u._id)
2683
- }
1242
+ async latestQuotaAndUsage(e) {
1243
+ const t = { quota: 0, storage: 0 };
1244
+ if (!e) return t;
1245
+ try {
1246
+ return await this.http.get(
1247
+ `/workspace/quota/user/${e == null ? void 0 : e.userId}`
2684
1248
  );
2685
- if (this.http.isResponseError())
2686
- throw this.http.latestResponse.statusText;
2687
- return r.forEach((u, a) => {
2688
- const c = e.findIndex(
2689
- (h) => h._id === u._id
2690
- );
2691
- 0 <= c && c < e.length && (e[c] = i[a]);
2692
- }), e.filter((u) => !!u);
1249
+ } catch (s) {
1250
+ return console.error(s), t;
2693
1251
  }
2694
- return e;
2695
1252
  }
2696
- /**
2697
- * Get the URL of the thumbnail of a workspace element (or its URL),
2698
- * or `null` if none exists or can be created.
2699
- */
2700
- getThumbnailUrl(e, t = 0, s = 0) {
2701
- var i, u;
2702
- const r = t > 0 || s > 0 ? `${t}x${s}` : "120x120";
2703
- if (typeof e == "string")
2704
- return e.includes("data:image") || e.includes("thumbnail") ? e : `${e}${e.includes("?") ? "&" : "?"}thumbnail=${r}`;
2705
- {
2706
- const a = `/workspace/${e.public ? "pub/" : ""}document/${e._id}?thumbnail=`, c = e.thumbnails;
2707
- if ((u = (i = e.metadata) == null ? void 0 : i["content-type"]) != null && u.includes("video")) {
2708
- const h = c && Object.keys(c).length > 0 ? Object.keys(c)[0] : null;
2709
- return h ? a + h : null;
2710
- } else
2711
- return a + r;
1253
+ async getCurrentLanguage(e) {
1254
+ const t = (e == null ? void 0 : e.sessionMetadata) && (e == null ? void 0 : e.sessionMetadata.userId);
1255
+ try {
1256
+ let s;
1257
+ return t ? s = await this.loadUserLanguage() : s = await this.loadDefaultLanguage(), s;
1258
+ } catch (s) {
1259
+ console.error(s);
1260
+ }
1261
+ }
1262
+ async loadUserLanguage() {
1263
+ try {
1264
+ const e = await this.http.get(
1265
+ "/userbook/preference/language"
1266
+ );
1267
+ return JSON.parse(e.preference)["default-domain"];
1268
+ } catch {
1269
+ return await this.loadDefaultLanguage();
1270
+ }
1271
+ }
1272
+ async loadDefaultLanguage() {
1273
+ return (await this.cache.httpGetJson(
1274
+ "/locale"
1275
+ )).locale;
1276
+ }
1277
+ async getUser() {
1278
+ const { response: e, value: t } = await this.cache.httpGet(
1279
+ "/auth/oauth2/userinfo"
1280
+ );
1281
+ if (!(e.status < 200 || e.status >= 300) && typeof t == "object")
1282
+ return t;
1283
+ throw ERROR_CODE.NOT_LOGGED_IN;
1284
+ }
1285
+ hasWorkflow({
1286
+ workflowName: e,
1287
+ user: t
1288
+ }) {
1289
+ return e === void 0 || (t == null ? void 0 : t.authorizedActions.findIndex((s) => s.name === e)) !== -1;
1290
+ }
1291
+ async loadDescription(e) {
1292
+ if (!e) return {};
1293
+ try {
1294
+ const [t, s] = await Promise.all([
1295
+ // FIXME The full user's description should be obtainable from a single endpoint in the backend.
1296
+ this.getUserProfile({
1297
+ options: { requestName: "refreshAvatar" }
1298
+ }),
1299
+ this.http.get("/directory/userbook/" + (e == null ? void 0 : e.userId))
1300
+ ]);
1301
+ return { ...s, profiles: t };
1302
+ } catch (t) {
1303
+ return console.error(t), {};
2712
1304
  }
2713
1305
  }
1306
+ async getBookmarks(e) {
1307
+ if (!e) return [];
1308
+ const t = await this.http.get("/userbook/preference/apps");
1309
+ t.preference || (t.preference = null);
1310
+ const s = JSON.parse(t.preference);
1311
+ let r;
1312
+ r = s, r || (r = {
1313
+ bookmarks: [],
1314
+ applications: []
1315
+ });
1316
+ const i = [];
1317
+ return r.bookmarks.forEach((o, a) => {
1318
+ const c = ((e == null ? void 0 : e.apps) || []).find(
1319
+ (l) => l.name === o
1320
+ );
1321
+ if (c) {
1322
+ const l = Object.assign({}, c);
1323
+ i.push(l);
1324
+ }
1325
+ }), i;
1326
+ }
1327
+ async getUserProfile(e = {}) {
1328
+ var c, l;
1329
+ const { options: t = {}, params: s = {} } = e, r = new URLSearchParams(s).toString(), i = `/userbook/api/person${r ? `?${r}` : ""}`, { response: o, value: a } = await this.cache.httpGet(i, t);
1330
+ return o.status < 200 || o.status >= 300 || typeof a == "string" ? ["Guest"] : ((l = (c = a == null ? void 0 : a.result) == null ? void 0 : c[0]) == null ? void 0 : l.type) || ["Guest"];
1331
+ }
1332
+ async isAdml() {
1333
+ const e = await this.getUser();
1334
+ return (e == null ? void 0 : e.functions.ADMIN_LOCAL) !== void 0;
1335
+ }
1336
+ /**
1337
+ * Get details of an application if the user can access it.
1338
+ * @return undefined if no access, or app not found
1339
+ */
1340
+ async getWebApp(e) {
1341
+ const t = await this.getUser();
1342
+ return t == null ? void 0 : t.apps.find((s) => {
1343
+ var r;
1344
+ return s != null && s.prefix ? (s == null ? void 0 : s.prefix.replace("/", "")) === e || !1 : s != null && s.address && ((r = s.address) == null ? void 0 : r.split("/")[1]) === e || !1;
1345
+ });
1346
+ }
2714
1347
  }
2715
1348
  const bundle = {}, promises = {}, defaultDiacriticsRemovalMap = [
2716
1349
  {
@@ -2866,138 +1499,505 @@ const bundle = {}, promises = {}, defaultDiacriticsRemovalMap = [
2866
1499
  base: "l",
2867
1500
  letters: /[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g
2868
1501
  },
2869
- { base: "lj", letters: /[\u01C9]/g },
2870
- { base: "m", letters: /[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g },
2871
- {
2872
- base: "n",
2873
- letters: /[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g
1502
+ { base: "lj", letters: /[\u01C9]/g },
1503
+ { base: "m", letters: /[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g },
1504
+ {
1505
+ base: "n",
1506
+ letters: /[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g
1507
+ },
1508
+ { base: "nj", letters: /[\u01CC]/g },
1509
+ {
1510
+ base: "o",
1511
+ letters: /[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g
1512
+ },
1513
+ { base: "oi", letters: /[\u01A3]/g },
1514
+ { base: "ou", letters: /[\u0223]/g },
1515
+ { base: "oo", letters: /[\uA74F]/g },
1516
+ {
1517
+ base: "p",
1518
+ letters: /[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g
1519
+ },
1520
+ { base: "q", letters: /[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g },
1521
+ {
1522
+ base: "r",
1523
+ letters: /[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g
1524
+ },
1525
+ {
1526
+ base: "s",
1527
+ letters: /[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g
1528
+ },
1529
+ {
1530
+ base: "t",
1531
+ letters: /[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g
1532
+ },
1533
+ { base: "tz", letters: /[\uA729]/g },
1534
+ {
1535
+ base: "u",
1536
+ letters: /[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g
1537
+ },
1538
+ { base: "v", letters: /[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g },
1539
+ { base: "vy", letters: /[\uA761]/g },
1540
+ {
1541
+ base: "w",
1542
+ letters: /[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g
1543
+ },
1544
+ { base: "x", letters: /[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g },
1545
+ {
1546
+ base: "y",
1547
+ letters: /[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g
1548
+ },
1549
+ {
1550
+ base: "z",
1551
+ letters: /[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g
1552
+ }
1553
+ ];
1554
+ class IdiomService {
1555
+ constructor(e) {
1556
+ this.context = e;
1557
+ }
1558
+ get http() {
1559
+ return this.context.http();
1560
+ }
1561
+ async getIdiom(e, t) {
1562
+ await Promise.all([
1563
+ this.addBundlePromise(e, "/i18n"),
1564
+ this.addBundlePromise(e, `/${t}/i18n`)
1565
+ ]);
1566
+ }
1567
+ translate(e, t) {
1568
+ e = e ?? "";
1569
+ let s = bundle[e] === void 0 ? e : bundle[e];
1570
+ if (t && typeof t == "object")
1571
+ for (let r in t)
1572
+ typeof t[r] < "u" && (s = s.replace(
1573
+ new RegExp("\\${" + r + "}", "g"),
1574
+ "" + t[r]
1575
+ ));
1576
+ return s;
1577
+ }
1578
+ addBundlePromise(e, t) {
1579
+ return this.loadBundlePromise(e, t);
1580
+ }
1581
+ addBundle(e, t, s) {
1582
+ this.loadBundle(e, t, s);
1583
+ }
1584
+ loadBundlePromise(e, t) {
1585
+ return this.loadBundle(e, t), promises[t];
1586
+ }
1587
+ loadBundle(e, t, s) {
1588
+ const r = promises[t];
1589
+ if (r)
1590
+ s && r.then(s).catch(s);
1591
+ else {
1592
+ const i = new Promisified();
1593
+ promises[t] = i.promise;
1594
+ const o = {};
1595
+ e && (o["Accept-Language"] = e), this.http.get(t, { headers: o }).then((a) => {
1596
+ Object.assign(bundle, a), typeof s == "function" && s(), i.resolve();
1597
+ }).catch((a) => {
1598
+ typeof s == "function" && s(), i.reject();
1599
+ });
1600
+ }
1601
+ }
1602
+ addTranslations(e, t) {
1603
+ notify.onLangReady().promise.then((s) => {
1604
+ this.loadBundle(s, e + "/" + s + ".json", t);
1605
+ });
1606
+ }
1607
+ addAllTranslations(e) {
1608
+ return e && e.length > 0 ? notify.onLangReady().promise.then(
1609
+ (t) => Promise.all(
1610
+ e.map(
1611
+ (s) => this.loadBundlePromise(t, s + "/" + t + ".json")
1612
+ )
1613
+ )
1614
+ ).then(() => {
1615
+ }) : Promise.reject();
1616
+ }
1617
+ addKeys(e) {
1618
+ for (var t in e)
1619
+ typeof bundle[t] != "string" && (bundle[t] = e[t]);
1620
+ }
1621
+ removeAccents(e) {
1622
+ for (var t = 0; t < defaultDiacriticsRemovalMap.length; t++)
1623
+ e = e.replace(
1624
+ defaultDiacriticsRemovalMap[t].letters,
1625
+ defaultDiacriticsRemovalMap[t].base
1626
+ );
1627
+ return e;
1628
+ }
1629
+ }
1630
+ class StringUtils {
1631
+ static removeAccents(e) {
1632
+ for (let t = 0; t < defaultDiacriticsRemovalMap.length; t++)
1633
+ e = e.replace(
1634
+ defaultDiacriticsRemovalMap[t].letters,
1635
+ defaultDiacriticsRemovalMap[t].base
1636
+ );
1637
+ return e;
1638
+ }
1639
+ }
1640
+ class ShareService {
1641
+ //
1642
+ // IMPLEMENTATION
1643
+ //
1644
+ constructor(e) {
1645
+ this.context = e;
1646
+ }
1647
+ get directory() {
1648
+ return this.context.directory();
1649
+ }
1650
+ get http() {
1651
+ return this.context.http();
1652
+ }
1653
+ get cache() {
1654
+ return this.context.cache();
1655
+ }
1656
+ async searchShareSubjects(e, t, s) {
1657
+ const r = StringUtils.removeAccents(s).toLowerCase(), i = await this.cache.httpGetJson(
1658
+ `/${e}/share/json/${t}?search=${s}`
1659
+ ), o = i.users.visibles.filter(({ username: h, firstName: E, lastName: p, login: d }) => {
1660
+ const g = StringUtils.removeAccents(
1661
+ p || ""
1662
+ ).toLowerCase(), A = StringUtils.removeAccents(
1663
+ E || ""
1664
+ ).toLowerCase(), m = StringUtils.removeAccents(
1665
+ h || ""
1666
+ ).toLowerCase(), R = StringUtils.removeAccents(d || "").toLowerCase();
1667
+ return m.includes(r) || A.includes(r) || g.includes(r) || R.includes(r);
1668
+ }).map((h) => ({
1669
+ avatarUrl: this.directory.getAvatarUrl(h.id, "user"),
1670
+ directoryUrl: this.directory.getDirectoryUrl(h.id, "user"),
1671
+ displayName: h.username,
1672
+ id: h.id,
1673
+ profile: h.profile,
1674
+ type: "user"
1675
+ })), a = i.groups.visibles.filter(({ name: h }) => StringUtils.removeAccents(h || "").toLowerCase().includes(r)).map((h) => ({
1676
+ avatarUrl: this.directory.getAvatarUrl(h.id, "group"),
1677
+ directoryUrl: this.directory.getDirectoryUrl(h.id, "group"),
1678
+ displayName: h.name,
1679
+ id: h.id,
1680
+ type: "group",
1681
+ structureName: h.structureName
1682
+ }));
1683
+ return [...(await this.directory.getBookMarks()).filter(({ displayName: h }) => StringUtils.removeAccents(
1684
+ h || ""
1685
+ ).toLowerCase().includes(r)).map((h) => ({
1686
+ avatarUrl: "",
1687
+ directoryUrl: "",
1688
+ profile: "",
1689
+ displayName: h.displayName,
1690
+ id: h.id,
1691
+ type: "sharebookmark"
1692
+ })), ...o, ...a];
1693
+ }
1694
+ async getShareMapping(e) {
1695
+ const t = await this.cache.httpGetJson(
1696
+ `/${e}/rights/sharing`
1697
+ );
1698
+ for (const s of Object.keys(t))
1699
+ if (s.includes(".")) {
1700
+ const r = s.split(".")[1], i = t[s];
1701
+ delete t[s], t[r] = i;
1702
+ }
1703
+ return t;
1704
+ }
1705
+ getActionsAvailableFor({ id: e, type: t }, s, r) {
1706
+ const o = (t === "user" ? s.users.checked[e] : s.groups.checked[e]) || [], a = Object.keys(r), c = [];
1707
+ for (const l of a)
1708
+ r[l].filter(
1709
+ (p) => o.includes(p)
1710
+ ).length > 0 && c.push(l);
1711
+ return c;
1712
+ }
1713
+ async getRightsForResource(e, t) {
1714
+ const s = await this.directory.getBookMarks(), r = `/${e}/share/json/${t}?search=`, i = await this.cache.httpGetJson(r), o = await this.getShareMapping(e), a = await this.cache.httpGetJson(
1715
+ "/infra/public/json/sharing-rights.json"
1716
+ ), c = Object.keys(i.users.checked).map((d) => i.users.visibles.find(
1717
+ (A) => A.id === d
1718
+ )).filter((d) => d !== void 0).map((d) => {
1719
+ const g = this.getActionsAvailableFor(
1720
+ { id: d.id, type: "user" },
1721
+ i,
1722
+ o
1723
+ );
1724
+ return {
1725
+ id: d.id,
1726
+ type: "user",
1727
+ displayName: d.username,
1728
+ profile: d.profile,
1729
+ avatarUrl: this.directory.getAvatarUrl(d.id, "user"),
1730
+ directoryUrl: this.directory.getDirectoryUrl(d.id, "user"),
1731
+ actions: g.map((m) => {
1732
+ const R = a[m];
1733
+ return {
1734
+ displayName: m,
1735
+ id: m,
1736
+ priority: R.priority
1737
+ };
1738
+ })
1739
+ };
1740
+ }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), l = Object.keys(i.groups.checked).map((d) => i.groups.visibles.find(
1741
+ (A) => A.id === d
1742
+ )).filter((d) => d !== void 0).map((d) => {
1743
+ const g = this.getActionsAvailableFor(
1744
+ { id: d.id, type: "group" },
1745
+ i,
1746
+ o
1747
+ );
1748
+ return {
1749
+ id: d.id,
1750
+ type: "group",
1751
+ displayName: d.name,
1752
+ profile: void 0,
1753
+ avatarUrl: this.directory.getAvatarUrl(d.id, "group"),
1754
+ directoryUrl: this.directory.getDirectoryUrl(d.id, "group"),
1755
+ actions: g.map((m) => {
1756
+ const R = a[m];
1757
+ return {
1758
+ displayName: m,
1759
+ id: m,
1760
+ priority: R.priority
1761
+ };
1762
+ })
1763
+ };
1764
+ }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), h = [...c, ...l], E = i.groups.visibles.map(
1765
+ ({ groupDisplayName: d, id: g, name: A }) => ({
1766
+ displayName: d || A,
1767
+ id: g
1768
+ })
1769
+ ), p = i.users.visibles.map(
1770
+ ({ id: d, profile: g, username: A, firstName: m, lastName: R, login: v }) => ({
1771
+ displayName: A,
1772
+ firstName: m,
1773
+ lastName: R,
1774
+ login: v,
1775
+ profile: g,
1776
+ id: d
1777
+ })
1778
+ );
1779
+ return {
1780
+ rights: h,
1781
+ visibleBookmarks: s,
1782
+ visibleGroups: E,
1783
+ visibleUsers: p
1784
+ };
1785
+ }
1786
+ async saveRights(e, t, s) {
1787
+ const r = await this.getShareMapping(e), i = {
1788
+ bookmarks: {},
1789
+ groups: {},
1790
+ users: {}
1791
+ };
1792
+ for (const c of s) {
1793
+ const l = c.actions.map((E) => r[E.id]).reduce((E, p) => Array.isArray(p) ? [...E, ...p] : E, []), h = [...new Set(l)];
1794
+ h.length > 0 && (c.type === "user" ? i.users[c.id] = h : c.type === "group" ? i.groups[c.id] = h : i.bookmarks[c.id] = h);
1795
+ }
1796
+ const o = `/${e}/share/resource/${t}`;
1797
+ return this.cache.clearCache(`/${e}/share/json/${t}?search=`), await this.http.putJson(o, i);
1798
+ }
1799
+ async getActionsForApp(e) {
1800
+ const t = await this.cache.httpGetJson(
1801
+ "/infra/public/json/sharing-rights.json"
1802
+ ), s = await this.getShareMapping(e);
1803
+ return Object.keys(t).map((i) => {
1804
+ const o = t[i];
1805
+ return {
1806
+ displayName: i,
1807
+ id: i,
1808
+ priority: o.priority,
1809
+ requires: o.requires
1810
+ };
1811
+ }).filter((i) => {
1812
+ var o;
1813
+ return ((o = s[i.id]) == null ? void 0 : o.length) > 0;
1814
+ }).sort((i, o) => i.priority - o.priority);
1815
+ }
1816
+ }
1817
+ const defaultMappers = {
1818
+ csv: function({ type: n, extension: e }) {
1819
+ return MimeTypeUtils.INSTANCE.isCsvLike(n, e);
1820
+ },
1821
+ doc: function({ type: n, extension: e }) {
1822
+ return MimeTypeUtils.INSTANCE.isWordLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("wordprocessing") !== -1;
2874
1823
  },
2875
- { base: "nj", letters: /[\u01CC]/g },
2876
- {
2877
- base: "o",
2878
- letters: /[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g
1824
+ xls: function({ type: n, extension: e }) {
1825
+ return MimeTypeUtils.INSTANCE.isExcelLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("spreadsheet") !== -1 || n.indexOf("ms-excel") !== -1;
2879
1826
  },
2880
- { base: "oi", letters: /[\u01A3]/g },
2881
- { base: "ou", letters: /[\u0223]/g },
2882
- { base: "oo", letters: /[\uA74F]/g },
2883
- {
2884
- base: "p",
2885
- letters: /[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g
1827
+ img: function({ type: n }) {
1828
+ return n.indexOf("image") !== -1;
2886
1829
  },
2887
- { base: "q", letters: /[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g },
2888
- {
2889
- base: "r",
2890
- letters: /[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g
1830
+ pdf: function({ type: n }) {
1831
+ return n.indexOf("pdf") !== -1 || n === "application/x-download";
2891
1832
  },
2892
- {
2893
- base: "s",
2894
- letters: /[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g
1833
+ ppt: function({ type: n, extension: e }) {
1834
+ return MimeTypeUtils.INSTANCE.isPowerpointLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("presentation") !== -1 || n.indexOf("powerpoint") !== -1;
2895
1835
  },
2896
- {
2897
- base: "t",
2898
- letters: /[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g
1836
+ txt: function({ type: n, extension: e }) {
1837
+ return MimeTypeUtils.INSTANCE.isTxtLike(n, e);
2899
1838
  },
2900
- { base: "tz", letters: /[\uA729]/g },
2901
- {
2902
- base: "u",
2903
- letters: /[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g
1839
+ md: function({ type: n, extension: e }) {
1840
+ return MimeTypeUtils.INSTANCE.isMdLike(n, e);
2904
1841
  },
2905
- { base: "v", letters: /[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g },
2906
- { base: "vy", letters: /[\uA761]/g },
2907
- {
2908
- base: "w",
2909
- letters: /[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g
1842
+ video: function({ type: n }) {
1843
+ return n.indexOf("video") !== -1;
2910
1844
  },
2911
- { base: "x", letters: /[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g },
2912
- {
2913
- base: "y",
2914
- letters: /[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g
1845
+ audio: function({ type: n }) {
1846
+ return n.indexOf("audio") !== -1;
2915
1847
  },
2916
- {
2917
- base: "z",
2918
- letters: /[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g
1848
+ zip: function({ type: n }) {
1849
+ return n.indexOf("zip") !== -1 || n.indexOf("rar") !== -1 || n.indexOf("tar") !== -1 || n.indexOf("7z") !== -1;
2919
1850
  }
2920
- ];
2921
- class IdiomService {
1851
+ }, b = class b {
1852
+ /* Similar role notion as in infra-front > workspace > Model.ts */
1853
+ static getRole(e) {
1854
+ var t, s;
1855
+ return b.role(
1856
+ (t = e.metadata) == null ? void 0 : t["content-type"],
1857
+ !1,
1858
+ (s = e.metadata) == null ? void 0 : s.extension
1859
+ );
1860
+ }
1861
+ /* Similar role notion as in infra-front > workspace > Model.ts */
1862
+ static role(e, t = !1, s) {
1863
+ if (s && (s = s.trim()), !e) return "unknown";
1864
+ this.roleMappers || console.warn("[DocumentHelper.role] should not have empty roles", this);
1865
+ const r = { type: e, previewRole: t, extension: s };
1866
+ for (const i of this.roleMappers) {
1867
+ const o = i(r);
1868
+ if (o)
1869
+ return o;
1870
+ }
1871
+ return "unknown";
1872
+ }
1873
+ };
1874
+ // FIXME add edumedia support
1875
+ u(b, "roleMappers", [
1876
+ (e) => Object.keys(defaultMappers).find((s) => defaultMappers[s](e))
1877
+ ]);
1878
+ let DocumentHelper = b;
1879
+ class WorkspaceService {
2922
1880
  constructor(e) {
2923
1881
  this.context = e;
2924
1882
  }
2925
1883
  get http() {
2926
1884
  return this.context.http();
2927
1885
  }
2928
- async getIdiom(e, t) {
2929
- await Promise.all([
2930
- this.addBundlePromise(e, "/i18n"),
2931
- this.addBundlePromise(e, `/${t}/i18n`)
2932
- ]);
2933
- }
2934
- translate(e, t) {
2935
- e = e ?? "";
2936
- let s = bundle[e] === void 0 ? e : bundle[e];
2937
- if (t && typeof t == "object")
2938
- for (let r in t)
2939
- typeof t[r] < "u" && (s = s.replace(
2940
- new RegExp("\\${" + r + "}", "g"),
2941
- "" + t[r]
2942
- ));
2943
- return s;
2944
- }
2945
- addBundlePromise(e, t) {
2946
- return this.loadBundlePromise(e, t);
1886
+ extractMetadata(e) {
1887
+ const t = e.name || "", s = t.split("."), r = e.type || "application/octet-stream", i = s.length > 1 ? s[s.length - 1] : "", o = {
1888
+ "content-type": r,
1889
+ filename: t,
1890
+ size: e.size,
1891
+ extension: i,
1892
+ role: DocumentHelper.role(r, !1, i)
1893
+ }, a = t.replace("." + o.extension, ""), c = o.extension ? a + "." + o.extension : a;
1894
+ return { basename: a, fullname: c, metadata: o };
2947
1895
  }
2948
- addBundle(e, t, s) {
2949
- this.loadBundle(e, t, s);
1896
+ async saveFile(e, t) {
1897
+ const { fullname: s, metadata: r } = this.extractMetadata(e), i = new FormData();
1898
+ i.append("file", e, s);
1899
+ const o = [];
1900
+ ((t == null ? void 0 : t.visibility) === "public" || (t == null ? void 0 : t.visibility) === "protected") && o.push(`${t.visibility}=true`), t != null && t.application && o.push(`application=${t.application}`), r.role === "img" && o.push("quality=1"), t != null && t.parentId && o.push(`parentId=${t.parentId}`);
1901
+ const a = await this.http.postFile(
1902
+ `/workspace/document?${o.join("&")}`,
1903
+ i
1904
+ );
1905
+ if (this.http.isResponseError())
1906
+ throw this.http.latestResponse.statusText;
1907
+ return a;
2950
1908
  }
2951
- loadBundlePromise(e, t) {
2952
- return this.loadBundle(e, t), promises[t];
1909
+ async updateFile(e, t, s) {
1910
+ const { fullname: r, metadata: i } = this.extractMetadata(t), o = new FormData();
1911
+ o.append("file", t, r);
1912
+ const a = [];
1913
+ i.role === "img" && a.push("quality=1"), s != null && s.alt && a.push(`alt=${s.alt}`), s != null && s.legend && a.push(`legend=${s.legend}`), s != null && s.name && a.push(`name=${s.name}`);
1914
+ const c = await this.http.putFile(
1915
+ `/workspace/document/${e}?${a.join("&")}`,
1916
+ o
1917
+ );
1918
+ if (this.http.isResponseError())
1919
+ throw this.http.latestResponse.statusText;
1920
+ return c;
2953
1921
  }
2954
- loadBundle(e, t, s) {
2955
- const r = promises[t];
2956
- if (r)
2957
- s && r.then(s).catch(s);
2958
- else {
2959
- const i = new Promisified();
2960
- promises[t] = i.promise;
2961
- const u = {};
2962
- e && (u["Accept-Language"] = e), this.http.get(t, { headers: u }).then((a) => {
2963
- Object.assign(bundle, a), typeof s == "function" && s(), i.resolve();
2964
- }).catch((a) => {
2965
- typeof s == "function" && s(), i.reject();
2966
- });
2967
- }
1922
+ async deleteFile(e) {
1923
+ const t = e.map((s) => s._id);
1924
+ if (t.length == 0)
1925
+ Promise.resolve(null);
1926
+ else if (await this.http.deleteJson("/workspace/documents", {
1927
+ ids: t
1928
+ }), this.http.isResponseError())
1929
+ throw this.http.latestResponse.statusText;
2968
1930
  }
2969
- addTranslations(e, t) {
2970
- notify.onLangReady().promise.then((s) => {
2971
- this.loadBundle(s, e + "/" + s + ".json", t);
2972
- });
1931
+ async acceptDocuments(e) {
1932
+ const t = await this.context.session().getUser();
1933
+ return (s) => s.deleted && s.trasher ? (t == null ? void 0 : t.userId) == s.trasher : !0;
2973
1934
  }
2974
- addAllTranslations(e) {
2975
- return e && e.length > 0 ? notify.onLangReady().promise.then(
2976
- (t) => Promise.all(
2977
- e.map(
2978
- (s) => this.loadBundlePromise(t, s + "/" + t + ".json")
2979
- )
2980
- )
2981
- ).then(() => {
2982
- }) : Promise.reject();
1935
+ async searchDocuments(e) {
1936
+ const t = e.filter !== "external" || e.parentId ? await this.http.get("/workspace/documents", {
1937
+ queryParams: { ...e, _: (/* @__PURE__ */ new Date()).getTime() }
1938
+ }) : [], s = await this.acceptDocuments(e);
1939
+ return t.filter(s);
2983
1940
  }
2984
- addKeys(e) {
2985
- for (var t in e)
2986
- typeof bundle[t] != "string" && (bundle[t] = e[t]);
1941
+ async listDocuments(e, t) {
1942
+ return this.searchDocuments({ filter: e, parentId: t, includeall: !0 });
2987
1943
  }
2988
- removeAccents(e) {
2989
- for (var t = 0; t < defaultDiacriticsRemovalMap.length; t++)
2990
- e = e.replace(
2991
- defaultDiacriticsRemovalMap[t].letters,
2992
- defaultDiacriticsRemovalMap[t].base
1944
+ /**
1945
+ * Duplicate and transfers documents if needed to a different folder with the specified application and visibility.
1946
+ * @param documents - The array of documents to transfer.
1947
+ * @param application - The application to associate with the transferred documents.
1948
+ * @param visibility - The visibility of the transferred documents. Defaults to "protected".
1949
+ * @returns A Promise that resolves to an array of transferred WorkspaceElements.
1950
+ */
1951
+ async transferDocuments(e, t, s = "protected") {
1952
+ const r = [];
1953
+ if (e.forEach((i) => {
1954
+ (s === "public" && !i.public || !i.public && !i.protected) && r.push(i);
1955
+ }), r.length > 0) {
1956
+ const i = await this.http.post(
1957
+ "/workspace/documents/transfer",
1958
+ {
1959
+ application: t,
1960
+ visibility: s,
1961
+ ids: r.map((o) => o._id)
1962
+ }
2993
1963
  );
1964
+ if (this.http.isResponseError())
1965
+ throw this.http.latestResponse.statusText;
1966
+ return r.forEach((o, a) => {
1967
+ const c = e.findIndex(
1968
+ (l) => l._id === o._id
1969
+ );
1970
+ 0 <= c && c < e.length && (e[c] = i[a]);
1971
+ }), e.filter((o) => !!o);
1972
+ }
2994
1973
  return e;
2995
1974
  }
1975
+ /**
1976
+ * Get the URL of the thumbnail of a workspace element (or its URL),
1977
+ * or `null` if none exists or can be created.
1978
+ */
1979
+ getThumbnailUrl(e, t = 0, s = 0) {
1980
+ var i, o;
1981
+ const r = t > 0 || s > 0 ? `${t}x${s}` : "120x120";
1982
+ if (typeof e == "string")
1983
+ return e.includes("data:image") || e.includes("thumbnail") ? e : `${e}${e.includes("?") ? "&" : "?"}thumbnail=${r}`;
1984
+ {
1985
+ const a = `/workspace/${e.public ? "pub/" : ""}document/${e._id}?thumbnail=`, c = e.thumbnails;
1986
+ if ((o = (i = e.metadata) == null ? void 0 : i["content-type"]) != null && o.includes("video")) {
1987
+ const l = c && Object.keys(c).length > 0 ? Object.keys(c)[0] : null;
1988
+ return l ? a + l : null;
1989
+ } else
1990
+ return a + r;
1991
+ }
1992
+ }
2996
1993
  }
2997
1994
  let ATTag;
2998
1995
  class AnalyticsService {
2999
- constructor(o) {
3000
- this.context = o;
1996
+ constructor(n) {
1997
+ this.context = n;
1998
+ }
1999
+ get conf() {
2000
+ return this.context.conf();
3001
2001
  }
3002
2002
  get http() {
3003
2003
  return this.context.http();
@@ -3010,7 +2010,7 @@ class AnalyticsService {
3010
2010
  * @param locationPath
3011
2011
  * @param app
3012
2012
  */
3013
- async trackPageLoad(o, e) {
2013
+ async trackPageLoad(n, e) {
3014
2014
  const [t] = await Promise.all([
3015
2015
  // get Xiti configuration
3016
2016
  this.getXitiConfig(e.name.toLowerCase()),
@@ -3020,7 +2020,7 @@ class AnalyticsService {
3020
2020
  if (!t || !ATInternet) return;
3021
2021
  let s = t.LIBELLE_SERVICE.default || null;
3022
2022
  for (const r in t.LIBELLE_SERVICE)
3023
- if (r !== "default" && o.indexOf(r) >= 0) {
2023
+ if (r !== "default" && n.indexOf(r) >= 0) {
3024
2024
  s = t.LIBELLE_SERVICE[r];
3025
2025
  break;
3026
2026
  }
@@ -3047,7 +2047,7 @@ class AnalyticsService {
3047
2047
  level2: t.STRUCT_UAI
3048
2048
  }), ATTag.dispatch();
3049
2049
  }
3050
- async getXitiConfig(o) {
2050
+ async getXitiConfig(n) {
3051
2051
  const [e, t] = await Promise.all([
3052
2052
  this.http.get("/analyticsConf"),
3053
2053
  //FIXME change servers config to only keep the "all-in-one" query to /analyticsConf.
@@ -3055,7 +2055,7 @@ class AnalyticsService {
3055
2055
  ]);
3056
2056
  if (!(e != null && e.type))
3057
2057
  throw ERROR_CODE.MALFORMED_DATA;
3058
- return t != null && t.active && (e.xiti = await this.getXitiTrackingParams(t, o)), e.xiti;
2058
+ return t != null && t.active && (e.xiti = await this.getXitiTrackingParams(t, n)), e.xiti;
3059
2059
  }
3060
2060
  async loadXitiScript() {
3061
2061
  if (typeof ATInternet > "u") {
@@ -3067,28 +2067,28 @@ class AnalyticsService {
3067
2067
  eval(response);
3068
2068
  }
3069
2069
  }
3070
- async getXitiTrackingParams(o, e) {
3071
- if (!o.structureMap || !e) return;
2070
+ async getXitiTrackingParams(n, e) {
2071
+ if (!n.structureMap || !e) return;
3072
2072
  const t = await this.session.getUser(), s = await this.session.getUserProfile();
3073
2073
  let r;
3074
2074
  if (!(t != null && t.structures)) return;
3075
- for (const h of t.structures) {
3076
- const l = o.structureMap[h];
3077
- if (l && l.collectiviteId && l.UAI) {
3078
- r = l;
2075
+ for (const l of t.structures) {
2076
+ const h = n.structureMap[l];
2077
+ if (h && h.collectiviteId && h.UAI) {
2078
+ r = h;
3079
2079
  break;
3080
2080
  }
3081
2081
  }
3082
2082
  if (!r || !r.active) return;
3083
- const i = await configure.Platform.apps.getPublicConf(e);
2083
+ const i = await this.conf.getPublicConf(e);
3084
2084
  if (!i) return;
3085
- const u = i.xiti;
3086
- if (!u || !u.LIBELLE_SERVICE || !r.UAI) return;
3087
- function a(h) {
3088
- let l = "";
3089
- for (let E = 0; E < h.length; E++)
3090
- l += h.charCodeAt(E);
3091
- return l;
2085
+ const o = i.xiti;
2086
+ if (!o || !o.LIBELLE_SERVICE || !r.UAI) return;
2087
+ function a(l) {
2088
+ let h = "";
2089
+ for (let E = 0; E < l.length; E++)
2090
+ h += l.charCodeAt(E);
2091
+ return h;
3092
2092
  }
3093
2093
  const c = {
3094
2094
  Student: "ELEVE",
@@ -3098,21 +2098,21 @@ class AnalyticsService {
3098
2098
  Guest: "AUTRE"
3099
2099
  };
3100
2100
  return {
3101
- LIBELLE_SERVICE: u.LIBELLE_SERVICE,
2101
+ LIBELLE_SERVICE: o.LIBELLE_SERVICE,
3102
2102
  // Which property of LIBELLE_SERVICE to use depends on the frontend.
3103
- TYPE: u.OUTIL ? "TIERS" : "NATIF",
3104
- OUTIL: u.OUTIL ? u.OUTIL : "",
2103
+ TYPE: o.OUTIL ? "TIERS" : "NATIF",
2104
+ OUTIL: o.OUTIL ? o.OUTIL : "",
3105
2105
  STRUCT_ID: r.collectiviteId,
3106
2106
  STRUCT_UAI: r.UAI,
3107
- PROJET: r.projetId ? r.projetId : o.ID_PROJET,
3108
- EXPLOITANT: o.ID_EXPLOITANT,
3109
- PLATFORME: r.plateformeId ? r.plateformeId : o.ID_PLATEFORME,
2107
+ PROJET: r.projetId ? r.projetId : n.ID_PROJET,
2108
+ EXPLOITANT: n.ID_EXPLOITANT,
2109
+ PLATFORME: r.plateformeId ? r.plateformeId : n.ID_PLATEFORME,
3110
2110
  ID_PERSO: a(t.userId),
3111
2111
  PROFILE: s && s.length > 0 ? c[s[0]] ?? "" : ""
3112
2112
  };
3113
2113
  }
3114
2114
  }
3115
- const C = class C {
2115
+ const w = class w {
3116
2116
  // in minutes. Applies to recorded videos.
3117
2117
  constructor(e) {
3118
2118
  this.context = e;
@@ -3130,11 +2130,11 @@ const C = class C {
3130
2130
  async getVideoConf() {
3131
2131
  var t;
3132
2132
  const e = await this.conf.getPublicConf(
3133
- APP$1.VIDEO
2133
+ APP$2.VIDEO
3134
2134
  );
3135
2135
  return {
3136
- maxWeight: (e == null ? void 0 : e["max-videosize-mbytes"]) ?? C.MAX_WEIGHT,
3137
- maxDuration: (e == null ? void 0 : e["max-videoduration-minutes"]) ?? C.MAX_DURATION,
2136
+ maxWeight: (e == null ? void 0 : e["max-videosize-mbytes"]) ?? w.MAX_WEIGHT,
2137
+ maxDuration: (e == null ? void 0 : e["max-videoduration-minutes"]) ?? w.MAX_DURATION,
3138
2138
  acceptVideoUploadExtensions: ((t = e == null ? void 0 : e["accept-videoupload-extensions"]) == null ? void 0 : t.map(
3139
2139
  (s) => s.toUpperCase()
3140
2140
  )) ?? []
@@ -3155,22 +2155,22 @@ const C = class C {
3155
2155
  throw new Error("Invalid video file.");
3156
2156
  if (!e.filename)
3157
2157
  throw new Error("Invalid video filename");
3158
- const i = `${e.browser.name} ${e.browser.version}`, u = new FormData();
3159
- u.append("device", e.device || ""), u.append("browser", i), u.append("url", e.url), u.append("app", t), u.append("file", e.file, e.filename), u.append("weight", "" + e.file.size), u.append("captation", "" + s);
2158
+ const i = `${e.browser.name} ${e.browser.version}`, o = new FormData();
2159
+ o.append("device", e.device || ""), o.append("browser", i), o.append("url", e.url), o.append("app", t), o.append("file", e.file, e.filename), o.append("weight", "" + e.file.size), o.append("captation", "" + s);
3160
2160
  let a = `/video/encode?captation=${s}`;
3161
2161
  r && (a += `&duration=${r}`);
3162
2162
  const c = await this.http.post(
3163
2163
  a,
3164
- u,
2164
+ o,
3165
2165
  { headers: { "Content-Type": "multipart/form-data" } }
3166
2166
  );
3167
2167
  if (c.state == "running") {
3168
- let h = 0, l = 1;
2168
+ let l = 0, h = 1;
3169
2169
  do {
3170
- const E = l + h;
2170
+ const E = h + l;
3171
2171
  await new Promise(
3172
2172
  (d) => setTimeout(d, E * 1e3)
3173
- ), h = l, l = Math.min(8, E);
2173
+ ), l = h, h = Math.min(8, E);
3174
2174
  const p = await this.http.get(
3175
2175
  `/video/status/${c.processid}`
3176
2176
  );
@@ -3191,9 +2191,9 @@ const C = class C {
3191
2191
  throw new Error("Video cannot be uploaded.");
3192
2192
  }
3193
2193
  };
3194
- n(C, "MAX_WEIGHT", 50), // in Mbytes. Applies to uploaded videos.
3195
- n(C, "MAX_DURATION", 3);
3196
- let VideoService = C;
2194
+ u(w, "MAX_WEIGHT", 50), // in Mbytes. Applies to uploaded videos.
2195
+ u(w, "MAX_DURATION", 3);
2196
+ let VideoService = w;
3197
2197
  class EmbedderService {
3198
2198
  constructor(e) {
3199
2199
  this.context = e;
@@ -3229,11 +2229,11 @@ class EmbedderService {
3229
2229
  urlIsFromPattern(e, t) {
3230
2230
  const s = new RegExp("[^{}]+(?=(?:[^{}]*{[^}]*})*[^}]*$)", "g"), r = new RegExp("{[^}]*}", "g");
3231
2231
  let i = !0;
3232
- const u = t.match(s) || [], a = [];
3233
- return (t.match(r) || []).forEach((h, l) => {
3234
- h.includes("ignore") || a.push(u[l]);
3235
- }), a.forEach((h) => {
3236
- if (!e.includes(h)) {
2232
+ const o = t.match(s) || [], a = [];
2233
+ return (t.match(r) || []).forEach((l, h) => {
2234
+ l.includes("ignore") || a.push(o[h]);
2235
+ }), a.forEach((l) => {
2236
+ if (!e.includes(l)) {
3237
2237
  i = !1;
3238
2238
  return;
3239
2239
  }
@@ -3262,20 +2262,20 @@ class EmbedderService {
3262
2262
  for (const s of e.url)
3263
2263
  if (this.urlIsFromPattern(t, s)) {
3264
2264
  const r = new RegExp("{[a-zA-Z0-9_.]+}", "g"), i = s.match(r) || [];
3265
- let u = e.embed;
2265
+ let o = e.embed;
3266
2266
  for (const a of i) {
3267
2267
  let c = s.split(a)[0];
3268
- const h = c.split("}");
3269
- h.length > 1 && (c = h[h.length - 1]);
3270
- let l = t.split(c)[1];
3271
- if (!l)
2268
+ const l = c.split("}");
2269
+ l.length > 1 && (c = l[l.length - 1]);
2270
+ let h = t.split(c)[1];
2271
+ if (!h)
3272
2272
  continue;
3273
2273
  const E = s.split(a)[1].split("{")[0];
3274
- E && (l = l.split(E)[0]);
2274
+ E && (h = h.split(E)[0]);
3275
2275
  const p = new RegExp("\\" + a.replace(/}/, "\\}"), "g");
3276
- u = u.replace(p, l);
2276
+ o = o.replace(p, h);
3277
2277
  }
3278
- return u;
2278
+ return o;
3279
2279
  }
3280
2280
  return "";
3281
2281
  }
@@ -3288,7 +2288,7 @@ class AbstractBehaviourService {
3288
2288
  //-----------------
3289
2289
  //--- Utilities ---
3290
2290
  //-----------------
3291
- n(this, "_cache");
2291
+ u(this, "_cache");
3292
2292
  this.context = e, this._cache = new CacheService(this.context);
3293
2293
  }
3294
2294
  getApplication() {
@@ -3322,8 +2322,8 @@ class AbstractBehaviourService {
3322
2322
  class ActualitesBehaviour extends AbstractBehaviourService {
3323
2323
  constructor() {
3324
2324
  super(...arguments);
3325
- n(this, "APP", "actualites");
3326
- n(this, "RESOURCE", "actualites");
2325
+ u(this, "APP", "actualites");
2326
+ u(this, "RESOURCE", "actualites");
3327
2327
  }
3328
2328
  async loadResources() {
3329
2329
  return (await this.httpGet(
@@ -3346,24 +2346,24 @@ class ActualitesBehaviour extends AbstractBehaviourService {
3346
2346
  class BlogBehaviour extends AbstractBehaviourService {
3347
2347
  constructor() {
3348
2348
  super(...arguments);
3349
- n(this, "APP", "blog");
3350
- n(this, "RESOURCE", "blog");
2349
+ u(this, "APP", "blog");
2350
+ u(this, "RESOURCE", "blog");
3351
2351
  }
3352
2352
  loadResources() {
3353
2353
  return new Promise(async (t, s) => {
3354
2354
  try {
3355
2355
  const r = await this.httpGet("/blog/linker"), i = [];
3356
- r.forEach((u) => {
3357
- u.thumbnail ? u.thumbnail = u.thumbnail + "?thumbnail=48x48" : u.thumbnail = "/img/illustrations/blog.svg";
3358
- const a = u.fetchPosts.map((c) => this.dataToResource({
3359
- owner: u.author.userId,
3360
- ownerName: u.author.username,
3361
- title: c.title + " [" + u.title + "]",
3362
- _id: `${u._id}#${c._id}`,
3363
- icon: u.thumbnail,
3364
- path: `/blog/id/${u._id}/post/${c._id}`,
3365
- shared: !!(u.shared && u.shared.length >= 0),
3366
- modified: u.modified
2356
+ r.forEach((o) => {
2357
+ o.thumbnail ? o.thumbnail = o.thumbnail + "?thumbnail=48x48" : o.thumbnail = "/img/illustrations/blog.svg";
2358
+ const a = o.fetchPosts.map((c) => this.dataToResource({
2359
+ owner: o.author.userId,
2360
+ ownerName: o.author.username,
2361
+ title: c.title + " [" + o.title + "]",
2362
+ _id: `${o._id}#${c._id}`,
2363
+ icon: o.thumbnail,
2364
+ path: `/blog/id/${o._id}/post/${c._id}`,
2365
+ shared: !!(o.shared && o.shared.length >= 0),
2366
+ modified: o.modified
3367
2367
  }));
3368
2368
  i.push(...a);
3369
2369
  }), t(i);
@@ -3376,8 +2376,8 @@ class BlogBehaviour extends AbstractBehaviourService {
3376
2376
  class CollaborativewallBehaviour extends AbstractBehaviourService {
3377
2377
  constructor() {
3378
2378
  super(...arguments);
3379
- n(this, "APP", "collaborativewall");
3380
- n(this, "RESOURCE", "collaborativewall");
2379
+ u(this, "APP", "collaborativewall");
2380
+ u(this, "RESOURCE", "collaborativewall");
3381
2381
  }
3382
2382
  async loadResources() {
3383
2383
  return (await this.httpGet(
@@ -3399,8 +2399,8 @@ class CollaborativewallBehaviour extends AbstractBehaviourService {
3399
2399
  class CommunityBehaviour extends AbstractBehaviourService {
3400
2400
  constructor() {
3401
2401
  super(...arguments);
3402
- n(this, "APP", "community");
3403
- n(this, "RESOURCE", "community");
2402
+ u(this, "APP", "community");
2403
+ u(this, "RESOURCE", "community");
3404
2404
  }
3405
2405
  async loadResources() {
3406
2406
  return (await this.httpGet(
@@ -3424,23 +2424,23 @@ class CommunityBehaviour extends AbstractBehaviourService {
3424
2424
  class ExercizerBehaviour extends AbstractBehaviourService {
3425
2425
  constructor() {
3426
2426
  super(...arguments);
3427
- n(this, "APP", "exercizer");
3428
- n(this, "RESOURCE", "exercizer");
2427
+ u(this, "APP", "exercizer");
2428
+ u(this, "RESOURCE", "exercizer");
3429
2429
  }
3430
2430
  async loadResources() {
3431
2431
  return (await this.httpGet(
3432
2432
  "/exercizer/subjects-scheduled"
3433
2433
  )).map((s) => {
3434
2434
  const r = s.picture ? s.picture + "?thumbnail=48x48" : "/img/illustrations/exercizer.svg";
3435
- let i, u = !1, a = JSON.parse(s.scheduled_at);
3436
- return a.groupList.length > 0 ? (u = !0, i = a.groupList[0].name) : a.userList.length > 0 ? (u = !0, i = a.userList[0].name) : i = "", a.groupList.length + a.userList.length > 1 && (i += "..."), this.dataToResource({
2435
+ let i, o = !1, a = JSON.parse(s.scheduled_at);
2436
+ return a.groupList.length > 0 ? (o = !0, i = a.groupList[0].name) : a.userList.length > 0 ? (o = !0, i = a.userList[0].name) : i = "", a.groupList.length + a.userList.length > 1 && (i += "..."), this.dataToResource({
3437
2437
  title: s.title,
3438
2438
  owner: s.owner,
3439
2439
  ownerName: i,
3440
2440
  icon: r,
3441
2441
  path: "/exercizer#/linker/" + s.id,
3442
2442
  _id: "" + s.id,
3443
- shared: u,
2443
+ shared: o,
3444
2444
  modified: s.modified
3445
2445
  });
3446
2446
  });
@@ -3449,8 +2449,8 @@ class ExercizerBehaviour extends AbstractBehaviourService {
3449
2449
  class FormulaireBehaviour extends AbstractBehaviourService {
3450
2450
  constructor() {
3451
2451
  super(...arguments);
3452
- n(this, "APP", "formulaire");
3453
- n(this, "RESOURCE", "formulaire");
2452
+ u(this, "APP", "formulaire");
2453
+ u(this, "RESOURCE", "formulaire");
3454
2454
  }
3455
2455
  async loadResources() {
3456
2456
  return (await this.httpGet(
@@ -3470,8 +2470,8 @@ class FormulaireBehaviour extends AbstractBehaviourService {
3470
2470
  class ForumBehaviour extends AbstractBehaviourService {
3471
2471
  constructor() {
3472
2472
  super(...arguments);
3473
- n(this, "APP", "forum");
3474
- n(this, "RESOURCE", "forum");
2473
+ u(this, "APP", "forum");
2474
+ u(this, "RESOURCE", "forum");
3475
2475
  }
3476
2476
  async loadResources() {
3477
2477
  return (await this.httpGet("/forum/categories")).map(
@@ -3491,8 +2491,8 @@ class ForumBehaviour extends AbstractBehaviourService {
3491
2491
  class HomeworksBehaviour extends AbstractBehaviourService {
3492
2492
  constructor() {
3493
2493
  super(...arguments);
3494
- n(this, "APP", "homeworks");
3495
- n(this, "RESOURCE", "homeworks");
2494
+ u(this, "APP", "homeworks");
2495
+ u(this, "RESOURCE", "homeworks");
3496
2496
  }
3497
2497
  async loadResources() {
3498
2498
  return (await this.httpGet("/homeworks/list")).filter((t) => t.owner && t.trashed === 0).map((t) => this.dataToResource({
@@ -3510,8 +2510,8 @@ class HomeworksBehaviour extends AbstractBehaviourService {
3510
2510
  class MagnetoBehaviour extends AbstractBehaviourService {
3511
2511
  constructor() {
3512
2512
  super(...arguments);
3513
- n(this, "APP", "magneto");
3514
- n(this, "RESOURCE", "magneto");
2513
+ u(this, "APP", "magneto");
2514
+ u(this, "RESOURCE", "magneto");
3515
2515
  }
3516
2516
  async loadResources() {
3517
2517
  const { all: t } = await this.httpGet(
@@ -3532,8 +2532,8 @@ class MagnetoBehaviour extends AbstractBehaviourService {
3532
2532
  class MindmapBehaviour extends AbstractBehaviourService {
3533
2533
  constructor() {
3534
2534
  super(...arguments);
3535
- n(this, "APP", "mindmap");
3536
- n(this, "RESOURCE", "mindmap");
2535
+ u(this, "APP", "mindmap");
2536
+ u(this, "RESOURCE", "mindmap");
3537
2537
  }
3538
2538
  async loadResources() {
3539
2539
  return (await this.httpGet("/mindmap/list/all")).map(
@@ -3553,13 +2553,13 @@ class MindmapBehaviour extends AbstractBehaviourService {
3553
2553
  class PagesBehaviour extends AbstractBehaviourService {
3554
2554
  constructor() {
3555
2555
  super(...arguments);
3556
- n(this, "APP", "pages");
3557
- n(this, "RESOURCE", "pages");
2556
+ u(this, "APP", "pages");
2557
+ u(this, "RESOURCE", "pages");
3558
2558
  }
3559
2559
  async loadResources() {
3560
2560
  const t = await this.httpGet("/pages/list/all"), s = [];
3561
2561
  return t.forEach((r) => {
3562
- var u;
2562
+ var o;
3563
2563
  const i = r.thumbnail ? r.thumbnail + "?thumbnail=48x48" : "/img/illustrations/pages.svg";
3564
2564
  s.push(
3565
2565
  this.dataToResource({
@@ -3572,7 +2572,7 @@ class PagesBehaviour extends AbstractBehaviourService {
3572
2572
  shared: typeof r.shared < "u",
3573
2573
  modified: r.modified
3574
2574
  })
3575
- ), (u = r.pages) == null || u.forEach((a) => {
2575
+ ), (o = r.pages) == null || o.forEach((a) => {
3576
2576
  s.push(
3577
2577
  this.dataToResource({
3578
2578
  title: a.title,
@@ -3592,8 +2592,8 @@ class PagesBehaviour extends AbstractBehaviourService {
3592
2592
  class PollBehaviour extends AbstractBehaviourService {
3593
2593
  constructor() {
3594
2594
  super(...arguments);
3595
- n(this, "APP", "poll");
3596
- n(this, "RESOURCE", "poll");
2595
+ u(this, "APP", "poll");
2596
+ u(this, "RESOURCE", "poll");
3597
2597
  }
3598
2598
  async loadResources() {
3599
2599
  return (await this.httpGet("/poll/list/all")).map((s) => {
@@ -3614,8 +2614,8 @@ class PollBehaviour extends AbstractBehaviourService {
3614
2614
  class ScrapbookBehaviour extends AbstractBehaviourService {
3615
2615
  constructor() {
3616
2616
  super(...arguments);
3617
- n(this, "APP", "scrapbook");
3618
- n(this, "RESOURCE", "scrapbook");
2617
+ u(this, "APP", "scrapbook");
2618
+ u(this, "RESOURCE", "scrapbook");
3619
2619
  }
3620
2620
  async loadResources() {
3621
2621
  return (await this.httpGet(
@@ -3638,25 +2638,25 @@ class ScrapbookBehaviour extends AbstractBehaviourService {
3638
2638
  class TimelinegeneratorBehaviour extends AbstractBehaviourService {
3639
2639
  constructor() {
3640
2640
  super(...arguments);
3641
- n(this, "APP", "timelinegenerator");
3642
- n(this, "RESOURCE", "timelinegenerator");
2641
+ u(this, "APP", "timelinegenerator");
2642
+ u(this, "RESOURCE", "timelinegenerator");
3643
2643
  }
3644
2644
  loadResources() {
3645
2645
  return new Promise(async (t, s) => {
3646
2646
  try {
3647
2647
  const i = (await this.httpGet(
3648
2648
  "/timelinegenerator/timelines"
3649
- )).map((u) => {
3650
- const a = u.icon || "/img/illustrations/timeline-default.png";
2649
+ )).map((o) => {
2650
+ const a = o.icon || "/img/illustrations/timeline-default.png";
3651
2651
  return this.dataToResource({
3652
- title: u.headline,
3653
- ownerName: u.owner.displayName,
3654
- owner: u.owner.userId,
2652
+ title: o.headline,
2653
+ ownerName: o.owner.displayName,
2654
+ owner: o.owner.userId,
3655
2655
  icon: a,
3656
- path: "/timelinegenerator#/view/" + u._id,
3657
- _id: u._id,
3658
- shared: typeof u.shared < "u",
3659
- modified: u.modified
2656
+ path: "/timelinegenerator#/view/" + o._id,
2657
+ _id: o._id,
2658
+ shared: typeof o.shared < "u",
2659
+ modified: o.modified
3660
2660
  });
3661
2661
  });
3662
2662
  t(i);
@@ -3669,11 +2669,13 @@ class TimelinegeneratorBehaviour extends AbstractBehaviourService {
3669
2669
  class WikiBehaviour extends AbstractBehaviourService {
3670
2670
  constructor() {
3671
2671
  super(...arguments);
3672
- n(this, "APP", "wiki");
3673
- n(this, "RESOURCE", "wiki");
2672
+ u(this, "APP", "wiki");
2673
+ u(this, "RESOURCE", "wiki");
3674
2674
  }
3675
2675
  async loadResources() {
3676
- return (await this.httpGet("/wiki/listallpages?visible=true")).map((s) => s.pages.map((r) => {
2676
+ return (await this.httpGet(
2677
+ "/wiki/listallpages?visible=true"
2678
+ )).map((s) => s.pages.map((r) => {
3677
2679
  let i;
3678
2680
  return typeof s.thumbnail > "u" || s.thumbnail === "" ? i = "/img/icons/glyphicons_036_file.png" : i = s.thumbnail + "?thumbnail=48x48", this.dataToResource({
3679
2681
  title: r.title + " [" + s.title + "]",
@@ -3691,30 +2693,30 @@ class WikiBehaviour extends AbstractBehaviourService {
3691
2693
  class WorkspaceBehaviour extends AbstractBehaviourService {
3692
2694
  constructor() {
3693
2695
  super(...arguments);
3694
- n(this, "APP", "workspace");
3695
- n(this, "RESOURCE", "workspace");
2696
+ u(this, "APP", "workspace");
2697
+ u(this, "RESOURCE", "workspace");
3696
2698
  }
3697
2699
  loadResources({ search: t, asset_id: s }) {
3698
2700
  return new Promise(async (r, i) => {
3699
2701
  try {
3700
- let u = "/workspace/documents?filter=all&hierarchical=true";
3701
- s && s.length ? u += `&search=${t}` : t && t.length && (u += `&search=${t}`);
3702
- const c = (await this.httpGet(u)).filter((h) => !h.deleted).map((h) => {
3703
- const l = h.metadata["content-type"] && h.metadata["content-type"].indexOf("image") !== -1 ? `/workspace/document/${h._id}?thumbnail=120x120` : "/img/icons/unknown-large.png";
2702
+ let o = "/workspace/documents?filter=all&hierarchical=true";
2703
+ s && s.length ? o += `&search=${t}` : t && t.length && (o += `&search=${t}`);
2704
+ const c = (await this.httpGet(o)).filter((l) => !l.deleted).map((l) => {
2705
+ const h = l.metadata["content-type"] && l.metadata["content-type"].indexOf("image") !== -1 ? `/workspace/document/${l._id}?thumbnail=120x120` : "/img/icons/unknown-large.png";
3704
2706
  return this.dataToResource({
3705
- title: h.name,
3706
- ownerName: h.ownerName,
3707
- owner: h.owner,
3708
- icon: l,
3709
- path: `/workspace/document/${h._id}`,
3710
- _id: h._id,
3711
- shared: !!(h.shared && h.shared.length >= 0),
3712
- modified: h.modified
2707
+ title: l.name,
2708
+ ownerName: l.ownerName,
2709
+ owner: l.owner,
2710
+ icon: h,
2711
+ path: `/workspace/document/${l._id}`,
2712
+ _id: l._id,
2713
+ shared: !!(l.shared && l.shared.length >= 0),
2714
+ modified: l.modified
3713
2715
  });
3714
2716
  });
3715
2717
  r(c);
3716
- } catch (u) {
3717
- i(u);
2718
+ } catch (o) {
2719
+ i(o);
3718
2720
  }
3719
2721
  });
3720
2722
  }
@@ -3730,7 +2732,7 @@ const y = class y {
3730
2732
  e.session().getUser()
3731
2733
  ]);
3732
2734
  i != null && i.apps && (r != null && r.length) && (this.resourceProducingApps = r.filter(
3733
- (u) => i.apps.some((a) => a.address.includes(u))
2735
+ (o) => i.apps.some((a) => a.address.includes(o))
3734
2736
  ));
3735
2737
  } catch (r) {
3736
2738
  console.warn("Failed to load resource-producing apps:", r);
@@ -3807,13 +2809,13 @@ const y = class y {
3807
2809
  //
3808
2810
  // STATIC REGISTRY
3809
2811
  //
3810
- n(y, "registry", new ServiceRegistry()), // Expose some useful functions
3811
- n(y, "findBehaviour", y.registry.findService.bind(y.registry)), n(y, "hasBehaviour", y.registry.isRegistered.bind(y.registry)), n(y, "resourceProducingApps", []);
2812
+ u(y, "registry", new ServiceRegistry()), // Expose some useful functions
2813
+ u(y, "findBehaviour", y.registry.findService.bind(y.registry)), u(y, "hasBehaviour", y.registry.isRegistered.bind(y.registry)), u(y, "resourceProducingApps", []);
3812
2814
  let SnipletsService = y;
3813
2815
  const SEND_ALL = "*";
3814
2816
  class WebBroker {
3815
2817
  constructor(e) {
3816
- n(this, "subscription");
2818
+ u(this, "subscription");
3817
2819
  this.odeServices = e;
3818
2820
  }
3819
2821
  get http() {
@@ -3845,10 +2847,10 @@ class WebBroker {
3845
2847
  }
3846
2848
  class DataService {
3847
2849
  constructor(e) {
3848
- n(this, "_webBroker");
3849
- n(this, "app");
3850
- n(this, "user");
3851
- n(this, "profile");
2850
+ u(this, "_webBroker");
2851
+ u(this, "app");
2852
+ u(this, "user");
2853
+ u(this, "profile");
3852
2854
  this.odeServices = e;
3853
2855
  }
3854
2856
  get conf() {
@@ -3882,12 +2884,12 @@ class DataService {
3882
2884
  addUserInfos(e) {
3883
2885
  return this.user && (e.userId = this.user.userId, e.structure = this.user.structureNames[0]), this.profile && (e.profil = this.profile[0]), e;
3884
2886
  }
3885
- trackVideoSave(e, t, s, r, i, u, a) {
2887
+ trackVideoSave(e, t, s, r, i, o, a) {
3886
2888
  const c = this.addUserInfos({
3887
2889
  "event-type": "VIDEO_SAVE",
3888
2890
  module: "video",
3889
2891
  video_id: e,
3890
- browser: u,
2892
+ browser: o,
3891
2893
  duration: Math.round(t),
3892
2894
  weight: s,
3893
2895
  source: r ? "CAPTURED" : "UPLOADED",
@@ -3896,7 +2898,7 @@ class DataService {
3896
2898
  this.app && (c["override-module"] = this.app), a && (c.device_type = a), this.trackWebEvent(c);
3897
2899
  }
3898
2900
  trackVideoRead(e, t, s, r, i) {
3899
- const u = this.addUserInfos({
2901
+ const o = this.addUserInfos({
3900
2902
  "event-type": "VIDEO_READ",
3901
2903
  module: "video",
3902
2904
  video_id: e,
@@ -3904,7 +2906,7 @@ class DataService {
3904
2906
  source: t ? "CAPTURED" : "UPLOADED",
3905
2907
  url: s
3906
2908
  });
3907
- this.app && (u["override-module"] = this.app), i && (u.device_type = i), this.trackWebEvent(u);
2909
+ this.app && (o["override-module"] = this.app), i && (o.device_type = i), this.trackWebEvent(o);
3908
2910
  }
3909
2911
  trackSpeechAndText(e) {
3910
2912
  const t = this.addUserInfos({
@@ -4010,20 +3012,20 @@ class AudienceService {
4010
3012
  }
4011
3013
  class OdeServices {
4012
3014
  constructor() {
4013
- n(this, "_analytics");
4014
- n(this, "_cache");
4015
- n(this, "_conf");
4016
- n(this, "_data");
4017
- n(this, "_directory");
4018
- n(this, "_http");
4019
- n(this, "_idiom");
4020
- n(this, "_notify");
4021
- n(this, "_rights");
4022
- n(this, "_session");
4023
- n(this, "_share");
4024
- n(this, "_video");
4025
- n(this, "_workspace");
4026
- n(this, "_embedder");
3015
+ u(this, "_analytics");
3016
+ u(this, "_cache");
3017
+ u(this, "_conf");
3018
+ u(this, "_data");
3019
+ u(this, "_directory");
3020
+ u(this, "_http");
3021
+ u(this, "_idiom");
3022
+ u(this, "_notify");
3023
+ u(this, "_rights");
3024
+ u(this, "_session");
3025
+ u(this, "_share");
3026
+ u(this, "_video");
3027
+ u(this, "_workspace");
3028
+ u(this, "_embedder");
4027
3029
  this._analytics = new AnalyticsService(this), this._cache = new CacheService(this), this._conf = new ConfService(this), this._data = new DataService(this), this._directory = new DirectoryService(this), this._http = new HttpService(this), this._idiom = new IdiomService(this), this._notify = NotifyFrameworkFactory.instance(), this._rights = new RightService(this), this._session = new SessionService(this), this._share = new ShareService(this), this._video = new VideoService(this), this._workspace = new WorkspaceService(this), this._embedder = new EmbedderService(this);
4028
3030
  }
4029
3031
  initialize() {
@@ -4138,187 +3140,31 @@ const ACTION = {
4138
3140
  favorite?: boolean;
4139
3141
  comments?: number;
4140
3142
  */
4141
- }, odeServices = new OdeServices().initialize();
4142
- class SessionFrameworkFactory {
4143
- //-------------------------------------
4144
- static instance() {
4145
- return session;
4146
- }
4147
- }
4148
- const WIDGET_POSITION = {
3143
+ }, odeServices = new OdeServices().initialize(), WIDGET_POSITION = {
4149
3144
  LEFT: "left",
4150
3145
  RIGHT: "right"
4151
3146
  // TODO: position pourrait être étendu à d'autres valeurs: |“top” ou “bottom” ou “fixed”...
4152
- };
4153
- class TransportFrameworkFactory {
4154
- //-------------------------------------
4155
- static instance() {
4156
- return transport;
4157
- }
4158
- }
4159
- const isActionAvailable = (o, e) => {
3147
+ }, isActionAvailable = (n, e) => {
4160
3148
  const t = e == null ? void 0 : e.filter(
4161
- (s) => s.id === o && s.available
3149
+ (s) => s.id === n && s.available
4162
3150
  );
4163
3151
  return t && t.length > 0;
4164
- }, firstLevelWidgets = [
4165
- "birthday",
4166
- "mood",
4167
- "calendar-widget",
4168
- "notes"
4169
- ], secondLevelWidgets = [
4170
- "agenda-widget",
4171
- "carnet-de-bord",
4172
- "my-apps",
4173
- "rss-widget",
4174
- "bookmark-widget",
4175
- "cursus-widget",
4176
- "maxicours-widget",
4177
- "school-widget"
4178
- ], defaultWidgetPosition = {
4179
- "last-infos-widget": WIDGET_POSITION.LEFT,
4180
- // Actualités
4181
- birthday: WIDGET_POSITION.LEFT,
4182
- "calendar-widget": WIDGET_POSITION.RIGHT,
4183
- // Calendrier
4184
- "carnet-de-bord": WIDGET_POSITION.LEFT,
4185
- "record-me": WIDGET_POSITION.RIGHT,
4186
- // Dictaphone
4187
- mood: WIDGET_POSITION.LEFT,
4188
- "my-apps": WIDGET_POSITION.RIGHT,
4189
- notes: WIDGET_POSITION.RIGHT,
4190
- "rss-widget": WIDGET_POSITION.LEFT,
4191
- "bookmark-widget": WIDGET_POSITION.RIGHT,
4192
- qwant: WIDGET_POSITION.RIGHT,
4193
- "qwant-junior": WIDGET_POSITION.LEFT,
4194
- "agenda-widget": WIDGET_POSITION.LEFT,
4195
- // Agenda
4196
- "cursus-widget": WIDGET_POSITION.LEFT,
4197
- "maxicours-widget": WIDGET_POSITION.RIGHT,
4198
- "universalis-widget": WIDGET_POSITION.RIGHT,
4199
- "briefme-widget": WIDGET_POSITION.LEFT,
4200
- "school-widget": WIDGET_POSITION.LEFT
4201
- }, defaultWidgetOrder = {
4202
- "school-widget": 0,
4203
- "my-apps": 10,
4204
- "record-me": 15,
4205
- "last-infos-widget": 20,
4206
- // Actualités
4207
- qwant: 30,
4208
- "qwant-junior": 30,
4209
- "universalis-widget": 35,
4210
- "agenda-widget": 40,
4211
- // Agenda
4212
- "bookmark-widget": 50,
4213
- "carnet-de-bord": 60,
4214
- "maxicours-widget": 70,
4215
- "cursus-widget": 80,
4216
- // Dictaphone
4217
- "briefme-widget": 90,
4218
- "rss-widget": 100,
4219
- mood: 110,
4220
- birthday: 120,
4221
- "calendar-widget": 130,
4222
- // Calendrier
4223
- notes: 140
4224
3152
  };
4225
- class WidgetFramework {
4226
- constructor() {
4227
- //-------------------------------------
4228
- n(this, "_initialized");
4229
- n(this, "_widgets", []);
4230
- ////////////////////////////////////// USER PREFERENCES
4231
- n(this, "_userPrefs", {});
4232
- }
4233
- initialize(e, t) {
4234
- return this._initialized || (this._initialized = new Promisified(), notify.onSessionReady().promise.then((s) => {
4235
- var r;
4236
- s && s.widgets ? (s.widgets.forEach((i) => {
4237
- this._widgets.push(new Widget(i));
4238
- }), this.loadUserPrefs().then(() => {
4239
- var i;
4240
- (i = this._initialized) == null || i.resolve();
4241
- }).catch((i) => {
4242
- var u;
4243
- (u = this._initialized) == null || u.reject();
4244
- })) : (r = this._initialized) == null || r.reject();
4245
- })), this._initialized.promise;
4246
- }
4247
- ////////////////////////////////////// ACCESSORS
4248
- get list() {
4249
- return this._widgets;
4250
- }
4251
- lookup(e) {
4252
- return this._widgets.find((t) => t.platformConf.name === e);
4253
- }
4254
- lookupDefaultPosition(e) {
4255
- return defaultWidgetPosition[e];
4256
- }
4257
- get userPrefs() {
4258
- return this._userPrefs;
4259
- }
4260
- async loadUserPrefs() {
4261
- await configure.User.preferences.load("widgets", {}).then((e) => this.applyUserPrefs(e));
4262
- }
4263
- saveUserPrefs() {
4264
- return configure.User.preferences.update("widgets", this._userPrefs).save("widgets").then(() => {
4265
- notify.events().publish(LAYER_NAME.WIDGETS, {
4266
- name: EVENT_NAME.USERPREF_CHANGED
4267
- });
4268
- });
4269
- }
4270
- async applyUserPrefs(e) {
4271
- this._userPrefs = e ?? this._userPrefs;
4272
- const t = configure.Platform.theme, s = [];
4273
- t.listSkins().then((r) => {
4274
- var a;
4275
- const i = ((a = r.find((c) => c.child === t.skin)) == null ? void 0 : a.parent) === "panda" ? secondLevelWidgets : firstLevelWidgets;
4276
- this._widgets = this._widgets.filter((c, h) => {
4277
- const l = c.platformConf.name;
4278
- return i.indexOf(l) !== -1 ? !1 : (this._userPrefs[l] || (this._userPrefs[l] = {
4279
- index: defaultWidgetOrder[l] ?? 999,
4280
- show: !0,
4281
- position: c.platformConf.position
4282
- }), c.platformConf.mandatory && (this._userPrefs[l].show = !0, this._userPrefs[l].index = defaultWidgetOrder[l] ?? 999), c.platformConf.i18n && s.push(c.platformConf.i18n), c.applyUserPref(this._userPrefs[l]), !0);
4283
- });
4284
- const u = new Idiom();
4285
- this._widgets = this._widgets.sort((c, h) => {
4286
- const l = u.translate(`timeline.settings.${c.platformConf.name}`).toLowerCase(), E = u.translate(`timeline.settings.${h.platformConf.name}`).toLowerCase();
4287
- return l < E ? -1 : l > E ? 1 : 0;
4288
- });
4289
- });
4290
- }
4291
- }
4292
- class Widget {
4293
- //-------------------------------------
3153
+ class LastInfosWidget {
4294
3154
  constructor(e) {
4295
- n(this, "_schoolConf", {});
4296
- n(this, "_userPref");
4297
- this._platformConf = e, this._userPref = null;
4298
- }
4299
- get platformConf() {
4300
- return this._platformConf;
4301
- }
4302
- get schoolConf() {
4303
- return this._schoolConf;
4304
- }
4305
- get userPref() {
4306
- return this._userPref;
3155
+ this.context = e;
4307
3156
  }
4308
- applyUserPref(e) {
4309
- this._userPref = e, this._userPref.position = this._userPref.position ?? widgets.lookupDefaultPosition(this._platformConf.name) ?? "left";
3157
+ get http() {
3158
+ return this.context.http();
4310
3159
  }
4311
- }
4312
- const widgets = new WidgetFramework();
4313
- class LastInfosWidget {
4314
3160
  loadInfos(e) {
4315
- return transport.http.get("/actualites/infos/last/" + e);
3161
+ return this.http.get("/actualites/infos/last/" + e);
4316
3162
  }
4317
3163
  getMaxResults() {
4318
- return transport.http.get("/userbook/preference/maxInfos").then((e) => e.preference ? parseInt(e.preference) : 4);
3164
+ return this.http.get("/userbook/preference/maxInfos").then((e) => e.preference ? parseInt(e.preference) : 4);
4319
3165
  }
4320
3166
  setMaxResults(e) {
4321
- return transport.http.putJson(
3167
+ return this.http.putJson(
4322
3168
  "/userbook/preference/maxInfos",
4323
3169
  `"${e}"`
4324
3170
  );
@@ -4344,22 +3190,14 @@ const WIDGET_NAME = {
4344
3190
  BRIEFME: "briefme-widget",
4345
3191
  SCHOOL: "school-widget"
4346
3192
  };
4347
- class WidgetFrameworkFactory {
4348
- //-------------------------------------
4349
- static instance() {
4350
- return widgets;
4351
- }
4352
- }
4353
3193
  export {
4354
3194
  ACTION,
4355
- APP$1 as APP,
3195
+ APP$2 as APP,
4356
3196
  BOOLEAN_FILTER,
4357
- ConfigurationFrameworkFactory,
4358
3197
  DocumentHelper,
4359
3198
  ERROR_CODE,
4360
3199
  EVENT_NAME,
4361
3200
  FOLDER,
4362
- ITimelineFactory,
4363
3201
  LAYER_NAME,
4364
3202
  LastInfosWidget,
4365
3203
  NotifyFrameworkFactory,
@@ -4367,14 +3205,11 @@ export {
4367
3205
  ResourceService,
4368
3206
  SORT_BY,
4369
3207
  SORT_ORDER,
4370
- SessionFrameworkFactory,
4371
3208
  SnipletsService,
4372
3209
  StringUtils,
4373
- TransportFrameworkFactory,
4374
3210
  USER_PREFS,
4375
3211
  WIDGET_NAME,
4376
3212
  WIDGET_POSITION,
4377
- WidgetFrameworkFactory,
4378
3213
  isActionAvailable,
4379
3214
  odeServices
4380
3215
  };