@yuuvis/app-drive 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.
Files changed (30) hide show
  1. package/esm2022/lib/actions/updateContent/update.content.action.mjs +5 -2
  2. package/esm2022/lib/components/add-button/add-button-overlay/add-button-overlay.component.mjs +2 -2
  3. package/esm2022/lib/components/drive-search/drive-search-overlay/drive-search-overlay.component.mjs +343 -0
  4. package/esm2022/lib/components/drive-search/drive-search.component.mjs +83 -0
  5. package/esm2022/lib/components/index.mjs +2 -2
  6. package/esm2022/lib/components/search-filter/search-filter.component.mjs +14 -330
  7. package/esm2022/lib/components/sort/sort.component.mjs +7 -6
  8. package/esm2022/lib/drive.icons.mjs +5 -2
  9. package/esm2022/lib/pages/files/files.component.mjs +31 -26
  10. package/esm2022/lib/pages/object/object.component.mjs +14 -6
  11. package/esm2022/lib/services/drive/drive.interface.mjs +1 -1
  12. package/esm2022/lib/services/drive/drive.service.mjs +9 -4
  13. package/fesm2022/yuuvis-app-drive.mjs +507 -440
  14. package/fesm2022/yuuvis-app-drive.mjs.map +1 -1
  15. package/lib/assets/i18n/de.json +100 -0
  16. package/lib/assets/i18n/en.json +100 -0
  17. package/lib/assets/yuvManifest.json +15 -0
  18. package/lib/components/drive-search/drive-search-overlay/drive-search-overlay.component.d.ts +52 -0
  19. package/lib/components/drive-search/drive-search.component.d.ts +21 -0
  20. package/lib/components/index.d.ts +1 -0
  21. package/lib/components/search-filter/search-filter.component.d.ts +0 -2
  22. package/lib/container/drive/drive.component.d.ts +3 -0
  23. package/lib/drive.icons.d.ts +3 -0
  24. package/lib/pages/files/files.component.d.ts +10 -7
  25. package/lib/pages/object/object.component.d.ts +2 -1
  26. package/lib/services/drive/drive.interface.d.ts +1 -0
  27. package/lib/services/drive/drive.service.d.ts +1 -1
  28. package/package.json +2 -2
  29. package/esm2022/lib/components/search-filter/date-range-picker/date-range-picker.component.mjs +0 -38
  30. package/lib/components/search-filter/date-range-picker/date-range-picker.component.d.ts +0 -13
@@ -1,19 +1,19 @@
1
- import * as i1$3 from '@angular/common';
1
+ import * as i1$1 from '@angular/common';
2
2
  import { CommonModule, DOCUMENT, NgClass, DatePipe, AsyncPipe } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { InjectionToken, inject, Component, Injectable, input, effect, output, signal, viewChild, ElementRef, HostBinding, viewChildren, computed, ChangeDetectionStrategy, HostListener, DestroyRef, contentChild, ViewEncapsulation, untracked } from '@angular/core';
5
5
  import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
6
- import * as i1 from '@angular/forms';
6
+ import * as i6 from '@angular/forms';
7
7
  import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
8
8
  import * as i1$2 from '@angular/router';
9
9
  import { Router, NavigationStart, ActivatedRoute, RouterModule, NavigationEnd } from '@angular/router';
10
10
  import * as i2 from '@yuuvis/client-core';
11
- import { SystemType, ClipboardService, TranslateService, TranslateModule, BaseObjectTypeField, EventService, DmsService, SearchService, BackendService, YuvEventType, ContentStreamField, NotificationService, Utils, SystemService, UserService, LocaleDatePipe, Operator, OperatorLabel, ObjectConfigService, DeviceService, AppCacheService } from '@yuuvis/client-core';
11
+ import { SystemType, ClipboardService, TranslateService, TranslateModule, BaseObjectTypeField, EventService, DmsService, SearchService, BackendService, YuvEventType, ContentStreamField, RetentionService, NotificationService, Utils, SystemService, Situation, Operator, UserService, ObjectConfigService, DeviceService, AppCacheService } from '@yuuvis/client-core';
12
12
  import { ActionsService, BASE_ACTION, SelectionRange, AbstractContextAction } from '@yuuvis/client-framework/actions';
13
13
  import { YUV_ICONS } from '@yuuvis/client-framework/icons';
14
14
  import { UploadProgressComponent } from '@yuuvis/client-framework/upload-progress';
15
15
  import { AppLogoComponent } from '@yuuvis/client-shell';
16
- import * as i1$1 from '@yuuvis/components/icon';
16
+ import * as i1 from '@yuuvis/components/icon';
17
17
  import { YvcIconModule, ICONS } from '@yuuvis/components/icon';
18
18
  import { YvcOverflowMenuComponent } from '@yuuvis/components/overflow-menu';
19
19
  import { YvcOverlayRef, YvcOverlayService, YvcOverlayModule } from '@yuuvis/components/overlay';
@@ -22,13 +22,13 @@ import { marker } from '@colsen1991/ngx-translate-extract-marker';
22
22
  import { signalState, patchState } from '@ngrx/signals';
23
23
  import { tap, Subject, filter, switchMap, of, forkJoin, map, catchError, timer, finalize, from } from 'rxjs';
24
24
  import { TranslateService as TranslateService$1, TranslateModule as TranslateModule$1 } from '@ngx-translate/core';
25
- import { FormInputComponent, StringComponent, DatetimeRangeComponent } from '@yuuvis/client-framework/forms';
25
+ import { FormInputComponent, StringComponent, RangeSelectDateComponent, RangeSelectFilesizeComponent } from '@yuuvis/client-framework/forms';
26
26
  import { ShellService } from '@yuuvis/client-shell-core';
27
27
  import { ObjectPreviewComponent } from '@yuuvis/client-framework/object-preview';
28
28
  import { ObjectSummaryDataComponent, ObjectSummaryComponent, MultiObjectSummaryComponent } from '@yuuvis/client-framework/object-summary';
29
29
  import * as i3 from '@yuuvis/components/split-view';
30
30
  import { YvcSplitViewModule, SplitViewComponent } from '@yuuvis/components/split-view';
31
- import * as i2$2 from '@yuuvis/components/tabs';
31
+ import * as i2$3 from '@yuuvis/components/tabs';
32
32
  import { YvcTabsModule } from '@yuuvis/components/tabs';
33
33
  import { ListComponent, ListItemDirective } from '@yuuvis/client-framework/list';
34
34
  import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
@@ -38,11 +38,13 @@ import { YvcDragScrollModule } from '@yuuvis/components/drag-scroll';
38
38
  import { FocusWithinDirective, ClickDoubleDirective, FileDropZoneDirective, ContainerSizeDirective } from '@yuuvis/client-framework/common';
39
39
  import { TreeComponent } from '@yuuvis/client-framework/tree';
40
40
  import { SimpleSearchComponent } from '@yuuvis/client-framework/simple-search';
41
+ import { ObjectFormComponent } from '@yuuvis/client-framework/object-form';
42
+ import { YvcCheckboxModule } from '@yuuvis/components/checkbox';
43
+ import * as i2$2 from '@yuuvis/components/dropdown';
44
+ import { YvcDropdownModule } from '@yuuvis/components/dropdown';
41
45
  import { TileListComponent, TileConfigTriggerComponent } from '@yuuvis/client-framework/tile-list';
42
46
  import { ClipboardComponent } from '@yuuvis/client-framework/clipboard';
43
- import * as i1$4 from '@yuuvis/components/dropdown';
44
- import { YvcDropdownModule } from '@yuuvis/components/dropdown';
45
- import { ObjectMetadataComponent, ObjectAuditComponent } from '@yuuvis/client-framework/object-details';
47
+ import { ObjectMetadataComponent, ObjectAuditComponent, RetentionBadgeComponent } from '@yuuvis/client-framework/object-details';
46
48
  import { ObjectFlavorComponent } from '@yuuvis/client-framework/object-flavor';
47
49
  import { RendererDirective } from '@yuuvis/client-framework/renderer';
48
50
 
@@ -59,7 +61,10 @@ const APP_DRIVE_ICONS = {
59
61
  clipboard: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M620-163 450-333l56-56 114 114 226-226 56 56-282 282Zm220-397h-80v-200h-80v120H280v-120h-80v560h240v80H200q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h167q11-35 43-57.5t70-22.5q40 0 71.5 22.5T594-840h166q33 0 56.5 23.5T840-760v200ZM480-760q17 0 28.5-11.5T520-800q0-17-11.5-28.5T480-840q-17 0-28.5 11.5T440-800q0 17 11.5 28.5T480-760Z"/></svg>',
60
62
  addCircle: '<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="M444-288h72v-156h156v-72H516v-156h-72v156H288v72h156v156Zm36.28 192Q401-96 331-126t-122.5-82.5Q156-261 126-330.96t-30-149.5Q96-560 126-629.5q30-69.5 82.5-122T330.96-834q69.96-30 149.5-30t149.04 30q69.5 30 122 82.5T834-629.28q30 69.73 30 149Q864-401 834-331t-82.5 122.5Q699-156 629.28-126q-69.73 30-149 30Zm-.28-72q130 0 221-91t91-221q0-130-91-221t-221-91q-130 0-221 91t-91 221q0 130 91 221t221 91Zm0-312Z"/></svg>',
61
63
  createFolder: '<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="M576-324h72v-72h72v-72h-72v-72h-72v72h-72v72h72v72ZM168-192q-29 0-50.5-21.5T96-264v-432q0-29.7 21.5-50.85Q139-768 168-768h216l96 96h312q29.7 0 50.85 21.15Q864-629.7 864-600v336q0 29-21.15 50.5T792-192H168Zm0-72h624v-336H450l-96-96H168v432Zm0 0v-432 432Z"/></svg>',
62
- createFile: '<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="M444-240h72v-108h108v-72H516v-108h-72v108H336v72h108v108ZM263.72-96Q234-96 213-117.15T192-168v-624q0-29.7 21.15-50.85Q234.3-864 264-864h312l192 192v504q0 29.7-21.16 50.85Q725.68-96 695.96-96H263.72ZM528-624v-168H264v624h432v-456H528ZM264-792v189-189 624-624Z"/></svg>'
64
+ createFile: '<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#e8eaed"><path d="M444-240h72v-108h108v-72H516v-108h-72v108H336v72h108v108ZM263.72-96Q234-96 213-117.15T192-168v-624q0-29.7 21.15-50.85Q234.3-864 264-864h312l192 192v504q0 29.7-21.16 50.85Q725.68-96 695.96-96H263.72ZM528-624v-168H264v624h432v-456H528ZM264-792v189-189 624-624Z"/></svg>',
65
+ unchecked: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Z"/></svg>',
66
+ checked: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="m424-312 282-282-56-56-226 226-114-114-56 56 170 170ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm0-560v560-560Z"/></svg>',
67
+ extendedSearch: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M440-120v-240h80v80h320v80H520v80h-80Zm-320-80v-80h240v80H120Zm160-160v-80H120v-80h160v-80h80v240h-80Zm160-80v-80h400v80H440Zm160-160v-240h80v80h160v80H680v80h-80Zm-480-80v-80h400v80H120Z"/></svg>'
63
68
  };
64
69
 
65
70
  // Mapping schema for this apps backend schema
@@ -343,6 +348,7 @@ class DriveService {
343
348
  currentFolder: null,
344
349
  query: null,
345
350
  queryTitle: null,
351
+ extendedQuery: false,
346
352
  selection: [],
347
353
  actions: [],
348
354
  busy: false,
@@ -399,10 +405,11 @@ class DriveService {
399
405
  patchState(this.state$, { selection: o });
400
406
  this._getActions();
401
407
  }
402
- updateQuery(query, queryTitle = null) {
408
+ updateQuery(query, queryTitle = null, extendedQuery = false) {
403
409
  patchState(this.state$, {
404
410
  query: this.applyFolderListSearchConditions(query),
405
- queryTitle: queryTitle
411
+ queryTitle: queryTitle,
412
+ extendedQuery: extendedQuery
406
413
  });
407
414
  }
408
415
  setSort(property, order) {
@@ -417,7 +424,10 @@ class DriveService {
417
424
  }
418
425
  }
419
426
  updateCurrentFolder(currentFolderID) {
420
- patchState(this.state$, { currentFolder: currentFolderID || null });
427
+ patchState(this.state$, {
428
+ currentFolder: currentFolderID || null,
429
+ extendedQuery: false,
430
+ });
421
431
  }
422
432
  #copyToFolder(objects, folderId, options, validateNames = true) {
423
433
  return validateNames
@@ -806,7 +816,7 @@ class ObjectNameComponent {
806
816
  this.nameChange.emit(this.nameForm.value.name);
807
817
  }
808
818
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ObjectNameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
809
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ObjectNameComponent, isStandalone: true, selector: "ymd-object-name", inputs: { headline: { classPropertyName: "headline", publicName: "headline", isSignal: true, isRequired: false, transformFunction: null }, submitButton: { classPropertyName: "submitButton", publicName: "submitButton", isSignal: true, isRequired: true, transformFunction: null }, cancelButton: { classPropertyName: "cancelButton", publicName: "cancelButton", isSignal: true, isRequired: false, transformFunction: null }, isFile: { classPropertyName: "isFile", publicName: "isFile", isSignal: true, isRequired: false, transformFunction: null }, isRename: { classPropertyName: "isRename", publicName: "isRename", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nameChange: "nameChange", onClose: "onClose" }, ngImport: i0, template: "<form [formGroup]=\"nameForm\" (ngSubmit)=\"submitForm()\">\n @if (headline() && headline()?.length) {\n <header>{{ headline() }}</header>\n }\n <main>\n <yuv-form-input [label]=\"'yuv.app.drive.property.name' | translate\" [required]=\"true\"> <yuv-string formControlName=\"name\"></yuv-string></yuv-form-input>\n @if (nameForm.hasError('nameAlreadyExists')) {\n <div class=\"error\">{{ 'yuv.app.drive.create.error.name.exist' | translate }}</div>\n }\n @if (nameForm.hasError('invalidFileNames')) {\n <div class=\"error\">{{ 'yuv.app.drive.create.error.name.invalid' | translate }}</div>\n }\n </main>\n\n <footer>\n <button class=\"primary\" type=\"submit\" [disabled]=\"disabled() || nameForm.invalid || busy || error\">{{ submitButton() }}</button>\n @if (cancelButton() && cancelButton().length) {\n <button class=\"secondary\" type=\"button\" (click)=\"onClose.emit()\" [disabled]=\"busy\">{{ cancelButton() }}</button>\n }\n </footer>\n</form>\n", styles: [":host header{font-size:var(--font-title)}:host main{padding:var(--app-pane-padding) 0}:host main .error{color:var(--text-color-caption);background-color:var(--panel-background-lightgrey);border:1px solid var(--panel-divider-color);border-radius:.25rem;padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2);margin-block-start:calc(var(--app-pane-padding) / 2)}:host footer{display:flex;flex-flow:row-reverse;justify-content:end;align-items:center;gap:calc(var(--app-pane-padding) / 4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FormInputComponent, selector: "yuv-form-input", inputs: ["label", "tag", "description", "invalid", "disabled", "required"] }, { kind: "component", type: StringComponent, selector: "yuv-string", inputs: ["multiselect", "rows", "readonly", "autofocus", "classifications", "situation", "regex", "minLength", "maxLength"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
819
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ObjectNameComponent, isStandalone: true, selector: "ymd-object-name", inputs: { headline: { classPropertyName: "headline", publicName: "headline", isSignal: true, isRequired: false, transformFunction: null }, submitButton: { classPropertyName: "submitButton", publicName: "submitButton", isSignal: true, isRequired: true, transformFunction: null }, cancelButton: { classPropertyName: "cancelButton", publicName: "cancelButton", isSignal: true, isRequired: false, transformFunction: null }, isFile: { classPropertyName: "isFile", publicName: "isFile", isSignal: true, isRequired: false, transformFunction: null }, isRename: { classPropertyName: "isRename", publicName: "isRename", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nameChange: "nameChange", onClose: "onClose" }, ngImport: i0, template: "<form [formGroup]=\"nameForm\" (ngSubmit)=\"submitForm()\">\n @if (headline() && headline()?.length) {\n <header>{{ headline() }}</header>\n }\n <main>\n <yuv-form-input [label]=\"'yuv.app.drive.property.name' | translate\" [required]=\"true\"> <yuv-string formControlName=\"name\"></yuv-string></yuv-form-input>\n @if (nameForm.hasError('nameAlreadyExists')) {\n <div class=\"error\">{{ 'yuv.app.drive.create.error.name.exist' | translate }}</div>\n }\n @if (nameForm.hasError('invalidFileNames')) {\n <div class=\"error\">{{ 'yuv.app.drive.create.error.name.invalid' | translate }}</div>\n }\n </main>\n\n <footer>\n <button class=\"primary\" type=\"submit\" [disabled]=\"disabled() || nameForm.invalid || busy || error\">{{ submitButton() }}</button>\n @if (cancelButton() && cancelButton().length) {\n <button class=\"secondary\" type=\"button\" (click)=\"onClose.emit()\" [disabled]=\"busy\">{{ cancelButton() }}</button>\n }\n </footer>\n</form>\n", styles: [":host header{font-size:var(--font-title)}:host main{padding:var(--app-pane-padding) 0}:host main .error{color:var(--text-color-caption);background-color:var(--panel-background-lightgrey);border:1px solid var(--panel-divider-color);border-radius:.25rem;padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2);margin-block-start:calc(var(--app-pane-padding) / 2)}:host footer{display:flex;flex-flow:row-reverse;justify-content:end;align-items:center;gap:calc(var(--app-pane-padding) / 4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FormInputComponent, selector: "yuv-form-input", inputs: ["label", "tag", "description", "invalid", "disabled", "required"] }, { kind: "component", type: StringComponent, selector: "yuv-string", inputs: ["multiselect", "rows", "readonly", "autofocus", "classifications", "situation", "regex", "minLength", "maxLength"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
810
820
  }
811
821
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ObjectNameComponent, decorators: [{
812
822
  type: Component,
@@ -911,6 +921,7 @@ class UpdateContentAction extends AbstractContextAction {
911
921
  this.#router = inject(Router);
912
922
  this.#drive = inject(DriveService);
913
923
  this.#document = inject(DOCUMENT);
924
+ this.#retention = inject(RetentionService);
914
925
  this.id = 'app.drive.action.new.content.version';
915
926
  this.label = this.translate.instant('yuv.app.drive.action.new.version');
916
927
  this.description = this.translate.instant('yuv.app.drive.action.new.version.description');
@@ -923,10 +934,11 @@ class UpdateContentAction extends AbstractContextAction {
923
934
  #router;
924
935
  #drive;
925
936
  #document;
937
+ #retention;
926
938
  isExecutable(selection) {
927
939
  const selected = selection[0];
928
940
  const canWrite = !!selected?.permissions?.writeContent;
929
- return of(canWrite && selection.length === 1 && !selected.isFolder);
941
+ return of(canWrite && selection.length === 1 && !selected.isFolder && !this.#retention.getRetentionState(selected).underRetention);
930
942
  }
931
943
  run(selection) {
932
944
  if (!selection[0].isFolder) {
@@ -1112,7 +1124,7 @@ class AddButtonOverlayComponent {
1112
1124
  }
1113
1125
  }
1114
1126
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddButtonOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1115
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AddButtonOverlayComponent, isStandalone: true, selector: "ymd-add-button-overlay", viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-list (itemSelect)=\"onListItemSelect($event)\" selectOnEnter=\"true\">\n @for (i of defaultItems; track $index) {\n <div yuvListItem>\n <yvc-icon [svg]=\"i.icon\"></yvc-icon>\n {{ i.label }}\n </div>\n }\n\n <!-- Upload file with flavor -->\n @for (f of flavorListItems; track f.flavor.id) {\n <div class=\"flavor\" yuvListItem>\n <yvc-icon [svg]=\"f.flavor.icon\"></yvc-icon>\n {{ f.label }}\n </div>\n }\n</yuv-list>\n\n<input style=\"display: none\" multiple=\"true\" #fileInput type=\"file\" (change)=\"createDocument(fileInput)\" />\n", styles: [":host{background-color:var(--color-accent);color:var(--color-accent-tone);display:flex;flex-flow:column;padding:calc(var(--app-pane-padding) / 2) 0;border-radius:0 4px 4px}:host yuv-list{outline:0;--list-item-current-background: rgb(from var(--color-accent-tone) r g b / .2)}:host yuv-list [yuvListItem]{--icon-size: 18px;cursor:pointer;display:flex;align-items:center;gap:calc(var(--app-pane-padding) / 2);padding:calc(var(--app-pane-padding) / 2) var(--app-pane-padding)}:host yuv-list [yuvListItem]:hover{background-color:var(--list-item-current-background)}:host yuv-list [yuvListItem]:nth-child(2){border-block-end:1px solid rgb(from var(--color-accent-tone) r g b/.2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ListComponent, selector: "yuv-list", inputs: ["multiselect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }] }); }
1127
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: AddButtonOverlayComponent, isStandalone: true, selector: "ymd-add-button-overlay", viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-list (itemSelect)=\"onListItemSelect($event)\" selectOnEnter=\"true\">\n @for (i of defaultItems; track $index) {\n <div yuvListItem>\n <yvc-icon [svg]=\"i.icon\"></yvc-icon>\n {{ i.label }}\n </div>\n }\n\n <!-- Upload file with flavor -->\n @for (f of flavorListItems; track f.flavor.id) {\n <div class=\"flavor\" yuvListItem>\n <yvc-icon [svg]=\"f.flavor.icon\"></yvc-icon>\n {{ f.label }}\n </div>\n }\n</yuv-list>\n\n<input style=\"display: none\" multiple=\"true\" #fileInput type=\"file\" (change)=\"createDocument(fileInput)\" />\n", styles: [":host{background-color:var(--color-accent);color:var(--color-accent-tone);display:flex;flex-flow:column;padding:calc(var(--app-pane-padding) / 2) 0;border-radius:0 4px 4px}:host yuv-list{outline:0;--list-item-current-background: rgb(from var(--color-accent-tone) r g b / .2)}:host yuv-list [yuvListItem]{--icon-size: 18px;cursor:pointer;display:flex;align-items:center;gap:calc(var(--app-pane-padding) / 2);padding:calc(var(--app-pane-padding) / 2) var(--app-pane-padding)}:host yuv-list [yuvListItem]:hover{background-color:var(--list-item-current-background)}:host yuv-list [yuvListItem]:nth-child(2){border-block-end:1px solid rgb(from var(--color-accent-tone) r g b/.2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ListComponent, selector: "yuv-list", inputs: ["multiselect", "selfHandleSelection", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }] }); }
1116
1128
  }
1117
1129
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddButtonOverlayComponent, decorators: [{
1118
1130
  type: Component,
@@ -1138,7 +1150,7 @@ class AddButtonComponent {
1138
1150
  });
1139
1151
  }
1140
1152
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1141
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AddButtonComponent, isStandalone: true, selector: "ymd-add-button", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.popover": "this.popoverOpen" } }, ngImport: i0, template: "\n <button class=\"toggle primary\" [disabled]=\"disabled()\" (click)=\"open()\">\n <yvc-icon [svg]=\"icon\"></yvc-icon><span class=\"label\">{{ 'yuv.app.drive.create.label' | translate }}</span>\n </button>\n\n", styles: [":host{--border-radius: var(--ribbon-button-border-radius)}:host.popover button{border-radius:4px 4px 0 0;pointer-events:none}:host button{padding:var(--ribbon-button-padding);border-radius:var(--border-radius);display:flex;gap:calc(var(--ribbon-icon-size) / 3);padding-inline-end:calc(var(--ribbon-icon-size) / 2)}:host button yvc-icon{--icon-size: var(--ribbon-icon-size)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
1153
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: AddButtonComponent, isStandalone: true, selector: "ymd-add-button", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.popover": "this.popoverOpen" } }, ngImport: i0, template: "\n <button class=\"toggle primary\" [disabled]=\"disabled()\" (click)=\"open()\">\n <yvc-icon [svg]=\"icon\"></yvc-icon><span class=\"label\">{{ 'yuv.app.drive.create.label' | translate }}</span>\n </button>\n\n", styles: [":host{--border-radius: var(--ribbon-button-border-radius)}:host.popover button{border-radius:4px 4px 0 0;pointer-events:none}:host button{padding:var(--ribbon-button-padding);border-radius:var(--border-radius);display:flex;gap:calc(var(--ribbon-icon-size) / 3);padding-inline-end:calc(var(--ribbon-icon-size) / 2)}:host button yvc-icon{--icon-size: var(--ribbon-icon-size)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
1142
1154
  }
1143
1155
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddButtonComponent, decorators: [{
1144
1156
  type: Component,
@@ -1225,7 +1237,7 @@ class SortComponent {
1225
1237
  }
1226
1238
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SortComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1227
1239
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SortComponent, isStandalone: true, selector: "ymd-sort", outputs: { sortChanged: "sortChanged" }, host: { listeners: { "blur": "onBlur()", "keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "items", predicate: ListItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
1228
- <button popovertarget="sort" class="sort-button">
1240
+ <button popovertarget="sort" title="{{'yuv.app.drive.sort.tooltip'| translate}}" class="sort-button">
1229
1241
  <yvc-icon [svg]="sortIcon" />
1230
1242
  </button>
1231
1243
 
@@ -1251,12 +1263,12 @@ class SortComponent {
1251
1263
  }
1252
1264
  </ol>
1253
1265
  </dialog>
1254
- `, isInline: true, styles: ["@charset \"UTF-8\";.sort-button{padding:calc(var(--app-pane-padding) / 4);anchor-name:--sort-button}dialog::backdrop{background-color:#ff69b4;display:none}.sort-menu{display:none;background-color:var(--panel-background);color:var(--text-color-body);border-color:var(--panel-background);position:absolute;position-anchor:--sort-button;position-area:block-end center;margin:0;inset:auto;bottom:anchor(bottom);left:anchor(right);opacity:0;transition:opacity .3s,display .3s,overlay .3s;transition-behavior:allow-discrete;position-try-fallbacks:--left;margin-left:.25rem;box-shadow:0 1px 12px #0000001a;border:1px solid var(--panel-divider-color)}.sort-menu::backdrop{background-color:#ff69b4;display:none;-webkit-backdrop-filter:none;backdrop-filter:none}.sort-menu:popover-open{display:grid;opacity:1}@starting-style{.sort-menu:popover-open{display:grid;opacity:0}}@position-try --left{inset:auto;top:anchor(bottom);right:anchor(right)}.sort-group{list-style-type:none;padding-inline:0;margin-block:0;padding:.5rem}.sort-group [yuvListItem]{padding-left:calc(var(--font-body) + 2px);line-height:1.5em;display:flex;align-items:center;text-decoration:none;white-space:nowrap;border-radius:2px;color:var(--text-color-caption)}.sort-group [yuvListItem][aria-selected=true]:before{content:\"\\2022\";position:absolute;left:var(--font-body);font-size:var(--font-title)}.sort-group [yuvListItem][aria-current=true],.sort-group [yuvListItem]:hover{cursor:pointer;color:var(--text-color-body);background-color:var(--item-focus-background-color);outline:2px solid var(--item-focus-background-color)}.sort-group [yuvListItem][aria-current=true]{outline-color:var(--text-color-caption)}.sort-group [yuvListItem] .label{margin-right:.5rem;padding:.1rem 0}.sort-group .divider{margin:.5rem 0;border-top:1px solid var(--panel-divider-color)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1266
+ `, isInline: true, styles: ["@charset \"UTF-8\";.sort-button{padding:calc(var(--app-pane-padding) / 4);anchor-name:--sort-button}dialog::backdrop{background-color:#ff69b4;display:none}.sort-menu{display:none;background-color:var(--panel-background);color:var(--text-color-body);border-color:var(--panel-background);position:absolute;position-anchor:--sort-button;position-area:block-end center;margin:0;inset:auto;bottom:anchor(bottom);left:anchor(right);opacity:0;transition:opacity .3s,display .3s,overlay .3s;transition-behavior:allow-discrete;position-try-fallbacks:--left;margin-left:.25rem;box-shadow:0 1px 12px #0000001a;border:1px solid var(--panel-divider-color)}.sort-menu::backdrop{background-color:#ff69b4;display:none;-webkit-backdrop-filter:none;backdrop-filter:none}.sort-menu:popover-open{display:grid;opacity:1}@starting-style{.sort-menu:popover-open{display:grid;opacity:0}}@position-try --left{inset:auto;top:anchor(bottom);right:anchor(right)}.sort-group{list-style-type:none;padding-inline:0;margin-block:0;padding:.5rem}.sort-group [yuvListItem]{padding-left:calc(var(--font-body) + 2px);line-height:1.5em;display:flex;align-items:center;text-decoration:none;white-space:nowrap;border-radius:2px;color:var(--text-color-caption)}.sort-group [yuvListItem][aria-selected=true]:before{content:\"\\2022\";position:absolute;left:var(--font-body);font-size:var(--font-title)}.sort-group [yuvListItem][aria-current=true],.sort-group [yuvListItem]:hover{cursor:pointer;color:var(--text-color-body);background-color:var(--item-focus-background-color);outline:2px solid var(--item-focus-background-color)}.sort-group [yuvListItem][aria-current=true]{outline-color:var(--text-color-caption)}.sort-group [yuvListItem] .label{margin-right:.5rem;padding:.1rem 0}.sort-group .divider{margin:.5rem 0;border-top:1px solid var(--panel-divider-color)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1255
1267
  }
1256
1268
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SortComponent, decorators: [{
1257
1269
  type: Component,
1258
- args: [{ selector: 'ymd-sort', standalone: true, imports: [NgClass, YvcIconModule, ListItemDirective, ReactiveFormsModule], template: `
1259
- <button popovertarget="sort" class="sort-button">
1270
+ args: [{ selector: 'ymd-sort', standalone: true, imports: [NgClass, YvcIconModule, ListItemDirective, ReactiveFormsModule, TranslateModule], template: `
1271
+ <button popovertarget="sort" title="{{'yuv.app.drive.sort.tooltip'| translate}}" class="sort-button">
1260
1272
  <yvc-icon [svg]="sortIcon" />
1261
1273
  </button>
1262
1274
 
@@ -1335,7 +1347,7 @@ class BreadcrumbComponent {
1335
1347
  this.#keyManager?.destroy();
1336
1348
  }
1337
1349
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1338
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: BreadcrumbComponent, isStandalone: true, selector: "ymd-breadcrumb", host: { attributes: { "tabindex": "0" }, listeners: { "blur": "onBlur()", "keydown": "onKeydown($event)" }, classAttribute: "breadcrumb" }, viewQueries: [{ propertyName: "items", predicate: ListItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@let bread = breadcrumb();\n\n<nav aria-label=\"breadcrumb\">\n <ol>\n @if (bread.items.length) {\n <li>\n <a tabindex=\"-1\" yuvListItem draggable=\"false\" class=\"home\" href=\"\" (click)=\"navigation('root', $event)\">\n <yvc-icon [svg]=\"homeIcon\" title=\"{{ 'yuv.app.drive.folder-tree.mydrive' | translate }}\" />\n </a>\n </li>\n\n <div class=\"spacer\" aria-label=\"hidden\"></div>\n\n @if (bread.partial) {\n <div class=\"partial\" aria-label=\"hidden\"></div>\n <div class=\"spacer\" aria-label=\"hidden\"></div>\n }\n\n <li yvcDragScroll>\n <ol>\n @for (crumb of bread.items; track $index) {\n @if (!$last) {\n <li>\n <a tabindex=\"-1\" yuvListItem draggable=\"false\" href=\"\" (click)=\"navigation(crumb.id, $event)\">\n {{ crumb.name }}\n </a>\n </li>\n } @else {\n <li aria-current=\"location\">{{ crumb.name }}</li>\n }\n @if (!$last) {\n <div class=\"spacer\" aria-label=\"hidden\"></div>\n }\n }\n </ol>\n </li>\n } @else {\n <li aria-current=\"location\"><yvc-icon [svg]=\"homeIcon\" title=\"{{ 'yuv.app.drive.folder-tree.mydrive' | translate }}\" /></li>\n }\n </ol>\n</nav>\n", styles: ["@charset \"UTF-8\";:host{color:var(--text-color-caption)}:host [aria-label=breadcrumb]{overflow:hidden;display:flex;align-items:center}:host [aria-current=location],:host a.home{--icon-size: 18px;display:flex;align-items:center;justify-content:center}:host ol{list-style:none;margin:0;padding:0;align-items:center;display:flex;flex-wrap:nowrap}:host li{align-items:center;display:flex;white-space:nowrap;cursor:default}:host nav>ol{overflow:hidden}:host nav>ol li[yvcDragScroll]{overflow-x:auto;--scrollbar-outer-size: 0px;--scrollbar-inner-size: 0px}:host .spacer:after{content:\"\\bb\";display:block;margin:0 4px}:host .partial:after{content:\"...\";display:block;padding:4px}:host [aria-current=location],:host [yuvListItem]{margin:2px;padding:2px;line-height:1em}:host [yuvListItem]{text-decoration:none;white-space:nowrap;border-radius:2px;color:var(--text-color-caption)}:host [yuvListItem][aria-current=true],:host [yuvListItem]:hover{color:var(--text-color-body);background-color:var(--item-focus-background-color);outline:2px solid var(--item-focus-background-color)}:host [yuvListItem][aria-current=true]{outline-color:var(--text-color-caption)}\n"], dependencies: [{ kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: YvcDragScrollModule }, { kind: "directive", type: i2$1.DragScrollDirective, selector: "[yvcDragScroll]" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1350
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: BreadcrumbComponent, isStandalone: true, selector: "ymd-breadcrumb", host: { attributes: { "tabindex": "0" }, listeners: { "blur": "onBlur()", "keydown": "onKeydown($event)" }, classAttribute: "breadcrumb" }, viewQueries: [{ propertyName: "items", predicate: ListItemDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@let bread = breadcrumb();\n\n<nav aria-label=\"breadcrumb\">\n <ol>\n @if (bread.items.length) {\n <li>\n <a tabindex=\"-1\" yuvListItem draggable=\"false\" class=\"home\" href=\"\" (click)=\"navigation('root', $event)\">\n <yvc-icon [svg]=\"homeIcon\" title=\"{{ 'yuv.app.drive.folder-tree.mydrive' | translate }}\" />\n </a>\n </li>\n\n <div class=\"spacer\" aria-label=\"hidden\"></div>\n\n @if (bread.partial) {\n <div class=\"partial\" aria-label=\"hidden\"></div>\n <div class=\"spacer\" aria-label=\"hidden\"></div>\n }\n\n <li yvcDragScroll>\n <ol>\n @for (crumb of bread.items; track $index) {\n @if (!$last) {\n <li>\n <a tabindex=\"-1\" yuvListItem draggable=\"false\" href=\"\" (click)=\"navigation(crumb.id, $event)\">\n {{ crumb.name }}\n </a>\n </li>\n } @else {\n <li aria-current=\"location\">{{ crumb.name }}</li>\n }\n @if (!$last) {\n <div class=\"spacer\" aria-label=\"hidden\"></div>\n }\n }\n </ol>\n </li>\n } @else {\n <li aria-current=\"location\"><yvc-icon [svg]=\"homeIcon\" title=\"{{ 'yuv.app.drive.folder-tree.mydrive' | translate }}\" /></li>\n }\n </ol>\n</nav>\n", styles: ["@charset \"UTF-8\";:host{color:var(--text-color-caption)}:host [aria-label=breadcrumb]{overflow:hidden;display:flex;align-items:center}:host [aria-current=location],:host a.home{--icon-size: 18px;display:flex;align-items:center;justify-content:center}:host ol{list-style:none;margin:0;padding:0;align-items:center;display:flex;flex-wrap:nowrap}:host li{align-items:center;display:flex;white-space:nowrap;cursor:default}:host nav>ol{overflow:hidden}:host nav>ol li[yvcDragScroll]{overflow-x:auto;--scrollbar-outer-size: 0px;--scrollbar-inner-size: 0px}:host .spacer:after{content:\"\\bb\";display:block;margin:0 4px}:host .partial:after{content:\"...\";display:block;padding:4px}:host [aria-current=location],:host [yuvListItem]{margin:2px;padding:2px;line-height:1em}:host [yuvListItem]{text-decoration:none;white-space:nowrap;border-radius:2px;color:var(--text-color-caption)}:host [yuvListItem][aria-current=true],:host [yuvListItem]:hover{color:var(--text-color-body);background-color:var(--item-focus-background-color);outline:2px solid var(--item-focus-background-color)}:host [yuvListItem][aria-current=true]{outline-color:var(--text-color-caption)}\n"], dependencies: [{ kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: YvcDragScrollModule }, { kind: "directive", type: i2$1.DragScrollDirective, selector: "[yvcDragScroll]" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1339
1351
  }
1340
1352
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BreadcrumbComponent, decorators: [{
1341
1353
  type: Component,
@@ -1615,6 +1627,392 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1615
1627
  args: ['keydown', ['$event']]
1616
1628
  }] } });
1617
1629
 
1630
+ class DriveSearchOverlayComponent {
1631
+ #fb;
1632
+ #oRef;
1633
+ #shell;
1634
+ #system;
1635
+ #drive;
1636
+ #search;
1637
+ #query;
1638
+ #queryEffect;
1639
+ #initialFormData;
1640
+ constructor() {
1641
+ this.translate = inject(TranslateService$1);
1642
+ this.#fb = inject(FormBuilder);
1643
+ this.#oRef = inject(YvcOverlayRef);
1644
+ this.#shell = inject(ShellService);
1645
+ this.#system = inject(SystemService);
1646
+ this.#drive = inject(DriveService);
1647
+ this.#search = inject(SearchService);
1648
+ this.objectForms = viewChildren(ObjectFormComponent);
1649
+ this.ANY_OPTION = 'any';
1650
+ this.#query = this.#drive.state$.query;
1651
+ this.#queryEffect = effect(() => {
1652
+ const q = this.#query();
1653
+ if (q)
1654
+ this.filterForm.patchValue(this.#queryToForm(q));
1655
+ });
1656
+ this.icons = {
1657
+ arrow: ICONS.arrowDown,
1658
+ remove: ICONS.clear,
1659
+ unchecked: APP_DRIVE_ICONS.unchecked,
1660
+ checked: APP_DRIVE_ICONS.checked
1661
+ };
1662
+ this.#initialFormData = {};
1663
+ this.selectedFlavorsRec = {};
1664
+ this.formStates = {};
1665
+ this.flavorFormOptions = signal({});
1666
+ this.flavorForms = computed(() => {
1667
+ const ffo = this.flavorFormOptions() || {};
1668
+ return Object.keys(ffo).map((k) => ({
1669
+ id: k,
1670
+ icon: this.selectedFlavorsRec[k]?.icon,
1671
+ label: this.translate.instant(k),
1672
+ formOptions: ffo[k]
1673
+ }));
1674
+ });
1675
+ this.scopeOptions = signal([]);
1676
+ this.filterForm = this.#fb.nonNullable.group({
1677
+ term: [this.#oRef.data.term || ''],
1678
+ scope: [this.ANY_OPTION],
1679
+ modified: [],
1680
+ created: [],
1681
+ contentlength: []
1682
+ });
1683
+ this.searchTokens = [];
1684
+ this.flavors = this.#shell.getObjectFlavors().map((f) => ({ ...f, label: this.translate.instant(f.id) }));
1685
+ this.translate.onLangChange.pipe(takeUntilDestroyed()).subscribe((_) => this.#setupOptions());
1686
+ this.#setupOptions();
1687
+ this.filterForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((v) => this.#onFormValueChange(v));
1688
+ }
1689
+ typeSelected(idx) {
1690
+ this.#toggleType(this.flavors[idx[0]]);
1691
+ }
1692
+ #toggleType(t) {
1693
+ if (this.selectedFlavorsRec[t.id]) {
1694
+ delete this.selectedFlavorsRec[t.id];
1695
+ const ffo = this.flavorFormOptions() || {};
1696
+ delete ffo[t.id];
1697
+ this.flavorFormOptions.set({ ...ffo });
1698
+ delete this.formStates[t.id];
1699
+ this.#getCombinedFormState();
1700
+ }
1701
+ else {
1702
+ this.selectedFlavorsRec[t.id] = t;
1703
+ this.#system.getObjectTypeForm(t.sot, Situation.SEARCH).subscribe((formModel) => {
1704
+ this.flavorFormOptions.set({
1705
+ ...this.flavorFormOptions(),
1706
+ [t.id]: {
1707
+ formModel,
1708
+ data: {}
1709
+ }
1710
+ });
1711
+ });
1712
+ }
1713
+ }
1714
+ // initial setup of types/flavors
1715
+ #setTypes(sots) {
1716
+ const sotQA = {};
1717
+ this.flavors
1718
+ .filter((f) => sots.includes(f.sot))
1719
+ .forEach((f) => {
1720
+ this.selectedFlavorsRec[f.id] = f;
1721
+ sotQA[f.sot] = f.id;
1722
+ });
1723
+ this.#system
1724
+ .getObjectTypeForms(sots, Situation.SEARCH)
1725
+ .pipe(finalize$1(() => (this.#initialFormData = {})))
1726
+ .subscribe((forms) => {
1727
+ const ffo = {};
1728
+ Object.keys(forms).forEach((sot) => {
1729
+ ffo[sotQA[sot]] = {
1730
+ formModel: forms[sot],
1731
+ data: this.#initialFormData
1732
+ };
1733
+ });
1734
+ this.flavorFormOptions.set(ffo);
1735
+ });
1736
+ }
1737
+ onFormStatusChanged(formId, evt) {
1738
+ this.formStates[formId] = evt;
1739
+ this.#getCombinedFormState();
1740
+ }
1741
+ #onFormValueChange(v) {
1742
+ this.searchTokens = [];
1743
+ if (this.filterForm.value.term) {
1744
+ this.searchTokens.push({
1745
+ fromControlName: 'term',
1746
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.term', { value: this.filterForm.value.term })
1747
+ });
1748
+ }
1749
+ const created = this.filterForm.value.created;
1750
+ if (created) {
1751
+ this.searchTokens.push({
1752
+ fromControlName: 'created',
1753
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.created', { value: created.label })
1754
+ });
1755
+ }
1756
+ const modified = this.filterForm.value.modified;
1757
+ if (modified) {
1758
+ this.searchTokens.push({
1759
+ fromControlName: 'modified',
1760
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.modified', { value: modified.label })
1761
+ });
1762
+ }
1763
+ const contentlength = this.filterForm.value.contentlength;
1764
+ if (contentlength) {
1765
+ this.searchTokens.push({
1766
+ fromControlName: 'contentlength',
1767
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.contentlength', { value: contentlength.label })
1768
+ });
1769
+ }
1770
+ if (this.filterForm.value.scope !== this.ANY_OPTION && this.filterForm.value.term) {
1771
+ const o = this.scopeOptions().find((o) => o.value === this.filterForm.value.scope);
1772
+ if (o)
1773
+ this.searchTokens.push({
1774
+ fromControlName: 'scope',
1775
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.where', { value: o.label })
1776
+ });
1777
+ }
1778
+ }
1779
+ removeSearchToken(t) {
1780
+ this.filterForm.patchValue({
1781
+ [t.fromControlName]: t.fromControlName === 'term' ? '' : this.ANY_OPTION
1782
+ });
1783
+ }
1784
+ #getCombinedFormState() {
1785
+ const combinedFormState = {
1786
+ dirty: false,
1787
+ indexdataChanged: false,
1788
+ invalid: false,
1789
+ data: {}
1790
+ };
1791
+ Object.values(this.formStates).forEach((s) => {
1792
+ if (s.dirty) {
1793
+ combinedFormState.dirty = s.dirty;
1794
+ }
1795
+ if (s.indexdataChanged) {
1796
+ combinedFormState.indexdataChanged = s.indexdataChanged;
1797
+ }
1798
+ if (s.invalid) {
1799
+ combinedFormState.invalid = s.invalid;
1800
+ }
1801
+ combinedFormState.data = { ...combinedFormState.data, ...s.data };
1802
+ });
1803
+ this.combinedFormState = combinedFormState;
1804
+ return this.combinedFormState;
1805
+ }
1806
+ cancel() {
1807
+ this.#oRef?.close();
1808
+ }
1809
+ submit() {
1810
+ this.#oRef?.close(this.#formToQuery());
1811
+ }
1812
+ //Converts the form values to a search query
1813
+ #formToQuery() {
1814
+ const filters = this.#search.formDataToSearchFilter(this.#getCombinedFormState().data);
1815
+ // types
1816
+ const sots = Object.values(this.selectedFlavorsRec).map((f) => f.sot);
1817
+ if (sots.length) {
1818
+ filters.push({
1819
+ f: BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS,
1820
+ o: Operator.IN,
1821
+ v1: sots
1822
+ });
1823
+ }
1824
+ // created
1825
+ if (this.filterForm.value.created) {
1826
+ const df = this.#search.rangeValueToSearchFilter(this.filterForm.value.created.rangeValue, BaseObjectTypeField.CREATION_DATE);
1827
+ df && filters.push(df);
1828
+ }
1829
+ // modified
1830
+ if (this.filterForm.value.modified) {
1831
+ const df = this.#search.rangeValueToSearchFilter(this.filterForm.value.modified.rangeValue, BaseObjectTypeField.MODIFICATION_DATE);
1832
+ df && filters.push(df);
1833
+ }
1834
+ // content length
1835
+ if (this.filterForm.value.contentlength) {
1836
+ const df = this.#search.rangeValueToSearchFilter(this.filterForm.value.contentlength.rangeValue, ContentStreamField.LENGTH);
1837
+ df && filters.push(df);
1838
+ }
1839
+ const searchQuery = {
1840
+ term: this.filterForm.value.term,
1841
+ filters
1842
+ };
1843
+ // search scope
1844
+ if (this.filterForm.value.scope !== this.ANY_OPTION)
1845
+ searchQuery.scope = this.filterForm.value.scope;
1846
+ return searchQuery;
1847
+ }
1848
+ /**
1849
+ * Converts the form values to a search query
1850
+ * @param q The search query
1851
+ */
1852
+ #queryToForm(q) {
1853
+ const patch = {};
1854
+ if (q?.term)
1855
+ patch['term'] = q.term;
1856
+ if (q?.scope)
1857
+ patch['scope'] = q.scope;
1858
+ q?.filters?.forEach((f) => {
1859
+ switch (f.f) {
1860
+ case BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS: {
1861
+ const sots = f.v1;
1862
+ // filter by available flavors
1863
+ const flavorSots = this.flavors.map((f) => f.sot);
1864
+ this.#setTypes(sots.filter((sot) => flavorSots.includes(sot)));
1865
+ break;
1866
+ }
1867
+ case BaseObjectTypeField.CREATION_DATE: {
1868
+ const rsv = {
1869
+ rangeValue: {
1870
+ operator: f.o,
1871
+ firstValue: f.v1,
1872
+ secondValue: f.v2
1873
+ }
1874
+ };
1875
+ patch['created'] = rsv;
1876
+ break;
1877
+ }
1878
+ case BaseObjectTypeField.MODIFICATION_DATE: {
1879
+ const rsv = {
1880
+ rangeValue: {
1881
+ operator: f.o,
1882
+ firstValue: f.v1,
1883
+ secondValue: f.v2
1884
+ }
1885
+ };
1886
+ patch['modified'] = rsv;
1887
+ break;
1888
+ }
1889
+ case ContentStreamField.LENGTH: {
1890
+ const rsv = {
1891
+ rangeValue: {
1892
+ operator: f.o,
1893
+ firstValue: f.v1,
1894
+ secondValue: f.v2
1895
+ }
1896
+ };
1897
+ patch['contentlength'] = rsv;
1898
+ break;
1899
+ }
1900
+ default: {
1901
+ // check for values to inject into flavor forms
1902
+ this.#initialFormData[f.f] = f.v1;
1903
+ }
1904
+ }
1905
+ });
1906
+ return patch;
1907
+ }
1908
+ #setupOptions() {
1909
+ this.#setupScopeOptions();
1910
+ }
1911
+ #setupScopeOptions() {
1912
+ this.scopeOptions.set([
1913
+ {
1914
+ label: this.translate.instant('yuv.app.drive.search.filter.option.where.any'),
1915
+ value: this.ANY_OPTION
1916
+ },
1917
+ {
1918
+ label: this.translate.instant('yuv.app.drive.search.filter.option.where.content'),
1919
+ value: 'content'
1920
+ },
1921
+ {
1922
+ label: this.translate.instant('yuv.app.drive.search.filter.option.where.metadata'),
1923
+ value: 'metadata'
1924
+ }
1925
+ ]);
1926
+ }
1927
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1928
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DriveSearchOverlayComponent, isStandalone: true, selector: "ymd-drive-search-overlay", viewQueries: [{ propertyName: "objectForms", predicate: ObjectFormComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<main>\n <yvc-split-view [gutterSize]=\"1\" [layoutSettingsID]=\"'yuv.app.drive.search.meta.splitview'\">\n <!-- search options -->\n <ng-template yvcSplitArea [size]=\"40\">\n <form class=\"options\" [formGroup]=\"filterForm\">\n <!-- term and scope -->\n <h2>{{ 'yuv.app.drive.search.meta.options.term' | translate }}</h2>\n <input class=\"term\" type=\"text\" formControlName=\"term\" />\n\n <h2>{{ 'yuv.app.drive.search.meta.options.where' | translate }}</h2>\n <yvc-dropdown formControlName=\"scope\" \n [disabled]=\"!filterForm.value.term\"\n [options]=\"scopeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n\n <!-- types -->\n <h2>{{ 'yuv.app.drive.search.meta.options.type' | translate }}</h2>\n <yuv-list (itemSelect)=\"typeSelected($event)\" [selfHandleSelection]=\"true\">\n @for (t of flavors; track t.id) {\n <div class=\"type\" yuvListItem [ngClass]=\"{ selected: !!selectedFlavorsRec[t.id] }\">\n <yvc-icon [svg]=\"!!selectedFlavorsRec[t.id] ? icons.checked : icons.unchecked\"></yvc-icon>\n {{ t.label }}\n </div>\n }\n </yuv-list>\n\n <!-- created -->\n <h2>{{ 'yuv.app.drive.search.meta.options.created' | translate }}</h2>\n <yuv-range-select-date formControlName=\"created\"></yuv-range-select-date>\n\n <!-- modified -->\n <h2>{{ 'yuv.app.drive.search.meta.options.modified' | translate }}</h2>\n <yuv-range-select-date formControlName=\"modified\"></yuv-range-select-date>\n \n <!-- content length -->\n <h2>{{ 'yuv.app.drive.search.meta.options.contentlength' | translate }}</h2>\n <yuv-range-select-filesize formControlName=\"contentlength\"></yuv-range-select-filesize>\n </form>\n </ng-template>\n\n <ng-template yvcSplitArea [size]=\"60\">\n <div class=\"query\">\n <h1>{{ 'yuv.app.drive.search.meta.headline.query' | translate }}</h1>\n\n <div class=\"tokens\">\n @if (flavorForms().length === 0 && !filterForm.value.term) {\n <p>{{ 'yuv.app.drive.search.meta.query.for-everything' | translate }}</p>\n }\n @for (o of flavorForms(); track $index) {\n <details class=\"token\">\n <summary [ngClass]=\"{dirty: formStates[o.id]?.dirty}\">\n <yvc-icon [svg]=\"o.icon\"></yvc-icon>\n {{ o.label }}\n <yvc-icon class=\"arr\" [svg]=\"icons.arrow\"></yvc-icon>\n </summary>\n <yuv-object-form [formOptions]=\"o.formOptions\"\n (statusChanged)=\"onFormStatusChanged(o.id, $event)\"></yuv-object-form>\n </details>\n }\n @for (t of searchTokens; track $index) {\n <div class=\"searchToken token\">\n {{ t.label }}\n <button class=\"icon\" (click)=\"removeSearchToken(t)\">\n <yvc-icon [svg]=\"icons.remove\"></yvc-icon>\n </button>\n </div>\n }\n </div>\n </div>\n </ng-template>\n </yvc-split-view>\n</main>\n\n<footer>\n <button type=\"button\" class=\"secondary\" (click)=\"cancel()\">{{ 'yuv.app.drive.search.meta.button.cancel' | translate }}</button>\n <button type=\"submit\" class=\"primary\" (click)=\"submit()\">{{ 'yuv.app.drive.search.meta.button.search' | translate }}</button>\n</footer>\n", styles: [":host{display:flex;flex-flow:column;height:100%;overflow:hidden}:host main{flex:1;overflow:hidden}:host main yvc-split-view{height:100%}:host main .query{background-color:var(--panel-background-grey);height:100%;box-sizing:border-box;overflow-y:auto;padding:var(--app-pane-padding)}:host main .query h1{font-size:var(--font-display);font-weight:400;margin:.5rem 0 1rem;color:var(--text-color-caption)}:host main .query .tokens{display:flex;flex-flow:row wrap;align-items:start;gap:var(--app-pane-padding)}:host main .query .tokens>.token{background-color:var(--panel-background);border:1px solid var(--panel-divider-color);animation:searchTokenEnter .2s ease-in-out forwards;box-sizing:border-box;color:var(--text-color-caption);border-radius:4px}:host main .query .tokens details{width:var(--om-section-max-width);max-width:100%}:host main .query .tokens details[open]{width:100%}:host main .query .tokens details[open] yvc-icon.arr{transform:rotate(180deg)}:host main .query .tokens details summary{padding:calc(var(--app-pane-padding) / 2);padding-inline-end:calc(var(--app-pane-padding) * 2);cursor:pointer;display:flex;align-items:center;position:relative;font-weight:700}:host main .query .tokens details summary.dirty:after{content:\"\";width:.5em;height:.5em;border-radius:50%;background-color:rgb(from var(--color-accent) r g b/.8);margin-inline-start:.5em;align-self:start}:host main .query .tokens details summary::marker{display:none}:host main .query .tokens details summary yvc-icon{--icon-size: 18px;margin-inline-end:calc(var(--app-pane-padding) / 2)}:host main .query .tokens details summary yvc-icon.arr{position:absolute;inset-inline-end:0}:host main .query .tokens .searchToken{padding:calc(var(--app-pane-padding) / 2);gap:calc(var(--app-pane-padding) / 2);cursor:pointer;display:flex;align-items:center;line-height:1em;font-weight:700}:host main .query .tokens .searchToken button{padding:0;border:0;--icon-size: 18px}:host main form.options{padding:var(--app-pane-padding);overflow-y:auto;display:flex;flex-flow:column}:host main form.options [aria-disabled=true]{cursor:default;opacity:.5}:host main form.options h2{font-size:var(--font-subhead);font-weight:400}:host main form.options input.term{border:1px solid var(--text-color-hint);padding:.5em;outline-offset:0}:host main form.options input.term:focus{border-color:var(--color-accent);outline:2px solid rgb(from var(--color-accent) r g b/.3)}:host main form.options .type:hover,:host main form.options yuv-list:focus .type[aria-current=true]{background-color:var(--item-focus-background-color)}:host main form.options yvc-dropdown,:host main form.options yuv-range-select-filesize,:host main form.options yuv-range-select-date{cursor:pointer}:host main form.options .type{display:flex;gap:var(--app-pane-padding);align-items:center;padding:calc(var(--app-pane-padding) / 2);cursor:pointer}:host main form.options .type yvc-icon{color:var(--text-color-caption)}:host footer{flex:0 0 auto;display:flex;border-block-start:1px solid var(--panel-divider-color);align-items:center;justify-content:flex-end;gap:calc(var(--app-pane-padding) / 2);padding:var(--app-pane-padding)}@keyframes searchTokenEnter{0%{opacity:0;transform:translateY(.5em)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: YvcDropdownModule }, { kind: "component", type: i2$2.Dropdown, selector: "yvc-dropdown", inputs: ["options", "filter", "disabled", "multiple", "disableClearButton"], outputs: ["onDropdownOptionsClose"] }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: ObjectFormComponent, selector: "yuv-object-form", inputs: ["formOptions", "inert", "elementExtensions", "isInnerTableForm"], outputs: ["statusChanged", "onFormReady"] }, { kind: "ngmodule", type: YvcSplitViewModule }, { kind: "component", type: i3.SplitViewComponent, selector: "yvc-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "gutterDblClickDuration", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "directive", type: i3.SplitAreaDirective, selector: "[yvcSplitArea]", inputs: ["size", "order", "minSize", "maxSize", "panelClass", "visible"] }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: YvcCheckboxModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ListComponent, selector: "yuv-list", inputs: ["multiselect", "selfHandleSelection", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "component", type: RangeSelectDateComponent, selector: "yuv-range-select-date", inputs: ["ranges", "customRange"] }, { kind: "component", type: RangeSelectFilesizeComponent, selector: "yuv-range-select-filesize", inputs: ["ranges"] }] }); }
1929
+ }
1930
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchOverlayComponent, decorators: [{
1931
+ type: Component,
1932
+ args: [{ selector: 'ymd-drive-search-overlay', standalone: true, imports: [
1933
+ CommonModule,
1934
+ YvcDropdownModule,
1935
+ TranslateModule$1,
1936
+ ObjectFormComponent,
1937
+ YvcSplitViewModule,
1938
+ YvcIconModule,
1939
+ YvcCheckboxModule,
1940
+ ReactiveFormsModule,
1941
+ ListComponent,
1942
+ ListItemDirective,
1943
+ RangeSelectDateComponent,
1944
+ RangeSelectFilesizeComponent
1945
+ ], template: "<main>\n <yvc-split-view [gutterSize]=\"1\" [layoutSettingsID]=\"'yuv.app.drive.search.meta.splitview'\">\n <!-- search options -->\n <ng-template yvcSplitArea [size]=\"40\">\n <form class=\"options\" [formGroup]=\"filterForm\">\n <!-- term and scope -->\n <h2>{{ 'yuv.app.drive.search.meta.options.term' | translate }}</h2>\n <input class=\"term\" type=\"text\" formControlName=\"term\" />\n\n <h2>{{ 'yuv.app.drive.search.meta.options.where' | translate }}</h2>\n <yvc-dropdown formControlName=\"scope\" \n [disabled]=\"!filterForm.value.term\"\n [options]=\"scopeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n\n <!-- types -->\n <h2>{{ 'yuv.app.drive.search.meta.options.type' | translate }}</h2>\n <yuv-list (itemSelect)=\"typeSelected($event)\" [selfHandleSelection]=\"true\">\n @for (t of flavors; track t.id) {\n <div class=\"type\" yuvListItem [ngClass]=\"{ selected: !!selectedFlavorsRec[t.id] }\">\n <yvc-icon [svg]=\"!!selectedFlavorsRec[t.id] ? icons.checked : icons.unchecked\"></yvc-icon>\n {{ t.label }}\n </div>\n }\n </yuv-list>\n\n <!-- created -->\n <h2>{{ 'yuv.app.drive.search.meta.options.created' | translate }}</h2>\n <yuv-range-select-date formControlName=\"created\"></yuv-range-select-date>\n\n <!-- modified -->\n <h2>{{ 'yuv.app.drive.search.meta.options.modified' | translate }}</h2>\n <yuv-range-select-date formControlName=\"modified\"></yuv-range-select-date>\n \n <!-- content length -->\n <h2>{{ 'yuv.app.drive.search.meta.options.contentlength' | translate }}</h2>\n <yuv-range-select-filesize formControlName=\"contentlength\"></yuv-range-select-filesize>\n </form>\n </ng-template>\n\n <ng-template yvcSplitArea [size]=\"60\">\n <div class=\"query\">\n <h1>{{ 'yuv.app.drive.search.meta.headline.query' | translate }}</h1>\n\n <div class=\"tokens\">\n @if (flavorForms().length === 0 && !filterForm.value.term) {\n <p>{{ 'yuv.app.drive.search.meta.query.for-everything' | translate }}</p>\n }\n @for (o of flavorForms(); track $index) {\n <details class=\"token\">\n <summary [ngClass]=\"{dirty: formStates[o.id]?.dirty}\">\n <yvc-icon [svg]=\"o.icon\"></yvc-icon>\n {{ o.label }}\n <yvc-icon class=\"arr\" [svg]=\"icons.arrow\"></yvc-icon>\n </summary>\n <yuv-object-form [formOptions]=\"o.formOptions\"\n (statusChanged)=\"onFormStatusChanged(o.id, $event)\"></yuv-object-form>\n </details>\n }\n @for (t of searchTokens; track $index) {\n <div class=\"searchToken token\">\n {{ t.label }}\n <button class=\"icon\" (click)=\"removeSearchToken(t)\">\n <yvc-icon [svg]=\"icons.remove\"></yvc-icon>\n </button>\n </div>\n }\n </div>\n </div>\n </ng-template>\n </yvc-split-view>\n</main>\n\n<footer>\n <button type=\"button\" class=\"secondary\" (click)=\"cancel()\">{{ 'yuv.app.drive.search.meta.button.cancel' | translate }}</button>\n <button type=\"submit\" class=\"primary\" (click)=\"submit()\">{{ 'yuv.app.drive.search.meta.button.search' | translate }}</button>\n</footer>\n", styles: [":host{display:flex;flex-flow:column;height:100%;overflow:hidden}:host main{flex:1;overflow:hidden}:host main yvc-split-view{height:100%}:host main .query{background-color:var(--panel-background-grey);height:100%;box-sizing:border-box;overflow-y:auto;padding:var(--app-pane-padding)}:host main .query h1{font-size:var(--font-display);font-weight:400;margin:.5rem 0 1rem;color:var(--text-color-caption)}:host main .query .tokens{display:flex;flex-flow:row wrap;align-items:start;gap:var(--app-pane-padding)}:host main .query .tokens>.token{background-color:var(--panel-background);border:1px solid var(--panel-divider-color);animation:searchTokenEnter .2s ease-in-out forwards;box-sizing:border-box;color:var(--text-color-caption);border-radius:4px}:host main .query .tokens details{width:var(--om-section-max-width);max-width:100%}:host main .query .tokens details[open]{width:100%}:host main .query .tokens details[open] yvc-icon.arr{transform:rotate(180deg)}:host main .query .tokens details summary{padding:calc(var(--app-pane-padding) / 2);padding-inline-end:calc(var(--app-pane-padding) * 2);cursor:pointer;display:flex;align-items:center;position:relative;font-weight:700}:host main .query .tokens details summary.dirty:after{content:\"\";width:.5em;height:.5em;border-radius:50%;background-color:rgb(from var(--color-accent) r g b/.8);margin-inline-start:.5em;align-self:start}:host main .query .tokens details summary::marker{display:none}:host main .query .tokens details summary yvc-icon{--icon-size: 18px;margin-inline-end:calc(var(--app-pane-padding) / 2)}:host main .query .tokens details summary yvc-icon.arr{position:absolute;inset-inline-end:0}:host main .query .tokens .searchToken{padding:calc(var(--app-pane-padding) / 2);gap:calc(var(--app-pane-padding) / 2);cursor:pointer;display:flex;align-items:center;line-height:1em;font-weight:700}:host main .query .tokens .searchToken button{padding:0;border:0;--icon-size: 18px}:host main form.options{padding:var(--app-pane-padding);overflow-y:auto;display:flex;flex-flow:column}:host main form.options [aria-disabled=true]{cursor:default;opacity:.5}:host main form.options h2{font-size:var(--font-subhead);font-weight:400}:host main form.options input.term{border:1px solid var(--text-color-hint);padding:.5em;outline-offset:0}:host main form.options input.term:focus{border-color:var(--color-accent);outline:2px solid rgb(from var(--color-accent) r g b/.3)}:host main form.options .type:hover,:host main form.options yuv-list:focus .type[aria-current=true]{background-color:var(--item-focus-background-color)}:host main form.options yvc-dropdown,:host main form.options yuv-range-select-filesize,:host main form.options yuv-range-select-date{cursor:pointer}:host main form.options .type{display:flex;gap:var(--app-pane-padding);align-items:center;padding:calc(var(--app-pane-padding) / 2);cursor:pointer}:host main form.options .type yvc-icon{color:var(--text-color-caption)}:host footer{flex:0 0 auto;display:flex;border-block-start:1px solid var(--panel-divider-color);align-items:center;justify-content:flex-end;gap:calc(var(--app-pane-padding) / 2);padding:var(--app-pane-padding)}@keyframes searchTokenEnter{0%{opacity:0;transform:translateY(.5em)}to{opacity:1;transform:translateY(0)}}\n"] }]
1946
+ }], ctorParameters: () => [] });
1947
+
1948
+ class DriveSearchComponent {
1949
+ constructor() {
1950
+ this.translate = inject(TranslateService$1);
1951
+ this.#overlay = inject(YvcOverlayService);
1952
+ this.#router = inject(Router);
1953
+ this.#route = inject(ActivatedRoute);
1954
+ this.#drive = inject(DriveService);
1955
+ this.icons = {
1956
+ extendedSearch: APP_DRIVE_ICONS.extendedSearch,
1957
+ clear: ICONS.clear
1958
+ };
1959
+ this.query = this.#drive.state$.query;
1960
+ this.extendedQuery = this.#drive.state$.extendedQuery;
1961
+ this.currentFolder = this.#drive.state$.currentFolder;
1962
+ this.term = '';
1963
+ }
1964
+ #overlay;
1965
+ #router;
1966
+ #route;
1967
+ #drive;
1968
+ #oRef;
1969
+ openModal(event) {
1970
+ event.stopPropagation();
1971
+ this.#oRef = this.#overlay.open(DriveSearchOverlayComponent, {
1972
+ term: this.term
1973
+ }, {
1974
+ width: '90vw',
1975
+ height: '90vh'
1976
+ });
1977
+ this.#oRef.afterClosed$.subscribe((res) => {
1978
+ if (res.data) {
1979
+ const q = res.data;
1980
+ this.onQuerySubmit(res.data, !!q.filters?.length || !!q.scope);
1981
+ }
1982
+ });
1983
+ }
1984
+ clear() {
1985
+ console.log(this.currentFolder());
1986
+ this.#router.navigate(['..', this.currentFolder() || DRIVE_ROOT_FOLDER_ID], {
1987
+ relativeTo: this.#route
1988
+ });
1989
+ }
1990
+ onQueryChange(q) {
1991
+ this.term = q.term || '';
1992
+ }
1993
+ onQuerySubmit(q, ext = false) {
1994
+ // in order to keep the query in the url as short as
1995
+ // possible we'll get rid of the fields because they could be
1996
+ // re-applied later on
1997
+ q.fields = undefined;
1998
+ this.#router.navigate(['..', 'query'], {
1999
+ queryParams: {
2000
+ q: encodeURIComponent(JSON.stringify(q)),
2001
+ ext
2002
+ },
2003
+ relativeTo: this.#route
2004
+ });
2005
+ }
2006
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2007
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DriveSearchComponent, isStandalone: true, selector: "ymd-drive-search", host: { properties: { "class.active": "extendedQuery()" } }, ngImport: i0, template: "<div class=\"extSearch\">\n <button class=\"icon\" (click)=\"openModal($event)\">\n <yvc-icon [svg]=\"icons.extendedSearch\"></yvc-icon>\n </button> \n <button class=\"icon clear\" (click)=\"clear()\">\n <yvc-icon [svg]=\"icons.clear\"></yvc-icon>\n </button>\n</div>\n<yuv-simple-search [query]=\"query()\" \n(queryChange)=\"onQueryChange($event)\"\n(querySubmit)=\"onQuerySubmit($event)\"></yuv-simple-search>", styles: [":host{display:flex;align-items:center;border:1px solid var(--panel-divider-color);--icon-size: 18px}:host.active .extSearch{background-color:var(--color-accent)}:host.active .extSearch button{color:var(--color-accent-tone)}:host.active .extSearch button.clear{display:flex}:host .extSearch{display:flex;align-items:center;margin:1px;padding:1px}:host .extSearch button{padding:calc(var(--app-pane-padding) / 4 - 2px)}:host .extSearch button.clear{--icon-size: 14px;margin-inline:2px;padding:0;display:none}:host yuv-simple-search{flex:1;border:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "component", type: SimpleSearchComponent, selector: "yuv-simple-search", inputs: ["targets", "query"], outputs: ["querySubmit", "targetSelectionChanged", "queryChange", "typeAggregation"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }] }); }
2008
+ }
2009
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchComponent, decorators: [{
2010
+ type: Component,
2011
+ args: [{ selector: 'ymd-drive-search', standalone: true, imports: [CommonModule, TranslateModule$1, FocusWithinDirective, SimpleSearchComponent, DriveSearchOverlayComponent, ReactiveFormsModule, YvcIconModule], host: {
2012
+ '[class.active]': 'extendedQuery()'
2013
+ }, template: "<div class=\"extSearch\">\n <button class=\"icon\" (click)=\"openModal($event)\">\n <yvc-icon [svg]=\"icons.extendedSearch\"></yvc-icon>\n </button> \n <button class=\"icon clear\" (click)=\"clear()\">\n <yvc-icon [svg]=\"icons.clear\"></yvc-icon>\n </button>\n</div>\n<yuv-simple-search [query]=\"query()\" \n(queryChange)=\"onQueryChange($event)\"\n(querySubmit)=\"onQuerySubmit($event)\"></yuv-simple-search>", styles: [":host{display:flex;align-items:center;border:1px solid var(--panel-divider-color);--icon-size: 18px}:host.active .extSearch{background-color:var(--color-accent)}:host.active .extSearch button{color:var(--color-accent-tone)}:host.active .extSearch button.clear{display:flex}:host .extSearch{display:flex;align-items:center;margin:1px;padding:1px}:host .extSearch button{padding:calc(var(--app-pane-padding) / 4 - 2px)}:host .extSearch button.clear{--icon-size: 14px;margin-inline:2px;padding:0;display:none}:host yuv-simple-search{flex:1;border:0}\n"] }]
2014
+ }] });
2015
+
1618
2016
  const COMPONENTS = [VersionsListComponent, ObjectSummaryDataComponent, ObjectPreviewComponent];
1619
2017
  const MODULES = [YvcIconModule, YvcTabsModule, YvcSplitViewModule, TranslateModule];
1620
2018
  class ManageVersionsComponent {
@@ -1693,7 +2091,7 @@ class ManageVersionsComponent {
1693
2091
  this.#drive.clearVersions();
1694
2092
  }
1695
2093
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ManageVersionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1696
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ManageVersionsComponent, isStandalone: true, selector: "ymd-manage-versions", ngImport: i0, template: "@if (isLoading()) {\n <div class=\"yuv-loader-linear loader\"></div>\n}\n<yvc-split-view [gutterSize]=\"1\" [layoutSettingsID]=\"layoutSettingIdBase + 'split'\">\n <!-- Versions -->\n <ng-template yvcSplitArea [size]=\"60\">\n <div class=\"version-details\">\n <header>\n <span>{{ dmsObject().name }}</span>\n </header>\n <div class=\"details\">\n @let selected = selectedVersion();\n @if (selected && selected.length === 1) {\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs'\" class=\"versions-details\">\n <ng-template [yvcTab]=\"{ id: 'content', label: 'yuv.app.drive.object-metadata.tabs.content.title' | translate }\">\n <yuv-object-preview [dmsObject]=\"selected[0]\" [version]=\"selected[0].version\"></yuv-object-preview>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'indexdata', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-summary-data [dmsObject]=\"selected[0]\"></yuv-object-summary-data>\n </ng-template>\n </yvc-tabs>\n }\n </div>\n </div>\n </ng-template>\n <!-- Details -->\n <ng-template yvcSplitArea [size]=\"40\">\n <div class=\"versions\">\n <header>\n <h2>{{ 'yuv.app.drive.versions.header.label' | translate }}</h2>\n <div class=\"actions\">\n <button class=\"refresh\" title=\"refresh\" (click)=\"reloadList()\"><yvc-icon [svg]=\"icons.refresh\"></yvc-icon></button>\n <button class=\"close\" title=\"close\" (click)=\"close()\"><yvc-icon [svg]=\"icons.close\"></yvc-icon></button>\n </div>\n </header>\n <ymd-versions-list\n class=\"staggered\"\n [attr.aria-label]=\"'yuv.app.drive.files.content.aria.label' | translate\"\n [attr.aria-busy]=\"isLoading()\"\n [attr.role]=\"'listbox'\"\n [id]=\"id()\"\n > \n </ymd-versions-list>\n </div>\n </ng-template>\n</yvc-split-view>\n<footer>\n <div class=\"actions\">\n <button class=\"secondary\" [disabled]=\"disabledRestore()\" (click)=\"setNewVersion()\">{{ 'yuv.app.drive.action.set.new.versions.label' | translate }}</button>\n </div>\n</footer>\n", styles: [":host{height:100%;display:grid;grid-auto-columns:1fr;grid-auto-rows:1fr;grid-template-columns:1.7fr;grid-template-rows:.1px 2.7fr .2fr;gap:0px 0px;grid-template-areas:\"loader\" \"content\" \"footer\"}:host .loader{grid-area:loader}:host yvc-split-view{grid-area:content;height:100%}:host header{display:grid;grid-template-columns:2fr max-content;grid-template-rows:1fr max-content;gap:0px 0px;grid-auto-flow:row;grid-template-areas:\"label actions\" \"title title\";padding:var(--app-pane-padding);align-items:center}:host header span{font-size:var(--font-headline);font-weight:var(--font-weight-bold)}:host .versions,:host .version-details{display:flex;flex-flow:column;height:100%}:host .version-details .details{flex:1;overflow-y:hidden}:host .versions header{border-bottom:1px solid var(--panel-divider-color);padding-top:0}:host .versions .label{grid-area:label}:host .versions .actions{grid-area:actions;display:flex;justify-content:center;align-items:center}:host .versions .actions button{padding:0}:host .versions .title{grid-area:title}:host .versions .staggered{flex:1;overflow-y:scroll}:host .versions-details{height:100%}:host footer{grid-area:footer;display:flex;justify-content:flex-end;align-items:center;background:var(--panel-background);border-top:1px solid var(--panel-divider-color);gap:calc(var(--app-pane-padding) / 4);padding:calc(var(--app-pane-padding) / 2)}\n"], dependencies: [{ kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: YvcTabsModule }, { kind: "component", type: i2$2.Tabs, selector: "yvc-tabs", inputs: ["tabs", "layoutSettingsID", "panelOrder", "panelOrderIncludeUnmentioned", "cacheViews", "tabSplitEnabled", "tabRemoveEnabled"], outputs: ["tabSplit", "tabRemove", "tabChange"] }, { kind: "directive", type: i2$2.YvcTabDirective, selector: "[yvcTab]", inputs: ["yvcTab"] }, { kind: "ngmodule", type: YvcSplitViewModule }, { kind: "component", type: i3.SplitViewComponent, selector: "yvc-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "gutterDblClickDuration", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "directive", type: i3.SplitAreaDirective, selector: "[yvcSplitArea]", inputs: ["size", "order", "minSize", "maxSize", "panelClass", "visible"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: VersionsListComponent, selector: "ymd-versions-list" }, { kind: "component", type: ObjectSummaryDataComponent, selector: "yuv-object-summary-data", inputs: ["dmsObject"] }, { kind: "component", type: ObjectPreviewComponent, selector: "yuv-object-preview", inputs: ["objectId", "dmsObject", "version"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2094
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ManageVersionsComponent, isStandalone: true, selector: "ymd-manage-versions", ngImport: i0, template: "@if (isLoading()) {\n <div class=\"yuv-loader-linear loader\"></div>\n}\n<yvc-split-view [gutterSize]=\"1\" [layoutSettingsID]=\"layoutSettingIdBase + 'split'\">\n <!-- Versions -->\n <ng-template yvcSplitArea [size]=\"60\">\n <div class=\"version-details\">\n <header>\n <span>{{ dmsObject().name }}</span>\n </header>\n <div class=\"details\">\n @let selected = selectedVersion();\n @if (selected && selected.length === 1) {\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs'\" class=\"versions-details\">\n <ng-template [yvcTab]=\"{ id: 'content', label: 'yuv.app.drive.object-metadata.tabs.content.title' | translate }\">\n <yuv-object-preview [dmsObject]=\"selected[0]\" [version]=\"selected[0].version\"></yuv-object-preview>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'indexdata', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-summary-data [dmsObject]=\"selected[0]\"></yuv-object-summary-data>\n </ng-template>\n </yvc-tabs>\n }\n </div>\n </div>\n </ng-template>\n <!-- Details -->\n <ng-template yvcSplitArea [size]=\"40\">\n <div class=\"versions\">\n <header>\n <h2>{{ 'yuv.app.drive.versions.header.label' | translate }}</h2>\n <div class=\"actions\">\n <button class=\"refresh\" title=\"refresh\" (click)=\"reloadList()\"><yvc-icon [svg]=\"icons.refresh\"></yvc-icon></button>\n <button class=\"close\" title=\"close\" (click)=\"close()\"><yvc-icon [svg]=\"icons.close\"></yvc-icon></button>\n </div>\n </header>\n <ymd-versions-list\n class=\"staggered\"\n [attr.aria-label]=\"'yuv.app.drive.files.content.aria.label' | translate\"\n [attr.aria-busy]=\"isLoading()\"\n [attr.role]=\"'listbox'\"\n [id]=\"id()\"\n > \n </ymd-versions-list>\n </div>\n </ng-template>\n</yvc-split-view>\n<footer>\n <div class=\"actions\">\n <button class=\"secondary\" [disabled]=\"disabledRestore()\" (click)=\"setNewVersion()\">{{ 'yuv.app.drive.action.set.new.versions.label' | translate }}</button>\n </div>\n</footer>\n", styles: [":host{height:100%;display:grid;grid-auto-columns:1fr;grid-auto-rows:1fr;grid-template-columns:1.7fr;grid-template-rows:.1px 2.7fr .2fr;gap:0px 0px;grid-template-areas:\"loader\" \"content\" \"footer\"}:host .loader{grid-area:loader}:host yvc-split-view{grid-area:content;height:100%}:host header{display:grid;grid-template-columns:2fr max-content;grid-template-rows:1fr max-content;gap:0px 0px;grid-auto-flow:row;grid-template-areas:\"label actions\" \"title title\";padding:var(--app-pane-padding);align-items:center}:host header span{font-size:var(--font-headline);font-weight:var(--font-weight-bold)}:host .versions,:host .version-details{display:flex;flex-flow:column;height:100%}:host .version-details .details{flex:1;overflow-y:hidden}:host .versions header{border-bottom:1px solid var(--panel-divider-color);padding-top:0}:host .versions .label{grid-area:label}:host .versions .actions{grid-area:actions;display:flex;justify-content:center;align-items:center}:host .versions .actions button{padding:0}:host .versions .title{grid-area:title}:host .versions .staggered{flex:1;overflow-y:scroll}:host .versions-details{height:100%}:host footer{grid-area:footer;display:flex;justify-content:flex-end;align-items:center;background:var(--panel-background);border-top:1px solid var(--panel-divider-color);gap:calc(var(--app-pane-padding) / 4);padding:calc(var(--app-pane-padding) / 2)}\n"], dependencies: [{ kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: YvcTabsModule }, { kind: "component", type: i2$3.Tabs, selector: "yvc-tabs", inputs: ["tabs", "layoutSettingsID", "panelOrder", "panelOrderIncludeUnmentioned", "cacheViews", "tabSplitEnabled", "tabRemoveEnabled"], outputs: ["tabSplit", "tabRemove", "tabChange"] }, { kind: "directive", type: i2$3.YvcTabDirective, selector: "[yvcTab]", inputs: ["yvcTab"] }, { kind: "ngmodule", type: YvcSplitViewModule }, { kind: "component", type: i3.SplitViewComponent, selector: "yvc-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "gutterDblClickDuration", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "directive", type: i3.SplitAreaDirective, selector: "[yvcSplitArea]", inputs: ["size", "order", "minSize", "maxSize", "panelClass", "visible"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: VersionsListComponent, selector: "ymd-versions-list" }, { kind: "component", type: ObjectSummaryDataComponent, selector: "yuv-object-summary-data", inputs: ["dmsObject"] }, { kind: "component", type: ObjectPreviewComponent, selector: "yuv-object-preview", inputs: ["objectId", "dmsObject", "version"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1697
2095
  }
1698
2096
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ManageVersionsComponent, decorators: [{
1699
2097
  type: Component,
@@ -1899,7 +2297,7 @@ class RibbonComponent {
1899
2297
  ];
1900
2298
  }
1901
2299
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RibbonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1902
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: RibbonComponent, isStandalone: true, selector: "ymd-ribbon", inputs: { busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, enableClipboard: { classPropertyName: "enableClipboard", publicName: "enableClipboard", isSignal: true, isRequired: false, transformFunction: null }, objects: { classPropertyName: "objects", publicName: "objects", isSignal: true, isRequired: false, transformFunction: null }, excludeActions: { classPropertyName: "excludeActions", publicName: "excludeActions", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ymd-ribbon" }, queries: [{ propertyName: "primarySlot", first: true, predicate: ["primaryActions"], descendants: true, isSignal: true }, { propertyName: "secondarySlot", first: true, predicate: ["secondaryActions"], descendants: true, isSignal: true }], ngImport: i0, template: "@let primary = primarySlot();\n@let secondary = secondarySlot();\n\n@if (primary) {\n <div class=\"primary-actions\">\n <ng-container [ngTemplateOutlet]=\"primary\"></ng-container>\n </div>\n}\n\n<div class=\"object-actions\">\n @if (enableClipboard()) {\n <yuv-clipboard class=\"dark\" [bucket]=\"clipboardBucket\" [enablePaste]=\"true\" (paste)=\"onClipboardPaste()\"></yuv-clipboard>\n }\n <yvc-overflow-menu [hideLabels]=\"true\" [menuItems]=\"menuItems\"></yvc-overflow-menu>\n</div>\n\n@if (secondary) {\n <div class=\"secondary-actions\">\n <ng-container [ngTemplateOutlet]=\"secondary\"></ng-container>\n </div>\n}\n\n@if (busy()) {\n <div class=\"yuv-loader-linear\"></div>\n}\n", styles: ["ymd-ribbon{--ribbon-button-padding: calc(var(--app-pane-padding) / 4);--ribbon-button-border-radius: 2px;--ribbon-button-gap: calc(var(--app-pane-padding) / 4);--ribbon-icon-size: 20px;flex:0 0 auto;display:grid;grid-template-columns:auto 1fr auto;grid-template-areas:\"primary actions sort secondary\";align-items:center;gap:calc(var(--app-pane-padding) / 2);border-block-end:1px solid var(--panel-divider-color);position:relative;padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2)}ymd-ribbon .primary-actions{grid-area:primary;overflow-x:auto}ymd-ribbon .secondary-actions{grid-area:secondary;overflow-x:auto}ymd-ribbon .object-actions{grid-area:actions;align-self:stretch;overflow-x:auto;border-color:var(--panel-divider-color);border-width:0 1px 0 1px;border-style:solid;display:grid;grid-template-rows:1fr;grid-template-columns:1fr;align-items:center}ymd-ribbon .object-actions yvc-overflow-menu{--menu-item-padding: var(--ribbon-button-padding);--menu-item-icon-size: var(--ribbon-icon-size);--menu-item-gap: var(--ribbon-button-gap);--menu-item-max-label-width: 10ch;grid-row:1;grid-column:1}ymd-ribbon .object-actions yuv-clipboard{--clipboard-background-color: var(--panel-divider-color);margin-inline:calc(var(--app-pane-padding) / 2);height:100%;grid-row:1;grid-column:1;z-index:1}ymd-ribbon .object-actions ymd-sort{grid-row:1;grid-column:1}ymd-ribbon .sort-column{grid-area:sort;display:flex;align-items:center;gap:var(--ribbon-button-gap);padding:0 var(--ribbon-button-padding)}ymd-ribbon .yuv-loader-linear{position:absolute;bottom:-2px;left:0;right:0;width:auto;height:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ClipboardComponent, selector: "yuv-clipboard", inputs: ["enablePaste", "bucket"], outputs: ["paste"] }, { kind: "component", type: YvcOverflowMenuComponent, selector: "yvc-overflow-menu", inputs: ["overflowIcon", "groupLabels", "menuItems", "hideLabels"] }], encapsulation: i0.ViewEncapsulation.None }); }
2300
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: RibbonComponent, isStandalone: true, selector: "ymd-ribbon", inputs: { busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null }, enableClipboard: { classPropertyName: "enableClipboard", publicName: "enableClipboard", isSignal: true, isRequired: false, transformFunction: null }, objects: { classPropertyName: "objects", publicName: "objects", isSignal: true, isRequired: false, transformFunction: null }, excludeActions: { classPropertyName: "excludeActions", publicName: "excludeActions", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ymd-ribbon" }, queries: [{ propertyName: "primarySlot", first: true, predicate: ["primaryActions"], descendants: true, isSignal: true }, { propertyName: "secondarySlot", first: true, predicate: ["secondaryActions"], descendants: true, isSignal: true }], ngImport: i0, template: "@let primary = primarySlot();\n@let secondary = secondarySlot();\n\n@if (primary) {\n <div class=\"primary-actions\">\n <ng-container [ngTemplateOutlet]=\"primary\"></ng-container>\n </div>\n}\n\n<div class=\"object-actions\">\n @if (enableClipboard()) {\n <yuv-clipboard class=\"dark\" [bucket]=\"clipboardBucket\" [enablePaste]=\"true\" (paste)=\"onClipboardPaste()\"></yuv-clipboard>\n }\n <yvc-overflow-menu [hideLabels]=\"true\" [menuItems]=\"menuItems\"></yvc-overflow-menu>\n</div>\n\n@if (secondary) {\n <div class=\"secondary-actions\">\n <ng-container [ngTemplateOutlet]=\"secondary\"></ng-container>\n </div>\n}\n\n@if (busy()) {\n <div class=\"yuv-loader-linear\"></div>\n}\n", styles: ["ymd-ribbon{--ribbon-button-padding: calc(var(--app-pane-padding) / 4);--ribbon-button-border-radius: 2px;--ribbon-button-gap: calc(var(--app-pane-padding) / 4);--ribbon-icon-size: 20px;flex:0 0 auto;display:grid;grid-template-columns:auto 1fr auto;grid-template-areas:\"primary actions sort secondary\";align-items:center;gap:calc(var(--app-pane-padding) / 2);border-block-end:1px solid var(--panel-divider-color);position:relative;padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2)}ymd-ribbon .primary-actions{grid-area:primary;overflow-x:auto}ymd-ribbon .secondary-actions{grid-area:secondary;overflow-x:auto}ymd-ribbon .object-actions{grid-area:actions;align-self:stretch;overflow-x:auto;border-color:var(--panel-divider-color);border-width:0 1px 0 1px;border-style:solid;display:grid;grid-template-rows:1fr;grid-template-columns:1fr;align-items:center}ymd-ribbon .object-actions yvc-overflow-menu{--menu-item-padding: var(--ribbon-button-padding);--menu-item-icon-size: var(--ribbon-icon-size);--menu-item-gap: var(--ribbon-button-gap);--menu-item-max-label-width: 10ch;grid-row:1;grid-column:1}ymd-ribbon .object-actions yuv-clipboard{--clipboard-background-color: var(--panel-divider-color);margin-inline:calc(var(--app-pane-padding) / 2);height:100%;grid-row:1;grid-column:1;z-index:1}ymd-ribbon .object-actions ymd-sort{grid-row:1;grid-column:1}ymd-ribbon .sort-column{grid-area:sort;display:flex;align-items:center;gap:var(--ribbon-button-gap);padding:0 var(--ribbon-button-padding)}ymd-ribbon .yuv-loader-linear{position:absolute;bottom:-2px;left:0;right:0;width:auto;height:2px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ClipboardComponent, selector: "yuv-clipboard", inputs: ["enablePaste", "bucket"], outputs: ["paste"] }, { kind: "component", type: YvcOverflowMenuComponent, selector: "yvc-overflow-menu", inputs: ["overflowIcon", "groupLabels", "menuItems", "hideLabels"] }], encapsulation: i0.ViewEncapsulation.None }); }
1903
2301
  }
1904
2302
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RibbonComponent, decorators: [{
1905
2303
  type: Component,
@@ -1908,90 +2306,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1908
2306
  }, template: "@let primary = primarySlot();\n@let secondary = secondarySlot();\n\n@if (primary) {\n <div class=\"primary-actions\">\n <ng-container [ngTemplateOutlet]=\"primary\"></ng-container>\n </div>\n}\n\n<div class=\"object-actions\">\n @if (enableClipboard()) {\n <yuv-clipboard class=\"dark\" [bucket]=\"clipboardBucket\" [enablePaste]=\"true\" (paste)=\"onClipboardPaste()\"></yuv-clipboard>\n }\n <yvc-overflow-menu [hideLabels]=\"true\" [menuItems]=\"menuItems\"></yvc-overflow-menu>\n</div>\n\n@if (secondary) {\n <div class=\"secondary-actions\">\n <ng-container [ngTemplateOutlet]=\"secondary\"></ng-container>\n </div>\n}\n\n@if (busy()) {\n <div class=\"yuv-loader-linear\"></div>\n}\n", styles: ["ymd-ribbon{--ribbon-button-padding: calc(var(--app-pane-padding) / 4);--ribbon-button-border-radius: 2px;--ribbon-button-gap: calc(var(--app-pane-padding) / 4);--ribbon-icon-size: 20px;flex:0 0 auto;display:grid;grid-template-columns:auto 1fr auto;grid-template-areas:\"primary actions sort secondary\";align-items:center;gap:calc(var(--app-pane-padding) / 2);border-block-end:1px solid var(--panel-divider-color);position:relative;padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2)}ymd-ribbon .primary-actions{grid-area:primary;overflow-x:auto}ymd-ribbon .secondary-actions{grid-area:secondary;overflow-x:auto}ymd-ribbon .object-actions{grid-area:actions;align-self:stretch;overflow-x:auto;border-color:var(--panel-divider-color);border-width:0 1px 0 1px;border-style:solid;display:grid;grid-template-rows:1fr;grid-template-columns:1fr;align-items:center}ymd-ribbon .object-actions yvc-overflow-menu{--menu-item-padding: var(--ribbon-button-padding);--menu-item-icon-size: var(--ribbon-icon-size);--menu-item-gap: var(--ribbon-button-gap);--menu-item-max-label-width: 10ch;grid-row:1;grid-column:1}ymd-ribbon .object-actions yuv-clipboard{--clipboard-background-color: var(--panel-divider-color);margin-inline:calc(var(--app-pane-padding) / 2);height:100%;grid-row:1;grid-column:1;z-index:1}ymd-ribbon .object-actions ymd-sort{grid-row:1;grid-column:1}ymd-ribbon .sort-column{grid-area:sort;display:flex;align-items:center;gap:var(--ribbon-button-gap);padding:0 var(--ribbon-button-padding)}ymd-ribbon .yuv-loader-linear{position:absolute;bottom:-2px;left:0;right:0;width:auto;height:2px}\n"] }]
1909
2307
  }], ctorParameters: () => [] });
1910
2308
 
1911
- class StoredQueryService {
1912
- constructor() {
1913
- this.userService = inject(UserService);
1914
- this.translate = inject(TranslateService);
1915
- }
1916
- getStoredQuery(id) {
1917
- const q = STORED_QUERIES[id];
1918
- if (!q)
1919
- return undefined;
1920
- try {
1921
- // if query has no label try to resolve from language resources
1922
- return {
1923
- label: q.label || this.translate.instant(id),
1924
- query: JSON.parse(this._replaceVars(q.query))
1925
- };
1926
- }
1927
- catch (e) {
1928
- return undefined;
1929
- }
1930
- }
1931
- _replaceVars(str) {
1932
- const vars = [{ placeholder: '##me##', replace: this.userService.getCurrentUser().id }];
1933
- vars.forEach((v) => {
1934
- str = str.replaceAll(v.placeholder, v.replace);
1935
- });
1936
- return str;
1937
- }
1938
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1939
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, providedIn: 'root' }); }
1940
- }
1941
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, decorators: [{
1942
- type: Injectable,
1943
- args: [{
1944
- providedIn: 'root'
1945
- }]
1946
- }] });
1947
-
1948
- class DateRangePickerComponent {
1949
- constructor() {
1950
- this.#oRef = inject(YvcOverlayRef);
1951
- this.#fb = inject(FormBuilder);
1952
- this.form = this.#fb.group({
1953
- range: this.#fb.control(undefined, Validators.required)
1954
- });
1955
- this.range = input(this.#oRef.data.range);
1956
- this.rangeChange = output();
1957
- this.#rangeEffect = effect(() => {
1958
- const range = this.range();
1959
- this.form.patchValue({ range });
1960
- });
1961
- }
1962
- #oRef;
1963
- #fb;
1964
- #rangeEffect;
1965
- apply() {
1966
- this.rangeChange.emit(this.form.value.range || undefined);
1967
- this.#oRef?.close(this.form.value.range);
1968
- }
1969
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateRangePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1970
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.13", type: DateRangePickerComponent, isStandalone: true, selector: "ymd-date-range-picker", inputs: { range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rangeChange: "rangeChange" }, ngImport: i0, template: "<form [formGroup]=\"form\" (ngSubmit)=\"apply()\">\n <h2>{{ 'yuv.app.drive.search.filter.option.date.custom.overlay.title' | translate }}</h2>\n <yuv-datetime-range [withTime]=\"false\" formControlName=\"range\"></yuv-datetime-range>\n <button class=\"primary\" [disabled]=\"form.invalid\">{{ 'yuv.app.drive.search.filter.option.date.custom.overlay.button.apply' | translate }}</button>\n</form>\n", styles: [":host{--form-element-border-color: transparent;--yvc-form-element-border-color: transparent}:host form{display:grid;grid-template-columns:1fr auto;grid-template-rows:repeat(3,auto);grid-template-areas:\"title title\" \"input input\" \". button\";gap:var(--app-pane-padding);padding:var(--app-pane-padding)}:host form h2{grid-area:title;margin:0}:host form yuv-datetime-range{grid-area:input;border:1px solid var(--text-color-hint);padding:1px 2px;border-radius:2px}:host form button{grid-area:button}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: DatetimeRangeComponent, selector: "yuv-datetime-range", inputs: ["withTime", "readonly", "operator"] }] }); }
1971
- }
1972
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DateRangePickerComponent, decorators: [{
1973
- type: Component,
1974
- args: [{ selector: 'ymd-date-range-picker', standalone: true, imports: [CommonModule, ReactiveFormsModule, TranslateModule, DatetimeRangeComponent], template: "<form [formGroup]=\"form\" (ngSubmit)=\"apply()\">\n <h2>{{ 'yuv.app.drive.search.filter.option.date.custom.overlay.title' | translate }}</h2>\n <yuv-datetime-range [withTime]=\"false\" formControlName=\"range\"></yuv-datetime-range>\n <button class=\"primary\" [disabled]=\"form.invalid\">{{ 'yuv.app.drive.search.filter.option.date.custom.overlay.button.apply' | translate }}</button>\n</form>\n", styles: [":host{--form-element-border-color: transparent;--yvc-form-element-border-color: transparent}:host form{display:grid;grid-template-columns:1fr auto;grid-template-rows:repeat(3,auto);grid-template-areas:\"title title\" \"input input\" \". button\";gap:var(--app-pane-padding);padding:var(--app-pane-padding)}:host form h2{grid-area:title;margin:0}:host form yuv-datetime-range{grid-area:input;border:1px solid var(--text-color-hint);padding:1px 2px;border-radius:2px}:host form button{grid-area:button}\n"] }]
1975
- }] });
1976
-
1977
2309
  class SearchFilterComponent {
1978
2310
  #shell;
1979
2311
  #fb;
1980
- #overlay;
1981
- #CREATED_CUSTOM;
2312
+ #search;
1982
2313
  #flavors;
1983
- #customDateRange;
1984
2314
  constructor() {
1985
2315
  this.#shell = inject(ShellService);
1986
2316
  this.#fb = inject(FormBuilder);
1987
- this.#overlay = inject(YvcOverlayService);
1988
- this.#CREATED_CUSTOM = 'custom';
2317
+ this.#search = inject(SearchService);
1989
2318
  this.translate = inject(TranslateService$1);
1990
2319
  this.ANY_OPTION = 'any';
1991
2320
  this.#flavors = this.#shell.getObjectFlavors();
1992
2321
  this.typeOptions = signal([]);
1993
- this.dateOptions = signal([]);
1994
- this.sizeOptions = signal([]);
1995
2322
  this.query = input(null);
1996
2323
  this.queryChange = output();
1997
2324
  this.filtersActive = signal(false);
@@ -2003,57 +2330,6 @@ class SearchFilterComponent {
2003
2330
  this.translate.onLangChange.pipe(takeUntilDestroyed()).subscribe((_) => this.#setupOptions());
2004
2331
  this.#setupOptions();
2005
2332
  this.filterForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((v) => this.#onFormValueChange(v));
2006
- // listen to created filter changes to catch custom date range
2007
- this.filterForm
2008
- .get('created')
2009
- ?.valueChanges.pipe(takeUntilDestroyed())
2010
- .subscribe((v) => {
2011
- if (v === this.#CREATED_CUSTOM) {
2012
- // open date range picker
2013
- console.log(this.#customDateRange);
2014
- const o = this.#overlay.open(DateRangePickerComponent, {
2015
- range: this.#customDateRange
2016
- });
2017
- o.afterClosed$.subscribe((res) => {
2018
- this.#customDateRange = res.data;
2019
- if (!res.data) {
2020
- this.filterForm.get('created')?.patchValue(this.ANY_OPTION);
2021
- this.#setupDateOptions();
2022
- }
2023
- else {
2024
- this.#onFormValueChange(this.filterForm.value);
2025
- this.#setupDateOptions(this.#customDateRangeToString());
2026
- setTimeout(() => {
2027
- this.filterForm.patchValue({
2028
- created: this.#CREATED_CUSTOM
2029
- }, {
2030
- emitEvent: false
2031
- });
2032
- });
2033
- }
2034
- });
2035
- }
2036
- });
2037
- }
2038
- #customDateRangeToString() {
2039
- if (!this.#customDateRange)
2040
- return undefined;
2041
- const dp = new LocaleDatePipe(this.translate);
2042
- switch (this.#customDateRange.operator) {
2043
- case Operator.EQUAL: {
2044
- return dp.transform(this.#customDateRange.firstValue, 'shortDate');
2045
- }
2046
- case Operator.GREATER_OR_EQUAL: {
2047
- return `${OperatorLabel.GREATER_OR_EQUAL} ${dp.transform(this.#customDateRange.firstValue, 'shortDate')}`;
2048
- }
2049
- case Operator.LESS_OR_EQUAL: {
2050
- return `${OperatorLabel.LESS_OR_EQUAL} ${dp.transform(this.#customDateRange.firstValue, 'shortDate')}`;
2051
- }
2052
- case Operator.INTERVAL_INCLUDE_BOTH: {
2053
- return `${dp.transform(this.#customDateRange.firstValue, 'shortDate')} ${OperatorLabel.INTERVAL_INCLUDE_BOTH} ${dp.transform(this.#customDateRange.secondValue, 'shortDate')}`;
2054
- }
2055
- }
2056
- return undefined;
2057
2333
  }
2058
2334
  reset() {
2059
2335
  const q = this.query();
@@ -2063,13 +2339,6 @@ class SearchFilterComponent {
2063
2339
  }
2064
2340
  }
2065
2341
  #onFormValueChange(v) {
2066
- // do not create a new query if custom date range is selected but not set
2067
- if (v.created === this.#CREATED_CUSTOM && !this.#customDateRange)
2068
- return;
2069
- if (v.created !== this.#CREATED_CUSTOM) {
2070
- this.#customDateRange = undefined;
2071
- this.#setupDateOptions();
2072
- }
2073
2342
  const updatedQuery = this.#applyFilters(v);
2074
2343
  this.queryChange.emit(updatedQuery);
2075
2344
  this.filtersActive.set(!!updatedQuery.filters && updatedQuery.filters.length > 0);
@@ -2085,19 +2354,17 @@ class SearchFilterComponent {
2085
2354
  if (typeFilter)
2086
2355
  updatedQuery.filters.push(typeFilter);
2087
2356
  // file size filter
2088
- const sizeFilter = this.#toSizeFilter(v.size);
2357
+ const sizeFilter = v.size !== this.ANY_OPTION ? this.#toSizeFilter(v.size) : undefined;
2089
2358
  if (sizeFilter)
2090
2359
  updatedQuery.filters.push(sizeFilter);
2091
2360
  // creation date filter
2092
- const dateFilter = this.#toDateFilter(v.created);
2361
+ const dateFilter = v.created !== this.ANY_OPTION ? this.#toDateFilter(v.created) : undefined;
2093
2362
  if (dateFilter)
2094
2363
  updatedQuery.filters.push(dateFilter);
2095
2364
  return updatedQuery;
2096
2365
  }
2097
2366
  #setupOptions() {
2098
2367
  this.#setupTypeOptions();
2099
- this.#setupDateOptions();
2100
- this.#setupSizeOptions();
2101
2368
  }
2102
2369
  #setupTypeOptions() {
2103
2370
  this.typeOptions.set([
@@ -2111,264 +2378,11 @@ class SearchFilterComponent {
2111
2378
  }))
2112
2379
  ]);
2113
2380
  }
2114
- #setupDateOptions(custom) {
2115
- this.dateOptions.set([
2116
- ...[
2117
- {
2118
- label: this.translate.instant('yuv.app.drive.search.filter.option.date.any'),
2119
- value: this.ANY_OPTION
2120
- },
2121
- {
2122
- label: this.translate.instant('yuv.app.drive.search.filter.option.date.today'),
2123
- value: 'today'
2124
- },
2125
- {
2126
- label: this.translate.instant('yuv.app.drive.search.filter.option.date.yesterday'),
2127
- value: 'yesterday'
2128
- },
2129
- {
2130
- label: this.translate.instant('yuv.app.drive.search.filter.option.date.thisweek'),
2131
- value: 'thisweek'
2132
- },
2133
- // {
2134
- // label: this.translate.instant('yuv.app.drive.search.filter.option.date.lastweek'),
2135
- // value: 'lastweek'
2136
- // },
2137
- {
2138
- label: this.translate.instant('yuv.app.drive.search.filter.option.date.thismonth'),
2139
- value: 'thismonth'
2140
- },
2141
- // {
2142
- // label: this.translate.instant('yuv.app.drive.search.filter.option.date.lastmonth'),
2143
- // value: 'lastmonth'
2144
- // },
2145
- {
2146
- label: this.translate.instant('yuv.app.drive.search.filter.option.date.thisyear'),
2147
- value: 'thisyear'
2148
- },
2149
- // {
2150
- // label: this.translate.instant('yuv.app.drive.search.filter.option.date.lastyear'),
2151
- // value: 'lastyear'
2152
- // },
2153
- {
2154
- label: custom || this.translate.instant('yuv.app.drive.search.filter.option.date.custom'),
2155
- value: this.#CREATED_CUSTOM
2156
- }
2157
- ]
2158
- ]);
2159
- }
2160
- #setupSizeOptions() {
2161
- this.sizeOptions.set([
2162
- {
2163
- label: this.translate.instant('yuv.app.drive.search.filter.option.size.any'),
2164
- value: this.ANY_OPTION
2165
- },
2166
- {
2167
- label: this.translate.instant('yuv.app.drive.search.filter.option.size.small'),
2168
- value: 's'
2169
- },
2170
- {
2171
- label: this.translate.instant('yuv.app.drive.search.filter.option.size.medium'),
2172
- value: 'm'
2173
- },
2174
- {
2175
- label: this.translate.instant('yuv.app.drive.search.filter.option.size.large'),
2176
- value: 'l'
2177
- },
2178
- {
2179
- label: this.translate.instant('yuv.app.drive.search.filter.option.size.verylarge'),
2180
- value: 'xl'
2181
- }
2182
- ]);
2183
- }
2184
2381
  #toDateFilter(value) {
2185
- let dateFilter = undefined;
2186
- switch (value) {
2187
- case 'today': {
2188
- dateFilter = {
2189
- f: BaseObjectTypeField.CREATION_DATE,
2190
- o: Operator.INTERVAL_INCLUDE_BOTH,
2191
- v1: new Date().toISOString().split('T')[0] + 'T00:00:00.000',
2192
- v2: new Date().toISOString().split('T')[0] + 'T23:59:59.000'
2193
- };
2194
- break;
2195
- }
2196
- case 'yesterday': {
2197
- const yesterday = new Date();
2198
- yesterday.setDate(yesterday.getDate() - 1);
2199
- dateFilter = {
2200
- f: BaseObjectTypeField.CREATION_DATE,
2201
- o: Operator.INTERVAL_INCLUDE_BOTH,
2202
- v1: yesterday.toISOString().split('T')[0] + 'T00:00:00.000',
2203
- v2: yesterday.toISOString().split('T')[0] + 'T23:59:59.000'
2204
- };
2205
- break;
2206
- }
2207
- case 'thisweek': {
2208
- const firstDay = new Date();
2209
- firstDay.setDate(firstDay.getDate() - firstDay.getDay());
2210
- dateFilter = {
2211
- f: BaseObjectTypeField.CREATION_DATE,
2212
- o: Operator.INTERVAL_INCLUDE_BOTH,
2213
- v1: firstDay.toISOString().split('T')[0] + 'T00:00:00.000',
2214
- v2: new Date().toISOString().split('T')[0] + 'T23:59:59.000'
2215
- };
2216
- break;
2217
- }
2218
- // case 'lastweek': {
2219
- // const firstDay = new Date();
2220
- // firstDay.setDate(firstDay.getDate() - firstDay.getDay() - 7);
2221
- // const lastDay = new Date();
2222
- // lastDay.setDate(lastDay.getDate() - lastDay.getDay() - 1);
2223
- // dateFilter = {
2224
- // f: BaseObjectTypeField.CREATION_DATE,
2225
- // o: Operator.INTERVAL_INCLUDE_BOTH,
2226
- // v1: firstDay.toISOString().split('T')[0] + 'T00:00:00.000',
2227
- // v2: lastDay.toISOString().split('T')[0] + 'T23:59:59.000'
2228
- // };
2229
- // break;
2230
- // }
2231
- case 'thismonth': {
2232
- const firstDay = new Date();
2233
- firstDay.setDate(1);
2234
- dateFilter = {
2235
- f: BaseObjectTypeField.CREATION_DATE,
2236
- o: Operator.INTERVAL_INCLUDE_BOTH,
2237
- v1: firstDay.toISOString().split('T')[0] + 'T00:00:00.000',
2238
- v2: new Date().toISOString().split('T')[0] + 'T23:59:59.000'
2239
- };
2240
- break;
2241
- }
2242
- // case 'lastmonth': {
2243
- // const firstDay = new Date();
2244
- // firstDay.setDate(1);
2245
- // firstDay.setMonth(firstDay.getMonth() - 1);
2246
- // const lastDay = new Date();
2247
- // lastDay.setDate(0);
2248
- // dateFilter = {
2249
- // f: BaseObjectTypeField.CREATION_DATE,
2250
- // o: Operator.INTERVAL_INCLUDE_BOTH,
2251
- // v1: firstDay.toISOString().split('T')[0] + 'T00:00:00.000',
2252
- // v2: lastDay.toISOString().split('T')[0] + 'T23:59:59.000'
2253
- // };
2254
- // break;
2255
- // }
2256
- case 'thisyear': {
2257
- const firstDay = new Date();
2258
- firstDay.setMonth(0);
2259
- firstDay.setDate(1);
2260
- dateFilter = {
2261
- f: BaseObjectTypeField.CREATION_DATE,
2262
- o: Operator.INTERVAL_INCLUDE_BOTH,
2263
- v1: firstDay.toISOString().split('T')[0] + 'T00:00:00.000',
2264
- v2: new Date().toISOString().split('T')[0] + 'T23:59:59.000'
2265
- };
2266
- break;
2267
- }
2268
- // case 'lastyear': {
2269
- // const firstDay = new Date();
2270
- // firstDay.setFullYear(firstDay.getFullYear() - 1);
2271
- // firstDay.setMonth(0);
2272
- // firstDay.setDate(1);
2273
- // const lastDay = new Date();
2274
- // lastDay.setFullYear(lastDay.getFullYear() - 1);
2275
- // lastDay.setMonth(11);
2276
- // lastDay.setDate(31);
2277
- // dateFilter = {
2278
- // f: BaseObjectTypeField.CREATION_DATE,
2279
- // o: Operator.INTERVAL_INCLUDE_BOTH,
2280
- // v1: firstDay.toISOString().split('T')[0] + 'T00:00:00.000',
2281
- // v2: lastDay.toISOString().split('T')[0] + 'T23:59:59.000'
2282
- // };
2283
- // break;
2284
- // }
2285
- case this.#CREATED_CUSTOM: {
2286
- if (this.#customDateRange)
2287
- dateFilter = this.#customRangeToFilter(this.#customDateRange);
2288
- else
2289
- this.filterForm.get('created')?.patchValue(this.ANY_OPTION);
2290
- break;
2291
- }
2292
- }
2293
- return dateFilter;
2294
- }
2295
- #customRangeToFilter(rv) {
2296
- const v1 = rv.firstValue.toISOString();
2297
- const v2 = rv.secondValue ? rv.secondValue.toISOString() : undefined;
2298
- let filter;
2299
- switch (rv.operator) {
2300
- case Operator.EQUAL: {
2301
- filter = {
2302
- f: BaseObjectTypeField.CREATION_DATE,
2303
- o: Operator.INTERVAL_INCLUDE_BOTH,
2304
- v1: v1.split('T')[0] + 'T00:00:00.000',
2305
- v2: v1.split('T')[0] + 'T23:59:59.000'
2306
- };
2307
- break;
2308
- }
2309
- case Operator.GREATER_OR_EQUAL: {
2310
- filter = {
2311
- f: BaseObjectTypeField.CREATION_DATE,
2312
- o: rv.operator,
2313
- v1: v1.split('T')[0] + 'T00:00:00.000'
2314
- };
2315
- break;
2316
- }
2317
- case Operator.LESS_OR_EQUAL: {
2318
- filter = {
2319
- f: BaseObjectTypeField.CREATION_DATE,
2320
- o: rv.operator,
2321
- v1: v1.split('T')[0] + 'T23:59:59.000'
2322
- };
2323
- break;
2324
- }
2325
- case Operator.INTERVAL_INCLUDE_BOTH: {
2326
- filter = {
2327
- f: BaseObjectTypeField.CREATION_DATE,
2328
- o: rv.operator,
2329
- v1: v1.split('T')[0] + 'T00:00:00.000',
2330
- v2: v2.split('T')[0] + 'T23:59:59.000'
2331
- };
2332
- break;
2333
- }
2334
- }
2335
- return filter;
2382
+ return value ? this.#search.rangeValueToSearchFilter(value.rangeValue, BaseObjectTypeField.CREATION_DATE) : undefined;
2336
2383
  }
2337
2384
  #toSizeFilter(value) {
2338
- let sizeFilter = undefined;
2339
- switch (value) {
2340
- case 's':
2341
- sizeFilter = {
2342
- f: ContentStreamField.LENGTH,
2343
- o: Operator.LESS_THAN,
2344
- v1: 1024 * 1024
2345
- };
2346
- break;
2347
- case 'm':
2348
- sizeFilter = {
2349
- f: ContentStreamField.LENGTH,
2350
- o: Operator.INTERVAL_INCLUDE_BOTH,
2351
- v1: 1024 * 1024,
2352
- v2: 1024 * 1024 * 10
2353
- };
2354
- break;
2355
- case 'l':
2356
- sizeFilter = {
2357
- f: ContentStreamField.LENGTH,
2358
- o: Operator.INTERVAL_INCLUDE_BOTH,
2359
- v1: 1024 * 1024 * 10,
2360
- v2: 1024 * 1024 * 100
2361
- };
2362
- break;
2363
- case 'xl':
2364
- sizeFilter = {
2365
- f: ContentStreamField.LENGTH,
2366
- o: Operator.GREATER_THAN,
2367
- v1: 1024 * 1024 * 100
2368
- };
2369
- break;
2370
- }
2371
- return sizeFilter;
2385
+ return value ? this.#search.rangeValueToSearchFilter(value.rangeValue, ContentStreamField.LENGTH) : undefined;
2372
2386
  }
2373
2387
  #toTypeFilter(value) {
2374
2388
  return value === this.ANY_OPTION
@@ -2380,13 +2394,53 @@ class SearchFilterComponent {
2380
2394
  };
2381
2395
  }
2382
2396
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2383
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SearchFilterComponent, isStandalone: true, selector: "ymd-search-filter", inputs: { query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { queryChange: "queryChange" }, ngImport: i0, template: "<form [formGroup]=\"filterForm\" yvcDragScroll>\n <yvc-dropdown formControlName=\"type\" [options]=\"typeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n <yvc-dropdown formControlName=\"size\" [options]=\"sizeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n <yvc-dropdown formControlName=\"created\" [options]=\"dateOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n\n @if (filtersActive()) {\n <button class=\"secondary\" (click)=\"reset()\">{{ 'yuv.app.drive.search.filter.button.reset' | translate }}</button>\n }\n</form>\n", styles: [":host form{display:flex;gap:2px;overflow-x:auto;--scrollbar-outer-size: 0;margin-block:calc(var(--app-pane-padding) / 2)}:host form yvc-dropdown{--icon-size: 18px;font-size:var(--font-caption);color:var(--text-color-caption);border:0;outline-offset:-2px;cursor:pointer;flex:0 0 auto;padding:0}:host form button{padding:.15em .5em;line-height:1em;margin-inline-start:1em;border-radius:.25em;font-size:var(--font-caption)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: YvcDropdownModule }, { kind: "component", type: i1$4.Dropdown, selector: "yvc-dropdown", inputs: ["options", "filter", "disabled", "multiple", "disableClearButton"], outputs: ["onDropdownOptionsClose"] }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: YvcDragScrollModule }, { kind: "directive", type: i2$1.DragScrollDirective, selector: "[yvcDragScroll]" }] }); }
2397
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: SearchFilterComponent, isStandalone: true, selector: "ymd-search-filter", inputs: { query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { queryChange: "queryChange" }, ngImport: i0, template: "<form [formGroup]=\"filterForm\" yvcDragScroll>\n <yvc-dropdown formControlName=\"type\" [options]=\"typeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n <yuv-range-select-filesize formControlName=\"size\"></yuv-range-select-filesize>\n <yuv-range-select-date formControlName=\"created\"></yuv-range-select-date>\n\n @if (filtersActive()) {\n <button class=\"secondary\" (click)=\"reset()\">{{ 'yuv.app.drive.search.filter.button.reset' | translate }}</button>\n }\n</form>\n", styles: [":host form{display:flex;gap:2px;overflow-x:auto;--scrollbar-outer-size: 0;margin-block:calc(var(--app-pane-padding) / 2);padding:2px}:host form yuv-range-select-filesize,:host form yuv-range-select-date,:host form yvc-dropdown{--icon-size: 18px;--form-element-border-color: transparent;font-size:var(--font-caption);color:var(--text-color-caption);outline-offset:0px;cursor:pointer;flex:0 0 auto;padding:0}:host form button{padding:.15em .5em;line-height:1em;margin-inline-start:1em;border-radius:.25em;font-size:var(--font-caption)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: YvcDropdownModule }, { kind: "component", type: i2$2.Dropdown, selector: "yvc-dropdown", inputs: ["options", "filter", "disabled", "multiple", "disableClearButton"], outputs: ["onDropdownOptionsClose"] }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: RangeSelectFilesizeComponent, selector: "yuv-range-select-filesize", inputs: ["ranges"] }, { kind: "component", type: RangeSelectDateComponent, selector: "yuv-range-select-date", inputs: ["ranges", "customRange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: YvcDragScrollModule }, { kind: "directive", type: i2$1.DragScrollDirective, selector: "[yvcDragScroll]" }] }); }
2384
2398
  }
2385
2399
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchFilterComponent, decorators: [{
2386
2400
  type: Component,
2387
- args: [{ selector: 'ymd-search-filter', standalone: true, imports: [CommonModule, YvcDropdownModule, TranslateModule$1, ReactiveFormsModule, YvcDragScrollModule], template: "<form [formGroup]=\"filterForm\" yvcDragScroll>\n <yvc-dropdown formControlName=\"type\" [options]=\"typeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n <yvc-dropdown formControlName=\"size\" [options]=\"sizeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n <yvc-dropdown formControlName=\"created\" [options]=\"dateOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n\n @if (filtersActive()) {\n <button class=\"secondary\" (click)=\"reset()\">{{ 'yuv.app.drive.search.filter.button.reset' | translate }}</button>\n }\n</form>\n", styles: [":host form{display:flex;gap:2px;overflow-x:auto;--scrollbar-outer-size: 0;margin-block:calc(var(--app-pane-padding) / 2)}:host form yvc-dropdown{--icon-size: 18px;font-size:var(--font-caption);color:var(--text-color-caption);border:0;outline-offset:-2px;cursor:pointer;flex:0 0 auto;padding:0}:host form button{padding:.15em .5em;line-height:1em;margin-inline-start:1em;border-radius:.25em;font-size:var(--font-caption)}\n"] }]
2401
+ args: [{ selector: 'ymd-search-filter', standalone: true, imports: [CommonModule, YvcDropdownModule, TranslateModule$1,
2402
+ RangeSelectFilesizeComponent,
2403
+ RangeSelectDateComponent,
2404
+ ReactiveFormsModule, YvcDragScrollModule], template: "<form [formGroup]=\"filterForm\" yvcDragScroll>\n <yvc-dropdown formControlName=\"type\" [options]=\"typeOptions()\" [disableClearButton]=\"true\"></yvc-dropdown>\n <yuv-range-select-filesize formControlName=\"size\"></yuv-range-select-filesize>\n <yuv-range-select-date formControlName=\"created\"></yuv-range-select-date>\n\n @if (filtersActive()) {\n <button class=\"secondary\" (click)=\"reset()\">{{ 'yuv.app.drive.search.filter.button.reset' | translate }}</button>\n }\n</form>\n", styles: [":host form{display:flex;gap:2px;overflow-x:auto;--scrollbar-outer-size: 0;margin-block:calc(var(--app-pane-padding) / 2);padding:2px}:host form yuv-range-select-filesize,:host form yuv-range-select-date,:host form yvc-dropdown{--icon-size: 18px;--form-element-border-color: transparent;font-size:var(--font-caption);color:var(--text-color-caption);outline-offset:0px;cursor:pointer;flex:0 0 auto;padding:0}:host form button{padding:.15em .5em;line-height:1em;margin-inline-start:1em;border-radius:.25em;font-size:var(--font-caption)}\n"] }]
2388
2405
  }], ctorParameters: () => [] });
2389
2406
 
2407
+ class StoredQueryService {
2408
+ constructor() {
2409
+ this.userService = inject(UserService);
2410
+ this.translate = inject(TranslateService);
2411
+ }
2412
+ getStoredQuery(id) {
2413
+ const q = STORED_QUERIES[id];
2414
+ if (!q)
2415
+ return undefined;
2416
+ try {
2417
+ // if query has no label try to resolve from language resources
2418
+ return {
2419
+ label: q.label || this.translate.instant(id),
2420
+ query: JSON.parse(this._replaceVars(q.query))
2421
+ };
2422
+ }
2423
+ catch (e) {
2424
+ return undefined;
2425
+ }
2426
+ }
2427
+ _replaceVars(str) {
2428
+ const vars = [{ placeholder: '##me##', replace: this.userService.getCurrentUser().id }];
2429
+ vars.forEach((v) => {
2430
+ str = str.replaceAll(v.placeholder, v.replace);
2431
+ });
2432
+ return str;
2433
+ }
2434
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2435
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, providedIn: 'root' }); }
2436
+ }
2437
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, decorators: [{
2438
+ type: Injectable,
2439
+ args: [{
2440
+ providedIn: 'root'
2441
+ }]
2442
+ }] });
2443
+
2390
2444
  const components = [
2391
2445
  TileListComponent,
2392
2446
  BreadcrumbComponent,
@@ -2398,13 +2452,15 @@ const components = [
2398
2452
  SimpleSearchComponent,
2399
2453
  MultiObjectSummaryComponent,
2400
2454
  SortComponent,
2401
- SearchFilterComponent
2455
+ SearchFilterComponent,
2456
+ DriveSearchComponent
2402
2457
  ];
2403
2458
  const module = [YvcIconModule, TranslateModule, RouterModule, YvcSplitViewModule];
2404
2459
  class FilesPageComponent {
2405
2460
  #LAYOUT_SETTINGS_STORAGE_KEY;
2406
2461
  #objectConfigService;
2407
2462
  #device;
2463
+ #retention;
2408
2464
  #eventService;
2409
2465
  #appCache;
2410
2466
  #highlightStyles;
@@ -2423,6 +2479,7 @@ class FilesPageComponent {
2423
2479
  this.actionsService = inject(ActionsService);
2424
2480
  this.#objectConfigService = inject(ObjectConfigService);
2425
2481
  this.#device = inject(DeviceService);
2482
+ this.#retention = inject(RetentionService);
2426
2483
  this.#eventService = inject(EventService);
2427
2484
  this.ERROR_CODE = {
2428
2485
  NOT_FOUND: '404',
@@ -2433,10 +2490,14 @@ class FilesPageComponent {
2433
2490
  this.objectConfigBucket = APP_SCHEMA.id;
2434
2491
  this.splitViewCmp = viewChild.required(SplitViewComponent);
2435
2492
  this.selected = signal(undefined);
2436
- this.fileDropSummaryDisabled = computed(() => !this.selected()?.permissions?.writeContent);
2493
+ this.fileDropSummaryDisabled = computed(() => {
2494
+ const e = this.selected();
2495
+ return !e || !e.permissions?.writeContent || this.#retention.getRetentionState(e).underRetention;
2496
+ });
2437
2497
  this.disableCreate = false;
2438
2498
  this.actions = this.drive.state$.actions;
2439
2499
  this.selection = this.drive.state$.selection;
2500
+ this.extendedQuery = this.drive.state$.extendedQuery;
2440
2501
  this.busy = this.drive.state$.busy;
2441
2502
  this.flavorChips = this.shellService.getObjectFlavors();
2442
2503
  this.selectionActions = computed(() => ({ selection: this.selection(), actions: this.actions() }));
@@ -2448,12 +2509,12 @@ class FilesPageComponent {
2448
2509
  folder: { bucket: APP_ID, type: APP_SCHEMA.types['folder'] },
2449
2510
  file: { bucket: APP_ID, type: APP_SCHEMA.types['file'] }
2450
2511
  };
2451
- this.searchFocused = false;
2452
2512
  this.enableDetails = signal(true);
2453
2513
  this.enableTree = signal(true);
2454
2514
  this.tileConfigBucketLabel = this.translate.instant('yuv.app.drive.tile-config.bucket');
2455
2515
  this.smallScreenLayout = signal(false);
2456
2516
  this.sortOptionsAvailable = signal(true);
2517
+ this.extendedSearch = signal(false);
2457
2518
  this.id = input(null);
2458
2519
  this.highlightStyles$ = this.clipboard.clipboard$(APP_ID).pipe(takeUntilDestroyed(), map((c) => {
2459
2520
  return c && c.mode && c.objects?.length
@@ -2544,8 +2605,8 @@ class FilesPageComponent {
2544
2605
  if (this.route.snapshot.params['id'] === DRIVE_QUERY_FOLDER_ID) {
2545
2606
  const q = p.get('q');
2546
2607
  this.disableCreate = true;
2547
- // check if the query is a stored query
2548
2608
  if (q?.startsWith(STORED_QUERY_ID_PREFIX)) {
2609
+ // stored query
2549
2610
  const sq = this.storedQueryService.getStoredQuery(q);
2550
2611
  if (sq) {
2551
2612
  this.drive.updateQuery(sq.query, sq.label);
@@ -2554,11 +2615,12 @@ class FilesPageComponent {
2554
2615
  }
2555
2616
  }
2556
2617
  else if (q) {
2618
+ // search query
2557
2619
  this.sortOptionsAvailable.set(true);
2558
2620
  try {
2559
2621
  const sq = JSON.parse(decodeURIComponent(q));
2560
2622
  sq.filters = (sq.filters || []).filter((f) => f.f !== BaseObjectTypeField.PARENT_ID);
2561
- this.drive.updateQuery(sq, this.translate.instant('yuv.app.drive.files.search.result.title'));
2623
+ this.drive.updateQuery(sq, this.translate.instant('yuv.app.drive.files.search.result.title'), p.get('ext') === 'true');
2562
2624
  return;
2563
2625
  }
2564
2626
  catch (e) {
@@ -2633,16 +2695,16 @@ class FilesPageComponent {
2633
2695
  onCut(tiles) {
2634
2696
  this.clipboard.addObjects(tiles.map((t) => t.dmsObject), 'cut', APP_ID);
2635
2697
  }
2636
- onQuerySubmit(q) {
2637
- // in order to keep the query in the url as short as
2638
- // possible we'll get rid of the fields because they could be
2639
- // re-applied later on
2640
- q.fields = undefined;
2641
- this.router.navigate(['..', 'query'], {
2642
- queryParams: { q: encodeURIComponent(JSON.stringify(q)) },
2643
- relativeTo: this.route
2644
- });
2645
- }
2698
+ // onQuerySubmit(q: SearchQuery) {
2699
+ // // in order to keep the query in the url as short as
2700
+ // // possible we'll get rid of the fields because they could be
2701
+ // // re-applied later on
2702
+ // q.fields = undefined;
2703
+ // this.router.navigate(['..', 'query'], {
2704
+ // queryParams: { q: encodeURIComponent(JSON.stringify(q)) },
2705
+ // relativeTo: this.route
2706
+ // });
2707
+ // }
2646
2708
  selectionChanged(tiles) {
2647
2709
  if (tiles.length === 1)
2648
2710
  this.loadDetails(tiles[0].id);
@@ -2722,17 +2784,14 @@ class FilesPageComponent {
2722
2784
  this.clipboard.clear(APP_ID);
2723
2785
  }
2724
2786
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilesPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2725
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilesPageComponent, isStandalone: true, selector: "ymd-files", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.smallScreen": "smallScreenLayout()", "class.searchFocused": "this.searchFocused" } }, viewQueries: [{ propertyName: "tileList", first: true, predicate: ["tileList"], descendants: true, isSignal: true }, { propertyName: "splitViewCmp", first: true, predicate: SplitViewComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<header>\n <!-- navigation bar -->\n <nav [attr.aria-label]=\"'yuv.app.drive.files.naviagtion.aria.label' | translate\">\n <div class=\"nav\">\n <button class=\"back\" [disabled]=\"!currentFolder\" title=\"{{ 'yuv.app.drive.files.nav.back.tooltip' | translate }}\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.files.nav.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n\n @if (!query()?.term) {\n <ymd-breadcrumb></ymd-breadcrumb>\n } @else {\n <div class=\"breadcrumb\"></div>\n }\n <div class=\"search\">\n <yuv-simple-search [query]=\"query()\" (querySubmit)=\"onQuerySubmit($event)\"></yuv-simple-search>\n <!-- TODO: enable again once drive search needs to be a little bit more sophisticated -->\n <!-- <ymd-drive-search (focused)=\"searchFocused = $event\"></ymd-drive-search> -->\n </div>\n </nav>\n\n <!-- ribbon with actions and options -->\n <ymd-ribbon [objects]=\"selection()\" [busy]=\"busy()\" [enableClipboard]=\"true\">\n <ng-template #primaryActions>\n <ymd-add-button [disabled]=\"disableCreate\"></ymd-add-button>\n </ng-template>\n\n <ng-template #secondaryActions>\n <div class=\"options\">\n @if (!smallScreenLayout()) {\n <button\n class=\"toggle-tree toggle\"\n [ngClass]=\"{ enabled: enableTree() }\"\n title=\"{{ 'yuv.app.drive.files.toggletree.tooltip' | translate }}\"\n (click)=\"enableTree.set(!enableTree())\"\n >\n <yvc-icon [svg]=\"icons.toggleLeft\"></yvc-icon>\n </button>\n <button\n class=\"toggle-details toggle\"\n [ngClass]=\"{ enabled: enableDetails() }\"\n title=\"{{ 'yuv.app.drive.files.toggledetails.tooltip' | translate }}\"\n (click)=\"enableDetails.set(!enableDetails())\"\n >\n <yvc-icon [svg]=\"icons.toggleRight\"></yvc-icon>\n </button>\n }\n <yuv-tile-config-trigger\n [icon]=\"icons.settings\"\n [bucket]=\"objectConfigBucket\"\n [bucketLabel]=\"tileConfigBucketLabel\"\n [options]=\"tileListOptions\"\n ></yuv-tile-config-trigger>\n </div>\n </ng-template>\n </ymd-ribbon>\n</header>\n\n<yvc-split-view [gutterSize]=\"1\" (layoutSettingsChange)=\"onLayoutSettingsChange($event)\">\n <!-- folder tree -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableTree() && !smallScreenLayout()\">\n <ymd-folder-tree yuvFocusable=\"Tree\"></ymd-folder-tree>\n </ng-template>\n\n <!-- files -->\n <ng-template yvcSplitArea [size]=\"60\">\n @let err = error();\n @if (err) {\n <div class=\"error\">\n <p>\n <yvc-icon [svg]=\"icons.attention\"></yvc-icon>\n @switch (err) {\n @case (ERROR_CODE.NOT_FOUND) {\n {{ 'yuv.app.drive.files.error.load.not-found' | translate }}\n }\n @case (ERROR_CODE.INVALID_ID) {\n {{ 'yuv.app.drive.files.error.load.invalid-id' | translate }}\n }\n @default {\n {{ 'yuv.app.drive.files.error.load' | translate }}\n }\n }\n </p>\n </div>\n } @else {\n <div class=\"files\" [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.label' | translate }\" (fileDrop)=\"onFileDrop($event)\">\n <header class=\"files-header\">\n <h1>{{ queryTitle() }}</h1>\n @if (query()?.term) {\n <ymd-search-filter [query]=\"query()\" (queryChange)=\"onFilterQueryChange($event)\"></ymd-search-filter>\n }\n @if (sortOptionsAvailable()) {\n <ymd-sort />\n }\n <div class=\"flavors\">\n <!-- TODO: enable again once flavors/aspects are supported -->\n <!-- @for (f of flavorChips; track f.id) {\n <yuv-flavor-chip [ngClass]=\"{ active: f.id === appliedFlavor?.id }\" [flavor]=\"f\" (click)=\"appliedFlavor = f\"></yuv-flavor-chip>\n }-->\n </div>\n </header>\n\n <yuv-tile-list\n #tileList\n class=\"staggered\"\n [attr.aria-label]=\"'yuv.app.drive.files.content.aria.label' | translate\"\n [attr.aria-busy]=\"busy()\"\n [attr.role]=\"'listbox'\"\n (keydown.delete)=\"onDelete()\"\n [bucket]=\"objectConfigBucket\"\n [multiselect]=\"true\"\n [query]=\"query()\"\n [flavor]=\"appliedFlavor\"\n [options]=\"tileListOptions\"\n (itemDblClick)=\"itemDoubleClicked($event)\"\n (itemSelect)=\"itemClicked($event)\"\n (selectionChange)=\"selectionChanged($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n (busy)=\"setBusy($event)\"\n (ctxMenu)=\"onContextmenu($event)\"\n [highlights]=\"highlightStyles$ | async\"\n >\n <div #empty>\n @if (emptyMode() === 'root') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.root.list' | translate }}</p>\n } @else if (emptyMode() === 'query') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.query.list' | translate }}</p>\n } @else {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.list' | translate }}</p>\n }\n </div>\n </yuv-tile-list>\n </div>\n }\n </ng-template>\n\n <!-- details -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableDetails()\">\n @let selectedItem = selected();\n @if (enableDetails() && selectedItem) {\n @if (selectedItem?.isFolder) {\n <yuv-object-summary [configType]=\"configTypeOptions['folder']\" [dmsObject]=\"selectedItem\"></yuv-object-summary>\n } @else {\n <yuv-object-summary\n [configType]=\"configTypeOptions['file']\"\n [dmsObject]=\"selectedItem\"\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropSummaryDisabled()\"\n (fileDrop)=\"onFileUpdateDrop($event)\"\n ></yuv-object-summary>\n }\n } @else {\n @let sel = selection();\n @if (sel && sel.length > 0) {\n <yuv-multi-object-summary [headline]=\"'yuv.app.drive.multiselected.details' | translate: { count: selection().length }\"></yuv-multi-object-summary>\n } @else if (tileList()?.items?.length === 0) {\n <!-- TODO: CHOULD HAVE A DIFFERENT MESSAGE FOR EMPTY RESULTS EMPTY FOR NOW -->\n <div class=\"message\">{{ 'yuv.app.drive.empty.results.details.message' | translate }}</div>\n } @else {\n <div class=\"message\">{{ 'yuv.app.drive.unselected.details' | translate }}</div>\n }\n }\n </ng-template>\n</yvc-split-view>\n", styles: [":host{--files-button-padding: calc(var(--app-pane-padding) / 4);--files-button-border-radius: 2px;--files-button-gap: calc(var(--app-pane-padding) / 4);--files-icon-size: 20px;height:100%;overflow:hidden;display:flex;flex-flow:column}:host.searchFocused header>nav .search{grid-column:-1/-3}:host header{flex:0 0 auto}:host header>nav{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);display:grid;grid-template-columns:auto 1fr 1fr auto;align-items:center;gap:calc(var(--app-pane-padding) / 2);padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2)}:host header>nav .nav{grid-column:1/2;grid-row:1;display:flex;align-items:center;gap:var(--files-button-gap)}:host header>nav .nav button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host header>nav .nav button yvc-icon{--icon-size: var(--files-icon-size)}:host header>nav .breadcrumb{grid-column:2/4;grid-row:1;align-self:stretch;display:flex;align-items:center;border-radius:var(--files-button-border-radius);padding:0 .5em;border:1px solid var(--panel-divider-color)}:host header>nav .search{grid-column:-1/-2;grid-row:1;z-index:1}:host yvc-split-view{flex:1;animation:fade-in .3s ease-in-out}:host ymd-ribbon{--ribbon-button-padding: var(--files-button-padding);--ribbon-button-border-radius: var(--files-button-border-radius);--ribbon-button-gap: var(--files-button-gap);--ribbon-icon-size: var(--files-icon-size)}:host ymd-ribbon .options{grid-area:options;display:flex;gap:var(--files-button-gap);align-items:center}:host ymd-ribbon .options yuv-tile-config-trigger{--icon-size: var(--files-icon-size);--button-padding: var(--files-button-padding)}:host ymd-ribbon .options button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host ymd-ribbon .options button yvc-icon{--icon-size: var(--files-icon-size)}:host ymd-ribbon .options button.toggle.enabled{background-color:var(--item-focus-background-color)}:host main{height:100%;overflow:hidden;display:flex;flex-flow:column}:host main yvc-master-details{flex:1;overflow:hidden;box-sizing:border-box}:host .error{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .error p{max-width:31ch;line-height:1.5em;display:grid;justify-items:center}:host .error p yvc-icon{--icon-size: 48px;display:block;margin-block-end:1rem}:host .files{display:flex;flex-flow:column;overflow:hidden;height:100%}:host .files header{flex:0 0 auto;padding:var(--app-pane-padding);display:grid;grid-template-columns:2fr max-content;grid-template-rows:auto auto 1fr;gap:0;grid-auto-flow:row;grid-template-areas:\"title sort\" \"searchfilter searchfilter\" \"flavours flavours\"}:host .files header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400;text-overflow:ellipsis;overflow:hidden}:host .files header .flavors{grid-area:flavors;display:flex;gap:2px;justify-content:flex-end;padding:calc(var(--app-pane-padding) / 4)}:host .files header .flavors yuv-flavor-chip{font-size:var(--font-hint);cursor:pointer;--flavor-background: var(--panel-background);--flavor-icon-size: 16px}:host .files header .flavors yuv-flavor-chip:hover{--flavor-border-color: var(--color-accent)}:host .files header ymd-sort{grid-area:sort}:host .files header ymd-search-filter{grid-area:searchfilter}:host .files yuv-tile-list{flex:1;overflow:hidden}:host .message{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .message p{max-width:31ch;line-height:1.5em}:host yvc-split-view{height:100%;box-sizing:border-box}:host ymd-folder-tree,:host yuv-object-summary{height:100%;overflow-y:auto;box-sizing:border-box}:host yuv-tile-list{--tile-border: 1px solid var(--panel-divider-color);--tile-border-width: 0 0 1px 0;--tile-padding: calc(var(--app-pane-padding) / 2);--tile-icon-size: 18px;--tile-action-icon-size: 18px;--paging-background: var(--panel-background-lightgrey)}:host p.empty{color:var(--text-color-caption)}:host .details{height:100%}:host .details yuv-object-details{height:100%}:host.smallScreen yuv-tile-list{--tile-padding: var(--app-pane-padding) !important}@keyframes fade-in{0%{opacity:0}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: YvcSplitViewModule }, { kind: "component", type: i3.SplitViewComponent, selector: "yvc-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "gutterDblClickDuration", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "directive", type: i3.SplitAreaDirective, selector: "[yvcSplitArea]", inputs: ["size", "order", "minSize", "maxSize", "panelClass", "visible"] }, { kind: "component", type: TileListComponent, selector: "yuv-tile-list", inputs: ["bucket", "multiselect", "options", "flavor", "query", "preselect", "highlights"], outputs: ["itemSelect", "copy", "cut", "busy", "queryResult", "selectionChange", "itemDblClick", "ctxMenu"] }, { kind: "component", type: BreadcrumbComponent, selector: "ymd-breadcrumb" }, { kind: "component", type: FolderTreeComponent, selector: "ymd-folder-tree" }, { kind: "component", type: ObjectSummaryComponent, selector: "yuv-object-summary", inputs: ["actions", "dmsObject", "objectId", "configType"] }, { kind: "component", type: TileConfigTriggerComponent, selector: "yuv-tile-config-trigger", inputs: ["icon", "bucket", "bucketLabel", "options"] }, { kind: "component", type: RibbonComponent, selector: "ymd-ribbon", inputs: ["busy", "enableClipboard", "objects", "excludeActions"] }, { kind: "component", type: AddButtonComponent, selector: "ymd-add-button", inputs: ["disabled"] }, { kind: "component", type: SimpleSearchComponent, selector: "yuv-simple-search", inputs: ["targets", "query"], outputs: ["querySubmit", "targetSelectionChanged", "queryChange", "typeAggregation"] }, { kind: "component", type: MultiObjectSummaryComponent, selector: "yuv-multi-object-summary", inputs: ["headline"] }, { kind: "component", type: SortComponent, selector: "ymd-sort", outputs: ["sortChanged"] }, { kind: "component", type: SearchFilterComponent, selector: "ymd-search-filter", inputs: ["query"], outputs: ["queryChange"] }, { kind: "directive", type: FileDropZoneDirective, selector: "[yuvFileDropZone]", inputs: ["yuvFileDropZone", "fileDropDisabled"], outputs: ["fileDrop", "fileDropOver"] }] }); }
2787
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: FilesPageComponent, isStandalone: true, selector: "ymd-files", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.smallScreen": "smallScreenLayout()" } }, viewQueries: [{ propertyName: "tileList", first: true, predicate: ["tileList"], descendants: true, isSignal: true }, { propertyName: "splitViewCmp", first: true, predicate: SplitViewComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<header>\n <!-- navigation bar -->\n <nav [attr.aria-label]=\"'yuv.app.drive.files.naviagtion.aria.label' | translate\">\n <div class=\"nav\">\n <button class=\"back\" [disabled]=\"!currentFolder\" title=\"{{ 'yuv.app.drive.files.nav.back.tooltip' | translate }}\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.files.nav.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n\n @if (!query()?.term) {\n <ymd-breadcrumb></ymd-breadcrumb>\n } @else {\n <div class=\"breadcrumb\"></div>\n }\n <div class=\"search\">\n <ymd-drive-search></ymd-drive-search>\n </div>\n </nav>\n\n <!-- ribbon with actions and options -->\n <ymd-ribbon [objects]=\"selection()\" [busy]=\"busy()\" [enableClipboard]=\"true\">\n <ng-template #primaryActions>\n <ymd-add-button [disabled]=\"disableCreate\"></ymd-add-button>\n </ng-template>\n\n <ng-template #secondaryActions>\n <div class=\"options\">\n @if (!smallScreenLayout()) {\n <button\n class=\"toggle-tree toggle\"\n [ngClass]=\"{ enabled: enableTree() }\"\n title=\"{{ 'yuv.app.drive.files.toggletree.tooltip' | translate }}\"\n (click)=\"enableTree.set(!enableTree())\"\n >\n <yvc-icon [svg]=\"icons.toggleLeft\"></yvc-icon>\n </button>\n <button\n class=\"toggle-details toggle\"\n [ngClass]=\"{ enabled: enableDetails() }\"\n title=\"{{ 'yuv.app.drive.files.toggledetails.tooltip' | translate }}\"\n (click)=\"enableDetails.set(!enableDetails())\"\n >\n <yvc-icon [svg]=\"icons.toggleRight\"></yvc-icon>\n </button>\n }\n <yuv-tile-config-trigger\n [icon]=\"icons.settings\"\n [bucket]=\"objectConfigBucket\"\n [bucketLabel]=\"tileConfigBucketLabel\"\n [options]=\"tileListOptions\"\n ></yuv-tile-config-trigger>\n </div>\n </ng-template>\n </ymd-ribbon>\n</header>\n\n<yvc-split-view [gutterSize]=\"1\" (layoutSettingsChange)=\"onLayoutSettingsChange($event)\">\n <!-- folder tree -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableTree() && !smallScreenLayout()\">\n <ymd-folder-tree yuvFocusable=\"Tree\"></ymd-folder-tree>\n </ng-template>\n\n <!-- files -->\n <ng-template yvcSplitArea [size]=\"60\">\n @let err = error();\n @if (err) {\n <div class=\"error\">\n <p>\n <yvc-icon [svg]=\"icons.attention\"></yvc-icon>\n @switch (err) {\n @case (ERROR_CODE.NOT_FOUND) {\n {{ 'yuv.app.drive.files.error.load.not-found' | translate }}\n }\n @case (ERROR_CODE.INVALID_ID) {\n {{ 'yuv.app.drive.files.error.load.invalid-id' | translate }}\n }\n @default {\n {{ 'yuv.app.drive.files.error.load' | translate }}\n }\n }\n </p>\n </div>\n } @else {\n <div class=\"files\" [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.label' | translate }\" (fileDrop)=\"onFileDrop($event)\">\n <header class=\"files-header\">\n <h1>{{ queryTitle() }}</h1>\n @if (query()?.term && !extendedQuery()) {\n <ymd-search-filter [query]=\"query()\" (queryChange)=\"onFilterQueryChange($event)\"></ymd-search-filter>\n }\n @if (sortOptionsAvailable()) {\n <ymd-sort />\n }\n <div class=\"flavors\">\n <!-- TODO: enable again once flavors/aspects are supported -->\n <!-- @for (f of flavorChips; track f.id) {\n <yuv-flavor-chip [ngClass]=\"{ active: f.id === appliedFlavor?.id }\" [flavor]=\"f\" (click)=\"appliedFlavor = f\"></yuv-flavor-chip>\n }-->\n </div>\n </header>\n\n <yuv-tile-list\n #tileList\n class=\"staggered\"\n [attr.aria-label]=\"'yuv.app.drive.files.content.aria.label' | translate\"\n [attr.aria-busy]=\"busy()\"\n [attr.role]=\"'listbox'\"\n (keydown.delete)=\"onDelete()\"\n [bucket]=\"objectConfigBucket\"\n [multiselect]=\"true\"\n [query]=\"query()\"\n [flavor]=\"appliedFlavor\"\n [options]=\"tileListOptions\"\n (itemDblClick)=\"itemDoubleClicked($event)\"\n (itemSelect)=\"itemClicked($event)\"\n (selectionChange)=\"selectionChanged($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n (busy)=\"setBusy($event)\"\n (ctxMenu)=\"onContextmenu($event)\"\n [highlights]=\"highlightStyles$ | async\"\n >\n <div #empty>\n @if (emptyMode() === 'root') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.root.list' | translate }}</p>\n } @else if (emptyMode() === 'query') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.query.list' | translate }}</p>\n } @else {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.list' | translate }}</p>\n }\n </div>\n </yuv-tile-list>\n </div>\n }\n </ng-template>\n\n <!-- details -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableDetails()\">\n @let selectedItem = selected();\n @if (enableDetails() && selectedItem) {\n @if (selectedItem?.isFolder) {\n <yuv-object-summary [configType]=\"configTypeOptions['folder']\" [dmsObject]=\"selectedItem\"></yuv-object-summary>\n } @else {\n <yuv-object-summary\n [configType]=\"configTypeOptions['file']\"\n [dmsObject]=\"selectedItem\"\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropSummaryDisabled()\"\n (fileDrop)=\"onFileUpdateDrop($event)\"\n ></yuv-object-summary>\n }\n } @else {\n @let sel = selection();\n @if (sel && sel.length > 0) {\n <yuv-multi-object-summary [headline]=\"'yuv.app.drive.multiselected.details' | translate: { count: selection().length }\"></yuv-multi-object-summary>\n } @else if (tileList()?.items?.length === 0) {\n <!-- TODO: CHOULD HAVE A DIFFERENT MESSAGE FOR EMPTY RESULTS EMPTY FOR NOW -->\n <div class=\"message\">{{ 'yuv.app.drive.empty.results.details.message' | translate }}</div>\n } @else {\n <div class=\"message\">{{ 'yuv.app.drive.unselected.details' | translate }}</div>\n }\n }\n </ng-template>\n</yvc-split-view>\n", styles: [":host{--files-button-padding: calc(var(--app-pane-padding) / 4);--files-button-border-radius: 2px;--files-button-gap: calc(var(--app-pane-padding) / 4);--files-icon-size: 20px;height:100%;overflow:hidden;display:flex;flex-flow:column}:host header{flex:0 0 auto}:host header>nav{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);display:grid;grid-template-columns:auto 1fr 1fr auto;align-items:center;gap:calc(var(--app-pane-padding) / 2);padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2)}:host header>nav .nav{grid-column:1/2;grid-row:1;display:flex;align-items:center;gap:var(--files-button-gap)}:host header>nav .nav button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host header>nav .nav button yvc-icon{--icon-size: var(--files-icon-size)}:host header>nav .breadcrumb{grid-column:2/4;grid-row:1;align-self:stretch;display:flex;align-items:center;border-radius:var(--files-button-border-radius);padding:0 .5em;border:1px solid var(--panel-divider-color)}:host header>nav .search{grid-column:-1/-2;grid-row:1;z-index:1}:host yvc-split-view{flex:1;animation:fade-in .3s ease-in-out}:host ymd-ribbon{--ribbon-button-padding: var(--files-button-padding);--ribbon-button-border-radius: var(--files-button-border-radius);--ribbon-button-gap: var(--files-button-gap);--ribbon-icon-size: var(--files-icon-size)}:host ymd-ribbon .options{grid-area:options;display:flex;gap:var(--files-button-gap);align-items:center}:host ymd-ribbon .options yuv-tile-config-trigger{--icon-size: var(--files-icon-size);--button-padding: var(--files-button-padding)}:host ymd-ribbon .options button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host ymd-ribbon .options button yvc-icon{--icon-size: var(--files-icon-size)}:host ymd-ribbon .options button.toggle.enabled{background-color:var(--item-focus-background-color)}:host main{height:100%;overflow:hidden;display:flex;flex-flow:column}:host main yvc-master-details{flex:1;overflow:hidden;box-sizing:border-box}:host .error{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .error p{max-width:31ch;line-height:1.5em;display:grid;justify-items:center}:host .error p yvc-icon{--icon-size: 48px;display:block;margin-block-end:1rem}:host .files{display:flex;flex-flow:column;overflow:hidden;height:100%}:host .files header{flex:0 0 auto;padding:var(--app-pane-padding);display:grid;grid-template-columns:2fr max-content;grid-template-rows:auto auto 1fr;gap:0;grid-auto-flow:row;grid-template-areas:\"title sort\" \"searchfilter searchfilter\" \"flavours flavours\"}:host .files header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400;text-overflow:ellipsis;overflow:hidden}:host .files header .flavors{grid-area:flavors;display:flex;gap:2px;justify-content:flex-end;padding:calc(var(--app-pane-padding) / 4)}:host .files header .flavors yuv-flavor-chip{font-size:var(--font-hint);cursor:pointer;--flavor-background: var(--panel-background);--flavor-icon-size: 16px}:host .files header .flavors yuv-flavor-chip:hover{--flavor-border-color: var(--color-accent)}:host .files header ymd-sort{grid-area:sort}:host .files header ymd-search-filter{grid-area:searchfilter}:host .files yuv-tile-list{flex:1;overflow:hidden}:host .message{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .message p{max-width:31ch;line-height:1.5em}:host yvc-split-view{height:100%;box-sizing:border-box}:host ymd-folder-tree,:host yuv-object-summary{height:100%;overflow-y:auto;box-sizing:border-box}:host yuv-tile-list{--tile-border: 1px solid var(--panel-divider-color);--tile-border-width: 0 0 1px 0;--tile-padding: calc(var(--app-pane-padding) / 2);--tile-icon-size: 18px;--tile-action-icon-size: 18px;--paging-background: var(--panel-background-lightgrey)}:host p.empty{color:var(--text-color-caption)}:host .details{height:100%}:host .details yuv-object-details{height:100%}:host.smallScreen yuv-tile-list{--tile-padding: var(--app-pane-padding) !important}@keyframes fade-in{0%{opacity:0}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: YvcSplitViewModule }, { kind: "component", type: i3.SplitViewComponent, selector: "yvc-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "gutterDblClickDuration", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "directive", type: i3.SplitAreaDirective, selector: "[yvcSplitArea]", inputs: ["size", "order", "minSize", "maxSize", "panelClass", "visible"] }, { kind: "component", type: TileListComponent, selector: "yuv-tile-list", inputs: ["bucket", "multiselect", "options", "flavor", "query", "preselect", "highlights"], outputs: ["itemSelect", "copy", "cut", "busy", "queryResult", "selectionChange", "itemDblClick", "ctxMenu"] }, { kind: "component", type: BreadcrumbComponent, selector: "ymd-breadcrumb" }, { kind: "component", type: FolderTreeComponent, selector: "ymd-folder-tree" }, { kind: "component", type: ObjectSummaryComponent, selector: "yuv-object-summary", inputs: ["actions", "dmsObject", "objectId", "configType"] }, { kind: "component", type: TileConfigTriggerComponent, selector: "yuv-tile-config-trigger", inputs: ["icon", "bucket", "bucketLabel", "options"] }, { kind: "component", type: RibbonComponent, selector: "ymd-ribbon", inputs: ["busy", "enableClipboard", "objects", "excludeActions"] }, { kind: "component", type: AddButtonComponent, selector: "ymd-add-button", inputs: ["disabled"] }, { kind: "component", type: MultiObjectSummaryComponent, selector: "yuv-multi-object-summary", inputs: ["headline"] }, { kind: "component", type: SortComponent, selector: "ymd-sort", outputs: ["sortChanged"] }, { kind: "component", type: SearchFilterComponent, selector: "ymd-search-filter", inputs: ["query"], outputs: ["queryChange"] }, { kind: "component", type: DriveSearchComponent, selector: "ymd-drive-search" }, { kind: "directive", type: FileDropZoneDirective, selector: "[yuvFileDropZone]", inputs: ["yuvFileDropZone", "fileDropDisabled"], outputs: ["fileDrop", "fileDropOver"] }] }); }
2726
2788
  }
2727
2789
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilesPageComponent, decorators: [{
2728
2790
  type: Component,
2729
2791
  args: [{ selector: 'ymd-files', standalone: true, imports: [NgClass, AsyncPipe, ...module, ...components, FileDropZoneDirective], host: {
2730
2792
  '[class.smallScreen]': 'smallScreenLayout()'
2731
- }, template: "<header>\n <!-- navigation bar -->\n <nav [attr.aria-label]=\"'yuv.app.drive.files.naviagtion.aria.label' | translate\">\n <div class=\"nav\">\n <button class=\"back\" [disabled]=\"!currentFolder\" title=\"{{ 'yuv.app.drive.files.nav.back.tooltip' | translate }}\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.files.nav.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n\n @if (!query()?.term) {\n <ymd-breadcrumb></ymd-breadcrumb>\n } @else {\n <div class=\"breadcrumb\"></div>\n }\n <div class=\"search\">\n <yuv-simple-search [query]=\"query()\" (querySubmit)=\"onQuerySubmit($event)\"></yuv-simple-search>\n <!-- TODO: enable again once drive search needs to be a little bit more sophisticated -->\n <!-- <ymd-drive-search (focused)=\"searchFocused = $event\"></ymd-drive-search> -->\n </div>\n </nav>\n\n <!-- ribbon with actions and options -->\n <ymd-ribbon [objects]=\"selection()\" [busy]=\"busy()\" [enableClipboard]=\"true\">\n <ng-template #primaryActions>\n <ymd-add-button [disabled]=\"disableCreate\"></ymd-add-button>\n </ng-template>\n\n <ng-template #secondaryActions>\n <div class=\"options\">\n @if (!smallScreenLayout()) {\n <button\n class=\"toggle-tree toggle\"\n [ngClass]=\"{ enabled: enableTree() }\"\n title=\"{{ 'yuv.app.drive.files.toggletree.tooltip' | translate }}\"\n (click)=\"enableTree.set(!enableTree())\"\n >\n <yvc-icon [svg]=\"icons.toggleLeft\"></yvc-icon>\n </button>\n <button\n class=\"toggle-details toggle\"\n [ngClass]=\"{ enabled: enableDetails() }\"\n title=\"{{ 'yuv.app.drive.files.toggledetails.tooltip' | translate }}\"\n (click)=\"enableDetails.set(!enableDetails())\"\n >\n <yvc-icon [svg]=\"icons.toggleRight\"></yvc-icon>\n </button>\n }\n <yuv-tile-config-trigger\n [icon]=\"icons.settings\"\n [bucket]=\"objectConfigBucket\"\n [bucketLabel]=\"tileConfigBucketLabel\"\n [options]=\"tileListOptions\"\n ></yuv-tile-config-trigger>\n </div>\n </ng-template>\n </ymd-ribbon>\n</header>\n\n<yvc-split-view [gutterSize]=\"1\" (layoutSettingsChange)=\"onLayoutSettingsChange($event)\">\n <!-- folder tree -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableTree() && !smallScreenLayout()\">\n <ymd-folder-tree yuvFocusable=\"Tree\"></ymd-folder-tree>\n </ng-template>\n\n <!-- files -->\n <ng-template yvcSplitArea [size]=\"60\">\n @let err = error();\n @if (err) {\n <div class=\"error\">\n <p>\n <yvc-icon [svg]=\"icons.attention\"></yvc-icon>\n @switch (err) {\n @case (ERROR_CODE.NOT_FOUND) {\n {{ 'yuv.app.drive.files.error.load.not-found' | translate }}\n }\n @case (ERROR_CODE.INVALID_ID) {\n {{ 'yuv.app.drive.files.error.load.invalid-id' | translate }}\n }\n @default {\n {{ 'yuv.app.drive.files.error.load' | translate }}\n }\n }\n </p>\n </div>\n } @else {\n <div class=\"files\" [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.label' | translate }\" (fileDrop)=\"onFileDrop($event)\">\n <header class=\"files-header\">\n <h1>{{ queryTitle() }}</h1>\n @if (query()?.term) {\n <ymd-search-filter [query]=\"query()\" (queryChange)=\"onFilterQueryChange($event)\"></ymd-search-filter>\n }\n @if (sortOptionsAvailable()) {\n <ymd-sort />\n }\n <div class=\"flavors\">\n <!-- TODO: enable again once flavors/aspects are supported -->\n <!-- @for (f of flavorChips; track f.id) {\n <yuv-flavor-chip [ngClass]=\"{ active: f.id === appliedFlavor?.id }\" [flavor]=\"f\" (click)=\"appliedFlavor = f\"></yuv-flavor-chip>\n }-->\n </div>\n </header>\n\n <yuv-tile-list\n #tileList\n class=\"staggered\"\n [attr.aria-label]=\"'yuv.app.drive.files.content.aria.label' | translate\"\n [attr.aria-busy]=\"busy()\"\n [attr.role]=\"'listbox'\"\n (keydown.delete)=\"onDelete()\"\n [bucket]=\"objectConfigBucket\"\n [multiselect]=\"true\"\n [query]=\"query()\"\n [flavor]=\"appliedFlavor\"\n [options]=\"tileListOptions\"\n (itemDblClick)=\"itemDoubleClicked($event)\"\n (itemSelect)=\"itemClicked($event)\"\n (selectionChange)=\"selectionChanged($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n (busy)=\"setBusy($event)\"\n (ctxMenu)=\"onContextmenu($event)\"\n [highlights]=\"highlightStyles$ | async\"\n >\n <div #empty>\n @if (emptyMode() === 'root') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.root.list' | translate }}</p>\n } @else if (emptyMode() === 'query') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.query.list' | translate }}</p>\n } @else {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.list' | translate }}</p>\n }\n </div>\n </yuv-tile-list>\n </div>\n }\n </ng-template>\n\n <!-- details -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableDetails()\">\n @let selectedItem = selected();\n @if (enableDetails() && selectedItem) {\n @if (selectedItem?.isFolder) {\n <yuv-object-summary [configType]=\"configTypeOptions['folder']\" [dmsObject]=\"selectedItem\"></yuv-object-summary>\n } @else {\n <yuv-object-summary\n [configType]=\"configTypeOptions['file']\"\n [dmsObject]=\"selectedItem\"\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropSummaryDisabled()\"\n (fileDrop)=\"onFileUpdateDrop($event)\"\n ></yuv-object-summary>\n }\n } @else {\n @let sel = selection();\n @if (sel && sel.length > 0) {\n <yuv-multi-object-summary [headline]=\"'yuv.app.drive.multiselected.details' | translate: { count: selection().length }\"></yuv-multi-object-summary>\n } @else if (tileList()?.items?.length === 0) {\n <!-- TODO: CHOULD HAVE A DIFFERENT MESSAGE FOR EMPTY RESULTS EMPTY FOR NOW -->\n <div class=\"message\">{{ 'yuv.app.drive.empty.results.details.message' | translate }}</div>\n } @else {\n <div class=\"message\">{{ 'yuv.app.drive.unselected.details' | translate }}</div>\n }\n }\n </ng-template>\n</yvc-split-view>\n", styles: [":host{--files-button-padding: calc(var(--app-pane-padding) / 4);--files-button-border-radius: 2px;--files-button-gap: calc(var(--app-pane-padding) / 4);--files-icon-size: 20px;height:100%;overflow:hidden;display:flex;flex-flow:column}:host.searchFocused header>nav .search{grid-column:-1/-3}:host header{flex:0 0 auto}:host header>nav{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);display:grid;grid-template-columns:auto 1fr 1fr auto;align-items:center;gap:calc(var(--app-pane-padding) / 2);padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2)}:host header>nav .nav{grid-column:1/2;grid-row:1;display:flex;align-items:center;gap:var(--files-button-gap)}:host header>nav .nav button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host header>nav .nav button yvc-icon{--icon-size: var(--files-icon-size)}:host header>nav .breadcrumb{grid-column:2/4;grid-row:1;align-self:stretch;display:flex;align-items:center;border-radius:var(--files-button-border-radius);padding:0 .5em;border:1px solid var(--panel-divider-color)}:host header>nav .search{grid-column:-1/-2;grid-row:1;z-index:1}:host yvc-split-view{flex:1;animation:fade-in .3s ease-in-out}:host ymd-ribbon{--ribbon-button-padding: var(--files-button-padding);--ribbon-button-border-radius: var(--files-button-border-radius);--ribbon-button-gap: var(--files-button-gap);--ribbon-icon-size: var(--files-icon-size)}:host ymd-ribbon .options{grid-area:options;display:flex;gap:var(--files-button-gap);align-items:center}:host ymd-ribbon .options yuv-tile-config-trigger{--icon-size: var(--files-icon-size);--button-padding: var(--files-button-padding)}:host ymd-ribbon .options button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host ymd-ribbon .options button yvc-icon{--icon-size: var(--files-icon-size)}:host ymd-ribbon .options button.toggle.enabled{background-color:var(--item-focus-background-color)}:host main{height:100%;overflow:hidden;display:flex;flex-flow:column}:host main yvc-master-details{flex:1;overflow:hidden;box-sizing:border-box}:host .error{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .error p{max-width:31ch;line-height:1.5em;display:grid;justify-items:center}:host .error p yvc-icon{--icon-size: 48px;display:block;margin-block-end:1rem}:host .files{display:flex;flex-flow:column;overflow:hidden;height:100%}:host .files header{flex:0 0 auto;padding:var(--app-pane-padding);display:grid;grid-template-columns:2fr max-content;grid-template-rows:auto auto 1fr;gap:0;grid-auto-flow:row;grid-template-areas:\"title sort\" \"searchfilter searchfilter\" \"flavours flavours\"}:host .files header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400;text-overflow:ellipsis;overflow:hidden}:host .files header .flavors{grid-area:flavors;display:flex;gap:2px;justify-content:flex-end;padding:calc(var(--app-pane-padding) / 4)}:host .files header .flavors yuv-flavor-chip{font-size:var(--font-hint);cursor:pointer;--flavor-background: var(--panel-background);--flavor-icon-size: 16px}:host .files header .flavors yuv-flavor-chip:hover{--flavor-border-color: var(--color-accent)}:host .files header ymd-sort{grid-area:sort}:host .files header ymd-search-filter{grid-area:searchfilter}:host .files yuv-tile-list{flex:1;overflow:hidden}:host .message{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .message p{max-width:31ch;line-height:1.5em}:host yvc-split-view{height:100%;box-sizing:border-box}:host ymd-folder-tree,:host yuv-object-summary{height:100%;overflow-y:auto;box-sizing:border-box}:host yuv-tile-list{--tile-border: 1px solid var(--panel-divider-color);--tile-border-width: 0 0 1px 0;--tile-padding: calc(var(--app-pane-padding) / 2);--tile-icon-size: 18px;--tile-action-icon-size: 18px;--paging-background: var(--panel-background-lightgrey)}:host p.empty{color:var(--text-color-caption)}:host .details{height:100%}:host .details yuv-object-details{height:100%}:host.smallScreen yuv-tile-list{--tile-padding: var(--app-pane-padding) !important}@keyframes fade-in{0%{opacity:0}}\n"] }]
2732
- }], ctorParameters: () => [], propDecorators: { searchFocused: [{
2733
- type: HostBinding,
2734
- args: ['class.searchFocused']
2735
- }] } });
2793
+ }, template: "<header>\n <!-- navigation bar -->\n <nav [attr.aria-label]=\"'yuv.app.drive.files.naviagtion.aria.label' | translate\">\n <div class=\"nav\">\n <button class=\"back\" [disabled]=\"!currentFolder\" title=\"{{ 'yuv.app.drive.files.nav.back.tooltip' | translate }}\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.files.nav.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n\n @if (!query()?.term) {\n <ymd-breadcrumb></ymd-breadcrumb>\n } @else {\n <div class=\"breadcrumb\"></div>\n }\n <div class=\"search\">\n <ymd-drive-search></ymd-drive-search>\n </div>\n </nav>\n\n <!-- ribbon with actions and options -->\n <ymd-ribbon [objects]=\"selection()\" [busy]=\"busy()\" [enableClipboard]=\"true\">\n <ng-template #primaryActions>\n <ymd-add-button [disabled]=\"disableCreate\"></ymd-add-button>\n </ng-template>\n\n <ng-template #secondaryActions>\n <div class=\"options\">\n @if (!smallScreenLayout()) {\n <button\n class=\"toggle-tree toggle\"\n [ngClass]=\"{ enabled: enableTree() }\"\n title=\"{{ 'yuv.app.drive.files.toggletree.tooltip' | translate }}\"\n (click)=\"enableTree.set(!enableTree())\"\n >\n <yvc-icon [svg]=\"icons.toggleLeft\"></yvc-icon>\n </button>\n <button\n class=\"toggle-details toggle\"\n [ngClass]=\"{ enabled: enableDetails() }\"\n title=\"{{ 'yuv.app.drive.files.toggledetails.tooltip' | translate }}\"\n (click)=\"enableDetails.set(!enableDetails())\"\n >\n <yvc-icon [svg]=\"icons.toggleRight\"></yvc-icon>\n </button>\n }\n <yuv-tile-config-trigger\n [icon]=\"icons.settings\"\n [bucket]=\"objectConfigBucket\"\n [bucketLabel]=\"tileConfigBucketLabel\"\n [options]=\"tileListOptions\"\n ></yuv-tile-config-trigger>\n </div>\n </ng-template>\n </ymd-ribbon>\n</header>\n\n<yvc-split-view [gutterSize]=\"1\" (layoutSettingsChange)=\"onLayoutSettingsChange($event)\">\n <!-- folder tree -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableTree() && !smallScreenLayout()\">\n <ymd-folder-tree yuvFocusable=\"Tree\"></ymd-folder-tree>\n </ng-template>\n\n <!-- files -->\n <ng-template yvcSplitArea [size]=\"60\">\n @let err = error();\n @if (err) {\n <div class=\"error\">\n <p>\n <yvc-icon [svg]=\"icons.attention\"></yvc-icon>\n @switch (err) {\n @case (ERROR_CODE.NOT_FOUND) {\n {{ 'yuv.app.drive.files.error.load.not-found' | translate }}\n }\n @case (ERROR_CODE.INVALID_ID) {\n {{ 'yuv.app.drive.files.error.load.invalid-id' | translate }}\n }\n @default {\n {{ 'yuv.app.drive.files.error.load' | translate }}\n }\n }\n </p>\n </div>\n } @else {\n <div class=\"files\" [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.label' | translate }\" (fileDrop)=\"onFileDrop($event)\">\n <header class=\"files-header\">\n <h1>{{ queryTitle() }}</h1>\n @if (query()?.term && !extendedQuery()) {\n <ymd-search-filter [query]=\"query()\" (queryChange)=\"onFilterQueryChange($event)\"></ymd-search-filter>\n }\n @if (sortOptionsAvailable()) {\n <ymd-sort />\n }\n <div class=\"flavors\">\n <!-- TODO: enable again once flavors/aspects are supported -->\n <!-- @for (f of flavorChips; track f.id) {\n <yuv-flavor-chip [ngClass]=\"{ active: f.id === appliedFlavor?.id }\" [flavor]=\"f\" (click)=\"appliedFlavor = f\"></yuv-flavor-chip>\n }-->\n </div>\n </header>\n\n <yuv-tile-list\n #tileList\n class=\"staggered\"\n [attr.aria-label]=\"'yuv.app.drive.files.content.aria.label' | translate\"\n [attr.aria-busy]=\"busy()\"\n [attr.role]=\"'listbox'\"\n (keydown.delete)=\"onDelete()\"\n [bucket]=\"objectConfigBucket\"\n [multiselect]=\"true\"\n [query]=\"query()\"\n [flavor]=\"appliedFlavor\"\n [options]=\"tileListOptions\"\n (itemDblClick)=\"itemDoubleClicked($event)\"\n (itemSelect)=\"itemClicked($event)\"\n (selectionChange)=\"selectionChanged($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n (busy)=\"setBusy($event)\"\n (ctxMenu)=\"onContextmenu($event)\"\n [highlights]=\"highlightStyles$ | async\"\n >\n <div #empty>\n @if (emptyMode() === 'root') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.root.list' | translate }}</p>\n } @else if (emptyMode() === 'query') {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.query.list' | translate }}</p>\n } @else {\n <p class=\"empty\">{{ 'yuv.app.drive.files.content.empty.list' | translate }}</p>\n }\n </div>\n </yuv-tile-list>\n </div>\n }\n </ng-template>\n\n <!-- details -->\n <ng-template yvcSplitArea [size]=\"20\" [visible]=\"enableDetails()\">\n @let selectedItem = selected();\n @if (enableDetails() && selectedItem) {\n @if (selectedItem?.isFolder) {\n <yuv-object-summary [configType]=\"configTypeOptions['folder']\" [dmsObject]=\"selectedItem\"></yuv-object-summary>\n } @else {\n <yuv-object-summary\n [configType]=\"configTypeOptions['file']\"\n [dmsObject]=\"selectedItem\"\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropSummaryDisabled()\"\n (fileDrop)=\"onFileUpdateDrop($event)\"\n ></yuv-object-summary>\n }\n } @else {\n @let sel = selection();\n @if (sel && sel.length > 0) {\n <yuv-multi-object-summary [headline]=\"'yuv.app.drive.multiselected.details' | translate: { count: selection().length }\"></yuv-multi-object-summary>\n } @else if (tileList()?.items?.length === 0) {\n <!-- TODO: CHOULD HAVE A DIFFERENT MESSAGE FOR EMPTY RESULTS EMPTY FOR NOW -->\n <div class=\"message\">{{ 'yuv.app.drive.empty.results.details.message' | translate }}</div>\n } @else {\n <div class=\"message\">{{ 'yuv.app.drive.unselected.details' | translate }}</div>\n }\n }\n </ng-template>\n</yvc-split-view>\n", styles: [":host{--files-button-padding: calc(var(--app-pane-padding) / 4);--files-button-border-radius: 2px;--files-button-gap: calc(var(--app-pane-padding) / 4);--files-icon-size: 20px;height:100%;overflow:hidden;display:flex;flex-flow:column}:host header{flex:0 0 auto}:host header>nav{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);display:grid;grid-template-columns:auto 1fr 1fr auto;align-items:center;gap:calc(var(--app-pane-padding) / 2);padding:calc(var(--app-pane-padding) / 4) calc(var(--app-pane-padding) / 2)}:host header>nav .nav{grid-column:1/2;grid-row:1;display:flex;align-items:center;gap:var(--files-button-gap)}:host header>nav .nav button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host header>nav .nav button yvc-icon{--icon-size: var(--files-icon-size)}:host header>nav .breadcrumb{grid-column:2/4;grid-row:1;align-self:stretch;display:flex;align-items:center;border-radius:var(--files-button-border-radius);padding:0 .5em;border:1px solid var(--panel-divider-color)}:host header>nav .search{grid-column:-1/-2;grid-row:1;z-index:1}:host yvc-split-view{flex:1;animation:fade-in .3s ease-in-out}:host ymd-ribbon{--ribbon-button-padding: var(--files-button-padding);--ribbon-button-border-radius: var(--files-button-border-radius);--ribbon-button-gap: var(--files-button-gap);--ribbon-icon-size: var(--files-icon-size)}:host ymd-ribbon .options{grid-area:options;display:flex;gap:var(--files-button-gap);align-items:center}:host ymd-ribbon .options yuv-tile-config-trigger{--icon-size: var(--files-icon-size);--button-padding: var(--files-button-padding)}:host ymd-ribbon .options button{padding:var(--files-button-padding);border-radius:var(--files-button-border-radius)}:host ymd-ribbon .options button yvc-icon{--icon-size: var(--files-icon-size)}:host ymd-ribbon .options button.toggle.enabled{background-color:var(--item-focus-background-color)}:host main{height:100%;overflow:hidden;display:flex;flex-flow:column}:host main yvc-master-details{flex:1;overflow:hidden;box-sizing:border-box}:host .error{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .error p{max-width:31ch;line-height:1.5em;display:grid;justify-items:center}:host .error p yvc-icon{--icon-size: 48px;display:block;margin-block-end:1rem}:host .files{display:flex;flex-flow:column;overflow:hidden;height:100%}:host .files header{flex:0 0 auto;padding:var(--app-pane-padding);display:grid;grid-template-columns:2fr max-content;grid-template-rows:auto auto 1fr;gap:0;grid-auto-flow:row;grid-template-areas:\"title sort\" \"searchfilter searchfilter\" \"flavours flavours\"}:host .files header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400;text-overflow:ellipsis;overflow:hidden}:host .files header .flavors{grid-area:flavors;display:flex;gap:2px;justify-content:flex-end;padding:calc(var(--app-pane-padding) / 4)}:host .files header .flavors yuv-flavor-chip{font-size:var(--font-hint);cursor:pointer;--flavor-background: var(--panel-background);--flavor-icon-size: 16px}:host .files header .flavors yuv-flavor-chip:hover{--flavor-border-color: var(--color-accent)}:host .files header ymd-sort{grid-area:sort}:host .files header ymd-search-filter{grid-area:searchfilter}:host .files yuv-tile-list{flex:1;overflow:hidden}:host .message{display:grid;justify-items:center;align-items:center;height:100%;padding:0 2rem;text-align:center;color:var(--text-color-caption)}:host .message p{max-width:31ch;line-height:1.5em}:host yvc-split-view{height:100%;box-sizing:border-box}:host ymd-folder-tree,:host yuv-object-summary{height:100%;overflow-y:auto;box-sizing:border-box}:host yuv-tile-list{--tile-border: 1px solid var(--panel-divider-color);--tile-border-width: 0 0 1px 0;--tile-padding: calc(var(--app-pane-padding) / 2);--tile-icon-size: 18px;--tile-action-icon-size: 18px;--paging-background: var(--panel-background-lightgrey)}:host p.empty{color:var(--text-color-caption)}:host .details{height:100%}:host .details yuv-object-details{height:100%}:host.smallScreen yuv-tile-list{--tile-padding: var(--app-pane-padding) !important}@keyframes fade-in{0%{opacity:0}}\n"] }]
2794
+ }], ctorParameters: () => [] });
2736
2795
 
2737
2796
  class ObjectPageComponent {
2738
2797
  #dmsService;
@@ -2743,6 +2802,7 @@ class ObjectPageComponent {
2743
2802
  #objectConfig;
2744
2803
  #drive;
2745
2804
  #device;
2805
+ #retention;
2746
2806
  #dmsObjectEffect;
2747
2807
  constructor() {
2748
2808
  this.#dmsService = inject(DmsService);
@@ -2754,11 +2814,16 @@ class ObjectPageComponent {
2754
2814
  this.translate = inject(TranslateService);
2755
2815
  this.#drive = inject(DriveService);
2756
2816
  this.#device = inject(DeviceService);
2817
+ this.#retention = inject(RetentionService);
2757
2818
  this.busy = this.#drive.state$.busy;
2758
2819
  this.smallScreenLayout = signal(false);
2759
2820
  this.dmsObject = signal(undefined);
2821
+ this.retentionState = signal(undefined);
2760
2822
  this.#dmsObjectEffect = effect(() => this.#setHeaderData());
2761
- this.fileDropReplaceDisabled = computed(() => !this.dmsObject()?.permissions?.writeContent);
2823
+ this.fileDropReplaceDisabled = computed(() => {
2824
+ const e = this.dmsObject();
2825
+ return !e || !e.permissions?.writeContent || this.#retention.getRetentionState(e).underRetention;
2826
+ });
2762
2827
  this.flavoredDmsObject = computed(() => {
2763
2828
  const o = this.dmsObject();
2764
2829
  return o
@@ -2844,6 +2909,7 @@ class ObjectPageComponent {
2844
2909
  description: roc.description,
2845
2910
  icon: roc.icon?.value
2846
2911
  };
2912
+ this.retentionState.set(this.#retention.getRetentionState(o));
2847
2913
  }
2848
2914
  }
2849
2915
  onFileDrop(file) {
@@ -2886,7 +2952,7 @@ class ObjectPageComponent {
2886
2952
  }
2887
2953
  }
2888
2954
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ObjectPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2889
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ObjectPageComponent, isStandalone: true, selector: "ymd-object", host: { attributes: { "class.smallScreenLayout": "smallScreenLayout()" } }, ngImport: i0, template: "@let object = dmsObject();\n@if (object) {\n <div\n class=\"object\"\n yuvContainerSize\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropReplaceDisabled()\"\n (fileDrop)=\"onFileDrop($event)\"\n >\n <ymd-ribbon [objects]=\"[object]\" [excludeActions]=\"excludeActions\">\n <ng-template #primaryActions>\n <div class=\"nav\">\n <button class=\"back\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.page.object.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n </ng-template>\n <!-- <ng-template #secondaryActions></ng-template> -->\n </ymd-ribbon>\n\n @let ssl = smallScreenLayout();\n @if (ssl) {\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs.small'\" [cacheViews]=\"false\">\n <ng-template [yvcTab]=\"{ id: 'content_s', label: 'yuv.app.drive.object-metadata.tabs.content.title' | translate }\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'indexdata_s', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history_s', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n } @else {\n <yvc-split-view [layoutSettingsID]=\"layoutSettingIdBase + 'splitview'\" [gutterSize]=\"1\">\n <ng-template yvcSplitArea [size]=\"40\">\n <section class=\"meta\">\n <header>\n <yuv-object-flavor disableSelection=\"true\" [dmsObject]=\"object\"></yuv-object-flavor>\n\n @if (headerData) {\n <yvc-icon class=\"object-icon\" [svg]=\"headerData.icon\"></yvc-icon>\n <h1><ng-container *yuvRenderer=\"headerData.title\"></ng-container></h1>\n <div class=\"description\"><ng-container *yuvRenderer=\"headerData.description\"></ng-container></div>\n }\n </header>\n\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs'\">\n <ng-template [yvcTab]=\"{ id: 'indexdata', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\" [versionsLink]=\"versionsLink()\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n </section>\n </ng-template>\n <ng-template yvcSplitArea [size]=\"60\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n </yvc-split-view>\n }\n </div>\n} @else if (errorMessage) {\n <!-- object could not be loaded -->\n <div class=\"error state\">\n <yvc-icon [svg]=\"icons.error\"></yvc-icon>\n <p>{{ errorMessage }}</p>\n </div>\n} @else {\n <!-- object is loading -->\n <div class=\"loading state\">\n <div class=\"yuv-loader\"></div>\n </div>\n}\n", styles: [":host{--button-gap: calc(var(--app-pane-padding) / 4);display:flex;flex-flow:column;height:100%;overflow:hidden}:host .state{display:flex;flex-flow:column;height:100%;align-items:center;justify-content:center;border-block-start:1px solid var(--panel-divider-color)}:host .error yvc-icon{--icon-size: 48px;color:rgb(from var(--text-color-body) r g b/.1)}:host .error p{margin:var(--app-pane-padding);max-width:35ch;color:var(--text-color-caption)}:host .state,:host .object{animation:fade-in .3s ease-in-out}:host .object{height:100%;display:flex;flex-flow:column}:host .object ymd-ribbon{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);flex:0 0 auto}:host .object ymd-ribbon button{padding:var(--ribbon-button-padding);border-radius:var(--ribbon-button-border-radius)}:host .object ymd-ribbon button yvc-icon{--icon-size: var(--ribbon-icon-size)}:host .object ymd-ribbon .nav{display:flex;align-items:center;gap:var(--button-gap)}:host .object yvc-tabs{flex:1;background-color:var(--app-drive-header-background)}:host .object yvc-split-view{flex:1}:host .meta{background-color:var(--panel-background);display:flex;flex-flow:column;height:100%}:host .meta header{flex:0 0 auto;display:grid;grid-template-rows:auto calc(var(--app-pane-padding) / 2) auto auto var(--app-pane-padding);grid-template-columns:calc(var(--app-pane-padding) / 2) auto 1fr auto calc(var(--app-pane-padding) / 2);grid-template-areas:\"flavor flavor flavor flavor flavor\" \". . . . .\" \". icon title actions .\" \". . description description .\" \". . . . .\";gap:calc(var(--app-pane-padding) / 2)}:host .meta header yuv-object-flavor{grid-area:flavor;border-block-end:1px solid var(--panel-divider-color)}:host .meta header yvc-icon.object-icon{color:var(--text-color-caption);grid-area:icon}:host .meta header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400}:host .meta header .description{grid-area:description}:host .meta yvc-tabs{flex:1}@keyframes fade-in{0%{opacity:0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectMetadataComponent, selector: "yuv-object-metadata", inputs: ["situation", "formDisabled", "dmsObject", "flavoredDmsObject"], outputs: ["indexDataSaved", "statusChanged"] }, { kind: "component", type: ObjectAuditComponent, selector: "yuv-object-audit", inputs: ["dmsObject", "skipActions", "allActions", "versionsLink"] }, { kind: "component", type: ObjectFlavorComponent, selector: "yuv-object-flavor", inputs: ["dmsObject"], outputs: ["flavorClick"] }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: YvcSplitViewModule }, { kind: "component", type: i3.SplitViewComponent, selector: "yvc-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "gutterDblClickDuration", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "directive", type: i3.SplitAreaDirective, selector: "[yvcSplitArea]", inputs: ["size", "order", "minSize", "maxSize", "panelClass", "visible"] }, { kind: "directive", type: RendererDirective, selector: "[yuvRenderer]", inputs: ["yuvRenderer"] }, { kind: "directive", type: ContainerSizeDirective, selector: "[yuvContainerSize]", outputs: ["containerHeight", "containerWidth"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: RibbonComponent, selector: "ymd-ribbon", inputs: ["busy", "enableClipboard", "objects", "excludeActions"] }, { kind: "ngmodule", type: YvcTabsModule }, { kind: "component", type: i2$2.Tabs, selector: "yvc-tabs", inputs: ["tabs", "layoutSettingsID", "panelOrder", "panelOrderIncludeUnmentioned", "cacheViews", "tabSplitEnabled", "tabRemoveEnabled"], outputs: ["tabSplit", "tabRemove", "tabChange"] }, { kind: "directive", type: i2$2.YvcTabDirective, selector: "[yvcTab]", inputs: ["yvcTab"] }, { kind: "component", type: ObjectPreviewComponent, selector: "yuv-object-preview", inputs: ["objectId", "dmsObject", "version"] }, { kind: "directive", type: FileDropZoneDirective, selector: "[yuvFileDropZone]", inputs: ["yuvFileDropZone", "fileDropDisabled"], outputs: ["fileDrop", "fileDropOver"] }] }); }
2955
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ObjectPageComponent, isStandalone: true, selector: "ymd-object", host: { attributes: { "class.smallScreenLayout": "smallScreenLayout()" } }, ngImport: i0, template: "@let object = dmsObject();\n@if (object) {\n <div\n class=\"object\"\n yuvContainerSize\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropReplaceDisabled()\"\n (fileDrop)=\"onFileDrop($event)\"\n >\n <ymd-ribbon [objects]=\"[object]\" [excludeActions]=\"excludeActions\">\n <ng-template #primaryActions>\n <div class=\"nav\">\n <button class=\"back\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.page.object.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n </ng-template>\n <!-- <ng-template #secondaryActions></ng-template> -->\n </ymd-ribbon>\n\n @let ssl = smallScreenLayout();\n @if (ssl) {\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs.small'\" [cacheViews]=\"false\">\n <ng-template [yvcTab]=\"{ id: 'content_s', label: 'yuv.app.drive.object-metadata.tabs.content.title' | translate }\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'indexdata_s', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history_s', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n } @else {\n <yvc-split-view [layoutSettingsID]=\"layoutSettingIdBase + 'splitview'\" [gutterSize]=\"1\">\n <ng-template yvcSplitArea [size]=\"40\">\n <section class=\"meta\">\n <header>\n <yuv-object-flavor disableSelection=\"true\" [dmsObject]=\"object\"></yuv-object-flavor>\n\n @if (headerData) {\n <yvc-icon class=\"object-icon\" [svg]=\"headerData.icon\"></yvc-icon>\n <h1><ng-container *yuvRenderer=\"headerData.title\"></ng-container></h1>\n <div class=\"description\"><ng-container *yuvRenderer=\"headerData.description\"></ng-container></div>\n <div class=\"badges\">\n <yuv-retention-badge [dmsObject]=\"object\"></yuv-retention-badge>\n </div>\n }\n </header>\n\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs'\">\n <ng-template [yvcTab]=\"{ id: 'indexdata', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\" [versionsLink]=\"versionsLink()\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n </section>\n </ng-template>\n <ng-template yvcSplitArea [size]=\"60\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n </yvc-split-view>\n }\n </div>\n} @else if (errorMessage) {\n <!-- object could not be loaded -->\n <div class=\"error state\">\n <yvc-icon [svg]=\"icons.error\"></yvc-icon>\n <p>{{ errorMessage }}</p>\n </div>\n} @else {\n <!-- object is loading -->\n <div class=\"loading state\">\n <div class=\"yuv-loader\"></div>\n </div>\n}\n", styles: [":host{--button-gap: calc(var(--app-pane-padding) / 4);display:flex;flex-flow:column;height:100%;overflow:hidden}:host .state{display:flex;flex-flow:column;height:100%;align-items:center;justify-content:center;border-block-start:1px solid var(--panel-divider-color)}:host .error yvc-icon{--icon-size: 48px;color:rgb(from var(--text-color-body) r g b/.1)}:host .error p{margin:var(--app-pane-padding);max-width:35ch;color:var(--text-color-caption)}:host .state,:host .object{animation:fade-in .3s ease-in-out}:host .object{height:100%;display:flex;flex-flow:column}:host .object ymd-ribbon{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);flex:0 0 auto}:host .object ymd-ribbon button{padding:var(--ribbon-button-padding);border-radius:var(--ribbon-button-border-radius)}:host .object ymd-ribbon button yvc-icon{--icon-size: var(--ribbon-icon-size)}:host .object ymd-ribbon .nav{display:flex;align-items:center;gap:var(--button-gap)}:host .object yvc-tabs{flex:1;background-color:var(--app-drive-header-background)}:host .object yvc-split-view{flex:1}:host .meta{background-color:var(--panel-background);display:flex;flex-flow:column;height:100%}:host .meta header{flex:0 0 auto;display:grid;grid-template-rows:auto calc(var(--app-pane-padding) / 2) auto auto var(--app-pane-padding);grid-template-columns:calc(var(--app-pane-padding) / 2) auto 1fr auto calc(var(--app-pane-padding) / 2);grid-template-areas:\"flavor flavor flavor flavor flavor\" \". . . . .\" \". icon title actions .\" \". . description description .\" \". . badges badges .\" \". . . . .\";gap:calc(var(--app-pane-padding) / 2)}:host .meta header yuv-object-flavor{grid-area:flavor;border-block-end:1px solid var(--panel-divider-color)}:host .meta header yvc-icon.object-icon{color:var(--text-color-caption);grid-area:icon}:host .meta header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400}:host .meta header .description{grid-area:description}:host .meta header .badges{grid-area:badges;display:flex;flex-flow:row wrap;align-items:center;justify-content:start;gap:calc(var(--app-pane-padding) / 4)}:host .meta yvc-tabs{flex:1}@keyframes fade-in{0%{opacity:0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectMetadataComponent, selector: "yuv-object-metadata", inputs: ["situation", "formDisabled", "dmsObject", "flavoredDmsObject"], outputs: ["indexDataSaved", "statusChanged"] }, { kind: "component", type: ObjectAuditComponent, selector: "yuv-object-audit", inputs: ["dmsObject", "skipActions", "allActions", "versionsLink"] }, { kind: "component", type: ObjectFlavorComponent, selector: "yuv-object-flavor", inputs: ["dmsObject"], outputs: ["flavorClick"] }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: i1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: YvcSplitViewModule }, { kind: "component", type: i3.SplitViewComponent, selector: "yvc-split-view", inputs: ["direction", "gutterSize", "restrictMove", "disabled", "gutterDblClickDuration", "layoutSettingsID"], outputs: ["layoutSettingsChange", "dragStart", "dragEnd", "gutterClick", "gutterDblClick"] }, { kind: "directive", type: i3.SplitAreaDirective, selector: "[yvcSplitArea]", inputs: ["size", "order", "minSize", "maxSize", "panelClass", "visible"] }, { kind: "directive", type: RendererDirective, selector: "[yuvRenderer]", inputs: ["yuvRenderer"] }, { kind: "directive", type: ContainerSizeDirective, selector: "[yuvContainerSize]", outputs: ["containerHeight", "containerWidth"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: RibbonComponent, selector: "ymd-ribbon", inputs: ["busy", "enableClipboard", "objects", "excludeActions"] }, { kind: "ngmodule", type: YvcTabsModule }, { kind: "component", type: i2$3.Tabs, selector: "yvc-tabs", inputs: ["tabs", "layoutSettingsID", "panelOrder", "panelOrderIncludeUnmentioned", "cacheViews", "tabSplitEnabled", "tabRemoveEnabled"], outputs: ["tabSplit", "tabRemove", "tabChange"] }, { kind: "directive", type: i2$3.YvcTabDirective, selector: "[yvcTab]", inputs: ["yvcTab"] }, { kind: "component", type: RetentionBadgeComponent, selector: "yuv-retention-badge", inputs: ["dmsObject"] }, { kind: "component", type: ObjectPreviewComponent, selector: "yuv-object-preview", inputs: ["objectId", "dmsObject", "version"] }, { kind: "directive", type: FileDropZoneDirective, selector: "[yuvFileDropZone]", inputs: ["yuvFileDropZone", "fileDropDisabled"], outputs: ["fileDrop", "fileDropOver"] }] }); }
2890
2956
  }
2891
2957
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ObjectPageComponent, decorators: [{
2892
2958
  type: Component,
@@ -2902,11 +2968,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
2902
2968
  TranslateModule,
2903
2969
  RibbonComponent,
2904
2970
  YvcTabsModule,
2971
+ RetentionBadgeComponent,
2905
2972
  ObjectPreviewComponent,
2906
2973
  FileDropZoneDirective
2907
2974
  ], host: {
2908
2975
  ['class.smallScreenLayout']: 'smallScreenLayout()'
2909
- }, template: "@let object = dmsObject();\n@if (object) {\n <div\n class=\"object\"\n yuvContainerSize\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropReplaceDisabled()\"\n (fileDrop)=\"onFileDrop($event)\"\n >\n <ymd-ribbon [objects]=\"[object]\" [excludeActions]=\"excludeActions\">\n <ng-template #primaryActions>\n <div class=\"nav\">\n <button class=\"back\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.page.object.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n </ng-template>\n <!-- <ng-template #secondaryActions></ng-template> -->\n </ymd-ribbon>\n\n @let ssl = smallScreenLayout();\n @if (ssl) {\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs.small'\" [cacheViews]=\"false\">\n <ng-template [yvcTab]=\"{ id: 'content_s', label: 'yuv.app.drive.object-metadata.tabs.content.title' | translate }\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'indexdata_s', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history_s', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n } @else {\n <yvc-split-view [layoutSettingsID]=\"layoutSettingIdBase + 'splitview'\" [gutterSize]=\"1\">\n <ng-template yvcSplitArea [size]=\"40\">\n <section class=\"meta\">\n <header>\n <yuv-object-flavor disableSelection=\"true\" [dmsObject]=\"object\"></yuv-object-flavor>\n\n @if (headerData) {\n <yvc-icon class=\"object-icon\" [svg]=\"headerData.icon\"></yvc-icon>\n <h1><ng-container *yuvRenderer=\"headerData.title\"></ng-container></h1>\n <div class=\"description\"><ng-container *yuvRenderer=\"headerData.description\"></ng-container></div>\n }\n </header>\n\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs'\">\n <ng-template [yvcTab]=\"{ id: 'indexdata', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\" [versionsLink]=\"versionsLink()\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n </section>\n </ng-template>\n <ng-template yvcSplitArea [size]=\"60\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n </yvc-split-view>\n }\n </div>\n} @else if (errorMessage) {\n <!-- object could not be loaded -->\n <div class=\"error state\">\n <yvc-icon [svg]=\"icons.error\"></yvc-icon>\n <p>{{ errorMessage }}</p>\n </div>\n} @else {\n <!-- object is loading -->\n <div class=\"loading state\">\n <div class=\"yuv-loader\"></div>\n </div>\n}\n", styles: [":host{--button-gap: calc(var(--app-pane-padding) / 4);display:flex;flex-flow:column;height:100%;overflow:hidden}:host .state{display:flex;flex-flow:column;height:100%;align-items:center;justify-content:center;border-block-start:1px solid var(--panel-divider-color)}:host .error yvc-icon{--icon-size: 48px;color:rgb(from var(--text-color-body) r g b/.1)}:host .error p{margin:var(--app-pane-padding);max-width:35ch;color:var(--text-color-caption)}:host .state,:host .object{animation:fade-in .3s ease-in-out}:host .object{height:100%;display:flex;flex-flow:column}:host .object ymd-ribbon{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);flex:0 0 auto}:host .object ymd-ribbon button{padding:var(--ribbon-button-padding);border-radius:var(--ribbon-button-border-radius)}:host .object ymd-ribbon button yvc-icon{--icon-size: var(--ribbon-icon-size)}:host .object ymd-ribbon .nav{display:flex;align-items:center;gap:var(--button-gap)}:host .object yvc-tabs{flex:1;background-color:var(--app-drive-header-background)}:host .object yvc-split-view{flex:1}:host .meta{background-color:var(--panel-background);display:flex;flex-flow:column;height:100%}:host .meta header{flex:0 0 auto;display:grid;grid-template-rows:auto calc(var(--app-pane-padding) / 2) auto auto var(--app-pane-padding);grid-template-columns:calc(var(--app-pane-padding) / 2) auto 1fr auto calc(var(--app-pane-padding) / 2);grid-template-areas:\"flavor flavor flavor flavor flavor\" \". . . . .\" \". icon title actions .\" \". . description description .\" \". . . . .\";gap:calc(var(--app-pane-padding) / 2)}:host .meta header yuv-object-flavor{grid-area:flavor;border-block-end:1px solid var(--panel-divider-color)}:host .meta header yvc-icon.object-icon{color:var(--text-color-caption);grid-area:icon}:host .meta header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400}:host .meta header .description{grid-area:description}:host .meta yvc-tabs{flex:1}@keyframes fade-in{0%{opacity:0}}\n"] }]
2976
+ }, template: "@let object = dmsObject();\n@if (object) {\n <div\n class=\"object\"\n yuvContainerSize\n [yuvFileDropZone]=\"{ label: 'yuv.app.drive.files.dropzone.content.replace.label' | translate }\"\n [fileDropDisabled]=\"fileDropReplaceDisabled()\"\n (fileDrop)=\"onFileDrop($event)\"\n >\n <ymd-ribbon [objects]=\"[object]\" [excludeActions]=\"excludeActions\">\n <ng-template #primaryActions>\n <div class=\"nav\">\n <button class=\"back\" (click)=\"openParent()\">\n <yvc-icon [svg]=\"icons.back\"></yvc-icon>\n </button>\n <button class=\"refresh\" title=\"{{ 'yuv.app.drive.page.object.refresh.tooltip' | translate }}\" (click)=\"refresh()\">\n <yvc-icon [svg]=\"icons.refresh\"></yvc-icon>\n </button>\n </div>\n </ng-template>\n <!-- <ng-template #secondaryActions></ng-template> -->\n </ymd-ribbon>\n\n @let ssl = smallScreenLayout();\n @if (ssl) {\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs.small'\" [cacheViews]=\"false\">\n <ng-template [yvcTab]=\"{ id: 'content_s', label: 'yuv.app.drive.object-metadata.tabs.content.title' | translate }\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'indexdata_s', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history_s', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n } @else {\n <yvc-split-view [layoutSettingsID]=\"layoutSettingIdBase + 'splitview'\" [gutterSize]=\"1\">\n <ng-template yvcSplitArea [size]=\"40\">\n <section class=\"meta\">\n <header>\n <yuv-object-flavor disableSelection=\"true\" [dmsObject]=\"object\"></yuv-object-flavor>\n\n @if (headerData) {\n <yvc-icon class=\"object-icon\" [svg]=\"headerData.icon\"></yvc-icon>\n <h1><ng-container *yuvRenderer=\"headerData.title\"></ng-container></h1>\n <div class=\"description\"><ng-container *yuvRenderer=\"headerData.description\"></ng-container></div>\n <div class=\"badges\">\n <yuv-retention-badge [dmsObject]=\"object\"></yuv-retention-badge>\n </div>\n }\n </header>\n\n <yvc-tabs [layoutSettingsID]=\"layoutSettingIdBase + 'tabs'\">\n <ng-template [yvcTab]=\"{ id: 'indexdata', label: 'yuv.app.drive.object-metadata.tabs.indexdata.title' | translate }\">\n <yuv-object-metadata [flavoredDmsObject]=\"flavoredDmsObject()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n <ng-template [yvcTab]=\"{ id: 'history', label: 'yuv.app.drive.object-metadata.tabs.history.title' | translate }\">\n <yuv-object-audit [dmsObject]=\"object\" [versionsLink]=\"versionsLink()\"></yuv-object-audit>\n </ng-template>\n </yvc-tabs>\n </section>\n </ng-template>\n <ng-template yvcSplitArea [size]=\"60\">\n @if (object && object?.content) {\n <yuv-object-preview [dmsObject]=\"object\"></yuv-object-preview>\n }\n </ng-template>\n </yvc-split-view>\n }\n </div>\n} @else if (errorMessage) {\n <!-- object could not be loaded -->\n <div class=\"error state\">\n <yvc-icon [svg]=\"icons.error\"></yvc-icon>\n <p>{{ errorMessage }}</p>\n </div>\n} @else {\n <!-- object is loading -->\n <div class=\"loading state\">\n <div class=\"yuv-loader\"></div>\n </div>\n}\n", styles: [":host{--button-gap: calc(var(--app-pane-padding) / 4);display:flex;flex-flow:column;height:100%;overflow:hidden}:host .state{display:flex;flex-flow:column;height:100%;align-items:center;justify-content:center;border-block-start:1px solid var(--panel-divider-color)}:host .error yvc-icon{--icon-size: 48px;color:rgb(from var(--text-color-body) r g b/.1)}:host .error p{margin:var(--app-pane-padding);max-width:35ch;color:var(--text-color-caption)}:host .state,:host .object{animation:fade-in .3s ease-in-out}:host .object{height:100%;display:flex;flex-flow:column}:host .object ymd-ribbon{background-color:var(--app-drive-header-background);border-block-end:1px solid var(--panel-divider-color);flex:0 0 auto}:host .object ymd-ribbon button{padding:var(--ribbon-button-padding);border-radius:var(--ribbon-button-border-radius)}:host .object ymd-ribbon button yvc-icon{--icon-size: var(--ribbon-icon-size)}:host .object ymd-ribbon .nav{display:flex;align-items:center;gap:var(--button-gap)}:host .object yvc-tabs{flex:1;background-color:var(--app-drive-header-background)}:host .object yvc-split-view{flex:1}:host .meta{background-color:var(--panel-background);display:flex;flex-flow:column;height:100%}:host .meta header{flex:0 0 auto;display:grid;grid-template-rows:auto calc(var(--app-pane-padding) / 2) auto auto var(--app-pane-padding);grid-template-columns:calc(var(--app-pane-padding) / 2) auto 1fr auto calc(var(--app-pane-padding) / 2);grid-template-areas:\"flavor flavor flavor flavor flavor\" \". . . . .\" \". icon title actions .\" \". . description description .\" \". . badges badges .\" \". . . . .\";gap:calc(var(--app-pane-padding) / 2)}:host .meta header yuv-object-flavor{grid-area:flavor;border-block-end:1px solid var(--panel-divider-color)}:host .meta header yvc-icon.object-icon{color:var(--text-color-caption);grid-area:icon}:host .meta header h1{grid-area:title;margin:0;padding:0;font-size:var(--font-title);font-weight:400}:host .meta header .description{grid-area:description}:host .meta header .badges{grid-area:badges;display:flex;flex-flow:row wrap;align-items:center;justify-content:start;gap:calc(var(--app-pane-padding) / 4)}:host .meta yvc-tabs{flex:1}@keyframes fade-in{0%{opacity:0}}\n"] }]
2910
2977
  }], ctorParameters: () => [] });
2911
2978
 
2912
2979
  const filesResolver = (route) => {