@edifice.io/client 2.5.23-develop.20260623112621 → 2.5.23-develop.20260623175634

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
@@ -1082,9 +1082,9 @@ class Analytics {
1082
1082
  const t = await notify.onSessionReady().promise, s = session.session.description;
1083
1083
  let r;
1084
1084
  for (const l of t.structures) {
1085
- const h = e.structureMap[l];
1086
- if (h && h.collectiviteId && h.UAI) {
1087
- r = h;
1085
+ const p = e.structureMap[l];
1086
+ if (p && p.collectiviteId && p.UAI) {
1087
+ r = p;
1088
1088
  break;
1089
1089
  }
1090
1090
  }
@@ -1096,10 +1096,10 @@ class Analytics {
1096
1096
  const o = i.xiti;
1097
1097
  if (!o || !o.LIBELLE_SERVICE || !r.UAI) return;
1098
1098
  function a(l) {
1099
- let h = "";
1099
+ let p = "";
1100
1100
  for (let E = 0; E < l.length; E++)
1101
- h += l.charCodeAt(E);
1102
- return h;
1101
+ p += l.charCodeAt(E);
1102
+ return p;
1103
1103
  }
1104
1104
  const c = {
1105
1105
  Student: "ELEVE",
@@ -1635,27 +1635,22 @@ const m = class m {
1635
1635
  u(m, "registry", new ServiceRegistry()), // Expose some useful functions
1636
1636
  u(m, "register", m.registry.register.bind(m.registry)), u(m, "findService", m.registry.findService.bind(m.registry)), u(m, "findMainService", m.registry.findMainService.bind(m.registry)), u(m, "isRegistered", m.registry.isRegistered.bind(m.registry));
1637
1637
  let ResourceService = m;
1638
- const APP$3 = "collaborativeeditor", RESOURCE$3 = "collaborativeeditor";
1639
- class CollaborativeEditorResourceService extends ResourceService {
1640
- async create(e) {
1641
- const { name: t, description: s, thumbnail: r, folder: i } = e, o = r ? await this.getThumbnailPath(r) : "", a = await this.http.post("/collaborativeeditor", {
1642
- name: t,
1643
- description: s,
1644
- thumbnail: o,
1645
- folder: i
1646
- });
1647
- return this.checkHttpResponse(a), a;
1638
+ const APP$3 = "scrapbook", RESOURCE$3 = "scrapbook";
1639
+ class ScrapbookResourceService extends ResourceService {
1640
+ create(e) {
1641
+ throw new Error("Method not implemented.");
1648
1642
  }
1649
1643
  async update(e) {
1650
- const { name: t, description: s, thumbnail: r, entId: i } = e, o = await this.getThumbnailPath(r), a = await this.http.put(
1651
- `/collaborativeeditor/${i}`,
1644
+ const t = await this.getThumbnailPath(e.thumbnail), s = await this.http.put(
1645
+ `/scrapbook/${e.entId}`,
1652
1646
  {
1653
- name: t,
1654
- description: s,
1655
- thumbnail: o
1647
+ trashed: e.trashed ? 1 : 0,
1648
+ title: e.name,
1649
+ icon: t,
1650
+ subTitle: e.description
1656
1651
  }
1657
1652
  );
1658
- return this.checkHttpResponse(a), { thumbnail: o, entId: i };
1653
+ return this.checkHttpResponse(s), { thumbnail: t, entId: e.entId };
1659
1654
  }
1660
1655
  getResourceType() {
1661
1656
  return RESOURCE$3;
@@ -1663,25 +1658,25 @@ class CollaborativeEditorResourceService extends ResourceService {
1663
1658
  getApplication() {
1664
1659
  return APP$3;
1665
1660
  }
1666
- getFormUrl() {
1667
- throw new Error("Method not implemented.");
1661
+ getFormUrl(e) {
1662
+ return e ? `/scrapbook?folderid=${e}#/create-scrapbook/` : "/scrapbook#/create-scrapbook/";
1668
1663
  }
1669
1664
  getViewUrl(e) {
1670
- return `/collaborativeeditor#/view/${e}`;
1665
+ return `/scrapbook#/view-scrapbook/${e}`;
1671
1666
  }
1672
- getPrintUrl() {
1673
- throw new Error("Method not implemented.");
1667
+ getPrintUrl(e) {
1668
+ return `/scrapbook/print#/print-scrapbook/${e}`;
1674
1669
  }
1675
- getEditUrl() {
1676
- throw new Error("Method not implemented.");
1670
+ getEditUrl(e) {
1671
+ return `/scrapbook#/edit-scrapbook/${e}`;
1677
1672
  }
1678
- getExportUrl() {
1679
- throw new Error("Method not implemented.");
1673
+ getExportUrl(e) {
1674
+ return `/scrapbook/exportHtml/${e}`;
1680
1675
  }
1681
1676
  }
1682
1677
  ResourceService.register(
1683
1678
  { application: RESOURCE$3, resourceType: RESOURCE$3 },
1684
- (n) => new CollaborativeEditorResourceService(n)
1679
+ (n) => new ScrapbookResourceService(n)
1685
1680
  );
1686
1681
  const APP$2 = "homeworks", RESOURCE$2 = "homeworks";
1687
1682
  class HomeworksResourceService extends ResourceService {
@@ -1733,50 +1728,7 @@ ResourceService.register(
1733
1728
  { application: RESOURCE$2, resourceType: RESOURCE$2 },
1734
1729
  (n) => new HomeworksResourceService(n)
1735
1730
  );
1736
- const APP$1 = "scrapbook", RESOURCE$1 = "scrapbook";
1737
- class ScrapbookResourceService extends ResourceService {
1738
- create(e) {
1739
- throw new Error("Method not implemented.");
1740
- }
1741
- async update(e) {
1742
- const t = await this.getThumbnailPath(e.thumbnail), s = await this.http.put(
1743
- `/scrapbook/${e.entId}`,
1744
- {
1745
- trashed: e.trashed ? 1 : 0,
1746
- title: e.name,
1747
- icon: t,
1748
- subTitle: e.description
1749
- }
1750
- );
1751
- return this.checkHttpResponse(s), { thumbnail: t, entId: e.entId };
1752
- }
1753
- getResourceType() {
1754
- return RESOURCE$1;
1755
- }
1756
- getApplication() {
1757
- return APP$1;
1758
- }
1759
- getFormUrl(e) {
1760
- return e ? `/scrapbook?folderid=${e}#/create-scrapbook/` : "/scrapbook#/create-scrapbook/";
1761
- }
1762
- getViewUrl(e) {
1763
- return `/scrapbook#/view-scrapbook/${e}`;
1764
- }
1765
- getPrintUrl(e) {
1766
- return `/scrapbook/print#/print-scrapbook/${e}`;
1767
- }
1768
- getEditUrl(e) {
1769
- return `/scrapbook#/edit-scrapbook/${e}`;
1770
- }
1771
- getExportUrl(e) {
1772
- return `/scrapbook/exportHtml/${e}`;
1773
- }
1774
- }
1775
- ResourceService.register(
1776
- { application: RESOURCE$1, resourceType: RESOURCE$1 },
1777
- (n) => new ScrapbookResourceService(n)
1778
- );
1779
- const APP = "timelinegenerator", RESOURCE = "timelinegenerator";
1731
+ const APP$1 = "timelinegenerator", RESOURCE$1 = "timelinegenerator";
1780
1732
  class TimelineGeneratorResourceService extends ResourceService {
1781
1733
  async create(e) {
1782
1734
  const t = e.thumbnail ? await this.getThumbnailPath(e.thumbnail) : "", s = await this.http.post(
@@ -1806,10 +1758,10 @@ class TimelineGeneratorResourceService extends ResourceService {
1806
1758
  return this.checkHttpResponse(s), { thumbnail: t, entId: e.entId };
1807
1759
  }
1808
1760
  getResourceType() {
1809
- return RESOURCE;
1761
+ return RESOURCE$1;
1810
1762
  }
1811
1763
  getApplication() {
1812
- return APP;
1764
+ return APP$1;
1813
1765
  }
1814
1766
  getFormUrl() {
1815
1767
  throw new Error("Method not implemented.");
@@ -1828,226 +1780,68 @@ class TimelineGeneratorResourceService extends ResourceService {
1828
1780
  }
1829
1781
  }
1830
1782
  ResourceService.register(
1831
- { application: RESOURCE, resourceType: RESOURCE },
1783
+ { application: RESOURCE$1, resourceType: RESOURCE$1 },
1832
1784
  (n) => new TimelineGeneratorResourceService(n)
1833
1785
  );
1834
- let ATTag;
1835
- class AnalyticsService {
1836
- constructor(n) {
1837
- this.context = n;
1786
+ const APP = "collaborativeeditor", RESOURCE = "collaborativeeditor";
1787
+ class CollaborativeEditorResourceService extends ResourceService {
1788
+ async create(e) {
1789
+ const { name: t, description: s, thumbnail: r, folder: i } = e, o = r ? await this.getThumbnailPath(r) : "", a = await this.http.post("/collaborativeeditor", {
1790
+ name: t,
1791
+ description: s,
1792
+ thumbnail: o,
1793
+ folder: i
1794
+ });
1795
+ return this.checkHttpResponse(a), a;
1838
1796
  }
1839
- get http() {
1840
- return this.context.http();
1797
+ async update(e) {
1798
+ const { name: t, description: s, thumbnail: r, entId: i } = e, o = await this.getThumbnailPath(r), a = await this.http.put(
1799
+ `/collaborativeeditor/${i}`,
1800
+ {
1801
+ name: t,
1802
+ description: s,
1803
+ thumbnail: o
1804
+ }
1805
+ );
1806
+ return this.checkHttpResponse(a), { thumbnail: o, entId: i };
1841
1807
  }
1842
- get session() {
1843
- return this.context.session();
1808
+ getResourceType() {
1809
+ return RESOURCE;
1844
1810
  }
1845
- /**
1846
- * Xiti tracker for page loading.
1847
- * @param locationPath
1848
- * @param app
1849
- */
1850
- async trackPageLoad(n, e) {
1851
- const [t] = await Promise.all([
1852
- // get Xiti configuration
1853
- this.getXitiConfig(e.name.toLowerCase()),
1854
- // load Xiti javascript file
1855
- this.loadXitiScript()
1856
- ]);
1857
- if (!t || !ATInternet) return;
1858
- let s = t.LIBELLE_SERVICE.default || null;
1859
- for (const r in t.LIBELLE_SERVICE)
1860
- if (r !== "default" && n.indexOf(r) >= 0) {
1861
- s = t.LIBELLE_SERVICE[r];
1862
- break;
1863
- }
1864
- ATTag = new ATInternet.Tracker.Tag({ site: t.STRUCT_ID }), ATTag.setProps(
1865
- {
1866
- SERVICE: s,
1867
- TYPE: t.TYPE,
1868
- OUTIL: t.OUTIL,
1869
- UAI: t.STRUCT_UAI,
1870
- PROJET: t.PROJET,
1871
- EXPLOITANT: t.EXPLOITANT,
1872
- PLATEFORME: t.PLATFORME,
1873
- PROFIL: t.PROFILE
1874
- },
1875
- !0
1876
- ), ATTag.identifiedVisitor.set({
1877
- id: t.ID_PERSO,
1878
- category: t.PROFILE
1879
- }), ATTag.page.set({
1880
- name: (e == null ? void 0 : e.prefix) === "userbook" ? "directory" : e == null ? void 0 : e.prefix,
1881
- chapter1: "",
1882
- chapter2: "",
1883
- chapter3: "",
1884
- level2: t.STRUCT_UAI
1885
- }), ATTag.dispatch();
1811
+ getApplication() {
1812
+ return APP;
1886
1813
  }
1887
- async getXitiConfig(n) {
1888
- const [e, t] = await Promise.all([
1889
- this.http.get("/analyticsConf"),
1890
- //FIXME change servers config to only keep the "all-in-one" query to /analyticsConf.
1891
- this.http.get("/xiti/config")
1892
- ]);
1893
- if (!(e != null && e.type))
1894
- throw ERROR_CODE.MALFORMED_DATA;
1895
- return t != null && t.active && (e.xiti = await this.getXitiTrackingParams(t, n)), e.xiti;
1814
+ getFormUrl() {
1815
+ throw new Error("Method not implemented.");
1896
1816
  }
1897
- async loadXitiScript() {
1898
- if (typeof ATInternet > "u") {
1899
- const scriptPath = "/xiti/public/js/lib/smarttag_ENT.js", response = await this.http.get(scriptPath, {
1900
- headers: { Accept: "application/javascript" }
1901
- });
1902
- if (this.http.latestResponse.status != 200)
1903
- throw "Error while loading XiTi script";
1904
- eval(response);
1905
- }
1817
+ getViewUrl(e) {
1818
+ return `/collaborativeeditor#/view/${e}`;
1906
1819
  }
1907
- async getXitiTrackingParams(n, e) {
1908
- if (!n.structureMap || !e) return;
1909
- const t = await this.session.getUser(), s = await this.session.getUserProfile();
1910
- let r;
1911
- if (!(t != null && t.structures)) return;
1912
- for (const l of t.structures) {
1913
- const h = n.structureMap[l];
1914
- if (h && h.collectiviteId && h.UAI) {
1915
- r = h;
1916
- break;
1917
- }
1918
- }
1919
- if (!r || !r.active) return;
1920
- const i = await configure.Platform.apps.getPublicConf(e);
1921
- if (!i) return;
1922
- const o = i.xiti;
1923
- if (!o || !o.LIBELLE_SERVICE || !r.UAI) return;
1924
- function a(l) {
1925
- let h = "";
1926
- for (let E = 0; E < l.length; E++)
1927
- h += l.charCodeAt(E);
1928
- return h;
1929
- }
1930
- const c = {
1931
- Student: "ELEVE",
1932
- Teacher: "ENSEIGNANT",
1933
- Relative: "PARENT",
1934
- Personnel: "ADMIN_VIE_SCOL_TECH",
1935
- Guest: "AUTRE"
1936
- };
1937
- return {
1938
- LIBELLE_SERVICE: o.LIBELLE_SERVICE,
1939
- // Which property of LIBELLE_SERVICE to use depends on the frontend.
1940
- TYPE: o.OUTIL ? "TIERS" : "NATIF",
1941
- OUTIL: o.OUTIL ? o.OUTIL : "",
1942
- STRUCT_ID: r.collectiviteId,
1943
- STRUCT_UAI: r.UAI,
1944
- PROJET: r.projetId ? r.projetId : n.ID_PROJET,
1945
- EXPLOITANT: n.ID_EXPLOITANT,
1946
- PLATFORME: r.plateformeId ? r.plateformeId : n.ID_PLATEFORME,
1947
- ID_PERSO: a(t.userId),
1948
- PROFILE: s && s.length > 0 ? c[s[0]] ?? "" : ""
1949
- };
1820
+ getPrintUrl() {
1821
+ throw new Error("Method not implemented.");
1822
+ }
1823
+ getEditUrl() {
1824
+ throw new Error("Method not implemented.");
1825
+ }
1826
+ getExportUrl() {
1827
+ throw new Error("Method not implemented.");
1950
1828
  }
1951
1829
  }
1952
- class ReactionsService {
1953
- constructor(e, t, s) {
1954
- this.context = e, this.module = t, this.resourceType = s;
1830
+ ResourceService.register(
1831
+ { application: RESOURCE, resourceType: RESOURCE },
1832
+ (n) => new CollaborativeEditorResourceService(n)
1833
+ );
1834
+ const globalCache = {}, mutexPromise = {};
1835
+ class CacheService {
1836
+ constructor(e) {
1837
+ this.context = e;
1955
1838
  }
1956
1839
  get http() {
1957
1840
  return this.context.http();
1958
1841
  }
1959
- async loadAvailableReactions() {
1960
- try {
1961
- const { "reaction-types": e } = await this.context.conf().getPublicConf("audience");
1962
- return Array.isArray(e) ? e : void 0;
1963
- } catch {
1964
- console.error("Audience configuration not found");
1965
- return;
1966
- }
1967
- }
1968
- async loadReactionSummaries(e) {
1969
- const t = await this.http.get(
1970
- `/audience/reactions/${this.module}/${this.resourceType}?resourceIds=${e.join(",")}`
1971
- );
1972
- return this.http.isResponseError() ? {} : t.reactionsByResource;
1973
- }
1974
- async loadReactionDetails(e, t, s) {
1975
- const r = await this.http.get(
1976
- `/audience/reactions/${this.module}/${this.resourceType}/${e}?page=${t}&size=${s}`
1977
- );
1978
- return this.http.isResponseError() ? void 0 : r;
1979
- }
1980
- async deleteReaction(e) {
1981
- await this.http.delete(
1982
- `/audience/reactions/${this.module}/${this.resourceType}/${e}`
1983
- );
1984
- }
1985
- async updateReaction(e, t) {
1986
- await this.http.putJson(
1987
- `/audience/reactions/${this.module}/${this.resourceType}`,
1988
- {
1989
- resourceId: e,
1990
- reactionType: t
1991
- }
1992
- );
1993
- }
1994
- async createReaction(e, t) {
1995
- await this.http.postJson(
1996
- `/audience/reactions/${this.module}/${this.resourceType}`,
1997
- {
1998
- resourceId: e,
1999
- reactionType: t
2000
- }
2001
- );
2002
- }
2003
- }
2004
- class ViewsService {
2005
- constructor(e, t, s) {
2006
- this.context = e, this.module = t, this.resourceType = s;
2007
- }
2008
- get http() {
2009
- return this.context.http();
2010
- }
2011
- async getCounters(e) {
2012
- const t = await this.http.get(
2013
- `/audience/views/count/${this.module}/${this.resourceType}?resourceIds=${e.join(",")}`
2014
- );
2015
- return this.http.isResponseError() ? {} : t;
2016
- }
2017
- async getDetails(e) {
2018
- const t = await this.http.get(
2019
- `/audience/views/details/${this.module}/${this.resourceType}/${e}`
2020
- );
2021
- return this.http.isResponseError() ? void 0 : t;
2022
- }
2023
- trigger(e) {
2024
- return this.http.post(
2025
- `/audience/views/${this.module}/${this.resourceType}/${e}`
2026
- );
2027
- }
2028
- }
2029
- class AudienceService {
2030
- constructor(e, t, s) {
2031
- this.context = e, this.module = t, this.resourceType = s;
2032
- }
2033
- get views() {
2034
- return new ViewsService(this.context, this.module, this.resourceType);
2035
- }
2036
- get reactions() {
2037
- return new ReactionsService(this.context, this.module, this.resourceType);
2038
- }
2039
- }
2040
- const globalCache = {}, mutexPromise = {};
2041
- class CacheService {
2042
- constructor(e) {
2043
- this.context = e;
2044
- }
2045
- get http() {
2046
- return this.context.http();
2047
- }
2048
- async fromCacheIfPossible(e, t, s) {
2049
- if (mutexPromise[e] !== void 0 && await mutexPromise[e], globalCache[e])
2050
- return globalCache[e];
1842
+ async fromCacheIfPossible(e, t, s) {
1843
+ if (mutexPromise[e] !== void 0 && await mutexPromise[e], globalCache[e])
1844
+ return globalCache[e];
2051
1845
  try {
2052
1846
  const r = t();
2053
1847
  mutexPromise[e] = r;
@@ -2165,17 +1959,17 @@ class ConfService {
2165
1959
  }) {
2166
1960
  var E;
2167
1961
  const r = await this.http.get("/theme"), i = (E = t == null ? void 0 : t.overriding) == null ? void 0 : E.find(
2168
- (p) => (
1962
+ (h) => (
2169
1963
  // Fix #WB2-2660:
2170
1964
  // If Public access => get the neo theme
2171
1965
  // Else get the theme from the user preference
2172
- s ? p.parent === "theme-open-ent" && p.bootstrapVersion === "ode-bootstrap-neo" : p.child === (r == null ? void 0 : r.themeName)
1966
+ s ? h.parent === "theme-open-ent" && h.bootstrapVersion === "ode-bootstrap-neo" : h.child === (r == null ? void 0 : r.themeName)
2173
1967
  )
2174
- ), o = s ? "default" : (r == null ? void 0 : r.skinName) || (i == null ? void 0 : i.skins[0]), a = (r == null ? void 0 : r.skin) || `/assets/themes/${i == null ? void 0 : i.child}/skins/${o}/`, c = i == null ? void 0 : i.skins, l = i == null ? void 0 : i.bootstrapVersion.split("-").slice(-1)[0], h = (i == null ? void 0 : i.parent) === "panda";
1968
+ ), o = s ? "default" : (r == null ? void 0 : r.skinName) || (i == null ? void 0 : i.skins[0]), a = (r == null ? void 0 : r.skin) || `/assets/themes/${i == null ? void 0 : i.child}/skins/${o}/`, c = i == null ? void 0 : i.skins, l = i == null ? void 0 : i.bootstrapVersion.split("-").slice(-1)[0], p = (i == null ? void 0 : i.parent) === "panda";
2175
1969
  return {
2176
1970
  basePath: `${this.cdnDomain}${a}../../`,
2177
1971
  bootstrapVersion: l,
2178
- is1d: h,
1972
+ is1d: p,
2179
1973
  logoutCallback: (r == null ? void 0 : r.logoutCallback) || "",
2180
1974
  skin: i == null ? void 0 : i.child,
2181
1975
  skinName: o,
@@ -2194,116 +1988,6 @@ class ConfService {
2194
1988
  return s.logoutCallback;
2195
1989
  }
2196
1990
  }
2197
- const SEND_ALL = "*";
2198
- class WebBroker {
2199
- constructor(e) {
2200
- u(this, "subscription");
2201
- this.odeServices = e;
2202
- }
2203
- get http() {
2204
- return this.odeServices.http();
2205
- }
2206
- get events() {
2207
- return this.odeServices.notify().events();
2208
- }
2209
- dispatchEvent(e, t) {
2210
- t.findIndex(
2211
- (r) => SEND_ALL === r || e.data["event-type"] === r
2212
- ) >= 0 && this.http.post("/infra/event/web/store", e.data, {
2213
- disableNotifications: !0
2214
- });
2215
- }
2216
- initialize(e) {
2217
- if (e === void 0 || e.send === void 0 || e.send.length > 0) {
2218
- const t = (e == null ? void 0 : e.send) ?? [SEND_ALL];
2219
- this.subscription = this.events.subscribe(
2220
- LAYER_NAME.WEB_DATA,
2221
- (s) => this.dispatchEvent(s, t)
2222
- );
2223
- }
2224
- return this;
2225
- }
2226
- destroy() {
2227
- this.subscription && (this.subscription.revoke(), delete this.subscription);
2228
- }
2229
- }
2230
- class DataService {
2231
- constructor(e) {
2232
- u(this, "_webBroker");
2233
- u(this, "app");
2234
- u(this, "user");
2235
- u(this, "profile");
2236
- this.odeServices = e;
2237
- }
2238
- get conf() {
2239
- return this.odeServices.conf();
2240
- }
2241
- get notify() {
2242
- return this.odeServices.notify();
2243
- }
2244
- // This method is called once, by the service container.
2245
- async initialize() {
2246
- try {
2247
- const { app: e } = await this.notify.onAppConfReady().promise;
2248
- this.app = e, this.user = await this.odeServices.session().getUser(), this.profile = await this.odeServices.session().getUserProfile();
2249
- const { ["data-service"]: t } = await this.conf.getPublicConf(e);
2250
- this._webBroker = new WebBroker(this.odeServices).initialize(t == null ? void 0 : t.web);
2251
- } catch {
2252
- console.log("DataService not initialized, usage data unavailable.");
2253
- }
2254
- }
2255
- //FIXME When to call that ??
2256
- predestroy() {
2257
- this._webBroker && (this._webBroker.destroy(), delete this._webBroker);
2258
- }
2259
- /** Send a web-user-level event to the data pipeline. */
2260
- trackWebEvent(e) {
2261
- this.notify.events().publish(LAYER_NAME.WEB_DATA, {
2262
- name: EVENT_NAME.DATA_TRACKED,
2263
- data: e
2264
- });
2265
- }
2266
- addUserInfos(e) {
2267
- return this.user && (e.userId = this.user.userId, e.structure = this.user.structureNames[0]), this.profile && (e.profil = this.profile[0]), e;
2268
- }
2269
- trackVideoSave(e, t, s, r, i, o, a) {
2270
- const c = this.addUserInfos({
2271
- "event-type": "VIDEO_SAVE",
2272
- module: this.app || "video",
2273
- video_id: e,
2274
- browser: o,
2275
- duration: Math.round(t),
2276
- weight: s,
2277
- source: r ? "CAPTURED" : "UPLOADED",
2278
- url: i
2279
- });
2280
- a && (c.device_type = a), this.trackWebEvent(c);
2281
- }
2282
- trackVideoRead(e, t, s, r, i) {
2283
- const o = this.addUserInfos({
2284
- "event-type": "VIDEO_READ",
2285
- module: "video",
2286
- video_id: e,
2287
- browser: r,
2288
- source: t ? "CAPTURED" : "UPLOADED",
2289
- url: s
2290
- });
2291
- this.app && (o["override-module"] = this.app), i && (o.device_type = i), this.trackWebEvent(o);
2292
- }
2293
- trackSpeechAndText(e) {
2294
- const t = this.addUserInfos({
2295
- "event-type": "SPEECH_AND_TEXT",
2296
- function: e
2297
- });
2298
- this.app && (t.module = this.app), this.trackWebEvent(t);
2299
- }
2300
- trackAccessLibraryFromExplorer() {
2301
- const e = this.addUserInfos({
2302
- "event-type": "ACCESS_LIBRARY_FROM_EXPLORER"
2303
- });
2304
- this.app && (e.module = this.app), this.trackWebEvent(e);
2305
- }
2306
- }
2307
1991
  class DirectoryService {
2308
1992
  constructor(e) {
2309
1993
  this.odeServices = e;
@@ -2361,9 +2045,9 @@ class DirectoryService {
2361
2045
  users: r
2362
2046
  }) {
2363
2047
  this.cache.clearCache("/directory/sharebookmark/all");
2364
- 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) => {
2365
- if (typeof p == "string") {
2366
- const { displayName: y, groups: d, id: g, notVisibleCount: A, users: f } = await this.getBookMarkById(p), w = f.map((D) => D.id), F = d.map((D) => D.id);
2048
+ const i = r.map((h) => typeof h == "string" ? h : h.id), o = s.map((h) => typeof h == "string" ? h : h.id), a = t.map(async (h) => {
2049
+ if (typeof h == "string") {
2050
+ const { displayName: y, groups: d, id: g, notVisibleCount: A, users: f } = await this.getBookMarkById(h), w = f.map((D) => D.id), F = d.map((D) => D.id);
2367
2051
  return {
2368
2052
  displayName: y,
2369
2053
  id: g,
@@ -2371,2094 +2055,2372 @@ class DirectoryService {
2371
2055
  members: [...F, ...w]
2372
2056
  };
2373
2057
  } else
2374
- return Promise.resolve(p);
2375
- }), l = (await Promise.all(a)).map((p) => p.members).reduce((p, y) => [...p, ...y], []), h = {
2058
+ return Promise.resolve(h);
2059
+ }), l = (await Promise.all(a)).map((h) => h.members).reduce((h, y) => [...h, ...y], []), p = {
2376
2060
  name: e,
2377
2061
  members: [...i, ...o, ...l]
2378
2062
  }, { id: E } = await this.http.postJson(
2379
2063
  "/directory/sharebookmark",
2380
- h
2064
+ p
2381
2065
  );
2382
2066
  return {
2383
2067
  id: E,
2384
2068
  displayName: e,
2385
2069
  notVisibleCount: 0,
2386
- members: h.members
2070
+ members: p.members
2387
2071
  };
2388
2072
  }
2389
2073
  }
2390
- class EmbedderService {
2391
- constructor(e) {
2392
- this.context = e;
2393
- }
2394
- get http() {
2395
- return this.context.http();
2074
+ const loadedScripts = {};
2075
+ class HttpService {
2076
+ constructor(e, t) {
2077
+ // Axios automatically manages the XSRF-TOKEN cookie and the X-XSRF-TOKEN HTTP header.
2078
+ u(this, "axios");
2079
+ u(this, "baseUrl");
2080
+ u(this, "headers", {});
2081
+ u(this, "_latestResponse");
2082
+ this.context = e, this.axios = axios.create(t);
2396
2083
  }
2397
- /**
2398
- * Returns the default list of video embedder
2399
- * @returns the default list of video embedder
2400
- */
2401
- async getDefault() {
2402
- return this.http.get("/infra/embed/default");
2084
+ fixBaseUrl(e) {
2085
+ return e.startsWith("http://") || e.startsWith("https://") ? e : this.baseUrl ? this.baseUrl.endsWith("/") || e.startsWith("/") ? `${this.baseUrl}${e}` : `${this.baseUrl}/${e}` : e;
2403
2086
  }
2404
- /**
2405
- * Returns the custom list of video embedder
2406
- * @returns the custom list of video embedder
2407
- */
2408
- async getCustom() {
2409
- return this.http.get("/infra/embed/custom");
2087
+ useBaseUrl(e) {
2088
+ return this.baseUrl = e, this;
2410
2089
  }
2411
- /**
2412
- * The provider matching with the URL
2413
- * @param {Embedder[]} embedderList - The list of video providers to test with
2414
- * @param {String} url - The URL for the video
2415
- * @returns The provider matching with the URL or undefined
2416
- */
2417
- getProviderFromUrl(e, t) {
2418
- for (const s of e)
2419
- if (this.isUrlFromProvider(t, s))
2420
- return s;
2090
+ useHeaders(e) {
2091
+ return this.headers = e, this;
2421
2092
  }
2422
- urlIsFromPattern(e, t) {
2423
- const s = new RegExp("[^{}]+(?=(?:[^{}]*{[^}]*})*[^}]*$)", "g"), r = new RegExp("{[^}]*}", "g");
2424
- let i = !0;
2425
- const o = t.match(s) || [], a = [];
2426
- return (t.match(r) || []).forEach((l, h) => {
2427
- l.includes("ignore") || a.push(o[h]);
2428
- }), a.forEach((l) => {
2429
- if (!e.includes(l)) {
2430
- i = !1;
2431
- return;
2432
- }
2433
- }), i;
2093
+ setCdn(e) {
2094
+ e && XMLHttpRequest && !XMLHttpRequest.prototype.cdnUrl && (XMLHttpRequest.prototype.cdnUrl = e, XMLHttpRequest.prototype.baseOpen = XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.open = function() {
2095
+ const t = arguments[1];
2096
+ 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);
2097
+ });
2434
2098
  }
2435
- /**
2436
- * Check if a given URL correspond to one of the URL pattern of the provider
2437
- * @param {String} url - The URL for the video
2438
- * @param {Embedder} embedder - The video provider to test with
2439
- * @returns boolean depending if a given URL correspond to one of the URL pattern of the provider
2440
- */
2441
- isUrlFromProvider(e, t) {
2442
- typeof t.url == "string" && (t.url = [t.url]);
2443
- for (const s of t.url)
2444
- if (this.urlIsFromPattern(e, s))
2445
- return !0;
2446
- return !1;
2099
+ // private toAxiosConfig(params?: IHttpParams): AxiosRequestConfig {
2100
+ toAxiosConfig(e) {
2101
+ if (e) {
2102
+ const t = Object.assign({}, this.axios.defaults);
2103
+ 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));
2104
+ const s = t.headers ?? {};
2105
+ return t.headers = { ...s, ...this.headers }, t;
2106
+ } else
2107
+ return this.axios.defaults;
2447
2108
  }
2448
- /**
2449
- * Get embed code to display the video for an URL and a provider
2450
- * @param {Embedder} embedder - The video provider for the URL
2451
- * @param {String} url - The URL for the video
2452
- * @returns embed code to display the video for an URL and a provider
2453
- */
2454
- getEmbedCodeForProvider(e, t) {
2455
- for (const s of e.url)
2456
- if (this.urlIsFromPattern(t, s)) {
2457
- const r = new RegExp("{[a-zA-Z0-9_.]+}", "g"), i = s.match(r) || [];
2458
- let o = e.embed;
2459
- for (const a of i) {
2460
- let c = s.split(a)[0];
2461
- const l = c.split("}");
2462
- l.length > 1 && (c = l[l.length - 1]);
2463
- let h = t.split(c)[1];
2464
- if (!h)
2465
- continue;
2466
- const E = s.split(a)[1].split("{")[0];
2467
- E && (h = h.split(E)[0]);
2468
- const p = new RegExp("\\" + a.replace(/}/, "\\}"), "g");
2469
- o = o.replace(p, h);
2109
+ toCdnUrl(e) {
2110
+ e = this.fixBaseUrl(e);
2111
+ const t = this.context.conf().getCdnUrl() || "";
2112
+ if (t.length > 0 && e !== "/conf/public") {
2113
+ const s = "" + e;
2114
+ (s.startsWith("/infra/public") || s.startsWith("/assets") || /^\/([^\/]*)\/public/.test(s)) && (e = t + s);
2115
+ }
2116
+ return e;
2117
+ }
2118
+ mapAxiosError(e, t) {
2119
+ e.response ? this._latestResponse = e.response : e.request ? this._latestResponse = {
2120
+ status: 408,
2121
+ statusText: ERROR_CODE.TIME_OUT
2122
+ } : this._latestResponse = {
2123
+ status: 500,
2124
+ statusText: ERROR_CODE.UNKNOWN
2125
+ };
2126
+ const { status: s, statusText: r, headers: i, data: o } = this._latestResponse;
2127
+ return t != null && t.disableNotifications || notify.events().publish(LAYER_NAME.TRANSPORT, {
2128
+ name: EVENT_NAME.ERROR_OCCURED,
2129
+ data: {
2130
+ params: t,
2131
+ response: { status: s, statusText: r, headers: i },
2132
+ payload: o
2133
+ }
2134
+ }), o;
2135
+ }
2136
+ mapAxiosResponse(e, t) {
2137
+ return this._latestResponse = e, e.data;
2138
+ }
2139
+ get latestResponse() {
2140
+ return this._latestResponse;
2141
+ }
2142
+ isResponseError() {
2143
+ return this.latestResponse.status < 200 || this.latestResponse.status >= 300;
2144
+ }
2145
+ async get(e, t) {
2146
+ try {
2147
+ const s = await this.axios.get(
2148
+ this.toCdnUrl(e),
2149
+ this.toAxiosConfig(t)
2150
+ );
2151
+ return this.mapAxiosResponse(s, t);
2152
+ } catch (s) {
2153
+ throw this.mapAxiosError(s, t);
2154
+ }
2155
+ }
2156
+ async post(e, t, s) {
2157
+ try {
2158
+ const r = await this.axios.post(
2159
+ this.fixBaseUrl(e),
2160
+ t,
2161
+ this.toAxiosConfig(s)
2162
+ );
2163
+ return this.mapAxiosResponse(r, s);
2164
+ } catch (r) {
2165
+ throw this.mapAxiosError(r, s);
2166
+ }
2167
+ }
2168
+ async postFile(e, t, s) {
2169
+ const r = this.toAxiosConfig(s);
2170
+ r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
2171
+ try {
2172
+ const i = await this.axios.post(this.fixBaseUrl(e), t, {
2173
+ ...r,
2174
+ headers: {
2175
+ "Content-Type": "multipart/form-data"
2176
+ }
2177
+ });
2178
+ return this.mapAxiosResponse(i, s);
2179
+ } catch (i) {
2180
+ throw this.mapAxiosError(i, s);
2181
+ }
2182
+ }
2183
+ async postJson(e, t, s) {
2184
+ const r = this.toAxiosConfig();
2185
+ r.headers && (r.headers["Content-Type"] = "application/json");
2186
+ try {
2187
+ const i = await this.axios.post(
2188
+ this.fixBaseUrl(e),
2189
+ t,
2190
+ this.toAxiosConfig(s)
2191
+ );
2192
+ return this.mapAxiosResponse(i, s);
2193
+ } catch (i) {
2194
+ throw this.mapAxiosError(i, s);
2195
+ }
2196
+ }
2197
+ async put(e, t, s) {
2198
+ try {
2199
+ const r = await this.axios.put(
2200
+ this.fixBaseUrl(e),
2201
+ t,
2202
+ this.toAxiosConfig(s)
2203
+ );
2204
+ return this.mapAxiosResponse(r, s);
2205
+ } catch (r) {
2206
+ throw this.mapAxiosError(r, s);
2207
+ }
2208
+ }
2209
+ async putFile(e, t, s) {
2210
+ try {
2211
+ const r = this.toAxiosConfig(s);
2212
+ r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
2213
+ const i = await this.axios.put(this.fixBaseUrl(e), t, {
2214
+ ...r,
2215
+ headers: {
2216
+ "Content-Type": "multipart/form-data"
2217
+ }
2218
+ });
2219
+ return this.mapAxiosResponse(i, s);
2220
+ } catch (r) {
2221
+ throw this.mapAxiosError(r, s);
2222
+ }
2223
+ }
2224
+ async putJson(e, t, s) {
2225
+ const r = this.toAxiosConfig(s);
2226
+ r.headers && (r.headers["Content-Type"] = "application/json");
2227
+ try {
2228
+ const i = await this.axios.put(this.fixBaseUrl(e), t, r);
2229
+ return this.mapAxiosResponse(i, s);
2230
+ } catch (i) {
2231
+ throw this.mapAxiosError(i, s);
2232
+ }
2233
+ }
2234
+ async patch(e, t, s) {
2235
+ try {
2236
+ const r = await this.axios.patch(
2237
+ this.fixBaseUrl(e),
2238
+ t,
2239
+ this.toAxiosConfig(s)
2240
+ );
2241
+ return this.mapAxiosResponse(r, s);
2242
+ } catch (r) {
2243
+ throw this.mapAxiosError(r, s);
2244
+ }
2245
+ }
2246
+ async patchFile(e, t, s) {
2247
+ try {
2248
+ const r = this.toAxiosConfig(s);
2249
+ r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
2250
+ const i = await this.axios.patch(this.fixBaseUrl(e), t, {
2251
+ ...r,
2252
+ headers: {
2253
+ "Content-Type": "multipart/form-data"
2470
2254
  }
2255
+ });
2256
+ return this.mapAxiosResponse(i, s);
2257
+ } catch (r) {
2258
+ throw this.mapAxiosError(r, s);
2259
+ }
2260
+ }
2261
+ async patchJson(e, t, s) {
2262
+ const r = this.toAxiosConfig(s);
2263
+ r.headers && (r.headers["Content-Type"] = "application/json");
2264
+ try {
2265
+ const i = await this.axios.patch(this.fixBaseUrl(e), t, r);
2266
+ return this.mapAxiosResponse(i, s);
2267
+ } catch (i) {
2268
+ throw this.mapAxiosError(i, s);
2269
+ }
2270
+ }
2271
+ async delete(e, t) {
2272
+ try {
2273
+ const s = await this.axios.delete(
2274
+ this.fixBaseUrl(e),
2275
+ this.toAxiosConfig(t)
2276
+ );
2277
+ return this.mapAxiosResponse(s, t);
2278
+ } catch (s) {
2279
+ throw this.mapAxiosError(s, t);
2280
+ }
2281
+ }
2282
+ async deleteJson(e, t) {
2283
+ try {
2284
+ const s = await this.axios.delete(this.fixBaseUrl(e), {
2285
+ data: t
2286
+ });
2287
+ return this.mapAxiosResponse(s);
2288
+ } catch (s) {
2289
+ throw this.mapAxiosError(s);
2290
+ }
2291
+ }
2292
+ getScript(e, t, s) {
2293
+ const r = s ?? "exports", i = this.toAxiosConfig(t);
2294
+ return i.headers && (i.headers.Accept = "application/javascript"), this.axios.get(this.toCdnUrl(e), i).then((o) => this.mapAxiosResponse(o, t)).then((o) => {
2295
+ try {
2296
+ const a = `"use strict";var ${r.split(".")[0]}={};${o};return ${r};`;
2297
+ return Function(a)();
2298
+ } catch {
2471
2299
  return o;
2472
2300
  }
2473
- return "";
2301
+ }).catch((o) => {
2302
+ throw this.mapAxiosError(o, t), o;
2303
+ });
2304
+ }
2305
+ loadScript(e, t) {
2306
+ return loadedScripts[e] ? Promise.resolve() : this.getScript(e, t).then((s) => {
2307
+ loadedScripts[e] = !0;
2308
+ });
2474
2309
  }
2475
2310
  }
2476
- const bundle = {}, promises = {}, defaultDiacriticsRemovalMap = [
2477
- {
2478
- base: "A",
2479
- 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
2480
- },
2481
- { base: "AA", letters: /[\uA732]/g },
2482
- { base: "AE", letters: /[\u00C6\u01FC\u01E2]/g },
2483
- { base: "AO", letters: /[\uA734]/g },
2484
- { base: "AU", letters: /[\uA736]/g },
2485
- { base: "AV", letters: /[\uA738\uA73A]/g },
2486
- { base: "AY", letters: /[\uA73C]/g },
2487
- {
2488
- base: "B",
2489
- letters: /[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g
2490
- },
2491
- {
2492
- base: "C",
2493
- letters: /[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g
2494
- },
2495
- {
2496
- base: "D",
2497
- letters: /[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g
2498
- },
2499
- { base: "DZ", letters: /[\u01F1\u01C4]/g },
2500
- { base: "Dz", letters: /[\u01F2\u01C5]/g },
2501
- {
2502
- base: "E",
2503
- 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
2504
- },
2505
- { base: "F", letters: /[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g },
2506
- {
2507
- base: "G",
2508
- letters: /[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g
2509
- },
2510
- {
2511
- base: "H",
2512
- letters: /[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g
2513
- },
2514
- {
2515
- base: "I",
2516
- letters: /[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g
2517
- },
2518
- { base: "J", letters: /[\u004A\u24BF\uFF2A\u0134\u0248]/g },
2519
- {
2520
- base: "K",
2521
- letters: /[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g
2522
- },
2523
- {
2524
- base: "L",
2525
- letters: /[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g
2526
- },
2527
- { base: "LJ", letters: /[\u01C7]/g },
2528
- { base: "Lj", letters: /[\u01C8]/g },
2529
- { base: "M", letters: /[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g },
2530
- {
2531
- base: "N",
2532
- letters: /[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g
2533
- },
2534
- { base: "NJ", letters: /[\u01CA]/g },
2535
- { base: "Nj", letters: /[\u01CB]/g },
2536
- {
2537
- base: "O",
2538
- 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
2539
- },
2540
- { base: "OI", letters: /[\u01A2]/g },
2541
- { base: "OO", letters: /[\uA74E]/g },
2542
- { base: "OU", letters: /[\u0222]/g },
2543
- {
2544
- base: "P",
2545
- letters: /[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g
2546
- },
2547
- { base: "Q", letters: /[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g },
2548
- {
2549
- base: "R",
2550
- letters: /[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g
2551
- },
2552
- {
2553
- base: "S",
2554
- letters: /[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g
2555
- },
2556
- {
2557
- base: "T",
2558
- letters: /[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g
2559
- },
2560
- { base: "TZ", letters: /[\uA728]/g },
2561
- {
2562
- base: "U",
2563
- 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
2564
- },
2565
- { base: "V", letters: /[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g },
2566
- { base: "VY", letters: /[\uA760]/g },
2567
- {
2568
- base: "W",
2569
- letters: /[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g
2570
- },
2571
- { base: "X", letters: /[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g },
2572
- {
2573
- base: "Y",
2574
- letters: /[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g
2575
- },
2576
- {
2577
- base: "Z",
2578
- letters: /[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g
2579
- },
2580
- {
2581
- base: "a",
2582
- 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
2583
- },
2584
- { base: "aa", letters: /[\uA733]/g },
2585
- { base: "ae", letters: /[\u00E6\u01FD\u01E3]/g },
2586
- { base: "ao", letters: /[\uA735]/g },
2587
- { base: "au", letters: /[\uA737]/g },
2588
- { base: "av", letters: /[\uA739\uA73B]/g },
2589
- { base: "ay", letters: /[\uA73D]/g },
2590
- {
2591
- base: "b",
2592
- letters: /[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g
2593
- },
2594
- {
2595
- base: "c",
2596
- letters: /[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g
2597
- },
2598
- {
2599
- base: "d",
2600
- letters: /[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g
2601
- },
2602
- { base: "dz", letters: /[\u01F3\u01C6]/g },
2603
- {
2604
- base: "e",
2605
- 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
2606
- },
2607
- { base: "f", letters: /[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g },
2608
- {
2609
- base: "g",
2610
- letters: /[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g
2611
- },
2612
- {
2613
- base: "h",
2614
- letters: /[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g
2615
- },
2616
- { base: "hv", letters: /[\u0195]/g },
2617
- {
2618
- base: "i",
2619
- letters: /[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g
2620
- },
2621
- { base: "j", letters: /[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g },
2622
- {
2623
- base: "k",
2624
- letters: /[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g
2625
- },
2626
- {
2627
- base: "l",
2628
- letters: /[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g
2629
- },
2630
- { base: "lj", letters: /[\u01C9]/g },
2631
- { base: "m", letters: /[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g },
2632
- {
2633
- base: "n",
2634
- letters: /[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g
2635
- },
2636
- { base: "nj", letters: /[\u01CC]/g },
2637
- {
2638
- base: "o",
2639
- 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
2640
- },
2641
- { base: "oi", letters: /[\u01A3]/g },
2642
- { base: "ou", letters: /[\u0223]/g },
2643
- { base: "oo", letters: /[\uA74F]/g },
2644
- {
2645
- base: "p",
2646
- letters: /[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g
2647
- },
2648
- { base: "q", letters: /[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g },
2649
- {
2650
- base: "r",
2651
- letters: /[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g
2652
- },
2653
- {
2654
- base: "s",
2655
- letters: /[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g
2656
- },
2657
- {
2658
- base: "t",
2659
- letters: /[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g
2660
- },
2661
- { base: "tz", letters: /[\uA729]/g },
2662
- {
2663
- base: "u",
2664
- 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
2665
- },
2666
- { base: "v", letters: /[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g },
2667
- { base: "vy", letters: /[\uA761]/g },
2668
- {
2669
- base: "w",
2670
- letters: /[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g
2671
- },
2672
- { base: "x", letters: /[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g },
2673
- {
2674
- base: "y",
2675
- letters: /[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g
2676
- },
2677
- {
2678
- base: "z",
2679
- letters: /[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g
2680
- }
2681
- ];
2682
- class IdiomService {
2311
+ class RightService {
2683
2312
  constructor(e) {
2684
2313
  this.context = e;
2685
2314
  }
2686
- get http() {
2687
- return this.context.http();
2315
+ get session() {
2316
+ return this.context.session();
2688
2317
  }
2689
- async getIdiom(e, t) {
2690
- await Promise.all([
2691
- this.addBundlePromise(e, "/i18n"),
2692
- this.addBundlePromise(e, `/${t}/i18n`)
2693
- ]);
2318
+ /**
2319
+ * Parse right concat as "$TYPE:$ID:$RIGHT"
2320
+ * $TYPE = user | group | creator
2321
+ * $ID: id of the resource
2322
+ * $RIGHT: read | contrib | manage
2323
+ *
2324
+ * @param right a concat right
2325
+ * @returns Right parsed
2326
+ */
2327
+ parseResourceRight(e) {
2328
+ const t = e.split(":");
2329
+ if (t.length === 2) {
2330
+ if (t[0] === "creator")
2331
+ return {
2332
+ id: t[1],
2333
+ right: "creator",
2334
+ type: "creator"
2335
+ };
2336
+ } else return t.length === 3 ? {
2337
+ id: t[1],
2338
+ right: t[2],
2339
+ type: t[0]
2340
+ } : void 0;
2694
2341
  }
2695
- translate(e, t) {
2696
- e = e ?? "";
2697
- let s = bundle[e] === void 0 ? e : bundle[e];
2698
- if (t && typeof t == "object")
2699
- for (const r in t)
2700
- typeof t[r] < "u" && (s = s.replace(
2701
- new RegExp("\\${" + r + "}", "g"),
2702
- "" + t[r]
2703
- ));
2704
- return s;
2342
+ /**
2343
+ * Parse an array of rights concat as "$TYPE:$ID:$RIGHT"
2344
+ * $TYPE = user | group | creator
2345
+ * $ID: id of the resource
2346
+ * $RIGHT: read | contrib | manage
2347
+ *
2348
+ * @param rights a list of concat rights
2349
+ * @returns Array of Right parsed
2350
+ */
2351
+ parseResourceRights(e) {
2352
+ return e.map((s) => this.parseResourceRight(s)).filter((s) => s !== void 0);
2705
2353
  }
2706
- addBundlePromise(e, t) {
2707
- return this.loadBundlePromise(e, t);
2354
+ /**
2355
+ * Check wether a user has the expected right for a resource
2356
+ * @param user the userId and groupId concerned by the check
2357
+ * @param expect the expected right to check
2358
+ * @param rights array of Right for the resource
2359
+ * @returns true if has rights
2360
+ */
2361
+ hasResourceRight({ id: e, groupIds: t }, s, r) {
2362
+ const i = r.map((o) => typeof o == "string" ? this.parseResourceRight(o) : o).filter((o) => o !== void 0);
2363
+ for (const o of i) {
2364
+ if (o.id === e && o.type === "creator")
2365
+ return !0;
2366
+ if (o.id === e && o.type === "user" && o.right === s)
2367
+ return !0;
2368
+ if (t.includes(o.id) && o.type === "group" && o.right === s)
2369
+ return !0;
2370
+ }
2371
+ return !1;
2708
2372
  }
2709
- addBundle(e, t, s) {
2710
- this.loadBundle(e, t, s);
2373
+ /**
2374
+ * Check wether the current user have resource right
2375
+ * @param expect the expected right to check
2376
+ * @param rights array of Right for the resource
2377
+ * @returns true if has rights
2378
+ */
2379
+ async sessionHasResourceRight(e, t) {
2380
+ try {
2381
+ const s = await this.session.getUser();
2382
+ return !!s && this.hasResourceRight(
2383
+ { groupIds: s.groupsIds, id: s.userId },
2384
+ e,
2385
+ t
2386
+ );
2387
+ } catch (s) {
2388
+ return console.error(`Unexpected error ${s} in sessionHasResourceRight()`), !1;
2389
+ }
2711
2390
  }
2712
- loadBundlePromise(e, t) {
2713
- return this.loadBundle(e, t), promises[t];
2391
+ /**
2392
+ * Check wether the current user have at least one of resource right expected
2393
+ * @param expects array of expected right to check
2394
+ * @param rights array of Right for the resource
2395
+ * @returns true if has rights
2396
+ */
2397
+ async sessionHasAtLeastOneResourceRight(e, t) {
2398
+ for (const s of e)
2399
+ if (await this.sessionHasResourceRight(s, t))
2400
+ return !0;
2401
+ return !1;
2714
2402
  }
2715
- loadBundle(e, t, s) {
2716
- const r = promises[t];
2717
- if (r)
2718
- s && r.then(s).catch(s);
2719
- else {
2720
- const i = new Promisified();
2721
- promises[t] = i.promise;
2722
- const o = {};
2723
- e && (o["Accept-Language"] = e), this.http.get(t, { headers: o }).then((a) => {
2724
- Object.assign(bundle, a), typeof s == "function" && s(), i.resolve();
2725
- }).catch((a) => {
2726
- typeof s == "function" && s(), i.reject();
2727
- });
2403
+ /**
2404
+ * Check wether the current user has resource right for each right list
2405
+ * @param expect expected right to check
2406
+ * @param rightsArray array of array of Right for multiple resources
2407
+ * @returns true if has rights
2408
+ */
2409
+ async sessionHasResourceRightForEachList(e, t) {
2410
+ let s = 0;
2411
+ for (const r of t)
2412
+ await this.sessionHasResourceRight(e, r) && s++;
2413
+ return s === t.length;
2414
+ }
2415
+ /**
2416
+ * Check wether the current user have at least one of resource right for each right list
2417
+ * @param expects array of expected right to check
2418
+ * @param rightsArray array of array of Right for multiple resources
2419
+ * @returns true if has rights
2420
+ */
2421
+ async sessionHasAtLeastOneResourceRightForEachList(e, t) {
2422
+ for (const s of e) {
2423
+ let r = 0;
2424
+ for (const i of t)
2425
+ await this.sessionHasResourceRight(s, i) && r++;
2426
+ if (r === t.length)
2427
+ return !0;
2728
2428
  }
2429
+ return !1;
2729
2430
  }
2730
- addTranslations(e, t) {
2731
- notify.onLangReady().promise.then((s) => {
2732
- this.loadBundle(s, e + "/" + s + ".json", t);
2733
- });
2431
+ hasWorkflowRight(e, t) {
2432
+ return t.findIndex((s) => s === e) !== -1;
2734
2433
  }
2735
- addAllTranslations(e) {
2736
- return e && e.length > 0 ? notify.onLangReady().promise.then(
2737
- (t) => Promise.all(
2738
- e.map(
2739
- (s) => this.loadBundlePromise(t, s + "/" + t + ".json")
2434
+ /**
2435
+ * @param expect a workflow right
2436
+ * @returns true if current session has right on it
2437
+ */
2438
+ async sessionHasWorkflowRight(e) {
2439
+ try {
2440
+ const t = await this.session.getUser();
2441
+ return !!t && this.hasWorkflowRight(
2442
+ e,
2443
+ t.authorizedActions.map(
2444
+ (s) => s.name
2740
2445
  )
2741
- )
2742
- ).then(() => {
2743
- }) : Promise.reject();
2744
- }
2745
- addKeys(e) {
2746
- for (const t in e)
2747
- typeof bundle[t] != "string" && (bundle[t] = e[t]);
2748
- }
2749
- removeAccents(e) {
2750
- for (let t = 0; t < defaultDiacriticsRemovalMap.length; t++)
2751
- e = e.replace(
2752
- defaultDiacriticsRemovalMap[t].letters,
2753
- defaultDiacriticsRemovalMap[t].base
2754
2446
  );
2755
- return e;
2447
+ } catch (t) {
2448
+ return console.error(`Unexpected error ${t} in sessionHasWorkflowRight()`), !1;
2449
+ }
2450
+ }
2451
+ /**
2452
+ * @param expect a workflow right
2453
+ * @returns a record with right as key and boolean as value if current session has right on it
2454
+ */
2455
+ async sessionHasWorkflowRights(e) {
2456
+ const t = {};
2457
+ try {
2458
+ const s = await this.session.getUser();
2459
+ for (const r of e)
2460
+ t[r] = !!s && this.hasWorkflowRight(
2461
+ r,
2462
+ s.authorizedActions.map(
2463
+ (i) => i.name
2464
+ )
2465
+ );
2466
+ } catch (s) {
2467
+ console.error(`Unexpected error ${s} in sessionHasWorkflowRights()`);
2468
+ for (const r of e)
2469
+ t[r] = !1;
2470
+ }
2471
+ return t;
2756
2472
  }
2757
2473
  }
2758
- class AbstractBehaviourService {
2759
- //
2760
- // IMPLEMENTATION
2761
- //
2474
+ class SessionService {
2762
2475
  constructor(e) {
2763
- //-----------------
2764
- //--- Utilities ---
2765
- //-----------------
2766
- u(this, "_cache");
2767
- this.context = e, this._cache = new CacheService(this.context);
2476
+ this.context = e;
2768
2477
  }
2769
- getApplication() {
2770
- return this.APP;
2478
+ get http() {
2479
+ return this.context.http();
2771
2480
  }
2772
- getResourceType() {
2773
- return this.RESOURCE;
2481
+ get cache() {
2482
+ return this.context.cache();
2774
2483
  }
2775
- httpGet(e, t) {
2776
- return this._cache.httpGetJson(e, t);
2484
+ get conf() {
2485
+ return this.context.conf();
2777
2486
  }
2778
- /* Utility to map data between linker model and search model. */
2779
- dataToResource({
2780
- modified: e,
2781
- ...t
2782
- }) {
2783
- const s = typeof e == "string" ? e : e != null && e.$date ? "" + e.$date : "";
2487
+ /**
2488
+ * Callback to call when user logout
2489
+ */
2490
+ onLogout() {
2491
+ this.cache.clearCache();
2492
+ }
2493
+ /**
2494
+ * Callback to call when session change
2495
+ */
2496
+ onRefreshSession() {
2497
+ this.cache.clearCache();
2498
+ }
2499
+ async getSession() {
2500
+ const e = await this.getUser(), [
2501
+ t,
2502
+ s,
2503
+ r,
2504
+ i,
2505
+ o
2506
+ ] = await Promise.all([
2507
+ this.getCurrentLanguage(e),
2508
+ this.latestQuotaAndUsage(e),
2509
+ this.loadDescription(e),
2510
+ this.getUserProfile(),
2511
+ this.getBookmarks(e)
2512
+ ]);
2784
2513
  return {
2785
- application: this.RESOURCE,
2786
- name: t.title,
2787
- creatorId: t.owner,
2788
- creatorName: t.ownerName,
2789
- thumbnail: t.icon,
2790
- assetId: t._id,
2791
- modifiedAt: s,
2792
- shared: t.shared,
2793
- path: t.path
2514
+ user: e,
2515
+ quotaAndUsage: s,
2516
+ currentLanguage: t,
2517
+ userDescription: r,
2518
+ userProfile: i,
2519
+ bookmarkedApps: o
2794
2520
  };
2795
2521
  }
2796
- }
2797
- class ActualitesBehaviour extends AbstractBehaviourService {
2798
- constructor() {
2799
- super(...arguments);
2800
- u(this, "APP", "actualites");
2801
- u(this, "RESOURCE", "actualites");
2802
- }
2803
- async loadResources() {
2804
- const [t, s] = await Promise.all([
2805
- this.httpGet("/actualites/api/v1/infos/linker"),
2806
- this.httpGet("/actualites/api/v1/threads")
2807
- ]), r = s.reduce(
2808
- (i, o) => i.set(o.id, o),
2809
- /* @__PURE__ */ new Map()
2810
- );
2811
- return t.map((i) => {
2812
- var a;
2813
- let o;
2814
- return i.threadIcon ? o = i.threadIcon + "?thumbnail=48x48" : o = "/img/icons/glyphicons_036_file.png", this.dataToResource({
2815
- title: i.title + " [" + ((a = r.get(i.threadId)) == null ? void 0 : a.title) + "]",
2816
- ownerName: i.owner.displayName,
2817
- owner: i.owner.id,
2818
- icon: o,
2819
- path: "/actualites/threads/" + i.threadId + "?info=" + i.id,
2820
- _id: `${i.threadId}#${i.id}`,
2821
- shared: !!(i.shared && i.shared.length >= 0),
2822
- modified: i.modified
2823
- });
2522
+ login(e, t, s, r) {
2523
+ const i = new FormData();
2524
+ 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, {
2525
+ headers: { "content-type": "application/x-www-form-urlencoded" }
2526
+ }).finally(() => {
2527
+ switch (this.http.latestResponse.status) {
2528
+ case 200:
2529
+ throw ERROR_CODE.MALFORMED_DATA;
2530
+ }
2824
2531
  });
2825
2532
  }
2826
- }
2827
- const hexToDataUrl = (n, e = 1, t = 1) => {
2828
- const s = document.createElement("canvas");
2829
- s.width = e, s.height = t;
2830
- const r = s.getContext("2d");
2831
- return r ? (r.fillStyle = n, r.fillRect(0, 0, e, t), s.toDataURL("image/png")) : "";
2832
- };
2833
- class AppointmentsBehaviour extends AbstractBehaviourService {
2834
- constructor() {
2835
- super(...arguments);
2836
- u(this, "APP", "appointments");
2837
- u(this, "RESOURCE", "appointments");
2533
+ async logout() {
2534
+ const e = await this.conf.getLogoutCallback();
2535
+ return this.http.get("/auth/logout?callback=" + e).finally(() => {
2536
+ });
2838
2537
  }
2839
- async loadResources() {
2840
- return (await this.httpGet("/appointments/grids/linker")).map((s) => this.dataToResource({
2841
- _id: s.id.toString(),
2842
- icon: hexToDataUrl(s.color, 100, 100),
2843
- title: s.name,
2844
- ownerName: s.ownerName,
2845
- owner: s.ownerId,
2846
- path: `${window.location.origin}/appointments#?gridId=${s.id}`,
2847
- shared: !1,
2848
- modified: s.updatingDate
2849
- }));
2538
+ async latestQuotaAndUsage(e) {
2539
+ const t = { quota: 0, storage: 0 };
2540
+ if (!e) return t;
2541
+ try {
2542
+ return await this.http.get(
2543
+ `/workspace/quota/user/${e == null ? void 0 : e.userId}`
2544
+ );
2545
+ } catch (s) {
2546
+ return console.error(s), t;
2547
+ }
2850
2548
  }
2851
- }
2852
- class BlogBehaviour extends AbstractBehaviourService {
2853
- constructor() {
2854
- super(...arguments);
2855
- u(this, "APP", "blog");
2856
- u(this, "RESOURCE", "blog");
2549
+ async getCurrentLanguage(e) {
2550
+ const t = (e == null ? void 0 : e.sessionMetadata) && (e == null ? void 0 : e.sessionMetadata.userId);
2551
+ try {
2552
+ let s;
2553
+ return t ? s = await this.loadUserLanguage() : s = await this.loadDefaultLanguage(), s;
2554
+ } catch (s) {
2555
+ console.error(s);
2556
+ }
2857
2557
  }
2858
- loadResources() {
2859
- return new Promise(async (t, s) => {
2860
- try {
2861
- const r = await this.httpGet("/blog/linker"), i = [];
2862
- r.forEach((o) => {
2863
- o.thumbnail ? o.thumbnail = o.thumbnail + "?thumbnail=48x48" : o.thumbnail = "/img/illustrations/blog.svg";
2864
- const a = o.fetchPosts.map((c) => this.dataToResource({
2865
- owner: o.author.userId,
2866
- ownerName: o.author.username,
2867
- title: c.title + " [" + o.title + "]",
2868
- _id: `${o._id}#${c._id}`,
2869
- icon: o.thumbnail,
2870
- path: `/blog/id/${o._id}/post/${c._id}`,
2871
- shared: !!(o.shared && o.shared.length >= 0),
2872
- modified: o.modified
2873
- }));
2874
- i.push(...a);
2875
- }), t(i);
2876
- } catch (r) {
2877
- s(r);
2878
- }
2879
- });
2558
+ async loadUserLanguage() {
2559
+ try {
2560
+ const e = await this.http.get(
2561
+ "/userbook/preference/language"
2562
+ );
2563
+ return JSON.parse(e.preference)["default-domain"];
2564
+ } catch {
2565
+ return await this.loadDefaultLanguage();
2566
+ }
2880
2567
  }
2881
- }
2882
- class CollaborativewallBehaviour extends AbstractBehaviourService {
2883
- constructor() {
2884
- super(...arguments);
2885
- u(this, "APP", "collaborativewall");
2886
- u(this, "RESOURCE", "collaborativewall");
2568
+ async loadDefaultLanguage() {
2569
+ return (await this.cache.httpGetJson(
2570
+ "/locale"
2571
+ )).locale;
2887
2572
  }
2888
- async loadResources() {
2889
- return (await this.httpGet(
2890
- "/collaborativewall/list/all"
2891
- )).map(
2892
- (s) => this.dataToResource({
2893
- title: s.name,
2894
- ownerName: s.owner.displayName,
2895
- owner: s.owner.userId,
2896
- icon: s.icon ? s.icon : "/img/illustrations/collaborative-wall-default.png",
2897
- path: "/collaborativewall#/view/" + s._id,
2898
- _id: s._id,
2899
- shared: !!(s.shared && s.shared.length >= 0),
2900
- modified: s.modified
2901
- })
2573
+ async getUser() {
2574
+ const { response: e, value: t } = await this.cache.httpGet(
2575
+ "/auth/oauth2/userinfo"
2902
2576
  );
2577
+ if (!(e.status < 200 || e.status >= 300) && typeof t == "object")
2578
+ return t;
2579
+ throw ERROR_CODE.NOT_LOGGED_IN;
2903
2580
  }
2904
- }
2905
- class CommunityBehaviour extends AbstractBehaviourService {
2906
- constructor() {
2907
- super(...arguments);
2908
- u(this, "APP", "community");
2909
- u(this, "RESOURCE", "community");
2910
- }
2911
- async loadResources() {
2912
- return (await this.httpGet(
2913
- "/community/listallpages"
2914
- )).map((s) => {
2915
- let r;
2916
- return typeof s.thumbnail > "u" || s.thumbnail === "" ? r = "/img/icons/glyphicons_036_file.png" : r = s.thumbnail + "?thumbnail=48x48", this.dataToResource({
2917
- title: s.name,
2918
- icon: r,
2919
- path: "/community#/view/" + s.id,
2920
- _id: s.id,
2921
- owner: "",
2922
- ownerName: "",
2923
- shared: !!(s.shared && s.shared.length >= 0),
2924
- modified: s.name
2925
- // FIXME date ?
2926
- });
2927
- });
2581
+ hasWorkflow({
2582
+ workflowName: e,
2583
+ user: t
2584
+ }) {
2585
+ return e === void 0 || (t == null ? void 0 : t.authorizedActions.findIndex((s) => s.name === e)) !== -1;
2928
2586
  }
2929
- }
2930
- class ExercizerBehaviour extends AbstractBehaviourService {
2931
- constructor() {
2932
- super(...arguments);
2933
- u(this, "APP", "exercizer");
2934
- u(this, "RESOURCE", "exercizer");
2587
+ async loadDescription(e) {
2588
+ if (!e) return {};
2589
+ try {
2590
+ const [t, s] = await Promise.all([
2591
+ // FIXME The full user's description should be obtainable from a single endpoint in the backend.
2592
+ this.getUserProfile({
2593
+ options: { requestName: "refreshAvatar" }
2594
+ }),
2595
+ this.http.get("/directory/userbook/" + (e == null ? void 0 : e.userId))
2596
+ ]);
2597
+ return { ...s, profiles: t };
2598
+ } catch (t) {
2599
+ return console.error(t), {};
2600
+ }
2935
2601
  }
2936
- async loadResources() {
2937
- return (await this.httpGet(
2938
- "/exercizer/subjects-scheduled"
2939
- )).map((s) => {
2940
- const r = s.picture ? s.picture + "?thumbnail=48x48" : "/img/illustrations/exercizer.svg";
2941
- let i, o = !1;
2942
- const a = JSON.parse(s.scheduled_at);
2943
- 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({
2944
- title: s.title,
2945
- owner: s.owner,
2946
- ownerName: i,
2947
- icon: r,
2948
- path: "/exercizer#/linker/" + s.id,
2949
- _id: "" + s.id,
2950
- shared: o,
2951
- modified: s.modified
2952
- });
2602
+ async getBookmarks(e) {
2603
+ if (!e) return [];
2604
+ const t = await this.http.get("/userbook/preference/apps");
2605
+ t.preference || (t.preference = null);
2606
+ const s = JSON.parse(t.preference);
2607
+ let r;
2608
+ r = s, r || (r = {
2609
+ bookmarks: [],
2610
+ applications: []
2953
2611
  });
2612
+ const i = [];
2613
+ return r.bookmarks.forEach((o, a) => {
2614
+ const c = ((e == null ? void 0 : e.apps) || []).find(
2615
+ (l) => l.name === o
2616
+ );
2617
+ if (c) {
2618
+ const l = Object.assign({}, c);
2619
+ i.push(l);
2620
+ }
2621
+ }), i;
2954
2622
  }
2955
- }
2956
- class FormulaireBehaviour extends AbstractBehaviourService {
2957
- constructor() {
2958
- super(...arguments);
2959
- u(this, "APP", "formulaire");
2960
- u(this, "RESOURCE", "formulaire");
2961
- }
2962
- async loadResources() {
2963
- return (await this.httpGet(
2964
- "/formulaire/forms/linker"
2965
- )).map((s) => (s.picture || (s.picture = "/formulaire/public/img/logo.svg"), this.dataToResource({
2966
- _id: "" + s.id,
2967
- icon: s.picture,
2968
- title: s.title,
2969
- ownerName: s.owner_name,
2970
- owner: s.owner_id,
2971
- path: s.is_public ? `${window.location.origin}/formulaire-public#/form/${s.public_key}` : `${window.location.origin}/formulaire#/form/${s.id}/${s.rgpd ? "rgpd" : "new"}`,
2972
- shared: !!(s.shared && s.shared.length >= 0),
2973
- modified: "" + s.date_modification
2974
- })));
2975
- }
2976
- }
2977
- class ForumBehaviour extends AbstractBehaviourService {
2978
- constructor() {
2979
- super(...arguments);
2980
- u(this, "APP", "forum");
2981
- u(this, "RESOURCE", "forum");
2982
- }
2983
- async loadResources() {
2984
- return (await this.httpGet("/forum/categories")).map(
2985
- (s) => this.dataToResource({
2986
- _id: s._id,
2987
- title: s.name,
2988
- icon: s.icon || "/img/illustrations/forum.svg",
2989
- path: "/forum#/view/" + s._id,
2990
- ownerName: s.owner.displayName,
2991
- owner: s.owner.userId,
2992
- shared: !!(s.shared && s.shared.length >= 0),
2993
- modified: s.modified
2994
- })
2995
- );
2623
+ async getUserProfile(e = {}) {
2624
+ var c, l;
2625
+ 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);
2626
+ 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"];
2996
2627
  }
2997
- }
2998
- class HomeworksBehaviour extends AbstractBehaviourService {
2999
- constructor() {
3000
- super(...arguments);
3001
- u(this, "APP", "homeworks");
3002
- u(this, "RESOURCE", "homeworks");
2628
+ async isAdml() {
2629
+ const e = await this.getUser();
2630
+ return (e == null ? void 0 : e.functions.ADMIN_LOCAL) !== void 0;
3003
2631
  }
3004
- async loadResources() {
3005
- return (await this.httpGet("/homeworks/list")).filter((t) => t.owner && t.trashed === 0).map((t) => this.dataToResource({
3006
- title: t.title,
3007
- ownerName: t.owner.displayName,
3008
- owner: t.owner.userId,
3009
- icon: t.thumbnail || "/img/illustrations/homeworks.svg",
3010
- path: "/homeworks#/view-homeworks/" + t._id,
3011
- _id: "" + t._id,
3012
- shared: typeof t.shared < "u",
3013
- modified: t.modified
3014
- }));
2632
+ /**
2633
+ * Get details of an application if the user can access it.
2634
+ * @return undefined if no access, or app not found
2635
+ */
2636
+ async getWebApp(e) {
2637
+ const t = await this.getUser();
2638
+ return t == null ? void 0 : t.apps.find((s) => {
2639
+ var r;
2640
+ 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;
2641
+ });
3015
2642
  }
3016
2643
  }
3017
- class MagnetoBehaviour extends AbstractBehaviourService {
3018
- constructor() {
3019
- super(...arguments);
3020
- u(this, "APP", "magneto");
3021
- u(this, "RESOURCE", "magneto");
2644
+ const bundle = {}, promises = {}, defaultDiacriticsRemovalMap = [
2645
+ {
2646
+ base: "A",
2647
+ 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
2648
+ },
2649
+ { base: "AA", letters: /[\uA732]/g },
2650
+ { base: "AE", letters: /[\u00C6\u01FC\u01E2]/g },
2651
+ { base: "AO", letters: /[\uA734]/g },
2652
+ { base: "AU", letters: /[\uA736]/g },
2653
+ { base: "AV", letters: /[\uA738\uA73A]/g },
2654
+ { base: "AY", letters: /[\uA73C]/g },
2655
+ {
2656
+ base: "B",
2657
+ letters: /[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g
2658
+ },
2659
+ {
2660
+ base: "C",
2661
+ letters: /[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g
2662
+ },
2663
+ {
2664
+ base: "D",
2665
+ letters: /[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g
2666
+ },
2667
+ { base: "DZ", letters: /[\u01F1\u01C4]/g },
2668
+ { base: "Dz", letters: /[\u01F2\u01C5]/g },
2669
+ {
2670
+ base: "E",
2671
+ 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
2672
+ },
2673
+ { base: "F", letters: /[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g },
2674
+ {
2675
+ base: "G",
2676
+ letters: /[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g
2677
+ },
2678
+ {
2679
+ base: "H",
2680
+ letters: /[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g
2681
+ },
2682
+ {
2683
+ base: "I",
2684
+ letters: /[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g
2685
+ },
2686
+ { base: "J", letters: /[\u004A\u24BF\uFF2A\u0134\u0248]/g },
2687
+ {
2688
+ base: "K",
2689
+ letters: /[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g
2690
+ },
2691
+ {
2692
+ base: "L",
2693
+ letters: /[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780]/g
2694
+ },
2695
+ { base: "LJ", letters: /[\u01C7]/g },
2696
+ { base: "Lj", letters: /[\u01C8]/g },
2697
+ { base: "M", letters: /[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g },
2698
+ {
2699
+ base: "N",
2700
+ letters: /[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g
2701
+ },
2702
+ { base: "NJ", letters: /[\u01CA]/g },
2703
+ { base: "Nj", letters: /[\u01CB]/g },
2704
+ {
2705
+ base: "O",
2706
+ 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
2707
+ },
2708
+ { base: "OI", letters: /[\u01A2]/g },
2709
+ { base: "OO", letters: /[\uA74E]/g },
2710
+ { base: "OU", letters: /[\u0222]/g },
2711
+ {
2712
+ base: "P",
2713
+ letters: /[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g
2714
+ },
2715
+ { base: "Q", letters: /[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g },
2716
+ {
2717
+ base: "R",
2718
+ letters: /[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g
2719
+ },
2720
+ {
2721
+ base: "S",
2722
+ letters: /[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g
2723
+ },
2724
+ {
2725
+ base: "T",
2726
+ letters: /[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g
2727
+ },
2728
+ { base: "TZ", letters: /[\uA728]/g },
2729
+ {
2730
+ base: "U",
2731
+ 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
2732
+ },
2733
+ { base: "V", letters: /[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g },
2734
+ { base: "VY", letters: /[\uA760]/g },
2735
+ {
2736
+ base: "W",
2737
+ letters: /[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g
2738
+ },
2739
+ { base: "X", letters: /[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g },
2740
+ {
2741
+ base: "Y",
2742
+ letters: /[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g
2743
+ },
2744
+ {
2745
+ base: "Z",
2746
+ letters: /[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g
2747
+ },
2748
+ {
2749
+ base: "a",
2750
+ 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
2751
+ },
2752
+ { base: "aa", letters: /[\uA733]/g },
2753
+ { base: "ae", letters: /[\u00E6\u01FD\u01E3]/g },
2754
+ { base: "ao", letters: /[\uA735]/g },
2755
+ { base: "au", letters: /[\uA737]/g },
2756
+ { base: "av", letters: /[\uA739\uA73B]/g },
2757
+ { base: "ay", letters: /[\uA73D]/g },
2758
+ {
2759
+ base: "b",
2760
+ letters: /[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g
2761
+ },
2762
+ {
2763
+ base: "c",
2764
+ letters: /[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g
2765
+ },
2766
+ {
2767
+ base: "d",
2768
+ letters: /[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g
2769
+ },
2770
+ { base: "dz", letters: /[\u01F3\u01C6]/g },
2771
+ {
2772
+ base: "e",
2773
+ 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
2774
+ },
2775
+ { base: "f", letters: /[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g },
2776
+ {
2777
+ base: "g",
2778
+ letters: /[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g
2779
+ },
2780
+ {
2781
+ base: "h",
2782
+ letters: /[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g
2783
+ },
2784
+ { base: "hv", letters: /[\u0195]/g },
2785
+ {
2786
+ base: "i",
2787
+ letters: /[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g
2788
+ },
2789
+ { base: "j", letters: /[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g },
2790
+ {
2791
+ base: "k",
2792
+ letters: /[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g
2793
+ },
2794
+ {
2795
+ base: "l",
2796
+ letters: /[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g
2797
+ },
2798
+ { base: "lj", letters: /[\u01C9]/g },
2799
+ { base: "m", letters: /[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g },
2800
+ {
2801
+ base: "n",
2802
+ letters: /[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g
2803
+ },
2804
+ { base: "nj", letters: /[\u01CC]/g },
2805
+ {
2806
+ base: "o",
2807
+ 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
2808
+ },
2809
+ { base: "oi", letters: /[\u01A3]/g },
2810
+ { base: "ou", letters: /[\u0223]/g },
2811
+ { base: "oo", letters: /[\uA74F]/g },
2812
+ {
2813
+ base: "p",
2814
+ letters: /[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g
2815
+ },
2816
+ { base: "q", letters: /[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g },
2817
+ {
2818
+ base: "r",
2819
+ letters: /[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g
2820
+ },
2821
+ {
2822
+ base: "s",
2823
+ letters: /[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g
2824
+ },
2825
+ {
2826
+ base: "t",
2827
+ letters: /[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g
2828
+ },
2829
+ { base: "tz", letters: /[\uA729]/g },
2830
+ {
2831
+ base: "u",
2832
+ 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
2833
+ },
2834
+ { base: "v", letters: /[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g },
2835
+ { base: "vy", letters: /[\uA761]/g },
2836
+ {
2837
+ base: "w",
2838
+ letters: /[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g
2839
+ },
2840
+ { base: "x", letters: /[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g },
2841
+ {
2842
+ base: "y",
2843
+ letters: /[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g
2844
+ },
2845
+ {
2846
+ base: "z",
2847
+ letters: /[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g
3022
2848
  }
3023
- async loadResources() {
3024
- const { all: t } = await this.httpGet(
3025
- "/magneto/boards/editable"
3026
- );
3027
- return t.map((s) => this.dataToResource({
3028
- _id: s._id,
3029
- title: s.title,
3030
- icon: s.imageUrl,
3031
- owner: s.ownerId,
3032
- ownerName: s.ownerName,
3033
- path: `/magneto#/board/${s._id}/view`,
3034
- shared: !!(s.shared && s.shared.length >= 0),
3035
- modified: "" + s.modificationDate
3036
- }));
2849
+ ];
2850
+ class IdiomService {
2851
+ constructor(e) {
2852
+ this.context = e;
3037
2853
  }
3038
- }
3039
- class MindmapBehaviour extends AbstractBehaviourService {
3040
- constructor() {
3041
- super(...arguments);
3042
- u(this, "APP", "mindmap");
3043
- u(this, "RESOURCE", "mindmap");
2854
+ get http() {
2855
+ return this.context.http();
3044
2856
  }
3045
- async loadResources() {
3046
- return (await this.httpGet("/mindmap/list/all")).map(
3047
- (s) => this.dataToResource({
3048
- title: s.name,
3049
- ownerName: s.owner.displayName,
3050
- owner: s.owner.userId,
3051
- icon: s.thumbnail || "/img/illustrations/mindmap-default.png",
3052
- path: "/mindmap#/view/" + s._id,
3053
- _id: s._id,
3054
- shared: !!(s.shared && s.shared.length >= 0),
3055
- modified: s.modified
3056
- })
3057
- );
2857
+ async getIdiom(e, t) {
2858
+ await Promise.all([
2859
+ this.addBundlePromise(e, "/i18n"),
2860
+ this.addBundlePromise(e, `/${t}/i18n`)
2861
+ ]);
3058
2862
  }
3059
- }
3060
- class PagesBehaviour extends AbstractBehaviourService {
3061
- constructor() {
3062
- super(...arguments);
3063
- u(this, "APP", "pages");
3064
- u(this, "RESOURCE", "pages");
2863
+ translate(e, t) {
2864
+ e = e ?? "";
2865
+ let s = bundle[e] === void 0 ? e : bundle[e];
2866
+ if (t && typeof t == "object")
2867
+ for (const r in t)
2868
+ typeof t[r] < "u" && (s = s.replace(
2869
+ new RegExp("\\${" + r + "}", "g"),
2870
+ "" + t[r]
2871
+ ));
2872
+ return s;
3065
2873
  }
3066
- async loadResources() {
3067
- const t = await this.httpGet("/pages/list/all"), s = [];
3068
- return t.forEach((r) => {
3069
- var o;
3070
- const i = r.thumbnail ? r.thumbnail + "?thumbnail=48x48" : "/img/illustrations/pages.svg";
3071
- s.push(
3072
- this.dataToResource({
3073
- title: r.title,
3074
- owner: r.owner.userId,
3075
- ownerName: r.owner.displayName,
3076
- icon: i,
3077
- path: "/pages#/website/" + r._id,
3078
- _id: r._id,
3079
- shared: typeof r.shared < "u",
3080
- modified: r.modified
3081
- })
3082
- ), (o = r.pages) == null || o.forEach((a) => {
3083
- s.push(
3084
- this.dataToResource({
3085
- title: a.title,
3086
- owner: r.owner.userId,
3087
- ownerName: r.owner.displayName,
3088
- icon: i,
3089
- path: "/pages#/website/" + r._id + "/" + a.titleLink,
3090
- _id: r._id + "/" + a.titleLink,
3091
- shared: typeof r.shared < "u",
3092
- modified: r.modified
3093
- })
3094
- );
3095
- });
3096
- }), s;
2874
+ addBundlePromise(e, t) {
2875
+ return this.loadBundlePromise(e, t);
3097
2876
  }
3098
- }
3099
- class PollBehaviour extends AbstractBehaviourService {
3100
- constructor() {
3101
- super(...arguments);
3102
- u(this, "APP", "poll");
3103
- u(this, "RESOURCE", "poll");
2877
+ addBundle(e, t, s) {
2878
+ this.loadBundle(e, t, s);
3104
2879
  }
3105
- async loadResources() {
3106
- return (await this.httpGet("/poll/list/all")).map((s) => {
3107
- const r = s.icon ? s.icon + "?thumbnail=48x48" : "/img/icons/glyphicons_036_file.png";
3108
- return this.dataToResource({
3109
- title: s.question,
3110
- ownerName: s.owner.displayName,
3111
- icon: r,
3112
- path: "/poll#/view/" + s._id,
3113
- _id: s._id,
3114
- owner: s.owner.userId,
3115
- shared: !!(s.shared && s.shared.length >= 0),
3116
- modified: s.modified
2880
+ loadBundlePromise(e, t) {
2881
+ return this.loadBundle(e, t), promises[t];
2882
+ }
2883
+ loadBundle(e, t, s) {
2884
+ const r = promises[t];
2885
+ if (r)
2886
+ s && r.then(s).catch(s);
2887
+ else {
2888
+ const i = new Promisified();
2889
+ promises[t] = i.promise;
2890
+ const o = {};
2891
+ e && (o["Accept-Language"] = e), this.http.get(t, { headers: o }).then((a) => {
2892
+ Object.assign(bundle, a), typeof s == "function" && s(), i.resolve();
2893
+ }).catch((a) => {
2894
+ typeof s == "function" && s(), i.reject();
3117
2895
  });
2896
+ }
2897
+ }
2898
+ addTranslations(e, t) {
2899
+ notify.onLangReady().promise.then((s) => {
2900
+ this.loadBundle(s, e + "/" + s + ".json", t);
3118
2901
  });
3119
2902
  }
3120
- }
3121
- class ScrapbookBehaviour extends AbstractBehaviourService {
3122
- constructor() {
3123
- super(...arguments);
3124
- u(this, "APP", "scrapbook");
3125
- u(this, "RESOURCE", "scrapbook");
2903
+ addAllTranslations(e) {
2904
+ return e && e.length > 0 ? notify.onLangReady().promise.then(
2905
+ (t) => Promise.all(
2906
+ e.map(
2907
+ (s) => this.loadBundlePromise(t, s + "/" + t + ".json")
2908
+ )
2909
+ )
2910
+ ).then(() => {
2911
+ }) : Promise.reject();
3126
2912
  }
3127
- async loadResources() {
3128
- return (await this.httpGet(
3129
- "/scrapbook/list/all"
3130
- )).map((s) => {
3131
- const r = s.icon || "/img/illustrations/scrapbook.svg";
3132
- return this.dataToResource({
3133
- title: s.name,
3134
- owner: s.owner.userId,
3135
- ownerName: s.owner.displayName,
3136
- icon: r,
3137
- path: "/scrapbook#/view-scrapbook/" + s._id,
3138
- _id: s._id,
3139
- shared: !!(s.shared && s.shared.length >= 0),
3140
- modified: s.modified
3141
- });
3142
- });
2913
+ addKeys(e) {
2914
+ for (const t in e)
2915
+ typeof bundle[t] != "string" && (bundle[t] = e[t]);
3143
2916
  }
3144
- }
3145
- class TimelinegeneratorBehaviour extends AbstractBehaviourService {
3146
- constructor() {
3147
- super(...arguments);
3148
- u(this, "APP", "timelinegenerator");
3149
- u(this, "RESOURCE", "timelinegenerator");
2917
+ removeAccents(e) {
2918
+ for (let t = 0; t < defaultDiacriticsRemovalMap.length; t++)
2919
+ e = e.replace(
2920
+ defaultDiacriticsRemovalMap[t].letters,
2921
+ defaultDiacriticsRemovalMap[t].base
2922
+ );
2923
+ return e;
3150
2924
  }
3151
- loadResources() {
3152
- return new Promise(async (t, s) => {
3153
- try {
3154
- const i = (await this.httpGet(
3155
- "/timelinegenerator/timelines"
3156
- )).map((o) => {
3157
- const a = o.icon || "/img/illustrations/timeline-default.png";
3158
- return this.dataToResource({
3159
- title: o.headline,
3160
- ownerName: o.owner.displayName,
3161
- owner: o.owner.userId,
3162
- icon: a,
3163
- path: "/timelinegenerator#/view/" + o._id,
3164
- _id: o._id,
3165
- shared: typeof o.shared < "u",
3166
- modified: o.modified
3167
- });
3168
- });
3169
- t(i);
3170
- } catch (r) {
3171
- s(r);
3172
- }
3173
- });
2925
+ }
2926
+ class StringUtils {
2927
+ static removeAccents(e) {
2928
+ for (let t = 0; t < defaultDiacriticsRemovalMap.length; t++)
2929
+ e = e.replace(
2930
+ defaultDiacriticsRemovalMap[t].letters,
2931
+ defaultDiacriticsRemovalMap[t].base
2932
+ );
2933
+ return e;
3174
2934
  }
3175
2935
  }
3176
- class WikiBehaviour extends AbstractBehaviourService {
3177
- constructor() {
3178
- super(...arguments);
3179
- u(this, "APP", "wiki");
3180
- u(this, "RESOURCE", "wiki");
2936
+ class ShareService {
2937
+ //
2938
+ // IMPLEMENTATION
2939
+ //
2940
+ constructor(e) {
2941
+ this.context = e;
3181
2942
  }
3182
- async loadResources() {
3183
- return (await this.httpGet(
3184
- "/wiki/listallpages?visible=true"
3185
- )).map((s) => s.pages.map((r) => {
3186
- let i;
3187
- return typeof s.thumbnail > "u" || s.thumbnail === "" ? i = "/img/icons/glyphicons_036_file.png" : i = s.thumbnail + "?thumbnail=48x48", this.dataToResource({
3188
- title: r.title + " [" + s.title + "]",
3189
- ownerName: s.owner.displayName,
3190
- owner: s.owner.userId,
3191
- icon: i,
3192
- path: "/wiki#/view/" + s._id + "/" + r._id,
3193
- _id: `${s._id}#${r._id}`,
3194
- shared: typeof s.shared < "u",
3195
- modified: r.modified
3196
- });
3197
- })).flat();
2943
+ get directory() {
2944
+ return this.context.directory();
3198
2945
  }
3199
- }
3200
- class WorkspaceBehaviour extends AbstractBehaviourService {
3201
- constructor() {
3202
- super(...arguments);
3203
- u(this, "APP", "workspace");
3204
- u(this, "RESOURCE", "workspace");
2946
+ get http() {
2947
+ return this.context.http();
2948
+ }
2949
+ get cache() {
2950
+ return this.context.cache();
2951
+ }
2952
+ getSearchUrl(e, t, s, r) {
2953
+ if (!r)
2954
+ return `/${e}/share/json/${t}?search=${s}`;
2955
+ if (r.includes("?search=")) {
2956
+ const [i] = r.split("?search=");
2957
+ return `${i}?search=${s}`;
2958
+ } else return r.includes("?") ? `${r}&search=${s}` : `${r}?search=${s}`;
2959
+ }
2960
+ async searchShareSubjects(e, t, s, r) {
2961
+ const i = StringUtils.removeAccents(s).toLowerCase(), o = this.getSearchUrl(
2962
+ e,
2963
+ t,
2964
+ s,
2965
+ r
2966
+ ), a = await this.cache.httpGetJson(o), c = a.users.visibles.filter(({ username: h, firstName: y, lastName: d, login: g }) => {
2967
+ const A = StringUtils.removeAccents(
2968
+ d || ""
2969
+ ).toLowerCase(), f = StringUtils.removeAccents(
2970
+ y || ""
2971
+ ).toLowerCase(), w = StringUtils.removeAccents(
2972
+ h || ""
2973
+ ).toLowerCase(), F = StringUtils.removeAccents(g || "").toLowerCase();
2974
+ return w.includes(i) || f.includes(i) || A.includes(i) || F.includes(i);
2975
+ }).map((h) => ({
2976
+ avatarUrl: this.directory.getAvatarUrl(h.id, "user"),
2977
+ directoryUrl: this.directory.getDirectoryUrl(h.id, "user"),
2978
+ displayName: h.username,
2979
+ id: h.id,
2980
+ profile: h.profile,
2981
+ type: "user"
2982
+ })), l = a.groups.visibles.filter(({ name: h }) => StringUtils.removeAccents(h || "").toLowerCase().includes(i)).map((h) => ({
2983
+ avatarUrl: this.directory.getAvatarUrl(h.id, "group"),
2984
+ directoryUrl: this.directory.getDirectoryUrl(h.id, "group"),
2985
+ displayName: h.name,
2986
+ id: h.id,
2987
+ type: "group",
2988
+ structureName: h.structureName
2989
+ }));
2990
+ return [...(await this.directory.getBookMarks()).filter(({ displayName: h }) => StringUtils.removeAccents(
2991
+ h || ""
2992
+ ).toLowerCase().includes(i)).map((h) => ({
2993
+ avatarUrl: "",
2994
+ directoryUrl: "",
2995
+ profile: "",
2996
+ displayName: h.displayName,
2997
+ id: h.id,
2998
+ type: "sharebookmark"
2999
+ })), ...c, ...l];
3205
3000
  }
3206
- loadResources({ search: t, asset_id: s }) {
3207
- return new Promise(async (r, i) => {
3208
- try {
3209
- let o = "/workspace/documents?filter=all&hierarchical=true";
3210
- s && s.length ? o += `&search=${t}` : t && t.length && (o += `&search=${t}`);
3211
- const c = (await this.httpGet(o)).filter((l) => !l.deleted).map((l) => {
3212
- const h = l.metadata["content-type"] && l.metadata["content-type"].indexOf("image") !== -1 ? `/workspace/document/${l._id}?thumbnail=120x120` : "/img/icons/unknown-large.png";
3213
- return this.dataToResource({
3214
- title: l.name,
3215
- ownerName: l.ownerName,
3216
- owner: l.owner,
3217
- icon: h,
3218
- path: `/workspace/document/${l._id}`,
3219
- _id: l._id,
3220
- shared: !!(l.shared && l.shared.length >= 0),
3221
- modified: l.modified
3222
- });
3223
- });
3224
- r(c);
3225
- } catch (o) {
3226
- i(o);
3001
+ async getShareMapping(e, t) {
3002
+ const s = await this.cache.httpGetJson(
3003
+ t || `/${e}/rights/sharing`
3004
+ );
3005
+ for (const r of Object.keys(s))
3006
+ if (r.includes(".")) {
3007
+ const i = r.split(".")[1], o = s[r];
3008
+ delete s[r], s[i] = o;
3227
3009
  }
3228
- });
3010
+ return s;
3229
3011
  }
3230
- }
3231
- const b = class b {
3232
- static async initialize(e, t) {
3233
- const s = e.http();
3234
- if (!this.resourceProducingApps.length) {
3235
- this.resourceProducingApps = [t, "workspace"];
3236
- try {
3237
- const [r, i] = await Promise.all([
3238
- s.get("/resources-applications"),
3239
- e.session().getUser()
3240
- ]);
3241
- i != null && i.apps && (r != null && r.length) && (this.resourceProducingApps = r.filter(
3242
- (o) => i.apps.some((a) => a.address.includes(o))
3243
- ));
3244
- } catch (r) {
3245
- console.warn("Failed to load resource-producing apps:", r);
3246
- }
3012
+ getActionsAvailableFor({ id: e, type: t }, s, r) {
3013
+ const o = (t === "user" ? s.users.checked[e] : s.groups.checked[e]) || [], a = Object.keys(r), c = [];
3014
+ for (const l of a)
3015
+ r[l].filter(
3016
+ (h) => o.includes(h)
3017
+ ).length > 0 && c.push(l);
3018
+ return c;
3019
+ }
3020
+ async getRightsForResource(e, t, s) {
3021
+ const r = await this.directory.getBookMarks(), i = this.getSearchUrl(
3022
+ e,
3023
+ t,
3024
+ "",
3025
+ s == null ? void 0 : s.getResourceRights
3026
+ ), o = await this.cache.httpGetJson(
3027
+ i
3028
+ ), a = await this.getShareMapping(
3029
+ e,
3030
+ s == null ? void 0 : s.getShareMapping
3031
+ ), c = await this.cache.httpGetJson(
3032
+ "/infra/public/json/sharing-rights.json"
3033
+ ), l = Object.keys(o.users.checked).map((d) => o.users.visibles.find(
3034
+ (A) => A.id === d
3035
+ )).filter((d) => d !== void 0).map((d) => {
3036
+ const g = this.getActionsAvailableFor(
3037
+ { id: d.id, type: "user" },
3038
+ o,
3039
+ a
3040
+ );
3041
+ return {
3042
+ id: d.id,
3043
+ type: "user",
3044
+ displayName: d.username,
3045
+ profile: d.profile,
3046
+ avatarUrl: this.directory.getAvatarUrl(d.id, "user"),
3047
+ directoryUrl: this.directory.getDirectoryUrl(d.id, "user"),
3048
+ actions: g.map((f) => {
3049
+ const w = c[f];
3050
+ return {
3051
+ displayName: f,
3052
+ id: f,
3053
+ priority: w.priority
3054
+ };
3055
+ })
3056
+ };
3057
+ }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), p = Object.keys(o.groups.checked).map((d) => o.groups.visibles.find(
3058
+ (A) => A.id === d
3059
+ )).filter((d) => d !== void 0).map((d) => {
3060
+ const g = this.getActionsAvailableFor(
3061
+ { id: d.id, type: "group" },
3062
+ o,
3063
+ a
3064
+ );
3065
+ return {
3066
+ id: d.id,
3067
+ type: "group",
3068
+ displayName: d.name,
3069
+ profile: void 0,
3070
+ avatarUrl: this.directory.getAvatarUrl(d.id, "group"),
3071
+ directoryUrl: this.directory.getDirectoryUrl(d.id, "group"),
3072
+ actions: g.map((f) => {
3073
+ const w = c[f];
3074
+ return {
3075
+ displayName: f,
3076
+ id: f,
3077
+ priority: w.priority
3078
+ };
3079
+ })
3080
+ };
3081
+ }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), E = [...l, ...p], h = o.groups.visibles.map(
3082
+ ({ groupDisplayName: d, id: g, name: A, labels: f }) => ({
3083
+ labels: f,
3084
+ displayName: d || A,
3085
+ id: g
3086
+ })
3087
+ ), y = o.users.visibles.map(
3088
+ ({ id: d, profile: g, username: A, firstName: f, lastName: w, login: F }) => ({
3089
+ displayName: A,
3090
+ firstName: f,
3091
+ lastName: w,
3092
+ login: F,
3093
+ profile: g,
3094
+ id: d
3095
+ })
3096
+ );
3097
+ return {
3098
+ rights: E,
3099
+ visibleBookmarks: r,
3100
+ visibleGroups: h,
3101
+ visibleUsers: y
3102
+ };
3103
+ }
3104
+ async getPutSharePayload(e, t, s) {
3105
+ const r = {
3106
+ users: {},
3107
+ groups: {},
3108
+ bookmarks: {}
3109
+ }, i = await this.getShareMapping(e, s);
3110
+ for (const o of t) {
3111
+ const a = o.actions.map((l) => i[l.id]).reduce((l, p) => Array.isArray(p) ? [...l, ...p] : l, []), c = [...new Set(a)];
3112
+ c.length > 0 && (o.type === "user" ? r.users[o.id] = c : o.type === "group" ? r.groups[o.id] = c : r.bookmarks[o.id] = c);
3247
3113
  }
3248
- return this.resourceProducingApps;
3114
+ return r;
3249
3115
  }
3250
- static registerCustomBehaviour(e, t, s) {
3251
- this.registry.register({ application: e, resourceType: t }, s);
3116
+ async saveRights(e, t, s, r) {
3117
+ const i = await this.getPutSharePayload(
3118
+ e,
3119
+ s,
3120
+ r == null ? void 0 : r.getShareMapping
3121
+ ), o = (r == null ? void 0 : r.saveResourceRights) || `/${e}/share/resource/${t}`, a = this.getSearchUrl(
3122
+ e,
3123
+ t,
3124
+ "",
3125
+ r == null ? void 0 : r.getResourceRights
3126
+ );
3127
+ return this.cache.clearCache(a), await this.http.putJson(o, i);
3252
3128
  }
3253
- static async registerBehaviours(e) {
3254
- this.resourceProducingApps.forEach((t) => {
3255
- const s = { application: e, resourceType: t };
3256
- this.registry.register(
3257
- s,
3258
- (r) => this.serviceFor(r, e, t)
3259
- );
3260
- });
3129
+ async getActionsForApp(e, t) {
3130
+ const s = await this.cache.httpGetJson(
3131
+ "/infra/public/json/sharing-rights.json"
3132
+ ), r = await this.getShareMapping(e, t);
3133
+ return Object.keys(s).map((o) => {
3134
+ const a = s[o];
3135
+ return {
3136
+ displayName: o,
3137
+ id: o,
3138
+ priority: a.priority,
3139
+ requires: a.requires
3140
+ };
3141
+ }).filter((o) => {
3142
+ var a;
3143
+ return ((a = r[o.id]) == null ? void 0 : a.length) > 0;
3144
+ }).sort((o, a) => o.priority - a.priority);
3261
3145
  }
3262
- static serviceFor(e, t, s) {
3263
- let r;
3264
- switch (s) {
3265
- case "timelinegenerator":
3266
- r = new TimelinegeneratorBehaviour(e);
3267
- break;
3268
- case "workspace":
3269
- r = new WorkspaceBehaviour(e);
3270
- break;
3271
- case "blog":
3272
- r = new BlogBehaviour(e);
3273
- break;
3274
- case "actualites":
3275
- r = new ActualitesBehaviour(e);
3276
- break;
3277
- case "wiki":
3278
- r = new WikiBehaviour(e);
3279
- break;
3280
- case "pages":
3281
- r = new PagesBehaviour(e);
3282
- break;
3283
- case "poll":
3284
- r = new PollBehaviour(e);
3285
- break;
3286
- case "community":
3287
- r = new CommunityBehaviour(e);
3288
- break;
3289
- case "mindmap":
3290
- r = new MindmapBehaviour(e);
3291
- break;
3292
- case "forum":
3293
- r = new ForumBehaviour(e);
3294
- break;
3295
- case "homeworks":
3296
- r = new HomeworksBehaviour(e);
3297
- break;
3298
- case "scrapbook":
3299
- r = new ScrapbookBehaviour(e);
3300
- break;
3301
- case "collaborativewall":
3302
- r = new CollaborativewallBehaviour(e);
3303
- break;
3304
- case "exercizer":
3305
- r = new ExercizerBehaviour(e);
3306
- break;
3307
- case "formulaire":
3308
- r = new FormulaireBehaviour(e);
3309
- break;
3310
- case "magneto":
3311
- r = new MagnetoBehaviour(e);
3312
- break;
3313
- case "appointments":
3314
- r = new AppointmentsBehaviour(e);
3315
- break;
3316
- default:
3317
- throw ERROR_CODE.NOT_SUPPORTED;
3146
+ }
3147
+ const defaultMappers = {
3148
+ csv: function({ type: n, extension: e }) {
3149
+ return MimeTypeUtils.INSTANCE.isCsvLike(n, e);
3150
+ },
3151
+ doc: function({ type: n, extension: e }) {
3152
+ return MimeTypeUtils.INSTANCE.isWordLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("wordprocessing") !== -1;
3153
+ },
3154
+ xls: function({ type: n, extension: e }) {
3155
+ return MimeTypeUtils.INSTANCE.isExcelLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("spreadsheet") !== -1 || n.indexOf("ms-excel") !== -1;
3156
+ },
3157
+ img: function({ type: n }) {
3158
+ return n.indexOf("image") !== -1;
3159
+ },
3160
+ pdf: function({ type: n }) {
3161
+ return n.indexOf("pdf") !== -1 || n === "application/x-download";
3162
+ },
3163
+ ppt: function({ type: n, extension: e }) {
3164
+ return MimeTypeUtils.INSTANCE.isPowerpointLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("presentation") !== -1 || n.indexOf("powerpoint") !== -1;
3165
+ },
3166
+ txt: function({ type: n, extension: e }) {
3167
+ return MimeTypeUtils.INSTANCE.isTxtLike(n, e);
3168
+ },
3169
+ md: function({ type: n, extension: e }) {
3170
+ return MimeTypeUtils.INSTANCE.isMdLike(n, e);
3171
+ },
3172
+ video: function({ type: n }) {
3173
+ return n.indexOf("video") !== -1;
3174
+ },
3175
+ audio: function({ type: n }) {
3176
+ return n.indexOf("audio") !== -1;
3177
+ },
3178
+ zip: function({ type: n }) {
3179
+ return n.indexOf("zip") !== -1 || n.indexOf("rar") !== -1 || n.indexOf("tar") !== -1 || n.indexOf("7z") !== -1;
3180
+ }
3181
+ }, v = class v {
3182
+ /* Similar role notion as in infra-front > workspace > Model.ts */
3183
+ static getRole(e) {
3184
+ var t, s;
3185
+ return v.role(
3186
+ (t = e.metadata) == null ? void 0 : t["content-type"],
3187
+ !1,
3188
+ (s = e.metadata) == null ? void 0 : s.extension
3189
+ );
3190
+ }
3191
+ /* Similar role notion as in infra-front > workspace > Model.ts */
3192
+ static role(e, t = !1, s) {
3193
+ if (s && (s = s.trim()), !e) return "unknown";
3194
+ this.roleMappers || console.warn("[DocumentHelper.role] should not have empty roles", this);
3195
+ const r = { type: e, previewRole: t, extension: s };
3196
+ for (const i of this.roleMappers) {
3197
+ const o = i(r);
3198
+ if (o)
3199
+ return o;
3318
3200
  }
3319
- return r.APP = t, r;
3201
+ return "unknown";
3320
3202
  }
3321
3203
  };
3322
- //
3323
- // STATIC REGISTRY
3324
- //
3325
- u(b, "registry", new ServiceRegistry()), // Expose some useful functions
3326
- u(b, "findBehaviour", b.registry.findService.bind(b.registry)), u(b, "hasBehaviour", b.registry.isRegistered.bind(b.registry)), u(b, "resourceProducingApps", []);
3327
- let SnipletsService = b;
3328
- class RightService {
3204
+ // FIXME add edumedia support
3205
+ u(v, "roleMappers", [
3206
+ (e) => Object.keys(defaultMappers).find((s) => defaultMappers[s](e))
3207
+ ]);
3208
+ let DocumentHelper = v;
3209
+ class WorkspaceService {
3329
3210
  constructor(e) {
3330
3211
  this.context = e;
3331
3212
  }
3332
- get session() {
3333
- return this.context.session();
3213
+ get http() {
3214
+ return this.context.http();
3215
+ }
3216
+ extractMetadata(e) {
3217
+ const t = e.name || "", s = t.split("."), r = e.type || "application/octet-stream", i = s.length > 1 ? s[s.length - 1] : "", o = {
3218
+ "content-type": r,
3219
+ filename: t,
3220
+ size: e.size,
3221
+ extension: i,
3222
+ role: DocumentHelper.role(r, !1, i)
3223
+ }, a = t.replace("." + o.extension, ""), c = o.extension ? a + "." + o.extension : a;
3224
+ return { basename: a, fullname: c, metadata: o };
3225
+ }
3226
+ async saveFile(e, t) {
3227
+ const { fullname: s, metadata: r } = this.extractMetadata(e), i = new FormData();
3228
+ i.append("file", e, s);
3229
+ const o = [];
3230
+ ((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}`);
3231
+ const a = await this.http.postFile(
3232
+ `/workspace/document?${o.join("&")}`,
3233
+ i
3234
+ );
3235
+ if (this.http.isResponseError())
3236
+ throw this.http.latestResponse.statusText;
3237
+ return a;
3238
+ }
3239
+ async updateFile(e, t, s) {
3240
+ const { fullname: r, metadata: i } = this.extractMetadata(t), o = new FormData();
3241
+ o.append("file", t, r);
3242
+ const a = [];
3243
+ 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}`);
3244
+ const c = await this.http.putFile(
3245
+ `/workspace/document/${e}?${a.join("&")}`,
3246
+ o
3247
+ );
3248
+ if (this.http.isResponseError())
3249
+ throw this.http.latestResponse.statusText;
3250
+ return c;
3251
+ }
3252
+ async deleteFile(e) {
3253
+ const t = e.map((s) => s._id);
3254
+ if (t.length == 0)
3255
+ Promise.resolve(null);
3256
+ else if (await this.http.deleteJson("/workspace/documents", {
3257
+ ids: t
3258
+ }), this.http.isResponseError())
3259
+ throw this.http.latestResponse.statusText;
3260
+ }
3261
+ async acceptDocuments(e) {
3262
+ const t = await this.context.session().getUser();
3263
+ return (s) => s.deleted && s.trasher ? (t == null ? void 0 : t.userId) == s.trasher : !0;
3264
+ }
3265
+ async searchDocuments(e) {
3266
+ const t = e.filter !== "external" || e.parentId ? await this.http.get("/workspace/documents", {
3267
+ queryParams: { ...e, _: (/* @__PURE__ */ new Date()).getTime() }
3268
+ }) : [], s = await this.acceptDocuments(e);
3269
+ return t.filter(s);
3270
+ }
3271
+ async listDocuments(e, t) {
3272
+ return this.searchDocuments({ filter: e, parentId: t, includeall: !0 });
3334
3273
  }
3335
3274
  /**
3336
- * Parse right concat as "$TYPE:$ID:$RIGHT"
3337
- * $TYPE = user | group | creator
3338
- * $ID: id of the resource
3339
- * $RIGHT: read | contrib | manage
3340
- *
3341
- * @param right a concat right
3342
- * @returns Right parsed
3275
+ * Duplicate and transfers documents if needed to a different folder with the specified application and visibility.
3276
+ * @param documents - The array of documents to transfer.
3277
+ * @param application - The application to associate with the transferred documents.
3278
+ * @param visibility - The visibility of the transferred documents. Defaults to "protected".
3279
+ * @returns A Promise that resolves to an array of transferred WorkspaceElements.
3343
3280
  */
3344
- parseResourceRight(e) {
3345
- const t = e.split(":");
3346
- if (t.length === 2) {
3347
- if (t[0] === "creator")
3348
- return {
3349
- id: t[1],
3350
- right: "creator",
3351
- type: "creator"
3352
- };
3353
- } else return t.length === 3 ? {
3354
- id: t[1],
3355
- right: t[2],
3356
- type: t[0]
3357
- } : void 0;
3281
+ async transferDocuments(e, t, s = "protected") {
3282
+ const r = [];
3283
+ if (e.forEach((i) => {
3284
+ (s === "public" && !i.public || !i.public && !i.protected) && r.push(i);
3285
+ }), r.length > 0) {
3286
+ const i = await this.http.post(
3287
+ "/workspace/documents/transfer",
3288
+ {
3289
+ application: t,
3290
+ visibility: s,
3291
+ ids: r.map((o) => o._id)
3292
+ }
3293
+ );
3294
+ if (this.http.isResponseError())
3295
+ throw this.http.latestResponse.statusText;
3296
+ return r.forEach((o, a) => {
3297
+ const c = e.findIndex(
3298
+ (l) => l._id === o._id
3299
+ );
3300
+ 0 <= c && c < e.length && (e[c] = i[a]);
3301
+ }), e.filter((o) => !!o);
3302
+ }
3303
+ return e;
3358
3304
  }
3359
3305
  /**
3360
- * Parse an array of rights concat as "$TYPE:$ID:$RIGHT"
3361
- * $TYPE = user | group | creator
3362
- * $ID: id of the resource
3363
- * $RIGHT: read | contrib | manage
3364
- *
3365
- * @param rights a list of concat rights
3366
- * @returns Array of Right parsed
3306
+ * Get the URL of the thumbnail of a workspace element (or its URL),
3307
+ * or `null` if none exists or can be created.
3367
3308
  */
3368
- parseResourceRights(e) {
3369
- return e.map((s) => this.parseResourceRight(s)).filter((s) => s !== void 0);
3309
+ getThumbnailUrl(e, t = 0, s = 0) {
3310
+ var i, o;
3311
+ const r = t > 0 || s > 0 ? `${t}x${s}` : "120x120";
3312
+ if (typeof e == "string")
3313
+ return e.includes("data:image") || e.includes("thumbnail") ? e : `${e}${e.includes("?") ? "&" : "?"}thumbnail=${r}`;
3314
+ {
3315
+ const a = `/workspace/${e.public ? "pub/" : ""}document/${e._id}?thumbnail=`, c = e.thumbnails;
3316
+ if ((o = (i = e.metadata) == null ? void 0 : i["content-type"]) != null && o.includes("video")) {
3317
+ const l = c && Object.keys(c).length > 0 ? Object.keys(c)[0] : null;
3318
+ return l ? a + l : null;
3319
+ } else
3320
+ return a + r;
3321
+ }
3370
3322
  }
3371
3323
  /**
3372
- * Check wether a user has the expected right for a resource
3373
- * @param user the userId and groupId concerned by the check
3374
- * @param expect the expected right to check
3375
- * @param rights array of Right for the resource
3376
- * @returns true if has rights
3324
+ * Get the URL of the file of a workspace element (or its URL),
3325
+ * or `null` if none exists or can be created.
3326
+ * @param filter - The filter to apply to the workspace element.
3327
+ * @param withChildren - If true, include all children folders.
3328
+ * @param parentId - The ID of the parent folder to list.
3329
+ * @param directShared - If true, include only elements directly shared with the user.
3330
+ *
3377
3331
  */
3378
- hasResourceRight({ id: e, groupIds: t }, s, r) {
3379
- const i = r.map((o) => typeof o == "string" ? this.parseResourceRight(o) : o).filter((o) => o !== void 0);
3380
- for (const o of i) {
3381
- if (o.id === e && o.type === "creator")
3382
- return !0;
3383
- if (o.id === e && o.type === "user" && o.right === s)
3384
- return !0;
3385
- if (t.includes(o.id) && o.type === "group" && o.right === s)
3386
- return !0;
3387
- }
3388
- return !1;
3332
+ listFolder(e, t = !1, s, r) {
3333
+ const i = {
3334
+ filter: e,
3335
+ hierarchical: t,
3336
+ parentId: s,
3337
+ directShared: r
3338
+ };
3339
+ return this.http.get("/workspace/folders/list", {
3340
+ queryParams: i
3341
+ });
3389
3342
  }
3390
3343
  /**
3391
- * Check wether the current user have resource right
3392
- * @param expect the expected right to check
3393
- * @param rights array of Right for the resource
3394
- * @returns true if has rights
3344
+ * List all folders in the workspace.
3345
+ * @param withChildren - If true, include all children folders.
3346
+ * @param parentId - The ID of the parent folder to list.
3347
+ * @returns A promise that resolves to an array of WorkspaceElement objects.
3395
3348
  */
3396
- async sessionHasResourceRight(e, t) {
3397
- try {
3398
- const s = await this.session.getUser();
3399
- return !!s && this.hasResourceRight(
3400
- { groupIds: s.groupsIds, id: s.userId },
3401
- e,
3402
- t
3403
- );
3404
- } catch (s) {
3405
- return console.error(`Unexpected error ${s} in sessionHasResourceRight()`), !1;
3406
- }
3349
+ listOwnerFolders(e, t) {
3350
+ return this.listFolder("owner", e, t);
3407
3351
  }
3408
3352
  /**
3409
- * Check wether the current user have at least one of resource right expected
3410
- * @param expects array of expected right to check
3411
- * @param rights array of Right for the resource
3412
- * @returns true if has rights
3353
+ * List all shared folders in the workspace.
3354
+ * @param withChildren - If true, include all children folders.
3355
+ * @param parentId - The ID of the parent folder to list.
3356
+ * @returns A promise that resolves to an array of WorkspaceElement objects.
3413
3357
  */
3414
- async sessionHasAtLeastOneResourceRight(e, t) {
3415
- for (const s of e)
3416
- if (await this.sessionHasResourceRight(s, t))
3417
- return !0;
3418
- return !1;
3358
+ listSharedFolders(e, t) {
3359
+ return this.listFolder("shared", e, t, !0);
3419
3360
  }
3420
3361
  /**
3421
- * Check wether the current user has resource right for each right list
3422
- * @param expect expected right to check
3423
- * @param rightsArray array of array of Right for multiple resources
3424
- * @returns true if has rights
3362
+ * Create a new folder in the workspace.
3363
+ * @param name - The name of the new folder.
3364
+ * @param parentId - The ID of the parent folder where the new folder will be created.
3365
+ * @returns void
3425
3366
  */
3426
- async sessionHasResourceRightForEachList(e, t) {
3427
- let s = 0;
3428
- for (const r of t)
3429
- await this.sessionHasResourceRight(e, r) && s++;
3430
- return s === t.length;
3367
+ createFolder(e, t) {
3368
+ const s = new FormData();
3369
+ return s.append("name", e), t && s.append("parentFolderId", t), this.http.postFile("/workspace/folder", s);
3370
+ }
3371
+ }
3372
+ let ATTag;
3373
+ class AnalyticsService {
3374
+ constructor(n) {
3375
+ this.context = n;
3376
+ }
3377
+ get http() {
3378
+ return this.context.http();
3379
+ }
3380
+ get session() {
3381
+ return this.context.session();
3431
3382
  }
3432
3383
  /**
3433
- * Check wether the current user have at least one of resource right for each right list
3434
- * @param expects array of expected right to check
3435
- * @param rightsArray array of array of Right for multiple resources
3436
- * @returns true if has rights
3384
+ * Xiti tracker for page loading.
3385
+ * @param locationPath
3386
+ * @param app
3437
3387
  */
3438
- async sessionHasAtLeastOneResourceRightForEachList(e, t) {
3439
- for (const s of e) {
3440
- let r = 0;
3441
- for (const i of t)
3442
- await this.sessionHasResourceRight(s, i) && r++;
3443
- if (r === t.length)
3444
- return !0;
3388
+ async trackPageLoad(n, e) {
3389
+ const [t] = await Promise.all([
3390
+ // get Xiti configuration
3391
+ this.getXitiConfig(e.name.toLowerCase()),
3392
+ // load Xiti javascript file
3393
+ this.loadXitiScript()
3394
+ ]);
3395
+ if (!t || !ATInternet) return;
3396
+ let s = t.LIBELLE_SERVICE.default || null;
3397
+ for (const r in t.LIBELLE_SERVICE)
3398
+ if (r !== "default" && n.indexOf(r) >= 0) {
3399
+ s = t.LIBELLE_SERVICE[r];
3400
+ break;
3401
+ }
3402
+ ATTag = new ATInternet.Tracker.Tag({ site: t.STRUCT_ID }), ATTag.setProps(
3403
+ {
3404
+ SERVICE: s,
3405
+ TYPE: t.TYPE,
3406
+ OUTIL: t.OUTIL,
3407
+ UAI: t.STRUCT_UAI,
3408
+ PROJET: t.PROJET,
3409
+ EXPLOITANT: t.EXPLOITANT,
3410
+ PLATEFORME: t.PLATFORME,
3411
+ PROFIL: t.PROFILE
3412
+ },
3413
+ !0
3414
+ ), ATTag.identifiedVisitor.set({
3415
+ id: t.ID_PERSO,
3416
+ category: t.PROFILE
3417
+ }), ATTag.page.set({
3418
+ name: (e == null ? void 0 : e.prefix) === "userbook" ? "directory" : e == null ? void 0 : e.prefix,
3419
+ chapter1: "",
3420
+ chapter2: "",
3421
+ chapter3: "",
3422
+ level2: t.STRUCT_UAI
3423
+ }), ATTag.dispatch();
3424
+ }
3425
+ async getXitiConfig(n) {
3426
+ const [e, t] = await Promise.all([
3427
+ this.http.get("/analyticsConf"),
3428
+ //FIXME change servers config to only keep the "all-in-one" query to /analyticsConf.
3429
+ this.http.get("/xiti/config")
3430
+ ]);
3431
+ if (!(e != null && e.type))
3432
+ throw ERROR_CODE.MALFORMED_DATA;
3433
+ return t != null && t.active && (e.xiti = await this.getXitiTrackingParams(t, n)), e.xiti;
3434
+ }
3435
+ async loadXitiScript() {
3436
+ if (typeof ATInternet > "u") {
3437
+ const scriptPath = "/xiti/public/js/lib/smarttag_ENT.js", response = await this.http.get(scriptPath, {
3438
+ headers: { Accept: "application/javascript" }
3439
+ });
3440
+ if (this.http.latestResponse.status != 200)
3441
+ throw "Error while loading XiTi script";
3442
+ eval(response);
3445
3443
  }
3446
- return !1;
3447
3444
  }
3448
- hasWorkflowRight(e, t) {
3449
- return t.findIndex((s) => s === e) !== -1;
3445
+ async getXitiTrackingParams(n, e) {
3446
+ if (!n.structureMap || !e) return;
3447
+ const t = await this.session.getUser(), s = await this.session.getUserProfile();
3448
+ let r;
3449
+ if (!(t != null && t.structures)) return;
3450
+ for (const l of t.structures) {
3451
+ const p = n.structureMap[l];
3452
+ if (p && p.collectiviteId && p.UAI) {
3453
+ r = p;
3454
+ break;
3455
+ }
3456
+ }
3457
+ if (!r || !r.active) return;
3458
+ const i = await configure.Platform.apps.getPublicConf(e);
3459
+ if (!i) return;
3460
+ const o = i.xiti;
3461
+ if (!o || !o.LIBELLE_SERVICE || !r.UAI) return;
3462
+ function a(l) {
3463
+ let p = "";
3464
+ for (let E = 0; E < l.length; E++)
3465
+ p += l.charCodeAt(E);
3466
+ return p;
3467
+ }
3468
+ const c = {
3469
+ Student: "ELEVE",
3470
+ Teacher: "ENSEIGNANT",
3471
+ Relative: "PARENT",
3472
+ Personnel: "ADMIN_VIE_SCOL_TECH",
3473
+ Guest: "AUTRE"
3474
+ };
3475
+ return {
3476
+ LIBELLE_SERVICE: o.LIBELLE_SERVICE,
3477
+ // Which property of LIBELLE_SERVICE to use depends on the frontend.
3478
+ TYPE: o.OUTIL ? "TIERS" : "NATIF",
3479
+ OUTIL: o.OUTIL ? o.OUTIL : "",
3480
+ STRUCT_ID: r.collectiviteId,
3481
+ STRUCT_UAI: r.UAI,
3482
+ PROJET: r.projetId ? r.projetId : n.ID_PROJET,
3483
+ EXPLOITANT: n.ID_EXPLOITANT,
3484
+ PLATFORME: r.plateformeId ? r.plateformeId : n.ID_PLATEFORME,
3485
+ ID_PERSO: a(t.userId),
3486
+ PROFILE: s && s.length > 0 ? c[s[0]] ?? "" : ""
3487
+ };
3488
+ }
3489
+ }
3490
+ const R = class R {
3491
+ // in minutes. Applies to recorded videos.
3492
+ constructor(e) {
3493
+ this.context = e;
3494
+ }
3495
+ get http() {
3496
+ return this.context.http();
3497
+ }
3498
+ get conf() {
3499
+ return this.context.conf();
3450
3500
  }
3451
3501
  /**
3452
- * @param expect a workflow right
3453
- * @returns true if current session has right on it
3502
+ * Returns the video app public conf (maxWeight, maxDuration and accepted extensions)
3503
+ * @returns the Video app public conf
3454
3504
  */
3455
- async sessionHasWorkflowRight(e) {
3456
- try {
3457
- const t = await this.session.getUser();
3458
- return !!t && this.hasWorkflowRight(
3459
- e,
3460
- t.authorizedActions.map(
3461
- (s) => s.name
3462
- )
3463
- );
3464
- } catch (t) {
3465
- return console.error(`Unexpected error ${t} in sessionHasWorkflowRight()`), !1;
3466
- }
3505
+ async getVideoConf() {
3506
+ var t;
3507
+ const e = await this.conf.getPublicConf(
3508
+ APP$4.VIDEO
3509
+ );
3510
+ return {
3511
+ maxWeight: (e == null ? void 0 : e["max-videosize-mbytes"]) ?? R.MAX_WEIGHT,
3512
+ maxDuration: (e == null ? void 0 : e["max-videoduration-minutes"]) ?? R.MAX_DURATION,
3513
+ acceptVideoUploadExtensions: ((t = e == null ? void 0 : e["accept-videoupload-extensions"]) == null ? void 0 : t.map(
3514
+ (s) => s.toUpperCase()
3515
+ )) ?? []
3516
+ };
3467
3517
  }
3468
3518
  /**
3469
- * @param expect a workflow right
3470
- * @returns a record with right as key and boolean as value if current session has right on it
3519
+ * Starts the encoding process and check when video is fully processed.
3520
+ * @param params cf VideoUploadParams
3521
+ * @returns a VideoCheckResponse
3471
3522
  */
3472
- async sessionHasWorkflowRights(e) {
3473
- const t = {};
3474
- try {
3475
- const s = await this.session.getUser();
3476
- for (const r of e)
3477
- t[r] = !!s && this.hasWorkflowRight(
3478
- r,
3479
- s.authorizedActions.map(
3480
- (i) => i.name
3481
- )
3523
+ async upload({
3524
+ data: e,
3525
+ appCode: t,
3526
+ captation: s,
3527
+ duration: r
3528
+ }) {
3529
+ if (!e.file)
3530
+ throw new Error("Invalid video file.");
3531
+ if (!e.filename)
3532
+ throw new Error("Invalid video filename");
3533
+ const i = `${e.browser.name} ${e.browser.version}`, o = new FormData();
3534
+ 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);
3535
+ let a = `/video/encode?captation=${s}`;
3536
+ r && (a += `&duration=${r}`);
3537
+ const c = await this.http.post(
3538
+ a,
3539
+ o,
3540
+ { headers: { "Content-Type": "multipart/form-data" } }
3541
+ );
3542
+ if (c.state == "running") {
3543
+ let l = 0, p = 1;
3544
+ do {
3545
+ const E = p + l;
3546
+ await new Promise(
3547
+ (y) => setTimeout(y, E * 1e3)
3548
+ ), l = p, p = Math.min(8, E);
3549
+ const h = await this.http.get(
3550
+ `/video/status/${c.processid}`
3482
3551
  );
3483
- } catch (s) {
3484
- console.error(`Unexpected error ${s} in sessionHasWorkflowRights()`);
3485
- for (const r of e)
3486
- t[r] = !1;
3552
+ if (h.state == "succeed")
3553
+ return h.videoworkspaceid && h.videosize && this.context.data().trackVideoSave(
3554
+ h.videoworkspaceid,
3555
+ Math.round(r),
3556
+ h.videosize,
3557
+ s,
3558
+ e.url,
3559
+ i,
3560
+ e.device
3561
+ ), h;
3562
+ if (h.state == "error")
3563
+ break;
3564
+ } while (!0);
3487
3565
  }
3488
- return t;
3566
+ throw new Error("Video cannot be uploaded.");
3489
3567
  }
3490
- }
3491
- class SessionService {
3568
+ };
3569
+ u(R, "MAX_WEIGHT", 50), // in Mbytes. Applies to uploaded videos.
3570
+ u(R, "MAX_DURATION", 3);
3571
+ let VideoService = R;
3572
+ class EmbedderService {
3492
3573
  constructor(e) {
3493
3574
  this.context = e;
3494
3575
  }
3495
3576
  get http() {
3496
3577
  return this.context.http();
3497
3578
  }
3498
- get cache() {
3499
- return this.context.cache();
3500
- }
3501
- get conf() {
3502
- return this.context.conf();
3579
+ /**
3580
+ * Returns the default list of video embedder
3581
+ * @returns the default list of video embedder
3582
+ */
3583
+ async getDefault() {
3584
+ return this.http.get("/infra/embed/default");
3503
3585
  }
3504
3586
  /**
3505
- * Callback to call when user logout
3587
+ * Returns the custom list of video embedder
3588
+ * @returns the custom list of video embedder
3506
3589
  */
3507
- onLogout() {
3508
- this.cache.clearCache();
3590
+ async getCustom() {
3591
+ return this.http.get("/infra/embed/custom");
3509
3592
  }
3510
3593
  /**
3511
- * Callback to call when session change
3594
+ * The provider matching with the URL
3595
+ * @param {Embedder[]} embedderList - The list of video providers to test with
3596
+ * @param {String} url - The URL for the video
3597
+ * @returns The provider matching with the URL or undefined
3512
3598
  */
3513
- onRefreshSession() {
3514
- this.cache.clearCache();
3515
- }
3516
- async getSession() {
3517
- const [e, t] = await Promise.all([
3518
- this.getUser(),
3519
- this.getPerson()
3520
- ]), [
3521
- s,
3522
- r,
3523
- i,
3524
- o,
3525
- a
3526
- ] = await Promise.all([
3527
- this.getCurrentLanguage(e),
3528
- this.latestQuotaAndUsage(e),
3529
- this.loadDescription(e),
3530
- this.getUserProfile(),
3531
- this.getBookmarks(e)
3532
- ]), { type: c, ...l } = t || {}, h = {
3533
- ...l,
3534
- profiles: c || ["Guest"],
3535
- // "type" field from /userbook/api/person becomes "profiles"
3536
- ...i
3537
- // Inject other fields (also the correct "type")
3538
- };
3539
- return {
3540
- user: e,
3541
- quotaAndUsage: r,
3542
- currentLanguage: s,
3543
- userDescription: h,
3544
- userProfile: o,
3545
- bookmarkedApps: a
3546
- };
3599
+ getProviderFromUrl(e, t) {
3600
+ for (const s of e)
3601
+ if (this.isUrlFromProvider(t, s))
3602
+ return s;
3547
3603
  }
3548
- login(e, t, s, r) {
3549
- const i = new FormData();
3550
- 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, {
3551
- headers: { "content-type": "application/x-www-form-urlencoded" }
3552
- }).finally(() => {
3553
- switch (this.http.latestResponse.status) {
3554
- case 200:
3555
- throw ERROR_CODE.MALFORMED_DATA;
3604
+ urlIsFromPattern(e, t) {
3605
+ const s = new RegExp("[^{}]+(?=(?:[^{}]*{[^}]*})*[^}]*$)", "g"), r = new RegExp("{[^}]*}", "g");
3606
+ let i = !0;
3607
+ const o = t.match(s) || [], a = [];
3608
+ return (t.match(r) || []).forEach((l, p) => {
3609
+ l.includes("ignore") || a.push(o[p]);
3610
+ }), a.forEach((l) => {
3611
+ if (!e.includes(l)) {
3612
+ i = !1;
3613
+ return;
3556
3614
  }
3557
- });
3615
+ }), i;
3558
3616
  }
3559
- async logout() {
3560
- const e = await this.conf.getLogoutCallback();
3561
- return this.http.get("/auth/logout?callback=" + e).finally(() => {
3562
- });
3617
+ /**
3618
+ * Check if a given URL correspond to one of the URL pattern of the provider
3619
+ * @param {String} url - The URL for the video
3620
+ * @param {Embedder} embedder - The video provider to test with
3621
+ * @returns boolean depending if a given URL correspond to one of the URL pattern of the provider
3622
+ */
3623
+ isUrlFromProvider(e, t) {
3624
+ typeof t.url == "string" && (t.url = [t.url]);
3625
+ for (const s of t.url)
3626
+ if (this.urlIsFromPattern(e, s))
3627
+ return !0;
3628
+ return !1;
3563
3629
  }
3564
- async latestQuotaAndUsage(e) {
3565
- const t = { quota: 0, storage: 0 };
3566
- if (!e) return t;
3567
- try {
3568
- return await this.http.get(
3569
- `/workspace/quota/user/${e == null ? void 0 : e.userId}`
3570
- );
3571
- } catch (s) {
3572
- return console.error(s), t;
3573
- }
3630
+ /**
3631
+ * Get embed code to display the video for an URL and a provider
3632
+ * @param {Embedder} embedder - The video provider for the URL
3633
+ * @param {String} url - The URL for the video
3634
+ * @returns embed code to display the video for an URL and a provider
3635
+ */
3636
+ getEmbedCodeForProvider(e, t) {
3637
+ for (const s of e.url)
3638
+ if (this.urlIsFromPattern(t, s)) {
3639
+ const r = new RegExp("{[a-zA-Z0-9_.]+}", "g"), i = s.match(r) || [];
3640
+ let o = e.embed;
3641
+ for (const a of i) {
3642
+ let c = s.split(a)[0];
3643
+ const l = c.split("}");
3644
+ l.length > 1 && (c = l[l.length - 1]);
3645
+ let p = t.split(c)[1];
3646
+ if (!p)
3647
+ continue;
3648
+ const E = s.split(a)[1].split("{")[0];
3649
+ E && (p = p.split(E)[0]);
3650
+ const h = new RegExp("\\" + a.replace(/}/, "\\}"), "g");
3651
+ o = o.replace(h, p);
3652
+ }
3653
+ return o;
3654
+ }
3655
+ return "";
3574
3656
  }
3575
- async getCurrentLanguage(e) {
3576
- const t = (e == null ? void 0 : e.sessionMetadata) && (e == null ? void 0 : e.sessionMetadata.userId);
3577
- try {
3578
- let s;
3579
- return t ? s = await this.loadUserLanguage() : s = await this.loadDefaultLanguage(), s;
3580
- } catch (s) {
3581
- console.error(s);
3582
- }
3657
+ }
3658
+ class AbstractBehaviourService {
3659
+ //
3660
+ // IMPLEMENTATION
3661
+ //
3662
+ constructor(e) {
3663
+ //-----------------
3664
+ //--- Utilities ---
3665
+ //-----------------
3666
+ u(this, "_cache");
3667
+ this.context = e, this._cache = new CacheService(this.context);
3583
3668
  }
3584
- async loadUserLanguage() {
3585
- try {
3586
- const e = await this.http.get(
3587
- "/userbook/preference/language"
3588
- );
3589
- return JSON.parse(e.preference)["default-domain"];
3590
- } catch {
3591
- return await this.loadDefaultLanguage();
3592
- }
3669
+ getApplication() {
3670
+ return this.APP;
3593
3671
  }
3594
- async loadDefaultLanguage() {
3595
- return (await this.cache.httpGetJson(
3596
- "/locale"
3597
- )).locale;
3672
+ getResourceType() {
3673
+ return this.RESOURCE;
3598
3674
  }
3599
- async getUser() {
3600
- const { response: e, value: t } = await this.cache.httpGet(
3601
- "/auth/oauth2/userinfo"
3602
- );
3603
- if (!(e.status < 200 || e.status >= 300) && typeof t == "object")
3604
- return t;
3605
- throw ERROR_CODE.NOT_LOGGED_IN;
3675
+ httpGet(e, t) {
3676
+ return this._cache.httpGetJson(e, t);
3606
3677
  }
3607
- hasWorkflow({
3608
- workflowName: e,
3609
- user: t
3678
+ /* Utility to map data between linker model and search model. */
3679
+ dataToResource({
3680
+ modified: e,
3681
+ ...t
3610
3682
  }) {
3611
- return e === void 0 || (t == null ? void 0 : t.authorizedActions.findIndex((s) => s.name === e)) !== -1;
3612
- }
3613
- async loadDescription(e) {
3614
- if (!e) return {};
3615
- try {
3616
- const [t, s] = await Promise.all([
3617
- // FIXME The full user's description should be obtainable from a single endpoint in the backend.
3618
- this.getUserProfile({
3619
- options: { requestName: "refreshAvatar" }
3620
- }),
3621
- this.http.get("/directory/userbook/" + (e == null ? void 0 : e.userId))
3622
- ]);
3623
- return { ...s, profiles: t };
3624
- } catch (t) {
3625
- return console.error(t), {};
3626
- }
3627
- }
3628
- async getBookmarks(e) {
3629
- if (!e) return [];
3630
- const t = await this.http.get("/userbook/preference/apps");
3631
- t.preference || (t.preference = null);
3632
- const s = JSON.parse(t.preference);
3633
- let r;
3634
- r = s, r || (r = {
3635
- bookmarks: [],
3636
- applications: []
3637
- });
3638
- const i = [];
3639
- return r.bookmarks.forEach((o, a) => {
3640
- const c = ((e == null ? void 0 : e.apps) || []).find(
3641
- (l) => l.name === o
3642
- );
3643
- if (c) {
3644
- const l = Object.assign({}, c);
3645
- i.push(l);
3646
- }
3647
- }), i;
3683
+ const s = typeof e == "string" ? e : e != null && e.$date ? "" + e.$date : "";
3684
+ return {
3685
+ application: this.RESOURCE,
3686
+ name: t.title,
3687
+ creatorId: t.owner,
3688
+ creatorName: t.ownerName,
3689
+ thumbnail: t.icon,
3690
+ assetId: t._id,
3691
+ modifiedAt: s,
3692
+ shared: t.shared,
3693
+ path: t.path
3694
+ };
3648
3695
  }
3649
- async getUserProfile(e = {}) {
3650
- const t = await this.getPerson(e);
3651
- return (t == null ? void 0 : t.type) || ["Guest"];
3696
+ }
3697
+ class ActualitesBehaviour extends AbstractBehaviourService {
3698
+ constructor() {
3699
+ super(...arguments);
3700
+ u(this, "APP", "actualites");
3701
+ u(this, "RESOURCE", "actualites");
3652
3702
  }
3653
- async getPerson(e = {}) {
3654
- var c;
3655
- 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(
3656
- i,
3657
- t
3703
+ async loadResources() {
3704
+ const [t, s] = await Promise.all([
3705
+ this.httpGet("/actualites/api/v1/infos/linker"),
3706
+ this.httpGet("/actualites/api/v1/threads")
3707
+ ]), r = s.reduce(
3708
+ (i, o) => i.set(o.id, o),
3709
+ /* @__PURE__ */ new Map()
3658
3710
  );
3659
- return o.status < 200 || o.status >= 300 || typeof a == "string" ? null : ((c = a == null ? void 0 : a.result) == null ? void 0 : c[0]) || null;
3660
- }
3661
- async isAdml() {
3662
- const e = await this.getUser();
3663
- return (e == null ? void 0 : e.functions.ADMIN_LOCAL) !== void 0;
3664
- }
3665
- /**
3666
- * Get details of an application if the user can access it.
3667
- * @return undefined if no access, or app not found
3668
- */
3669
- async getWebApp(e) {
3670
- const t = await this.getUser();
3671
- return t == null ? void 0 : t.apps.find((s) => {
3672
- var r;
3673
- 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;
3674
- });
3675
- }
3676
- }
3677
- class StringUtils {
3678
- static removeAccents(e) {
3679
- for (let t = 0; t < defaultDiacriticsRemovalMap.length; t++)
3680
- e = e.replace(
3681
- defaultDiacriticsRemovalMap[t].letters,
3682
- defaultDiacriticsRemovalMap[t].base
3683
- );
3684
- return e;
3711
+ return t.map((i) => {
3712
+ var a;
3713
+ let o;
3714
+ return i.threadIcon ? o = i.threadIcon + "?thumbnail=48x48" : o = "/img/icons/glyphicons_036_file.png", this.dataToResource({
3715
+ title: i.title + " [" + ((a = r.get(i.threadId)) == null ? void 0 : a.title) + "]",
3716
+ ownerName: i.owner.displayName,
3717
+ owner: i.owner.id,
3718
+ icon: o,
3719
+ path: "/actualites/threads/" + i.threadId + "?info=" + i.id,
3720
+ _id: `${i.threadId}#${i.id}`,
3721
+ shared: !!(i.shared && i.shared.length >= 0),
3722
+ modified: i.modified
3723
+ });
3724
+ });
3685
3725
  }
3686
3726
  }
3687
- class ShareService {
3688
- //
3689
- // IMPLEMENTATION
3690
- //
3691
- constructor(e) {
3692
- this.context = e;
3693
- }
3694
- get directory() {
3695
- return this.context.directory();
3696
- }
3697
- get http() {
3698
- return this.context.http();
3699
- }
3700
- get cache() {
3701
- return this.context.cache();
3702
- }
3703
- getSearchUrl(e, t, s, r) {
3704
- if (!r)
3705
- return `/${e}/share/json/${t}?search=${s}`;
3706
- if (r.includes("?search=")) {
3707
- const [i] = r.split("?search=");
3708
- return `${i}?search=${s}`;
3709
- } else return r.includes("?") ? `${r}&search=${s}` : `${r}?search=${s}`;
3727
+ const hexToDataUrl = (n, e = 1, t = 1) => {
3728
+ const s = document.createElement("canvas");
3729
+ s.width = e, s.height = t;
3730
+ const r = s.getContext("2d");
3731
+ return r ? (r.fillStyle = n, r.fillRect(0, 0, e, t), s.toDataURL("image/png")) : "";
3732
+ };
3733
+ class AppointmentsBehaviour extends AbstractBehaviourService {
3734
+ constructor() {
3735
+ super(...arguments);
3736
+ u(this, "APP", "appointments");
3737
+ u(this, "RESOURCE", "appointments");
3710
3738
  }
3711
- async searchShareSubjects(e, t, s, r) {
3712
- const i = StringUtils.removeAccents(s).toLowerCase(), o = this.getSearchUrl(
3713
- e,
3714
- t,
3715
- s,
3716
- r
3717
- ), a = await this.cache.httpGetJson(o), c = a.users.visibles.filter(({ username: p, firstName: y, lastName: d, login: g }) => {
3718
- const A = StringUtils.removeAccents(
3719
- d || ""
3720
- ).toLowerCase(), f = StringUtils.removeAccents(
3721
- y || ""
3722
- ).toLowerCase(), w = StringUtils.removeAccents(
3723
- p || ""
3724
- ).toLowerCase(), F = StringUtils.removeAccents(g || "").toLowerCase();
3725
- return w.includes(i) || f.includes(i) || A.includes(i) || F.includes(i);
3726
- }).map((p) => ({
3727
- avatarUrl: this.directory.getAvatarUrl(p.id, "user"),
3728
- directoryUrl: this.directory.getDirectoryUrl(p.id, "user"),
3729
- displayName: p.username,
3730
- id: p.id,
3731
- profile: p.profile,
3732
- type: "user"
3733
- })), l = a.groups.visibles.filter(({ name: p }) => StringUtils.removeAccents(p || "").toLowerCase().includes(i)).map((p) => ({
3734
- avatarUrl: this.directory.getAvatarUrl(p.id, "group"),
3735
- directoryUrl: this.directory.getDirectoryUrl(p.id, "group"),
3736
- displayName: p.name,
3737
- id: p.id,
3738
- type: "group",
3739
- structureName: p.structureName
3739
+ async loadResources() {
3740
+ return (await this.httpGet("/appointments/grids/linker")).map((s) => this.dataToResource({
3741
+ _id: s.id.toString(),
3742
+ icon: hexToDataUrl(s.color, 100, 100),
3743
+ title: s.name,
3744
+ ownerName: s.ownerName,
3745
+ owner: s.ownerId,
3746
+ path: `${window.location.origin}/appointments#?gridId=${s.id}`,
3747
+ shared: !1,
3748
+ modified: s.updatingDate
3740
3749
  }));
3741
- return [...(await this.directory.getBookMarks()).filter(({ displayName: p }) => StringUtils.removeAccents(
3742
- p || ""
3743
- ).toLowerCase().includes(i)).map((p) => ({
3744
- avatarUrl: "",
3745
- directoryUrl: "",
3746
- profile: "",
3747
- displayName: p.displayName,
3748
- id: p.id,
3749
- type: "sharebookmark"
3750
- })), ...c, ...l];
3751
3750
  }
3752
- async getShareMapping(e, t) {
3753
- const s = await this.cache.httpGetJson(
3754
- t || `/${e}/rights/sharing`
3755
- );
3756
- for (const r of Object.keys(s))
3757
- if (r.includes(".")) {
3758
- const i = r.split(".")[1], o = s[r];
3759
- delete s[r], s[i] = o;
3751
+ }
3752
+ class BlogBehaviour extends AbstractBehaviourService {
3753
+ constructor() {
3754
+ super(...arguments);
3755
+ u(this, "APP", "blog");
3756
+ u(this, "RESOURCE", "blog");
3757
+ }
3758
+ loadResources() {
3759
+ return new Promise(async (t, s) => {
3760
+ try {
3761
+ const r = await this.httpGet("/blog/linker"), i = [];
3762
+ r.forEach((o) => {
3763
+ o.thumbnail ? o.thumbnail = o.thumbnail + "?thumbnail=48x48" : o.thumbnail = "/img/illustrations/blog.svg";
3764
+ const a = o.fetchPosts.map((c) => this.dataToResource({
3765
+ owner: o.author.userId,
3766
+ ownerName: o.author.username,
3767
+ title: c.title + " [" + o.title + "]",
3768
+ _id: `${o._id}#${c._id}`,
3769
+ icon: o.thumbnail,
3770
+ path: `/blog/id/${o._id}/post/${c._id}`,
3771
+ shared: !!(o.shared && o.shared.length >= 0),
3772
+ modified: o.modified
3773
+ }));
3774
+ i.push(...a);
3775
+ }), t(i);
3776
+ } catch (r) {
3777
+ s(r);
3760
3778
  }
3761
- return s;
3779
+ });
3762
3780
  }
3763
- getActionsAvailableFor({ id: e, type: t }, s, r) {
3764
- const o = (t === "user" ? s.users.checked[e] : s.groups.checked[e]) || [], a = Object.keys(r), c = [];
3765
- for (const l of a)
3766
- r[l].filter(
3767
- (p) => o.includes(p)
3768
- ).length > 0 && c.push(l);
3769
- return c;
3781
+ }
3782
+ class CollaborativewallBehaviour extends AbstractBehaviourService {
3783
+ constructor() {
3784
+ super(...arguments);
3785
+ u(this, "APP", "collaborativewall");
3786
+ u(this, "RESOURCE", "collaborativewall");
3770
3787
  }
3771
- async getRightsForResource(e, t, s) {
3772
- const r = await this.directory.getBookMarks(), i = this.getSearchUrl(
3773
- e,
3774
- t,
3775
- "",
3776
- s == null ? void 0 : s.getResourceRights
3777
- ), o = await this.cache.httpGetJson(
3778
- i
3779
- ), a = await this.getShareMapping(
3780
- e,
3781
- s == null ? void 0 : s.getShareMapping
3782
- ), c = await this.cache.httpGetJson(
3783
- "/infra/public/json/sharing-rights.json"
3784
- ), l = Object.keys(o.users.checked).map((d) => o.users.visibles.find(
3785
- (A) => A.id === d
3786
- )).filter((d) => d !== void 0).map((d) => {
3787
- const g = this.getActionsAvailableFor(
3788
- { id: d.id, type: "user" },
3789
- o,
3790
- a
3791
- );
3792
- return {
3793
- id: d.id,
3794
- type: "user",
3795
- displayName: d.username,
3796
- profile: d.profile,
3797
- avatarUrl: this.directory.getAvatarUrl(d.id, "user"),
3798
- directoryUrl: this.directory.getDirectoryUrl(d.id, "user"),
3799
- actions: g.map((f) => {
3800
- const w = c[f];
3801
- return {
3802
- displayName: f,
3803
- id: f,
3804
- priority: w.priority
3805
- };
3806
- })
3807
- };
3808
- }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), h = Object.keys(o.groups.checked).map((d) => o.groups.visibles.find(
3809
- (A) => A.id === d
3810
- )).filter((d) => d !== void 0).map((d) => {
3811
- const g = this.getActionsAvailableFor(
3812
- { id: d.id, type: "group" },
3813
- o,
3814
- a
3815
- );
3816
- return {
3817
- id: d.id,
3818
- type: "group",
3819
- displayName: d.name,
3820
- profile: void 0,
3821
- avatarUrl: this.directory.getAvatarUrl(d.id, "group"),
3822
- directoryUrl: this.directory.getDirectoryUrl(d.id, "group"),
3823
- actions: g.map((f) => {
3824
- const w = c[f];
3825
- return {
3826
- displayName: f,
3827
- id: f,
3828
- priority: w.priority
3829
- };
3830
- })
3831
- };
3832
- }).sort((d, g) => (d.displayName || "").localeCompare(g.displayName)), E = [...l, ...h], p = o.groups.visibles.map(
3833
- ({ groupDisplayName: d, id: g, name: A, labels: f }) => ({
3834
- labels: f,
3835
- displayName: d || A,
3836
- id: g
3837
- })
3838
- ), y = o.users.visibles.map(
3839
- ({ id: d, profile: g, username: A, firstName: f, lastName: w, login: F }) => ({
3840
- displayName: A,
3841
- firstName: f,
3842
- lastName: w,
3843
- login: F,
3844
- profile: g,
3845
- id: d
3788
+ async loadResources() {
3789
+ return (await this.httpGet(
3790
+ "/collaborativewall/list/all"
3791
+ )).map(
3792
+ (s) => this.dataToResource({
3793
+ title: s.name,
3794
+ ownerName: s.owner.displayName,
3795
+ owner: s.owner.userId,
3796
+ icon: s.icon ? s.icon : "/img/illustrations/collaborative-wall-default.png",
3797
+ path: "/collaborativewall#/view/" + s._id,
3798
+ _id: s._id,
3799
+ shared: !!(s.shared && s.shared.length >= 0),
3800
+ modified: s.modified
3846
3801
  })
3847
3802
  );
3848
- return {
3849
- rights: E,
3850
- visibleBookmarks: r,
3851
- visibleGroups: p,
3852
- visibleUsers: y
3853
- };
3854
3803
  }
3855
- async getPutSharePayload(e, t, s) {
3856
- const r = {
3857
- users: {},
3858
- groups: {},
3859
- bookmarks: {}
3860
- }, i = await this.getShareMapping(e, s);
3861
- for (const o of t) {
3862
- const a = o.actions.map((l) => i[l.id]).reduce((l, h) => Array.isArray(h) ? [...l, ...h] : l, []), c = [...new Set(a)];
3863
- c.length > 0 && (o.type === "user" ? r.users[o.id] = c : o.type === "group" ? r.groups[o.id] = c : r.bookmarks[o.id] = c);
3864
- }
3865
- return r;
3804
+ }
3805
+ class CommunityBehaviour extends AbstractBehaviourService {
3806
+ constructor() {
3807
+ super(...arguments);
3808
+ u(this, "APP", "community");
3809
+ u(this, "RESOURCE", "community");
3810
+ }
3811
+ async loadResources() {
3812
+ return (await this.httpGet(
3813
+ "/community/listallpages"
3814
+ )).map((s) => {
3815
+ let r;
3816
+ return typeof s.thumbnail > "u" || s.thumbnail === "" ? r = "/img/icons/glyphicons_036_file.png" : r = s.thumbnail + "?thumbnail=48x48", this.dataToResource({
3817
+ title: s.name,
3818
+ icon: r,
3819
+ path: "/community#/view/" + s.id,
3820
+ _id: s.id,
3821
+ owner: "",
3822
+ ownerName: "",
3823
+ shared: !!(s.shared && s.shared.length >= 0),
3824
+ modified: s.name
3825
+ // FIXME date ?
3826
+ });
3827
+ });
3828
+ }
3829
+ }
3830
+ class ExercizerBehaviour extends AbstractBehaviourService {
3831
+ constructor() {
3832
+ super(...arguments);
3833
+ u(this, "APP", "exercizer");
3834
+ u(this, "RESOURCE", "exercizer");
3835
+ }
3836
+ async loadResources() {
3837
+ return (await this.httpGet(
3838
+ "/exercizer/subjects-scheduled"
3839
+ )).map((s) => {
3840
+ const r = s.picture ? s.picture + "?thumbnail=48x48" : "/img/illustrations/exercizer.svg";
3841
+ let i, o = !1;
3842
+ const a = JSON.parse(s.scheduled_at);
3843
+ 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({
3844
+ title: s.title,
3845
+ owner: s.owner,
3846
+ ownerName: i,
3847
+ icon: r,
3848
+ path: "/exercizer#/linker/" + s.id,
3849
+ _id: "" + s.id,
3850
+ shared: o,
3851
+ modified: s.modified
3852
+ });
3853
+ });
3854
+ }
3855
+ }
3856
+ class FormulaireBehaviour extends AbstractBehaviourService {
3857
+ constructor() {
3858
+ super(...arguments);
3859
+ u(this, "APP", "formulaire");
3860
+ u(this, "RESOURCE", "formulaire");
3866
3861
  }
3867
- async saveRights(e, t, s, r) {
3868
- const i = await this.getPutSharePayload(
3869
- e,
3870
- s,
3871
- r == null ? void 0 : r.getShareMapping
3872
- ), o = (r == null ? void 0 : r.saveResourceRights) || `/${e}/share/resource/${t}`, a = this.getSearchUrl(
3873
- e,
3874
- t,
3875
- "",
3876
- r == null ? void 0 : r.getResourceRights
3862
+ async loadResources() {
3863
+ return (await this.httpGet(
3864
+ "/formulaire/forms/linker"
3865
+ )).map((s) => (s.picture || (s.picture = "/formulaire/public/img/logo.svg"), this.dataToResource({
3866
+ _id: "" + s.id,
3867
+ icon: s.picture,
3868
+ title: s.title,
3869
+ ownerName: s.owner_name,
3870
+ owner: s.owner_id,
3871
+ path: s.is_public ? `${window.location.origin}/formulaire-public#/form/${s.public_key}` : `${window.location.origin}/formulaire#/form/${s.id}/${s.rgpd ? "rgpd" : "new"}`,
3872
+ shared: !!(s.shared && s.shared.length >= 0),
3873
+ modified: "" + s.date_modification
3874
+ })));
3875
+ }
3876
+ }
3877
+ class ForumBehaviour extends AbstractBehaviourService {
3878
+ constructor() {
3879
+ super(...arguments);
3880
+ u(this, "APP", "forum");
3881
+ u(this, "RESOURCE", "forum");
3882
+ }
3883
+ async loadResources() {
3884
+ return (await this.httpGet("/forum/categories")).map(
3885
+ (s) => this.dataToResource({
3886
+ _id: s._id,
3887
+ title: s.name,
3888
+ icon: s.icon || "/img/illustrations/forum.svg",
3889
+ path: "/forum#/view/" + s._id,
3890
+ ownerName: s.owner.displayName,
3891
+ owner: s.owner.userId,
3892
+ shared: !!(s.shared && s.shared.length >= 0),
3893
+ modified: s.modified
3894
+ })
3877
3895
  );
3878
- return this.cache.clearCache(a), await this.http.putJson(o, i);
3879
3896
  }
3880
- async getActionsForApp(e, t) {
3881
- const s = await this.cache.httpGetJson(
3882
- "/infra/public/json/sharing-rights.json"
3883
- ), r = await this.getShareMapping(e, t);
3884
- return Object.keys(s).map((o) => {
3885
- const a = s[o];
3886
- return {
3887
- displayName: o,
3888
- id: o,
3889
- priority: a.priority,
3890
- requires: a.requires
3891
- };
3892
- }).filter((o) => {
3893
- var a;
3894
- return ((a = r[o.id]) == null ? void 0 : a.length) > 0;
3895
- }).sort((o, a) => o.priority - a.priority);
3897
+ }
3898
+ class HomeworksBehaviour extends AbstractBehaviourService {
3899
+ constructor() {
3900
+ super(...arguments);
3901
+ u(this, "APP", "homeworks");
3902
+ u(this, "RESOURCE", "homeworks");
3903
+ }
3904
+ async loadResources() {
3905
+ return (await this.httpGet("/homeworks/list")).filter((t) => t.owner && t.trashed === 0).map((t) => this.dataToResource({
3906
+ title: t.title,
3907
+ ownerName: t.owner.displayName,
3908
+ owner: t.owner.userId,
3909
+ icon: t.thumbnail || "/img/illustrations/homeworks.svg",
3910
+ path: "/homeworks#/view-homeworks/" + t._id,
3911
+ _id: "" + t._id,
3912
+ shared: typeof t.shared < "u",
3913
+ modified: t.modified
3914
+ }));
3896
3915
  }
3897
3916
  }
3898
- const loadedScripts = {};
3899
- class HttpService {
3900
- constructor(e, t) {
3901
- // Axios automatically manages the XSRF-TOKEN cookie and the X-XSRF-TOKEN HTTP header.
3902
- u(this, "axios");
3903
- u(this, "baseUrl");
3904
- u(this, "headers", {});
3905
- u(this, "_latestResponse");
3906
- this.context = e, this.axios = axios.create(t);
3917
+ class MagnetoBehaviour extends AbstractBehaviourService {
3918
+ constructor() {
3919
+ super(...arguments);
3920
+ u(this, "APP", "magneto");
3921
+ u(this, "RESOURCE", "magneto");
3907
3922
  }
3908
- fixBaseUrl(e) {
3909
- return e.startsWith("http://") || e.startsWith("https://") ? e : this.baseUrl ? this.baseUrl.endsWith("/") || e.startsWith("/") ? `${this.baseUrl}${e}` : `${this.baseUrl}/${e}` : e;
3923
+ async loadResources() {
3924
+ const { all: t } = await this.httpGet(
3925
+ "/magneto/boards/editable"
3926
+ );
3927
+ return t.map((s) => this.dataToResource({
3928
+ _id: s._id,
3929
+ title: s.title,
3930
+ icon: s.imageUrl,
3931
+ owner: s.ownerId,
3932
+ ownerName: s.ownerName,
3933
+ path: `/magneto#/board/${s._id}/view`,
3934
+ shared: !!(s.shared && s.shared.length >= 0),
3935
+ modified: "" + s.modificationDate
3936
+ }));
3910
3937
  }
3911
- useBaseUrl(e) {
3912
- return this.baseUrl = e, this;
3938
+ }
3939
+ class MindmapBehaviour extends AbstractBehaviourService {
3940
+ constructor() {
3941
+ super(...arguments);
3942
+ u(this, "APP", "mindmap");
3943
+ u(this, "RESOURCE", "mindmap");
3913
3944
  }
3914
- useHeaders(e) {
3915
- return this.headers = e, this;
3945
+ async loadResources() {
3946
+ return (await this.httpGet("/mindmap/list/all")).map(
3947
+ (s) => this.dataToResource({
3948
+ title: s.name,
3949
+ ownerName: s.owner.displayName,
3950
+ owner: s.owner.userId,
3951
+ icon: s.thumbnail || "/img/illustrations/mindmap-default.png",
3952
+ path: "/mindmap#/view/" + s._id,
3953
+ _id: s._id,
3954
+ shared: !!(s.shared && s.shared.length >= 0),
3955
+ modified: s.modified
3956
+ })
3957
+ );
3916
3958
  }
3917
- setCdn(e) {
3918
- e && XMLHttpRequest && !XMLHttpRequest.prototype.cdnUrl && (XMLHttpRequest.prototype.cdnUrl = e, XMLHttpRequest.prototype.baseOpen = XMLHttpRequest.prototype.open, XMLHttpRequest.prototype.open = function() {
3919
- const t = arguments[1];
3920
- 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);
3921
- });
3959
+ }
3960
+ class PagesBehaviour extends AbstractBehaviourService {
3961
+ constructor() {
3962
+ super(...arguments);
3963
+ u(this, "APP", "pages");
3964
+ u(this, "RESOURCE", "pages");
3922
3965
  }
3923
- // private toAxiosConfig(params?: IHttpParams): AxiosRequestConfig {
3924
- toAxiosConfig(e) {
3925
- if (e) {
3926
- const t = Object.assign({}, this.axios.defaults);
3927
- 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));
3928
- const s = t.headers ?? {};
3929
- return t.headers = { ...s, ...this.headers }, t;
3930
- } else
3931
- return this.axios.defaults;
3966
+ async loadResources() {
3967
+ const t = await this.httpGet("/pages/list/all"), s = [];
3968
+ return t.forEach((r) => {
3969
+ var o;
3970
+ const i = r.thumbnail ? r.thumbnail + "?thumbnail=48x48" : "/img/illustrations/pages.svg";
3971
+ s.push(
3972
+ this.dataToResource({
3973
+ title: r.title,
3974
+ owner: r.owner.userId,
3975
+ ownerName: r.owner.displayName,
3976
+ icon: i,
3977
+ path: "/pages#/website/" + r._id,
3978
+ _id: r._id,
3979
+ shared: typeof r.shared < "u",
3980
+ modified: r.modified
3981
+ })
3982
+ ), (o = r.pages) == null || o.forEach((a) => {
3983
+ s.push(
3984
+ this.dataToResource({
3985
+ title: a.title,
3986
+ owner: r.owner.userId,
3987
+ ownerName: r.owner.displayName,
3988
+ icon: i,
3989
+ path: "/pages#/website/" + r._id + "/" + a.titleLink,
3990
+ _id: r._id + "/" + a.titleLink,
3991
+ shared: typeof r.shared < "u",
3992
+ modified: r.modified
3993
+ })
3994
+ );
3995
+ });
3996
+ }), s;
3932
3997
  }
3933
- toCdnUrl(e) {
3934
- e = this.fixBaseUrl(e);
3935
- const t = this.context.conf().getCdnUrl() || "";
3936
- if (t.length > 0 && e !== "/conf/public") {
3937
- const s = "" + e;
3938
- (s.startsWith("/infra/public") || s.startsWith("/assets") || /^\/([^\/]*)\/public/.test(s)) && (e = t + s);
3939
- }
3940
- return e;
3998
+ }
3999
+ class PollBehaviour extends AbstractBehaviourService {
4000
+ constructor() {
4001
+ super(...arguments);
4002
+ u(this, "APP", "poll");
4003
+ u(this, "RESOURCE", "poll");
3941
4004
  }
3942
- mapAxiosError(e, t) {
3943
- e.response ? this._latestResponse = e.response : e.request ? this._latestResponse = {
3944
- status: 408,
3945
- statusText: ERROR_CODE.TIME_OUT
3946
- } : this._latestResponse = {
3947
- status: 500,
3948
- statusText: ERROR_CODE.UNKNOWN
3949
- };
3950
- const { status: s, statusText: r, headers: i, data: o } = this._latestResponse;
3951
- return t != null && t.disableNotifications || notify.events().publish(LAYER_NAME.TRANSPORT, {
3952
- name: EVENT_NAME.ERROR_OCCURED,
3953
- data: {
3954
- params: t,
3955
- response: { status: s, statusText: r, headers: i },
3956
- payload: o
3957
- }
3958
- }), o;
4005
+ async loadResources() {
4006
+ return (await this.httpGet("/poll/list/all")).map((s) => {
4007
+ const r = s.icon ? s.icon + "?thumbnail=48x48" : "/img/icons/glyphicons_036_file.png";
4008
+ return this.dataToResource({
4009
+ title: s.question,
4010
+ ownerName: s.owner.displayName,
4011
+ icon: r,
4012
+ path: "/poll#/view/" + s._id,
4013
+ _id: s._id,
4014
+ owner: s.owner.userId,
4015
+ shared: !!(s.shared && s.shared.length >= 0),
4016
+ modified: s.modified
4017
+ });
4018
+ });
3959
4019
  }
3960
- mapAxiosResponse(e, t) {
3961
- return this._latestResponse = e, e.data;
4020
+ }
4021
+ class ScrapbookBehaviour extends AbstractBehaviourService {
4022
+ constructor() {
4023
+ super(...arguments);
4024
+ u(this, "APP", "scrapbook");
4025
+ u(this, "RESOURCE", "scrapbook");
3962
4026
  }
3963
- get latestResponse() {
3964
- return this._latestResponse;
4027
+ async loadResources() {
4028
+ return (await this.httpGet(
4029
+ "/scrapbook/list/all"
4030
+ )).map((s) => {
4031
+ const r = s.icon || "/img/illustrations/scrapbook.svg";
4032
+ return this.dataToResource({
4033
+ title: s.name,
4034
+ owner: s.owner.userId,
4035
+ ownerName: s.owner.displayName,
4036
+ icon: r,
4037
+ path: "/scrapbook#/view-scrapbook/" + s._id,
4038
+ _id: s._id,
4039
+ shared: !!(s.shared && s.shared.length >= 0),
4040
+ modified: s.modified
4041
+ });
4042
+ });
3965
4043
  }
3966
- isResponseError() {
3967
- return this.latestResponse.status < 200 || this.latestResponse.status >= 300;
4044
+ }
4045
+ class TimelinegeneratorBehaviour extends AbstractBehaviourService {
4046
+ constructor() {
4047
+ super(...arguments);
4048
+ u(this, "APP", "timelinegenerator");
4049
+ u(this, "RESOURCE", "timelinegenerator");
3968
4050
  }
3969
- async get(e, t) {
3970
- try {
3971
- const s = await this.axios.get(
3972
- this.toCdnUrl(e),
3973
- this.toAxiosConfig(t)
3974
- );
3975
- return this.mapAxiosResponse(s, t);
3976
- } catch (s) {
3977
- throw this.mapAxiosError(s, t);
3978
- }
4051
+ loadResources() {
4052
+ return new Promise(async (t, s) => {
4053
+ try {
4054
+ const i = (await this.httpGet(
4055
+ "/timelinegenerator/timelines"
4056
+ )).map((o) => {
4057
+ const a = o.icon || "/img/illustrations/timeline-default.png";
4058
+ return this.dataToResource({
4059
+ title: o.headline,
4060
+ ownerName: o.owner.displayName,
4061
+ owner: o.owner.userId,
4062
+ icon: a,
4063
+ path: "/timelinegenerator#/view/" + o._id,
4064
+ _id: o._id,
4065
+ shared: typeof o.shared < "u",
4066
+ modified: o.modified
4067
+ });
4068
+ });
4069
+ t(i);
4070
+ } catch (r) {
4071
+ s(r);
4072
+ }
4073
+ });
3979
4074
  }
3980
- async post(e, t, s) {
3981
- try {
3982
- const r = await this.axios.post(
3983
- this.fixBaseUrl(e),
3984
- t,
3985
- this.toAxiosConfig(s)
3986
- );
3987
- return this.mapAxiosResponse(r, s);
3988
- } catch (r) {
3989
- throw this.mapAxiosError(r, s);
3990
- }
4075
+ }
4076
+ class WikiBehaviour extends AbstractBehaviourService {
4077
+ constructor() {
4078
+ super(...arguments);
4079
+ u(this, "APP", "wiki");
4080
+ u(this, "RESOURCE", "wiki");
3991
4081
  }
3992
- async postFile(e, t, s) {
3993
- const r = this.toAxiosConfig(s);
3994
- r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
3995
- try {
3996
- const i = await this.axios.post(this.fixBaseUrl(e), t, {
3997
- ...r,
3998
- headers: {
3999
- "Content-Type": "multipart/form-data"
4000
- }
4082
+ async loadResources() {
4083
+ return (await this.httpGet(
4084
+ "/wiki/listallpages?visible=true"
4085
+ )).map((s) => s.pages.map((r) => {
4086
+ let i;
4087
+ return typeof s.thumbnail > "u" || s.thumbnail === "" ? i = "/img/icons/glyphicons_036_file.png" : i = s.thumbnail + "?thumbnail=48x48", this.dataToResource({
4088
+ title: r.title + " [" + s.title + "]",
4089
+ ownerName: s.owner.displayName,
4090
+ owner: s.owner.userId,
4091
+ icon: i,
4092
+ path: "/wiki#/view/" + s._id + "/" + r._id,
4093
+ _id: `${s._id}#${r._id}`,
4094
+ shared: typeof s.shared < "u",
4095
+ modified: r.modified
4001
4096
  });
4002
- return this.mapAxiosResponse(i, s);
4003
- } catch (i) {
4004
- throw this.mapAxiosError(i, s);
4005
- }
4097
+ })).flat();
4006
4098
  }
4007
- async postJson(e, t, s) {
4008
- const r = this.toAxiosConfig();
4009
- r.headers && (r.headers["Content-Type"] = "application/json");
4010
- try {
4011
- const i = await this.axios.post(
4012
- this.fixBaseUrl(e),
4013
- t,
4014
- this.toAxiosConfig(s)
4015
- );
4016
- return this.mapAxiosResponse(i, s);
4017
- } catch (i) {
4018
- throw this.mapAxiosError(i, s);
4019
- }
4099
+ }
4100
+ class WorkspaceBehaviour extends AbstractBehaviourService {
4101
+ constructor() {
4102
+ super(...arguments);
4103
+ u(this, "APP", "workspace");
4104
+ u(this, "RESOURCE", "workspace");
4020
4105
  }
4021
- async put(e, t, s) {
4022
- try {
4023
- const r = await this.axios.put(
4024
- this.fixBaseUrl(e),
4025
- t,
4026
- this.toAxiosConfig(s)
4027
- );
4028
- return this.mapAxiosResponse(r, s);
4029
- } catch (r) {
4030
- throw this.mapAxiosError(r, s);
4031
- }
4106
+ loadResources({ search: t, asset_id: s }) {
4107
+ return new Promise(async (r, i) => {
4108
+ try {
4109
+ let o = "/workspace/documents?filter=all&hierarchical=true";
4110
+ s && s.length ? o += `&search=${t}` : t && t.length && (o += `&search=${t}`);
4111
+ const c = (await this.httpGet(o)).filter((l) => !l.deleted).map((l) => {
4112
+ const p = l.metadata["content-type"] && l.metadata["content-type"].indexOf("image") !== -1 ? `/workspace/document/${l._id}?thumbnail=120x120` : "/img/icons/unknown-large.png";
4113
+ return this.dataToResource({
4114
+ title: l.name,
4115
+ ownerName: l.ownerName,
4116
+ owner: l.owner,
4117
+ icon: p,
4118
+ path: `/workspace/document/${l._id}`,
4119
+ _id: l._id,
4120
+ shared: !!(l.shared && l.shared.length >= 0),
4121
+ modified: l.modified
4122
+ });
4123
+ });
4124
+ r(c);
4125
+ } catch (o) {
4126
+ i(o);
4127
+ }
4128
+ });
4032
4129
  }
4033
- async putFile(e, t, s) {
4034
- try {
4035
- const r = this.toAxiosConfig(s);
4036
- r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
4037
- const i = await this.axios.put(this.fixBaseUrl(e), t, {
4038
- ...r,
4039
- headers: {
4040
- "Content-Type": "multipart/form-data"
4041
- }
4042
- });
4043
- return this.mapAxiosResponse(i, s);
4044
- } catch (r) {
4045
- throw this.mapAxiosError(r, s);
4130
+ }
4131
+ const b = class b {
4132
+ static async initialize(e, t) {
4133
+ const s = e.http();
4134
+ if (!this.resourceProducingApps.length) {
4135
+ this.resourceProducingApps = [t, "workspace"];
4136
+ try {
4137
+ const [r, i] = await Promise.all([
4138
+ s.get("/resources-applications"),
4139
+ e.session().getUser()
4140
+ ]);
4141
+ i != null && i.apps && (r != null && r.length) && (this.resourceProducingApps = r.filter(
4142
+ (o) => i.apps.some((a) => a.address.includes(o))
4143
+ ));
4144
+ } catch (r) {
4145
+ console.warn("Failed to load resource-producing apps:", r);
4146
+ }
4046
4147
  }
4148
+ return this.resourceProducingApps;
4047
4149
  }
4048
- async putJson(e, t, s) {
4049
- const r = this.toAxiosConfig(s);
4050
- r.headers && (r.headers["Content-Type"] = "application/json");
4051
- try {
4052
- const i = await this.axios.put(this.fixBaseUrl(e), t, r);
4053
- return this.mapAxiosResponse(i, s);
4054
- } catch (i) {
4055
- throw this.mapAxiosError(i, s);
4056
- }
4150
+ static registerCustomBehaviour(e, t, s) {
4151
+ this.registry.register({ application: e, resourceType: t }, s);
4057
4152
  }
4058
- async patch(e, t, s) {
4059
- try {
4060
- const r = await this.axios.patch(
4061
- this.fixBaseUrl(e),
4062
- t,
4063
- this.toAxiosConfig(s)
4153
+ static async registerBehaviours(e) {
4154
+ this.resourceProducingApps.forEach((t) => {
4155
+ const s = { application: e, resourceType: t };
4156
+ this.registry.register(
4157
+ s,
4158
+ (r) => this.serviceFor(r, e, t)
4064
4159
  );
4065
- return this.mapAxiosResponse(r, s);
4066
- } catch (r) {
4067
- throw this.mapAxiosError(r, s);
4068
- }
4160
+ });
4069
4161
  }
4070
- async patchFile(e, t, s) {
4071
- try {
4072
- const r = this.toAxiosConfig(s);
4073
- r.headers && r.headers["Content-Type"] && delete r.headers["Content-Type"];
4074
- const i = await this.axios.patch(this.fixBaseUrl(e), t, {
4075
- ...r,
4076
- headers: {
4077
- "Content-Type": "multipart/form-data"
4078
- }
4079
- });
4080
- return this.mapAxiosResponse(i, s);
4081
- } catch (r) {
4082
- throw this.mapAxiosError(r, s);
4162
+ static serviceFor(e, t, s) {
4163
+ let r;
4164
+ switch (s) {
4165
+ case "timelinegenerator":
4166
+ r = new TimelinegeneratorBehaviour(e);
4167
+ break;
4168
+ case "workspace":
4169
+ r = new WorkspaceBehaviour(e);
4170
+ break;
4171
+ case "blog":
4172
+ r = new BlogBehaviour(e);
4173
+ break;
4174
+ case "actualites":
4175
+ r = new ActualitesBehaviour(e);
4176
+ break;
4177
+ case "wiki":
4178
+ r = new WikiBehaviour(e);
4179
+ break;
4180
+ case "pages":
4181
+ r = new PagesBehaviour(e);
4182
+ break;
4183
+ case "poll":
4184
+ r = new PollBehaviour(e);
4185
+ break;
4186
+ case "community":
4187
+ r = new CommunityBehaviour(e);
4188
+ break;
4189
+ case "mindmap":
4190
+ r = new MindmapBehaviour(e);
4191
+ break;
4192
+ case "forum":
4193
+ r = new ForumBehaviour(e);
4194
+ break;
4195
+ case "homeworks":
4196
+ r = new HomeworksBehaviour(e);
4197
+ break;
4198
+ case "scrapbook":
4199
+ r = new ScrapbookBehaviour(e);
4200
+ break;
4201
+ case "collaborativewall":
4202
+ r = new CollaborativewallBehaviour(e);
4203
+ break;
4204
+ case "exercizer":
4205
+ r = new ExercizerBehaviour(e);
4206
+ break;
4207
+ case "formulaire":
4208
+ r = new FormulaireBehaviour(e);
4209
+ break;
4210
+ case "magneto":
4211
+ r = new MagnetoBehaviour(e);
4212
+ break;
4213
+ case "appointments":
4214
+ r = new AppointmentsBehaviour(e);
4215
+ break;
4216
+ default:
4217
+ throw ERROR_CODE.NOT_SUPPORTED;
4083
4218
  }
4219
+ return r.APP = t, r;
4084
4220
  }
4085
- async patchJson(e, t, s) {
4086
- const r = this.toAxiosConfig(s);
4087
- r.headers && (r.headers["Content-Type"] = "application/json");
4088
- try {
4089
- const i = await this.axios.patch(this.fixBaseUrl(e), t, r);
4090
- return this.mapAxiosResponse(i, s);
4091
- } catch (i) {
4092
- throw this.mapAxiosError(i, s);
4093
- }
4221
+ };
4222
+ //
4223
+ // STATIC REGISTRY
4224
+ //
4225
+ u(b, "registry", new ServiceRegistry()), // Expose some useful functions
4226
+ u(b, "findBehaviour", b.registry.findService.bind(b.registry)), u(b, "hasBehaviour", b.registry.isRegistered.bind(b.registry)), u(b, "resourceProducingApps", []);
4227
+ let SnipletsService = b;
4228
+ const SEND_ALL = "*";
4229
+ class WebBroker {
4230
+ constructor(e) {
4231
+ u(this, "subscription");
4232
+ this.odeServices = e;
4094
4233
  }
4095
- async delete(e, t) {
4096
- try {
4097
- const s = await this.axios.delete(
4098
- this.fixBaseUrl(e),
4099
- this.toAxiosConfig(t)
4100
- );
4101
- return this.mapAxiosResponse(s, t);
4102
- } catch (s) {
4103
- throw this.mapAxiosError(s, t);
4104
- }
4234
+ get http() {
4235
+ return this.odeServices.http();
4105
4236
  }
4106
- async deleteJson(e, t) {
4107
- try {
4108
- const s = await this.axios.delete(this.fixBaseUrl(e), {
4109
- data: t
4110
- });
4111
- return this.mapAxiosResponse(s);
4112
- } catch (s) {
4113
- throw this.mapAxiosError(s);
4114
- }
4237
+ get events() {
4238
+ return this.odeServices.notify().events();
4115
4239
  }
4116
- getScript(e, t, s) {
4117
- const r = s ?? "exports", i = this.toAxiosConfig(t);
4118
- return i.headers && (i.headers.Accept = "application/javascript"), this.axios.get(this.toCdnUrl(e), i).then((o) => this.mapAxiosResponse(o, t)).then((o) => {
4119
- try {
4120
- const a = `"use strict";var ${r.split(".")[0]}={};${o};return ${r};`;
4121
- return Function(a)();
4122
- } catch {
4123
- return o;
4124
- }
4125
- }).catch((o) => {
4126
- throw this.mapAxiosError(o, t), o;
4240
+ dispatchEvent(e, t) {
4241
+ t.findIndex(
4242
+ (r) => SEND_ALL === r || e.data["event-type"] === r
4243
+ ) >= 0 && this.http.post("/infra/event/web/store", e.data, {
4244
+ disableNotifications: !0
4127
4245
  });
4128
4246
  }
4129
- loadScript(e, t) {
4130
- return loadedScripts[e] ? Promise.resolve() : this.getScript(e, t).then((s) => {
4131
- loadedScripts[e] = !0;
4132
- });
4247
+ initialize(e) {
4248
+ if (e === void 0 || e.send === void 0 || e.send.length > 0) {
4249
+ const t = (e == null ? void 0 : e.send) ?? [SEND_ALL];
4250
+ this.subscription = this.events.subscribe(
4251
+ LAYER_NAME.WEB_DATA,
4252
+ (s) => this.dispatchEvent(s, t)
4253
+ );
4254
+ }
4255
+ return this;
4256
+ }
4257
+ destroy() {
4258
+ this.subscription && (this.subscription.revoke(), delete this.subscription);
4133
4259
  }
4134
4260
  }
4135
- const R = class R {
4136
- // in minutes. Applies to recorded videos.
4261
+ class DataService {
4137
4262
  constructor(e) {
4138
- this.context = e;
4139
- }
4140
- get http() {
4141
- return this.context.http();
4263
+ u(this, "_webBroker");
4264
+ u(this, "app");
4265
+ u(this, "user");
4266
+ u(this, "profile");
4267
+ this.odeServices = e;
4142
4268
  }
4143
4269
  get conf() {
4144
- return this.context.conf();
4270
+ return this.odeServices.conf();
4145
4271
  }
4146
- /**
4147
- * Returns the video app public conf (maxWeight, maxDuration and accepted extensions)
4148
- * @returns the Video app public conf
4149
- */
4150
- async getVideoConf() {
4151
- var t;
4152
- const e = await this.conf.getPublicConf(
4153
- APP$4.VIDEO
4154
- );
4155
- return {
4156
- maxWeight: (e == null ? void 0 : e["max-videosize-mbytes"]) ?? R.MAX_WEIGHT,
4157
- maxDuration: (e == null ? void 0 : e["max-videoduration-minutes"]) ?? R.MAX_DURATION,
4158
- acceptVideoUploadExtensions: ((t = e == null ? void 0 : e["accept-videoupload-extensions"]) == null ? void 0 : t.map(
4159
- (s) => s.toUpperCase()
4160
- )) ?? []
4161
- };
4272
+ get notify() {
4273
+ return this.odeServices.notify();
4162
4274
  }
4163
- /**
4164
- * Starts the encoding process and check when video is fully processed.
4165
- * @param params cf VideoUploadParams
4166
- * @returns a VideoCheckResponse
4167
- */
4168
- async upload({
4169
- data: e,
4170
- appCode: t,
4171
- captation: s,
4172
- duration: r
4173
- }) {
4174
- if (!e.file)
4175
- throw new Error("Invalid video file.");
4176
- if (!e.filename)
4177
- throw new Error("Invalid video filename");
4178
- const i = `${e.browser.name} ${e.browser.version}`, o = new FormData();
4179
- 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);
4180
- let a = `/video/encode?captation=${s}`;
4181
- r && (a += `&duration=${r}`);
4182
- const c = await this.http.post(
4183
- a,
4184
- o,
4185
- { headers: { "Content-Type": "multipart/form-data" } }
4186
- );
4187
- if (c.state == "running") {
4188
- let l = 0, h = 1;
4189
- do {
4190
- const E = h + l;
4191
- await new Promise(
4192
- (y) => setTimeout(y, E * 1e3)
4193
- ), l = h, h = Math.min(8, E);
4194
- const p = await this.http.get(
4195
- `/video/status/${c.processid}`
4196
- );
4197
- if (p.state == "succeed")
4198
- return p.videoworkspaceid && p.videosize && this.context.data().trackVideoSave(
4199
- p.videoworkspaceid,
4200
- Math.round(r),
4201
- p.videosize,
4202
- s,
4203
- e.url,
4204
- i,
4205
- e.device
4206
- ), p;
4207
- if (p.state == "error")
4208
- break;
4209
- } while (!0);
4275
+ // This method is called once, by the service container.
4276
+ async initialize() {
4277
+ try {
4278
+ const { app: e } = await this.notify.onAppConfReady().promise;
4279
+ this.app = e, this.user = await this.odeServices.session().getUser(), this.profile = await this.odeServices.session().getUserProfile();
4280
+ const { ["data-service"]: t } = await this.conf.getPublicConf(e);
4281
+ this._webBroker = new WebBroker(this.odeServices).initialize(t == null ? void 0 : t.web);
4282
+ } catch {
4283
+ console.log("DataService not initialized, usage data unavailable.");
4210
4284
  }
4211
- throw new Error("Video cannot be uploaded.");
4212
- }
4213
- };
4214
- u(R, "MAX_WEIGHT", 50), // in Mbytes. Applies to uploaded videos.
4215
- u(R, "MAX_DURATION", 3);
4216
- let VideoService = R;
4217
- class WidgetService {
4218
- constructor(e) {
4219
- this.context = e;
4220
4285
  }
4221
- get session() {
4222
- return this.context.session();
4286
+ //FIXME When to call that ??
4287
+ predestroy() {
4288
+ this._webBroker && (this._webBroker.destroy(), delete this._webBroker);
4223
4289
  }
4224
- async getSystemWidgets() {
4225
- try {
4226
- const e = await this.session.getUser();
4227
- return e == null ? void 0 : e.widgets;
4228
- } catch (e) {
4229
- throw console.error("[WidgetService] getSystemWidgets failed", e), e;
4230
- }
4290
+ /** Send a web-user-level event to the data pipeline. */
4291
+ trackWebEvent(e) {
4292
+ this.notify.events().publish(LAYER_NAME.WEB_DATA, {
4293
+ name: EVENT_NAME.DATA_TRACKED,
4294
+ data: e
4295
+ });
4231
4296
  }
4232
- async getPreferences() {
4233
- return await this.context.conf().getPreference("widgets");
4297
+ addUserInfos(e) {
4298
+ return this.user && (e.userId = this.user.userId, e.structure = this.user.structureNames[0]), this.profile && (e.profil = this.profile[0]), e;
4234
4299
  }
4235
- async setPreferences(e) {
4236
- await this.context.conf().savePreference("widgets", e);
4300
+ trackVideoSave(e, t, s, r, i, o, a) {
4301
+ const c = this.addUserInfos({
4302
+ "event-type": "VIDEO_SAVE",
4303
+ module: this.app || "video",
4304
+ video_id: e,
4305
+ browser: o,
4306
+ duration: Math.round(t),
4307
+ weight: s,
4308
+ source: r ? "CAPTURED" : "UPLOADED",
4309
+ url: i
4310
+ });
4311
+ a && (c.device_type = a), this.trackWebEvent(c);
4237
4312
  }
4238
- }
4239
- const defaultMappers = {
4240
- csv: function({ type: n, extension: e }) {
4241
- return MimeTypeUtils.INSTANCE.isCsvLike(n, e);
4242
- },
4243
- doc: function({ type: n, extension: e }) {
4244
- return MimeTypeUtils.INSTANCE.isWordLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("wordprocessing") !== -1;
4245
- },
4246
- xls: function({ type: n, extension: e }) {
4247
- return MimeTypeUtils.INSTANCE.isExcelLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("spreadsheet") !== -1 || n.indexOf("ms-excel") !== -1;
4248
- },
4249
- img: function({ type: n }) {
4250
- return n.indexOf("image") !== -1;
4251
- },
4252
- pdf: function({ type: n }) {
4253
- return n.indexOf("pdf") !== -1 || n === "application/x-download";
4254
- },
4255
- ppt: function({ type: n, extension: e }) {
4256
- return MimeTypeUtils.INSTANCE.isPowerpointLike(n, e) ? !0 : n.indexOf("document") !== -1 && n.indexOf("presentation") !== -1 || n.indexOf("powerpoint") !== -1;
4257
- },
4258
- txt: function({ type: n, extension: e }) {
4259
- return MimeTypeUtils.INSTANCE.isTxtLike(n, e);
4260
- },
4261
- md: function({ type: n, extension: e }) {
4262
- return MimeTypeUtils.INSTANCE.isMdLike(n, e);
4263
- },
4264
- video: function({ type: n }) {
4265
- return n.indexOf("video") !== -1;
4266
- },
4267
- audio: function({ type: n }) {
4268
- return n.indexOf("audio") !== -1;
4269
- },
4270
- zip: function({ type: n }) {
4271
- return n.indexOf("zip") !== -1 || n.indexOf("rar") !== -1 || n.indexOf("tar") !== -1 || n.indexOf("7z") !== -1;
4313
+ trackVideoRead(e, t, s, r, i) {
4314
+ const o = this.addUserInfos({
4315
+ "event-type": "VIDEO_READ",
4316
+ module: "video",
4317
+ video_id: e,
4318
+ browser: r,
4319
+ source: t ? "CAPTURED" : "UPLOADED",
4320
+ url: s
4321
+ });
4322
+ this.app && (o["override-module"] = this.app), i && (o.device_type = i), this.trackWebEvent(o);
4272
4323
  }
4273
- }, v = class v {
4274
- /* Similar role notion as in infra-front > workspace > Model.ts */
4275
- static getRole(e) {
4276
- var t, s;
4277
- return v.role(
4278
- (t = e.metadata) == null ? void 0 : t["content-type"],
4279
- !1,
4280
- (s = e.metadata) == null ? void 0 : s.extension
4281
- );
4324
+ trackSpeechAndText(e) {
4325
+ const t = this.addUserInfos({
4326
+ "event-type": "SPEECH_AND_TEXT",
4327
+ function: e
4328
+ });
4329
+ this.app && (t.module = this.app), this.trackWebEvent(t);
4282
4330
  }
4283
- /* Similar role notion as in infra-front > workspace > Model.ts */
4284
- static role(e, t = !1, s) {
4285
- if (s && (s = s.trim()), !e) return "unknown";
4286
- this.roleMappers || console.warn("[DocumentHelper.role] should not have empty roles", this);
4287
- const r = { type: e, previewRole: t, extension: s };
4288
- for (const i of this.roleMappers) {
4289
- const o = i(r);
4290
- if (o)
4291
- return o;
4292
- }
4293
- return "unknown";
4331
+ trackAccessLibraryFromExplorer() {
4332
+ const e = this.addUserInfos({
4333
+ "event-type": "ACCESS_LIBRARY_FROM_EXPLORER"
4334
+ });
4335
+ this.app && (e.module = this.app), this.trackWebEvent(e);
4294
4336
  }
4295
- };
4296
- // FIXME add edumedia support
4297
- u(v, "roleMappers", [
4298
- (e) => Object.keys(defaultMappers).find((s) => defaultMappers[s](e))
4299
- ]);
4300
- let DocumentHelper = v;
4301
- class WorkspaceService {
4302
- constructor(e) {
4303
- this.context = e;
4337
+ }
4338
+ class ReactionsService {
4339
+ constructor(e, t, s) {
4340
+ this.context = e, this.module = t, this.resourceType = s;
4304
4341
  }
4305
4342
  get http() {
4306
4343
  return this.context.http();
4307
4344
  }
4308
- extractMetadata(e) {
4309
- const t = e.name || "", s = t.split("."), r = e.type || "application/octet-stream", i = s.length > 1 ? s[s.length - 1] : "", o = {
4310
- "content-type": r,
4311
- filename: t,
4312
- size: e.size,
4313
- extension: i,
4314
- role: DocumentHelper.role(r, !1, i)
4315
- }, a = t.replace("." + o.extension, ""), c = o.extension ? a + "." + o.extension : a;
4316
- return { basename: a, fullname: c, metadata: o };
4345
+ async loadAvailableReactions() {
4346
+ try {
4347
+ const { "reaction-types": e } = await this.context.conf().getPublicConf("audience");
4348
+ return Array.isArray(e) ? e : void 0;
4349
+ } catch {
4350
+ console.error("Audience configuration not found");
4351
+ return;
4352
+ }
4317
4353
  }
4318
- async saveFile(e, t) {
4319
- const { fullname: s, metadata: r } = this.extractMetadata(e), i = new FormData();
4320
- i.append("file", e, s);
4321
- const o = [];
4322
- ((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}`);
4323
- const a = await this.http.postFile(
4324
- `/workspace/document?${o.join("&")}`,
4325
- i
4354
+ async loadReactionSummaries(e) {
4355
+ const t = await this.http.get(
4356
+ `/audience/reactions/${this.module}/${this.resourceType}?resourceIds=${e.join(",")}`
4326
4357
  );
4327
- if (this.http.isResponseError())
4328
- throw this.http.latestResponse.statusText;
4329
- return a;
4358
+ return this.http.isResponseError() ? {} : t.reactionsByResource;
4330
4359
  }
4331
- async updateFile(e, t, s) {
4332
- const { fullname: r, metadata: i } = this.extractMetadata(t), o = new FormData();
4333
- o.append("file", t, r);
4334
- const a = [];
4335
- 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}`);
4336
- const c = await this.http.putFile(
4337
- `/workspace/document/${e}?${a.join("&")}`,
4338
- o
4360
+ async loadReactionDetails(e, t, s) {
4361
+ const r = await this.http.get(
4362
+ `/audience/reactions/${this.module}/${this.resourceType}/${e}?page=${t}&size=${s}`
4339
4363
  );
4340
- if (this.http.isResponseError())
4341
- throw this.http.latestResponse.statusText;
4342
- return c;
4364
+ return this.http.isResponseError() ? void 0 : r;
4343
4365
  }
4344
- async deleteFile(e) {
4345
- const t = e.map((s) => s._id);
4346
- if (t.length == 0)
4347
- Promise.resolve(null);
4348
- else if (await this.http.deleteJson("/workspace/documents", {
4349
- ids: t
4350
- }), this.http.isResponseError())
4351
- throw this.http.latestResponse.statusText;
4366
+ async deleteReaction(e) {
4367
+ await this.http.delete(
4368
+ `/audience/reactions/${this.module}/${this.resourceType}/${e}`
4369
+ );
4352
4370
  }
4353
- async acceptDocuments(e) {
4354
- const t = await this.context.session().getUser();
4355
- return (s) => s.deleted && s.trasher ? (t == null ? void 0 : t.userId) == s.trasher : !0;
4371
+ async updateReaction(e, t) {
4372
+ await this.http.putJson(
4373
+ `/audience/reactions/${this.module}/${this.resourceType}`,
4374
+ {
4375
+ resourceId: e,
4376
+ reactionType: t
4377
+ }
4378
+ );
4356
4379
  }
4357
- async searchDocuments(e) {
4358
- const t = e.filter !== "external" || e.parentId ? await this.http.get("/workspace/documents", {
4359
- queryParams: { ...e, _: (/* @__PURE__ */ new Date()).getTime() }
4360
- }) : [], s = await this.acceptDocuments(e);
4361
- return t.filter(s);
4380
+ async createReaction(e, t) {
4381
+ await this.http.postJson(
4382
+ `/audience/reactions/${this.module}/${this.resourceType}`,
4383
+ {
4384
+ resourceId: e,
4385
+ reactionType: t
4386
+ }
4387
+ );
4362
4388
  }
4363
- async listDocuments(e, t) {
4364
- return this.searchDocuments({ filter: e, parentId: t, includeall: !0 });
4389
+ }
4390
+ class ViewsService {
4391
+ constructor(e, t, s) {
4392
+ this.context = e, this.module = t, this.resourceType = s;
4365
4393
  }
4366
- /**
4367
- * Duplicate and transfers documents if needed to a different folder with the specified application and visibility.
4368
- * @param documents - The array of documents to transfer.
4369
- * @param application - The application to associate with the transferred documents.
4370
- * @param visibility - The visibility of the transferred documents. Defaults to "protected".
4371
- * @returns A Promise that resolves to an array of transferred WorkspaceElements.
4372
- */
4373
- async transferDocuments(e, t, s = "protected") {
4374
- const r = [];
4375
- if (e.forEach((i) => {
4376
- (s === "public" && !i.public || !i.public && !i.protected) && r.push(i);
4377
- }), r.length > 0) {
4378
- const i = await this.http.post(
4379
- "/workspace/documents/transfer",
4380
- {
4381
- application: t,
4382
- visibility: s,
4383
- ids: r.map((o) => o._id)
4384
- }
4385
- );
4386
- if (this.http.isResponseError())
4387
- throw this.http.latestResponse.statusText;
4388
- return r.forEach((o, a) => {
4389
- const c = e.findIndex(
4390
- (l) => l._id === o._id
4391
- );
4392
- 0 <= c && c < e.length && (e[c] = i[a]);
4393
- }), e.filter((o) => !!o);
4394
- }
4395
- return e;
4394
+ get http() {
4395
+ return this.context.http();
4396
4396
  }
4397
- /**
4398
- * Get the URL of the thumbnail of a workspace element (or its URL),
4399
- * or `null` if none exists or can be created.
4400
- */
4401
- getThumbnailUrl(e, t = 0, s = 0) {
4402
- var i, o;
4403
- const r = t > 0 || s > 0 ? `${t}x${s}` : "120x120";
4404
- if (typeof e == "string")
4405
- return e.includes("data:image") || e.includes("thumbnail") ? e : `${e}${e.includes("?") ? "&" : "?"}thumbnail=${r}`;
4406
- {
4407
- const a = `/workspace/${e.public ? "pub/" : ""}document/${e._id}?thumbnail=`, c = e.thumbnails;
4408
- if ((o = (i = e.metadata) == null ? void 0 : i["content-type"]) != null && o.includes("video")) {
4409
- const l = c && Object.keys(c).length > 0 ? Object.keys(c)[0] : null;
4410
- return l ? a + l : null;
4411
- } else
4412
- return a + r;
4413
- }
4397
+ async getCounters(e) {
4398
+ const t = await this.http.get(
4399
+ `/audience/views/count/${this.module}/${this.resourceType}?resourceIds=${e.join(",")}`
4400
+ );
4401
+ return this.http.isResponseError() ? {} : t;
4414
4402
  }
4415
- /**
4416
- * Get the URL of the file of a workspace element (or its URL),
4417
- * or `null` if none exists or can be created.
4418
- * @param filter - The filter to apply to the workspace element.
4419
- * @param withChildren - If true, include all children folders.
4420
- * @param parentId - The ID of the parent folder to list.
4421
- * @param directShared - If true, include only elements directly shared with the user.
4422
- *
4423
- */
4424
- listFolder(e, t = !1, s, r) {
4425
- const i = {
4426
- filter: e,
4427
- hierarchical: t,
4428
- parentId: s,
4429
- directShared: r
4430
- };
4431
- return this.http.get("/workspace/folders/list", {
4432
- queryParams: i
4433
- });
4403
+ async getDetails(e) {
4404
+ const t = await this.http.get(
4405
+ `/audience/views/details/${this.module}/${this.resourceType}/${e}`
4406
+ );
4407
+ return this.http.isResponseError() ? void 0 : t;
4434
4408
  }
4435
- /**
4436
- * List all folders in the workspace.
4437
- * @param withChildren - If true, include all children folders.
4438
- * @param parentId - The ID of the parent folder to list.
4439
- * @returns A promise that resolves to an array of WorkspaceElement objects.
4440
- */
4441
- listOwnerFolders(e, t) {
4442
- return this.listFolder("owner", e, t);
4409
+ trigger(e) {
4410
+ return this.http.post(
4411
+ `/audience/views/${this.module}/${this.resourceType}/${e}`
4412
+ );
4443
4413
  }
4444
- /**
4445
- * List all shared folders in the workspace.
4446
- * @param withChildren - If true, include all children folders.
4447
- * @param parentId - The ID of the parent folder to list.
4448
- * @returns A promise that resolves to an array of WorkspaceElement objects.
4449
- */
4450
- listSharedFolders(e, t) {
4451
- return this.listFolder("shared", e, t, !0);
4414
+ }
4415
+ class AudienceService {
4416
+ constructor(e, t, s) {
4417
+ this.context = e, this.module = t, this.resourceType = s;
4452
4418
  }
4453
- /**
4454
- * Create a new folder in the workspace.
4455
- * @param name - The name of the new folder.
4456
- * @param parentId - The ID of the parent folder where the new folder will be created.
4457
- * @returns void
4458
- */
4459
- createFolder(e, t) {
4460
- const s = new FormData();
4461
- return s.append("name", e), t && s.append("parentFolderId", t), this.http.postFile("/workspace/folder", s);
4419
+ get views() {
4420
+ return new ViewsService(this.context, this.module, this.resourceType);
4421
+ }
4422
+ get reactions() {
4423
+ return new ReactionsService(this.context, this.module, this.resourceType);
4462
4424
  }
4463
4425
  }
4464
4426
  class OdeServices {
@@ -4475,10 +4437,9 @@ class OdeServices {
4475
4437
  u(this, "_session");
4476
4438
  u(this, "_share");
4477
4439
  u(this, "_video");
4478
- u(this, "_widget");
4479
4440
  u(this, "_workspace");
4480
4441
  u(this, "_embedder");
4481
- 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._widget = new WidgetService(this), this._workspace = new WorkspaceService(this), this._embedder = new EmbedderService(this);
4442
+ 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);
4482
4443
  }
4483
4444
  initialize() {
4484
4445
  return this._data.initialize(), this;
@@ -4528,9 +4489,6 @@ class OdeServices {
4528
4489
  video() {
4529
4490
  return this._video;
4530
4491
  }
4531
- widget() {
4532
- return this._widget;
4533
- }
4534
4492
  workspace() {
4535
4493
  return this._workspace;
4536
4494
  }
@@ -4731,17 +4689,17 @@ class WidgetFramework {
4731
4689
  var a;
4732
4690
  const i = ((a = r.find((c) => c.child === t.skin)) == null ? void 0 : a.parent) === "panda" ? secondLevelWidgets : firstLevelWidgets;
4733
4691
  this._widgets = this._widgets.filter((c, l) => {
4734
- const h = c.platformConf.name;
4735
- return i.indexOf(h) !== -1 ? !1 : (this._userPrefs[h] || (this._userPrefs[h] = {
4736
- index: defaultWidgetOrder[h] ?? 999,
4692
+ const p = c.platformConf.name;
4693
+ return i.indexOf(p) !== -1 ? !1 : (this._userPrefs[p] || (this._userPrefs[p] = {
4694
+ index: defaultWidgetOrder[p] ?? 999,
4737
4695
  show: !0,
4738
4696
  position: c.platformConf.position
4739
- }), c.platformConf.mandatory && (this._userPrefs[h].show = !0, this._userPrefs[h].index = defaultWidgetOrder[h] ?? 999), c.platformConf.i18n && s.push(c.platformConf.i18n), c.applyUserPref(this._userPrefs[h]), !0);
4697
+ }), c.platformConf.mandatory && (this._userPrefs[p].show = !0, this._userPrefs[p].index = defaultWidgetOrder[p] ?? 999), c.platformConf.i18n && s.push(c.platformConf.i18n), c.applyUserPref(this._userPrefs[p]), !0);
4740
4698
  });
4741
4699
  const o = new Idiom();
4742
4700
  this._widgets = this._widgets.sort((c, l) => {
4743
- const h = o.translate(`timeline.settings.${c.platformConf.name}`).toLowerCase(), E = o.translate(`timeline.settings.${l.platformConf.name}`).toLowerCase();
4744
- return h < E ? -1 : h > E ? 1 : 0;
4701
+ const p = o.translate(`timeline.settings.${c.platformConf.name}`).toLowerCase(), E = o.translate(`timeline.settings.${l.platformConf.name}`).toLowerCase();
4702
+ return p < E ? -1 : p > E ? 1 : 0;
4745
4703
  });
4746
4704
  });
4747
4705
  }
@@ -4766,7 +4724,22 @@ class Widget {
4766
4724
  this._userPref = e, this._userPref.position = this._userPref.position ?? widgets.lookupDefaultPosition(this._platformConf.name) ?? "left";
4767
4725
  }
4768
4726
  }
4769
- const widgets = new WidgetFramework(), WIDGET_NAME = {
4727
+ const widgets = new WidgetFramework();
4728
+ class LastInfosWidget {
4729
+ loadInfos(e) {
4730
+ return transport.http.get("/actualites/infos/last/" + e);
4731
+ }
4732
+ getMaxResults() {
4733
+ return transport.http.get("/userbook/preference/maxInfos").then((e) => e.preference ? parseInt(e.preference) : 4);
4734
+ }
4735
+ setMaxResults(e) {
4736
+ return transport.http.putJson(
4737
+ "/userbook/preference/maxInfos",
4738
+ `"${e}"`
4739
+ );
4740
+ }
4741
+ }
4742
+ const WIDGET_NAME = {
4770
4743
  LAST_INFOS: "last-infos-widget",
4771
4744
  BIRTHDAY: "birthday",
4772
4745
  CALENDAR: "calendar-widget",
@@ -4803,6 +4776,7 @@ export {
4803
4776
  FOLDER,
4804
4777
  ITimelineFactory,
4805
4778
  LAYER_NAME,
4779
+ LastInfosWidget,
4806
4780
  NotifyFrameworkFactory,
4807
4781
  ReactionTypes,
4808
4782
  ResourceService,