@yuuvis/app-drive 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/esm2022/lib/components/add-button/add-button-overlay/add-button-overlay.component.mjs +2 -2
  2. package/esm2022/lib/components/drive-search/drive-search-overlay/drive-search-overlay.component.mjs +343 -0
  3. package/esm2022/lib/components/drive-search/drive-search.component.mjs +83 -0
  4. package/esm2022/lib/components/index.mjs +2 -2
  5. package/esm2022/lib/components/search-filter/search-filter.component.mjs +14 -330
  6. package/esm2022/lib/drive.icons.mjs +5 -2
  7. package/esm2022/lib/pages/files/files.component.mjs +24 -24
  8. package/esm2022/lib/services/drive/drive.interface.mjs +1 -1
  9. package/esm2022/lib/services/drive/drive.service.mjs +9 -4
  10. package/fesm2022/yuuvis-app-drive.mjs +490 -438
  11. package/fesm2022/yuuvis-app-drive.mjs.map +1 -1
  12. package/lib/components/drive-search/drive-search-overlay/drive-search-overlay.component.d.ts +52 -0
  13. package/lib/components/drive-search/drive-search.component.d.ts +21 -0
  14. package/lib/components/index.d.ts +1 -0
  15. package/lib/components/search-filter/search-filter.component.d.ts +0 -2
  16. package/lib/container/drive/drive.component.d.ts +3 -0
  17. package/lib/drive.icons.d.ts +3 -0
  18. package/lib/pages/files/files.component.d.ts +10 -7
  19. package/lib/services/drive/drive.interface.d.ts +1 -0
  20. package/lib/services/drive/drive.service.d.ts +1 -1
  21. package/package.json +2 -2
  22. package/esm2022/lib/components/search-filter/date-range-picker/date-range-picker.component.mjs +0 -38
  23. package/lib/components/search-filter/date-range-picker/date-range-picker.component.d.ts +0 -13
@@ -1,14 +1,14 @@
1
- import * as i1$3 from '@angular/common';
1
+ import * as i1$2 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
- import * as i1$2 from '@angular/router';
8
+ import * as i1$3 from '@angular/router';
9
9
  import { Router, NavigationStart, ActivatedRoute, RouterModule, NavigationEnd } from '@angular/router';
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';
10
+ import * as i1 from '@yuuvis/client-core';
11
+ import { SystemType, ClipboardService, TranslateService, TranslateModule, BaseObjectTypeField, EventService, DmsService, SearchService, BackendService, YuvEventType, ContentStreamField, 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';
@@ -22,7 +22,7 @@ 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';
@@ -33,15 +33,17 @@ import { YvcTabsModule } from '@yuuvis/components/tabs';
33
33
  import { ListComponent, ListItemDirective } from '@yuuvis/client-framework/list';
34
34
  import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
35
35
  import { Directionality } from '@angular/cdk/bidi';
36
- import * as i2$1 from '@yuuvis/components/drag-scroll';
36
+ import * as i2 from '@yuuvis/components/drag-scroll';
37
37
  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$1 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
47
  import { ObjectMetadataComponent, ObjectAuditComponent } 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';
@@ -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
@@ -264,7 +269,7 @@ class ResolveNameConflictsComponent {
264
269
  this.#setupContent();
265
270
  }
266
271
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ResolveNameConflictsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
267
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ResolveNameConflictsComponent, isStandalone: true, selector: "ymd-resolve-name-conflicts", ngImport: i0, template: "<h2>{{ content.headline }}</h2>\n<p>{{ content.message }}</p>\n\n<ul>\n @for (ef of existingFileNames; track $index) {\n <li>{{ ef }}</li>\n }\n</ul>\n\n@if (validItems.length) {\n <p>{{ content.messageValid }}</p>\n <ul>\n @for (f of validItems; track $index) {\n <li>{{ f.name }}</li>\n }\n </ul>\n}\n\n<footer>\n @if (validItems.length) {\n <button class=\"primary\" (click)=\"proceed()\">{{ content.proceed }}</button>\n }\n <button class=\"secondary\" (click)=\"cancel()\">{{ 'yuv.app.drive.name.conflict.cancel' | translate }}</button>\n</footer>\n", styles: ["@charset \"UTF-8\";:host{display:block;padding:var(--app-pane-padding);position:relative}:host .yuv-loader-linear{position:absolute;inset:0}:host h2{margin:0 0 2em;font-size:var(--font-title);font-weight:400}:host ul{font-weight:700;list-style:none;padding:0 1em}:host ul li{padding:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ul li:before{content:\"\\2022\";margin-inline-end:.5rem}:host footer{margin-block-start:calc(var(--app-pane-padding) * 2);display:flex;flex-flow:row-reverse;gap:calc(var(--app-pane-padding) / 4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
272
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ResolveNameConflictsComponent, isStandalone: true, selector: "ymd-resolve-name-conflicts", ngImport: i0, template: "<h2>{{ content.headline }}</h2>\n<p>{{ content.message }}</p>\n\n<ul>\n @for (ef of existingFileNames; track $index) {\n <li>{{ ef }}</li>\n }\n</ul>\n\n@if (validItems.length) {\n <p>{{ content.messageValid }}</p>\n <ul>\n @for (f of validItems; track $index) {\n <li>{{ f.name }}</li>\n }\n </ul>\n}\n\n<footer>\n @if (validItems.length) {\n <button class=\"primary\" (click)=\"proceed()\">{{ content.proceed }}</button>\n }\n <button class=\"secondary\" (click)=\"cancel()\">{{ 'yuv.app.drive.name.conflict.cancel' | translate }}</button>\n</footer>\n", styles: ["@charset \"UTF-8\";:host{display:block;padding:var(--app-pane-padding);position:relative}:host .yuv-loader-linear{position:absolute;inset:0}:host h2{margin:0 0 2em;font-size:var(--font-title);font-weight:400}:host ul{font-weight:700;list-style:none;padding:0 1em}:host ul li{padding:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ul li:before{content:\"\\2022\";margin-inline-end:.5rem}:host footer{margin-block-start:calc(var(--app-pane-padding) * 2);display:flex;flex-flow:row-reverse;gap:calc(var(--app-pane-padding) / 4)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
268
273
  }
269
274
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ResolveNameConflictsComponent, decorators: [{
270
275
  type: Component,
@@ -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: i1.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,
@@ -836,7 +846,7 @@ class RenameComponent {
836
846
  });
837
847
  }
838
848
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RenameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
839
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RenameComponent, isStandalone: true, selector: "ymd-rename", host: { properties: { "class.busy": "busy()" } }, ngImport: i0, template: "<div class=\"yuv-loader-linear\"></div>\n<ymd-object-name\n [item]=\"item\"\n [isRename]=\"true\"\n [isFile]=\"!item.isFolder\"\n [headline]=\"'yuv.app.drive.action.rename.headline' | translate\"\n [submitButton]=\"'yuv.app.drive.action.rename.submit' | translate\"\n [cancelButton]=\"'yuv.app.drive.action.rename.cancel' | translate\"\n (nameChange)=\"rename($event)\"\n (onClose)=\"overlayRef.close()\"\n></ymd-object-name>\n", styles: [":host{display:block;position:relative}:host ymd-object-name{padding:var(--app-pane-padding);display:block}:host .yuv-loader-linear{position:absolute;inset-block-start:0;inset-inline-start:0;inset-inline-end:0}:host:not(.busy) .yuv-loader-linear{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectNameComponent, selector: "ymd-object-name", inputs: ["headline", "submitButton", "cancelButton", "isFile", "isRename", "item", "disabled"], outputs: ["nameChange", "onClose"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
849
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RenameComponent, isStandalone: true, selector: "ymd-rename", host: { properties: { "class.busy": "busy()" } }, ngImport: i0, template: "<div class=\"yuv-loader-linear\"></div>\n<ymd-object-name\n [item]=\"item\"\n [isRename]=\"true\"\n [isFile]=\"!item.isFolder\"\n [headline]=\"'yuv.app.drive.action.rename.headline' | translate\"\n [submitButton]=\"'yuv.app.drive.action.rename.submit' | translate\"\n [cancelButton]=\"'yuv.app.drive.action.rename.cancel' | translate\"\n (nameChange)=\"rename($event)\"\n (onClose)=\"overlayRef.close()\"\n></ymd-object-name>\n", styles: [":host{display:block;position:relative}:host ymd-object-name{padding:var(--app-pane-padding);display:block}:host .yuv-loader-linear{position:absolute;inset-block-start:0;inset-inline-start:0;inset-inline-end:0}:host:not(.busy) .yuv-loader-linear{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectNameComponent, selector: "ymd-object-name", inputs: ["headline", "submitButton", "cancelButton", "isFile", "isRename", "item", "disabled"], outputs: ["nameChange", "onClose"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
840
850
  }
841
851
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RenameComponent, decorators: [{
842
852
  type: Component,
@@ -1013,7 +1023,7 @@ class CreateFolderComponent {
1013
1023
  this.parentModalRef.close();
1014
1024
  }
1015
1025
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CreateFolderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1016
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: CreateFolderComponent, isStandalone: true, selector: "ymd-create-folder", host: { properties: { "class.busy": "busy()" } }, ngImport: i0, template: "<div class=\"yuv-loader-linear\"></div>\n\n<ymd-object-name [disabled]=\"busy()\"\n [headline]=\"'yuv.app.drive.folder.create.headline' | translate\"\n [submitButton]=\"'yuv.app.drive.folder.create.submit' | translate\"\n [cancelButton]=\"'yuv.app.drive.action.rename.cancel' | translate\"\n (onClose)=\"close()\"\n (nameChange)=\"createFolder($event)\"\n></ymd-object-name>\n\n@if (message) {\n <div class=\"message\">{{message}}</div>\n}", styles: [":host{display:block;position:relative}:host .yuv-loader-linear{position:absolute;inset-inline-start:0;inset-inline-end:0;inset-block-start:0;opacity:0}:host ymd-object-name{display:block;padding:var(--app-pane-padding)}:host.busy .yuv-loader-linear{opacity:1}:host .message{padding:var(--app-pane-padding);background-color:var(--panel-background-lightgrey);border-block-start:1px solid var(--panel-divider-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectNameComponent, selector: "ymd-object-name", inputs: ["headline", "submitButton", "cancelButton", "isFile", "isRename", "item", "disabled"], outputs: ["nameChange", "onClose"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
1026
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: CreateFolderComponent, isStandalone: true, selector: "ymd-create-folder", host: { properties: { "class.busy": "busy()" } }, ngImport: i0, template: "<div class=\"yuv-loader-linear\"></div>\n\n<ymd-object-name [disabled]=\"busy()\"\n [headline]=\"'yuv.app.drive.folder.create.headline' | translate\"\n [submitButton]=\"'yuv.app.drive.folder.create.submit' | translate\"\n [cancelButton]=\"'yuv.app.drive.action.rename.cancel' | translate\"\n (onClose)=\"close()\"\n (nameChange)=\"createFolder($event)\"\n></ymd-object-name>\n\n@if (message) {\n <div class=\"message\">{{message}}</div>\n}", styles: [":host{display:block;position:relative}:host .yuv-loader-linear{position:absolute;inset-inline-start:0;inset-inline-end:0;inset-block-start:0;opacity:0}:host ymd-object-name{display:block;padding:var(--app-pane-padding)}:host.busy .yuv-loader-linear{opacity:1}:host .message{padding:var(--app-pane-padding);background-color:var(--panel-background-lightgrey);border-block-start:1px solid var(--panel-divider-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectNameComponent, selector: "ymd-object-name", inputs: ["headline", "submitButton", "cancelButton", "isFile", "isRename", "item", "disabled"], outputs: ["nameChange", "onClose"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1017
1027
  }
1018
1028
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CreateFolderComponent, decorators: [{
1019
1029
  type: Component,
@@ -1112,7 +1122,7 @@ class AddButtonOverlayComponent {
1112
1122
  }
1113
1123
  }
1114
1124
  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"] }] }); }
1125
+ 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$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }] }); }
1116
1126
  }
1117
1127
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddButtonOverlayComponent, decorators: [{
1118
1128
  type: Component,
@@ -1138,7 +1148,7 @@ class AddButtonComponent {
1138
1148
  });
1139
1149
  }
1140
1150
  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" }] }); }
1151
+ 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: i1.TranslatePipe, name: "translate" }] }); }
1142
1152
  }
1143
1153
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddButtonComponent, decorators: [{
1144
1154
  type: Component,
@@ -1335,7 +1345,7 @@ class BreadcrumbComponent {
1335
1345
  this.#keyManager?.destroy();
1336
1346
  }
1337
1347
  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 }); }
1348
+ 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.DragScrollDirective, selector: "[yvcDragScroll]" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "directive", type: ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1339
1349
  }
1340
1350
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BreadcrumbComponent, decorators: [{
1341
1351
  type: Component,
@@ -1468,7 +1478,7 @@ class PasteFromClipboardComponent {
1468
1478
  this.overlayRef.close();
1469
1479
  }
1470
1480
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PasteFromClipboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1471
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: PasteFromClipboardComponent, isStandalone: true, selector: "ymd-paste-from-clipboard", ngImport: i0, template: "<main>\n <p>{{ 'yuv.app.drive.paste-from-clipboard.message' | translate }}</p>\n <ol>\n @for (f of data.files; track $index) {\n <li>{{ f.name }}</li>\n }\n </ol>\n</main>\n\n<footer>\n <button class=\"primary\" (click)=\"uploadFromClipboard()\">{{ 'yuv.app.drive.paste-from-clipboard.button.paste' | translate }}</button>\n <button class=\"secondary\" (click)=\"cancel()\">{{ 'yuv.app.drive.paste-from-clipboard.button.cancel' | translate }}</button>\n</footer>\n", styles: [":host{display:grid;grid-template-rows:1fr auto;grid-template-areas:\"main\" \"footer\";padding:var(--app-pane-padding)}:host main{grid-area:main;overflow-y:auto}:host footer{grid-area:footer;display:flex;flex-flow:row-reverse;justify-content:space-between;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
1481
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: PasteFromClipboardComponent, isStandalone: true, selector: "ymd-paste-from-clipboard", ngImport: i0, template: "<main>\n <p>{{ 'yuv.app.drive.paste-from-clipboard.message' | translate }}</p>\n <ol>\n @for (f of data.files; track $index) {\n <li>{{ f.name }}</li>\n }\n </ol>\n</main>\n\n<footer>\n <button class=\"primary\" (click)=\"uploadFromClipboard()\">{{ 'yuv.app.drive.paste-from-clipboard.button.paste' | translate }}</button>\n <button class=\"secondary\" (click)=\"cancel()\">{{ 'yuv.app.drive.paste-from-clipboard.button.cancel' | translate }}</button>\n</footer>\n", styles: [":host{display:grid;grid-template-rows:1fr auto;grid-template-areas:\"main\" \"footer\";padding:var(--app-pane-padding)}:host main{grid-area:main;overflow-y:auto}:host footer{grid-area:footer;display:flex;flex-flow:row-reverse;justify-content:space-between;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1472
1482
  }
1473
1483
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PasteFromClipboardComponent, decorators: [{
1474
1484
  type: Component,
@@ -1505,7 +1515,7 @@ class VersionTileComponent {
1505
1515
  {{ rendererInputs().modified }}
1506
1516
  </div>
1507
1517
  </div>
1508
- `, isInline: true, styles: [":host{--_tile-background: var(--tile-background, transparent);--_tile-icon-fill: var(--tile-icon-fill, currentColor);--_tile-padding: var(--tile-padding, var(--app-pane-padding));--_tile-action-icon-size: var(--tile-action-icon-size);--_tile-icon-size: var(--tile-icon-size);--_transition-duration: var(--transition-duration, .1s);display:flex;align-items:center;background-color:var(--_tile-background);padding:var(--_tile-padding);transition:background-color var(--_transition-duration)}:host .slots{display:grid;grid-template-columns:1fr 2fr;grid-template-rows:repeat(2,1fr);grid-template-areas:\"version version\" \"date modified\";flex:1;gap:calc(var(--_tile-padding) / 2) calc(var(--_tile-padding) * 2)}:host [data-slot]{align-items:center;-webkit-user-select:none;user-select:none;display:grid}:host [data-slot=icon]{--icon-renderer-icon-size: var(--_tile-icon-size);color:var(--_tile-icon-fill);width:0;grid-area:icon;display:grid;align-items:center;justify-content:center}:host [data-slot=version]{font-weight:700;grid-area:version}:host [data-slot=date]{grid-area:date}:host [data-slot=modified]{grid-area:modified;white-space:nowrap;justify-self:end}\n"], dependencies: [{ kind: "pipe", type: DatePipe, name: "date" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] }); }
1518
+ `, isInline: true, styles: [":host{--_tile-background: var(--tile-background, transparent);--_tile-icon-fill: var(--tile-icon-fill, currentColor);--_tile-padding: var(--tile-padding, var(--app-pane-padding));--_tile-action-icon-size: var(--tile-action-icon-size);--_tile-icon-size: var(--tile-icon-size);--_transition-duration: var(--transition-duration, .1s);display:flex;align-items:center;background-color:var(--_tile-background);padding:var(--_tile-padding);transition:background-color var(--_transition-duration)}:host .slots{display:grid;grid-template-columns:1fr 2fr;grid-template-rows:repeat(2,1fr);grid-template-areas:\"version version\" \"date modified\";flex:1;gap:calc(var(--_tile-padding) / 2) calc(var(--_tile-padding) * 2)}:host [data-slot]{align-items:center;-webkit-user-select:none;user-select:none;display:grid}:host [data-slot=icon]{--icon-renderer-icon-size: var(--_tile-icon-size);color:var(--_tile-icon-fill);width:0;grid-area:icon;display:grid;align-items:center;justify-content:center}:host [data-slot=version]{font-weight:700;grid-area:version}:host [data-slot=date]{grid-area:date}:host [data-slot=modified]{grid-area:modified;white-space:nowrap;justify-self:end}\n"], dependencies: [{ kind: "pipe", type: DatePipe, name: "date" }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }] }); }
1509
1519
  }
1510
1520
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: VersionTileComponent, decorators: [{
1511
1521
  type: Component,
@@ -1615,6 +1625,392 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1615
1625
  args: ['keydown', ['$event']]
1616
1626
  }] } });
1617
1627
 
1628
+ class DriveSearchOverlayComponent {
1629
+ #fb;
1630
+ #oRef;
1631
+ #shell;
1632
+ #system;
1633
+ #drive;
1634
+ #search;
1635
+ #query;
1636
+ #queryEffect;
1637
+ #initialFormData;
1638
+ constructor() {
1639
+ this.translate = inject(TranslateService$1);
1640
+ this.#fb = inject(FormBuilder);
1641
+ this.#oRef = inject(YvcOverlayRef);
1642
+ this.#shell = inject(ShellService);
1643
+ this.#system = inject(SystemService);
1644
+ this.#drive = inject(DriveService);
1645
+ this.#search = inject(SearchService);
1646
+ this.objectForms = viewChildren(ObjectFormComponent);
1647
+ this.ANY_OPTION = 'any';
1648
+ this.#query = this.#drive.state$.query;
1649
+ this.#queryEffect = effect(() => {
1650
+ const q = this.#query();
1651
+ if (q)
1652
+ this.filterForm.patchValue(this.#queryToForm(q));
1653
+ });
1654
+ this.icons = {
1655
+ arrow: ICONS.arrowDown,
1656
+ remove: ICONS.clear,
1657
+ unchecked: APP_DRIVE_ICONS.unchecked,
1658
+ checked: APP_DRIVE_ICONS.checked
1659
+ };
1660
+ this.#initialFormData = {};
1661
+ this.selectedFlavorsRec = {};
1662
+ this.formStates = {};
1663
+ this.flavorFormOptions = signal({});
1664
+ this.flavorForms = computed(() => {
1665
+ const ffo = this.flavorFormOptions() || {};
1666
+ return Object.keys(ffo).map((k) => ({
1667
+ id: k,
1668
+ icon: this.selectedFlavorsRec[k]?.icon,
1669
+ label: this.translate.instant(k),
1670
+ formOptions: ffo[k]
1671
+ }));
1672
+ });
1673
+ this.scopeOptions = signal([]);
1674
+ this.filterForm = this.#fb.nonNullable.group({
1675
+ term: [this.#oRef.data.term || ''],
1676
+ scope: [this.ANY_OPTION],
1677
+ modified: [],
1678
+ created: [],
1679
+ contentlength: []
1680
+ });
1681
+ this.searchTokens = [];
1682
+ this.flavors = this.#shell.getObjectFlavors().map((f) => ({ ...f, label: this.translate.instant(f.id) }));
1683
+ this.translate.onLangChange.pipe(takeUntilDestroyed()).subscribe((_) => this.#setupOptions());
1684
+ this.#setupOptions();
1685
+ this.filterForm.valueChanges.pipe(takeUntilDestroyed()).subscribe((v) => this.#onFormValueChange(v));
1686
+ }
1687
+ typeSelected(idx) {
1688
+ this.#toggleType(this.flavors[idx[0]]);
1689
+ }
1690
+ #toggleType(t) {
1691
+ if (this.selectedFlavorsRec[t.id]) {
1692
+ delete this.selectedFlavorsRec[t.id];
1693
+ const ffo = this.flavorFormOptions() || {};
1694
+ delete ffo[t.id];
1695
+ this.flavorFormOptions.set({ ...ffo });
1696
+ delete this.formStates[t.id];
1697
+ this.#getCombinedFormState();
1698
+ }
1699
+ else {
1700
+ this.selectedFlavorsRec[t.id] = t;
1701
+ this.#system.getObjectTypeForm(t.sot, Situation.SEARCH).subscribe((formModel) => {
1702
+ this.flavorFormOptions.set({
1703
+ ...this.flavorFormOptions(),
1704
+ [t.id]: {
1705
+ formModel,
1706
+ data: {}
1707
+ }
1708
+ });
1709
+ });
1710
+ }
1711
+ }
1712
+ // initial setup of types/flavors
1713
+ #setTypes(sots) {
1714
+ const sotQA = {};
1715
+ this.flavors
1716
+ .filter((f) => sots.includes(f.sot))
1717
+ .forEach((f) => {
1718
+ this.selectedFlavorsRec[f.id] = f;
1719
+ sotQA[f.sot] = f.id;
1720
+ });
1721
+ this.#system
1722
+ .getObjectTypeForms(sots, Situation.SEARCH)
1723
+ .pipe(finalize$1(() => (this.#initialFormData = {})))
1724
+ .subscribe((forms) => {
1725
+ const ffo = {};
1726
+ Object.keys(forms).forEach((sot) => {
1727
+ ffo[sotQA[sot]] = {
1728
+ formModel: forms[sot],
1729
+ data: this.#initialFormData
1730
+ };
1731
+ });
1732
+ this.flavorFormOptions.set(ffo);
1733
+ });
1734
+ }
1735
+ onFormStatusChanged(formId, evt) {
1736
+ this.formStates[formId] = evt;
1737
+ this.#getCombinedFormState();
1738
+ }
1739
+ #onFormValueChange(v) {
1740
+ this.searchTokens = [];
1741
+ if (this.filterForm.value.term) {
1742
+ this.searchTokens.push({
1743
+ fromControlName: 'term',
1744
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.term', { value: this.filterForm.value.term })
1745
+ });
1746
+ }
1747
+ const created = this.filterForm.value.created;
1748
+ if (created) {
1749
+ this.searchTokens.push({
1750
+ fromControlName: 'created',
1751
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.created', { value: created.label })
1752
+ });
1753
+ }
1754
+ const modified = this.filterForm.value.modified;
1755
+ if (modified) {
1756
+ this.searchTokens.push({
1757
+ fromControlName: 'modified',
1758
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.modified', { value: modified.label })
1759
+ });
1760
+ }
1761
+ const contentlength = this.filterForm.value.contentlength;
1762
+ if (contentlength) {
1763
+ this.searchTokens.push({
1764
+ fromControlName: 'contentlength',
1765
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.contentlength', { value: contentlength.label })
1766
+ });
1767
+ }
1768
+ if (this.filterForm.value.scope !== this.ANY_OPTION && this.filterForm.value.term) {
1769
+ const o = this.scopeOptions().find((o) => o.value === this.filterForm.value.scope);
1770
+ if (o)
1771
+ this.searchTokens.push({
1772
+ fromControlName: 'scope',
1773
+ label: this.translate.instant('yuv.app.drive.search.meta.search-token.where', { value: o.label })
1774
+ });
1775
+ }
1776
+ }
1777
+ removeSearchToken(t) {
1778
+ this.filterForm.patchValue({
1779
+ [t.fromControlName]: t.fromControlName === 'term' ? '' : this.ANY_OPTION
1780
+ });
1781
+ }
1782
+ #getCombinedFormState() {
1783
+ const combinedFormState = {
1784
+ dirty: false,
1785
+ indexdataChanged: false,
1786
+ invalid: false,
1787
+ data: {}
1788
+ };
1789
+ Object.values(this.formStates).forEach((s) => {
1790
+ if (s.dirty) {
1791
+ combinedFormState.dirty = s.dirty;
1792
+ }
1793
+ if (s.indexdataChanged) {
1794
+ combinedFormState.indexdataChanged = s.indexdataChanged;
1795
+ }
1796
+ if (s.invalid) {
1797
+ combinedFormState.invalid = s.invalid;
1798
+ }
1799
+ combinedFormState.data = { ...combinedFormState.data, ...s.data };
1800
+ });
1801
+ this.combinedFormState = combinedFormState;
1802
+ return this.combinedFormState;
1803
+ }
1804
+ cancel() {
1805
+ this.#oRef?.close();
1806
+ }
1807
+ submit() {
1808
+ this.#oRef?.close(this.#formToQuery());
1809
+ }
1810
+ //Converts the form values to a search query
1811
+ #formToQuery() {
1812
+ const filters = this.#search.formDataToSearchFilter(this.#getCombinedFormState().data);
1813
+ // types
1814
+ const sots = Object.values(this.selectedFlavorsRec).map((f) => f.sot);
1815
+ if (sots.length) {
1816
+ filters.push({
1817
+ f: BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS,
1818
+ o: Operator.IN,
1819
+ v1: sots
1820
+ });
1821
+ }
1822
+ // created
1823
+ if (this.filterForm.value.created) {
1824
+ const df = this.#search.rangeValueToSearchFilter(this.filterForm.value.created.rangeValue, BaseObjectTypeField.CREATION_DATE);
1825
+ df && filters.push(df);
1826
+ }
1827
+ // modified
1828
+ if (this.filterForm.value.modified) {
1829
+ const df = this.#search.rangeValueToSearchFilter(this.filterForm.value.modified.rangeValue, BaseObjectTypeField.MODIFICATION_DATE);
1830
+ df && filters.push(df);
1831
+ }
1832
+ // content length
1833
+ if (this.filterForm.value.contentlength) {
1834
+ const df = this.#search.rangeValueToSearchFilter(this.filterForm.value.contentlength.rangeValue, ContentStreamField.LENGTH);
1835
+ df && filters.push(df);
1836
+ }
1837
+ const searchQuery = {
1838
+ term: this.filterForm.value.term,
1839
+ filters
1840
+ };
1841
+ // search scope
1842
+ if (this.filterForm.value.scope !== this.ANY_OPTION)
1843
+ searchQuery.scope = this.filterForm.value.scope;
1844
+ return searchQuery;
1845
+ }
1846
+ /**
1847
+ * Converts the form values to a search query
1848
+ * @param q The search query
1849
+ */
1850
+ #queryToForm(q) {
1851
+ const patch = {};
1852
+ if (q?.term)
1853
+ patch['term'] = q.term;
1854
+ if (q?.scope)
1855
+ patch['scope'] = q.scope;
1856
+ q?.filters?.forEach((f) => {
1857
+ switch (f.f) {
1858
+ case BaseObjectTypeField.SECONDARY_OBJECT_TYPE_IDS: {
1859
+ const sots = f.v1;
1860
+ // filter by available flavors
1861
+ const flavorSots = this.flavors.map((f) => f.sot);
1862
+ this.#setTypes(sots.filter((sot) => flavorSots.includes(sot)));
1863
+ break;
1864
+ }
1865
+ case BaseObjectTypeField.CREATION_DATE: {
1866
+ const rsv = {
1867
+ rangeValue: {
1868
+ operator: f.o,
1869
+ firstValue: f.v1,
1870
+ secondValue: f.v2
1871
+ }
1872
+ };
1873
+ patch['created'] = rsv;
1874
+ break;
1875
+ }
1876
+ case BaseObjectTypeField.MODIFICATION_DATE: {
1877
+ const rsv = {
1878
+ rangeValue: {
1879
+ operator: f.o,
1880
+ firstValue: f.v1,
1881
+ secondValue: f.v2
1882
+ }
1883
+ };
1884
+ patch['modified'] = rsv;
1885
+ break;
1886
+ }
1887
+ case ContentStreamField.LENGTH: {
1888
+ const rsv = {
1889
+ rangeValue: {
1890
+ operator: f.o,
1891
+ firstValue: f.v1,
1892
+ secondValue: f.v2
1893
+ }
1894
+ };
1895
+ patch['contentlength'] = rsv;
1896
+ break;
1897
+ }
1898
+ default: {
1899
+ // check for values to inject into flavor forms
1900
+ this.#initialFormData[f.f] = f.v1;
1901
+ }
1902
+ }
1903
+ });
1904
+ return patch;
1905
+ }
1906
+ #setupOptions() {
1907
+ this.#setupScopeOptions();
1908
+ }
1909
+ #setupScopeOptions() {
1910
+ this.scopeOptions.set([
1911
+ {
1912
+ label: this.translate.instant('yuv.app.drive.search.filter.option.where.any'),
1913
+ value: this.ANY_OPTION
1914
+ },
1915
+ {
1916
+ label: this.translate.instant('yuv.app.drive.search.filter.option.where.content'),
1917
+ value: 'content'
1918
+ },
1919
+ {
1920
+ label: this.translate.instant('yuv.app.drive.search.filter.option.where.metadata'),
1921
+ value: 'metadata'
1922
+ }
1923
+ ]);
1924
+ }
1925
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1926
+ 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$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: YvcDropdownModule }, { kind: "component", type: i2$1.Dropdown, selector: "yvc-dropdown", inputs: ["options", "filter", "disabled", "multiple", "disableClearButton"], outputs: ["onDropdownOptionsClose"] }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i1.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$1.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"] }] }); }
1927
+ }
1928
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchOverlayComponent, decorators: [{
1929
+ type: Component,
1930
+ args: [{ selector: 'ymd-drive-search-overlay', standalone: true, imports: [
1931
+ CommonModule,
1932
+ YvcDropdownModule,
1933
+ TranslateModule$1,
1934
+ ObjectFormComponent,
1935
+ YvcSplitViewModule,
1936
+ YvcIconModule,
1937
+ YvcCheckboxModule,
1938
+ ReactiveFormsModule,
1939
+ ListComponent,
1940
+ ListItemDirective,
1941
+ RangeSelectDateComponent,
1942
+ RangeSelectFilesizeComponent
1943
+ ], 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"] }]
1944
+ }], ctorParameters: () => [] });
1945
+
1946
+ class DriveSearchComponent {
1947
+ constructor() {
1948
+ this.translate = inject(TranslateService$1);
1949
+ this.#overlay = inject(YvcOverlayService);
1950
+ this.#router = inject(Router);
1951
+ this.#route = inject(ActivatedRoute);
1952
+ this.#drive = inject(DriveService);
1953
+ this.icons = {
1954
+ extendedSearch: APP_DRIVE_ICONS.extendedSearch,
1955
+ clear: ICONS.clear
1956
+ };
1957
+ this.query = this.#drive.state$.query;
1958
+ this.extendedQuery = this.#drive.state$.extendedQuery;
1959
+ this.currentFolder = this.#drive.state$.currentFolder;
1960
+ this.term = '';
1961
+ }
1962
+ #overlay;
1963
+ #router;
1964
+ #route;
1965
+ #drive;
1966
+ #oRef;
1967
+ openModal(event) {
1968
+ event.stopPropagation();
1969
+ this.#oRef = this.#overlay.open(DriveSearchOverlayComponent, {
1970
+ term: this.term
1971
+ }, {
1972
+ width: '90vw',
1973
+ height: '90vh'
1974
+ });
1975
+ this.#oRef.afterClosed$.subscribe((res) => {
1976
+ if (res.data) {
1977
+ const q = res.data;
1978
+ this.onQuerySubmit(res.data, !!q.filters?.length || !!q.scope);
1979
+ }
1980
+ });
1981
+ }
1982
+ clear() {
1983
+ console.log(this.currentFolder());
1984
+ this.#router.navigate(['..', this.currentFolder() || DRIVE_ROOT_FOLDER_ID], {
1985
+ relativeTo: this.#route
1986
+ });
1987
+ }
1988
+ onQueryChange(q) {
1989
+ this.term = q.term || '';
1990
+ }
1991
+ onQuerySubmit(q, ext = false) {
1992
+ // in order to keep the query in the url as short as
1993
+ // possible we'll get rid of the fields because they could be
1994
+ // re-applied later on
1995
+ q.fields = undefined;
1996
+ this.#router.navigate(['..', 'query'], {
1997
+ queryParams: {
1998
+ q: encodeURIComponent(JSON.stringify(q)),
1999
+ ext
2000
+ },
2001
+ relativeTo: this.#route
2002
+ });
2003
+ }
2004
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2005
+ 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$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }] }); }
2006
+ }
2007
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveSearchComponent, decorators: [{
2008
+ type: Component,
2009
+ args: [{ selector: 'ymd-drive-search', standalone: true, imports: [CommonModule, TranslateModule$1, FocusWithinDirective, SimpleSearchComponent, DriveSearchOverlayComponent, ReactiveFormsModule, YvcIconModule], host: {
2010
+ '[class.active]': 'extendedQuery()'
2011
+ }, 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"] }]
2012
+ }] });
2013
+
1618
2014
  const COMPONENTS = [VersionsListComponent, ObjectSummaryDataComponent, ObjectPreviewComponent];
1619
2015
  const MODULES = [YvcIconModule, YvcTabsModule, YvcSplitViewModule, TranslateModule];
1620
2016
  class ManageVersionsComponent {
@@ -1693,7 +2089,7 @@ class ManageVersionsComponent {
1693
2089
  this.#drive.clearVersions();
1694
2090
  }
1695
2091
  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 }); }
2092
+ 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: i1.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
2093
  }
1698
2094
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ManageVersionsComponent, decorators: [{
1699
2095
  type: Component,
@@ -1801,7 +2197,7 @@ class DriveFrameComponent {
1801
2197
  this.#actions.forEach((a) => this.#actionsService.concealActions([a.id]));
1802
2198
  }
1803
2199
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1804
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DriveFrameComponent, isStandalone: true, selector: "ymd-drive", ngImport: i0, template: "<yuv-upload-progress (resultItemClick)=\"onUploadProgressResultItemClick($event)\"></yuv-upload-progress>\n\n<header>\n <yuv-app-logo [label]=\"appName\" routerLink=\"files\"></yuv-app-logo>\n\n <nav [attr.aria-label]=\"'yuv.app.drive.navigation.aria.label' | translate\">\n <yvc-overflow-menu [menuItems]=\"headerNavItems\"></yvc-overflow-menu>\n </nav>\n</header>\n\n<section class=\"drive-main__content\" [attr.aria-label]=\"'yuv.app.drive.content.aria.label' | translate\">\n <router-outlet></router-outlet>\n</section>\n\n<router-outlet name=\"modal\"></router-outlet>\n", styles: [":host{--app-drive-header-background: var(--panel-background);display:flex;flex-flow:column;height:100%}:host header{flex:0 0 auto;display:grid;grid-template-rows:auto;grid-template-columns:auto 1fr auto auto;grid-template-areas:\"logo . . nav\";gap:var(--app-pane-padding);align-items:center;height:var(--client-shell-bar-width);background-color:var(--app-drive-header-background)}:host header yuv-app-logo{--band-icon-size: 50px;--icon-color: var(--app-drive-header-background)}:host header ymd-drive-search{max-width:400px}:host header nav{grid-area:nav}:host header nav yvc-overflow-menu{--menu-item-padding: calc(var(--app-pane-padding) / 4);--menu-item-icon-size: 18px;--menu-item-gap: calc(var(--app-pane-padding) / 4)}:host .drive-main__content{flex:1;overflow-y:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$2.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: YvcOverflowMenuComponent, selector: "yvc-overflow-menu", inputs: ["overflowIcon", "groupLabels", "menuItems", "hideLabels"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: YvcOverlayModule }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: AppLogoComponent, selector: "yuv-app-logo", inputs: ["icon", "label"] }, { kind: "component", type: UploadProgressComponent, selector: "yuv-upload-progress", outputs: ["resultItemClick"] }] }); }
2200
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DriveFrameComponent, isStandalone: true, selector: "ymd-drive", ngImport: i0, template: "<yuv-upload-progress (resultItemClick)=\"onUploadProgressResultItemClick($event)\"></yuv-upload-progress>\n\n<header>\n <yuv-app-logo [label]=\"appName\" routerLink=\"files\"></yuv-app-logo>\n\n <nav [attr.aria-label]=\"'yuv.app.drive.navigation.aria.label' | translate\">\n <yvc-overflow-menu [menuItems]=\"headerNavItems\"></yvc-overflow-menu>\n </nav>\n</header>\n\n<section class=\"drive-main__content\" [attr.aria-label]=\"'yuv.app.drive.content.aria.label' | translate\">\n <router-outlet></router-outlet>\n</section>\n\n<router-outlet name=\"modal\"></router-outlet>\n", styles: [":host{--app-drive-header-background: var(--panel-background);display:flex;flex-flow:column;height:100%}:host header{flex:0 0 auto;display:grid;grid-template-rows:auto;grid-template-columns:auto 1fr auto auto;grid-template-areas:\"logo . . nav\";gap:var(--app-pane-padding);align-items:center;height:var(--client-shell-bar-width);background-color:var(--app-drive-header-background)}:host header yuv-app-logo{--band-icon-size: 50px;--icon-color: var(--app-drive-header-background)}:host header ymd-drive-search{max-width:400px}:host header nav{grid-area:nav}:host header nav yvc-overflow-menu{--menu-item-padding: calc(var(--app-pane-padding) / 4);--menu-item-icon-size: 18px;--menu-item-gap: calc(var(--app-pane-padding) / 4)}:host .drive-main__content{flex:1;overflow-y:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$3.RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: i1$3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: YvcOverflowMenuComponent, selector: "yvc-overflow-menu", inputs: ["overflowIcon", "groupLabels", "menuItems", "hideLabels"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: YvcOverlayModule }, { kind: "ngmodule", type: YvcIconModule }, { kind: "component", type: AppLogoComponent, selector: "yuv-app-logo", inputs: ["icon", "label"] }, { kind: "component", type: UploadProgressComponent, selector: "yuv-upload-progress", outputs: ["resultItemClick"] }] }); }
1805
2201
  }
1806
2202
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DriveFrameComponent, decorators: [{
1807
2203
  type: Component,
@@ -1899,7 +2295,7 @@ class RibbonComponent {
1899
2295
  ];
1900
2296
  }
1901
2297
  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 }); }
2298
+ 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$2.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
2299
  }
1904
2300
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RibbonComponent, decorators: [{
1905
2301
  type: Component,
@@ -1908,90 +2304,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
1908
2304
  }, 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
2305
  }], ctorParameters: () => [] });
1910
2306
 
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
2307
  class SearchFilterComponent {
1978
2308
  #shell;
1979
2309
  #fb;
1980
- #overlay;
1981
- #CREATED_CUSTOM;
2310
+ #search;
1982
2311
  #flavors;
1983
- #customDateRange;
1984
2312
  constructor() {
1985
2313
  this.#shell = inject(ShellService);
1986
2314
  this.#fb = inject(FormBuilder);
1987
- this.#overlay = inject(YvcOverlayService);
1988
- this.#CREATED_CUSTOM = 'custom';
2315
+ this.#search = inject(SearchService);
1989
2316
  this.translate = inject(TranslateService$1);
1990
2317
  this.ANY_OPTION = 'any';
1991
2318
  this.#flavors = this.#shell.getObjectFlavors();
1992
2319
  this.typeOptions = signal([]);
1993
- this.dateOptions = signal([]);
1994
- this.sizeOptions = signal([]);
1995
2320
  this.query = input(null);
1996
2321
  this.queryChange = output();
1997
2322
  this.filtersActive = signal(false);
@@ -2003,57 +2328,6 @@ class SearchFilterComponent {
2003
2328
  this.translate.onLangChange.pipe(takeUntilDestroyed()).subscribe((_) => this.#setupOptions());
2004
2329
  this.#setupOptions();
2005
2330
  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
2331
  }
2058
2332
  reset() {
2059
2333
  const q = this.query();
@@ -2063,13 +2337,6 @@ class SearchFilterComponent {
2063
2337
  }
2064
2338
  }
2065
2339
  #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
2340
  const updatedQuery = this.#applyFilters(v);
2074
2341
  this.queryChange.emit(updatedQuery);
2075
2342
  this.filtersActive.set(!!updatedQuery.filters && updatedQuery.filters.length > 0);
@@ -2085,19 +2352,17 @@ class SearchFilterComponent {
2085
2352
  if (typeFilter)
2086
2353
  updatedQuery.filters.push(typeFilter);
2087
2354
  // file size filter
2088
- const sizeFilter = this.#toSizeFilter(v.size);
2355
+ const sizeFilter = v.size !== this.ANY_OPTION ? this.#toSizeFilter(v.size) : undefined;
2089
2356
  if (sizeFilter)
2090
2357
  updatedQuery.filters.push(sizeFilter);
2091
2358
  // creation date filter
2092
- const dateFilter = this.#toDateFilter(v.created);
2359
+ const dateFilter = v.created !== this.ANY_OPTION ? this.#toDateFilter(v.created) : undefined;
2093
2360
  if (dateFilter)
2094
2361
  updatedQuery.filters.push(dateFilter);
2095
2362
  return updatedQuery;
2096
2363
  }
2097
2364
  #setupOptions() {
2098
2365
  this.#setupTypeOptions();
2099
- this.#setupDateOptions();
2100
- this.#setupSizeOptions();
2101
2366
  }
2102
2367
  #setupTypeOptions() {
2103
2368
  this.typeOptions.set([
@@ -2111,264 +2376,11 @@ class SearchFilterComponent {
2111
2376
  }))
2112
2377
  ]);
2113
2378
  }
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
2379
  #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;
2380
+ return value ? this.#search.rangeValueToSearchFilter(value.rangeValue, BaseObjectTypeField.CREATION_DATE) : undefined;
2336
2381
  }
2337
2382
  #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;
2383
+ return value ? this.#search.rangeValueToSearchFilter(value.rangeValue, ContentStreamField.LENGTH) : undefined;
2372
2384
  }
2373
2385
  #toTypeFilter(value) {
2374
2386
  return value === this.ANY_OPTION
@@ -2380,13 +2392,53 @@ class SearchFilterComponent {
2380
2392
  };
2381
2393
  }
2382
2394
  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]" }] }); }
2395
+ 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$1.Dropdown, selector: "yvc-dropdown", inputs: ["options", "filter", "disabled", "multiple", "disableClearButton"], outputs: ["onDropdownOptionsClose"] }, { kind: "ngmodule", type: TranslateModule$1 }, { kind: "pipe", type: i1.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.DragScrollDirective, selector: "[yvcDragScroll]" }] }); }
2384
2396
  }
2385
2397
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchFilterComponent, decorators: [{
2386
2398
  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"] }]
2399
+ args: [{ selector: 'ymd-search-filter', standalone: true, imports: [CommonModule, YvcDropdownModule, TranslateModule$1,
2400
+ RangeSelectFilesizeComponent,
2401
+ RangeSelectDateComponent,
2402
+ 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
2403
  }], ctorParameters: () => [] });
2389
2404
 
2405
+ class StoredQueryService {
2406
+ constructor() {
2407
+ this.userService = inject(UserService);
2408
+ this.translate = inject(TranslateService);
2409
+ }
2410
+ getStoredQuery(id) {
2411
+ const q = STORED_QUERIES[id];
2412
+ if (!q)
2413
+ return undefined;
2414
+ try {
2415
+ // if query has no label try to resolve from language resources
2416
+ return {
2417
+ label: q.label || this.translate.instant(id),
2418
+ query: JSON.parse(this._replaceVars(q.query))
2419
+ };
2420
+ }
2421
+ catch (e) {
2422
+ return undefined;
2423
+ }
2424
+ }
2425
+ _replaceVars(str) {
2426
+ const vars = [{ placeholder: '##me##', replace: this.userService.getCurrentUser().id }];
2427
+ vars.forEach((v) => {
2428
+ str = str.replaceAll(v.placeholder, v.replace);
2429
+ });
2430
+ return str;
2431
+ }
2432
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2433
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, providedIn: 'root' }); }
2434
+ }
2435
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StoredQueryService, decorators: [{
2436
+ type: Injectable,
2437
+ args: [{
2438
+ providedIn: 'root'
2439
+ }]
2440
+ }] });
2441
+
2390
2442
  const components = [
2391
2443
  TileListComponent,
2392
2444
  BreadcrumbComponent,
@@ -2398,7 +2450,8 @@ const components = [
2398
2450
  SimpleSearchComponent,
2399
2451
  MultiObjectSummaryComponent,
2400
2452
  SortComponent,
2401
- SearchFilterComponent
2453
+ SearchFilterComponent,
2454
+ DriveSearchComponent
2402
2455
  ];
2403
2456
  const module = [YvcIconModule, TranslateModule, RouterModule, YvcSplitViewModule];
2404
2457
  class FilesPageComponent {
@@ -2437,6 +2490,7 @@ class FilesPageComponent {
2437
2490
  this.disableCreate = false;
2438
2491
  this.actions = this.drive.state$.actions;
2439
2492
  this.selection = this.drive.state$.selection;
2493
+ this.extendedQuery = this.drive.state$.extendedQuery;
2440
2494
  this.busy = this.drive.state$.busy;
2441
2495
  this.flavorChips = this.shellService.getObjectFlavors();
2442
2496
  this.selectionActions = computed(() => ({ selection: this.selection(), actions: this.actions() }));
@@ -2448,12 +2502,12 @@ class FilesPageComponent {
2448
2502
  folder: { bucket: APP_ID, type: APP_SCHEMA.types['folder'] },
2449
2503
  file: { bucket: APP_ID, type: APP_SCHEMA.types['file'] }
2450
2504
  };
2451
- this.searchFocused = false;
2452
2505
  this.enableDetails = signal(true);
2453
2506
  this.enableTree = signal(true);
2454
2507
  this.tileConfigBucketLabel = this.translate.instant('yuv.app.drive.tile-config.bucket');
2455
2508
  this.smallScreenLayout = signal(false);
2456
2509
  this.sortOptionsAvailable = signal(true);
2510
+ this.extendedSearch = signal(false);
2457
2511
  this.id = input(null);
2458
2512
  this.highlightStyles$ = this.clipboard.clipboard$(APP_ID).pipe(takeUntilDestroyed(), map((c) => {
2459
2513
  return c && c.mode && c.objects?.length
@@ -2544,8 +2598,8 @@ class FilesPageComponent {
2544
2598
  if (this.route.snapshot.params['id'] === DRIVE_QUERY_FOLDER_ID) {
2545
2599
  const q = p.get('q');
2546
2600
  this.disableCreate = true;
2547
- // check if the query is a stored query
2548
2601
  if (q?.startsWith(STORED_QUERY_ID_PREFIX)) {
2602
+ // stored query
2549
2603
  const sq = this.storedQueryService.getStoredQuery(q);
2550
2604
  if (sq) {
2551
2605
  this.drive.updateQuery(sq.query, sq.label);
@@ -2554,11 +2608,12 @@ class FilesPageComponent {
2554
2608
  }
2555
2609
  }
2556
2610
  else if (q) {
2611
+ // search query
2557
2612
  this.sortOptionsAvailable.set(true);
2558
2613
  try {
2559
2614
  const sq = JSON.parse(decodeURIComponent(q));
2560
2615
  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'));
2616
+ this.drive.updateQuery(sq, this.translate.instant('yuv.app.drive.files.search.result.title'), p.get('ext') === 'true');
2562
2617
  return;
2563
2618
  }
2564
2619
  catch (e) {
@@ -2633,16 +2688,16 @@ class FilesPageComponent {
2633
2688
  onCut(tiles) {
2634
2689
  this.clipboard.addObjects(tiles.map((t) => t.dmsObject), 'cut', APP_ID);
2635
2690
  }
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
- }
2691
+ // onQuerySubmit(q: SearchQuery) {
2692
+ // // in order to keep the query in the url as short as
2693
+ // // possible we'll get rid of the fields because they could be
2694
+ // // re-applied later on
2695
+ // q.fields = undefined;
2696
+ // this.router.navigate(['..', 'query'], {
2697
+ // queryParams: { q: encodeURIComponent(JSON.stringify(q)) },
2698
+ // relativeTo: this.route
2699
+ // });
2700
+ // }
2646
2701
  selectionChanged(tiles) {
2647
2702
  if (tiles.length === 1)
2648
2703
  this.loadDetails(tiles[0].id);
@@ -2722,17 +2777,14 @@ class FilesPageComponent {
2722
2777
  this.clipboard.clear(APP_ID);
2723
2778
  }
2724
2779
  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"] }] }); }
2780
+ 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$1.Icon, selector: "yvc-icon", inputs: ["label", "svg", "svgSrc"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.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
2781
  }
2727
2782
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FilesPageComponent, decorators: [{
2728
2783
  type: Component,
2729
2784
  args: [{ selector: 'ymd-files', standalone: true, imports: [NgClass, AsyncPipe, ...module, ...components, FileDropZoneDirective], host: {
2730
2785
  '[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
- }] } });
2786
+ }, 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"] }]
2787
+ }], ctorParameters: () => [] });
2736
2788
 
2737
2789
  class ObjectPageComponent {
2738
2790
  #dmsService;
@@ -2886,7 +2938,7 @@ class ObjectPageComponent {
2886
2938
  }
2887
2939
  }
2888
2940
  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"] }] }); }
2941
+ 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: i1.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"] }] }); }
2890
2942
  }
2891
2943
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ObjectPageComponent, decorators: [{
2892
2944
  type: Component,