@yuuvis/client-framework 2.6.3 → 2.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 (45) hide show
  1. package/common/lib/components/busy-overlay/busy-overlay.component.d.ts +0 -1
  2. package/datepicker/lib/calendar/calendar.component.d.ts +1 -2
  3. package/datepicker/lib/date-input/date-input.component.d.ts +1 -1
  4. package/fesm2022/yuuvis-client-framework-common.mjs +1 -4
  5. package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -1
  6. package/fesm2022/yuuvis-client-framework-datepicker.mjs +32 -29
  7. package/fesm2022/yuuvis-client-framework-datepicker.mjs.map +1 -1
  8. package/fesm2022/yuuvis-client-framework-forms.mjs +7 -4
  9. package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
  10. package/fesm2022/yuuvis-client-framework-list.mjs +96 -62
  11. package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -1
  12. package/fesm2022/yuuvis-client-framework-object-flavor.mjs +2 -2
  13. package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -1
  14. package/fesm2022/yuuvis-client-framework-object-versions.mjs +1 -1
  15. package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
  16. package/fesm2022/yuuvis-client-framework-query-list.mjs +284 -0
  17. package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -0
  18. package/fesm2022/yuuvis-client-framework-tile-list.mjs +92 -203
  19. package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
  20. package/fesm2022/yuuvis-client-framework-tree.mjs +8 -5
  21. package/fesm2022/yuuvis-client-framework-tree.mjs.map +1 -1
  22. package/fesm2022/yuuvis-client-framework.mjs +716 -160
  23. package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
  24. package/lib/config/halo-focus-defaults/halo-excluded-elements.const.d.ts +26 -0
  25. package/lib/config/halo-focus-defaults/halo-focus-navigation-keys.const.d.ts +25 -0
  26. package/lib/config/halo-focus-defaults/halo-focus-offset.const.d.ts +25 -0
  27. package/lib/config/halo-focus-defaults/halo-focus-styles.const.d.ts +26 -0
  28. package/lib/config/halo-focus-defaults/index.d.ts +4 -0
  29. package/lib/config/index.d.ts +1 -0
  30. package/lib/models/halo-focus-config/halo-focus-config.model.d.ts +48 -0
  31. package/lib/models/halo-focus-config/index.d.ts +1 -0
  32. package/lib/models/index.d.ts +1 -0
  33. package/lib/providers/halo-focus/index.d.ts +1 -0
  34. package/lib/providers/halo-focus/provide-halo-focus.d.ts +58 -6
  35. package/lib/providers/index.d.ts +1 -1
  36. package/lib/services/halo-focus/halo-focus.service.d.ts +80 -17
  37. package/lib/services/halo-utility/halo-utility.service.d.ts +230 -0
  38. package/lib/services/index.d.ts +1 -0
  39. package/list/lib/list.component.d.ts +35 -6
  40. package/package.json +19 -15
  41. package/query-list/README.md +3 -0
  42. package/query-list/index.d.ts +2 -0
  43. package/query-list/lib/query-list.component.d.ts +152 -0
  44. package/query-list/lib/query-list.module.d.ts +7 -0
  45. package/tile-list/lib/tile-list/tile-list.component.d.ts +60 -34
@@ -1,32 +1,34 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, viewChild, ChangeDetectionStrategy, Component, Injectable, inject, ViewContainerRef, effect, Directive, DestroyRef, ElementRef, contentChild, computed, viewChildren, signal, untracked, HostBinding, HostListener } from '@angular/core';
2
+ import { input, output, viewChild, ChangeDetectionStrategy, Component, Injectable, inject, ViewContainerRef, effect, Directive, DestroyRef, ElementRef, contentChild, computed, untracked, signal, HostListener } from '@angular/core';
3
3
  import * as i1$1 from '@yuuvis/client-core';
4
- import { ObjectConfigService, SystemService, SearchService, EventService, DmsService, YuvEventType, BaseObjectTypeField, DmsObject, TranslateModule, ContentStreamField, Utils, Sort } from '@yuuvis/client-core';
5
- import { ClickDoubleDirective, DragSelectDirective, DragSelectItemDirective, DialogComponent } from '@yuuvis/client-framework/common';
4
+ import { ObjectConfigService, DmsService, DmsObject, SearchService, BaseObjectTypeField, TranslateModule, SystemService, ContentStreamField, Utils, Sort } from '@yuuvis/client-core';
6
5
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
6
  import * as i1$3 from '@angular/forms';
8
7
  import { ReactiveFormsModule, FormsModule } from '@angular/forms';
9
- import * as i2 from '@angular/material/icon';
8
+ import * as i3 from '@angular/material/icon';
10
9
  import { MatIcon, MatIconModule } from '@angular/material/icon';
11
10
  import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
12
- import * as i3 from '@angular/material/paginator';
13
11
  import { MatPaginatorModule } from '@angular/material/paginator';
14
12
  import * as i2$1 from '@angular/material/tooltip';
15
13
  import { MatTooltipModule } from '@angular/material/tooltip';
16
14
  import { ActionsService } from '@yuuvis/client-framework/actions';
17
- import { YUV_ICONS, ObjectTypeIconComponent } from '@yuuvis/client-framework/icons';
18
15
  import * as i1 from '@yuuvis/client-framework/list';
19
- import { ListTileComponent, YuvListModule } from '@yuuvis/client-framework/list';
16
+ import { YuvListModule } from '@yuuvis/client-framework/list';
17
+ import * as i2 from '@yuuvis/client-framework/query-list';
18
+ import { YuvQueryListModule } from '@yuuvis/client-framework/query-list';
20
19
  import { RendererDirective } from '@yuuvis/client-framework/renderer';
21
- import { DeviceService, YmtMatIconRegistryService, YmtIconButtonDirective, YmtButtonDirective } from '@yuuvis/material';
22
- import { switchMap, finalize } from 'rxjs';
20
+ import { YmtMatIconRegistryService, YmtIconButtonDirective, YmtButtonDirective } from '@yuuvis/material';
21
+ import { switchMap } from 'rxjs';
22
+ import { coerceBooleanProperty } from '@angular/cdk/coercion';
23
23
  import * as i1$2 from '@angular/material/button';
24
24
  import { MatButtonModule } from '@angular/material/button';
25
25
  import { MatDialogModule, MatDialog } from '@angular/material/dialog';
26
26
  import { MatFormFieldModule } from '@angular/material/form-field';
27
27
  import * as i3$1 from '@angular/material/select';
28
28
  import { MatSelectModule } from '@angular/material/select';
29
+ import { DialogComponent } from '@yuuvis/client-framework/common';
29
30
  import { NgClass, CommonModule } from '@angular/common';
31
+ import { ObjectTypeIconComponent } from '@yuuvis/client-framework/icons';
30
32
  import { TranslateModule as TranslateModule$1 } from '@ngx-translate/core';
31
33
 
32
34
  class TileActionsMenuComponent {
@@ -141,51 +143,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
141
143
  * List that renders the result of a search query as object config based tiles. It also contains a component to
142
144
  * set up that configuration.
143
145
  *
144
- * ## Paging
145
- * If the search result contains more items than the page size, the list will show a
146
- * pagination control to navigate inbetween the pages.
147
- *
148
- * ## Staggered animation
149
- * Adding a class of `staggered` to the `yuv-tile-list` component will animate
150
- * the tiles in a staggered way (only if the user has not set up the OS to not
151
- * play animation).
152
146
  */
153
147
  const MATERIAL_IMPORTS = [MatIconModule, MatPaginatorModule, MatTooltipModule, MatMenuTrigger];
154
148
  class TileListComponent {
155
- #objectConfigService;
156
- #system;
157
- #searchService;
158
- #destroyRef;
159
- #device;
160
- #elRef;
161
- #events;
162
- #actionService;
163
- #dmsService;
164
- #contextFlag;
165
- onCopy(event) {
166
- event.preventDefault();
167
- if (this._selection.length)
168
- this.tileCopy.emit(this._selectionToTileData(this._selection));
169
- }
170
- onCut(event) {
171
- event.preventDefault();
172
- if (this._selection.length)
173
- this.tileCut.emit(this._selectionToTileData(this._selection));
174
- }
175
- #currBusy;
176
- #_busyEffect;
177
- #preselect;
178
- #preselectEffect;
179
- #query;
180
- #executeQueryEffect;
181
149
  constructor() {
182
150
  this.#objectConfigService = inject(ObjectConfigService);
183
- this.#system = inject(SystemService);
184
- this.#searchService = inject(SearchService);
185
151
  this.#destroyRef = inject(DestroyRef);
186
- this.#device = inject(DeviceService);
187
152
  this.#elRef = inject(ElementRef);
188
- this.#events = inject(EventService);
189
153
  this.#actionService = inject(ActionsService);
190
154
  this.#dmsService = inject(DmsService);
191
155
  this.menuComponent = contentChild(TileActionsMenuComponent);
@@ -194,27 +158,30 @@ class TileListComponent {
194
158
  return comp?.matMenu() ?? null;
195
159
  });
196
160
  this.emptyContent = contentChild('empty');
197
- this.isTouchDevice = this.#device.isTouchEnabled;
198
- this.tiles = viewChildren(ListTileComponent);
199
161
  this.list = viewChild.required('list');
200
- this.#contextFlag = signal(false);
201
- this.#currBusy = false;
202
- this._busy = signal(false);
203
- this.#_busyEffect = effect(() => {
204
- const b = this._busy();
162
+ this.transformer = (res) => {
163
+ this.#rawResultItems = res;
164
+ const mappedItems = this.#mapToTileData(res.map((i) => new DmsObject(i)));
165
+ const items = mappedItems.map((item) => ({
166
+ ...item,
167
+ actions: (item.actions || [])
168
+ .map((a) => this.#actionService.getActionById(a.id, this.options()?.actionContext))
169
+ .filter((a) => a !== undefined)
170
+ }));
171
+ untracked(() => this.items.set(items));
172
+ return items;
173
+ };
174
+ this._busy = computed(() => this.list().busy());
175
+ this.#busyEffect = effect(() => {
205
176
  const preselect = this.#preselect();
206
- if (!b && preselect.length) {
177
+ const busy = this._busy();
178
+ if (!busy && preselect.length) {
207
179
  this.selectById(preselect);
208
180
  this.#preselect.set([]);
209
181
  }
210
- if (b !== this.#currBusy) {
211
- this.#currBusy = b;
212
- this.busy.emit(b);
213
- }
214
182
  });
215
183
  this._selection = [];
216
184
  this.selectedTile = signal([]);
217
- this.empytIcon = signal(YUV_ICONS.trash);
218
185
  /**
219
186
  * The ID of the selected list item
220
187
  */
@@ -226,15 +193,29 @@ class TileListComponent {
226
193
  * retrieved. Buckets should be unique so be sure to use a unique namespace.
227
194
  */
228
195
  this.bucket = input();
196
+ /**
197
+ * The number of items to display per page.
198
+ */
229
199
  this.pageSize = input(SearchService.DEFAULT_QUERY_SIZE);
230
200
  /**
231
- * Sets up the ability to select multile tiles
201
+ * Sets up the ability to select multiple tiles
202
+ * @default false
232
203
  */
233
204
  this.multiselect = input(false);
205
+ /**
206
+ * If `true`, the tiles will be rendered in a more compact, denser style.
207
+ * @default false
208
+ */
234
209
  this.dense = input(false);
210
+ /**
211
+ * Configuration options for the tile list component.
212
+ */
235
213
  this.options = input(undefined);
214
+ /**
215
+ * The object flavor to be applied to the tiles.
216
+ */
236
217
  this.flavor = input();
237
- this.flavorEffect = effect(() => {
218
+ this.#flavorEffect = effect(() => {
238
219
  const f = this.flavor();
239
220
  if (f)
240
221
  this.applyFlavor(f);
@@ -258,7 +239,17 @@ class TileListComponent {
258
239
  });
259
240
  return x;
260
241
  });
261
- this.preventChangeUntil = input(() => true);
242
+ /**
243
+ * Prevent selection changes while the provided function returns false.
244
+ */
245
+ this.preventChangeUntil = input(() => false);
246
+ /**
247
+ * If `true`, the list will select an item automatically on initialization.
248
+ * First, list will search for an item item that has the "selected"-attribute
249
+ * and is not disabled. If no such item exists, the first item will be selected.
250
+ * @default false
251
+ */
252
+ this.autoSelect = input(false, { transform: (value) => coerceBooleanProperty(value) });
262
253
  this.disableCustomContextMenu = input(false);
263
254
  /**
264
255
  * Emitted when a list item has been selected
@@ -275,43 +266,34 @@ class TileListComponent {
275
266
  */
276
267
  this.selectionChange = output();
277
268
  /**
278
- * Emitted when a list item has been doubleclicked
269
+ * Emitted when a list item has been double-clicked
279
270
  */
280
271
  this.itemDblClick = output();
281
272
  this.ctxMenu = output();
282
273
  // the items rendered in the list
283
274
  this.items = signal([]);
284
- this._items = computed(() => {
285
- const items = this.items();
286
- return items.map((item) => ({
287
- ...item,
288
- actions: (item.actions || [])
289
- .map((a) => this.#actionService.getActionById(a.id, this.options()?.actionContext))
290
- .filter((a) => a !== undefined)
291
- }));
292
- });
293
275
  this.searchExecuted = false;
294
- this.#executeQueryEffect = effect(() => {
295
- // execute the query each time it changes
296
- this.#query = this.query();
297
- if (this.#query && this.oc)
298
- untracked(() => {
299
- this.#executeQuery(this.#query || undefined);
300
- this.empytIcon.set(YUV_ICONS.refresh);
301
- });
302
- });
303
- this.#events
304
- .on(YuvEventType.DMS_OBJECT_UPDATED)
305
- .pipe(takeUntilDestroyed())
306
- .subscribe((e) => {
307
- const dmsObject = e.data;
308
- // check if the updated object is part of the list
309
- this.items().findIndex((item) => item.id === dmsObject.id) >= 0 && this.updateTileList([dmsObject]);
310
- });
311
276
  }
312
- getPageSize() {
313
- return typeof this.#query === 'string' ? this.pageSize() : this.#query?.size || this.pageSize();
277
+ #objectConfigService;
278
+ #destroyRef;
279
+ #elRef;
280
+ #actionService;
281
+ #dmsService;
282
+ onCopy(event) {
283
+ event.preventDefault();
284
+ if (this._selection.length)
285
+ this.tileCopy.emit(this._selectionToTileData(this._selection));
314
286
  }
287
+ onCut(event) {
288
+ event.preventDefault();
289
+ if (this._selection.length)
290
+ this.tileCut.emit(this._selectionToTileData(this._selection));
291
+ }
292
+ #busyEffect;
293
+ #flavorEffect;
294
+ #preselect;
295
+ #preselectEffect;
296
+ #rawResultItems;
315
297
  contextMenuHandler(event, index) {
316
298
  if (this.disableCustomContextMenu())
317
299
  return;
@@ -332,14 +314,6 @@ class TileListComponent {
332
314
  .pipe(switchMap((o) => a.run([o])))
333
315
  .subscribe();
334
316
  }
335
- select(i, evt) {
336
- const check = this.preventChangeUntil();
337
- const checked = check();
338
- if (checked) {
339
- const idx = this.items().findIndex((item) => item.id === i.id);
340
- this.selectByIndex(idx, evt);
341
- }
342
- }
343
317
  selectById(ids) {
344
318
  if (this._busy())
345
319
  this.#preselect.set(ids);
@@ -351,41 +325,29 @@ class TileListComponent {
351
325
  this.selectionChange.emit(tiles);
352
326
  }
353
327
  }
354
- onDragSelectChange(sel) {
355
- this.list().multiSelect(sel);
356
- this._selection = sel;
357
- this._selection.sort();
328
+ selectByIndex(idx, evt) {
329
+ this.#select(idx, evt?.shiftKey, evt?.ctrlKey);
358
330
  }
359
- onDragSelect(sel) {
360
- this.#elRef.nativeElement.focus();
361
- this._selection = sel;
362
- const tiles = this._selectionToTileData(sel);
363
- this.selectionChange.emit(tiles);
331
+ onQueryResult(e) {
332
+ this.searchExecuted = true;
333
+ this.queryResult.emit(e);
364
334
  }
365
335
  onListItemsSelect(sel) {
366
336
  this._selection = sel;
367
337
  if (sel.length)
368
338
  this.selectByIndex(sel[0]);
369
339
  }
370
- selectByIndex(idx, evt) {
371
- this.#select(idx, evt?.shiftKey, evt?.ctrlKey);
372
- }
373
340
  refresh() {
374
- if (this.#query) {
375
- if (this.pagination) {
376
- this.goToPage(this.pagination.page);
377
- }
378
- else
379
- this.#executeQuery(this.query() || undefined);
380
- }
341
+ this.list().refresh();
381
342
  }
382
343
  applyFlavor(flavor) {
383
344
  this.appliedFlavor = this.appliedFlavor?.id === flavor.id ? undefined : flavor;
384
- if (this._rawResult)
385
- this.items.set(this._mapSearchResult(this._rawResult));
345
+ if (this.#rawResultItems)
346
+ this.items.set(this.#mapToTileData(this.#rawResultItems.map((i) => new DmsObject(i))));
386
347
  }
387
348
  clearSelection(silent = false) {
388
349
  if (this._selection.length) {
350
+ this.list().clear(silent);
389
351
  this._selection = [];
390
352
  if (!silent)
391
353
  this.selectionChange.emit([]);
@@ -407,26 +369,6 @@ class TileListComponent {
407
369
  this.#select(this._lastSelection - 1);
408
370
  }
409
371
  }
410
- changePage(pe) {
411
- this.goToPage(pe.pageIndex + 1);
412
- }
413
- goToPage(page) {
414
- if (!this.#query)
415
- return;
416
- this._busy.set(true);
417
- this.#searchService
418
- .getPage(this.#query, page, this.getPageSize())
419
- .pipe(finalize(() => this._busy.set(false)))
420
- .subscribe({
421
- next: (res) => {
422
- this.#setupPagination(res);
423
- this.items.set(this._mapSearchResult(res));
424
- },
425
- error: (err) => {
426
- // TODO: how should errors be handles in case hat loading pages fail
427
- }
428
- });
429
- }
430
372
  #select(index, shiftKey = false, ctrlKey = false) {
431
373
  this.#elRef.nativeElement.focus();
432
374
  if (index === -1) {
@@ -471,47 +413,6 @@ class TileListComponent {
471
413
  _selectionToTileData(selection) {
472
414
  return selection.map((idx) => this.items()[idx]);
473
415
  }
474
- /**
475
- * Executes a search query.
476
- * @param query The search query to execute. This may be a SearchQuery object or a string. If it's a string, it is supposed to
477
- * be a CMIS query statement.
478
- */
479
- #executeQuery(query) {
480
- if (query && this.#system.system && !this._busy()) {
481
- this.searchExecuted = false;
482
- // reset items to avoid old data being shown while new stuff is loaded
483
- this.items.set([]);
484
- this._busy.set(true);
485
- const isSearchQuery = query && typeof query !== 'string';
486
- if (isSearchQuery) {
487
- query.fields = undefined;
488
- }
489
- (isSearchQuery ? this.#searchService.search(query) : this.#searchService.searchCmis(query, this.getPageSize()))
490
- .pipe(finalize(() => this._busy.set(false)))
491
- .subscribe({
492
- next: (res) => {
493
- this.#setupPagination(res);
494
- this.items.set(this._mapSearchResult(res));
495
- this.queryResult.emit({ totalCount: res.items.length });
496
- const preselect = this.preselect();
497
- if (preselect) {
498
- this.selectById(preselect);
499
- }
500
- },
501
- error: (err) => console.error(err)
502
- });
503
- }
504
- }
505
- #setupPagination(searchResult) {
506
- this.pagination = undefined;
507
- this.pagination = searchResult.paging
508
- ? {
509
- total: searchResult.totalNumItems,
510
- pages: searchResult.paging.totalPages,
511
- page: searchResult.paging.page
512
- }
513
- : undefined;
514
- }
515
416
  #mapToTileData(objects) {
516
417
  return objects.map((dmsObject) => {
517
418
  const sots = dmsObject.sots || [];
@@ -562,11 +463,6 @@ class TileListComponent {
562
463
  return tli;
563
464
  });
564
465
  }
565
- _mapSearchResult(res) {
566
- this.searchExecuted = true;
567
- this._rawResult = res;
568
- return this.oc ? this.#mapToTileData(res.items.map((i) => new DmsObject(i))) : [];
569
- }
570
466
  #getResolvedObjectConfigItem(propertyName, instanceData) {
571
467
  const item = {
572
468
  propertyName: propertyName,
@@ -597,6 +493,7 @@ class TileListComponent {
597
493
  });
598
494
  }
599
495
  ngOnInit() {
496
+ this._busy = this.list().busy;
600
497
  this.#objectConfigService
601
498
  .getObjectConfigs$(this.bucket() || '', true)
602
499
  .pipe(takeUntilDestroyed(this.#destroyRef))
@@ -604,15 +501,12 @@ class TileListComponent {
604
501
  next: (res) => {
605
502
  this.oc = res;
606
503
  const q = this.query();
607
- q && this.#executeQuery(q);
504
+ // q && this.#executeQuery(q);
608
505
  }
609
506
  });
610
507
  }
611
- ngOnDestroy() {
612
- // this._keyManager?.destroy();
613
- }
614
508
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TileListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
615
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TileListComponent, isStandalone: true, selector: "yuv-tile-list", inputs: { bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, multiselect: { classPropertyName: "multiselect", publicName: "multiselect", isSignal: true, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, flavor: { classPropertyName: "flavor", publicName: "flavor", isSignal: true, isRequired: false, transformFunction: null }, query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, preselect: { classPropertyName: "preselect", publicName: "preselect", isSignal: true, isRequired: false, transformFunction: null }, highlights: { classPropertyName: "highlights", publicName: "highlights", isSignal: true, isRequired: false, transformFunction: null }, preventChangeUntil: { classPropertyName: "preventChangeUntil", publicName: "preventChangeUntil", isSignal: true, isRequired: false, transformFunction: null }, disableCustomContextMenu: { classPropertyName: "disableCustomContextMenu", publicName: "disableCustomContextMenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect", tileCopy: "tileCopy", tileCut: "tileCut", busy: "busy", queryResult: "queryResult", selectionChange: "selectionChange", itemDblClick: "itemDblClick", ctxMenu: "ctxMenu" }, host: { listeners: { "keydown.control.c": "onCopy($event)", "keydown.control.x": "onCut($event)" }, properties: { "class.dense": "dense()", "class.pagination": "this.pagination" } }, providers: [], queries: [{ propertyName: "menuComponent", first: true, predicate: TileActionsMenuComponent, descendants: true, isSignal: true }, { propertyName: "emptyContent", first: true, predicate: ["empty"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "tiles", predicate: ListTileComponent, descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-list\n #list\n [multiselect]=\"this.multiselect()\"\n [selfHandleSelection]=\"true\"\n (itemSelect)=\"onListItemsSelect($event)\"\n [yuvDragSelect]=\"{ disabled: !this.multiselect() || isTouchDevice }\"\n (dragSelectChange)=\"onDragSelectChange($event)\"\n (dragSelect)=\"onDragSelect($event)\"\n>\n @for (i of _items(); track i.id) {\n <yuv-list-tile [class.dense]=\"dense()\"\n yuvListItem\n yuvDragSelectItem\n (click.single)=\"select(i, $event)\"\n (click.double)=\"itemDblClick.emit(i)\"\n (contextmenu)=\"contextMenuHandler($event, $index)\"\n >\n <ng-template #iconSlot><ng-container *yuvRenderer=\"i.icon\"></ng-container></ng-template>\n <ng-template #titleSlot><ng-container *yuvRenderer=\"i.title\"></ng-container></ng-template>\n <ng-template #descriptionSlot><ng-container *yuvRenderer=\"i.description\"></ng-container></ng-template>\n <ng-template #metaSlot><ng-container *yuvRenderer=\"i.meta\"></ng-container></ng-template>\n <ng-template #asideSlot><ng-container *yuvRenderer=\"i.aside\"></ng-container></ng-template>\n <ng-template #actionsSlot>\n @for (a of i.actions; track a.id) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matTooltip]=\"a.label\" (click)=\"executeAction(i, a, $event)\">\n <mat-icon inert=\"true\">{{ a.icon }}</mat-icon>\n </button>\n }\n\n @if (menu()) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matMenuTriggerFor]=\"menu()\">\n <mat-icon inert=\"true\">more_vert</mat-icon>\n </button>\n }\n <ng-content select=\"yuv-tile-actions-menu, [yuv-tile-actions-menu]\"></ng-content>\n </ng-template>\n <ng-template #extensionSlot> <ng-container *yuvTileExtension=\"{ typeId: i.objectTypeId, data: i.instanceData }\"></ng-container> </ng-template>\n <ng-template #badgesSlot>{{ i.badges }}</ng-template>\n </yuv-list-tile>\n } @empty {\n <div class=\"empyt-list\">\n @if (searchExecuted && emptyContent()) {\n <ng-content></ng-content>\n }\n </div>\n }\n <div class=\"offset\" (click)=\"clearSelection()\"></div>\n</yuv-list>\n@if (pagination) {\n <mat-paginator class=\"paginator\" [length]=\"pagination?.total\" [pageSize]=\"getPageSize()\" (page)=\"changePage($event)\" hidePageSize> </mat-paginator>\n}\n", styles: [":host{--paging-background: var(--ymt-surface);display:flex;flex-direction:column}:host yuv-list{overflow-y:auto;display:flex;flex-flow:column;height:100%}:host yuv-list .offset{flex:1 1 auto}:host .paginator{border-block-start:1px solid var(--ymt-outline-variant);font:inherit;background-color:var(--paging-background)}:host yuv-tile{cursor:pointer}:host yuv-tile:not(.last){border:var(--tile-border);border-width:var(--tile-border-width);margin-block-end:var(--tile-gap)}:host .empyt-list{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i1.ListComponent, selector: "yuv-list", inputs: ["preventChangeUntil", "multiselect", "selfHandleSelection", "autoSelect", "disableSelection"], outputs: ["itemSelect", "itemFocus"] }, { kind: "directive", type: i1.ListItemDirective, selector: "[yuvListItem]", inputs: ["disabled", "active", "selected"] }, { kind: "component", type: i1.ListTileComponent, selector: "yuv-list-tile" }, { kind: "directive", type: ClickDoubleDirective, selector: "[click.single],[click.double]", inputs: ["debounceTime"], outputs: ["click.double", "click.single"] }, { kind: "directive", type: DragSelectDirective, selector: "[yuvDragSelect]", inputs: ["yuvDragSelect"], outputs: ["dragSelectChange", "dragSelect"] }, { kind: "directive", type: DragSelectItemDirective, selector: "[yuvDragSelectItem]" }, { kind: "directive", type: RendererDirective, selector: "[yuvRenderer]", inputs: ["yuvRenderer"] }, { kind: "directive", type: TileExtensionDirective, selector: "[yuvTileExtension]", inputs: ["yuvTileExtension"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i3.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] }); }
509
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TileListComponent, isStandalone: true, selector: "yuv-tile-list", inputs: { bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, multiselect: { classPropertyName: "multiselect", publicName: "multiselect", isSignal: true, isRequired: false, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, flavor: { classPropertyName: "flavor", publicName: "flavor", isSignal: true, isRequired: false, transformFunction: null }, query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, preselect: { classPropertyName: "preselect", publicName: "preselect", isSignal: true, isRequired: false, transformFunction: null }, highlights: { classPropertyName: "highlights", publicName: "highlights", isSignal: true, isRequired: false, transformFunction: null }, preventChangeUntil: { classPropertyName: "preventChangeUntil", publicName: "preventChangeUntil", isSignal: true, isRequired: false, transformFunction: null }, autoSelect: { classPropertyName: "autoSelect", publicName: "autoSelect", isSignal: true, isRequired: false, transformFunction: null }, disableCustomContextMenu: { classPropertyName: "disableCustomContextMenu", publicName: "disableCustomContextMenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemSelect: "itemSelect", tileCopy: "tileCopy", tileCut: "tileCut", busy: "busy", queryResult: "queryResult", selectionChange: "selectionChange", itemDblClick: "itemDblClick", ctxMenu: "ctxMenu" }, host: { listeners: { "keydown.control.c": "onCopy($event)", "keydown.control.x": "onCut($event)" }, properties: { "class.dense": "dense()" } }, providers: [], queries: [{ propertyName: "menuComponent", first: true, predicate: TileActionsMenuComponent, descendants: true, isSignal: true }, { propertyName: "emptyContent", first: true, predicate: ["empty"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<yuv-query-list\n #list\n [query]=\"query()\"\n [transformer]=\"transformer\"\n [preventChangeUntil]=\"preventChangeUntil()\"\n [autoSelect]=\"autoSelect()\"\n [pageSize]=\"pageSize()\"\n [multiselect]=\"multiselect()\"\n (itemDoubleClick)=\"selectByIndex($event)\"\n (itemSelect)=\"onListItemsSelect($event)\"\n (queryResult)=\"onQueryResult($event)\"\n>\n\n <ng-template #yuvQueryListItem let-item let-index=\"index\">\n <yuv-list-tile\n [class.dense]=\"dense()\"\n (contextmenu)=\"contextMenuHandler($event, index)\"\n >\n <ng-template #iconSlot><ng-container *yuvRenderer=\"item.icon\"></ng-container></ng-template>\n <ng-template #titleSlot><ng-container *yuvRenderer=\"item.title\"></ng-container></ng-template>\n <ng-template #descriptionSlot><ng-container *yuvRenderer=\"item.description\"></ng-container></ng-template>\n <ng-template #metaSlot><ng-container *yuvRenderer=\"item.meta\"></ng-container></ng-template>\n <ng-template #asideSlot><ng-container *yuvRenderer=\"item.aside\"></ng-container></ng-template>\n <ng-template #actionsSlot>\n @for (a of item.actions; track a.id) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matTooltip]=\"a.label\" (click)=\"executeAction(item, a, $event)\">\n <mat-icon inert=\"true\">{{ a.icon }}</mat-icon>\n </button>\n }\n\n @if (menu()) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matMenuTriggerFor]=\"menu()\">\n <mat-icon inert=\"true\">more_vert</mat-icon>\n </button>\n }\n <ng-content select=\"yuv-tile-actions-menu, [yuv-tile-actions-menu]\"></ng-content>\n </ng-template>\n <ng-template #extensionSlot> <ng-container *yuvTileExtension=\"{ typeId: item.objectTypeId, data: item.instanceData }\"></ng-container> </ng-template>\n <ng-template #badgesSlot>{{ item.badges }}</ng-template>\n </yuv-list-tile>\n </ng-template>\n\n <ng-template #yuvQueryListEmpty>\n <div class=\"empyt-list\">\n @if (searchExecuted && emptyContent()) {\n <ng-content></ng-content>\n }\n </div>\n </ng-template>\n <div class=\"offset\" (click)=\"clearSelection()\"></div>\n</yuv-query-list>\n", styles: [":host{--paging-background: var(--ymt-surface);display:flex;flex-direction:column}:host yuv-query-list{flex:1;overflow-y:auto;display:flex;flex-flow:column;height:100%}:host yuv-query-list .offset{flex:1 1 auto}:host .empyt-list{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: YuvListModule }, { kind: "component", type: i1.ListTileComponent, selector: "yuv-list-tile" }, { kind: "ngmodule", type: YuvQueryListModule }, { kind: "component", type: i2.QueryListComponent, selector: "yuv-query-list", inputs: ["query", "transformer", "preventChangeUntil", "autoSelect", "pageSize", "enableDragSelect", "multiselect", "selfHandleSelection"], outputs: ["itemSelect", "dragSelectChange", "itemDoubleClick", "queryResult"] }, { kind: "directive", type: RendererDirective, selector: "[yuvRenderer]", inputs: ["yuvRenderer"] }, { kind: "directive", type: TileExtensionDirective, selector: "[yuvTileExtension]", inputs: ["yuvTileExtension"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] }); }
616
510
  }
617
511
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TileListComponent, decorators: [{
618
512
  type: Component,
@@ -620,26 +514,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
620
514
  TranslateModule,
621
515
  ReactiveFormsModule,
622
516
  YuvListModule,
623
- ClickDoubleDirective,
517
+ YuvQueryListModule,
624
518
  YuvListModule,
625
- DragSelectDirective,
626
- DragSelectItemDirective,
627
519
  RendererDirective,
628
520
  TileExtensionDirective,
629
521
  YmtIconButtonDirective,
630
522
  ...MATERIAL_IMPORTS
631
523
  ], host: {
632
524
  '[class.dense]': 'dense()'
633
- }, template: "<yuv-list\n #list\n [multiselect]=\"this.multiselect()\"\n [selfHandleSelection]=\"true\"\n (itemSelect)=\"onListItemsSelect($event)\"\n [yuvDragSelect]=\"{ disabled: !this.multiselect() || isTouchDevice }\"\n (dragSelectChange)=\"onDragSelectChange($event)\"\n (dragSelect)=\"onDragSelect($event)\"\n>\n @for (i of _items(); track i.id) {\n <yuv-list-tile [class.dense]=\"dense()\"\n yuvListItem\n yuvDragSelectItem\n (click.single)=\"select(i, $event)\"\n (click.double)=\"itemDblClick.emit(i)\"\n (contextmenu)=\"contextMenuHandler($event, $index)\"\n >\n <ng-template #iconSlot><ng-container *yuvRenderer=\"i.icon\"></ng-container></ng-template>\n <ng-template #titleSlot><ng-container *yuvRenderer=\"i.title\"></ng-container></ng-template>\n <ng-template #descriptionSlot><ng-container *yuvRenderer=\"i.description\"></ng-container></ng-template>\n <ng-template #metaSlot><ng-container *yuvRenderer=\"i.meta\"></ng-container></ng-template>\n <ng-template #asideSlot><ng-container *yuvRenderer=\"i.aside\"></ng-container></ng-template>\n <ng-template #actionsSlot>\n @for (a of i.actions; track a.id) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matTooltip]=\"a.label\" (click)=\"executeAction(i, a, $event)\">\n <mat-icon inert=\"true\">{{ a.icon }}</mat-icon>\n </button>\n }\n\n @if (menu()) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matMenuTriggerFor]=\"menu()\">\n <mat-icon inert=\"true\">more_vert</mat-icon>\n </button>\n }\n <ng-content select=\"yuv-tile-actions-menu, [yuv-tile-actions-menu]\"></ng-content>\n </ng-template>\n <ng-template #extensionSlot> <ng-container *yuvTileExtension=\"{ typeId: i.objectTypeId, data: i.instanceData }\"></ng-container> </ng-template>\n <ng-template #badgesSlot>{{ i.badges }}</ng-template>\n </yuv-list-tile>\n } @empty {\n <div class=\"empyt-list\">\n @if (searchExecuted && emptyContent()) {\n <ng-content></ng-content>\n }\n </div>\n }\n <div class=\"offset\" (click)=\"clearSelection()\"></div>\n</yuv-list>\n@if (pagination) {\n <mat-paginator class=\"paginator\" [length]=\"pagination?.total\" [pageSize]=\"getPageSize()\" (page)=\"changePage($event)\" hidePageSize> </mat-paginator>\n}\n", styles: [":host{--paging-background: var(--ymt-surface);display:flex;flex-direction:column}:host yuv-list{overflow-y:auto;display:flex;flex-flow:column;height:100%}:host yuv-list .offset{flex:1 1 auto}:host .paginator{border-block-start:1px solid var(--ymt-outline-variant);font:inherit;background-color:var(--paging-background)}:host yuv-tile{cursor:pointer}:host yuv-tile:not(.last){border:var(--tile-border);border-width:var(--tile-border-width);margin-block-end:var(--tile-gap)}:host .empyt-list{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"] }]
634
- }], ctorParameters: () => [], propDecorators: { onCopy: [{
525
+ }, template: "<yuv-query-list\n #list\n [query]=\"query()\"\n [transformer]=\"transformer\"\n [preventChangeUntil]=\"preventChangeUntil()\"\n [autoSelect]=\"autoSelect()\"\n [pageSize]=\"pageSize()\"\n [multiselect]=\"multiselect()\"\n (itemDoubleClick)=\"selectByIndex($event)\"\n (itemSelect)=\"onListItemsSelect($event)\"\n (queryResult)=\"onQueryResult($event)\"\n>\n\n <ng-template #yuvQueryListItem let-item let-index=\"index\">\n <yuv-list-tile\n [class.dense]=\"dense()\"\n (contextmenu)=\"contextMenuHandler($event, index)\"\n >\n <ng-template #iconSlot><ng-container *yuvRenderer=\"item.icon\"></ng-container></ng-template>\n <ng-template #titleSlot><ng-container *yuvRenderer=\"item.title\"></ng-container></ng-template>\n <ng-template #descriptionSlot><ng-container *yuvRenderer=\"item.description\"></ng-container></ng-template>\n <ng-template #metaSlot><ng-container *yuvRenderer=\"item.meta\"></ng-container></ng-template>\n <ng-template #asideSlot><ng-container *yuvRenderer=\"item.aside\"></ng-container></ng-template>\n <ng-template #actionsSlot>\n @for (a of item.actions; track a.id) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matTooltip]=\"a.label\" (click)=\"executeAction(item, a, $event)\">\n <mat-icon inert=\"true\">{{ a.icon }}</mat-icon>\n </button>\n }\n\n @if (menu()) {\n <button ymt-icon-button [icon-button-size]=\"'small'\" [matMenuTriggerFor]=\"menu()\">\n <mat-icon inert=\"true\">more_vert</mat-icon>\n </button>\n }\n <ng-content select=\"yuv-tile-actions-menu, [yuv-tile-actions-menu]\"></ng-content>\n </ng-template>\n <ng-template #extensionSlot> <ng-container *yuvTileExtension=\"{ typeId: item.objectTypeId, data: item.instanceData }\"></ng-container> </ng-template>\n <ng-template #badgesSlot>{{ item.badges }}</ng-template>\n </yuv-list-tile>\n </ng-template>\n\n <ng-template #yuvQueryListEmpty>\n <div class=\"empyt-list\">\n @if (searchExecuted && emptyContent()) {\n <ng-content></ng-content>\n }\n </div>\n </ng-template>\n <div class=\"offset\" (click)=\"clearSelection()\"></div>\n</yuv-query-list>\n", styles: [":host{--paging-background: var(--ymt-surface);display:flex;flex-direction:column}:host yuv-query-list{flex:1;overflow-y:auto;display:flex;flex-flow:column;height:100%}:host yuv-query-list .offset{flex:1 1 auto}:host .empyt-list{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}\n"] }]
526
+ }], propDecorators: { onCopy: [{
635
527
  type: HostListener,
636
528
  args: ['keydown.control.c', ['$event']]
637
529
  }], onCut: [{
638
530
  type: HostListener,
639
531
  args: ['keydown.control.x', ['$event']]
640
- }], pagination: [{
641
- type: HostBinding,
642
- args: ['class.pagination']
643
532
  }] } });
644
533
 
645
534
  class ActionSelectComponent {
@@ -654,7 +543,7 @@ class ActionSelectComponent {
654
543
  this.actionSelect = output();
655
544
  }
656
545
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ActionSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
657
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ActionSelectComponent, isStandalone: true, selector: "yuv-tile-action-select", inputs: { objectType: { classPropertyName: "objectType", publicName: "objectType", isSignal: true, isRequired: true, transformFunction: null }, selectedActionIds: { classPropertyName: "selectedActionIds", publicName: "selectedActionIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionSelect: "actionSelect" }, ngImport: i0, template: "<div class=\"actions\">\n @for (a of actions(); track a.id) {\n <button [ngClass]=\"{ selected: selectedActionIds().includes(a.id) }\" (click)=\"actionSelect.emit(a)\">\n <mat-icon>{{ a.icon }}</mat-icon\n >{{ a.label }}\n </button>\n }\n</div>\n", styles: [":host .actions{display:flex;gap:var(--ymt-spacing-xs)}:host .actions button{border:1px solid var(--ymt-outline-variant);border-radius:0;margin-block-end:1px;background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);border:0;display:inline-flex;gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);align-items:center;border-radius:var(--ymt-corner-s)}:host .actions button.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
546
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ActionSelectComponent, isStandalone: true, selector: "yuv-tile-action-select", inputs: { objectType: { classPropertyName: "objectType", publicName: "objectType", isSignal: true, isRequired: true, transformFunction: null }, selectedActionIds: { classPropertyName: "selectedActionIds", publicName: "selectedActionIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionSelect: "actionSelect" }, ngImport: i0, template: "<div class=\"actions\">\n @for (a of actions(); track a.id) {\n <button [ngClass]=\"{ selected: selectedActionIds().includes(a.id) }\" (click)=\"actionSelect.emit(a)\">\n <mat-icon>{{ a.icon }}</mat-icon\n >{{ a.label }}\n </button>\n }\n</div>\n", styles: [":host .actions{display:flex;gap:var(--ymt-spacing-xs)}:host .actions button{border:1px solid var(--ymt-outline-variant);border-radius:0;margin-block-end:1px;background-color:var(--mat-sys-secondary-container);color:var(--mat-sys-on-secondary-container);border:0;display:inline-flex;gap:var(--ymt-spacing-xs);padding:var(--ymt-spacing-2xs) var(--ymt-spacing-xs);align-items:center;border-radius:var(--ymt-corner-s)}:host .actions button.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
658
547
  }
659
548
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ActionSelectComponent, decorators: [{
660
549
  type: Component,
@@ -781,7 +670,7 @@ class PropertySelectComponent {
781
670
  return this.system.getLocalizedLabel(otf.id) || otf.id;
782
671
  }
783
672
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PropertySelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
784
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: PropertySelectComponent, isStandalone: true, selector: "yuv-tile-property-select", inputs: { objectType: { classPropertyName: "objectType", publicName: "objectType", isSignal: true, isRequired: false, transformFunction: null }, selectedProperty: { classPropertyName: "selectedProperty", publicName: "selectedProperty", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { propertySelect: "propertySelect" }, ngImport: i0, template: "<!-- TODO: enable once filtering of properties makes sense -->\n<!-- <form class=\"filter\">\n <div class=\"filter-input\">\n <input type=\"text\" [placeholder]=\"'yuv.tile-config.property-select.filter.placeholder' | translate\" name=\"query\" [(ngModel)]=\"query\" />\n @if (query()) {\n <button class=\"icn\" (click)=\"query.set(null)\">\n <yuv-icon [svg]=\"clearIcon\"></yuv-icon>\n </button>\n }\n </div>\n</form> -->\n\n<ul class=\"properties\">\n @for (p of filteredObjectTypeFields(); track $index) {\n <li\n tabindex=\"0\"\n [ngClass]=\"{ baseProperty: p.baseProperty, selected: p.id === selectedProperty()?.propertyName }\"\n (click)=\"selectProperty(p)\"\n (keydown.enter)=\"selectPropertyOnKeydown($event, p)\"\n (keydown.space)=\"selectPropertyOnKeydown($event, p)\"\n >\n <div class=\"label\">{{ p.label }}</div>\n <button\n mat-icon-button\n (click)=\"removeProperty($event)\"\n (keydown.enter)=\"removePropertyOnKeydown($event)\"\n (keydown.space)=\"removePropertyOnKeydown($event)\"\n >\n <mat-icon aria-hidden=\"true\" [attr.inert]=\"true\">close</mat-icon>\n </button>\n </li>\n }\n</ul>\n", styles: [":host{display:flex;flex-flow:column;max-height:100%}:host .filter{flex:0 0 auto}:host .filter .filter-input{background-color:var(--ymt-surface-panel);border:1px solid var(--ymt-outline-variant);display:flex;padding:.25em;align-items:center}:host .filter .filter-input input{background-color:transparent;border:0;outline:0;flex:1;color:var(--ymt-text-color)}:host .properties{flex:1;column-count:3;column-width:30ch;column-rule:1px dotted var(--ymt-outline);column-gap:2em;margin-block-start:var(--ymt-spacing-m)}:host .properties li{border:1px solid var(--ymt-outline-variant);border-radius:0;margin-block-end:1px;display:flex;align-items:center;justify-content:space-between;cursor:default}:host .properties li:hover{background-color:var(--ymt-hover-background)}:host .properties li.baseProperty{font-style:italic}:host .properties li.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host .properties li:not(.selected) button{display:none}:host .properties li .label{padding:var(--ymt-spacing-xs) var(--ymt-spacing-m)}:host .properties li button{color:currentColor}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
673
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: PropertySelectComponent, isStandalone: true, selector: "yuv-tile-property-select", inputs: { objectType: { classPropertyName: "objectType", publicName: "objectType", isSignal: true, isRequired: false, transformFunction: null }, selectedProperty: { classPropertyName: "selectedProperty", publicName: "selectedProperty", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { propertySelect: "propertySelect" }, ngImport: i0, template: "<!-- TODO: enable once filtering of properties makes sense -->\n<!-- <form class=\"filter\">\n <div class=\"filter-input\">\n <input type=\"text\" [placeholder]=\"'yuv.tile-config.property-select.filter.placeholder' | translate\" name=\"query\" [(ngModel)]=\"query\" />\n @if (query()) {\n <button class=\"icn\" (click)=\"query.set(null)\">\n <yuv-icon [svg]=\"clearIcon\"></yuv-icon>\n </button>\n }\n </div>\n</form> -->\n\n<ul class=\"properties\">\n @for (p of filteredObjectTypeFields(); track $index) {\n <li\n tabindex=\"0\"\n [ngClass]=\"{ baseProperty: p.baseProperty, selected: p.id === selectedProperty()?.propertyName }\"\n (click)=\"selectProperty(p)\"\n (keydown.enter)=\"selectPropertyOnKeydown($event, p)\"\n (keydown.space)=\"selectPropertyOnKeydown($event, p)\"\n >\n <div class=\"label\">{{ p.label }}</div>\n <button\n mat-icon-button\n (click)=\"removeProperty($event)\"\n (keydown.enter)=\"removePropertyOnKeydown($event)\"\n (keydown.space)=\"removePropertyOnKeydown($event)\"\n >\n <mat-icon aria-hidden=\"true\" [attr.inert]=\"true\">close</mat-icon>\n </button>\n </li>\n }\n</ul>\n", styles: [":host{display:flex;flex-flow:column;max-height:100%}:host .filter{flex:0 0 auto}:host .filter .filter-input{background-color:var(--ymt-surface-panel);border:1px solid var(--ymt-outline-variant);display:flex;padding:.25em;align-items:center}:host .filter .filter-input input{background-color:transparent;border:0;outline:0;flex:1;color:var(--ymt-text-color)}:host .properties{flex:1;column-count:3;column-width:30ch;column-rule:1px dotted var(--ymt-outline);column-gap:2em;margin-block-start:var(--ymt-spacing-m)}:host .properties li{border:1px solid var(--ymt-outline-variant);border-radius:0;margin-block-end:1px;display:flex;align-items:center;justify-content:space-between;cursor:default}:host .properties li:hover{background-color:var(--ymt-hover-background)}:host .properties li.baseProperty{font-style:italic}:host .properties li.selected{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host .properties li:not(.selected) button{display:none}:host .properties li .label{padding:var(--ymt-spacing-xs) var(--ymt-spacing-m)}:host .properties li button{color:currentColor}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] }); }
785
674
  }
786
675
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: PropertySelectComponent, decorators: [{
787
676
  type: Component,
@@ -839,7 +728,7 @@ class TileConfigTileComponent {
839
728
  });
840
729
  }
841
730
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TileConfigTileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
842
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TileConfigTileComponent, isStandalone: true, selector: "yuv-tile-config-tile", inputs: { disableIconSlot: { classPropertyName: "disableIconSlot", publicName: "disableIconSlot", isSignal: true, isRequired: false, transformFunction: null }, disableBadgesSlot: { classPropertyName: "disableBadgesSlot", publicName: "disableBadgesSlot", isSignal: true, isRequired: false, transformFunction: null }, objectConfig: { classPropertyName: "objectConfig", publicName: "objectConfig", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { slotSelect: "slotSelect" }, ngImport: i0, template: "@let oc = _objectConfig();\n\n<div\n data-slot=\"icon\"\n [attr.disabled]=\"disableIconSlot()\"\n tabindex=\"0\"\n (click)=\"selectSlot('icon')\"\n (keydown.enter)=\"selectSlot('icon')\"\n (keydown.space)=\"selectSlot('icon'); $event.preventDefault()\"\n>\n @if (oc && oc.icon) {\n <mat-icon aria-hidden=\"true\" [attr.inert]=\"true\">{{ oc.icon.svg }}</mat-icon>\n } @else if (oc && oc.objectTypeId) {\n <yuv-object-type-icon [objectTypeId]=\"oc.objectTypeId\"></yuv-object-type-icon>\n }\n</div>\n<div\n data-slot=\"title\"\n tabindex=\"0\"\n (click)=\"selectSlot('title')\"\n (keydown.enter)=\"selectSlot('title')\"\n (keydown.space)=\"selectSlot('title'); $event.preventDefault()\"\n>\n {{ oc?.title?.label }}\n</div>\n<div\n data-slot=\"actions\"\n tabindex=\"0\"\n (click)=\"selectSlot('actions')\"\n (keydown.enter)=\"selectSlot('actions')\"\n (keydown.space)=\"selectSlot('actions'); $event.preventDefault()\"\n>\n @for (a of actions(); track a.id) {\n <button mat-icon-button [matTooltip]=\"a.label\" [attr.inert]=\"true\" aria-hidden=\"true\">\n <mat-icon inert=\"true\" aria-hidden=\"true\">{{ a.icon }}</mat-icon>\n </button>\n }\n</div>\n<div\n data-slot=\"description\"\n tabindex=\"0\"\n (click)=\"selectSlot('description')\"\n (keydown.enter)=\"selectSlot('description')\"\n (keydown.space)=\"selectSlot('description'); $event.preventDefault()\"\n>\n {{ oc?.description?.label }}\n</div>\n<div\n data-slot=\"aside\"\n tabindex=\"0\"\n (click)=\"selectSlot('aside')\"\n (keydown.enter)=\"selectSlot('aside')\"\n (keydown.space)=\"selectSlot('aside'); $event.preventDefault()\"\n>\n {{ oc?.aside?.label }}\n</div>\n<div\n data-slot=\"meta\"\n tabindex=\"0\"\n (click)=\"selectSlot('meta')\"\n (keydown.enter)=\"selectSlot('meta')\"\n (keydown.space)=\"selectSlot('meta'); $event.preventDefault()\"\n>\n {{ oc?.meta?.label }}\n</div>\n@if (!disableBadgesSlot()) {\n <div\n data-slot=\"badges\"\n tabindex=\"0\"\n (click)=\"selectSlot('badges')\"\n (keydown.enter)=\"selectSlot('badges')\"\n (keydown.space)=\"selectSlot('badges'); $event.preventDefault()\"\n >\n {{ oc?.badges }}\n </div>\n}\n", styles: [":host{--tile-item-gap: .5em;--tile-background: transparent;--tile-icon-fill: currentColor;display:grid;grid-template-rows:auto auto auto auto;grid-template-columns:3rem 1fr auto;grid-template-areas:\"icon title title actions\" \"icon description aside aside\" \"icon meta meta badges\";gap:var(--tile-item-gap);padding:var(--ymt-spacing-m);background-color:var(--tile-background)}:host:hover [data-slot=actions]{opacity:1}:host [data-slot=icon]{grid-area:icon;display:flex;align-items:center;justify-content:center}:host [data-slot=title]{grid-area:title;font-weight:700}:host [data-slot=description]{grid-area:description}:host [data-slot=meta]{grid-area:meta}:host [data-slot=aside]{flex:0 0 auto;grid-area:aside}:host [data-slot=actions]{flex:0 0 auto;display:flex;justify-self:end;grid-area:actions}:host [data-slot=actions] button{padding:0;gap:2px}:host [data-slot=badges]{grid-area:badges;justify-self:end;flex:0 0 auto}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]){display:flex;align-items:center;background-color:var(--ymt-surface-panel);border:1px solid var(--ymt-outline);padding:.25em .5em;box-sizing:border-box;min-height:2.2em;border-radius:var(--ymt-corner-xs)}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]):not([disabled]){cursor:pointer}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]):not([disabled]):hover{background-color:var(--ymt-focus-background);color:var(--ymt-on-focus-background)}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]):not([disabled]).active{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta])[disabled]{border:none;background-color:transparent}:host :where([data-slot=badges],[data-slot=actions]){min-width:3em}:host :where([data-slot=badges],[data-slot=actions]) button{width:24px;height:24px;pointer-events:none;color:currentColor}:host [data-slot=aside]{min-width:4em}:host [data-slot=icon]{height:3em;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectTypeIconComponent, selector: "yuv-object-type-icon", inputs: ["objectTypeId"] }] }); }
731
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TileConfigTileComponent, isStandalone: true, selector: "yuv-tile-config-tile", inputs: { disableIconSlot: { classPropertyName: "disableIconSlot", publicName: "disableIconSlot", isSignal: true, isRequired: false, transformFunction: null }, disableBadgesSlot: { classPropertyName: "disableBadgesSlot", publicName: "disableBadgesSlot", isSignal: true, isRequired: false, transformFunction: null }, objectConfig: { classPropertyName: "objectConfig", publicName: "objectConfig", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { slotSelect: "slotSelect" }, ngImport: i0, template: "@let oc = _objectConfig();\n\n<div\n data-slot=\"icon\"\n [attr.disabled]=\"disableIconSlot()\"\n tabindex=\"0\"\n (click)=\"selectSlot('icon')\"\n (keydown.enter)=\"selectSlot('icon')\"\n (keydown.space)=\"selectSlot('icon'); $event.preventDefault()\"\n>\n @if (oc && oc.icon) {\n <mat-icon aria-hidden=\"true\" [attr.inert]=\"true\">{{ oc.icon.svg }}</mat-icon>\n } @else if (oc && oc.objectTypeId) {\n <yuv-object-type-icon [objectTypeId]=\"oc.objectTypeId\"></yuv-object-type-icon>\n }\n</div>\n<div\n data-slot=\"title\"\n tabindex=\"0\"\n (click)=\"selectSlot('title')\"\n (keydown.enter)=\"selectSlot('title')\"\n (keydown.space)=\"selectSlot('title'); $event.preventDefault()\"\n>\n {{ oc?.title?.label }}\n</div>\n<div\n data-slot=\"actions\"\n tabindex=\"0\"\n (click)=\"selectSlot('actions')\"\n (keydown.enter)=\"selectSlot('actions')\"\n (keydown.space)=\"selectSlot('actions'); $event.preventDefault()\"\n>\n @for (a of actions(); track a.id) {\n <button mat-icon-button [matTooltip]=\"a.label\" [attr.inert]=\"true\" aria-hidden=\"true\">\n <mat-icon inert=\"true\" aria-hidden=\"true\">{{ a.icon }}</mat-icon>\n </button>\n }\n</div>\n<div\n data-slot=\"description\"\n tabindex=\"0\"\n (click)=\"selectSlot('description')\"\n (keydown.enter)=\"selectSlot('description')\"\n (keydown.space)=\"selectSlot('description'); $event.preventDefault()\"\n>\n {{ oc?.description?.label }}\n</div>\n<div\n data-slot=\"aside\"\n tabindex=\"0\"\n (click)=\"selectSlot('aside')\"\n (keydown.enter)=\"selectSlot('aside')\"\n (keydown.space)=\"selectSlot('aside'); $event.preventDefault()\"\n>\n {{ oc?.aside?.label }}\n</div>\n<div\n data-slot=\"meta\"\n tabindex=\"0\"\n (click)=\"selectSlot('meta')\"\n (keydown.enter)=\"selectSlot('meta')\"\n (keydown.space)=\"selectSlot('meta'); $event.preventDefault()\"\n>\n {{ oc?.meta?.label }}\n</div>\n@if (!disableBadgesSlot()) {\n <div\n data-slot=\"badges\"\n tabindex=\"0\"\n (click)=\"selectSlot('badges')\"\n (keydown.enter)=\"selectSlot('badges')\"\n (keydown.space)=\"selectSlot('badges'); $event.preventDefault()\"\n >\n {{ oc?.badges }}\n </div>\n}\n", styles: [":host{--tile-item-gap: .5em;--tile-background: transparent;--tile-icon-fill: currentColor;display:grid;grid-template-rows:auto auto auto auto;grid-template-columns:3rem 1fr auto;grid-template-areas:\"icon title title actions\" \"icon description aside aside\" \"icon meta meta badges\";gap:var(--tile-item-gap);padding:var(--ymt-spacing-m);background-color:var(--tile-background)}:host:hover [data-slot=actions]{opacity:1}:host [data-slot=icon]{grid-area:icon;display:flex;align-items:center;justify-content:center}:host [data-slot=title]{grid-area:title;font-weight:700}:host [data-slot=description]{grid-area:description}:host [data-slot=meta]{grid-area:meta}:host [data-slot=aside]{flex:0 0 auto;grid-area:aside}:host [data-slot=actions]{flex:0 0 auto;display:flex;justify-self:end;grid-area:actions}:host [data-slot=actions] button{padding:0;gap:2px}:host [data-slot=badges]{grid-area:badges;justify-self:end;flex:0 0 auto}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]){display:flex;align-items:center;background-color:var(--ymt-surface-panel);border:1px solid var(--ymt-outline);padding:.25em .5em;box-sizing:border-box;min-height:2.2em;border-radius:var(--ymt-corner-xs)}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]):not([disabled]){cursor:pointer}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]):not([disabled]):hover{background-color:var(--ymt-focus-background);color:var(--ymt-on-focus-background)}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta]):not([disabled]).active{background-color:var(--ymt-primary-container);color:var(--ymt-on-primary-container)}:host :where([data-slot=badges],[data-slot=actions],[data-slot=aside],[data-slot=icon],[data-slot=title],[data-slot=description],[data-slot=meta])[disabled]{border:none;background-color:transparent}:host :where([data-slot=badges],[data-slot=actions]){min-width:3em}:host :where([data-slot=badges],[data-slot=actions]) button{width:24px;height:24px;pointer-events:none;color:currentColor}:host [data-slot=aside]{min-width:4em}:host [data-slot=icon]{height:3em;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$2.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i2$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectTypeIconComponent, selector: "yuv-object-type-icon", inputs: ["objectTypeId"] }] }); }
843
732
  }
844
733
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TileConfigTileComponent, decorators: [{
845
734
  type: Component,