@yuuvis/client-framework 2.18.0 → 2.20.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 (40) hide show
  1. package/breadcrumb/index.d.ts +2 -0
  2. package/breadcrumb/lib/breadcrumb/breadcrumb.component.d.ts +94 -0
  3. package/breadcrumb/lib/models/breadcrumb-item.model.d.ts +14 -0
  4. package/breadcrumb/lib/models/index.d.ts +1 -0
  5. package/common/lib/components/confirm/confirm.component.d.ts +1 -0
  6. package/common/lib/components/confirm/confirm.interface.d.ts +2 -0
  7. package/fesm2022/yuuvis-client-framework-breadcrumb.mjs +117 -0
  8. package/fesm2022/yuuvis-client-framework-breadcrumb.mjs.map +1 -0
  9. package/fesm2022/yuuvis-client-framework-common.mjs +24 -10
  10. package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -1
  11. package/fesm2022/yuuvis-client-framework-forms.mjs +2 -2
  12. package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
  13. package/fesm2022/yuuvis-client-framework-list.mjs +365 -121
  14. package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -1
  15. package/fesm2022/yuuvis-client-framework-object-details.mjs +28 -26
  16. package/fesm2022/yuuvis-client-framework-object-details.mjs.map +1 -1
  17. package/fesm2022/yuuvis-client-framework-object-form.mjs.map +1 -1
  18. package/fesm2022/yuuvis-client-framework-object-relationship.mjs +6 -5
  19. package/fesm2022/yuuvis-client-framework-object-relationship.mjs.map +1 -1
  20. package/fesm2022/yuuvis-client-framework-object-versions.mjs +1 -1
  21. package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
  22. package/fesm2022/yuuvis-client-framework-query-list.mjs +462 -127
  23. package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -1
  24. package/fesm2022/yuuvis-client-framework-renderer.mjs +14 -16
  25. package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
  26. package/fesm2022/yuuvis-client-framework-sort.mjs +26 -15
  27. package/fesm2022/yuuvis-client-framework-sort.mjs.map +1 -1
  28. package/fesm2022/yuuvis-client-framework-tile-list.mjs +709 -182
  29. package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
  30. package/lib/assets/i18n/ar.json +217 -0
  31. package/lib/assets/i18n/de.json +7 -3
  32. package/lib/assets/i18n/en.json +7 -3
  33. package/list/lib/list.component.d.ts +256 -44
  34. package/object-details/lib/object-details-header/object-details-header.component.d.ts +5 -2
  35. package/object-details/lib/object-details-shell/object-details-shell.component.d.ts +5 -2
  36. package/object-details/lib/object-details.component.d.ts +3 -1
  37. package/object-relationship/lib/object-relationship.component.d.ts +5 -2
  38. package/package.json +8 -4
  39. package/query-list/lib/query-list.component.d.ts +381 -86
  40. package/tile-list/lib/tile-list/tile-list.component.d.ts +527 -72
@@ -1 +1 @@
1
- {"version":3,"file":"yuuvis-client-framework-list.mjs","sources":["../../../../../libs/yuuvis/client-framework/list/src/lib/list-item.directive.ts","../../../../../libs/yuuvis/client-framework/list/src/lib/list.component.ts","../../../../../libs/yuuvis/client-framework/list/src/lib/list-tile/list-tile.component.ts","../../../../../libs/yuuvis/client-framework/list/src/lib/list-tile/list-tile.component.html","../../../../../libs/yuuvis/client-framework/list/src/lib/list.module.ts","../../../../../libs/yuuvis/client-framework/list/src/yuuvis-client-framework-list.ts"],"sourcesContent":["import { Highlightable } from '@angular/cdk/a11y';\nimport { AfterViewInit, Directive, ElementRef, HostListener, inject, input, Input, linkedSignal } from '@angular/core';\nimport { Utils } from '@yuuvis/client-core';\n\n/**\n * Directive for list items. It is used in the `yuvList` component\n * to keep track of active and selected items. Every element with this\n * directive will be treated as a list item and can be selected and focused.\n * \n *```html\n * <yuv-list (itemSelect)=\"itemSelected($event)\">\n * <div yuvListItem>Entry #1</div>\n * <div yuvListItem>Entry #2</div>\n * </yuv-list>\n * ```\n */\n@Directive({\n selector: '[yuvListItem]',\n standalone: true,\n host: {\n '[attr.aria-current]': 'activeInput()',\n '[attr.aria-selected]': 'selectedInput()'\n }\n})\nexport class ListItemDirective implements Highlightable, AfterViewInit {\n #elRef = inject(ElementRef);\n\n onClick?: (evt: MouseEvent) => void;\n\n // TO SATISFY THE HIGHLIGHTABLE INTERFACE\n @Input() disabled?: boolean | undefined;\n\n /**\n * Whether the item is active or not. \n */\n active = input<boolean>(false);\n /**\n * Whether the item is selected or not. \n */\n selected = input<boolean>(false);\n\n selectedInput = linkedSignal({\n source: this.selected,\n computation: (newOptions: any, previous: any) => (newOptions !== previous ? newOptions : previous)\n });\n\n activeInput = linkedSignal({\n source: this.active,\n computation: (newOptions: any, previous: any) => (newOptions !== previous ? newOptions : previous)\n });\n\n focusableChildren: Element[] = [];\n focusedIndex = -1;\n\n @HostListener('click', ['$event']) onHostClick(evt: MouseEvent) {\n if (!this.disabled && this.onClick) {\n this.#elRef.nativeElement.parentElement.focus();\n this.onClick(evt);\n }\n }\n\n setActiveStyles(): void {\n this.activeInput.set(true);\n this.#scrollIntoView();\n }\n\n setInactiveStyles(): void {\n this.activeInput.set(false);\n }\n\n focusNext() {\n \n }\n\n focusPrevious() {\n }\n\n #scrollIntoView() {\n const el = this.#elRef.nativeElement as HTMLElement;\n const { bottom, top, left, right } = el.getBoundingClientRect();\n const containerRect = this.#elRef.nativeElement.parentElement.getBoundingClientRect();\n\n const offsetY =\n top <= containerRect.top\n ? containerRect.top - top > 0\n ? (containerRect.top - top) * -1\n : 0\n : bottom - containerRect.bottom > 0\n ? bottom - containerRect.bottom\n : 0;\n const offsetX =\n left <= containerRect.left\n ? containerRect.left - left > 0\n ? (containerRect.left - left) * -1\n : 0\n : right - containerRect.right > 0\n ? right - containerRect.right\n : 0;\n\n if (offsetX || offsetY) (this.#elRef.nativeElement.parentElement as HTMLElement).scrollBy(offsetX, offsetY);\n }\n\n ngAfterViewInit(): void {\n // get all focusable elements and set tabindex to -1\n this.focusableChildren = Utils.getFocusableChildren(this.#elRef.nativeElement);\n this.focusableChildren.forEach((el) => el.setAttribute('tabindex', '-1'));\n }\n}\n","import { A11yModule, ActiveDescendantKeyManager } from '@angular/cdk/a11y';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule } from '@angular/common';\nimport {\n Component,\n ElementRef,\n HostAttributeToken,\n OnDestroy,\n ViewEncapsulation,\n contentChildren,\n effect,\n inject,\n input,\n output,\n untracked\n} from '@angular/core';\nimport { ListItemDirective } from './list-item.directive';\n\n/**\n * Component rendering a simple list of items. It supports keyboard\n * navigation and takes care of accessibility. To create a list just wrap\n * `yuvListItem` elements into this component:\n *\n * ```html\n * <yuv-list (itemSelect)=\"itemSelected($event)\">\n * <div yuvListItem>Entry #1</div>\n * <div yuvListItem>Entry #2</div>\n * </yuv-list>\n * ```\n */\n@Component({\n selector: 'yuv-list',\n standalone: true,\n imports: [CommonModule, A11yModule],\n template: '<ng-content></ng-content>',\n styleUrl: './list.component.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'listbox',\n tabindex: '0',\n '[class.self-handle-selection]': 'selfHandleSelection()',\n '(focus)': 'onFocus()',\n '(keydown)': 'onKeydown($event)'\n }\n})\nexport class ListComponent implements OnDestroy {\n #dir = inject(Directionality);\n #elRef = inject(ElementRef);\n\n protected onKeydown(event: KeyboardEvent) {\n if (this.disableSelection()) return;\n if (event.code === 'Escape') {\n this.clear();\n }\n\n if (event.code === 'Space' || (this.selectOnEnter && event.code === 'Enter')) {\n // prevent default behavior of space in scroll environments\n if (this.#preventEmit()) return;\n event.preventDefault();\n const aii: number = this.#keyManager.activeItemIndex !== null ? this.#keyManager.activeItemIndex : -1;\n if (aii >= 0) {\n this.#select(aii);\n this.#emitSelection();\n }\n } else this.#keyManager?.onKeydown(event);\n }\n\n protected onFocus() {\n // set timeout to check if the focus is coming from an item being clicked\n setTimeout(() => {\n // if there already is an active item, we do not want to set the focus again\n if (this.#keyManager.activeItemIndex === -1 && this.items().length > 0) {\n const indexToFocus = this.#selection.length > 0 ? this.#selection[0] : 0;\n this.#keyManager.setActiveItem(indexToFocus);\n this.itemFocus.emit(indexToFocus);\n this.#updateActiveItemState();\n }\n }, 300);\n }\n\n items = contentChildren(ListItemDirective);\n #itemsEffect = effect(() => {\n const items = this.items();\n if (this.#keyManager) this.#keyManager.destroy();\n untracked(() => {\n this.#keyManager = this.horizontal\n ? new ActiveDescendantKeyManager(items).withWrap().withHorizontalOrientation(this.#dir.value)\n : new ActiveDescendantKeyManager(items).withWrap();\n\n this.#keyManager.change.subscribe((activeIndex) => {\n if (activeIndex !== null) {\n this.#updateActiveItemState();\n this.itemFocus.emit(activeIndex);\n }\n });\n\n if (!this.selfHandleClick()) {\n items.forEach((item, index) => {\n item.onClick = (evt: MouseEvent) => {\n this.select(index, evt.shiftKey, evt.ctrlKey);\n };\n item.activeInput.set(false);\n });\n }\n if (this.#lastSelection !== undefined && this.#lastSelection <= items.length) {\n this.select(this.#lastSelection);\n }\n this.#preselectItem();\n });\n });\n\n #keyManager!: ActiveDescendantKeyManager<ListItemDirective>;\n #selection: number[] = [];\n #lastSelection?: number;\n\n /**\n * Function that returns `true` if selection changes should be prevented.\n * This can be used to temporarily block selection changes, e.g. while\n * there is a pending change inside another component that refers to the\n * current selection.\n */\n preventChangeUntil = input<() => boolean>(() => false);\n /**\n * If `true`, multiple items can be selected at once.\n * @default false\n */\n multiselect = input<boolean>(false);\n /**\n * If `true`, the component will handle selection itself. This means that\n * the parent component will be responsible for styling the selected and\n * focused items. If `false`, the component will take care of visualizing\n * the selection and focus states.\n * @default false\n */\n selfHandleSelection = input<boolean>(false);\n /**\n * By default the list handles click events on its items to select them.\n * If this input is set to `true`, the parent component has to handle\n * click events itself and call the `select()` method accordingly.\n *\n * If you for example use the `ClickDoubleDirective` on the list items,\n * you have to set this input to `true` to prevent the list from\n * selecting items on single click.\n * @default false\n */\n selfHandleClick = input<boolean>(false);\n /**\n * If `true`, the list will select an item automatically on initialization.\n * First, list will search for an item item that has the \"selected\"-attribute\n * and is not disabled. If no such item exists, the first item will be selected.\n * @default false\n */\n autoSelect = input<boolean, BooleanInput>(false, { transform: (value: BooleanInput) => coerceBooleanProperty(value) });\n /**\n * Emits the selected items indices.\n */\n itemSelect = output<number[]>();\n /**\n * Emits the index of the item that has focus.\n * @type {output<number>}\n */\n itemFocus = output<number>();\n\n selectOnEnter: boolean = (inject(new HostAttributeToken('selectOnEnter'), { optional: true }) || 'false') === 'true';\n horizontal: boolean = (inject(new HostAttributeToken('horizontal'), { optional: true }) || 'false') === 'true';\n\n /**\n * If `true`, the list will not allow selection of items.\n * This is useful for lists that are used for display purposes only.\n */\n disableSelection = input<boolean>(false);\n\n /**\n * Sets the active (focused) item by index. This updates the visual focus\n * indicator and scrolls the item into view, without changing the selection.\n */\n setActiveItem(index: number): void {\n if (this.#keyManager) {\n this.#keyManager.setActiveItem(index);\n this.#select(index);\n this.focus();\n }\n }\n\n focus() {\n this.#elRef.nativeElement.focus();\n }\n\n scrollToTop() {\n this.#elRef.nativeElement.scrollTo({ top: 0, behavior: 'smooth' });\n }\n\n /**\n * Shift the current selection by the given offset. Used for dynamically\n * adding items to the list without losing the current selection.\n * @param offset Number of items to shift the selection by.\n */\n shiftSelectionBy(offset: number): void {\n if (this.#keyManager?.activeItemIndex) this.#keyManager.setActiveItem(this.#keyManager.activeItemIndex + offset);\n this.#selection = this.#selection.map((i) => i + offset);\n this.items().forEach((item: ListItemDirective, i: number) => item.selectedInput.set(this.#selection.includes(i)));\n }\n\n /**\n * Select multiple items by their indices.\n */\n multiSelect(index: number[]): void {\n if (this.#preventEmit()) return;\n if (!this.multiselect() || this.disableSelection()) return;\n this.#selection = index.filter((i) => i >= 0 && i < this.items().length);\n this.#selection.sort();\n\n this.items().forEach((item: ListItemDirective, i: number) => item.selectedInput.set(this.#selection.includes(i)));\n this.#emitSelection();\n }\n\n /**\n * Selects a single item by its index.\n * @param index Index of the item to select.\n * @param shiftKey If `true`, selection will be extended from the last selected item to the given index.\n * @param ctrlKey If `true`, the item at the given index will be toggled in the selection.\n */\n select(index: number, shiftKey = false, ctrlKey = false) {\n if (this.#preventEmit()) return;\n if (this.disableSelection() || index < 0) return;\n if (index >= this.items().length) index = this.items().length - 1;\n\n this.#select(index, shiftKey, ctrlKey);\n if (this.#keyManager) this.#keyManager.setActiveItem(index);\n this.#emitSelection();\n }\n\n #preventEmit() {\n const preventUntilIsTrue = this.preventChangeUntil();\n return preventUntilIsTrue();\n }\n\n /**\n * Clear the current selection.\n * @param silent If `true`, the `itemSelect` event will not be emitted.\n */\n clear(silent = false) {\n if (this.#preventEmit()) return;\n if (this.#selection.length !== 0) {\n this.#select(-1);\n this.#keyManager.setActiveItem(-1);\n if (!silent) this.#emitSelection();\n }\n }\n\n #select(index: number, shiftKey = false, ctrlKey = false) {\n if (index === -1) this.#selection = [];\n else {\n if (this.multiselect()) {\n this.#selection = this.#selection.filter((i) => i !== index);\n if (ctrlKey) {\n this.#selection.push(index);\n } else if (shiftKey) {\n if (this.#lastSelection) {\n for (let i = this.#lastSelection < index ? this.#lastSelection : index; i < (this.#lastSelection > index ? this.#lastSelection : index); i++) {\n this.#selection.push(i);\n }\n } else {\n this.#selection = [index];\n }\n } else {\n this.#selection = [index];\n }\n } else this.#selection = [index];\n }\n this.#lastSelection = this.#selection.length === 0 ? undefined : index;\n this.#selection.sort();\n\n this.items().forEach((item: ListItemDirective, i: number) => item.selectedInput.set(this.#selection.includes(i)));\n }\n\n #updateActiveItemState() {\n const activeIndex = this.#keyManager.activeItemIndex;\n this.items().forEach((item: ListItemDirective, i: number) => {\n item.activeInput.set(i === activeIndex);\n });\n }\n\n #emitSelection() {\n this.itemSelect.emit(this.#selection);\n }\n\n #preselectItem() {\n const items = this.items();\n const autoSelect = this.autoSelect();\n let itemIndexToSelect = -1;\n\n // If the list has no items, do nothing.\n if (items.length < 1) return;\n\n // Find the first item that has the \"selected\"-attribute and is not disabled\n itemIndexToSelect = items.findIndex((item) => item.selected() && !item.disabled);\n\n // If no valid item index is given, but autoSelect is true, select the first item\n if (itemIndexToSelect === -1 && autoSelect) {\n itemIndexToSelect = 0;\n }\n\n // If there is a valid item index, select that item, otherwise do nothing\n if (itemIndexToSelect !== -1) {\n this.select(itemIndexToSelect);\n }\n }\n\n ngOnDestroy(): void {\n this.#keyManager?.destroy();\n }\n}\n","import { Component, contentChild, TemplateRef, viewChild } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ListItemDirective } from '../list-item.directive';\n\n@Component({\n selector: 'yuv-list-tile',\n imports: [CommonModule],\n templateUrl: './list-tile.component.html',\n styleUrl: './list-tile.component.scss',\n // hostDirectives: [ListItemDirective]\n})\nexport class ListTileComponent {\n iconSlot = contentChild<TemplateRef<any>>('iconSlot', {\n descendants: true\n });\n titleSlot = contentChild<TemplateRef<any>>('titleSlot');\n descriptionSlot = contentChild<TemplateRef<any>>('descriptionSlot');\n asideSlot = contentChild<TemplateRef<any>>('asideSlot');\n actionsSlot = contentChild<TemplateRef<any>>('actionsSlot', {\n descendants: true\n });\n badgesSlot = contentChild<TemplateRef<any>>('badgesSlot');\n metaSlot = contentChild<TemplateRef<any>>('metaSlot');\n extensionSlot = contentChild<TemplateRef<any>>('extensionSlot');\n}\n","<ng-content></ng-content>\n<div class=\"tile\">\n <div data-slot=\"icon\">\n <ng-container *ngTemplateOutlet=\"iconSlot() || null\"></ng-container>\n </div>\n <div class=\"slots\"> \n <div data-slot=\"title-description\">\n <div data-slot=\"title\">\n <ng-container *ngTemplateOutlet=\"titleSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"description\">\n <ng-container *ngTemplateOutlet=\"descriptionSlot() || null\"></ng-container>\n </div>\n </div>\n <div data-slot=\"actions\">\n <ng-container *ngTemplateOutlet=\"actionsSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"aside\">\n <ng-container *ngTemplateOutlet=\"asideSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"meta\">\n <ng-container *ngTemplateOutlet=\"metaSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"badges\">\n <ng-container *ngTemplateOutlet=\"badgesSlot() || null\"></ng-container>\n </div>\n <div class=\"extension\">\n <ng-container *ngTemplateOutlet=\"extensionSlot() || null\"></ng-container>\n </div>\n </div>\n</div>\n","import { NgModule } from '@angular/core';\nimport { ListItemDirective } from './list-item.directive';\nimport { ListComponent } from './list.component';\nimport { ListTileComponent } from './list-tile/list-tile.component';\n\n@NgModule({\n imports: [ListComponent, ListItemDirective, ListTileComponent],\n exports: [ListComponent, ListItemDirective, ListTileComponent]\n})\nexport class YuvListModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"yuuvis-client-framework-list.mjs","sources":["../../../../../libs/yuuvis/client-framework/list/src/lib/list-item.directive.ts","../../../../../libs/yuuvis/client-framework/list/src/lib/list.component.ts","../../../../../libs/yuuvis/client-framework/list/src/lib/list-tile/list-tile.component.ts","../../../../../libs/yuuvis/client-framework/list/src/lib/list-tile/list-tile.component.html","../../../../../libs/yuuvis/client-framework/list/src/lib/list.module.ts","../../../../../libs/yuuvis/client-framework/list/src/yuuvis-client-framework-list.ts"],"sourcesContent":["import { Highlightable } from '@angular/cdk/a11y';\nimport { AfterViewInit, Directive, ElementRef, HostListener, inject, input, Input, linkedSignal } from '@angular/core';\nimport { Utils } from '@yuuvis/client-core';\n\n/**\n * Directive for list items. It is used in the `yuvList` component\n * to keep track of active and selected items. Every element with this\n * directive will be treated as a list item and can be selected and focused.\n * \n *```html\n * <yuv-list (itemSelect)=\"itemSelected($event)\">\n * <div yuvListItem>Entry #1</div>\n * <div yuvListItem>Entry #2</div>\n * </yuv-list>\n * ```\n */\n@Directive({\n selector: '[yuvListItem]',\n standalone: true,\n host: {\n '[attr.aria-current]': 'activeInput()',\n '[attr.aria-selected]': 'selectedInput()'\n }\n})\nexport class ListItemDirective implements Highlightable, AfterViewInit {\n #elRef = inject(ElementRef);\n\n onClick?: (evt: MouseEvent) => void;\n\n // TO SATISFY THE HIGHLIGHTABLE INTERFACE\n @Input() disabled?: boolean | undefined;\n\n /**\n * Whether the item is active or not. \n */\n active = input<boolean>(false);\n /**\n * Whether the item is selected or not. \n */\n selected = input<boolean>(false);\n\n selectedInput = linkedSignal({\n source: this.selected,\n computation: (newOptions: any, previous: any) => (newOptions !== previous ? newOptions : previous)\n });\n\n activeInput = linkedSignal({\n source: this.active,\n computation: (newOptions: any, previous: any) => (newOptions !== previous ? newOptions : previous)\n });\n\n focusableChildren: Element[] = [];\n focusedIndex = -1;\n\n @HostListener('click', ['$event']) onHostClick(evt: MouseEvent) {\n if (!this.disabled && this.onClick) {\n this.#elRef.nativeElement.parentElement.focus();\n this.onClick(evt);\n }\n }\n\n setActiveStyles(): void {\n this.activeInput.set(true);\n this.#scrollIntoView();\n }\n\n setInactiveStyles(): void {\n this.activeInput.set(false);\n }\n\n focusNext() {\n \n }\n\n focusPrevious() {\n }\n\n #scrollIntoView() {\n const el = this.#elRef.nativeElement as HTMLElement;\n const { bottom, top, left, right } = el.getBoundingClientRect();\n const containerRect = this.#elRef.nativeElement.parentElement.getBoundingClientRect();\n\n const offsetY =\n top <= containerRect.top\n ? containerRect.top - top > 0\n ? (containerRect.top - top) * -1\n : 0\n : bottom - containerRect.bottom > 0\n ? bottom - containerRect.bottom\n : 0;\n const offsetX =\n left <= containerRect.left\n ? containerRect.left - left > 0\n ? (containerRect.left - left) * -1\n : 0\n : right - containerRect.right > 0\n ? right - containerRect.right\n : 0;\n\n if (offsetX || offsetY) (this.#elRef.nativeElement.parentElement as HTMLElement).scrollBy(offsetX, offsetY);\n }\n\n ngAfterViewInit(): void {\n // get all focusable elements and set tabindex to -1\n this.focusableChildren = Utils.getFocusableChildren(this.#elRef.nativeElement);\n this.focusableChildren.forEach((el) => el.setAttribute('tabindex', '-1'));\n }\n}\n","import { A11yModule, ActiveDescendantKeyManager } from '@angular/cdk/a11y';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostAttributeToken,\n OnDestroy,\n ViewEncapsulation,\n contentChildren,\n effect,\n inject,\n input,\n output,\n untracked\n} from '@angular/core';\nimport { ListItemDirective } from './list-item.directive';\n\n/**\n * Accessible list component with keyboard navigation, single- and multi-selection,\n * and flexible delegation of click- and selection-handling to the parent.\n *\n * The component renders as an ARIA `listbox` and delegates keyboard focus tracking\n * to Angular CDK's `ActiveDescendantKeyManager`. Content is projected via\n * `[yuvListItem]`-attributed children (see `ListItemDirective`).\n *\n * **Key Features:**\n * - Single and multi-selection (with Shift / Ctrl modifier support)\n * - Full keyboard navigation (Arrow keys, Space, Enter, Escape)\n * - Horizontal and vertical layout via the `horizontal` host attribute\n * - Auto-selection on initialization via the `autoSelect` input\n * - Selection guarding via `preventChangeUntil` callback\n * - Optional delegation of click and selection handling to the parent component\n * - Accessible: `role=\"listbox\"`, active-descendant focus management, `aria-selected` on items\n *\n * **Basic usage:**\n * ```html\n * <yuv-list (itemSelect)=\"onItemSelect($event)\">\n * <div yuvListItem>Entry #1</div>\n * <div yuvListItem>Entry #2</div>\n * </yuv-list>\n * ```\n *\n * **Multi-selection with Shift/Ctrl:**\n * ```html\n * <yuv-list [multiselect]=\"true\" (itemSelect)=\"onSelect($event)\">\n * @for (item of items; track item.id) {\n * <div yuvListItem>{{ item.label }}</div>\n * }\n * </yuv-list>\n * ```\n *\n * **Host Attributes (set declaratively in the template):**\n * - `selectOnEnter` — treat the Enter key as a selection trigger (in addition to Space)\n * - `horizontal` — switch key navigation to left/right arrows instead of up/down\n *\n * @example\n * ```html\n * <!-- Horizontal list, Enter key selects -->\n * <yuv-list horizontal selectOnEnter (itemSelect)=\"onSelect($event)\">\n * <button yuvListItem>A</button>\n * <button yuvListItem>B</button>\n * </yuv-list>\n * ```\n */\n@Component({\n selector: 'yuv-list',\n standalone: true,\n imports: [CommonModule, A11yModule],\n template: '<ng-content />',\n styleUrl: './list.component.scss',\n encapsulation: ViewEncapsulation.None,\n host: {\n role: 'listbox',\n tabindex: '0',\n '[class.self-handle-selection]': 'selfHandleSelection()',\n '(focus)': 'onFocus()',\n '(keydown)': 'onKeydown($event)'\n },\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ListComponent implements OnDestroy {\n //#region Dependencies\n\n #dir = inject(Directionality);\n #elRef = inject(ElementRef);\n\n //#endregion\n\n //#region Angular Stuff\n\n /**\n * All `[yuvListItem]` children projected into this list.\n *\n * Queried reactively via `contentChildren` — every time the projected content\n * changes (items added, removed, or reordered), the `#itemsEffect` re-runs,\n * rebuilds the key manager, and re-attaches click handlers.\n */\n items = contentChildren(ListItemDirective);\n /**\n * Guard function that temporarily blocks all selection changes.\n *\n * Provide a factory that returns a predicate; as long as that predicate\n * returns `true`, any attempt to change the selection (via click, keyboard,\n * or programmatic API) is silently ignored. Useful when the parent has\n * unsaved changes tied to the current selection and needs to prevent the user\n * from accidentally navigating away.\n *\n * @example\n * ```ts\n * // Block selection while a save is in progress\n * preventChangeUntil = () => () => this.isSaving();\n * ```\n *\n * @default () => false (never prevents)\n */\n preventChangeUntil = input<() => boolean>(() => false);\n /**\n * Enables multi-selection mode.\n *\n * When `true`, the user can hold **Shift** to range-select items between the last\n * selected item and the clicked one, or hold **Ctrl** to toggle individual items\n * in and out of the selection. The programmatic `multiSelect()` method is also\n * only effective when this input is `true`.\n *\n * @default false\n */\n multiselect = input<boolean>(false);\n /**\n * Delegates visual selection and focus state rendering to the parent component.\n *\n * When `false` (default), `yuv-list` applies `.selected` and `.active` CSS classes\n * to items via `ListItemDirective` signals, so the list stylesheet controls the look.\n * When `true`, those signals are still updated but the host gets the\n * `self-handle-selection` CSS class, which the parent can use to opt into its own\n * visual treatment — useful when item templates have custom selected/focused styling.\n *\n * @default false\n */\n selfHandleSelection = input<boolean>(false);\n /**\n * Disables the built-in click-to-select behavior, letting the parent component\n * decide when `select()` is called.\n *\n * By default the list attaches an `onClick` handler to every `ListItemDirective`\n * that calls `select()` with the correct Shift/Ctrl modifier flags. Set this\n * input to `true` to suppress that wiring — the parent must then call `select()`\n * imperatively in response to whatever interaction it chooses (e.g. a single-click\n * that is distinguished from a double-click by `ClickDoubleDirective`).\n *\n * @default false\n */\n selfHandleClick = input<boolean>(false);\n /**\n * Automatically selects an item when the list is first rendered.\n *\n * The selection logic runs once per content-children change (see `#itemsEffect`)\n * and follows this priority order:\n * 1. The first non-disabled item that already carries the `selected` attribute.\n * 2. If no such item exists and `autoSelect` is `true`, the item at index 0.\n *\n * Accepts any truthy string value in addition to a real boolean because the\n * input is also consumable as a plain HTML attribute (`<yuv-list autoSelect>`).\n *\n * @default false\n */\n autoSelect = input<boolean, BooleanInput>(false, {\n transform: (value: BooleanInput) => coerceBooleanProperty(value)\n });\n /**\n * Emits the current selection as an array of zero-based item indices whenever\n * the selection changes — via click, keyboard, or programmatic API calls.\n *\n * An empty array signals that the selection has been cleared.\n *\n * @example\n * ```ts\n * onItemSelect(indices: number[]): void {\n * this.selectedItems = indices.map(i => this.items[i]);\n * }\n * ```\n */\n itemSelect = output<number[]>();\n\n /**\n * Emits the zero-based index of the item that received keyboard focus\n * (i.e. the active descendant managed by `ActiveDescendantKeyManager`).\n *\n * Note that focus and selection are independent: navigating with arrow keys\n * moves focus without changing the selection until Space (or Enter when\n * `selectOnEnter` is set) is pressed.\n */\n itemFocus = output<number>();\n\n /**\n * Puts the list into a display-only mode where no item can be selected.\n *\n * When `true`, all selection paths are blocked: clicks, keyboard shortcuts\n * (`Space`, `Enter`, `Escape`), and programmatic calls to `select()`,\n * `multiSelect()`, and `clear()` are all no-ops. The list still renders\n * normally and keyboard navigation still moves the focus indicator.\n *\n * @default false\n */\n disableSelection = input<boolean>(false);\n\n //#endregion\n\n //#region Properties\n\n /**\n * When `true`, pressing **Enter** triggers item selection in addition to **Space**.\n *\n * Resolved once at construction time from the static `selectOnEnter` host attribute.\n * Useful in contexts where Enter has a conventional \"confirm\" meaning (e.g. search\n * result lists, command palettes).\n *\n * Set declaratively in the template: `<yuv-list selectOnEnter>`.\n */\n selectOnEnter: boolean = (inject(new HostAttributeToken('selectOnEnter'), { optional: true }) || 'false') === 'true';\n\n /**\n * When `true`, switches the `ActiveDescendantKeyManager` to horizontal mode so that\n * the **Left** / **Right** arrow keys navigate between items instead of **Up** / **Down**.\n *\n * Resolved once at construction time from the static `horizontal` host attribute.\n * The text direction of the document is respected automatically (RTL-aware via CDK\n * `Directionality`).\n *\n * Set declaratively in the template: `<yuv-list horizontal>`.\n */\n horizontal: boolean = (inject(new HostAttributeToken('horizontal'), { optional: true }) || 'false') === 'true';\n\n #keyManager!: ActiveDescendantKeyManager<ListItemDirective>;\n #selection: number[] = [];\n #lastSelection?: number;\n\n //#endregion\n\n //#region Lifecycle Hooks\n\n constructor() {\n effect(this.#itemsEffect);\n }\n\n ngOnDestroy(): void {\n this.#keyManager.destroy();\n }\n\n //#endregion\n\n //#region Public\n\n /**\n * Moves keyboard focus to the item at the given index and selects it.\n *\n * Combines three operations in one call: updating the CDK key manager's active\n * descendant (which drives the ARIA active-descendant attribute and the visual focus ring),\n * selecting the item, and transferring DOM focus to the list host element so that\n * subsequent keyboard events are processed correctly.\n *\n * Safe to call before the key manager is initialized — the guard at the top of\n * the method prevents errors during early lifecycle phases.\n *\n * @param index Zero-based index of the item to activate.\n */\n setActiveItem(index: number): void {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.#keyManager) {\n this.#keyManager.setActiveItem(index);\n this.#select(index);\n this.focus();\n }\n }\n\n /**\n * Transfers DOM focus to the list host element.\n *\n * Calling this ensures that subsequent keyboard events (arrow keys, Space, etc.)\n * are routed to the list's `(keydown)` handler. Called internally by\n * `setActiveItem()`, but also useful from the parent when programmatic focus\n * management is needed (e.g. after closing a dialog that was triggered from a\n * list item).\n */\n focus(): void {\n this.#elRef.nativeElement.focus();\n }\n\n /**\n * Smoothly scrolls the list container back to the top.\n *\n * Useful after programmatically refreshing the list contents when the user may\n * have scrolled far down and the new result set should be shown from the beginning.\n */\n scrollToTop(): void {\n this.#elRef.nativeElement.scrollTo({ top: 0, behavior: 'smooth' });\n }\n\n /**\n * Shifts all selected and focused item indices by the given offset.\n *\n * Use this when items are prepended or inserted at the beginning of the list so\n * that the existing selection and keyboard-focus position stay attached to the\n * same logical items after the index space shifts. A positive offset moves\n * indices forward (items were inserted before the selection); a negative offset\n * moves them backward (items were removed before the selection).\n *\n * Does **not** emit `itemSelect` — the selection indices change structurally,\n * not because the user chose different items.\n *\n * @param offset Number of positions to shift every selected index by.\n */\n shiftSelectionBy(offset: number): void {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.#keyManager?.activeItemIndex !== null && this.#keyManager?.activeItemIndex !== undefined) {\n this.#keyManager.setActiveItem(this.#keyManager.activeItemIndex + offset);\n }\n this.#selection = this.#selection.map((i) => i + offset);\n if (this.#lastSelection !== undefined) this.#lastSelection += offset;\n this.items().forEach((item: ListItemDirective, i: number) => item.selectedInput.set(this.#selection.includes(i)));\n }\n\n /**\n * Programmatically replaces the entire selection with the given indices.\n *\n * Only effective when `multiselect` is `true` and `disableSelection` is `false`.\n * Out-of-range indices are silently discarded. The resulting selection is sorted\n * ascending before being applied and emitted.\n *\n * Use this when the parent needs to restore a previously saved multi-selection\n * state, e.g. after navigation or on component re-initialization.\n *\n * @param index Array of zero-based item indices to select.\n */\n multiSelect(index: number[]): void {\n if (this.#preventEmit()) return;\n if (!this.multiselect() || this.disableSelection()) return;\n this.#selection = index.filter((i) => i >= 0 && i < this.items().length);\n this.#selection.sort();\n\n this.items().forEach((item: ListItemDirective, i: number) => item.selectedInput.set(this.#selection.includes(i)));\n this.#emitSelection();\n }\n\n /**\n * Selects the item at the given index, optionally extending or toggling\n * the existing selection using modifier-key semantics.\n *\n * - **No modifiers** (default): replaces the current selection with the single item.\n * - **`shiftKey = true`** (`multiselect` only): range-selects all items between the\n * last selected index and `index` (inclusive of neither endpoint, matching typical\n * OS list behavior).\n * - **`ctrlKey = true`** (`multiselect` only): toggles `index` in the selection\n * without affecting the rest.\n *\n * Index is clamped to `[0, items.length - 1]`. Negative values and calls while\n * `disableSelection` is `true` are ignored. The `preventChangeUntil` guard is\n * also respected.\n *\n * Emits `itemSelect` after updating the visual state.\n *\n * @param index Zero-based index of the item to select.\n * @param shiftKey Extend the selection from the last selected item to `index`.\n * @param ctrlKey Toggle `index` in or out of the current selection.\n */\n select(index: number, shiftKey = false, ctrlKey = false): void {\n if (this.#preventEmit()) return;\n if (this.disableSelection() || index < 0) return;\n if (index >= this.items().length) index = this.items().length - 1;\n\n this.#select(index, shiftKey, ctrlKey);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.#keyManager) this.#keyManager.setActiveItem(index);\n this.#emitSelection();\n }\n\n /**\n * Clears the current selection and resets the active keyboard-focus index.\n *\n * If the selection is already empty, the method is a no-op (no event emitted,\n * no state update). The `preventChangeUntil` guard is respected — if the guard\n * returns `true`, the clear is blocked entirely.\n *\n * Also triggered internally when the user presses **Escape**.\n *\n * @param silent When `true`, skips emitting `itemSelect` after clearing. Use this\n * when the parent needs to reset state programmatically without\n * triggering downstream reactions.\n */\n clear(silent = false): void {\n if (this.#preventEmit()) return;\n if (this.#selection.length !== 0) {\n this.#select(-1);\n this.#keyManager.setActiveItem(-1);\n if (!silent) this.#emitSelection();\n }\n }\n\n //#endregion\n\n //#region UI Methods\n\n /**\n * Host `keydown` handler — routes keyboard events to selection or navigation logic.\n *\n * Handled keys:\n * - **Escape**: clears the selection.\n * - **Space** (always) / **Enter** (when `selectOnEnter` is set): selects the\n * currently focused item. `preventDefault()` is called to stop the browser\n * from scrolling the container when Space is pressed.\n * - **All other keys**: forwarded to `ActiveDescendantKeyManager` so arrow keys,\n * Home, End, etc. move the focus indicator without changing the selection.\n *\n * When `disableSelection` is `true`, only navigation keys are forwarded to the\n * key manager — selection keys (Space, Enter, Escape) are suppressed.\n *\n * Bound via the `host` metadata as `(keydown)`.\n *\n * @param event The keyboard event originating from the list host element.\n */\n protected onKeydown(event: KeyboardEvent): void {\n if (this.disableSelection()) {\n this.#keyManager?.onKeydown(event);\n return;\n }\n if (event.code === 'Escape') {\n this.clear();\n }\n\n if (event.code === 'Space' || (this.selectOnEnter && event.code === 'Enter')) {\n // prevent default behavior of space in scroll environments\n if (this.#preventEmit()) return;\n event.preventDefault();\n const aii: number = this.#keyManager.activeItemIndex !== null ? this.#keyManager.activeItemIndex : -1;\n if (aii >= 0) {\n this.#select(aii);\n this.#emitSelection();\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n } else this.#keyManager?.onKeydown(event);\n }\n\n /**\n * Host `focus` handler — restores a sensible focus position when the list\n * host element receives DOM focus without an item already being active.\n *\n * The logic runs inside a 300 ms timeout so that focus events triggered by\n * an item being clicked (which also bubbles a focus event up to the host)\n * have already resolved their own active-item state before this handler acts.\n * If an active item already exists when the timeout fires, nothing happens.\n *\n * Focus target priority:\n * 1. The first index in the current selection (so the user lands back on the\n * previously selected item when tabbing into the list).\n * 2. Index 0 as the fallback when there is no selection.\n *\n * Bound via the `host` metadata as `(focus)`.\n */\n protected onFocus(): void {\n // set timeout to check if the focus is coming from an item being clicked\n setTimeout(() => {\n // if there already is an active item, we do not want to set the focus again\n if (this.#keyManager.activeItemIndex === -1 && this.items().length > 0) {\n const indexToFocus = this.#selection.length > 0 ? this.#selection[0] : 0;\n this.#keyManager.setActiveItem(indexToFocus);\n this.itemFocus.emit(indexToFocus);\n this.#updateActiveItemState();\n }\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\n }, 300);\n }\n\n //#endregion\n\n //#region Utilities\n\n #preventEmit(): boolean {\n const preventUntilIsTrue = this.preventChangeUntil();\n return preventUntilIsTrue();\n }\n\n #select(index: number, shiftKey = false, ctrlKey = false): void {\n if (index === -1) this.#selection = [];\n else {\n if (this.multiselect()) {\n this.#selection = this.#selection.filter((i) => i !== index);\n if (ctrlKey) {\n this.#selection.push(index);\n } else if (shiftKey) {\n if (this.#lastSelection) {\n for (\n let i = this.#lastSelection < index ? this.#lastSelection : index;\n i < (this.#lastSelection > index ? this.#lastSelection : index);\n i++\n ) {\n this.#selection.push(i);\n }\n } else {\n this.#selection = [index];\n }\n } else {\n this.#selection = [index];\n }\n } else this.#selection = [index];\n }\n this.#lastSelection = this.#selection.length === 0 ? undefined : index;\n this.#selection.sort();\n\n this.items().forEach((item: ListItemDirective, i: number) => item.selectedInput.set(this.#selection.includes(i)));\n }\n\n #updateActiveItemState(): void {\n const activeIndex = this.#keyManager.activeItemIndex;\n this.items().forEach((item: ListItemDirective, i: number) => {\n item.activeInput.set(i === activeIndex);\n });\n }\n\n #emitSelection(): void {\n this.itemSelect.emit(this.#selection);\n }\n\n #preselectItem(): void {\n const items = this.items();\n const autoSelect = this.autoSelect();\n let itemIndexToSelect = -1;\n\n // If the list has no items, do nothing.\n if (items.length < 1) return;\n\n // Find the first item that has the \"selected\"-attribute and is not disabled\n itemIndexToSelect = items.findIndex((item) => item.selected() && !item.disabled);\n\n // If no valid item index is given, but autoSelect is true, select the first item\n if (itemIndexToSelect === -1 && autoSelect) {\n itemIndexToSelect = 0;\n }\n\n // If there is a valid item index, select that item, otherwise do nothing\n if (itemIndexToSelect !== -1) {\n this.select(itemIndexToSelect);\n }\n }\n\n //#endregion\n\n //#region Effects\n\n readonly #itemsEffect = (): void => {\n const items = this.items();\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (this.#keyManager) this.#keyManager.destroy();\n untracked(() => {\n this.#keyManager = this.horizontal\n ? new ActiveDescendantKeyManager(items).withWrap().withHorizontalOrientation(this.#dir.value)\n : new ActiveDescendantKeyManager(items).withWrap();\n\n this.#keyManager.change.subscribe((activeIndex) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (activeIndex !== null) {\n this.#updateActiveItemState();\n this.itemFocus.emit(activeIndex);\n }\n });\n\n if (!this.selfHandleClick()) {\n items.forEach((item, index) => {\n item.onClick = (evt: MouseEvent): void => {\n this.select(index, evt.shiftKey, evt.ctrlKey);\n };\n item.activeInput.set(false);\n });\n }\n if (this.#lastSelection !== undefined && this.#lastSelection <= items.length) {\n this.select(this.#lastSelection);\n }\n this.#preselectItem();\n });\n };\n\n //#endregion\n}\n","import { Component, contentChild, TemplateRef, viewChild } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ListItemDirective } from '../list-item.directive';\n\n@Component({\n selector: 'yuv-list-tile',\n imports: [CommonModule],\n templateUrl: './list-tile.component.html',\n styleUrl: './list-tile.component.scss',\n // hostDirectives: [ListItemDirective]\n})\nexport class ListTileComponent {\n iconSlot = contentChild<TemplateRef<any>>('iconSlot', {\n descendants: true\n });\n titleSlot = contentChild<TemplateRef<any>>('titleSlot');\n descriptionSlot = contentChild<TemplateRef<any>>('descriptionSlot');\n asideSlot = contentChild<TemplateRef<any>>('asideSlot');\n actionsSlot = contentChild<TemplateRef<any>>('actionsSlot', {\n descendants: true\n });\n badgesSlot = contentChild<TemplateRef<any>>('badgesSlot');\n metaSlot = contentChild<TemplateRef<any>>('metaSlot');\n extensionSlot = contentChild<TemplateRef<any>>('extensionSlot');\n}\n","<ng-content></ng-content>\n<div class=\"tile\">\n <div data-slot=\"icon\">\n <ng-container *ngTemplateOutlet=\"iconSlot() || null\"></ng-container>\n </div>\n <div class=\"slots\"> \n <div data-slot=\"title-description\">\n <div data-slot=\"title\">\n <ng-container *ngTemplateOutlet=\"titleSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"description\">\n <ng-container *ngTemplateOutlet=\"descriptionSlot() || null\"></ng-container>\n </div>\n </div>\n <div data-slot=\"actions\">\n <ng-container *ngTemplateOutlet=\"actionsSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"aside\">\n <ng-container *ngTemplateOutlet=\"asideSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"meta\">\n <ng-container *ngTemplateOutlet=\"metaSlot() || null\"></ng-container>\n </div>\n <div data-slot=\"badges\">\n <ng-container *ngTemplateOutlet=\"badgesSlot() || null\"></ng-container>\n </div>\n <div class=\"extension\">\n <ng-container *ngTemplateOutlet=\"extensionSlot() || null\"></ng-container>\n </div>\n </div>\n</div>\n","import { NgModule } from '@angular/core';\nimport { ListItemDirective } from './list-item.directive';\nimport { ListComponent } from './list.component';\nimport { ListTileComponent } from './list-tile/list-tile.component';\n\n@NgModule({\n imports: [ListComponent, ListItemDirective, ListTileComponent],\n exports: [ListComponent, ListItemDirective, ListTileComponent]\n})\nexport class YuvListModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, input, computed, Component, signal, Injectable, effect, viewChild, linkedSignal, untracked, output, viewChildren, NgModule, Pipe } from '@angular/core';
2
+ import { inject, input, computed, ChangeDetectionStrategy, Component, signal, Injectable, effect, viewChild, linkedSignal, untracked, output, viewChildren, NgModule, Pipe } from '@angular/core';
3
3
  import * as i2 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import { takeUntilDestroyed, toSignal, rxResource } from '@angular/core/rxjs-interop';
@@ -53,24 +53,27 @@ class ObjectDetailsHeaderComponent {
53
53
  * Bucket of the object config to retrieve header data from
54
54
  */
55
55
  this.bucket = input(undefined);
56
+ /** Template rendered in the actions area, aligned to the right of the title row. */
56
57
  this.actions = input(undefined);
58
+ /** Template rendered in the badges area, aligned to the right of the subtitle row. */
59
+ this.badges = input();
57
60
  this.headerData = computed(() => {
58
- const o = this.dmsObject();
59
- const t = this.type();
60
- return o && t ? this.#setHeaderData() : undefined;
61
+ const object = this.dmsObject();
62
+ const type = this.type();
63
+ return object && type ? this.#setHeaderData() : undefined;
61
64
  });
62
65
  this.#eventService
63
66
  .on(YuvEventType.DMS_OBJECT_UPDATED)
64
67
  .pipe(takeUntilDestroyed())
65
- .subscribe((e) => this.#setHeaderData());
68
+ .subscribe(() => this.#setHeaderData());
66
69
  }
67
70
  #setHeaderData() {
68
- const o = this.dmsObject();
69
- if (!o) {
71
+ const object = this.dmsObject();
72
+ if (!object) {
70
73
  return undefined;
71
74
  }
72
75
  else {
73
- const roc = this.#objectConfig.getResolvedObjectConfig(o.data, this.type(), this.bucket());
76
+ const roc = this.#objectConfig.getResolvedObjectConfig(object.data, this.type(), this.bucket());
74
77
  return {
75
78
  title: roc.title,
76
79
  description: roc.description,
@@ -79,17 +82,11 @@ class ObjectDetailsHeaderComponent {
79
82
  }
80
83
  }
81
84
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ObjectDetailsHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
82
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ObjectDetailsHeaderComponent, isStandalone: true, selector: "yuv-object-details-header", inputs: { dmsObject: { classPropertyName: "dmsObject", publicName: "dmsObject", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let dmsObj = dmsObject();\n@let headerD = headerData();\n@if (dmsObj && headerD) {\n <ymt-pane-header [icon]=\"headerD.icon\" [actions]=\"actions()\">\n <ng-template #yuvPaneHeaderTitle>\n <ng-container *yuvRenderer=\"headerD.title\"></ng-container>\n </ng-template>\n <ng-template #yuvPaneHeaderSubtitle>\n <ng-container *yuvRenderer=\"headerD.description\"></ng-container>\n </ng-template>\n </ymt-pane-header>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i1.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions"] }, { kind: "directive", type: RendererDirective, selector: "[yuvRenderer]", inputs: ["yuvRenderer"] }] }); }
85
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ObjectDetailsHeaderComponent, isStandalone: true, selector: "yuv-object-details-header", inputs: { dmsObject: { classPropertyName: "dmsObject", publicName: "dmsObject", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, badges: { classPropertyName: "badges", publicName: "badges", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let dmsObj = dmsObject();\n@let headerD = headerData();\n@if (dmsObj && headerD) {\n <ymt-pane-header [icon]=\"headerD.icon\" [actions]=\"actions()\" [badges]=\"badges()\">\n <ng-template #yuvPaneHeaderTitle>\n <ng-container *yuvRenderer=\"headerD.title\" />\n </ng-template>\n <ng-template #yuvPaneHeaderSubtitle>\n <ng-container *yuvRenderer=\"headerD.description\" />\n </ng-template>\n </ymt-pane-header>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: YmtPanesModule }, { kind: "component", type: i1.YmtPaneHeaderComponent, selector: "ymt-pane-header", inputs: ["title", "icon", "subtitle", "actions", "badges"] }, { kind: "directive", type: RendererDirective, selector: "[yuvRenderer]", inputs: ["yuvRenderer"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
83
86
  }
84
87
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ObjectDetailsHeaderComponent, decorators: [{
85
88
  type: Component,
86
- args: [{ selector: 'yuv-object-details-header', imports: [
87
- CommonModule,
88
- MatIconModule,
89
- YmtPanesModule,
90
- RendererDirective
91
- // RetentionBadgeComponent
92
- ], template: "@let dmsObj = dmsObject();\n@let headerD = headerData();\n@if (dmsObj && headerD) {\n <ymt-pane-header [icon]=\"headerD.icon\" [actions]=\"actions()\">\n <ng-template #yuvPaneHeaderTitle>\n <ng-container *yuvRenderer=\"headerD.title\"></ng-container>\n </ng-template>\n <ng-template #yuvPaneHeaderSubtitle>\n <ng-container *yuvRenderer=\"headerD.description\"></ng-container>\n </ng-template>\n </ymt-pane-header>\n}\n" }]
89
+ args: [{ selector: 'yuv-object-details-header', imports: [CommonModule, MatIconModule, YmtPanesModule, RendererDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let dmsObj = dmsObject();\n@let headerD = headerData();\n@if (dmsObj && headerD) {\n <ymt-pane-header [icon]=\"headerD.icon\" [actions]=\"actions()\" [badges]=\"badges()\">\n <ng-template #yuvPaneHeaderTitle>\n <ng-container *yuvRenderer=\"headerD.title\" />\n </ng-template>\n <ng-template #yuvPaneHeaderSubtitle>\n <ng-container *yuvRenderer=\"headerD.description\" />\n </ng-template>\n </ymt-pane-header>\n}\n" }]
93
90
  }], ctorParameters: () => [] });
94
91
 
95
92
  class ObjectDetailsShellService {
@@ -143,7 +140,10 @@ class ObjectDetailsShellComponent {
143
140
  this.contextError = this.#odShellService.contextError;
144
141
  this.dmsObject = this.#odShellService.dmsObject;
145
142
  this.busy = this.#odShellService.busy;
143
+ /** Template rendered in the actions area, aligned to the right of the title row. */
146
144
  this.actions = input(undefined);
145
+ /** Template rendered in the badges area, aligned to the right of the subtitle row. */
146
+ this.badges = input();
147
147
  /**
148
148
  * Virtual object type to use for retrieving header data
149
149
  */
@@ -159,17 +159,17 @@ class ObjectDetailsShellComponent {
159
159
  this.#eventService
160
160
  .on(YuvEventType.DMS_OBJECT_UPDATED, YuvEventType.DMS_OBJECT_DELETED)
161
161
  .pipe(takeUntilDestroyed())
162
- .subscribe((e) => {
163
- switch (e.type) {
162
+ .subscribe((evt) => {
163
+ switch (evt.type) {
164
164
  case YuvEventType.DMS_OBJECT_UPDATED: {
165
- const o = e.data;
165
+ const obj = evt.data;
166
166
  const dmsObj = this.dmsObject();
167
- if (dmsObj && dmsObj.id === o.id)
168
- this.#odShellService.setDmsObject(o);
167
+ if (dmsObj?.id === obj.id)
168
+ this.#odShellService.setDmsObject(obj);
169
169
  break;
170
170
  }
171
171
  case YuvEventType.DMS_OBJECT_DELETED: {
172
- if (e.data?.id === this.dmsObject()?.id) {
172
+ if (evt.data?.id === this.dmsObject()?.id) {
173
173
  this.#odShellService.setDmsObject(undefined);
174
174
  }
175
175
  }
@@ -177,11 +177,11 @@ class ObjectDetailsShellComponent {
177
177
  });
178
178
  }
179
179
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ObjectDetailsShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
180
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ObjectDetailsShellComponent, isStandalone: true, selector: "yuv-object-details-shell", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let dmsObj = dmsObject();\n@if (dmsObj) {\n @if (!hideHeader()) {\n <yuv-object-details-header [dmsObject]=\"dmsObj\" [type]=\"type()\" [bucket]=\"bucket()\" [actions]=\"actions()\"></yuv-object-details-header>\n }\n <div class=\"content\" [yuvBusyOverlay]=\"busy()\">\n <ng-content></ng-content>\n </div>\n} @else {\n <div class=\"empty\">\n @if (contextError()) {\n <div class=\"error\">{{ contextError() }}</div>\n } @else {\n <!-- EMPTY -->\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;position:relative;background-color:var(--ymt-surface)}:host .content{flex:1;overflow:hidden}:host .empty{height:100%;display:grid;align-items:center;justify-content:center}:host .empty .error{max-width:40ch;margin:var(--ymt-spacing-m);color:var(--ymt-text-color-subtle);padding:var(--ymt-spacing-s);border-radius:.5em;line-height:1.5em;border:1px solid var(--ymt-outline-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectDetailsHeaderComponent, selector: "yuv-object-details-header", inputs: ["dmsObject", "type", "bucket", "actions"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay", "yuvBusyOverlayConfig", "yuvBusyError"], outputs: ["yuvBusyErrorDismiss"] }] }); }
180
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ObjectDetailsShellComponent, isStandalone: true, selector: "yuv-object-details-shell", inputs: { actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, badges: { classPropertyName: "badges", publicName: "badges", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, bucket: { classPropertyName: "bucket", publicName: "bucket", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let dmsObj = dmsObject();\n@if (dmsObj) {\n @if (!hideHeader()) {\n <yuv-object-details-header\n [dmsObject]=\"dmsObj\"\n [type]=\"type()\"\n [bucket]=\"bucket()\"\n [badges]=\"badges()\"\n [actions]=\"actions()\"\n />\n }\n <div class=\"content\" [yuvBusyOverlay]=\"busy()\">\n <ng-content />\n </div>\n} @else {\n <div class=\"empty\">\n @if (contextError()) {\n <div class=\"error\">{{ contextError() }}</div>\n } @else {\n <!-- EMPTY -->\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;position:relative;background-color:var(--ymt-surface)}:host .content{flex:1;overflow:hidden}:host .empty{height:100%;display:grid;align-items:center;justify-content:center}:host .empty .error{max-width:40ch;margin:var(--ymt-spacing-m);color:var(--ymt-text-color-subtle);padding:var(--ymt-spacing-s);border-radius:.5em;line-height:1.5em;border:1px solid var(--ymt-outline-variant)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ObjectDetailsHeaderComponent, selector: "yuv-object-details-header", inputs: ["dmsObject", "type", "bucket", "actions", "badges"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: BusyOverlayDirective, selector: "[yuvBusyOverlay]", inputs: ["yuvBusyOverlay", "yuvBusyOverlayConfig", "yuvBusyError"], outputs: ["yuvBusyErrorDismiss"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
181
181
  }
182
182
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ObjectDetailsShellComponent, decorators: [{
183
183
  type: Component,
184
- args: [{ selector: 'yuv-object-details-shell', standalone: true, imports: [CommonModule, ObjectDetailsHeaderComponent, MatTooltipModule, BusyOverlayDirective], template: "@let dmsObj = dmsObject();\n@if (dmsObj) {\n @if (!hideHeader()) {\n <yuv-object-details-header [dmsObject]=\"dmsObj\" [type]=\"type()\" [bucket]=\"bucket()\" [actions]=\"actions()\"></yuv-object-details-header>\n }\n <div class=\"content\" [yuvBusyOverlay]=\"busy()\">\n <ng-content></ng-content>\n </div>\n} @else {\n <div class=\"empty\">\n @if (contextError()) {\n <div class=\"error\">{{ contextError() }}</div>\n } @else {\n <!-- EMPTY -->\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;position:relative;background-color:var(--ymt-surface)}:host .content{flex:1;overflow:hidden}:host .empty{height:100%;display:grid;align-items:center;justify-content:center}:host .empty .error{max-width:40ch;margin:var(--ymt-spacing-m);color:var(--ymt-text-color-subtle);padding:var(--ymt-spacing-s);border-radius:.5em;line-height:1.5em;border:1px solid var(--ymt-outline-variant)}\n"] }]
184
+ args: [{ selector: 'yuv-object-details-shell', standalone: true, imports: [CommonModule, ObjectDetailsHeaderComponent, MatTooltipModule, BusyOverlayDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let dmsObj = dmsObject();\n@if (dmsObj) {\n @if (!hideHeader()) {\n <yuv-object-details-header\n [dmsObject]=\"dmsObj\"\n [type]=\"type()\"\n [bucket]=\"bucket()\"\n [badges]=\"badges()\"\n [actions]=\"actions()\"\n />\n }\n <div class=\"content\" [yuvBusyOverlay]=\"busy()\">\n <ng-content />\n </div>\n} @else {\n <div class=\"empty\">\n @if (contextError()) {\n <div class=\"error\">{{ contextError() }}</div>\n } @else {\n <!-- EMPTY -->\n }\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;position:relative;background-color:var(--ymt-surface)}:host .content{flex:1;overflow:hidden}:host .empty{height:100%;display:grid;align-items:center;justify-content:center}:host .empty .error{max-width:40ch;margin:var(--ymt-spacing-m);color:var(--ymt-text-color-subtle);padding:var(--ymt-spacing-s);border-radius:.5em;line-height:1.5em;border:1px solid var(--ymt-outline-variant)}\n"] }]
185
185
  }], ctorParameters: () => [] });
186
186
 
187
187
  class ObjectAuditComponent {
@@ -738,6 +738,8 @@ class ObjectDetailsComponent {
738
738
  */
739
739
  this.hideHeader = input(false);
740
740
  this.actions = input(undefined);
741
+ /** Template rendered in the badges area, aligned to the right of the subtitle row. */
742
+ this.badges = input();
741
743
  }
742
744
  #userService;
743
745
  #odShellService;
@@ -746,7 +748,7 @@ class ObjectDetailsComponent {
746
748
  this.#odShellService.setDmsObject(updatedObject);
747
749
  }
748
750
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ObjectDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
749
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ObjectDetailsComponent, isStandalone: true, selector: "yuv-object-details", inputs: { dmsObjectInput: { classPropertyName: "dmsObjectInput", publicName: "dmsObject", isSignal: true, isRequired: false, transformFunction: null }, flavors: { classPropertyName: "flavors", publicName: "flavors", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, objectConfigBucket: { classPropertyName: "objectConfigBucket", publicName: "objectConfigBucket", isSignal: true, isRequired: false, transformFunction: null }, objectId: { classPropertyName: "objectId", publicName: "objectId", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ObjectDetailsShellService], ngImport: i0, template: "<yuv-object-details-shell [type]=\"type()\" [hideHeader]=\"hideHeader()\" [bucket]=\"objectConfigBucket()\" [actions]=\"actions()\">\n @let dmsObj = dmsObject();\n <mat-tab-group yuvTabGuardDisable>\n <!-- content -->\n @if (dmsObj && dmsObj.content) {\n <mat-tab [label]=\"'yuv.object-details.tabs.content.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-preview [dmsObject]=\"dmsObj\"></yuv-object-preview>\n </ng-template>\n </mat-tab>\n }\n\n <!-- indexdata -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.indexdata.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-metadata [dmsObject]=\"dmsObject()\" [flavors]=\"flavors()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n </mat-tab>\n <!-- history -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.history.title' | translate\">\n <ng-template matTabContent> <yuv-object-audit [dmsObject]=\"dmsObj\"></yuv-object-audit> </ng-template\n ></mat-tab>\n </mat-tab-group>\n</yuv-object-details-shell>\n", styles: [":host{display:block;overflow:hidden}:host yuv-object-details-shell{height:100%}:host mat-tab-group{overflow:hidden;height:100%}:host mat-tab-group ::ng-deep .mat-mdc-tab-body-wrapper{height:100%}:host yuv-object-preview{background-color:var(--ymt-surface-container-low)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: TabGuardDirective, selector: "mat-tab-group[yuvTabGuardDisable]" }, { kind: "component", type: ObjectDetailsShellComponent, selector: "yuv-object-details-shell", inputs: ["actions", "type", "bucket", "hideHeader"] }, { kind: "component", type: ObjectPreviewComponent, selector: "yuv-object-preview", inputs: ["objectId", "dmsObject", "version", "metadata"] }, { kind: "component", type: ObjectMetadataComponent, selector: "yuv-object-metadata", inputs: ["disableControls", "disableBasicMetadata", "elementExtensions", "situation", "dmsObject", "flavoredDmsObject", "flavors"], outputs: ["indexDataSaved", "statusChanged"] }, { kind: "component", type: ObjectAuditComponent, selector: "yuv-object-audit", inputs: ["dmsObject", "skipActions", "allActions"] }] }); }
751
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: ObjectDetailsComponent, isStandalone: true, selector: "yuv-object-details", inputs: { dmsObjectInput: { classPropertyName: "dmsObjectInput", publicName: "dmsObject", isSignal: true, isRequired: false, transformFunction: null }, flavors: { classPropertyName: "flavors", publicName: "flavors", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, objectConfigBucket: { classPropertyName: "objectConfigBucket", publicName: "objectConfigBucket", isSignal: true, isRequired: false, transformFunction: null }, objectId: { classPropertyName: "objectId", publicName: "objectId", isSignal: true, isRequired: false, transformFunction: null }, hideHeader: { classPropertyName: "hideHeader", publicName: "hideHeader", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, badges: { classPropertyName: "badges", publicName: "badges", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ObjectDetailsShellService], ngImport: i0, template: "<yuv-object-details-shell [type]=\"type()\" [hideHeader]=\"hideHeader()\" [bucket]=\"objectConfigBucket()\" [actions]=\"actions()\" [badges]=\"badges()\">\n @let dmsObj = dmsObject();\n <mat-tab-group yuvTabGuardDisable>\n <!-- content -->\n @if (dmsObj && dmsObj.content) {\n <mat-tab [label]=\"'yuv.object-details.tabs.content.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-preview [dmsObject]=\"dmsObj\"></yuv-object-preview>\n </ng-template>\n </mat-tab>\n }\n\n <!-- indexdata -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.indexdata.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-metadata [dmsObject]=\"dmsObject()\" [flavors]=\"flavors()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n </mat-tab>\n <!-- history -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.history.title' | translate\">\n <ng-template matTabContent> <yuv-object-audit [dmsObject]=\"dmsObj\"></yuv-object-audit> </ng-template\n ></mat-tab>\n </mat-tab-group>\n</yuv-object-details-shell>\n", styles: [":host{display:block;overflow:hidden}:host yuv-object-details-shell{height:100%}:host mat-tab-group{overflow:hidden;height:100%}:host mat-tab-group ::ng-deep .mat-mdc-tab-body-wrapper{height:100%}:host yuv-object-preview{background-color:var(--ymt-surface-container-low)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i2$2.MatTabContent, selector: "[matTabContent]" }, { kind: "component", type: i2$2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2$2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: TabGuardDirective, selector: "mat-tab-group[yuvTabGuardDisable]" }, { kind: "component", type: ObjectDetailsShellComponent, selector: "yuv-object-details-shell", inputs: ["actions", "badges", "type", "bucket", "hideHeader"] }, { kind: "component", type: ObjectPreviewComponent, selector: "yuv-object-preview", inputs: ["objectId", "dmsObject", "version", "metadata"] }, { kind: "component", type: ObjectMetadataComponent, selector: "yuv-object-metadata", inputs: ["disableControls", "disableBasicMetadata", "elementExtensions", "situation", "dmsObject", "flavoredDmsObject", "flavors"], outputs: ["indexDataSaved", "statusChanged"] }, { kind: "component", type: ObjectAuditComponent, selector: "yuv-object-audit", inputs: ["dmsObject", "skipActions", "allActions"] }] }); }
750
752
  }
751
753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: ObjectDetailsComponent, decorators: [{
752
754
  type: Component,
@@ -759,7 +761,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
759
761
  ObjectPreviewComponent,
760
762
  ObjectMetadataComponent,
761
763
  ObjectAuditComponent
762
- ], providers: [ObjectDetailsShellService], template: "<yuv-object-details-shell [type]=\"type()\" [hideHeader]=\"hideHeader()\" [bucket]=\"objectConfigBucket()\" [actions]=\"actions()\">\n @let dmsObj = dmsObject();\n <mat-tab-group yuvTabGuardDisable>\n <!-- content -->\n @if (dmsObj && dmsObj.content) {\n <mat-tab [label]=\"'yuv.object-details.tabs.content.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-preview [dmsObject]=\"dmsObj\"></yuv-object-preview>\n </ng-template>\n </mat-tab>\n }\n\n <!-- indexdata -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.indexdata.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-metadata [dmsObject]=\"dmsObject()\" [flavors]=\"flavors()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n </mat-tab>\n <!-- history -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.history.title' | translate\">\n <ng-template matTabContent> <yuv-object-audit [dmsObject]=\"dmsObj\"></yuv-object-audit> </ng-template\n ></mat-tab>\n </mat-tab-group>\n</yuv-object-details-shell>\n", styles: [":host{display:block;overflow:hidden}:host yuv-object-details-shell{height:100%}:host mat-tab-group{overflow:hidden;height:100%}:host mat-tab-group ::ng-deep .mat-mdc-tab-body-wrapper{height:100%}:host yuv-object-preview{background-color:var(--ymt-surface-container-low)}\n"] }]
764
+ ], providers: [ObjectDetailsShellService], template: "<yuv-object-details-shell [type]=\"type()\" [hideHeader]=\"hideHeader()\" [bucket]=\"objectConfigBucket()\" [actions]=\"actions()\" [badges]=\"badges()\">\n @let dmsObj = dmsObject();\n <mat-tab-group yuvTabGuardDisable>\n <!-- content -->\n @if (dmsObj && dmsObj.content) {\n <mat-tab [label]=\"'yuv.object-details.tabs.content.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-preview [dmsObject]=\"dmsObj\"></yuv-object-preview>\n </ng-template>\n </mat-tab>\n }\n\n <!-- indexdata -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.indexdata.title' | translate\">\n <ng-template matTabContent>\n <yuv-object-metadata [dmsObject]=\"dmsObject()\" [flavors]=\"flavors()\" (indexDataSaved)=\"onIndexdataSaved($event)\"> </yuv-object-metadata>\n </ng-template>\n </mat-tab>\n <!-- history -->\n <mat-tab [label]=\"'yuv.object-metadata.tabs.history.title' | translate\">\n <ng-template matTabContent> <yuv-object-audit [dmsObject]=\"dmsObj\"></yuv-object-audit> </ng-template\n ></mat-tab>\n </mat-tab-group>\n</yuv-object-details-shell>\n", styles: [":host{display:block;overflow:hidden}:host yuv-object-details-shell{height:100%}:host mat-tab-group{overflow:hidden;height:100%}:host mat-tab-group ::ng-deep .mat-mdc-tab-body-wrapper{height:100%}:host yuv-object-preview{background-color:var(--ymt-surface-container-low)}\n"] }]
763
765
  }] });
764
766
 
765
767
  const cmp = [