@yuuvis/client-core 0.7.4 → 0.9.0

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.
@@ -4,8 +4,8 @@ export { TranslateDirective, TranslateLoader, TranslateModule, TranslatePipe, Tr
4
4
  import * as i0 from '@angular/core';
5
5
  import { NgModule, InjectionToken, Inject, Injectable, Optional, inject, APP_INITIALIZER, SkipSelf, Pipe } from '@angular/core';
6
6
  import { HttpErrorResponse, HttpHeaders, HttpClient, HttpParams, HttpRequest, HttpEventType, HttpResponse, HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
7
- import { map, tap, finalize, shareReplay, catchError, filter, switchMap, first, scan, delay } from 'rxjs/operators';
8
- import { EMPTY, of, from, Observable, forkJoin, Subject, ReplaySubject, BehaviorSubject, tap as tap$1, map as map$1, merge, fromEvent, filter as filter$1, debounceTime, throwError } from 'rxjs';
7
+ import { map, tap, finalize, shareReplay, catchError, switchMap, first, filter, scan, delay } from 'rxjs/operators';
8
+ import { EMPTY, of, from, Observable, forkJoin, ReplaySubject, Subject, BehaviorSubject, tap as tap$1, map as map$1, merge, fromEvent, filter as filter$1, debounceTime, throwError, switchMap as switchMap$1 } from 'rxjs';
9
9
  import * as i1 from 'angular-oauth2-oidc';
10
10
  import { OAuthStorage, OAuthModule } from 'angular-oauth2-oidc';
11
11
  import { __decorate, __param, __metadata } from 'tslib';
@@ -94,7 +94,7 @@ const SystemType = {
94
94
  SOT: 'system:secondray'
95
95
  };
96
96
  const SystemResult = {
97
- DELETE: 'system:deletionResult',
97
+ DELETE: 'system:deletionResult'
98
98
  };
99
99
  const AdministrationRoles = {
100
100
  ADMIN: 'YUUVIS_TENANT_ADMIN',
@@ -112,17 +112,6 @@ const RetentionField = {
112
112
  RETENTION_START: 'system:rmStartOfRetention',
113
113
  DESTRUCTION_DATE: 'system:rmDestructionDate'
114
114
  };
115
- var RetentionState;
116
- (function (RetentionState) {
117
- // no retention
118
- RetentionState[RetentionState["NONE"] = 0] = "NONE";
119
- // retention is active
120
- RetentionState[RetentionState["ACTIVE"] = 1] = "ACTIVE";
121
- // supposed to be destructed
122
- RetentionState[RetentionState["DESTRUCT"] = 2] = "DESTRUCT";
123
- // retention is not active yet
124
- RetentionState[RetentionState["INACTIVE"] = 3] = "INACTIVE";
125
- })(RetentionState || (RetentionState = {}));
126
115
  const BaseObjectTypeField = {
127
116
  OBJECT_TYPE_ID: 'system:objectTypeId',
128
117
  VERSION_NUMBER: 'system:versionNumber',
@@ -229,7 +218,6 @@ var InternalFieldType;
229
218
  InternalFieldType["STRING_DYNAMIC_CATALOG"] = "string:catalog:dynamic";
230
219
  InternalFieldType["BOOLEAN_SWITCH"] = "boolean:switch";
231
220
  })(InternalFieldType || (InternalFieldType = {}));
232
- ;
233
221
  var ObjectTag;
234
222
  (function (ObjectTag) {
235
223
  ObjectTag["AFO"] = "appclient:dlm:prepare";
@@ -1235,179 +1223,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1235
1223
  args: [{ providedIn: 'root' }]
1236
1224
  }] });
1237
1225
 
1238
- class SearchService {
1239
- #backend = inject(BackendService);
1240
- static { this.DEFAULT_QUERY_SIZE = 50; }
1241
- /**
1242
- * Execute a search query ans transform the result to a SearchResult object
1243
- * @param query The search query
1244
- * @returns Observable of a SearchResult
1245
- */
1246
- search(query) {
1247
- return this.searchRaw(query).pipe(map((res) => this.toSearchResult(res)));
1248
- }
1249
- /**
1250
- * Execute a raw search query and return the result as is.
1251
- * @param query The search query
1252
- * @returns Observable of the raw search result
1253
- */
1254
- searchRaw(query) {
1255
- if (!query.size)
1256
- query.size = SearchService.DEFAULT_QUERY_SIZE;
1257
- return this.#backend.post(`/dms/objects/search`, query);
1258
- }
1259
- /**
1260
- * Search for objects in the dms using CMIS like SQL syntax.
1261
- * @param statement The query statement
1262
- * @param size The number of items to return
1263
- * @returns Observable of a SearchResult
1264
- */
1265
- searchCmis(statement, size = 50) {
1266
- return this.#backend
1267
- .post('/dms/objects/search', {
1268
- query: {
1269
- statement,
1270
- skipCount: 0,
1271
- maxItems: size,
1272
- handleDeletedDocuments: 'DELETED_DOCUMENTS_EXCLUDE'
1273
- }
1274
- }
1275
- // Using API-WEB because it enriches the response with additional information (resolved user names, etc.)
1276
- // ApiBase.core
1277
- )
1278
- .pipe(map((res) => this.toSearchResult(res)));
1279
- }
1280
- /**
1281
- * Fetch aggragations for a given query.
1282
- * @param q The query
1283
- * @param aggregations List of aggregations to be fetched (e.g. `enaio:objectTypeId`
1284
- * to get an aggregation of object types)
1285
- */
1286
- aggregate(q, aggregations) {
1287
- q.aggs = aggregations;
1288
- return this.searchRaw(q).pipe(map((res) => this.#toAggregateResult(res, aggregations)));
1289
- }
1290
- /**
1291
- * Map search result from the backend to applications AggregateResult object
1292
- * @param searchResponse The backend response
1293
- * @param aggregations The aggregations to be fetched
1294
- */
1295
- #toAggregateResult(searchResponse, aggregations) {
1296
- const agg = [];
1297
- if (aggregations) {
1298
- aggregations.forEach((a) => {
1299
- const ag = {
1300
- aggKey: a,
1301
- entries: searchResponse.objects.map((o) => ({
1302
- key: o.properties[a].value,
1303
- count: o.properties['OBJECT_COUNT'].value
1304
- }))
1305
- };
1306
- agg.push(ag);
1307
- });
1308
- }
1309
- return {
1310
- totalNumItems: searchResponse.totalNumItems,
1311
- aggregations: agg
1312
- };
1313
- }
1314
- /**
1315
- * Go to a page of a search result.
1316
- * @param searchResult The search result (that supports pagination)
1317
- * @param page The number of the page to go to
1318
- */
1319
- getPage(query, page) {
1320
- query.from = (page - 1) * (query.size || SearchService.DEFAULT_QUERY_SIZE);
1321
- return this.search(query);
1322
- }
1323
- /**
1324
- * Map search result from the backend to applications SearchResult object
1325
- * @param searchResponse The backend response
1326
- */
1327
- toSearchResult(searchResponse) {
1328
- const resultListItems = [];
1329
- const objectTypes = [];
1330
- searchResponse.objects.forEach((o) => {
1331
- const fields = new Map();
1332
- // process properties section of result
1333
- Object.keys(o.properties).forEach((key) => {
1334
- let value = o.properties[key].value;
1335
- if (o.properties[key].clvalue) {
1336
- // table fields will have a clientValue too ...
1337
- value = o.properties[key].clvalue;
1338
- // ... and also may contain values that need to be resolved
1339
- if (o.properties[key].resolvedValues) {
1340
- value.forEach((v) => {
1341
- Object.keys(v).forEach((k) => {
1342
- const resValue = Array.isArray(v[k]) ? v[k].map((i) => o.properties[key].resolvedValues[i]) : o.properties[key].resolvedValues[v[k]];
1343
- if (resValue) {
1344
- v[`${k}_title`] = resValue;
1345
- }
1346
- });
1347
- });
1348
- }
1349
- }
1350
- fields.set(key, value);
1351
- if (o.properties[key].title) {
1352
- fields.set(key + '_title', o.properties[key].title);
1353
- }
1354
- });
1355
- // process contentStreams section of result if available.
1356
- // Objects that don't have files attached won't have this section
1357
- let content;
1358
- if (o.contentStreams && o.contentStreams.length > 0) {
1359
- // we assume that each result object only has ONE file attached, altough
1360
- // this is an array and there may be more
1361
- const contentStream = o.contentStreams[0];
1362
- // also add contentstream related fields to the result fields
1363
- fields.set(ContentStreamField.LENGTH, contentStream.length);
1364
- fields.set(ContentStreamField.MIME_TYPE, contentStream.mimeType);
1365
- fields.set(ContentStreamField.FILENAME, contentStream.fileName);
1366
- fields.set(ContentStreamField.ID, contentStream.contentStreamId);
1367
- fields.set(ContentStreamField.RANGE, contentStream.contentStreamRange);
1368
- fields.set(ContentStreamField.REPOSITORY_ID, contentStream.repositoryId);
1369
- fields.set(ContentStreamField.DIGEST, contentStream.digest);
1370
- fields.set(ContentStreamField.ARCHIVE_PATH, contentStream.archivePath);
1371
- content = {
1372
- contentStreamId: contentStream.contentStreamId,
1373
- repositoryId: contentStream.repositoryId,
1374
- range: contentStream.range,
1375
- digest: contentStream.digest,
1376
- archivePath: contentStream.archivePath,
1377
- fileName: contentStream.fileName,
1378
- mimeType: contentStream.mimeType,
1379
- size: contentStream.length
1380
- };
1381
- }
1382
- const objectTypeId = o.properties[BaseObjectTypeField.OBJECT_TYPE_ID] ? o.properties[BaseObjectTypeField.OBJECT_TYPE_ID].value : null;
1383
- if (objectTypes.indexOf(objectTypeId) === -1) {
1384
- objectTypes.push(objectTypeId);
1385
- }
1386
- resultListItems.push({
1387
- objectTypeId,
1388
- content,
1389
- fields,
1390
- permissions: o.permissions
1391
- });
1392
- });
1393
- const result = {
1394
- hasMoreItems: searchResponse.hasMoreItems,
1395
- totalNumItems: searchResponse.totalNumItems,
1396
- items: resultListItems,
1397
- objectTypes
1398
- };
1399
- return result;
1400
- }
1401
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1402
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, providedIn: 'root' }); }
1403
- }
1404
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, decorators: [{
1405
- type: Injectable,
1406
- args: [{
1407
- providedIn: 'root'
1408
- }]
1409
- }] });
1410
-
1411
1226
  var Operator;
1412
1227
  (function (Operator) {
1413
1228
  Operator["EQUAL"] = "eq";
@@ -1447,60 +1262,6 @@ const OperatorLabel = {
1447
1262
  CONTAINS: '~' // contains
1448
1263
  };
1449
1264
 
1450
- var Direction;
1451
- (function (Direction) {
1452
- Direction["LTR"] = "ltr";
1453
- Direction["RTL"] = "rtl";
1454
- })(Direction || (Direction = {}));
1455
-
1456
- /**
1457
- * Service for providing triggered events
1458
- */
1459
- class EventService {
1460
- constructor() {
1461
- this.#eventSource = new Subject();
1462
- this.event$ = this.#eventSource.asObservable();
1463
- }
1464
- #eventSource;
1465
- /**
1466
- * Trigger an global event
1467
- * @param type Type/key of the event
1468
- * @param data Data to be send along with the event
1469
- */
1470
- trigger(type, data) {
1471
- this.#eventSource.next({ type, data });
1472
- }
1473
- /**
1474
- * Listen on a triggered event
1475
- * @param types Type/key of the event
1476
- */
1477
- on(...types) {
1478
- return this.event$.pipe(filter((event) => event && !!types.find((t) => t === event.type)));
1479
- }
1480
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1481
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, providedIn: 'root' }); }
1482
- }
1483
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, decorators: [{
1484
- type: Injectable,
1485
- args: [{
1486
- providedIn: 'root'
1487
- }]
1488
- }] });
1489
-
1490
- /**
1491
- * Events emitted by parts of the application
1492
- */
1493
- var YuvEventType;
1494
- (function (YuvEventType) {
1495
- YuvEventType["LOGOUT"] = "yuv.user.logout";
1496
- YuvEventType["CLIENT_LOCALE_CHANGED"] = "yuv.user.locale.client.changed";
1497
- YuvEventType["DMS_OBJECT_LOADED"] = "yuv.dms.object.loaded";
1498
- YuvEventType["DMS_OBJECT_CREATED"] = "yuv.dms.object.created";
1499
- YuvEventType["DMS_OBJECT_DELETED"] = "yuv.dms.object.deleted";
1500
- YuvEventType["DMS_OBJECT_UPDATED"] = "yuv.dms.object.updated";
1501
- YuvEventType["DMS_OBJECTS_MOVED"] = "yuv.dms.objects.moved";
1502
- })(YuvEventType || (YuvEventType = {}));
1503
-
1504
1265
  /**
1505
1266
  * Service for saving or caching data on the users device. It uses the most efficient storage
1506
1267
  * available (IndexDB, localstorage, ...) on the device. Depending on the type of storage used,
@@ -2019,121 +1780,429 @@ class SystemService {
2019
1780
  return this.#backend.get(Utils.buildUri(`/dms/forms/${objectTypeId}`, { situation }));
2020
1781
  }
2021
1782
  /**
2022
- * Check whether or not the model has at least one form element. Recursive.
2023
- * @param element Form element to check child elements for
1783
+ * Check whether or not the model has at least one form element. Recursive.
1784
+ * @param element Form element to check child elements for
1785
+ */
1786
+ #formHasElements(element) {
1787
+ let hasElement = false;
1788
+ element.elements?.forEach((e) => {
1789
+ if (!['o2mGroup', 'o2mGroupStack'].includes(e.type)) {
1790
+ hasElement = true;
1791
+ }
1792
+ else if (!hasElement) {
1793
+ hasElement = this.#formHasElements(e);
1794
+ }
1795
+ });
1796
+ return hasElement;
1797
+ }
1798
+ /**
1799
+ * Generates an internal type for a given object type field.
1800
+ * Adding this to a form element or object type field enables us to render forms
1801
+ * based on object type fields in a more performant way. Otherwise we would
1802
+ * have to evaluate the conditions for every form element on every digest cycle.
1803
+ * @param type propertyType of the ObjectTypeField
1804
+ * @param classifications classifications of the ObjectTypeField
1805
+ */
1806
+ getInternalFormElementType(type, classifications) {
1807
+ const _classifications = this.getClassifications(classifications || []);
1808
+ if (type === 'string' && _classifications.has(Classification.STRING_REFERENCE)) {
1809
+ return InternalFieldType.STRING_REFERENCE;
1810
+ }
1811
+ else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION)) {
1812
+ return InternalFieldType.STRING_ORGANIZATION;
1813
+ }
1814
+ else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION_SET)) {
1815
+ return InternalFieldType.STRING_ORGANIZATION_SET;
1816
+ }
1817
+ else if (type === 'string' && _classifications.has(Classification.STRING_CATALOG)) {
1818
+ return InternalFieldType.STRING_CATALOG;
1819
+ }
1820
+ else if (type === 'boolean' && _classifications.has(Classification.BOOLEAN_SWITCH)) {
1821
+ return InternalFieldType.BOOLEAN_SWITCH;
1822
+ }
1823
+ else if (type === 'string' &&
1824
+ (_classifications.has(Classification.STRING_CATALOG_DYNAMIC) || _classifications.has(Classification.STRING_CATALOG_CUSTOM))) {
1825
+ return InternalFieldType.STRING_DYNAMIC_CATALOG;
1826
+ }
1827
+ else {
1828
+ // if there are no matching conditions just return the original type
1829
+ return type;
1830
+ }
1831
+ }
1832
+ getObjectTypeField(id) {
1833
+ const f = this.system?.allFields[id];
1834
+ return f ? { ...f, _internalType: this.getInternalFormElementType(f.propertyType, f.classifications) } : undefined;
1835
+ }
1836
+ /**
1837
+ * Extract classifications from object type fields classification
1838
+ * string. This string may contain more than one classification entry.
1839
+ *
1840
+ * Classification is a comma separated string that may contain additional
1841
+ * properties related to on classification entry. Example:
1842
+ *
1843
+ * `id:reference[system:folder], email`
1844
+ *
1845
+ * @param classifications Object type fields classification property (schema)
1846
+ */
1847
+ getClassifications(classifications) {
1848
+ const res = new Map();
1849
+ if (classifications) {
1850
+ classifications.forEach((c) => {
1851
+ const matches = c.match(/^([^\[]*)(\[(.*)\])?$/);
1852
+ if (matches && matches.length) {
1853
+ res.set(matches[1], {
1854
+ classification: matches[1],
1855
+ options: matches[3] ? matches[3].split(',').map((o) => o.trim()) : []
1856
+ });
1857
+ }
1858
+ });
1859
+ }
1860
+ return res;
1861
+ }
1862
+ toFormElement(field) {
1863
+ return { ...field, label: this.getLocalizedLabel(field.id), name: field.id, type: field.propertyType };
1864
+ }
1865
+ updateAuthData(data) {
1866
+ this.authData = { ...this.authData, ...data };
1867
+ this.#backend.setHeader('Accept-Language', this.authData.language);
1868
+ return this.#appCache.setItem(this.#STORAGE_KEY_AUTH_DATA, this.authData);
1869
+ }
1870
+ updateLocalizations(iso) {
1871
+ return this.updateAuthData({ language: iso }).pipe(switchMap(() => this.#fetchLocalizations()), tap((res) => {
1872
+ this.system.i18n = res;
1873
+ this.#appCache.setItem(this.#STORAGE_KEY, this.system).subscribe();
1874
+ this.#systemSource.next(this.system);
1875
+ }));
1876
+ }
1877
+ #fetchLocalizations() {
1878
+ return this.#backend.get('/resources/text');
1879
+ }
1880
+ fetchResources(id) {
1881
+ return this.#backend
1882
+ .batch([
1883
+ { uri: `/system/resources/${id}`, base: ApiBase.core },
1884
+ { uri: `/admin/resources/${id}`, base: ApiBase.core }
1885
+ ])
1886
+ .pipe(map(([global, tenant]) => ({ global, tenant })));
1887
+ }
1888
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1889
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, providedIn: 'root' }); }
1890
+ }
1891
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, decorators: [{
1892
+ type: Injectable,
1893
+ args: [{
1894
+ providedIn: 'root'
1895
+ }]
1896
+ }] });
1897
+
1898
+ class SearchService {
1899
+ #backend = inject(BackendService);
1900
+ #system = inject(SystemService);
1901
+ static { this.DEFAULT_QUERY_SIZE = 50; }
1902
+ /**
1903
+ * Execute a search query ans transform the result to a SearchResult object
1904
+ * @param query The search query
1905
+ * @returns Observable of a SearchResult
1906
+ */
1907
+ search(query) {
1908
+ return this.searchRaw(query).pipe(map((res) => this.toSearchResult(res)));
1909
+ }
1910
+ /**
1911
+ * Execute a raw search query and return the result as is.
1912
+ * @param query The search query
1913
+ * @returns Observable of the raw search result
1914
+ */
1915
+ searchRaw(query) {
1916
+ if (!query.size)
1917
+ query.size = SearchService.DEFAULT_QUERY_SIZE;
1918
+ return this.#backend.post(`/dms/objects/search`, query);
1919
+ }
1920
+ /**
1921
+ * Search for objects in the dms using CMIS like SQL syntax.
1922
+ * @param statement The query statement
1923
+ * @param size The number of items to return
1924
+ * @returns Observable of a SearchResult
1925
+ */
1926
+ searchCmis(statement, size = 50) {
1927
+ return this.#backend
1928
+ .post('/dms/objects/search', {
1929
+ query: {
1930
+ statement,
1931
+ skipCount: 0,
1932
+ maxItems: size,
1933
+ handleDeletedDocuments: 'DELETED_DOCUMENTS_EXCLUDE'
1934
+ }
1935
+ }
1936
+ // Using API-WEB because it enriches the response with additional information (resolved user names, etc.)
1937
+ // ApiBase.core
1938
+ )
1939
+ .pipe(map((res) => this.toSearchResult(res)));
1940
+ }
1941
+ /**
1942
+ * Fetch aggragations for a given query.
1943
+ * @param q The query
1944
+ * @param aggregations List of aggregations to be fetched (e.g. `enaio:objectTypeId`
1945
+ * to get an aggregation of object types)
1946
+ */
1947
+ aggregate(q, aggregations) {
1948
+ q.aggs = aggregations;
1949
+ return this.searchRaw(q).pipe(map((res) => this.#toAggregateResult(res, aggregations)));
1950
+ }
1951
+ /**
1952
+ * Map search result from the backend to applications AggregateResult object
1953
+ * @param searchResponse The backend response
1954
+ * @param aggregations The aggregations to be fetched
1955
+ */
1956
+ #toAggregateResult(searchResponse, aggregations) {
1957
+ const agg = [];
1958
+ if (aggregations) {
1959
+ aggregations.forEach((a) => {
1960
+ const ag = {
1961
+ aggKey: a,
1962
+ entries: searchResponse.objects.map((o) => ({
1963
+ key: o.properties[a].value,
1964
+ count: o.properties['OBJECT_COUNT'].value
1965
+ }))
1966
+ };
1967
+ agg.push(ag);
1968
+ });
1969
+ }
1970
+ return {
1971
+ totalNumItems: searchResponse.totalNumItems,
1972
+ aggregations: agg
1973
+ };
1974
+ }
1975
+ /**
1976
+ * Go to a page of a search result.
1977
+ * @param searchResult The search result (that supports pagination)
1978
+ * @param page The number of the page to go to
1979
+ */
1980
+ getPage(query, page) {
1981
+ query.from = (page - 1) * (query.size || SearchService.DEFAULT_QUERY_SIZE);
1982
+ return this.search(query);
1983
+ }
1984
+ /**
1985
+ * Map search result from the backend to applications SearchResult object
1986
+ * @param searchResponse The backend response
1987
+ */
1988
+ toSearchResult(searchResponse) {
1989
+ const resultListItems = [];
1990
+ const objectTypes = [];
1991
+ searchResponse.objects.forEach((o) => {
1992
+ const fields = new Map();
1993
+ // process properties section of result
1994
+ Object.keys(o.properties).forEach((key) => {
1995
+ let value = o.properties[key].value;
1996
+ if (o.properties[key].clvalue) {
1997
+ // table fields will have a clientValue too ...
1998
+ value = o.properties[key].clvalue;
1999
+ // ... and also may contain values that need to be resolved
2000
+ if (o.properties[key].resolvedValues) {
2001
+ value.forEach((v) => {
2002
+ Object.keys(v).forEach((k) => {
2003
+ const resValue = Array.isArray(v[k]) ? v[k].map((i) => o.properties[key].resolvedValues[i]) : o.properties[key].resolvedValues[v[k]];
2004
+ if (resValue) {
2005
+ v[`${k}_title`] = resValue;
2006
+ }
2007
+ });
2008
+ });
2009
+ }
2010
+ }
2011
+ fields.set(key, value);
2012
+ if (o.properties[key].title) {
2013
+ fields.set(key + '_title', o.properties[key].title);
2014
+ }
2015
+ });
2016
+ // process contentStreams section of result if available.
2017
+ // Objects that don't have files attached won't have this section
2018
+ let content;
2019
+ if (o.contentStreams && o.contentStreams.length > 0) {
2020
+ // we assume that each result object only has ONE file attached, altough
2021
+ // this is an array and there may be more
2022
+ const contentStream = o.contentStreams[0];
2023
+ // also add contentstream related fields to the result fields
2024
+ fields.set(ContentStreamField.LENGTH, contentStream.length);
2025
+ fields.set(ContentStreamField.MIME_TYPE, contentStream.mimeType);
2026
+ fields.set(ContentStreamField.FILENAME, contentStream.fileName);
2027
+ fields.set(ContentStreamField.ID, contentStream.contentStreamId);
2028
+ fields.set(ContentStreamField.RANGE, contentStream.contentStreamRange);
2029
+ fields.set(ContentStreamField.REPOSITORY_ID, contentStream.repositoryId);
2030
+ fields.set(ContentStreamField.DIGEST, contentStream.digest);
2031
+ fields.set(ContentStreamField.ARCHIVE_PATH, contentStream.archivePath);
2032
+ content = {
2033
+ contentStreamId: contentStream.contentStreamId,
2034
+ repositoryId: contentStream.repositoryId,
2035
+ range: contentStream.range,
2036
+ digest: contentStream.digest,
2037
+ archivePath: contentStream.archivePath,
2038
+ fileName: contentStream.fileName,
2039
+ mimeType: contentStream.mimeType,
2040
+ size: contentStream.length
2041
+ };
2042
+ }
2043
+ const objectTypeId = o.properties[BaseObjectTypeField.OBJECT_TYPE_ID] ? o.properties[BaseObjectTypeField.OBJECT_TYPE_ID].value : null;
2044
+ if (objectTypes.indexOf(objectTypeId) === -1) {
2045
+ objectTypes.push(objectTypeId);
2046
+ }
2047
+ resultListItems.push({
2048
+ objectTypeId,
2049
+ content,
2050
+ fields,
2051
+ permissions: o.permissions
2052
+ });
2053
+ });
2054
+ const result = {
2055
+ hasMoreItems: searchResponse.hasMoreItems,
2056
+ totalNumItems: searchResponse.totalNumItems,
2057
+ items: resultListItems,
2058
+ objectTypes
2059
+ };
2060
+ return result;
2061
+ }
2062
+ /**
2063
+ * Maps data extracted from a search form to search filters. Every key of the form data object
2064
+ * will be mapped to a search filter.
2065
+ * @param formData form data
2066
+ * @returns Array of search filters
2024
2067
  */
2025
- #formHasElements(element) {
2026
- let hasElement = false;
2027
- element.elements?.forEach((e) => {
2028
- if (!['o2mGroup', 'o2mGroupStack'].includes(e.type)) {
2029
- hasElement = true;
2068
+ formDataToSearchFilter(formData) {
2069
+ const isRangeValue = (v) => {
2070
+ return typeof v === 'object' && v !== null && 'firstValue' in v && 'operator' in v;
2071
+ };
2072
+ const filters = [];
2073
+ Object.keys(formData).forEach((key) => {
2074
+ const value = formData[key];
2075
+ if (isRangeValue(value)) {
2076
+ const f = this.rangeValueToSearchFilter(value, key);
2077
+ if (f)
2078
+ filters.push(f);
2030
2079
  }
2031
- else if (!hasElement) {
2032
- hasElement = this.#formHasElements(e);
2080
+ else {
2081
+ filters.push({
2082
+ f: key,
2083
+ o: Array.isArray(value) ? Operator.IN : Operator.EQUAL,
2084
+ v1: value
2085
+ });
2033
2086
  }
2034
2087
  });
2035
- return hasElement;
2088
+ return filters;
2089
+ }
2090
+ rangeValueToSearchFilter(value, property) {
2091
+ return this.#system.getObjectTypeField(property)?.propertyType === 'datetime'
2092
+ ? this.#dateRangeValueToSearchFilter(value, property)
2093
+ : {
2094
+ f: property,
2095
+ o: value.operator,
2096
+ v1: value.firstValue,
2097
+ v2: value.secondValue
2098
+ };
2036
2099
  }
2037
- /**
2038
- * Generates an internal type for a given object type field.
2039
- * Adding this to a form element or object type field enables us to render forms
2040
- * based on object type fields in a more performant way. Otherwise we would
2041
- * have to evaluate the conditions for every form element on every digest cycle.
2042
- * @param type propertyType of the ObjectTypeField
2043
- * @param classifications classifications of the ObjectTypeField
2044
- */
2045
- getInternalFormElementType(type, classifications) {
2046
- const _classifications = this.getClassifications(classifications || []);
2047
- if (type === 'string' && _classifications.has(Classification.STRING_REFERENCE)) {
2048
- return InternalFieldType.STRING_REFERENCE;
2049
- }
2050
- else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION)) {
2051
- return InternalFieldType.STRING_ORGANIZATION;
2052
- }
2053
- else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION_SET)) {
2054
- return InternalFieldType.STRING_ORGANIZATION_SET;
2055
- }
2056
- else if (type === 'string' && _classifications.has(Classification.STRING_CATALOG)) {
2057
- return InternalFieldType.STRING_CATALOG;
2058
- }
2059
- else if (type === 'boolean' && _classifications.has(Classification.BOOLEAN_SWITCH)) {
2060
- return InternalFieldType.BOOLEAN_SWITCH;
2061
- }
2062
- else if (type === 'string' &&
2063
- (_classifications.has(Classification.STRING_CATALOG_DYNAMIC) || _classifications.has(Classification.STRING_CATALOG_CUSTOM))) {
2064
- return InternalFieldType.STRING_DYNAMIC_CATALOG;
2065
- }
2066
- else {
2067
- // if there are no matching conditions just return the original type
2068
- return type;
2100
+ #dateRangeValueToSearchFilter(rv, property) {
2101
+ const v1 = rv.firstValue.toISOString();
2102
+ const v2 = rv.secondValue ? rv.secondValue.toISOString() : undefined;
2103
+ let filter;
2104
+ switch (rv.operator) {
2105
+ case Operator.EQUAL: {
2106
+ filter = {
2107
+ f: property,
2108
+ o: Operator.INTERVAL_INCLUDE_BOTH,
2109
+ v1: v1.split('T')[0] + 'T00:00:00.000',
2110
+ v2: v1.split('T')[0] + 'T23:59:59.000'
2111
+ };
2112
+ break;
2113
+ }
2114
+ case Operator.GREATER_OR_EQUAL: {
2115
+ filter = {
2116
+ f: property,
2117
+ o: rv.operator,
2118
+ v1: v1.split('T')[0] + 'T00:00:00.000'
2119
+ };
2120
+ break;
2121
+ }
2122
+ case Operator.LESS_OR_EQUAL: {
2123
+ filter = {
2124
+ f: property,
2125
+ o: rv.operator,
2126
+ v1: v1.split('T')[0] + 'T23:59:59.000'
2127
+ };
2128
+ break;
2129
+ }
2130
+ case Operator.INTERVAL_INCLUDE_BOTH: {
2131
+ filter = {
2132
+ f: property,
2133
+ o: rv.operator,
2134
+ v1: v1.split('T')[0] + 'T00:00:00.000',
2135
+ v2: v2.split('T')[0] + 'T23:59:59.000'
2136
+ };
2137
+ break;
2138
+ }
2069
2139
  }
2140
+ return filter;
2070
2141
  }
2071
- getObjectTypeField(id) {
2072
- const f = this.system?.allFields[id];
2073
- return f ? { ...f, _internalType: this.getInternalFormElementType(f.propertyType, f.classifications) } : undefined;
2142
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2143
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, providedIn: 'root' }); }
2144
+ }
2145
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, decorators: [{
2146
+ type: Injectable,
2147
+ args: [{
2148
+ providedIn: 'root'
2149
+ }]
2150
+ }] });
2151
+
2152
+ var Direction;
2153
+ (function (Direction) {
2154
+ Direction["LTR"] = "ltr";
2155
+ Direction["RTL"] = "rtl";
2156
+ })(Direction || (Direction = {}));
2157
+
2158
+ /**
2159
+ * Service for providing triggered events
2160
+ */
2161
+ class EventService {
2162
+ constructor() {
2163
+ this.#eventSource = new Subject();
2164
+ this.event$ = this.#eventSource.asObservable();
2074
2165
  }
2166
+ #eventSource;
2075
2167
  /**
2076
- * Extract classifications from object type fields classification
2077
- * string. This string may contain more than one classification entry.
2078
- *
2079
- * Classification is a comma separated string that may contain additional
2080
- * properties related to on classification entry. Example:
2081
- *
2082
- * `id:reference[system:folder], email`
2083
- *
2084
- * @param classifications Object type fields classification property (schema)
2168
+ * Trigger an global event
2169
+ * @param type Type/key of the event
2170
+ * @param data Data to be send along with the event
2085
2171
  */
2086
- getClassifications(classifications) {
2087
- const res = new Map();
2088
- if (classifications) {
2089
- classifications.forEach((c) => {
2090
- const matches = c.match(/^([^\[]*)(\[(.*)\])?$/);
2091
- if (matches && matches.length) {
2092
- res.set(matches[1], {
2093
- classification: matches[1],
2094
- options: matches[3] ? matches[3].split(',').map((o) => o.trim()) : []
2095
- });
2096
- }
2097
- });
2098
- }
2099
- return res;
2100
- }
2101
- toFormElement(field) {
2102
- return { ...field, label: this.getLocalizedLabel(field.id), name: field.id, type: field.propertyType };
2103
- }
2104
- updateAuthData(data) {
2105
- this.authData = { ...this.authData, ...data };
2106
- this.#backend.setHeader('Accept-Language', this.authData.language);
2107
- return this.#appCache.setItem(this.#STORAGE_KEY_AUTH_DATA, this.authData);
2108
- }
2109
- updateLocalizations(iso) {
2110
- return this.updateAuthData({ language: iso }).pipe(switchMap(() => this.#fetchLocalizations()), tap((res) => {
2111
- this.system.i18n = res;
2112
- this.#appCache.setItem(this.#STORAGE_KEY, this.system).subscribe();
2113
- this.#systemSource.next(this.system);
2114
- }));
2115
- }
2116
- #fetchLocalizations() {
2117
- return this.#backend.get('/resources/text');
2172
+ trigger(type, data) {
2173
+ this.#eventSource.next({ type, data });
2118
2174
  }
2119
- fetchResources(id) {
2120
- return this.#backend
2121
- .batch([
2122
- { uri: `/system/resources/${id}`, base: ApiBase.core },
2123
- { uri: `/admin/resources/${id}`, base: ApiBase.core }
2124
- ])
2125
- .pipe(map(([global, tenant]) => ({ global, tenant })));
2175
+ /**
2176
+ * Listen on a triggered event
2177
+ * @param types Type/key of the event
2178
+ */
2179
+ on(...types) {
2180
+ return this.event$.pipe(filter((event) => event && !!types.find((t) => t === event.type)));
2126
2181
  }
2127
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2128
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, providedIn: 'root' }); }
2182
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2183
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, providedIn: 'root' }); }
2129
2184
  }
2130
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, decorators: [{
2185
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, decorators: [{
2131
2186
  type: Injectable,
2132
2187
  args: [{
2133
2188
  providedIn: 'root'
2134
2189
  }]
2135
2190
  }] });
2136
2191
 
2192
+ /**
2193
+ * Events emitted by parts of the application
2194
+ */
2195
+ var YuvEventType;
2196
+ (function (YuvEventType) {
2197
+ YuvEventType["LOGOUT"] = "yuv.user.logout";
2198
+ YuvEventType["CLIENT_LOCALE_CHANGED"] = "yuv.user.locale.client.changed";
2199
+ YuvEventType["DMS_OBJECT_LOADED"] = "yuv.dms.object.loaded";
2200
+ YuvEventType["DMS_OBJECT_CREATED"] = "yuv.dms.object.created";
2201
+ YuvEventType["DMS_OBJECT_DELETED"] = "yuv.dms.object.deleted";
2202
+ YuvEventType["DMS_OBJECT_UPDATED"] = "yuv.dms.object.updated";
2203
+ YuvEventType["DMS_OBJECTS_MOVED"] = "yuv.dms.objects.moved";
2204
+ })(YuvEventType || (YuvEventType = {}));
2205
+
2137
2206
  /**
2138
2207
  * Service providing user account configurations.
2139
2208
  */
@@ -2488,7 +2557,6 @@ class ObjectConfigService {
2488
2557
  #objectConfigs;
2489
2558
  // called on core init (auth.service -> initApp)
2490
2559
  init() {
2491
- console.log('ObjectConfigService.init', this.#user.getCurrentUser().userSettings);
2492
2560
  return this.#user.loadObjectConfig().pipe(tap$1((res) => {
2493
2561
  this.#getDefaultObjectConfig();
2494
2562
  this.#objectConfigs = res || {
@@ -2933,6 +3001,15 @@ class ClipboardService {
2933
3001
  }
2934
3002
  this.#clipboardSource.next(this.#clipboard);
2935
3003
  }
3004
+ async addToNavigatorClipBoard(data) {
3005
+ try {
3006
+ await navigator.clipboard.writeText(data);
3007
+ console.log('Text copied to clipboard');
3008
+ }
3009
+ catch (error) {
3010
+ console.error('Failed to copy text: ', error);
3011
+ }
3012
+ }
2936
3013
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ClipboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2937
3014
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ClipboardService, providedIn: 'root' }); }
2938
3015
  }
@@ -4140,6 +4217,208 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
4140
4217
  }]
4141
4218
  }] });
4142
4219
 
4220
+ /**
4221
+ * Service to manage retention for DMS objects. This service allows to set retention
4222
+ * for objects and revert retention if necessary/possible.
4223
+ */
4224
+ class RetentionService {
4225
+ #dms = inject(DmsService);
4226
+ /**
4227
+ * Set retention for given objects. This will add the retention SOT to the objects
4228
+ * and set the retention start and end date. If the retetion start date is in the
4229
+ * future, you can revert the retention until then by calling `revertRetention`.
4230
+ * @param dmsObjects The objects to set retention for
4231
+ * @param retentionStart Date when retention period should begin
4232
+ * @param retentionEnd Date when retention period should end
4233
+ * @param destructionDate Date when the object should be destroyed. This right now is just a
4234
+ * marker and has no effect on the object lifecycle.
4235
+ * @returns The updated objects
4236
+ */
4237
+ setRetention(dmsObjects, retentionStart, retentionEnd, destructionDate) {
4238
+ const payload = [];
4239
+ dmsObjects.forEach((o) => {
4240
+ const data = {
4241
+ [BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS]: [
4242
+ ...o.data[BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS],
4243
+ SystemSOT.DESTRUCTION_RETENTION
4244
+ ],
4245
+ [RetentionField.RETENTION_START]: retentionStart
4246
+ };
4247
+ if (retentionEnd)
4248
+ data[RetentionField.RETENTION_END] = retentionEnd;
4249
+ if (destructionDate)
4250
+ data[RetentionField.DESTRUCTION_DATE] = destructionDate;
4251
+ payload.push({ id: o.id, data });
4252
+ });
4253
+ return this.#dms.updateDmsObjects(payload);
4254
+ }
4255
+ getRetentionState(dmsObject) {
4256
+ const hasRetentionSOT = dmsObject.data[BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS].includes(SystemSOT.DESTRUCTION_RETENTION);
4257
+ if (hasRetentionSOT) {
4258
+ const now = new Date();
4259
+ const retentionStart = new Date(dmsObject.data[RetentionField.RETENTION_START]);
4260
+ const retentionEnd = dmsObject.data[RetentionField.RETENTION_END] ? new Date(dmsObject.data[RetentionField.RETENTION_END]) : null;
4261
+ const underRetention = !!(retentionStart < now || (retentionEnd && retentionEnd > now));
4262
+ return {
4263
+ underRetention,
4264
+ start: new Date(retentionStart),
4265
+ end: retentionEnd ? new Date(retentionEnd) : undefined
4266
+ };
4267
+ }
4268
+ else
4269
+ return { underRetention: false };
4270
+ }
4271
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RetentionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4272
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RetentionService, providedIn: 'root' }); }
4273
+ }
4274
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RetentionService, decorators: [{
4275
+ type: Injectable,
4276
+ args: [{
4277
+ providedIn: 'root'
4278
+ }]
4279
+ }] });
4280
+
4281
+ class SearchUtils {
4282
+ static { this.dateRanges = ['today', 'yesterday', 'thisWeek', 'lastWeek', 'thisMonth', 'lastMonth', 'thisYear', 'lastYear']; }
4283
+ static { this.filesizeRanges = ['small', 'medium', 'large', 'verylarge']; }
4284
+ static dateRangeStartEnd(dateRange) {
4285
+ let start;
4286
+ let end;
4287
+ switch (dateRange) {
4288
+ case 'today': {
4289
+ start = new Date();
4290
+ end = new Date();
4291
+ break;
4292
+ }
4293
+ case 'yesterday': {
4294
+ const yesterday = new Date();
4295
+ yesterday.setDate(yesterday.getDate() - 1);
4296
+ start = yesterday;
4297
+ end = yesterday;
4298
+ break;
4299
+ }
4300
+ case 'thisWeek': {
4301
+ const firstDay = new Date();
4302
+ firstDay.setDate(firstDay.getDate() - firstDay.getDay());
4303
+ start = firstDay;
4304
+ end = new Date();
4305
+ break;
4306
+ }
4307
+ case 'lastWeek': {
4308
+ const firstDay = new Date();
4309
+ firstDay.setDate(firstDay.getDate() - firstDay.getDay() - 7);
4310
+ const lastDay = new Date();
4311
+ lastDay.setDate(lastDay.getDate() - lastDay.getDay() - 1);
4312
+ start = firstDay;
4313
+ end = lastDay;
4314
+ break;
4315
+ }
4316
+ case 'thisMonth': {
4317
+ const firstDay = new Date();
4318
+ firstDay.setDate(1);
4319
+ start = firstDay;
4320
+ end = new Date();
4321
+ break;
4322
+ }
4323
+ case 'lastMonth': {
4324
+ const firstDay = new Date();
4325
+ firstDay.setDate(1);
4326
+ firstDay.setMonth(firstDay.getMonth() - 1);
4327
+ const lastDay = new Date();
4328
+ lastDay.setDate(0);
4329
+ start = firstDay;
4330
+ end = lastDay;
4331
+ break;
4332
+ }
4333
+ case 'thisYear': {
4334
+ const firstDay = new Date();
4335
+ firstDay.setMonth(0);
4336
+ firstDay.setDate(1);
4337
+ start = firstDay;
4338
+ end = new Date();
4339
+ break;
4340
+ }
4341
+ case 'lastYear': {
4342
+ const firstDay = new Date();
4343
+ firstDay.setFullYear(firstDay.getFullYear() - 1);
4344
+ firstDay.setMonth(0);
4345
+ firstDay.setDate(1);
4346
+ const lastDay = new Date();
4347
+ lastDay.setFullYear(lastDay.getFullYear() - 1);
4348
+ lastDay.setMonth(11);
4349
+ lastDay.setDate(31);
4350
+ start = firstDay;
4351
+ end = lastDay;
4352
+ break;
4353
+ }
4354
+ }
4355
+ return { start, end };
4356
+ }
4357
+ /**
4358
+ * Maps a date range filter to a date range value like 'thisWeek', 'lastMonth', etc.
4359
+ * @param rangeValue the range value
4360
+ * @returns the date range (eg. 'thisWeek', 'lastMonth', etc.)
4361
+ */
4362
+ static getMatchingDateRange(rangeValue) {
4363
+ return SearchUtils.dateRanges.find((dateRange) => {
4364
+ const { start, end } = SearchUtils.dateRangeStartEnd(dateRange);
4365
+ return (rangeValue.firstValue === start.toISOString().split('T')[0] + 'T00:00:00.000' &&
4366
+ rangeValue.secondValue === end.toISOString().split('T')[0] + 'T23:59:59.000');
4367
+ });
4368
+ }
4369
+ // Files size ranges
4370
+ static getMatchingFilesizeRange(rangeValue) {
4371
+ let filesizeRange = undefined;
4372
+ if (rangeValue.operator === Operator.INTERVAL_INCLUDE_BOTH) {
4373
+ if (rangeValue.firstValue === 1024 * 1024 && rangeValue.secondValue === 1024 * 1024 * 10)
4374
+ filesizeRange = 'medium';
4375
+ else if (rangeValue.firstValue === 1024 * 1024 * 10 && rangeValue.secondValue === 1024 * 1024 * 100)
4376
+ filesizeRange = 'large';
4377
+ }
4378
+ else if (rangeValue.operator === Operator.LESS_THAN) {
4379
+ if (rangeValue.firstValue === 1024 * 1024)
4380
+ filesizeRange = 'small';
4381
+ }
4382
+ else if (rangeValue.operator === Operator.GREATER_THAN) {
4383
+ if (rangeValue.firstValue === 1024 * 1024 * 100)
4384
+ filesizeRange = 'verylarge';
4385
+ }
4386
+ return filesizeRange;
4387
+ }
4388
+ static filesizeRangeToRangeValue(filesizeRange) {
4389
+ let rv = undefined;
4390
+ switch (filesizeRange) {
4391
+ case 'small':
4392
+ rv = {
4393
+ operator: Operator.LESS_THAN,
4394
+ firstValue: 1024 * 1024
4395
+ };
4396
+ break;
4397
+ case 'medium':
4398
+ rv = {
4399
+ operator: Operator.INTERVAL_INCLUDE_BOTH,
4400
+ firstValue: 1024 * 1024,
4401
+ secondValue: 1024 * 1024 * 10
4402
+ };
4403
+ break;
4404
+ case 'large':
4405
+ rv = {
4406
+ operator: Operator.INTERVAL_INCLUDE_BOTH,
4407
+ firstValue: 1024 * 1024 * 10,
4408
+ secondValue: 1024 * 1024 * 100
4409
+ };
4410
+ break;
4411
+ case 'verylarge':
4412
+ rv = {
4413
+ operator: Operator.GREATER_THAN,
4414
+ firstValue: 1024 * 1024 * 100
4415
+ };
4416
+ break;
4417
+ }
4418
+ return rv;
4419
+ }
4420
+ }
4421
+
4143
4422
  class SessionStorageService {
4144
4423
  #TEMP_STORAGE_ENTRIES_KEY = 'yuv.core.sessionstorage.entries';
4145
4424
  constructor() {
@@ -4188,6 +4467,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
4188
4467
  }]
4189
4468
  }], ctorParameters: () => [] });
4190
4469
 
4470
+ /**
4471
+ * Service providing user related remote storage. This service is used load and
4472
+ * store user related data from any device.
4473
+ */
4474
+ class UserStorageService {
4475
+ #backend = inject(BackendService);
4476
+ #USERS_SETTINGS = '/users/settings';
4477
+ // prefix to be added to every section key to be able to later distinguish
4478
+ // between user settings and other settings
4479
+ #SECTION_PREFIX = 'x-user-';
4480
+ /**
4481
+ *
4482
+ * @param section section key for
4483
+ * @param value value to be stored
4484
+ */
4485
+ getItem(section) {
4486
+ return this.#backend.get(`${this.#USERS_SETTINGS}/${this.#sanitizeSection(this.#SECTION_PREFIX + section)}`);
4487
+ }
4488
+ setItem(section, data) {
4489
+ return this.getItem(section).pipe(switchMap$1((current) => this.#backend.post(`${this.#USERS_SETTINGS}/${this.#sanitizeSection(this.#SECTION_PREFIX + section)}`, { ...current, ...data })));
4490
+ }
4491
+ #sanitizeSection(section) {
4492
+ return encodeURIComponent(section);
4493
+ }
4494
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UserStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4495
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UserStorageService, providedIn: 'root' }); }
4496
+ }
4497
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UserStorageService, decorators: [{
4498
+ type: Injectable,
4499
+ args: [{
4500
+ providedIn: 'root'
4501
+ }]
4502
+ }] });
4503
+
4191
4504
  /**
4192
4505
  * Prevent app from running into 401 issues related to gateway timeouts.
4193
4506
  */
@@ -4771,5 +5084,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
4771
5084
  * Generated bundle index. Do not edit.
4772
5085
  */
4773
5086
 
4774
- export { AFO_STATE, AdministrationRoles, ApiBase, AppCacheService, AuditField, AuditService, AuthService, BackendService, BaseObjectTypeField, BpmService, CORE_CONFIG, CUSTOM_CONFIG, CatalogService, Classification, ClassificationPrefix, ClientDefaultsObjectTypeField, ClipboardService, ColumnConfigSkipFields, ConfigService, ConnectionService, ContentStreamAllowed, ContentStreamField, CoreConfig, DeviceScreenOrientation, DeviceService, Direction, DmsObject, DmsService, EventService, FileSizePipe, IdmService, InternalFieldType, KeysPipe, LocaleCurrencyPipe, LocaleDatePipe, LocaleDecimalPipe, LocaleNumberPipe, LocalePercentPipe, Logger, LoginStateName, NativeNotificationService, NotificationService, ObjectConfigService, ObjectTag, ObjectTypeClassification, ObjectTypePropertyClassification, OidcService, Operator, OperatorLabel, ParentField, PendingChangesGuard, PendingChangesService, PredictionService, ProcessAction, RetentionField, RetentionState, SafeHtmlPipe, SafeUrlPipe, SearchService, SecondaryObjectTypeClassification, SessionStorageService, Situation, Sort, SystemResult, SystemSOT, SystemService, SystemType, TENANT_HEADER, UploadService, UserRoles, UserService, Utils, YuvClientCoreModule, YuvClientCoreSharedModule, YuvError, YuvEventType, YuvUser, init_moduleFnc, storageFactory };
5087
+ export { AFO_STATE, AdministrationRoles, ApiBase, AppCacheService, AuditField, AuditService, AuthService, BackendService, BaseObjectTypeField, BpmService, CORE_CONFIG, CUSTOM_CONFIG, CatalogService, Classification, ClassificationPrefix, ClientDefaultsObjectTypeField, ClipboardService, ColumnConfigSkipFields, ConfigService, ConnectionService, ContentStreamAllowed, ContentStreamField, CoreConfig, DeviceScreenOrientation, DeviceService, Direction, DmsObject, DmsService, EventService, FileSizePipe, IdmService, InternalFieldType, KeysPipe, LocaleCurrencyPipe, LocaleDatePipe, LocaleDecimalPipe, LocaleNumberPipe, LocalePercentPipe, Logger, LoginStateName, NativeNotificationService, NotificationService, ObjectConfigService, ObjectTag, ObjectTypeClassification, ObjectTypePropertyClassification, OidcService, Operator, OperatorLabel, ParentField, PendingChangesGuard, PendingChangesService, PredictionService, ProcessAction, RetentionField, RetentionService, SafeHtmlPipe, SafeUrlPipe, SearchService, SearchUtils, SecondaryObjectTypeClassification, SessionStorageService, Situation, Sort, SystemResult, SystemSOT, SystemService, SystemType, TENANT_HEADER, UploadService, UserRoles, UserService, UserStorageService, Utils, YuvClientCoreModule, YuvClientCoreSharedModule, YuvError, YuvEventType, YuvUser, init_moduleFnc, storageFactory };
4775
5088
  //# sourceMappingURL=yuuvis-client-core.mjs.map