@yuuvis/client-core 0.7.3 → 0.8.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.
- package/esm2022/index.mjs +2 -1
- package/esm2022/lib/service/object-config/object-config.service.mjs +1 -2
- package/esm2022/lib/service/search/search.service.interface.mjs +1 -1
- package/esm2022/lib/service/search/search.service.mjs +84 -1
- package/esm2022/lib/service/search/search.utils.mjs +142 -0
- package/esm2022/lib/service/system/system.service.mjs +1 -1
- package/fesm2022/yuuvis-client-core.mjs +548 -327
- package/fesm2022/yuuvis-client-core.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/service/search/search.service.d.ts +10 -1
- package/lib/service/search/search.service.interface.d.ts +3 -1
- package/lib/service/search/search.utils.d.ts +18 -0
- package/package.json +1 -1
|
@@ -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,
|
|
8
|
-
import { EMPTY, of, from, Observable, forkJoin,
|
|
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 } 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';
|
|
@@ -1235,179 +1235,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
1235
1235
|
args: [{ providedIn: 'root' }]
|
|
1236
1236
|
}] });
|
|
1237
1237
|
|
|
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
1238
|
var Operator;
|
|
1412
1239
|
(function (Operator) {
|
|
1413
1240
|
Operator["EQUAL"] = "eq";
|
|
@@ -1447,60 +1274,6 @@ const OperatorLabel = {
|
|
|
1447
1274
|
CONTAINS: '~' // contains
|
|
1448
1275
|
};
|
|
1449
1276
|
|
|
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
1277
|
/**
|
|
1505
1278
|
* Service for saving or caching data on the users device. It uses the most efficient storage
|
|
1506
1279
|
* available (IndexDB, localstorage, ...) on the device. Depending on the type of storage used,
|
|
@@ -2019,121 +1792,429 @@ class SystemService {
|
|
|
2019
1792
|
return this.#backend.get(Utils.buildUri(`/dms/forms/${objectTypeId}`, { situation }));
|
|
2020
1793
|
}
|
|
2021
1794
|
/**
|
|
2022
|
-
* Check whether or not the model has at least one form element. Recursive.
|
|
2023
|
-
* @param element Form element to check child elements for
|
|
1795
|
+
* Check whether or not the model has at least one form element. Recursive.
|
|
1796
|
+
* @param element Form element to check child elements for
|
|
1797
|
+
*/
|
|
1798
|
+
#formHasElements(element) {
|
|
1799
|
+
let hasElement = false;
|
|
1800
|
+
element.elements?.forEach((e) => {
|
|
1801
|
+
if (!['o2mGroup', 'o2mGroupStack'].includes(e.type)) {
|
|
1802
|
+
hasElement = true;
|
|
1803
|
+
}
|
|
1804
|
+
else if (!hasElement) {
|
|
1805
|
+
hasElement = this.#formHasElements(e);
|
|
1806
|
+
}
|
|
1807
|
+
});
|
|
1808
|
+
return hasElement;
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Generates an internal type for a given object type field.
|
|
1812
|
+
* Adding this to a form element or object type field enables us to render forms
|
|
1813
|
+
* based on object type fields in a more performant way. Otherwise we would
|
|
1814
|
+
* have to evaluate the conditions for every form element on every digest cycle.
|
|
1815
|
+
* @param type propertyType of the ObjectTypeField
|
|
1816
|
+
* @param classifications classifications of the ObjectTypeField
|
|
1817
|
+
*/
|
|
1818
|
+
getInternalFormElementType(type, classifications) {
|
|
1819
|
+
const _classifications = this.getClassifications(classifications || []);
|
|
1820
|
+
if (type === 'string' && _classifications.has(Classification.STRING_REFERENCE)) {
|
|
1821
|
+
return InternalFieldType.STRING_REFERENCE;
|
|
1822
|
+
}
|
|
1823
|
+
else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION)) {
|
|
1824
|
+
return InternalFieldType.STRING_ORGANIZATION;
|
|
1825
|
+
}
|
|
1826
|
+
else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION_SET)) {
|
|
1827
|
+
return InternalFieldType.STRING_ORGANIZATION_SET;
|
|
1828
|
+
}
|
|
1829
|
+
else if (type === 'string' && _classifications.has(Classification.STRING_CATALOG)) {
|
|
1830
|
+
return InternalFieldType.STRING_CATALOG;
|
|
1831
|
+
}
|
|
1832
|
+
else if (type === 'boolean' && _classifications.has(Classification.BOOLEAN_SWITCH)) {
|
|
1833
|
+
return InternalFieldType.BOOLEAN_SWITCH;
|
|
1834
|
+
}
|
|
1835
|
+
else if (type === 'string' &&
|
|
1836
|
+
(_classifications.has(Classification.STRING_CATALOG_DYNAMIC) || _classifications.has(Classification.STRING_CATALOG_CUSTOM))) {
|
|
1837
|
+
return InternalFieldType.STRING_DYNAMIC_CATALOG;
|
|
1838
|
+
}
|
|
1839
|
+
else {
|
|
1840
|
+
// if there are no matching conditions just return the original type
|
|
1841
|
+
return type;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
getObjectTypeField(id) {
|
|
1845
|
+
const f = this.system?.allFields[id];
|
|
1846
|
+
return f ? { ...f, _internalType: this.getInternalFormElementType(f.propertyType, f.classifications) } : undefined;
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Extract classifications from object type fields classification
|
|
1850
|
+
* string. This string may contain more than one classification entry.
|
|
1851
|
+
*
|
|
1852
|
+
* Classification is a comma separated string that may contain additional
|
|
1853
|
+
* properties related to on classification entry. Example:
|
|
1854
|
+
*
|
|
1855
|
+
* `id:reference[system:folder], email`
|
|
1856
|
+
*
|
|
1857
|
+
* @param classifications Object type fields classification property (schema)
|
|
1858
|
+
*/
|
|
1859
|
+
getClassifications(classifications) {
|
|
1860
|
+
const res = new Map();
|
|
1861
|
+
if (classifications) {
|
|
1862
|
+
classifications.forEach((c) => {
|
|
1863
|
+
const matches = c.match(/^([^\[]*)(\[(.*)\])?$/);
|
|
1864
|
+
if (matches && matches.length) {
|
|
1865
|
+
res.set(matches[1], {
|
|
1866
|
+
classification: matches[1],
|
|
1867
|
+
options: matches[3] ? matches[3].split(',').map((o) => o.trim()) : []
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
return res;
|
|
1873
|
+
}
|
|
1874
|
+
toFormElement(field) {
|
|
1875
|
+
return { ...field, label: this.getLocalizedLabel(field.id), name: field.id, type: field.propertyType };
|
|
1876
|
+
}
|
|
1877
|
+
updateAuthData(data) {
|
|
1878
|
+
this.authData = { ...this.authData, ...data };
|
|
1879
|
+
this.#backend.setHeader('Accept-Language', this.authData.language);
|
|
1880
|
+
return this.#appCache.setItem(this.#STORAGE_KEY_AUTH_DATA, this.authData);
|
|
1881
|
+
}
|
|
1882
|
+
updateLocalizations(iso) {
|
|
1883
|
+
return this.updateAuthData({ language: iso }).pipe(switchMap(() => this.#fetchLocalizations()), tap((res) => {
|
|
1884
|
+
this.system.i18n = res;
|
|
1885
|
+
this.#appCache.setItem(this.#STORAGE_KEY, this.system).subscribe();
|
|
1886
|
+
this.#systemSource.next(this.system);
|
|
1887
|
+
}));
|
|
1888
|
+
}
|
|
1889
|
+
#fetchLocalizations() {
|
|
1890
|
+
return this.#backend.get('/resources/text');
|
|
1891
|
+
}
|
|
1892
|
+
fetchResources(id) {
|
|
1893
|
+
return this.#backend
|
|
1894
|
+
.batch([
|
|
1895
|
+
{ uri: `/system/resources/${id}`, base: ApiBase.core },
|
|
1896
|
+
{ uri: `/admin/resources/${id}`, base: ApiBase.core }
|
|
1897
|
+
])
|
|
1898
|
+
.pipe(map(([global, tenant]) => ({ global, tenant })));
|
|
1899
|
+
}
|
|
1900
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1901
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, providedIn: 'root' }); }
|
|
1902
|
+
}
|
|
1903
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, decorators: [{
|
|
1904
|
+
type: Injectable,
|
|
1905
|
+
args: [{
|
|
1906
|
+
providedIn: 'root'
|
|
1907
|
+
}]
|
|
1908
|
+
}] });
|
|
1909
|
+
|
|
1910
|
+
class SearchService {
|
|
1911
|
+
#backend = inject(BackendService);
|
|
1912
|
+
#system = inject(SystemService);
|
|
1913
|
+
static { this.DEFAULT_QUERY_SIZE = 50; }
|
|
1914
|
+
/**
|
|
1915
|
+
* Execute a search query ans transform the result to a SearchResult object
|
|
1916
|
+
* @param query The search query
|
|
1917
|
+
* @returns Observable of a SearchResult
|
|
1918
|
+
*/
|
|
1919
|
+
search(query) {
|
|
1920
|
+
return this.searchRaw(query).pipe(map((res) => this.toSearchResult(res)));
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Execute a raw search query and return the result as is.
|
|
1924
|
+
* @param query The search query
|
|
1925
|
+
* @returns Observable of the raw search result
|
|
1926
|
+
*/
|
|
1927
|
+
searchRaw(query) {
|
|
1928
|
+
if (!query.size)
|
|
1929
|
+
query.size = SearchService.DEFAULT_QUERY_SIZE;
|
|
1930
|
+
return this.#backend.post(`/dms/objects/search`, query);
|
|
1931
|
+
}
|
|
1932
|
+
/**
|
|
1933
|
+
* Search for objects in the dms using CMIS like SQL syntax.
|
|
1934
|
+
* @param statement The query statement
|
|
1935
|
+
* @param size The number of items to return
|
|
1936
|
+
* @returns Observable of a SearchResult
|
|
1937
|
+
*/
|
|
1938
|
+
searchCmis(statement, size = 50) {
|
|
1939
|
+
return this.#backend
|
|
1940
|
+
.post('/dms/objects/search', {
|
|
1941
|
+
query: {
|
|
1942
|
+
statement,
|
|
1943
|
+
skipCount: 0,
|
|
1944
|
+
maxItems: size,
|
|
1945
|
+
handleDeletedDocuments: 'DELETED_DOCUMENTS_EXCLUDE'
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
// Using API-WEB because it enriches the response with additional information (resolved user names, etc.)
|
|
1949
|
+
// ApiBase.core
|
|
1950
|
+
)
|
|
1951
|
+
.pipe(map((res) => this.toSearchResult(res)));
|
|
1952
|
+
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Fetch aggragations for a given query.
|
|
1955
|
+
* @param q The query
|
|
1956
|
+
* @param aggregations List of aggregations to be fetched (e.g. `enaio:objectTypeId`
|
|
1957
|
+
* to get an aggregation of object types)
|
|
1958
|
+
*/
|
|
1959
|
+
aggregate(q, aggregations) {
|
|
1960
|
+
q.aggs = aggregations;
|
|
1961
|
+
return this.searchRaw(q).pipe(map((res) => this.#toAggregateResult(res, aggregations)));
|
|
1962
|
+
}
|
|
1963
|
+
/**
|
|
1964
|
+
* Map search result from the backend to applications AggregateResult object
|
|
1965
|
+
* @param searchResponse The backend response
|
|
1966
|
+
* @param aggregations The aggregations to be fetched
|
|
1967
|
+
*/
|
|
1968
|
+
#toAggregateResult(searchResponse, aggregations) {
|
|
1969
|
+
const agg = [];
|
|
1970
|
+
if (aggregations) {
|
|
1971
|
+
aggregations.forEach((a) => {
|
|
1972
|
+
const ag = {
|
|
1973
|
+
aggKey: a,
|
|
1974
|
+
entries: searchResponse.objects.map((o) => ({
|
|
1975
|
+
key: o.properties[a].value,
|
|
1976
|
+
count: o.properties['OBJECT_COUNT'].value
|
|
1977
|
+
}))
|
|
1978
|
+
};
|
|
1979
|
+
agg.push(ag);
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
return {
|
|
1983
|
+
totalNumItems: searchResponse.totalNumItems,
|
|
1984
|
+
aggregations: agg
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
/**
|
|
1988
|
+
* Go to a page of a search result.
|
|
1989
|
+
* @param searchResult The search result (that supports pagination)
|
|
1990
|
+
* @param page The number of the page to go to
|
|
1991
|
+
*/
|
|
1992
|
+
getPage(query, page) {
|
|
1993
|
+
query.from = (page - 1) * (query.size || SearchService.DEFAULT_QUERY_SIZE);
|
|
1994
|
+
return this.search(query);
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* Map search result from the backend to applications SearchResult object
|
|
1998
|
+
* @param searchResponse The backend response
|
|
1999
|
+
*/
|
|
2000
|
+
toSearchResult(searchResponse) {
|
|
2001
|
+
const resultListItems = [];
|
|
2002
|
+
const objectTypes = [];
|
|
2003
|
+
searchResponse.objects.forEach((o) => {
|
|
2004
|
+
const fields = new Map();
|
|
2005
|
+
// process properties section of result
|
|
2006
|
+
Object.keys(o.properties).forEach((key) => {
|
|
2007
|
+
let value = o.properties[key].value;
|
|
2008
|
+
if (o.properties[key].clvalue) {
|
|
2009
|
+
// table fields will have a clientValue too ...
|
|
2010
|
+
value = o.properties[key].clvalue;
|
|
2011
|
+
// ... and also may contain values that need to be resolved
|
|
2012
|
+
if (o.properties[key].resolvedValues) {
|
|
2013
|
+
value.forEach((v) => {
|
|
2014
|
+
Object.keys(v).forEach((k) => {
|
|
2015
|
+
const resValue = Array.isArray(v[k]) ? v[k].map((i) => o.properties[key].resolvedValues[i]) : o.properties[key].resolvedValues[v[k]];
|
|
2016
|
+
if (resValue) {
|
|
2017
|
+
v[`${k}_title`] = resValue;
|
|
2018
|
+
}
|
|
2019
|
+
});
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
fields.set(key, value);
|
|
2024
|
+
if (o.properties[key].title) {
|
|
2025
|
+
fields.set(key + '_title', o.properties[key].title);
|
|
2026
|
+
}
|
|
2027
|
+
});
|
|
2028
|
+
// process contentStreams section of result if available.
|
|
2029
|
+
// Objects that don't have files attached won't have this section
|
|
2030
|
+
let content;
|
|
2031
|
+
if (o.contentStreams && o.contentStreams.length > 0) {
|
|
2032
|
+
// we assume that each result object only has ONE file attached, altough
|
|
2033
|
+
// this is an array and there may be more
|
|
2034
|
+
const contentStream = o.contentStreams[0];
|
|
2035
|
+
// also add contentstream related fields to the result fields
|
|
2036
|
+
fields.set(ContentStreamField.LENGTH, contentStream.length);
|
|
2037
|
+
fields.set(ContentStreamField.MIME_TYPE, contentStream.mimeType);
|
|
2038
|
+
fields.set(ContentStreamField.FILENAME, contentStream.fileName);
|
|
2039
|
+
fields.set(ContentStreamField.ID, contentStream.contentStreamId);
|
|
2040
|
+
fields.set(ContentStreamField.RANGE, contentStream.contentStreamRange);
|
|
2041
|
+
fields.set(ContentStreamField.REPOSITORY_ID, contentStream.repositoryId);
|
|
2042
|
+
fields.set(ContentStreamField.DIGEST, contentStream.digest);
|
|
2043
|
+
fields.set(ContentStreamField.ARCHIVE_PATH, contentStream.archivePath);
|
|
2044
|
+
content = {
|
|
2045
|
+
contentStreamId: contentStream.contentStreamId,
|
|
2046
|
+
repositoryId: contentStream.repositoryId,
|
|
2047
|
+
range: contentStream.range,
|
|
2048
|
+
digest: contentStream.digest,
|
|
2049
|
+
archivePath: contentStream.archivePath,
|
|
2050
|
+
fileName: contentStream.fileName,
|
|
2051
|
+
mimeType: contentStream.mimeType,
|
|
2052
|
+
size: contentStream.length
|
|
2053
|
+
};
|
|
2054
|
+
}
|
|
2055
|
+
const objectTypeId = o.properties[BaseObjectTypeField.OBJECT_TYPE_ID] ? o.properties[BaseObjectTypeField.OBJECT_TYPE_ID].value : null;
|
|
2056
|
+
if (objectTypes.indexOf(objectTypeId) === -1) {
|
|
2057
|
+
objectTypes.push(objectTypeId);
|
|
2058
|
+
}
|
|
2059
|
+
resultListItems.push({
|
|
2060
|
+
objectTypeId,
|
|
2061
|
+
content,
|
|
2062
|
+
fields,
|
|
2063
|
+
permissions: o.permissions
|
|
2064
|
+
});
|
|
2065
|
+
});
|
|
2066
|
+
const result = {
|
|
2067
|
+
hasMoreItems: searchResponse.hasMoreItems,
|
|
2068
|
+
totalNumItems: searchResponse.totalNumItems,
|
|
2069
|
+
items: resultListItems,
|
|
2070
|
+
objectTypes
|
|
2071
|
+
};
|
|
2072
|
+
return result;
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Maps data extracted from a search form to search filters. Every key of the form data object
|
|
2076
|
+
* will be mapped to a search filter.
|
|
2077
|
+
* @param formData form data
|
|
2078
|
+
* @returns Array of search filters
|
|
2024
2079
|
*/
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2080
|
+
formDataToSearchFilter(formData) {
|
|
2081
|
+
const isRangeValue = (v) => {
|
|
2082
|
+
return typeof v === 'object' && v !== null && 'firstValue' in v && 'operator' in v;
|
|
2083
|
+
};
|
|
2084
|
+
const filters = [];
|
|
2085
|
+
Object.keys(formData).forEach((key) => {
|
|
2086
|
+
const value = formData[key];
|
|
2087
|
+
if (isRangeValue(value)) {
|
|
2088
|
+
const f = this.rangeValueToSearchFilter(value, key);
|
|
2089
|
+
if (f)
|
|
2090
|
+
filters.push(f);
|
|
2030
2091
|
}
|
|
2031
|
-
else
|
|
2032
|
-
|
|
2092
|
+
else {
|
|
2093
|
+
filters.push({
|
|
2094
|
+
f: key,
|
|
2095
|
+
o: Array.isArray(value) ? Operator.IN : Operator.EQUAL,
|
|
2096
|
+
v1: value
|
|
2097
|
+
});
|
|
2033
2098
|
}
|
|
2034
2099
|
});
|
|
2035
|
-
return
|
|
2100
|
+
return filters;
|
|
2101
|
+
}
|
|
2102
|
+
rangeValueToSearchFilter(value, property) {
|
|
2103
|
+
return this.#system.getObjectTypeField(property)?.propertyType === 'datetime'
|
|
2104
|
+
? this.#dateRangeValueToSearchFilter(value, property)
|
|
2105
|
+
: {
|
|
2106
|
+
f: property,
|
|
2107
|
+
o: value.operator,
|
|
2108
|
+
v1: value.firstValue,
|
|
2109
|
+
v2: value.secondValue
|
|
2110
|
+
};
|
|
2036
2111
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2112
|
+
#dateRangeValueToSearchFilter(rv, property) {
|
|
2113
|
+
const v1 = rv.firstValue.toISOString();
|
|
2114
|
+
const v2 = rv.secondValue ? rv.secondValue.toISOString() : undefined;
|
|
2115
|
+
let filter;
|
|
2116
|
+
switch (rv.operator) {
|
|
2117
|
+
case Operator.EQUAL: {
|
|
2118
|
+
filter = {
|
|
2119
|
+
f: property,
|
|
2120
|
+
o: Operator.INTERVAL_INCLUDE_BOTH,
|
|
2121
|
+
v1: v1.split('T')[0] + 'T00:00:00.000',
|
|
2122
|
+
v2: v1.split('T')[0] + 'T23:59:59.000'
|
|
2123
|
+
};
|
|
2124
|
+
break;
|
|
2125
|
+
}
|
|
2126
|
+
case Operator.GREATER_OR_EQUAL: {
|
|
2127
|
+
filter = {
|
|
2128
|
+
f: property,
|
|
2129
|
+
o: rv.operator,
|
|
2130
|
+
v1: v1.split('T')[0] + 'T00:00:00.000'
|
|
2131
|
+
};
|
|
2132
|
+
break;
|
|
2133
|
+
}
|
|
2134
|
+
case Operator.LESS_OR_EQUAL: {
|
|
2135
|
+
filter = {
|
|
2136
|
+
f: property,
|
|
2137
|
+
o: rv.operator,
|
|
2138
|
+
v1: v1.split('T')[0] + 'T23:59:59.000'
|
|
2139
|
+
};
|
|
2140
|
+
break;
|
|
2141
|
+
}
|
|
2142
|
+
case Operator.INTERVAL_INCLUDE_BOTH: {
|
|
2143
|
+
filter = {
|
|
2144
|
+
f: property,
|
|
2145
|
+
o: rv.operator,
|
|
2146
|
+
v1: v1.split('T')[0] + 'T00:00:00.000',
|
|
2147
|
+
v2: v2.split('T')[0] + 'T23:59:59.000'
|
|
2148
|
+
};
|
|
2149
|
+
break;
|
|
2150
|
+
}
|
|
2069
2151
|
}
|
|
2152
|
+
return filter;
|
|
2070
2153
|
}
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2154
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2155
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, providedIn: 'root' }); }
|
|
2156
|
+
}
|
|
2157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchService, decorators: [{
|
|
2158
|
+
type: Injectable,
|
|
2159
|
+
args: [{
|
|
2160
|
+
providedIn: 'root'
|
|
2161
|
+
}]
|
|
2162
|
+
}] });
|
|
2163
|
+
|
|
2164
|
+
var Direction;
|
|
2165
|
+
(function (Direction) {
|
|
2166
|
+
Direction["LTR"] = "ltr";
|
|
2167
|
+
Direction["RTL"] = "rtl";
|
|
2168
|
+
})(Direction || (Direction = {}));
|
|
2169
|
+
|
|
2170
|
+
/**
|
|
2171
|
+
* Service for providing triggered events
|
|
2172
|
+
*/
|
|
2173
|
+
class EventService {
|
|
2174
|
+
constructor() {
|
|
2175
|
+
this.#eventSource = new Subject();
|
|
2176
|
+
this.event$ = this.#eventSource.asObservable();
|
|
2074
2177
|
}
|
|
2178
|
+
#eventSource;
|
|
2075
2179
|
/**
|
|
2076
|
-
*
|
|
2077
|
-
*
|
|
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)
|
|
2180
|
+
* Trigger an global event
|
|
2181
|
+
* @param type Type/key of the event
|
|
2182
|
+
* @param data Data to be send along with the event
|
|
2085
2183
|
*/
|
|
2086
|
-
|
|
2087
|
-
|
|
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');
|
|
2184
|
+
trigger(type, data) {
|
|
2185
|
+
this.#eventSource.next({ type, data });
|
|
2118
2186
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
.pipe(map(([global, tenant]) => ({ global, tenant })));
|
|
2187
|
+
/**
|
|
2188
|
+
* Listen on a triggered event
|
|
2189
|
+
* @param types Type/key of the event
|
|
2190
|
+
*/
|
|
2191
|
+
on(...types) {
|
|
2192
|
+
return this.event$.pipe(filter((event) => event && !!types.find((t) => t === event.type)));
|
|
2126
2193
|
}
|
|
2127
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type:
|
|
2128
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type:
|
|
2194
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2195
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, providedIn: 'root' }); }
|
|
2129
2196
|
}
|
|
2130
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type:
|
|
2197
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: EventService, decorators: [{
|
|
2131
2198
|
type: Injectable,
|
|
2132
2199
|
args: [{
|
|
2133
2200
|
providedIn: 'root'
|
|
2134
2201
|
}]
|
|
2135
2202
|
}] });
|
|
2136
2203
|
|
|
2204
|
+
/**
|
|
2205
|
+
* Events emitted by parts of the application
|
|
2206
|
+
*/
|
|
2207
|
+
var YuvEventType;
|
|
2208
|
+
(function (YuvEventType) {
|
|
2209
|
+
YuvEventType["LOGOUT"] = "yuv.user.logout";
|
|
2210
|
+
YuvEventType["CLIENT_LOCALE_CHANGED"] = "yuv.user.locale.client.changed";
|
|
2211
|
+
YuvEventType["DMS_OBJECT_LOADED"] = "yuv.dms.object.loaded";
|
|
2212
|
+
YuvEventType["DMS_OBJECT_CREATED"] = "yuv.dms.object.created";
|
|
2213
|
+
YuvEventType["DMS_OBJECT_DELETED"] = "yuv.dms.object.deleted";
|
|
2214
|
+
YuvEventType["DMS_OBJECT_UPDATED"] = "yuv.dms.object.updated";
|
|
2215
|
+
YuvEventType["DMS_OBJECTS_MOVED"] = "yuv.dms.objects.moved";
|
|
2216
|
+
})(YuvEventType || (YuvEventType = {}));
|
|
2217
|
+
|
|
2137
2218
|
/**
|
|
2138
2219
|
* Service providing user account configurations.
|
|
2139
2220
|
*/
|
|
@@ -2488,7 +2569,6 @@ class ObjectConfigService {
|
|
|
2488
2569
|
#objectConfigs;
|
|
2489
2570
|
// called on core init (auth.service -> initApp)
|
|
2490
2571
|
init() {
|
|
2491
|
-
console.log('ObjectConfigService.init', this.#user.getCurrentUser().userSettings);
|
|
2492
2572
|
return this.#user.loadObjectConfig().pipe(tap$1((res) => {
|
|
2493
2573
|
this.#getDefaultObjectConfig();
|
|
2494
2574
|
this.#objectConfigs = res || {
|
|
@@ -4140,6 +4220,147 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
4140
4220
|
}]
|
|
4141
4221
|
}] });
|
|
4142
4222
|
|
|
4223
|
+
class SearchUtils {
|
|
4224
|
+
static { this.dateRanges = ['today', 'yesterday', 'thisWeek', 'lastWeek', 'thisMonth', 'lastMonth', 'thisYear', 'lastYear']; }
|
|
4225
|
+
static { this.filesizeRanges = ['small', 'medium', 'large', 'verylarge']; }
|
|
4226
|
+
static dateRangeStartEnd(dateRange) {
|
|
4227
|
+
let start;
|
|
4228
|
+
let end;
|
|
4229
|
+
switch (dateRange) {
|
|
4230
|
+
case 'today': {
|
|
4231
|
+
start = new Date();
|
|
4232
|
+
end = new Date();
|
|
4233
|
+
break;
|
|
4234
|
+
}
|
|
4235
|
+
case 'yesterday': {
|
|
4236
|
+
const yesterday = new Date();
|
|
4237
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
4238
|
+
start = yesterday;
|
|
4239
|
+
end = yesterday;
|
|
4240
|
+
break;
|
|
4241
|
+
}
|
|
4242
|
+
case 'thisWeek': {
|
|
4243
|
+
const firstDay = new Date();
|
|
4244
|
+
firstDay.setDate(firstDay.getDate() - firstDay.getDay());
|
|
4245
|
+
start = firstDay;
|
|
4246
|
+
end = new Date();
|
|
4247
|
+
break;
|
|
4248
|
+
}
|
|
4249
|
+
case 'lastWeek': {
|
|
4250
|
+
const firstDay = new Date();
|
|
4251
|
+
firstDay.setDate(firstDay.getDate() - firstDay.getDay() - 7);
|
|
4252
|
+
const lastDay = new Date();
|
|
4253
|
+
lastDay.setDate(lastDay.getDate() - lastDay.getDay() - 1);
|
|
4254
|
+
start = firstDay;
|
|
4255
|
+
end = lastDay;
|
|
4256
|
+
break;
|
|
4257
|
+
}
|
|
4258
|
+
case 'thisMonth': {
|
|
4259
|
+
const firstDay = new Date();
|
|
4260
|
+
firstDay.setDate(1);
|
|
4261
|
+
start = firstDay;
|
|
4262
|
+
end = new Date();
|
|
4263
|
+
break;
|
|
4264
|
+
}
|
|
4265
|
+
case 'lastMonth': {
|
|
4266
|
+
const firstDay = new Date();
|
|
4267
|
+
firstDay.setDate(1);
|
|
4268
|
+
firstDay.setMonth(firstDay.getMonth() - 1);
|
|
4269
|
+
const lastDay = new Date();
|
|
4270
|
+
lastDay.setDate(0);
|
|
4271
|
+
start = firstDay;
|
|
4272
|
+
end = lastDay;
|
|
4273
|
+
break;
|
|
4274
|
+
}
|
|
4275
|
+
case 'thisYear': {
|
|
4276
|
+
const firstDay = new Date();
|
|
4277
|
+
firstDay.setMonth(0);
|
|
4278
|
+
firstDay.setDate(1);
|
|
4279
|
+
start = firstDay;
|
|
4280
|
+
end = new Date();
|
|
4281
|
+
break;
|
|
4282
|
+
}
|
|
4283
|
+
case 'lastYear': {
|
|
4284
|
+
const firstDay = new Date();
|
|
4285
|
+
firstDay.setFullYear(firstDay.getFullYear() - 1);
|
|
4286
|
+
firstDay.setMonth(0);
|
|
4287
|
+
firstDay.setDate(1);
|
|
4288
|
+
const lastDay = new Date();
|
|
4289
|
+
lastDay.setFullYear(lastDay.getFullYear() - 1);
|
|
4290
|
+
lastDay.setMonth(11);
|
|
4291
|
+
lastDay.setDate(31);
|
|
4292
|
+
start = firstDay;
|
|
4293
|
+
end = lastDay;
|
|
4294
|
+
break;
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4297
|
+
return { start, end };
|
|
4298
|
+
}
|
|
4299
|
+
/**
|
|
4300
|
+
* Maps a date range filter to a date range value like 'thisWeek', 'lastMonth', etc.
|
|
4301
|
+
* @param rangeValue the range value
|
|
4302
|
+
* @returns the date range (eg. 'thisWeek', 'lastMonth', etc.)
|
|
4303
|
+
*/
|
|
4304
|
+
static getMatchingDateRange(rangeValue) {
|
|
4305
|
+
return SearchUtils.dateRanges.find((dateRange) => {
|
|
4306
|
+
const { start, end } = SearchUtils.dateRangeStartEnd(dateRange);
|
|
4307
|
+
return (rangeValue.firstValue === start.toISOString().split('T')[0] + 'T00:00:00.000' &&
|
|
4308
|
+
rangeValue.secondValue === end.toISOString().split('T')[0] + 'T23:59:59.000');
|
|
4309
|
+
});
|
|
4310
|
+
}
|
|
4311
|
+
// Files size ranges
|
|
4312
|
+
static getMatchingFilesizeRange(rangeValue) {
|
|
4313
|
+
let filesizeRange = undefined;
|
|
4314
|
+
if (rangeValue.operator === Operator.INTERVAL_INCLUDE_BOTH) {
|
|
4315
|
+
if (rangeValue.firstValue === 1024 * 1024 && rangeValue.secondValue === 1024 * 1024 * 10)
|
|
4316
|
+
filesizeRange = 'medium';
|
|
4317
|
+
else if (rangeValue.firstValue === 1024 * 1024 * 10 && rangeValue.secondValue === 1024 * 1024 * 100)
|
|
4318
|
+
filesizeRange = 'large';
|
|
4319
|
+
}
|
|
4320
|
+
else if (rangeValue.operator === Operator.LESS_THAN) {
|
|
4321
|
+
if (rangeValue.firstValue === 1024 * 1024)
|
|
4322
|
+
filesizeRange = 'small';
|
|
4323
|
+
}
|
|
4324
|
+
else if (rangeValue.operator === Operator.GREATER_THAN) {
|
|
4325
|
+
if (rangeValue.firstValue === 1024 * 1024 * 100)
|
|
4326
|
+
filesizeRange = 'verylarge';
|
|
4327
|
+
}
|
|
4328
|
+
return filesizeRange;
|
|
4329
|
+
}
|
|
4330
|
+
static filesizeRangeToRangeValue(filesizeRange) {
|
|
4331
|
+
let rv = undefined;
|
|
4332
|
+
switch (filesizeRange) {
|
|
4333
|
+
case 'small':
|
|
4334
|
+
rv = {
|
|
4335
|
+
operator: Operator.LESS_THAN,
|
|
4336
|
+
firstValue: 1024 * 1024
|
|
4337
|
+
};
|
|
4338
|
+
break;
|
|
4339
|
+
case 'medium':
|
|
4340
|
+
rv = {
|
|
4341
|
+
operator: Operator.INTERVAL_INCLUDE_BOTH,
|
|
4342
|
+
firstValue: 1024 * 1024,
|
|
4343
|
+
secondValue: 1024 * 1024 * 10
|
|
4344
|
+
};
|
|
4345
|
+
break;
|
|
4346
|
+
case 'large':
|
|
4347
|
+
rv = {
|
|
4348
|
+
operator: Operator.INTERVAL_INCLUDE_BOTH,
|
|
4349
|
+
firstValue: 1024 * 1024 * 10,
|
|
4350
|
+
secondValue: 1024 * 1024 * 100
|
|
4351
|
+
};
|
|
4352
|
+
break;
|
|
4353
|
+
case 'verylarge':
|
|
4354
|
+
rv = {
|
|
4355
|
+
operator: Operator.GREATER_THAN,
|
|
4356
|
+
firstValue: 1024 * 1024 * 100
|
|
4357
|
+
};
|
|
4358
|
+
break;
|
|
4359
|
+
}
|
|
4360
|
+
return rv;
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4363
|
+
|
|
4143
4364
|
class SessionStorageService {
|
|
4144
4365
|
#TEMP_STORAGE_ENTRIES_KEY = 'yuv.core.sessionstorage.entries';
|
|
4145
4366
|
constructor() {
|
|
@@ -4771,5 +4992,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
4771
4992
|
* Generated bundle index. Do not edit.
|
|
4772
4993
|
*/
|
|
4773
4994
|
|
|
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 };
|
|
4995
|
+
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, SearchUtils, SecondaryObjectTypeClassification, SessionStorageService, Situation, Sort, SystemResult, SystemSOT, SystemService, SystemType, TENANT_HEADER, UploadService, UserRoles, UserService, Utils, YuvClientCoreModule, YuvClientCoreSharedModule, YuvError, YuvEventType, YuvUser, init_moduleFnc, storageFactory };
|
|
4775
4996
|
//# sourceMappingURL=yuuvis-client-core.mjs.map
|