@rt-tools/ui-kit-v2 0.33.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +92 -5
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-badge.mjs +191 -0
- package/fesm2022/rt-tools-ui-kit-v2-badge.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +3 -2
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs +6 -1
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +35 -4
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs +13 -4
- package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs +245 -60
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +30 -5
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +113 -2
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +14 -3
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +17 -3
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +6 -3
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-divider.mjs +112 -0
- package/fesm2022/rt-tools-ui-kit-v2-divider.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-drawer.mjs +854 -0
- package/fesm2022/rt-tools-ui-kit-v2-drawer.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +16 -5
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +580 -65
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +203 -15
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs +40 -8
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +7 -3
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +53 -2
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +14 -4
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +6 -3
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +16 -5
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +14 -4
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +3 -2
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs +207 -7
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +3 -2
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +2 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +3 -2
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +3 -2
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-progress-bar.mjs +171 -0
- package/fesm2022/rt-tools-ui-kit-v2-progress-bar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +176 -6
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +2 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +142 -23
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +22 -9
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +3 -2
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +105 -8
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +13 -2
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +654 -43
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +45 -7
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +11 -2
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +152 -11
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +199 -17
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +35 -5
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +14 -4
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +6 -3
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +21 -6
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2.mjs +4 -0
- package/package.json +17 -1
- package/src/assets/icons/volume-off.svg +2 -1
- package/src/lib/components/autocomplete/CONTEXT.md +25 -14
- package/src/lib/components/autocomplete/rt-autocomplete.component.scss +19 -0
- package/src/lib/components/badge/CONTEXT.md +33 -0
- package/src/lib/components/badge/rt-badge.directive.scss +104 -0
- package/src/lib/components/breadcrumbs/rt-breadcrumbs.component.scss +2 -2
- package/src/lib/components/button/CONTEXT.md +5 -0
- package/src/lib/components/button/rt-button.directive.scss +3 -1
- package/src/lib/components/checkbox/CONTEXT.md +15 -8
- package/src/lib/components/color-palette/rt-color-palette.component.scss +2 -2
- package/src/lib/components/container/CONTEXT.md +23 -6
- package/src/lib/components/container/rt-container.component.scss +90 -1
- package/src/lib/components/copy-value/CONTEXT.md +6 -5
- package/src/lib/components/copy-value/rt-copy-value.component.scss +16 -0
- package/src/lib/components/date-picker/rt-date-picker.component.scss +7 -0
- package/src/lib/components/date-range/rt-date-range.component.scss +7 -0
- package/src/lib/components/divider/CONTEXT.md +21 -0
- package/src/lib/components/divider/rt-divider.component.scss +34 -0
- package/src/lib/components/drawer/CONTEXT.md +73 -0
- package/src/lib/components/drawer/rt-drawer-container.component.scss +19 -0
- package/src/lib/components/drawer/rt-drawer.component.scss +168 -0
- package/src/lib/components/drawer/rt-resize-handle.component.scss +42 -0
- package/src/lib/components/dynamic-selector/CONTEXT.md +5 -0
- package/src/lib/components/expansion-panel/CONTEXT.md +32 -8
- package/src/lib/components/expansion-panel/rt-expansion-panel.component.scss +67 -2
- package/src/lib/components/field/CONTEXT.md +43 -0
- package/src/lib/components/field/rt-field-label-inside.scss +179 -0
- package/src/lib/components/field/rt-field.component.scss +51 -2
- package/src/lib/components/icon-button/CONTEXT.md +17 -15
- package/src/lib/components/icon-button/rt-icon-button.component.scss +3 -1
- package/src/lib/components/inline-edit/rt-inline-edit.component.scss +4 -4
- package/src/lib/components/input/CONTEXT.md +45 -11
- package/src/lib/components/input/rt-input-floating-label.scss +192 -0
- package/src/lib/components/input/rt-input-icons.scss +105 -0
- package/src/lib/components/input/rt-input.component.scss +91 -13
- package/src/lib/components/input-number/CONTEXT.md +7 -0
- package/src/lib/components/input-number/rt-input-number.component.scss +58 -1
- package/src/lib/components/menu/CONTEXT.md +1 -0
- package/src/lib/components/multiselect/CONTEXT.md +2 -1
- package/src/lib/components/multiselect/rt-multiselect.component.scss +7 -0
- package/src/lib/components/pagination/CONTEXT.md +3 -0
- package/src/lib/components/pagination/rt-pagination.component.scss +7 -0
- package/src/lib/components/progress-bar/CONTEXT.md +22 -0
- package/src/lib/components/progress-bar/rt-progress-bar.component.scss +77 -0
- package/src/lib/components/radio-button/CONTEXT.md +9 -0
- package/src/lib/components/radio-button/rt-radio-group.component.scss +13 -0
- package/src/lib/components/select/CONTEXT.md +28 -0
- package/src/lib/components/select/rt-select-clear.scss +88 -0
- package/src/lib/components/select/rt-select-floating-label.scss +155 -0
- package/src/lib/components/select/rt-select-material.scss +54 -0
- package/src/lib/components/select/rt-select.component.scss +54 -16
- package/src/lib/components/side-menu/CONTEXT.md +5 -0
- package/src/lib/components/speed-menu/rt-speed-menu.component.scss +5 -5
- package/src/lib/components/stepper/CONTEXT.md +13 -5
- package/src/lib/components/stepper/rt-stepper.component.scss +93 -0
- package/src/lib/components/tabs/CONTEXT.md +61 -9
- package/src/lib/components/tabs/rt-tabs.component.scss +201 -5
- package/src/lib/components/textarea/CONTEXT.md +12 -1
- package/src/lib/components/textarea/rt-textarea.component.scss +116 -1
- package/src/lib/components/toast/CONTEXT.md +23 -0
- package/src/lib/components/toast/rt-toast.component.scss +37 -0
- package/src/lib/components/toggle-button-group/CONTEXT.md +24 -4
- package/src/lib/components/toggle-button-group/rt-toggle-button-group-chips.scss +151 -0
- package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +35 -0
- package/src/lib/components/tooltip/CONTEXT.md +7 -1
- package/src/lib/components/tree/rt-tree.component.scss +2 -2
- package/src/styles/_color-scheme.scss +1 -1
- package/src/styles/_density.scss +48 -0
- package/src/styles/_index.scss +8 -0
- package/src/styles/_preset-material.scss +160 -70
- package/src/styles/_primitives.scss +1 -0
- package/src/styles/_semantic-navigation.scss +117 -0
- package/src/styles/_semantic.scss +29 -98
- package/src/styles/_theme-dark.scss +8 -0
- package/styles/tokens.css +2066 -1134
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +34 -0
- package/types/rt-tools-ui-kit-v2-badge.d.ts +71 -0
- package/types/rt-tools-ui-kit-v2-checkbox.d.ts +17 -3
- package/types/rt-tools-ui-kit-v2-container.d.ts +65 -9
- package/types/rt-tools-ui-kit-v2-copy-value.d.ts +11 -1
- package/types/rt-tools-ui-kit-v2-core.d.ts +109 -4
- package/types/rt-tools-ui-kit-v2-divider.d.ts +29 -0
- package/types/rt-tools-ui-kit-v2-drawer.d.ts +257 -0
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +240 -25
- package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +87 -3
- package/types/rt-tools-ui-kit-v2-field.d.ts +18 -1
- package/types/rt-tools-ui-kit-v2-form-control.d.ts +42 -4
- package/types/rt-tools-ui-kit-v2-icon-button.d.ts +2 -1
- package/types/rt-tools-ui-kit-v2-input-number.d.ts +1 -0
- package/types/rt-tools-ui-kit-v2-input.d.ts +98 -4
- package/types/rt-tools-ui-kit-v2-progress-bar.d.ts +53 -0
- package/types/rt-tools-ui-kit-v2-radio-button.d.ts +80 -1
- package/types/rt-tools-ui-kit-v2-select.d.ts +65 -1
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +3 -0
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +57 -4
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +337 -8
- package/types/rt-tools-ui-kit-v2-textarea.d.ts +16 -0
- package/types/rt-tools-ui-kit-v2-toast.d.ts +38 -2
- package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +83 -3
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +17 -2
- package/types/rt-tools-ui-kit-v2.d.ts +4 -0
- package/src/lib/components/dynamic-selector/stories/component/test-dynamic-selector-popup-frame.component.scss +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rt-tools-ui-kit-v2-tree.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.directives.ts","../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.logic.ts","../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.component.ts","../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\nimport { IRtTree } from './rt-tree.model';\n\n/**\n * Разметка приложения в конце каждой строки `rt-tree`. Узел строки приходит в контексте как\n * `$implicit`: дерево не заводит вход под каждый такой элемент.\n */\n@Directive({ selector: 'ng-template[rtTreeNodeEnd]' })\nexport class RtTreeNodeEndDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n\n/**\n * Разметка приложения под подписью строки, в одной линии с метками узла. Узел строки приходит в\n * контексте как `$implicit`.\n */\n@Directive({ selector: 'ng-template[rtTreeNodeMeta]' })\nexport class RtTreeNodeMetaDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n","import { IRtMatchPart, rtMatchParts, rtTreeBranchState, rtTreeLeaves } from '@rt-tools/ui-kit-v2/core';\nimport { IRtTree } from './rt-tree.model';\n\n/**\n * Расчёт выбора `rt-tree` — чистые функции над неизменяемыми узлами.\n *\n * Строки, листья и отметки ветвей считает модуль дерева выбора из списка: здесь только то, чего у\n * выбора из списка нет — режим отметок, выключенный каскад и «выбрать всё». Узлы не меняются\n * никогда: каждая функция отвечает новым массивом выбора.\n */\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\n\nfunction isBranch<TValue>(node: TNode<TValue>): boolean {\n return (node.children ?? []).length > 0;\n}\n\nfunction without<TValue>(value: ReadonlyArray<TValue>, drop: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n return value.filter((item: TValue): boolean => !drop.includes(item));\n}\n\nfunction withAll<TValue>(value: ReadonlyArray<TValue>, add: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n return [...value, ...add.filter((item: TValue): boolean => !value.includes(item))];\n}\n\n/**\n * Отметка строки. В каскаде ветка отмечена по своим листьям; без каскада и у листа — по тому,\n * лежит ли в выборе сам узел.\n */\nexport function rtTreeMark<TValue>(node: TNode<TValue>, value: ReadonlyArray<TValue>, cascade: boolean): IRtTree.Mark {\n if (cascade && isBranch(node)) {\n return rtTreeBranchState(node, value);\n }\n return value.includes(node.value) ? 'all' : 'none';\n}\n\n/**\n * Выбор после клика по узлу. Выключенный узел выбор не меняет. Одиночный режим держит один узел и\n * не снимает его повторным кликом. В каскаде ветка добавляет свои включённые листья или снимает\n * их, когда выбраны все; выключенные листья остаются как были.\n */\nexport function rtTreeChoose<TValue>(\n node: TNode<TValue>,\n value: ReadonlyArray<TValue>,\n mode: IRtTree.Mode,\n cascade: boolean\n): ReadonlyArray<TValue> {\n if (node.disabled || mode === 'none') {\n return value;\n }\n if (mode === 'single') {\n return [node.value];\n }\n if (cascade && isBranch(node)) {\n const leaves: ReadonlyArray<TValue> = rtTreeLeaves(node);\n return rtTreeBranchState(node, value) === 'all' ? without(value, leaves) : withAll(value, leaves);\n }\n return value.includes(node.value) ? without(value, [node.value]) : withAll(value, [node.value]);\n}\n\n/**\n * Включённые листья видимых строк. Раскрытая ветка отдаёт листья своими строками ниже, свёрнутая —\n * всеми листьями под собой: они видимы через неё.\n */\nexport function rtTreeVisibleLeaves<TValue>(rows: ReadonlyArray<IRtTree.Row<TValue>>): ReadonlyArray<TValue> {\n return rows.flatMap((row: IRtTree.Row<TValue>): ReadonlyArray<TValue> => (row.branch && row.open ? [] : rtTreeLeaves(row.option)));\n}\n\n/** Отметка «выбрать всё» по включённым листьям видимых строк. */\nexport function rtTreeSelectAllMark<TValue>(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): IRtTree.Mark {\n const leaves: ReadonlyArray<TValue> = rtTreeVisibleLeaves(rows);\n const count: number = leaves.filter((leaf: TValue): boolean => value.includes(leaf)).length;\n if (count === 0) {\n return 'none';\n }\n return count === leaves.length ? 'all' : 'some';\n}\n\n/**\n * Выбор после клика по «выбрать всё»: включённые листья видимых строк добавляются, а когда выбраны\n * все — снимаются. Выключенные листья `rtTreeLeaves` не отдаёт, поэтому их состояние не меняется.\n */\nexport function rtTreeSelectAll<TValue>(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n const leaves: ReadonlyArray<TValue> = rtTreeVisibleLeaves(rows);\n return rtTreeSelectAllMark(rows, value) === 'all' ? without(value, leaves) : withAll(value, leaves);\n}\n\n/**\n * Подпись, описание и метки узла, разрезанные по каждому слову запроса тем же резом, что у поиска\n * меню: приложение делит поиск по пробелам, и найденное слово видно там, где оно нашлось.\n */\nexport function rtTreeLabelParts<TValue>(node: TNode<TValue>, term: string): IRtTree.LabelParts {\n return {\n label: rtMatchParts(node.label, term),\n description: rtMatchParts(node.description ?? '', term),\n badges: (node.badges ?? []).map((badge: IRtTree.Badge): ReadonlyArray<IRtMatchPart> => rtMatchParts(badge.text, term)),\n };\n}\n\n/** Значения узла и всех его потомков. */\nfunction covered<TValue>(node: TNode<TValue>): ReadonlyArray<TValue> {\n return [node.value, ...(node.children ?? []).flatMap((child: TNode<TValue>): ReadonlyArray<TValue> => covered(child))];\n}\n\n/** Значения выключенных узлов дерева: их состояние не меняет ни одно действие. */\nfunction disabledValues<TValue>(nodes: ReadonlyArray<TNode<TValue>>): ReadonlyArray<TValue> {\n return nodes.flatMap((node: TNode<TValue>): ReadonlyArray<TValue> => [\n ...(node.disabled ? [node.value] : []),\n ...disabledValues(node.children ?? []),\n ]);\n}\n\n/** Что остаётся от выбора перед кликом без Ctrl и Cmd: то, что покрывает сам узел, и выключенные узлы. */\nexport function rtTreeAloneBase<TValue>(\n nodes: ReadonlyArray<TNode<TValue>>,\n node: TNode<TValue>,\n value: ReadonlyArray<TValue>\n): ReadonlyArray<TValue> {\n const keep: ReadonlyArray<TValue> = [...covered(node), ...disabledValues(nodes)];\n return value.filter((item: TValue): boolean => keep.includes(item));\n}\n\n/**\n * Выбор после клика без Ctrl и Cmd в режиме, где клик выбирает один узел. Из выбора остаётся только\n * то, что покрывает сам узел, и выключенные узлы; дальше клик работает как обычно — поэтому\n * повторный клик по единственному выбранному снимает его.\n */\nexport function rtTreeChooseAlone<TValue>(\n nodes: ReadonlyArray<TNode<TValue>>,\n node: TNode<TValue>,\n value: ReadonlyArray<TValue>,\n cascade: boolean\n): ReadonlyArray<TValue> {\n if (node.disabled) {\n return value;\n }\n return rtTreeChoose(node, rtTreeAloneBase(nodes, node, value), 'multiple', cascade);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { FormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IRtIcon, RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtCheckboxComponent } from '@rt-tools/ui-kit-v2/checkbox';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtRadioButtonComponent } from '@rt-tools/ui-kit-v2/radio-button';\nimport { RtTagComponent } from '@rt-tools/ui-kit-v2/tag';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtOptionTree, rtTreeOpenFor, rtTreeRows, rtTreeSideKey, rtTreeToggle } from '@rt-tools/ui-kit-v2/core';\nimport { RtTreeNodeEndDirective, RtTreeNodeMetaDirective } from './rt-tree.directives';\nimport { rtTreeChoose, rtTreeChooseAlone, rtTreeLabelParts, rtTreeMark, rtTreeSelectAll, rtTreeSelectAllMark } from './rt-tree.logic';\nimport { IRtTree } from './rt-tree.model';\n\nconst BEM_BLOCK: string = 'rt-tree';\n\n/** Видимая строка с тем, что разметке нужно о ней знать. */\ninterface IRtTreeView<TValue> {\n readonly row: IRtTree.Row<TValue>;\n readonly mark: IRtTree.Mark;\n /** Рисуется ли у строки флажок или радио: у групп без отметок его нет. */\n readonly marked: boolean;\n /** Радио вместо флажка. */\n readonly radio: boolean;\n /** Строка выключена: свой `disabled` у узла или выключено всё дерево. */\n readonly disabled: boolean;\n /** Число выбранного под группой в конце строки; `null` — числа нет. */\n readonly count: number | null;\n readonly parts: IRtTree.LabelParts;\n readonly highlighted: boolean;\n}\n\n/**\n * Дерево выбора, стоящее на странице само по себе.\n *\n * Строки, листья, отметки ветвей, отбор по слову и боковые стрелки считает модуль дерева выбора\n * из списка — тот же, что у `rt-select` и `rt-multiselect`. Выбор живёт в `value`; узлы не\n * меняются. Раскрытые ветки и подсвеченная строка — состояние самого дерева.\n *\n * Клавиатура идёт через `handleKeydown`: его зовёт и само дерево с фокуса на себе, и приложение\n * со своего поля поиска. Ответ — взята ли клавиша: чужую дерево не трогает.\n */\n@Component({\n selector: 'rt-tree',\n templateUrl: './rt-tree.component.html',\n styleUrl: './rt-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n FormsModule,\n RtCheckboxComponent,\n RtIconComponent,\n RtRadioButtonComponent,\n RtTagComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'tree',\n '[attr.tabindex]': 'disabled() ? -1 : 0',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.aria-label]': 'ariaLabel()',\n '[attr.aria-multiselectable]': \"mode() === 'multiple'\",\n '(keydown)': 'handleKeydown($event)',\n },\n})\nexport class RtTreeComponent<TValue> {\n readonly #open: WritableSignal<ReadonlySet<TValue> | null> = signal<ReadonlySet<TValue> | null>(null);\n readonly #highlighted: WritableSignal<TValue | null> = signal<TValue | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly nodeEnd: Signal<RtTreeNodeEndDirective<TValue> | undefined> = contentChild(RtTreeNodeEndDirective);\n\n protected readonly nodeMeta: Signal<RtTreeNodeMetaDirective<TValue> | undefined> = contentChild(RtTreeNodeMetaDirective);\n\n /** Разметка в конце строки: вход раньше директивы — обёртка вроде селектора отдаёт её входом. */\n protected readonly endTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeEndTemplate() ?? this.nodeEnd()?.templateRef ?? null\n );\n\n /** Разметка под подписью: вход раньше директивы. */\n protected readonly metaTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeMetaTemplate() ?? this.nodeMeta()?.templateRef ?? null\n );\n\n /** Раскрытые ветки: до первого действия человека — ветки над выбранным. */\n protected readonly openBranches: Signal<ReadonlySet<TValue>> = computed(\n (): ReadonlySet<TValue> => this.#open() ?? rtTreeOpenFor(this.nodes(), this.value())\n );\n\n protected readonly rows: Signal<ReadonlyArray<IRtTree.Row<TValue>>> = computed((): ReadonlyArray<IRtTree.Row<TValue>> =>\n rtTreeRows(this.nodes(), this.openBranches(), this.filter() ? this.searchTerm() : '')\n );\n\n protected readonly views: Signal<ReadonlyArray<IRtTreeView<TValue>>> = computed((): ReadonlyArray<IRtTreeView<TValue>> => {\n const value: ReadonlyArray<TValue> = this.value();\n const cascade: boolean = this.cascade();\n const term: string = this.searchTerm();\n const highlighted: TValue | null = this.#highlighted();\n const mode: IRtTree.Mode = this.mode();\n const branchMarks: boolean = this.branchMarks();\n const treeDisabled: boolean = this.disabled();\n return this.rows().map((row: IRtTree.Row<TValue>): IRtTreeView<TValue> => {\n const marked: boolean = mode !== 'none' && (branchMarks || !row.branch);\n const state: IRtTree.RowState = this.rowState(row, value, cascade);\n return {\n row,\n marked,\n mark: state.mark,\n radio: state.radio,\n disabled: treeDisabled || !!row.option.disabled,\n count: marked ? null : state.count,\n parts: rtTreeLabelParts(row.option, term),\n highlighted: row.option.value === highlighted,\n };\n });\n });\n\n protected readonly selectAllMark: Signal<IRtTree.Mark> = computed((): IRtTree.Mark => this.selectAllMarkOf(this.rows(), this.value()));\n\n protected readonly isSelectAllShown: Signal<boolean> = computed(\n (): boolean => this.showSelectAll() && this.cascade() && this.mode() === 'multiple' && this.rows().length > 0\n );\n\n /** Отметка «выбрать всё» встаёт над отметкой первой строки; у строки без отметки — над стрелкой. */\n protected readonly isSelectAllUnderMark: Signal<boolean> = computed((): boolean => this.views()[0]?.marked ?? false);\n\n /** Первая строка — лист: там, где у листа нет места под стрелку, его нет и у «выбрать всё». */\n protected readonly isSelectAllOverLeaf: Signal<boolean> = computed((): boolean => this.views()[0]?.row.branch === false);\n\n protected readonly emptyText: Signal<string> = computed((): string =>\n this.nodes().length > 0 ? this.t().uiNothingFound : this.t().uiNoOptions\n );\n\n public readonly nodes: InputSignal<ReadonlyArray<IRtTree.Node<TValue>>> = input.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n public readonly value: ModelSignal<ReadonlyArray<TValue>> = model<ReadonlyArray<TValue>>([]);\n public readonly mode: InputSignal<IRtTree.Mode> = input<IRtTree.Mode>('multiple');\n public readonly cascade: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, { transform: booleanAttribute });\n public readonly searchTerm: InputSignal<string> = input<string>('');\n public readonly showSelectAll: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n\n /** Отметки у групп. Без них клик, пробел и Enter по группе раскрывают и сворачивают её. */\n public readonly branchMarks: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n\n /** Клик без Ctrl и Cmd выбирает узел один; с Ctrl или Cmd добавляет к выбору. Только для флажков. */\n public readonly exclusive: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n /** Скрывает ли слово поиска строки. Без отбора строки отбирает приложение, а слово только отмечено. */\n public readonly filter: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n\n /** Выключенное дерево не меняет выбор ни кликом, ни клавишей, ни «выбрать всё»; ветки раскрываются стрелкой. */\n /** Значок кита над подписью пустого дерева. Без него пустое дерево — одна подпись. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /**\n * Разметка в конце каждой строки, отданная входом. Нужна компоненту, который оборачивает дерево и\n * не может положить в него директиву `rtTreeNodeEnd`; вход сильнее директивы.\n */\n public readonly nodeEndTemplate: InputSignal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = input<TemplateRef<\n IRtTree.NodeContext<TValue>\n > | null>(null);\n\n /** Разметка под подписью каждой строки, отданная входом; вход сильнее директивы `rtTreeNodeMeta`. */\n public readonly nodeMetaTemplate: InputSignal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = input<TemplateRef<\n IRtTree.NodeContext<TValue>\n > | null>(null);\n\n public readonly disabled: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n public readonly picked: OutputEmitterRef<IRtTree.Node<TValue>> = output<IRtTree.Node<TValue>>();\n\n /**\n * Клавиша для дерева. Отвечает, взята ли она: не взятая идёт дальше нетронутой, поэтому\n * приложение может отдавать сюда каждую клавишу своего поля поиска.\n */\n public handleKeydown(event: KeyboardEvent): boolean {\n if (this.disabled()) {\n return false;\n }\n const taken: boolean = this.#takeKey(event.key, event.ctrlKey || event.metaKey);\n if (taken) {\n event.preventDefault();\n event.stopPropagation();\n }\n return taken;\n }\n\n public expandAll(): void {\n const all: Set<TValue> = new Set<TValue>();\n this.#collectBranches(this.nodes(), all);\n this.#open.set(all);\n }\n\n public collapseAll(): void {\n this.#open.set(new Set<TValue>());\n }\n\n public clearHighlight(): void {\n this.#highlighted.set(null);\n }\n\n protected onRowClick(row: IRtTree.Row<TValue>, event: MouseEvent): void {\n if (this.disabled()) {\n return;\n }\n this.#highlighted.set(row.option.value);\n if (row.option.disabled) {\n return;\n }\n if (this.#opensOnly(row)) {\n this.#toggleOrPick(row);\n return;\n }\n this.#choose(this.nextChoice(row.option, event.ctrlKey || event.metaKey));\n }\n\n protected onToggleClick(event: Event, value: TValue): void {\n event.stopPropagation();\n this.#toggle(value);\n }\n\n protected onSelectAll(): void {\n if (this.disabled()) {\n return;\n }\n this.#choose(this.selectAllChoice(this.rows(), this.value()));\n }\n\n /**\n * Отметка строки, её вид и число выбранного под ней. Дерево числа не рисует; наследник со своими\n * правилами выбора считает всё это по ним.\n */\n protected rowState(row: IRtTree.Row<TValue>, value: ReadonlyArray<TValue>, cascade: boolean): IRtTree.RowState {\n return { mark: rtTreeMark(row.option, value, cascade), radio: this.mode() === 'single', count: null };\n }\n\n protected selectAllMarkOf(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): IRtTree.Mark {\n return rtTreeSelectAllMark(rows, value);\n }\n\n protected selectAllChoice(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n return rtTreeSelectAll(rows, value);\n }\n\n /** Выбор после действия над узлом: в исключающем режиме без Ctrl и Cmd узел остаётся один. */\n protected nextChoice(node: IRtTree.Node<TValue>, additive: boolean): ReadonlyArray<TValue> {\n if (this.exclusive() && this.mode() === 'multiple' && !additive) {\n return rtTreeChooseAlone(this.nodes(), node, this.value(), this.cascade());\n }\n return rtTreeChoose(node, this.value(), this.mode(), this.cascade());\n }\n\n /** Строка, клик по которой ничего не отмечает: режим без отметок или группа без флажка. */\n #opensOnly(row: IRtTree.Row<TValue>): boolean {\n return this.mode() === 'none' || (row.branch && !this.branchMarks());\n }\n\n #toggleOrPick(row: IRtTree.Row<TValue>): void {\n if (row.branch) {\n this.#toggle(row.option.value);\n } else {\n this.picked.emit(row.option);\n }\n }\n\n #collectBranches(list: ReadonlyArray<IRtTree.Node<TValue>>, into: Set<TValue>): void {\n list.forEach((node: IRtTree.Node<TValue>): void => {\n if ((node.children ?? []).length > 0) {\n into.add(node.value);\n this.#collectBranches(node.children ?? [], into);\n }\n });\n }\n\n /**\n * Меняет выбор, не трогая раскрытие. Пока ветки никто не раскрывал руками, раскрытие считается из\n * выбора, и без этой фиксации отметка ветки сворачивала или раскрывала её саму.\n */\n #choose(next: ReadonlyArray<TValue>): void {\n this.#open.set(this.openBranches());\n this.value.set(next);\n }\n\n #toggle(value: TValue): void {\n this.#open.set(rtTreeToggle(this.openBranches(), value));\n }\n\n #highlightedIndex(): number {\n const highlighted: TValue | null = this.#highlighted();\n return this.rows().findIndex((row: IRtTree.Row<TValue>): boolean => row.option.value === highlighted);\n }\n\n #takeKey(key: string, additive: boolean): boolean {\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const index: number = this.#highlightedIndex();\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n return this.#move(rows, index, key === 'ArrowDown' ? 1 : -1);\n }\n return index >= 0 && this.#takeRowKey(rows, index, key, additive);\n }\n\n /** Клавиши, которым нужна подсвеченная строка. */\n #takeRowKey(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, key: string, additive: boolean): boolean {\n if (key === 'Home' || key === 'End') {\n return this.#edge(rows, key);\n }\n if (key === 'ArrowRight' || key === 'ArrowLeft') {\n this.#side(rows, index, key);\n return true;\n }\n if (key === ' ') {\n this.#space(rows[index], additive);\n return true;\n }\n if (key === 'Enter') {\n this.#enter(rows[index], additive);\n return true;\n }\n return false;\n }\n\n #move(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, step: number): boolean {\n if (rows.length === 0) {\n return false;\n }\n const next: number = index < 0 ? 0 : Math.min(rows.length - 1, Math.max(0, index + step));\n this.#highlighted.set(rows[next].option.value);\n return true;\n }\n\n /** Home и End ведут подсветку к первой и последней строке; без подсветки они остаются у курсора поля. */\n #edge(rows: ReadonlyArray<IRtTree.Row<TValue>>, key: string): boolean {\n this.#highlighted.set(rows[key === 'Home' ? 0 : rows.length - 1].option.value);\n return true;\n }\n\n #side(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, key: string): void {\n const answer: IRtOptionTree.SideKeyAnswer<TValue> = rtTreeSideKey(rows, index, key);\n if (answer.toggle !== null) {\n this.#toggle(answer.toggle);\n }\n this.#highlighted.set(rows[answer.index].option.value);\n }\n\n #space(row: IRtTree.Row<TValue>, additive: boolean): void {\n if (this.#opensOnly(row) && row.branch) {\n this.#toggle(row.option.value);\n return;\n }\n if (!row.option.disabled && this.mode() !== 'none') {\n this.#choose(this.nextChoice(row.option, additive));\n }\n }\n\n #enter(row: IRtTree.Row<TValue>, additive: boolean): void {\n if (this.#opensOnly(row) && row.branch) {\n this.#toggle(row.option.value);\n return;\n }\n if (row.option.disabled) {\n return;\n }\n if (this.mode() !== 'none') {\n this.#choose(this.nextChoice(row.option, additive));\n }\n this.picked.emit(row.option);\n }\n}\n","<ng-container rtBlock=\"rt-tree\">\n <!--\n Строки выбираются мышью через (click); клавиатура — на самом дереве (handleKeydown), строки\n по отдельности фокус не берут: подсветка — третье состояние рядом с фокусом и выбором.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n @if (isSelectAllShown()) {\n <div\n rtElem=\"select-all\"\n qa-dataid=\"tree-select-all\"\n role=\"presentation\"\n [rtMod]=\"{ disabled: disabled(), 'over-leaf': isSelectAllOverLeaf() }\"\n (click)=\"onSelectAll()\">\n @if (isSelectAllUnderMark()) {\n <span rtElem=\"toggle-space\"></span>\n }\n <rt-checkbox\n rtElem=\"check\"\n inert\n [disabled]=\"disabled()\"\n [indeterminate]=\"selectAllMark() === 'some'\"\n [ngModel]=\"selectAllMark() === 'all'\"\n [ngModelOptions]=\"{ standalone: true }\" />\n <span rtElem=\"label\">{{ t().uiSelectAll }}</span>\n </div>\n }\n\n @for (view of views(); track view.row.option.value) {\n <div\n rtElem=\"row\"\n qa-dataid=\"tree-row\"\n role=\"treeitem\"\n [attr.data-value]=\"view.row.option.value\"\n [attr.aria-level]=\"view.row.level + 1\"\n [attr.aria-expanded]=\"view.row.branch ? view.row.open : null\"\n [attr.aria-selected]=\"view.marked ? view.mark === 'all' : null\"\n [attr.aria-disabled]=\"view.disabled\"\n [style.--rt-tree-level]=\"view.row.level\"\n [rtMod]=\"{ highlighted: view.highlighted, disabled: view.disabled, chosen: view.mark === 'all' }\"\n (click)=\"onRowClick(view.row, $event)\">\n @if (view.row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"tree-row-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"view.row.open ? t().uiCollapse : t().uiExpand\"\n (click)=\"onToggleClick($event, view.row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"view.row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n\n @if (view.marked && !view.radio) {\n <rt-checkbox\n rtElem=\"check\"\n qa-dataid=\"tree-row-checkbox\"\n inert\n [disabled]=\"view.disabled\"\n [indeterminate]=\"view.mark === 'some'\"\n [ngModel]=\"view.mark === 'all'\"\n [ngModelOptions]=\"{ standalone: true }\" />\n } @else if (view.marked) {\n <rt-radio-button\n rtElem=\"check\"\n qa-dataid=\"tree-row-radio\"\n inert\n [value]=\"view.row.option.value\"\n [checked]=\"view.mark === 'all'\"\n [disabled]=\"view.disabled\" />\n }\n\n <span rtElem=\"text\">\n <span rtElem=\"label\" qa-dataid=\"tree-row-label\" rtTooltipWhenTruncated [rtTooltip]=\"view.row.option.label\">\n @for (part of view.parts.label; track $index) {\n <span rtElem=\"part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n @if (view.parts.description.length > 0) {\n <span\n rtElem=\"description\"\n qa-dataid=\"tree-row-description\"\n rtTooltipWhenTruncated\n [rtTooltip]=\"view.row.option.description\">\n @for (part of view.parts.description; track $index) {\n <span rtElem=\"part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n }\n @if (view.row.option.badges?.length || metaTemplate()) {\n <span rtElem=\"meta\" qa-dataid=\"tree-row-meta\">\n @for (badge of view.row.option.badges; track $index) {\n <rt-tag size=\"sm\" [value]=\"badge.text\" [severity]=\"badge.severity ?? 'neutral'\" [highlight]=\"searchTerm()\" />\n }\n @if (metaTemplate(); as meta) {\n <ng-container [ngTemplateOutlet]=\"meta\" [ngTemplateOutletContext]=\"{ $implicit: view.row.option }\" />\n }\n </span>\n }\n </span>\n\n @if (view.count) {\n <span rtElem=\"count\" qa-dataid=\"tree-row-count\">{{ view.count }}</span>\n }\n\n @if (endTemplate(); as end) {\n <span rtElem=\"end\" qa-dataid=\"tree-row-end\">\n <ng-container [ngTemplateOutlet]=\"end\" [ngTemplateOutletContext]=\"{ $implicit: view.row.option }\" />\n </span>\n }\n </div>\n } @empty {\n <div rtElem=\"empty\" qa-dataid=\"tree-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"tree-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ emptyText() }}\n </div>\n }\n</ng-container>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-tree.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.directives.ts","../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.logic.ts","../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.component.ts","../../../projects/ui-kit-v2/src/lib/components/tree/rt-tree.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\nimport { IRtTree } from './rt-tree.model';\n\n/**\n * Разметка приложения в конце каждой строки `rt-tree`. Узел строки приходит в контексте как\n * `$implicit`: дерево не заводит вход под каждый такой элемент.\n */\n@Directive({ selector: 'ng-template[rtTreeNodeEnd]' })\nexport class RtTreeNodeEndDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n\n/**\n * Разметка приложения под подписью строки, в одной линии с метками узла. Узел строки приходит в\n * контексте как `$implicit`.\n */\n@Directive({ selector: 'ng-template[rtTreeNodeMeta]' })\nexport class RtTreeNodeMetaDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n","import { IRtMatchPart, rtMatchParts, rtTreeBranchState, rtTreeLeaves } from '@rt-tools/ui-kit-v2/core';\nimport { IRtTree } from './rt-tree.model';\n\n/**\n * Расчёт выбора `rt-tree` — чистые функции над неизменяемыми узлами.\n *\n * Строки, листья и отметки ветвей считает модуль дерева выбора из списка: здесь только то, чего у\n * выбора из списка нет — режим отметок, выключенный каскад и «выбрать всё». Узлы не меняются\n * никогда: каждая функция отвечает новым массивом выбора.\n */\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\n\nfunction isBranch<TValue>(node: TNode<TValue>): boolean {\n return (node.children ?? []).length > 0;\n}\n\nfunction without<TValue>(value: ReadonlyArray<TValue>, drop: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n return value.filter((item: TValue): boolean => !drop.includes(item));\n}\n\nfunction withAll<TValue>(value: ReadonlyArray<TValue>, add: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n return [...value, ...add.filter((item: TValue): boolean => !value.includes(item))];\n}\n\n/**\n * Отметка строки. В каскаде ветка отмечена по своим листьям; без каскада и у листа — по тому,\n * лежит ли в выборе сам узел.\n */\nexport function rtTreeMark<TValue>(node: TNode<TValue>, value: ReadonlyArray<TValue>, cascade: boolean): IRtTree.Mark {\n if (cascade && isBranch(node)) {\n return rtTreeBranchState(node, value);\n }\n return value.includes(node.value) ? 'all' : 'none';\n}\n\n/**\n * Выбор после клика по узлу. Выключенный узел выбор не меняет. Одиночный режим держит один узел и\n * не снимает его повторным кликом. В каскаде ветка добавляет свои включённые листья или снимает\n * их, когда выбраны все; выключенные листья остаются как были.\n */\nexport function rtTreeChoose<TValue>(\n node: TNode<TValue>,\n value: ReadonlyArray<TValue>,\n mode: IRtTree.Mode,\n cascade: boolean\n): ReadonlyArray<TValue> {\n if (node.disabled || mode === 'none') {\n return value;\n }\n if (mode === 'single') {\n return [node.value];\n }\n if (cascade && isBranch(node)) {\n const leaves: ReadonlyArray<TValue> = rtTreeLeaves(node);\n return rtTreeBranchState(node, value) === 'all' ? without(value, leaves) : withAll(value, leaves);\n }\n return value.includes(node.value) ? without(value, [node.value]) : withAll(value, [node.value]);\n}\n\n/**\n * Включённые листья видимых строк. Раскрытая ветка отдаёт листья своими строками ниже, свёрнутая —\n * всеми листьями под собой: они видимы через неё.\n */\nexport function rtTreeVisibleLeaves<TValue>(rows: ReadonlyArray<IRtTree.Row<TValue>>): ReadonlyArray<TValue> {\n return rows.flatMap((row: IRtTree.Row<TValue>): ReadonlyArray<TValue> => (row.branch && row.open ? [] : rtTreeLeaves(row.option)));\n}\n\n/** Отметка «выбрать всё» по включённым листьям видимых строк. */\nexport function rtTreeSelectAllMark<TValue>(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): IRtTree.Mark {\n const leaves: ReadonlyArray<TValue> = rtTreeVisibleLeaves(rows);\n const count: number = leaves.filter((leaf: TValue): boolean => value.includes(leaf)).length;\n if (count === 0) {\n return 'none';\n }\n return count === leaves.length ? 'all' : 'some';\n}\n\n/**\n * Выбор после клика по «выбрать всё»: включённые листья видимых строк добавляются, а когда выбраны\n * все — снимаются. Выключенные листья `rtTreeLeaves` не отдаёт, поэтому их состояние не меняется.\n */\nexport function rtTreeSelectAll<TValue>(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n const leaves: ReadonlyArray<TValue> = rtTreeVisibleLeaves(rows);\n return rtTreeSelectAllMark(rows, value) === 'all' ? without(value, leaves) : withAll(value, leaves);\n}\n\n/**\n * Подпись, описание и метки узла, разрезанные по каждому слову запроса тем же резом, что у поиска\n * меню: приложение делит поиск по пробелам, и найденное слово видно там, где оно нашлось.\n */\nexport function rtTreeLabelParts<TValue>(node: TNode<TValue>, term: string): IRtTree.LabelParts {\n return {\n label: rtMatchParts(node.label, term),\n description: rtMatchParts(node.description ?? '', term),\n badges: (node.badges ?? []).map((badge: IRtTree.Badge): ReadonlyArray<IRtMatchPart> => rtMatchParts(badge.text, term)),\n };\n}\n\n/** Значения узла и всех его потомков. */\nfunction covered<TValue>(node: TNode<TValue>): ReadonlyArray<TValue> {\n return [node.value, ...(node.children ?? []).flatMap((child: TNode<TValue>): ReadonlyArray<TValue> => covered(child))];\n}\n\n/** Значения выключенных узлов дерева: их состояние не меняет ни одно действие. */\nfunction disabledValues<TValue>(nodes: ReadonlyArray<TNode<TValue>>): ReadonlyArray<TValue> {\n return nodes.flatMap((node: TNode<TValue>): ReadonlyArray<TValue> => [\n ...(node.disabled ? [node.value] : []),\n ...disabledValues(node.children ?? []),\n ]);\n}\n\n/** Что остаётся от выбора перед кликом без Ctrl и Cmd: то, что покрывает сам узел, и выключенные узлы. */\nexport function rtTreeAloneBase<TValue>(\n nodes: ReadonlyArray<TNode<TValue>>,\n node: TNode<TValue>,\n value: ReadonlyArray<TValue>\n): ReadonlyArray<TValue> {\n const keep: ReadonlyArray<TValue> = [...covered(node), ...disabledValues(nodes)];\n return value.filter((item: TValue): boolean => keep.includes(item));\n}\n\n/**\n * Выбор после клика без Ctrl и Cmd в режиме, где клик выбирает один узел. Из выбора остаётся только\n * то, что покрывает сам узел, и выключенные узлы; дальше клик работает как обычно — поэтому\n * повторный клик по единственному выбранному снимает его.\n */\nexport function rtTreeChooseAlone<TValue>(\n nodes: ReadonlyArray<TNode<TValue>>,\n node: TNode<TValue>,\n value: ReadonlyArray<TValue>,\n cascade: boolean\n): ReadonlyArray<TValue> {\n if (node.disabled) {\n return value;\n }\n return rtTreeChoose(node, rtTreeAloneBase(nodes, node, value), 'multiple', cascade);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { FormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IRtIcon, RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtCheckboxComponent } from '@rt-tools/ui-kit-v2/checkbox';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtRadioButtonComponent } from '@rt-tools/ui-kit-v2/radio-button';\nimport { RtTagComponent } from '@rt-tools/ui-kit-v2/tag';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtOptionTree, rtTreeOpenFor, rtTreeRows, rtTreeSideKey, rtTreeToggle } from '@rt-tools/ui-kit-v2/core';\nimport { RtTreeNodeEndDirective, RtTreeNodeMetaDirective } from './rt-tree.directives';\nimport { rtTreeChoose, rtTreeChooseAlone, rtTreeLabelParts, rtTreeMark, rtTreeSelectAll, rtTreeSelectAllMark } from './rt-tree.logic';\nimport { IRtTree } from './rt-tree.model';\n\nconst BEM_BLOCK: string = 'rt-tree';\n\n/** Видимая строка с тем, что разметке нужно о ней знать. */\ninterface IRtTreeView<TValue> {\n readonly row: IRtTree.Row<TValue>;\n readonly mark: IRtTree.Mark;\n /** Рисуется ли у строки флажок или радио: у групп без отметок его нет. */\n readonly marked: boolean;\n /** Радио вместо флажка. */\n readonly radio: boolean;\n /** Строка выключена: свой `disabled` у узла или выключено всё дерево. */\n readonly disabled: boolean;\n /** Число выбранного под группой в конце строки; `null` — числа нет. */\n readonly count: number | null;\n readonly parts: IRtTree.LabelParts;\n readonly highlighted: boolean;\n}\n\n/**\n * Дерево выбора, стоящее на странице само по себе.\n *\n * Строки, листья, отметки ветвей, отбор по слову и боковые стрелки считает модуль дерева выбора\n * из списка — тот же, что у `rt-select` и `rt-multiselect`. Выбор живёт в `value`; узлы не\n * меняются. Раскрытые ветки и подсвеченная строка — состояние самого дерева.\n *\n * Клавиатура идёт через `handleKeydown`: его зовёт и само дерево с фокуса на себе, и приложение\n * со своего поля поиска. Ответ — взята ли клавиша: чужую дерево не трогает.\n */\n@Component({\n selector: 'rt-tree',\n templateUrl: './rt-tree.component.html',\n styleUrl: './rt-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n FormsModule,\n RtCheckboxComponent,\n RtIconComponent,\n RtRadioButtonComponent,\n RtTagComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'tree',\n '[attr.tabindex]': 'disabled() ? -1 : 0',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.aria-label]': 'ariaLabel()',\n '[attr.aria-multiselectable]': \"mode() === 'multiple'\",\n '(keydown)': 'handleKeydown($event)',\n },\n})\nexport class RtTreeComponent<TValue> {\n readonly #open: WritableSignal<ReadonlySet<TValue> | null> = signal<ReadonlySet<TValue> | null>(null);\n readonly #highlighted: WritableSignal<TValue | null> = signal<TValue | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly nodeEnd: Signal<RtTreeNodeEndDirective<TValue> | undefined> = contentChild(RtTreeNodeEndDirective);\n\n protected readonly nodeMeta: Signal<RtTreeNodeMetaDirective<TValue> | undefined> = contentChild(RtTreeNodeMetaDirective);\n\n /** Разметка в конце строки: вход раньше директивы — обёртка вроде селектора отдаёт её входом. */\n protected readonly endTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeEndTemplate() ?? this.nodeEnd()?.templateRef ?? null\n );\n\n /** Разметка под подписью: вход раньше директивы. */\n protected readonly metaTemplate: Signal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = computed(\n (): TemplateRef<IRtTree.NodeContext<TValue>> | null => this.nodeMetaTemplate() ?? this.nodeMeta()?.templateRef ?? null\n );\n\n /** Раскрытые ветки: до первого действия человека — ветки над выбранным. */\n protected readonly openBranches: Signal<ReadonlySet<TValue>> = computed(\n (): ReadonlySet<TValue> => this.#open() ?? rtTreeOpenFor(this.nodes(), this.value())\n );\n\n protected readonly rows: Signal<ReadonlyArray<IRtTree.Row<TValue>>> = computed((): ReadonlyArray<IRtTree.Row<TValue>> =>\n rtTreeRows(this.nodes(), this.openBranches(), this.filter() ? this.searchTerm() : '')\n );\n\n protected readonly views: Signal<ReadonlyArray<IRtTreeView<TValue>>> = computed((): ReadonlyArray<IRtTreeView<TValue>> => {\n const value: ReadonlyArray<TValue> = this.value();\n const cascade: boolean = this.cascade();\n const term: string = this.searchTerm();\n const highlighted: TValue | null = this.#highlighted();\n const mode: IRtTree.Mode = this.mode();\n const branchMarks: boolean = this.branchMarks();\n const treeDisabled: boolean = this.disabled();\n return this.rows().map((row: IRtTree.Row<TValue>): IRtTreeView<TValue> => {\n const marked: boolean = mode !== 'none' && (branchMarks || !row.branch);\n const state: IRtTree.RowState = this.rowState(row, value, cascade);\n return {\n row,\n marked,\n mark: state.mark,\n radio: state.radio,\n disabled: treeDisabled || !!row.option.disabled,\n count: marked ? null : state.count,\n parts: rtTreeLabelParts(row.option, term),\n highlighted: row.option.value === highlighted,\n };\n });\n });\n\n protected readonly selectAllMark: Signal<IRtTree.Mark> = computed((): IRtTree.Mark => this.selectAllMarkOf(this.rows(), this.value()));\n\n protected readonly isSelectAllShown: Signal<boolean> = computed(\n (): boolean => this.showSelectAll() && this.cascade() && this.mode() === 'multiple' && this.rows().length > 0\n );\n\n /** Отметка «выбрать всё» встаёт над отметкой первой строки; у строки без отметки — над стрелкой. */\n protected readonly isSelectAllUnderMark: Signal<boolean> = computed((): boolean => this.views()[0]?.marked ?? false);\n\n /** Первая строка — лист: там, где у листа нет места под стрелку, его нет и у «выбрать всё». */\n protected readonly isSelectAllOverLeaf: Signal<boolean> = computed((): boolean => this.views()[0]?.row.branch === false);\n\n protected readonly emptyText: Signal<string> = computed((): string =>\n this.nodes().length > 0 ? this.t().uiNothingFound : this.t().uiNoOptions\n );\n\n public readonly nodes: InputSignal<ReadonlyArray<IRtTree.Node<TValue>>> = input.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n public readonly value: ModelSignal<ReadonlyArray<TValue>> = model<ReadonlyArray<TValue>>([]);\n public readonly mode: InputSignal<IRtTree.Mode> = input<IRtTree.Mode>('multiple');\n public readonly cascade: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, { transform: booleanAttribute });\n public readonly searchTerm: InputSignal<string> = input<string>('');\n public readonly showSelectAll: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n\n /** Отметки у групп. Без них клик, пробел и Enter по группе раскрывают и сворачивают её. */\n public readonly branchMarks: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n\n /** Клик без Ctrl и Cmd выбирает узел один; с Ctrl или Cmd добавляет к выбору. Только для флажков. */\n public readonly exclusive: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n /** Скрывает ли слово поиска строки. Без отбора строки отбирает приложение, а слово только отмечено. */\n public readonly filter: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(true, {\n transform: booleanAttribute,\n });\n\n /** Выключенное дерево не меняет выбор ни кликом, ни клавишей, ни «выбрать всё»; ветки раскрываются стрелкой. */\n /** Значок кита над подписью пустого дерева. Без него пустое дерево — одна подпись. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /**\n * Разметка в конце каждой строки, отданная входом. Нужна компоненту, который оборачивает дерево и\n * не может положить в него директиву `rtTreeNodeEnd`; вход сильнее директивы.\n */\n public readonly nodeEndTemplate: InputSignal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = input<TemplateRef<\n IRtTree.NodeContext<TValue>\n > | null>(null);\n\n /** Разметка под подписью каждой строки, отданная входом; вход сильнее директивы `rtTreeNodeMeta`. */\n public readonly nodeMetaTemplate: InputSignal<TemplateRef<IRtTree.NodeContext<TValue>> | null> = input<TemplateRef<\n IRtTree.NodeContext<TValue>\n > | null>(null);\n\n public readonly disabled: InputSignalWithTransform<boolean, unknown> = input<boolean, unknown>(false, {\n transform: booleanAttribute,\n });\n\n public readonly picked: OutputEmitterRef<IRtTree.Node<TValue>> = output<IRtTree.Node<TValue>>();\n\n /**\n * Клавиша для дерева. Отвечает, взята ли она: не взятая идёт дальше нетронутой, поэтому\n * приложение может отдавать сюда каждую клавишу своего поля поиска.\n */\n public handleKeydown(event: KeyboardEvent): boolean {\n if (this.disabled()) {\n return false;\n }\n const taken: boolean = this.#takeKey(event.key, event.ctrlKey || event.metaKey);\n if (taken) {\n event.preventDefault();\n event.stopPropagation();\n }\n return taken;\n }\n\n public expandAll(): void {\n const all: Set<TValue> = new Set<TValue>();\n this.#collectBranches(this.nodes(), all);\n this.#open.set(all);\n }\n\n public collapseAll(): void {\n this.#open.set(new Set<TValue>());\n }\n\n public clearHighlight(): void {\n this.#highlighted.set(null);\n }\n\n protected onRowClick(row: IRtTree.Row<TValue>, event: MouseEvent): void {\n if (this.disabled()) {\n return;\n }\n this.#highlighted.set(row.option.value);\n if (row.option.disabled) {\n return;\n }\n if (this.#opensOnly(row)) {\n this.#toggleOrPick(row);\n return;\n }\n this.#choose(this.nextChoice(row.option, event.ctrlKey || event.metaKey));\n }\n\n protected onToggleClick(event: Event, value: TValue): void {\n event.stopPropagation();\n this.#toggle(value);\n }\n\n protected onSelectAll(): void {\n if (this.disabled()) {\n return;\n }\n this.#choose(this.selectAllChoice(this.rows(), this.value()));\n }\n\n /**\n * Отметка строки, её вид и число выбранного под ней. Дерево числа не рисует; наследник со своими\n * правилами выбора считает всё это по ним.\n */\n protected rowState(row: IRtTree.Row<TValue>, value: ReadonlyArray<TValue>, cascade: boolean): IRtTree.RowState {\n return { mark: rtTreeMark(row.option, value, cascade), radio: this.mode() === 'single', count: null };\n }\n\n protected selectAllMarkOf(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): IRtTree.Mark {\n return rtTreeSelectAllMark(rows, value);\n }\n\n protected selectAllChoice(rows: ReadonlyArray<IRtTree.Row<TValue>>, value: ReadonlyArray<TValue>): ReadonlyArray<TValue> {\n return rtTreeSelectAll(rows, value);\n }\n\n /** Выбор после действия над узлом: в исключающем режиме без Ctrl и Cmd узел остаётся один. */\n protected nextChoice(node: IRtTree.Node<TValue>, additive: boolean): ReadonlyArray<TValue> {\n if (this.exclusive() && this.mode() === 'multiple' && !additive) {\n return rtTreeChooseAlone(this.nodes(), node, this.value(), this.cascade());\n }\n return rtTreeChoose(node, this.value(), this.mode(), this.cascade());\n }\n\n /** Строка, клик по которой ничего не отмечает: режим без отметок или группа без флажка. */\n #opensOnly(row: IRtTree.Row<TValue>): boolean {\n return this.mode() === 'none' || (row.branch && !this.branchMarks());\n }\n\n #toggleOrPick(row: IRtTree.Row<TValue>): void {\n if (row.branch) {\n this.#toggle(row.option.value);\n } else {\n this.picked.emit(row.option);\n }\n }\n\n #collectBranches(list: ReadonlyArray<IRtTree.Node<TValue>>, into: Set<TValue>): void {\n list.forEach((node: IRtTree.Node<TValue>): void => {\n if ((node.children ?? []).length > 0) {\n into.add(node.value);\n this.#collectBranches(node.children ?? [], into);\n }\n });\n }\n\n /**\n * Меняет выбор, не трогая раскрытие. Пока ветки никто не раскрывал руками, раскрытие считается из\n * выбора, и без этой фиксации отметка ветки сворачивала или раскрывала её саму.\n */\n #choose(next: ReadonlyArray<TValue>): void {\n this.#open.set(this.openBranches());\n this.value.set(next);\n }\n\n #toggle(value: TValue): void {\n this.#open.set(rtTreeToggle(this.openBranches(), value));\n }\n\n #highlightedIndex(): number {\n const highlighted: TValue | null = this.#highlighted();\n return this.rows().findIndex((row: IRtTree.Row<TValue>): boolean => row.option.value === highlighted);\n }\n\n #takeKey(key: string, additive: boolean): boolean {\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const index: number = this.#highlightedIndex();\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n return this.#move(rows, index, key === 'ArrowDown' ? 1 : -1);\n }\n return index >= 0 && this.#takeRowKey(rows, index, key, additive);\n }\n\n /** Клавиши, которым нужна подсвеченная строка. */\n #takeRowKey(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, key: string, additive: boolean): boolean {\n if (key === 'Home' || key === 'End') {\n return this.#edge(rows, key);\n }\n if (key === 'ArrowRight' || key === 'ArrowLeft') {\n this.#side(rows, index, key);\n return true;\n }\n if (key === ' ') {\n this.#space(rows[index], additive);\n return true;\n }\n if (key === 'Enter') {\n this.#enter(rows[index], additive);\n return true;\n }\n return false;\n }\n\n #move(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, step: number): boolean {\n if (rows.length === 0) {\n return false;\n }\n const next: number = index < 0 ? 0 : Math.min(rows.length - 1, Math.max(0, index + step));\n this.#highlighted.set(rows[next].option.value);\n return true;\n }\n\n /** Home и End ведут подсветку к первой и последней строке; без подсветки они остаются у курсора поля. */\n #edge(rows: ReadonlyArray<IRtTree.Row<TValue>>, key: string): boolean {\n this.#highlighted.set(rows[key === 'Home' ? 0 : rows.length - 1].option.value);\n return true;\n }\n\n #side(rows: ReadonlyArray<IRtTree.Row<TValue>>, index: number, key: string): void {\n const answer: IRtOptionTree.SideKeyAnswer<TValue> = rtTreeSideKey(rows, index, key);\n if (answer.toggle !== null) {\n this.#toggle(answer.toggle);\n }\n this.#highlighted.set(rows[answer.index].option.value);\n }\n\n #space(row: IRtTree.Row<TValue>, additive: boolean): void {\n if (this.#opensOnly(row) && row.branch) {\n this.#toggle(row.option.value);\n return;\n }\n if (!row.option.disabled && this.mode() !== 'none') {\n this.#choose(this.nextChoice(row.option, additive));\n }\n }\n\n #enter(row: IRtTree.Row<TValue>, additive: boolean): void {\n if (this.#opensOnly(row) && row.branch) {\n this.#toggle(row.option.value);\n return;\n }\n if (row.option.disabled) {\n return;\n }\n if (this.mode() !== 'none') {\n this.#choose(this.nextChoice(row.option, additive));\n }\n this.picked.emit(row.option);\n }\n}\n","<ng-container rtBlock=\"rt-tree\">\n <!--\n Строки выбираются мышью через (click); клавиатура — на самом дереве (handleKeydown), строки\n по отдельности фокус не берут: подсветка — третье состояние рядом с фокусом и выбором.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n @if (isSelectAllShown()) {\n <div\n rtElem=\"select-all\"\n qa-dataid=\"tree-select-all\"\n role=\"presentation\"\n [rtMod]=\"{ disabled: disabled(), 'over-leaf': isSelectAllOverLeaf() }\"\n (click)=\"onSelectAll()\">\n @if (isSelectAllUnderMark()) {\n <span rtElem=\"toggle-space\"></span>\n }\n <rt-checkbox\n rtElem=\"check\"\n inert\n [disabled]=\"disabled()\"\n [indeterminate]=\"selectAllMark() === 'some'\"\n [ngModel]=\"selectAllMark() === 'all'\"\n [ngModelOptions]=\"{ standalone: true }\" />\n <span rtElem=\"label\">{{ t().uiSelectAll }}</span>\n </div>\n }\n\n @for (view of views(); track view.row.option.value) {\n <div\n rtElem=\"row\"\n qa-dataid=\"tree-row\"\n role=\"treeitem\"\n [attr.data-value]=\"view.row.option.value\"\n [attr.aria-level]=\"view.row.level + 1\"\n [attr.aria-expanded]=\"view.row.branch ? view.row.open : null\"\n [attr.aria-selected]=\"view.marked ? view.mark === 'all' : null\"\n [attr.aria-disabled]=\"view.disabled\"\n [style.--rt-tree-level]=\"view.row.level\"\n [rtMod]=\"{ highlighted: view.highlighted, disabled: view.disabled, chosen: view.mark === 'all' }\"\n (click)=\"onRowClick(view.row, $event)\">\n @if (view.row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"tree-row-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"view.row.open ? t().uiCollapse : t().uiExpand\"\n (click)=\"onToggleClick($event, view.row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"view.row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n\n @if (view.marked && !view.radio) {\n <rt-checkbox\n rtElem=\"check\"\n qa-dataid=\"tree-row-checkbox\"\n inert\n [disabled]=\"view.disabled\"\n [indeterminate]=\"view.mark === 'some'\"\n [ngModel]=\"view.mark === 'all'\"\n [ngModelOptions]=\"{ standalone: true }\" />\n } @else if (view.marked) {\n <rt-radio-button\n rtElem=\"check\"\n qa-dataid=\"tree-row-radio\"\n inert\n [value]=\"view.row.option.value\"\n [checked]=\"view.mark === 'all'\"\n [disabled]=\"view.disabled\" />\n }\n\n <span rtElem=\"text\">\n <span rtElem=\"label\" qa-dataid=\"tree-row-label\" rtTooltipWhenTruncated [rtTooltip]=\"view.row.option.label\">\n @for (part of view.parts.label; track $index) {\n <span rtElem=\"part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n @if (view.parts.description.length > 0) {\n <span\n rtElem=\"description\"\n qa-dataid=\"tree-row-description\"\n rtTooltipWhenTruncated\n [rtTooltip]=\"view.row.option.description\">\n @for (part of view.parts.description; track $index) {\n <span rtElem=\"part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n }\n @if (view.row.option.badges?.length || metaTemplate()) {\n <span rtElem=\"meta\" qa-dataid=\"tree-row-meta\">\n @for (badge of view.row.option.badges; track $index) {\n <rt-tag size=\"sm\" [value]=\"badge.text\" [severity]=\"badge.severity ?? 'neutral'\" [highlight]=\"searchTerm()\" />\n }\n @if (metaTemplate(); as meta) {\n <ng-container [ngTemplateOutlet]=\"meta\" [ngTemplateOutletContext]=\"{ $implicit: view.row.option }\" />\n }\n </span>\n }\n </span>\n\n @if (view.count) {\n <span rtElem=\"count\" qa-dataid=\"tree-row-count\">{{ view.count }}</span>\n }\n\n @if (endTemplate(); as end) {\n <span rtElem=\"end\" qa-dataid=\"tree-row-end\">\n <ng-container [ngTemplateOutlet]=\"end\" [ngTemplateOutletContext]=\"{ $implicit: view.row.option }\" />\n </span>\n }\n </div>\n } @empty {\n <div rtElem=\"empty\" qa-dataid=\"tree-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"tree-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ emptyText() }}\n </div>\n }\n</ng-container>\n"],"mappings":";;;;;;;;;;;;AASA,IAAa,yBAAb,MAAa,uBAAsB;CADnC,cAAA;EAEoB,KAAA,cAAwD,OAAiD,WAAW;CACvI;CAFY;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAsB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAtB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAsB,cAAA;GAAA,UAAA;GAAA,UAAA;EAAA,CAAA;CAAA;;AAAtB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAsB,YAAA,CAAA;EADlC,MAAA;EAAU,MAAA,CAAA,EAAE,UAAU,6BAA4B,CAAE;;;AAUrD,IAAa,0BAAb,MAAa,wBAAuB;CADpC,cAAA;EAEoB,KAAA,cAAwD,OAAiD,WAAW;CACvI;CAFY;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAuB,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAvB;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAuB,cAAA;GAAA,UAAA;GAAA,UAAA;EAAA,CAAA;CAAA;;AAAvB,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAuB,YAAA,CAAA;EADnC,MAAA;EAAU,MAAA,CAAA,EAAE,UAAU,8BAA6B,CAAE;;;ACJtD,SAAS,SAAiB,MAAmB;CACzC,QAAQ,KAAK,YAAY,CAAA,EAAA,CAAI,SAAS;AAC1C;AAEA,SAAS,QAAgB,OAA8B,MAA2B;CAC9E,OAAO,MAAM,QAAQ,SAA0B,CAAC,KAAK,SAAS,IAAI,CAAC;AACvE;AAEA,SAAS,QAAgB,OAA8B,KAA0B;CAC7E,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,QAAQ,SAA0B,CAAC,MAAM,SAAS,IAAI,CAAC,CAAC;AACrF;AAMA,SAAgB,WAAmB,MAAqB,OAA8B,SAAgB;CAClG,IAAI,WAAW,SAAS,IAAI,GACxB,OAAO,kBAAkB,MAAM,KAAK;CAExC,OAAO,MAAM,SAAS,KAAK,KAAK,IAAI,QAAQ;AAChD;AAOA,SAAgB,aACZ,MACA,OACA,MACA,SAAgB;CAEhB,IAAI,KAAK,YAAY,SAAS,QAC1B,OAAO;CAEX,IAAI,SAAS,UACT,OAAO,CAAC,KAAK,KAAK;CAEtB,IAAI,WAAW,SAAS,IAAI,GAAG;EAC3B,MAAM,SAAgC,aAAa,IAAI;EACvD,OAAO,kBAAkB,MAAM,KAAK,MAAM,QAAQ,QAAQ,OAAO,MAAM,IAAI,QAAQ,OAAO,MAAM;CACpG;CACA,OAAO,MAAM,SAAS,KAAK,KAAK,IAAI,QAAQ,OAAO,CAAC,KAAK,KAAK,CAAC,IAAI,QAAQ,OAAO,CAAC,KAAK,KAAK,CAAC;AAClG;AAMA,SAAgB,oBAA4B,MAAwC;CAChF,OAAO,KAAK,SAAS,QAAqD,IAAI,UAAU,IAAI,OAAO,CAAA,IAAK,aAAa,IAAI,MAAM,CAAE;AACrI;AAGA,SAAgB,oBAA4B,MAA0C,OAA4B;CAC9G,MAAM,SAAgC,oBAAoB,IAAI;CAC9D,MAAM,QAAgB,OAAO,QAAQ,SAA0B,MAAM,SAAS,IAAI,CAAC,CAAC,CAAC;CACrF,IAAI,UAAU,GACV,OAAO;CAEX,OAAO,UAAU,OAAO,SAAS,QAAQ;AAC7C;AAMA,SAAgB,gBAAwB,MAA0C,OAA4B;CAC1G,MAAM,SAAgC,oBAAoB,IAAI;CAC9D,OAAO,oBAAoB,MAAM,KAAK,MAAM,QAAQ,QAAQ,OAAO,MAAM,IAAI,QAAQ,OAAO,MAAM;AACtG;AAMA,SAAgB,iBAAyB,MAAqB,MAAY;CACtE,OAAO;EACH,OAAO,aAAa,KAAK,OAAO,IAAI;EACpC,aAAa,aAAa,KAAK,eAAe,IAAI,IAAI;EACtD,SAAS,KAAK,UAAU,CAAA,EAAA,CAAI,KAAK,UAAsD,aAAa,MAAM,MAAM,IAAI,CAAC;CACxH;AACL;AAGA,SAAS,QAAgB,MAAmB;CACxC,OAAO,CAAC,KAAK,OAAO,IAAI,KAAK,YAAY,CAAA,EAAA,CAAI,SAAS,UAAgD,QAAQ,KAAK,CAAC,CAAC;AACzH;AAGA,SAAS,eAAuB,OAAmC;CAC/D,OAAO,MAAM,SAAS,SAA+C,CACjE,GAAI,KAAK,WAAW,CAAC,KAAK,KAAK,IAAI,CAAA,GACnC,GAAG,eAAe,KAAK,YAAY,CAAA,CAAE,CACxC,CAAA;AACL;AAGA,SAAgB,gBACZ,OACA,MACA,OAA4B;CAE5B,MAAM,OAA8B,CAAC,GAAG,QAAQ,IAAI,GAAG,GAAG,eAAe,KAAK,CAAC;CAC/E,OAAO,MAAM,QAAQ,SAA0B,KAAK,SAAS,IAAI,CAAC;AACtE;AAOA,SAAgB,kBACZ,OACA,MACA,OACA,SAAgB;CAEhB,IAAI,KAAK,UACL,OAAO;CAEX,OAAO,aAAa,MAAM,gBAAgB,OAAO,MAAM,KAAK,GAAG,YAAY,OAAO;AACtF;ACpGA,MAAM,YAAoB;AAwD1B,IAAa,kBAAb,MAAa,gBAAe;CA5B5B,cAAA;EA6Ba,KAAA,QAAoD,OAAmC,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAC5F,KAAA,eAA8C,OAAsB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAE/D,KAAA,IAA4B,OAAO,aAAa;EAEhD,KAAA,UAA8D,aAAa,wBAAuB,GAAA,YAAA,CAAA,EAAA,WAAA,UAAA,CAAA,+BAAA,CAAA,CAAA;EAElG,KAAA,WAAgE,aAAa,yBAAwB,GAAA,YAAA,CAAA,EAAA,WAAA,WAAA,CAAA,+BAAA,CAAA,CAAA;EAGrG,KAAA,cAAuE,eAC/B,KAAK,gBAAe,KAAM,KAAK,QAAO,CAAE,EAAE,eAAe,MACnH,GAAA,YAAA,CAAA,EAAA,WAAA,cAAA,CAAA,+BAAA,CAAA,CAAA;EAGkB,KAAA,eAAwE,eAChC,KAAK,iBAAgB,KAAM,KAAK,SAAQ,CAAE,EAAE,eAAe,MACrH,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAGkB,KAAA,eAA4C,eAChC,KAAK,MAAK,KAAM,cAAc,KAAK,MAAK,GAAI,KAAK,MAAK,CAAE,GACtF,GAAA,YAAA,CAAA,EAAA,WAAA,eAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,OAAmD,eAClE,WAAW,KAAK,MAAK,GAAI,KAAK,aAAY,GAAI,KAAK,OAAM,IAAK,KAAK,WAAU,IAAK,EAAE,GACvF,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EAEkB,KAAA,QAAoD,eAAkD;GACrH,MAAM,QAA+B,KAAK,MAAK;GAC/C,MAAM,UAAmB,KAAK,QAAO;GACrC,MAAM,OAAe,KAAK,WAAU;GACpC,MAAM,cAA6B,KAAK,aAAY;GACpD,MAAM,OAAqB,KAAK,KAAI;GACpC,MAAM,cAAuB,KAAK,YAAW;GAC7C,MAAM,eAAwB,KAAK,SAAQ;GAC3C,OAAO,KAAK,KAAI,CAAE,CAAC,KAAK,QAAiD;IACrE,MAAM,SAAkB,SAAS,WAAW,eAAe,CAAC,IAAI;IAChE,MAAM,QAA0B,KAAK,SAAS,KAAK,OAAO,OAAO;IACjE,OAAO;KACH;KACA;KACA,MAAM,MAAM;KACZ,OAAO,MAAM;KACb,UAAU,gBAAgB,CAAC,CAAC,IAAI,OAAO;KACvC,OAAO,SAAS,OAAO,MAAM;KAC7B,OAAO,iBAAiB,IAAI,QAAQ,IAAI;KACxC,aAAa,IAAI,OAAO,UAAU;IACrC;GACL,CAAC;EACL,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAEiB,KAAA,gBAAsC,eAA6B,KAAK,gBAAgB,KAAK,KAAI,GAAI,KAAK,MAAK,CAAE,GAAE,GAAA,YAAA,CAAA,EAAA,WAAA,gBAAA,CAAA,+BAAA,CAAA,CAAA;EAEnH,KAAA,mBAAoC,eACpC,KAAK,cAAa,KAAM,KAAK,QAAO,KAAM,KAAK,KAAI,MAAO,cAAc,KAAK,KAAI,CAAE,CAAC,SAAS,GAC/G,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;EAGkB,KAAA,uBAAwC,eAAwB,KAAK,MAAK,CAAE,CAAC,EAAE,EAAE,UAAU,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,uBAAA,CAAA,+BAAA,CAAA,CAAA;EAGjG,KAAA,sBAAuC,eAAwB,KAAK,MAAK,CAAE,CAAC,EAAE,EAAE,IAAI,WAAW,OAAM,GAAA,YAAA,CAAA,EAAA,WAAA,sBAAA,CAAA,+BAAA,CAAA,CAAA;EAErG,KAAA,YAA4B,eAC3C,KAAK,MAAK,CAAE,CAAC,SAAS,IAAI,KAAK,EAAC,CAAE,CAAC,iBAAiB,KAAK,EAAC,CAAE,CAAC,aAChE,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAEe,KAAA,QAA0D,MAAM,SAA+C,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAC/G,KAAA,QAA4C,MAA6B,CAAA,GAAG,GAAA,YAAA,CAAA,EAAA,WAAA,QAAA,CAAA,+BAAA,CAAA,CAAA;EAC5E,KAAA,OAAkC,MAAoB,YAAW,GAAA,YAAA,CAAA,EAAA,WAAA,OAAA,CAAA,+BAAA,CAAA,CAAA;EACjE,KAAA,UAAsD,MAAwB,MAAI;GAAA,GAAA,YAAA,EAAA,WAAA,UAAA,+BAAA,CAAA;GAAI,WAAW;EAAgB,CAAA;EACjH,KAAA,aAAkC,MAAc,IAAG,GAAA,YAAA,CAAA,EAAA,WAAA,aAAA,CAAA,+BAAA,CAAA,CAAA;EACnD,KAAA,gBAA4D,MAAwB,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,gBAAA,+BAAA,CAAA;GACrG,WAAW;EAAgB,CAAA;EAEf,KAAA,YAAwC,MAAqB,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAGlE,KAAA,cAA0D,MAAwB,MAAI;GAAA,GAAA,YAAA,EAAA,WAAA,cAAA,+BAAA,CAAA;GAClG,WAAW;EAAgB,CAAA;EAIf,KAAA,YAAwD,MAAwB,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,YAAA,+BAAA,CAAA;GACjG,WAAW;EAAgB,CAAA;EAIf,KAAA,SAAqD,MAAwB,MAAI;GAAA,GAAA,YAAA,EAAA,WAAA,SAAA,+BAAA,CAAA;GAC7F,WAAW;EAAgB,CAAA;EAKf,KAAA,YAA8C,MAA2B,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,YAAA,CAAA,+BAAA,CAAA,CAAA;EAM9E,KAAA,kBAAgF,MAEtF,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,kBAAA,CAAA,+BAAA,CAAA,CAAA;EAGC,KAAA,mBAAiF,MAEvF,MAAK,GAAA,YAAA,CAAA,EAAA,WAAA,mBAAA,CAAA,+BAAA,CAAA,CAAA;EAEC,KAAA,WAAuD,MAAwB,OAAK;GAAA,GAAA,YAAA,EAAA,WAAA,WAAA,+BAAA,CAAA;GAChG,WAAW;EAAgB,CAAA;EAGf,KAAA,SAAiD,OAAM;CAsM1E;CAxTY;CACA;CAuHF,cAAc,OAAoB;EACrC,IAAI,KAAK,SAAQ,GACb,OAAO;EAEX,MAAM,QAAiB,KAAK,SAAS,MAAM,KAAK,MAAM,WAAW,MAAM,OAAO;EAC9E,IAAI,OAAO;GACP,MAAM,eAAc;GACpB,MAAM,gBAAe;EACzB;EACA,OAAO;CACX;CAEO,YAAS;EACZ,MAAM,sBAAmB,IAAI,IAAG;EAChC,KAAK,iBAAiB,KAAK,MAAK,GAAI,GAAG;EACvC,KAAK,MAAM,IAAI,GAAG;CACtB;CAEO,cAAW;EACd,KAAK,MAAM,oBAAI,IAAI,IAAG,CAAU;CACpC;CAEO,iBAAc;EACjB,KAAK,aAAa,IAAI,IAAI;CAC9B;CAEU,WAAW,KAA0B,OAAiB;EAC5D,IAAI,KAAK,SAAQ,GACb;EAEJ,KAAK,aAAa,IAAI,IAAI,OAAO,KAAK;EACtC,IAAI,IAAI,OAAO,UACX;EAEJ,IAAI,KAAK,WAAW,GAAG,GAAG;GACtB,KAAK,cAAc,GAAG;GACtB;EACJ;EACA,KAAK,QAAQ,KAAK,WAAW,IAAI,QAAQ,MAAM,WAAW,MAAM,OAAO,CAAC;CAC5E;CAEU,cAAc,OAAc,OAAa;EAC/C,MAAM,gBAAe;EACrB,KAAK,QAAQ,KAAK;CACtB;CAEU,cAAW;EACjB,IAAI,KAAK,SAAQ,GACb;EAEJ,KAAK,QAAQ,KAAK,gBAAgB,KAAK,KAAI,GAAI,KAAK,MAAK,CAAE,CAAC;CAChE;CAMU,SAAS,KAA0B,OAA8B,SAAgB;EACvF,OAAO;GAAE,MAAM,WAAW,IAAI,QAAQ,OAAO,OAAO;GAAG,OAAO,KAAK,KAAI,MAAO;GAAU,OAAO;EAAI;CACvG;CAEU,gBAAgB,MAA0C,OAA4B;EAC5F,OAAO,oBAAoB,MAAM,KAAK;CAC1C;CAEU,gBAAgB,MAA0C,OAA4B;EAC5F,OAAO,gBAAgB,MAAM,KAAK;CACtC;CAGU,WAAW,MAA4B,UAAiB;EAC9D,IAAI,KAAK,UAAS,KAAM,KAAK,KAAI,MAAO,cAAc,CAAC,UACnD,OAAO,kBAAkB,KAAK,MAAK,GAAI,MAAM,KAAK,MAAK,GAAI,KAAK,QAAO,CAAE;EAE7E,OAAO,aAAa,MAAM,KAAK,MAAK,GAAI,KAAK,KAAI,GAAI,KAAK,QAAO,CAAE;CACvE;CAGA,WAAW,KAAwB;EAC/B,OAAO,KAAK,KAAI,MAAO,UAAW,IAAI,UAAU,CAAC,KAAK,YAAW;CACrE;CAEA,cAAc,KAAwB;EAClC,IAAI,IAAI,QACJ,KAAK,QAAQ,IAAI,OAAO,KAAK;OAE7B,KAAK,OAAO,KAAK,IAAI,MAAM;CAEnC;CAEA,iBAAiB,MAA2C,MAAiB;EACzE,KAAK,SAAS,SAAoC;GAC9C,KAAK,KAAK,YAAY,CAAA,EAAA,CAAI,SAAS,GAAG;IAClC,KAAK,IAAI,KAAK,KAAK;IACnB,KAAK,iBAAiB,KAAK,YAAY,CAAA,GAAI,IAAI;GACnD;EACJ,CAAC;CACL;CAMA,QAAQ,MAA2B;EAC/B,KAAK,MAAM,IAAI,KAAK,aAAY,CAAE;EAClC,KAAK,MAAM,IAAI,IAAI;CACvB;CAEA,QAAQ,OAAa;EACjB,KAAK,MAAM,IAAI,aAAa,KAAK,aAAY,GAAI,KAAK,CAAC;CAC3D;CAEA,oBAAiB;EACb,MAAM,cAA6B,KAAK,aAAY;EACpD,OAAO,KAAK,KAAI,CAAE,CAAC,WAAW,QAAsC,IAAI,OAAO,UAAU,WAAW;CACxG;CAEA,SAAS,KAAa,UAAiB;EACnC,MAAM,OAA2C,KAAK,KAAI;EAC1D,MAAM,QAAgB,KAAK,kBAAiB;EAC5C,IAAI,QAAQ,eAAe,QAAQ,WAC/B,OAAO,KAAK,MAAM,MAAM,OAAO,QAAQ,cAAc,IAAI,EAAE;EAE/D,OAAO,SAAS,KAAK,KAAK,YAAY,MAAM,OAAO,KAAK,QAAQ;CACpE;CAGA,YAAY,MAA0C,OAAe,KAAa,UAAiB;EAC/F,IAAI,QAAQ,UAAU,QAAQ,OAC1B,OAAO,KAAK,MAAM,MAAM,GAAG;EAE/B,IAAI,QAAQ,gBAAgB,QAAQ,aAAa;GAC7C,KAAK,MAAM,MAAM,OAAO,GAAG;GAC3B,OAAO;EACX;EACA,IAAI,QAAQ,KAAK;GACb,KAAK,OAAO,KAAK,QAAQ,QAAQ;GACjC,OAAO;EACX;EACA,IAAI,QAAQ,SAAS;GACjB,KAAK,OAAO,KAAK,QAAQ,QAAQ;GACjC,OAAO;EACX;EACA,OAAO;CACX;CAEA,MAAM,MAA0C,OAAe,MAAY;EACvE,IAAI,KAAK,WAAW,GAChB,OAAO;EAEX,MAAM,OAAe,QAAQ,IAAI,IAAI,KAAK,IAAI,KAAK,SAAS,GAAG,KAAK,IAAI,GAAG,QAAQ,IAAI,CAAC;EACxF,KAAK,aAAa,IAAI,KAAK,KAAK,CAAC,OAAO,KAAK;EAC7C,OAAO;CACX;CAGA,MAAM,MAA0C,KAAW;EACvD,KAAK,aAAa,IAAI,KAAK,QAAQ,SAAS,IAAI,KAAK,SAAS,EAAE,CAAC,OAAO,KAAK;EAC7E,OAAO;CACX;CAEA,MAAM,MAA0C,OAAe,KAAW;EACtE,MAAM,SAA8C,cAAc,MAAM,OAAO,GAAG;EAClF,IAAI,OAAO,WAAW,MAClB,KAAK,QAAQ,OAAO,MAAM;EAE9B,KAAK,aAAa,IAAI,KAAK,OAAO,MAAM,CAAC,OAAO,KAAK;CACzD;CAEA,OAAO,KAA0B,UAAiB;EAC9C,IAAI,KAAK,WAAW,GAAG,KAAK,IAAI,QAAQ;GACpC,KAAK,QAAQ,IAAI,OAAO,KAAK;GAC7B;EACJ;EACA,IAAI,CAAC,IAAI,OAAO,YAAY,KAAK,KAAI,MAAO,QACxC,KAAK,QAAQ,KAAK,WAAW,IAAI,QAAQ,QAAQ,CAAC;CAE1D;CAEA,OAAO,KAA0B,UAAiB;EAC9C,IAAI,KAAK,WAAW,GAAG,KAAK,IAAI,QAAQ;GACpC,KAAK,QAAQ,IAAI,OAAO,KAAK;GAC7B;EACJ;EACA,IAAI,IAAI,OAAO,UACX;EAEJ,IAAI,KAAK,KAAI,MAAO,QAChB,KAAK,QAAQ,KAAK,WAAW,IAAI,QAAQ,QAAQ,CAAC;EAEtD,KAAK,OAAO,KAAK,IAAI,MAAM;CAC/B;CAxTS;EAAA,KAAA,OAAA,GAAA,mBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,UAAA;GAAA,MAAA;GAAe,MAAA,CAAA;GAAA,QAAA,GAAA,gBAAA;EAAA,CAAA;CAAA;CAAf;EAAA,KAAA,OAAA,GAAA,qBAAA;GAAA,YAAA;GAAA,SAAA;GAAA,MAAA;GAAe,cAAA;GAAA,UAAA;GAAA,QAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,OAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,MAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,SAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,YAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,eAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,aAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,QAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,WAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,iBAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,kBAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;IAAA,UAAA;KAAA,mBAAA;KAAA,YAAA;KAAA,UAAA;KAAA,YAAA;KAAA,mBAAA;IAAA;GAAA;GAAA,SAAA;IAAA,OAAA;IAAA,QAAA;GAAA;GAAA,MAAA;IAAA,YAAA,EAAA,QAAA,OAAA;IAAA,WAAA,EAAA,WAAA,wBAAA;IAAA,YAAA;KAAA,iBAAA;KAAA,sBAAA;KAAA,mBAAA;KAAA,6BAAA;IAAA;IAAA,gBAAA;GAAA;GAAA,SAAA,CAAA;IAAA,cAAA;IAAA,OAAA;IAAA,WAMsE;IAAsB,aAAA;IAAA,UAAA;GAAA,GAAA;IAAA,cAAA;IAAA,OAAA;IAAA,WAEpB;IAAuB,aAAA;IAAA,UAAA;GAAA,CAAA;GAAA,UAAA;GAAA,UCrG3H;GAyHA,QAAA,CAAA,09OAAA;GAAA,cAAA;IAAA;KAAA,MAAA;KAAA,MDjDQ;KAAgB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAChB;IAAW;IAAA;KAAA,MAAA;KAAA,MAAA,GAAA;KAAA,UAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAAA,GAAA;KAAA,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,eAAA;KAAA,UAAA,CAAA,SAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACX;KAAmB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,eAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACnB;KAAe,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACf;KAAsB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,eAAA,eAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACtB;KAAc,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,SAAA,CAAA,QAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAkB,UAAA;KAAA,QAAA;MAAA;MAAA;MAAA;MAAA;MAAA;KAAA;KAAA,UAAA,CAAA,WAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MAClB;KAAc,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACd;KAAa,UAAA;KAAA,QAAA,CAAA,OAAA;IAAA;IAAA;KAAA,MAAA;KAAA,MACb;KAAY,UAAA;IAAA;GAAA;GAAA,iBAAA,GAAA,wBAAA;GAAA,eAAA,GAAA,kBAAA;EAAA,CAAA;CAAA;;AAYP,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAe,YAAA,CAAA;EA5B3B,MAAA;EACa,MAAA,CAAA;GAAA,UAAA;GAAS,iBAGF,wBAAwB;GAAM,eAChC,kBAAkB;GAAI,SAC5B;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACH;GAAA,MACK;IACF,OAAO;IACP,MAAM;IACN,mBAAmB;IACnB,wBAAwB;IACxB,qBAAqB;IACrB,+BAA+B;IAC/B,aAAa;GAChB;GAAA,UAAA;GAAA,QAAA,CAAA,09OAAA;EAAA,CAAA;CAQ6F,CAAA;CAAA,gBAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,GAAA,iBAAA,sBAAsB,GAAA,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,GAAA,iBAEpB,uBAAuB,GAAA,EAAA,UAAA,KAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,OAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,GAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,aAAA;EAAA,CAAA;EAAA,MAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,SAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,YAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,eAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,aAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,QAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,WAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,iBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,kBAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,UAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA;IAAA,UAAA;IAAA,OAAA;IAAA,UAAA;GAAA,CAAA;EAAA,CAAA;EAAA,QAAA,CAAA;GAAA,MAAA,GAAA;GAAA,MAAA,CAAA,QAAA;EAAA,CAAA;CAAA;AAAA,CAAA"}
|
|
@@ -297,7 +297,7 @@ var RtWorkspaceDetailsComponent = class RtWorkspaceDetailsComponent {
|
|
|
297
297
|
},
|
|
298
298
|
host: { classAttribute: "rt-workspace-details" },
|
|
299
299
|
ngImport: i0,
|
|
300
|
-
template: "<ng-container rtBlock=\"rt-workspace-details\">\n @if (title(); as headTitle) {\n <header rtElem=\"head\">\n <span rtElem=\"head-title\" qa-dataid=\"workspace-details-title\">{{ headTitle }}</span>\n </header>\n }\n\n @if (hasTabs()) {\n <rt-tabs rtElem=\"tabs\" qa-dataid=\"workspace-details-tabs\">\n <ng-template rtTab=\"details\" [label]=\"t().uiDetails\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </ng-template>\n\n <ng-template rtTab=\"transition\" [label]=\"t().uiStageTransition\" [hidden]=\"transition() === null\">\n @if (transition(); as stageTransition) {\n @if (stageTransition.currentStageLabel; as stageLabel) {\n <rt-detail-list>\n <rt-detail-row qa-dataid=\"workspace-details-current-stage\" [label]=\"t().uiCurrentStage\">\n {{ stageLabel }}\n </rt-detail-row>\n </rt-detail-list>\n }\n\n @if (noTransitions()) {\n <rt-note qa-dataid=\"workspace-details-no-transitions\">{{ stageTransition.noTransitionsText }}</rt-note>\n } @else {\n <form\n rtElem=\"transition-form\"\n qa-dataid=\"workspace-details-transition-form\"\n [formGroup]=\"transitionForm\"\n (ngSubmit)=\"onTransitionSubmit()\">\n <rt-field\n [label]=\"t().uiTargetStage\"\n [loading]=\"stageTransition.loading\"\n [errors]=\"{ required: t().uiTargetStageRequired }\">\n <rt-select\n formControlName=\"to_key\"\n qa-dataid=\"workspace-details-transition-stage\"\n [placeholder]=\"t().uiPickTransition\"\n [options]=\"stageTransition.options\" />\n </rt-field>\n\n <rt-field [label]=\"t().uiCommentOptional\" [hint]=\"t().uiStageNoteHint\" [loading]=\"stageTransition.loading\">\n <rt-textarea formControlName=\"note\" qa-dataid=\"workspace-details-transition-note\" rows=\"3\" />\n </rt-field>\n\n <button\n rtButton\n rtElem=\"transition-submit\"\n qa-dataid=\"workspace-details-transition-submit\"\n type=\"submit\"\n [label]=\"t().uiMoveStage\"\n [attr.aria-label]=\"t().uiMoveStageAria\"\n [loading]=\"stageTransition.submitting\"\n [disabled]=\"stageTransition.loading || busy()\"></button>\n </form>\n }\n }\n </ng-template>\n\n <ng-template rtTab=\"audit\" [label]=\"t().uiHistory\" [hidden]=\"audit() === null\">\n @if (audit(); as auditFeed) {\n <div rtElem=\"audit\" qa-dataid=\"workspace-details-audit\">\n @if (auditFeed.loading) {\n <rt-spinner rtElem=\"audit-loading\" qa-dataid=\"workspace-details-audit-loading\" />\n } @else if (auditFeed.steps.length === 0) {\n <rt-empty-state\n qa-dataid=\"workspace-details-audit-empty\"\n icon=\"history\"\n [description]=\"t().uiAuditEmptyHint\"\n [title]=\"auditFeed.emptyText\" />\n } @else {\n <rt-timeline qa-dataid=\"workspace-details-audit-timeline\" [steps]=\"auditFeed.steps\" />\n }\n\n @if (auditFeed.hasMore) {\n <button\n rtButton\n rtElem=\"audit-more\"\n qa-dataid=\"workspace-details-audit-more\"\n type=\"button\"\n appearance=\"text\"\n [label]=\"t().uiLoadMore\"\n [attr.aria-label]=\"t().uiLoadMore\"\n [loading]=\"auditFeed.loadingMore\"\n [disabled]=\"auditFeed.loadingMore\"\n (click)=\"onAuditLoadMore()\"></button>\n }\n </div>\n }\n </ng-template>\n </rt-tabs>\n } @else {\n <div rtElem=\"body\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </div>\n }\n\n <ng-template #detailsTpl>\n @if (rows().length > 0) {\n <rt-detail-list>\n @for (row of rows(); track row.label) {\n <rt-detail-row qa-dataid=\"workspace-details-row\" [label]=\"row.label\" [loading]=\"loading()\">\n @if (row.agent && agentEdit(); as edit) {\n @if (!editingAgent()) {\n <div rtElem=\"agent-view\">\n <span rtElem=\"agent-name\" qa-dataid=\"workspace-details-agent-name\">{{ edit.currentLabel }}</span>\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-edit\"\n icon=\"pencil\"\n size=\"sm\"\n [ariaLabel]=\"t().uiChangeAgent\"\n [tooltip]=\"edit.canEdit ? edit.editTooltip : edit.cannotEditTooltip\"\n [disabled]=\"!edit.canEdit || busy()\"\n (clicked)=\"startEditAgent()\" />\n </div>\n } @else {\n <div rtElem=\"agent-edit\">\n <rt-select\n qa-dataid=\"workspace-details-agent-select\"\n [placeholder]=\"t().uiPickAgent\"\n [ngModel]=\"selectedAgentId()\"\n [options]=\"edit.options\"\n [clearable]=\"false\"\n (ngModelChange)=\"onSelectedAgentChange($event)\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-save\"\n icon=\"check\"\n size=\"sm\"\n rtConfirmTone=\"primary\"\n [ariaLabel]=\"t().uiSaveNewAgent\"\n [rtConfirmTitle]=\"t().uiReplaceAgentTitle\"\n [rtConfirmLabel]=\"t().uiReplace\"\n [tooltip]=\"canSaveReassign() ? t().uiSaveNewAgent : t().uiPickAnotherAgent\"\n [loading]=\"edit.loading\"\n [disabled]=\"!canSaveReassign() || busy()\"\n [rtConfirm]=\"edit.confirmText\"\n [rtConfirmDisabled]=\"!canSaveReassign() || busy()\"\n (confirmed)=\"onReassign()\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-cancel\"\n icon=\"ico-close\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRevert\"\n [tooltip]=\"t().uiRevert\"\n [disabled]=\"edit.loading\"\n (clicked)=\"cancelEditAgent()\" />\n </div>\n }\n } @else {\n {{ row.value }}\n }\n </rt-detail-row>\n }\n </rt-detail-list>\n }\n\n @if (money().length > 0) {\n <rt-money-list>\n @for (moneyRow of money(); track moneyRow.label) {\n <rt-money-row\n qa-dataid=\"workspace-details-money-row\"\n [label]=\"moneyRow.label\"\n [total]=\"moneyRow.total ?? false\"\n [loading]=\"loading()\">\n {{ moneyRow.amount | number: moneyRow.format ?? '1.0-0' }} ₽\n </rt-money-row>\n }\n </rt-money-list>\n }\n\n @if (toggles().length > 0 || toggleHint()) {\n <rt-aside-section>\n @for (toggle of toggles(); track toggle.id) {\n <div rtElem=\"toggle-row\" qa-dataid=\"workspace-details-toggle-row\" [attr.data-id]=\"toggle.id\">\n <span rtElem=\"toggle-label\" qa-dataid=\"workspace-details-toggle-label\">{{ toggle.label }}</span>\n <rt-toggle-switch\n qa-dataid=\"workspace-details-toggle\"\n [inputId]=\"toggle.id\"\n [ariaLabel]=\"toggle.label\"\n [ngModel]=\"toggle.value\"\n [disabled]=\"(toggle.disabled ?? false) || busy()\"\n (ngModelChange)=\"onToggleChange(toggle, $event)\" />\n </div>\n }\n @if (toggleHint(); as hint) {\n <p rtElem=\"toggle-hint\" qa-dataid=\"workspace-details-toggle-hint\">{{ hint }}</p>\n }\n </rt-aside-section>\n }\n </ng-template>\n\n <footer rtElem=\"footer\">\n @for (panelAction of actions(); track panelAction.id) {\n @if (panelAction.confirm; as confirm) {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [rtConfirmTitle]=\"confirm.title\"\n [rtConfirmLabel]=\"confirm.label\"\n [rtConfirmTone]=\"confirm.tone\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n [rtConfirm]=\"confirm.text\"\n [rtConfirmDisabled]=\"(panelAction.disabled ?? false) || busy()\"\n (confirmed)=\"onAction(panelAction)\"></button>\n } @else {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n (click)=\"onAction(panelAction)\"></button>\n }\n }\n </footer>\n</ng-container>\n",
|
|
300
|
+
template: "<ng-container rtBlock=\"rt-workspace-details\">\n @if (title(); as headTitle) {\n <header rtElem=\"head\">\n <span rtElem=\"head-title\" qa-dataid=\"workspace-details-title\">{{ headTitle }}</span>\n </header>\n }\n\n @if (hasTabs()) {\n <rt-tabs rtElem=\"tabs\" qa-dataid=\"workspace-details-tabs\">\n <ng-template rtTab=\"details\" [label]=\"t().uiDetails\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </ng-template>\n\n <ng-template rtTab=\"transition\" [label]=\"t().uiStageTransition\" [hidden]=\"transition() === null\">\n @if (transition(); as stageTransition) {\n @if (stageTransition.currentStageLabel; as stageLabel) {\n <rt-detail-list>\n <rt-detail-row qa-dataid=\"workspace-details-current-stage\" [label]=\"t().uiCurrentStage\">\n {{ stageLabel }}\n </rt-detail-row>\n </rt-detail-list>\n }\n\n @if (noTransitions()) {\n <rt-note qa-dataid=\"workspace-details-no-transitions\">{{ stageTransition.noTransitionsText }}</rt-note>\n } @else {\n <form\n rtElem=\"transition-form\"\n qa-dataid=\"workspace-details-transition-form\"\n [formGroup]=\"transitionForm\"\n (ngSubmit)=\"onTransitionSubmit()\">\n <rt-field\n [label]=\"t().uiTargetStage\"\n [loading]=\"stageTransition.loading\"\n [errors]=\"{ required: t().uiTargetStageRequired }\">\n <rt-select\n formControlName=\"to_key\"\n qa-dataid=\"workspace-details-transition-stage\"\n [placeholder]=\"t().uiPickTransition\"\n [options]=\"stageTransition.options\" />\n </rt-field>\n\n <rt-field [label]=\"t().uiCommentOptional\" [hint]=\"t().uiStageNoteHint\" [loading]=\"stageTransition.loading\">\n <rt-textarea formControlName=\"note\" qa-dataid=\"workspace-details-transition-note\" rows=\"3\" />\n </rt-field>\n\n <button\n rtButton\n rtElem=\"transition-submit\"\n qa-dataid=\"workspace-details-transition-submit\"\n type=\"submit\"\n [label]=\"t().uiMoveStage\"\n [attr.aria-label]=\"t().uiMoveStageAria\"\n [loading]=\"stageTransition.submitting\"\n [disabled]=\"stageTransition.loading || busy()\"></button>\n </form>\n }\n }\n </ng-template>\n\n <ng-template rtTab=\"audit\" [label]=\"t().uiHistory\" [hidden]=\"audit() === null\">\n @if (audit(); as auditFeed) {\n <div rtElem=\"audit\" qa-dataid=\"workspace-details-audit\">\n @if (auditFeed.loading) {\n <rt-spinner rtElem=\"audit-loading\" qa-dataid=\"workspace-details-audit-loading\" />\n } @else if (auditFeed.steps.length === 0) {\n <rt-empty-state\n qa-dataid=\"workspace-details-audit-empty\"\n icon=\"history\"\n [description]=\"t().uiAuditEmptyHint\"\n [title]=\"auditFeed.emptyText\" />\n } @else {\n <rt-timeline qa-dataid=\"workspace-details-audit-timeline\" [steps]=\"auditFeed.steps\" />\n }\n\n @if (auditFeed.hasMore) {\n <button\n rtButton\n rtElem=\"audit-more\"\n qa-dataid=\"workspace-details-audit-more\"\n type=\"button\"\n appearance=\"text\"\n [label]=\"t().uiLoadMore\"\n [attr.aria-label]=\"t().uiLoadMore\"\n [loading]=\"auditFeed.loadingMore\"\n [disabled]=\"auditFeed.loadingMore\"\n (click)=\"onAuditLoadMore()\"></button>\n }\n </div>\n }\n </ng-template>\n </rt-tabs>\n } @else {\n <div rtElem=\"body\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </div>\n }\n\n <ng-template #detailsTpl>\n @if (rows().length > 0) {\n <rt-detail-list>\n @for (row of rows(); track row.label) {\n <rt-detail-row qa-dataid=\"workspace-details-row\" [label]=\"row.label\" [loading]=\"loading()\">\n @if (row.agent && agentEdit(); as edit) {\n @if (!editingAgent()) {\n <div rtElem=\"agent-view\">\n <span rtElem=\"agent-name\" qa-dataid=\"workspace-details-agent-name\">{{ edit.currentLabel }}</span>\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-edit\"\n icon=\"pencil\"\n size=\"sm\"\n [ariaLabel]=\"t().uiChangeAgent\"\n [tooltip]=\"edit.canEdit ? edit.editTooltip : edit.cannotEditTooltip\"\n [disabled]=\"!edit.canEdit || busy()\"\n (clicked)=\"startEditAgent()\" />\n </div>\n } @else {\n <div rtElem=\"agent-edit\">\n <rt-select\n qa-dataid=\"workspace-details-agent-select\"\n [placeholder]=\"t().uiPickAgent\"\n [ngModel]=\"selectedAgentId()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [options]=\"edit.options\"\n [clearable]=\"false\"\n (ngModelChange)=\"onSelectedAgentChange($event)\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-save\"\n icon=\"check\"\n size=\"sm\"\n rtConfirmTone=\"primary\"\n [ariaLabel]=\"t().uiSaveNewAgent\"\n [rtConfirmTitle]=\"t().uiReplaceAgentTitle\"\n [rtConfirmLabel]=\"t().uiReplace\"\n [tooltip]=\"canSaveReassign() ? t().uiSaveNewAgent : t().uiPickAnotherAgent\"\n [loading]=\"edit.loading\"\n [disabled]=\"!canSaveReassign() || busy()\"\n [rtConfirm]=\"edit.confirmText\"\n [rtConfirmDisabled]=\"!canSaveReassign() || busy()\"\n (confirmed)=\"onReassign()\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-cancel\"\n icon=\"ico-close\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRevert\"\n [tooltip]=\"t().uiRevert\"\n [disabled]=\"edit.loading\"\n (clicked)=\"cancelEditAgent()\" />\n </div>\n }\n } @else {\n {{ row.value }}\n }\n </rt-detail-row>\n }\n </rt-detail-list>\n }\n\n @if (money().length > 0) {\n <rt-money-list>\n @for (moneyRow of money(); track moneyRow.label) {\n <rt-money-row\n qa-dataid=\"workspace-details-money-row\"\n [label]=\"moneyRow.label\"\n [total]=\"moneyRow.total ?? false\"\n [loading]=\"loading()\">\n {{ moneyRow.amount | number: moneyRow.format ?? '1.0-0' }} ₽\n </rt-money-row>\n }\n </rt-money-list>\n }\n\n @if (toggles().length > 0 || toggleHint()) {\n <rt-aside-section>\n @for (toggle of toggles(); track toggle.id) {\n <div rtElem=\"toggle-row\" qa-dataid=\"workspace-details-toggle-row\" [attr.data-id]=\"toggle.id\">\n <span rtElem=\"toggle-label\" qa-dataid=\"workspace-details-toggle-label\">{{ toggle.label }}</span>\n <rt-toggle-switch\n qa-dataid=\"workspace-details-toggle\"\n [inputId]=\"toggle.id\"\n [ariaLabel]=\"toggle.label\"\n [ngModel]=\"toggle.value\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"(toggle.disabled ?? false) || busy()\"\n (ngModelChange)=\"onToggleChange(toggle, $event)\" />\n </div>\n }\n @if (toggleHint(); as hint) {\n <p rtElem=\"toggle-hint\" qa-dataid=\"workspace-details-toggle-hint\">{{ hint }}</p>\n }\n </rt-aside-section>\n }\n </ng-template>\n\n <footer rtElem=\"footer\">\n @for (panelAction of actions(); track panelAction.id) {\n @if (panelAction.confirm; as confirm) {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [rtConfirmTitle]=\"confirm.title\"\n [rtConfirmLabel]=\"confirm.label\"\n [rtConfirmTone]=\"confirm.tone\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n [rtConfirm]=\"confirm.text\"\n [rtConfirmDisabled]=\"(panelAction.disabled ?? false) || busy()\"\n (confirmed)=\"onAction(panelAction)\"></button>\n } @else {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n (click)=\"onAction(panelAction)\"></button>\n }\n }\n </footer>\n</ng-container>\n",
|
|
301
301
|
styles: ["@layer rt-kit.components{.rt-workspace-details{--rt-workspace-details-border-width: var(--rt-border-width-thin);display:flex;flex-direction:column;block-size:100%;min-block-size:0}.rt-workspace-details__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-workspace-details-border-width) solid var(--rt-color-border-strong);padding-inline:var(--rt-space-lg)}.rt-workspace-details__head-title{color:var(--rt-color-text-primary);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold)}.rt-workspace-details__tabs{flex:1 1 auto;min-block-size:0}.rt-workspace-details__tabs .rt-tabs__header{align-items:flex-end;block-size:56px;border-block-end:var(--rt-workspace-details-border-width) solid var(--rt-color-border-strong);padding-inline:var(--rt-space-lg)}.rt-workspace-details__tabs .rt-tabs__tab-list{border-block-end:0}.rt-workspace-details__tabs .rt-tabs__content{padding-block-end:var(--rt-space-5);padding-inline:var(--rt-space-lg)}.rt-workspace-details__body{display:flex;flex:1 1 auto;flex-direction:column;padding:var(--rt-space-5) var(--rt-space-lg);gap:var(--rt-space-md);min-block-size:0;overflow-y:auto}.rt-workspace-details__agent-view,.rt-workspace-details__agent-edit{display:flex;align-items:center;gap:var(--rt-space-sm)}.rt-workspace-details__agent-name{overflow:hidden;min-inline-size:0;text-overflow:ellipsis;white-space:nowrap}.rt-workspace-details__toggle-row{display:flex;align-items:center;justify-content:space-between;gap:var(--rt-space-md)}.rt-workspace-details__toggle-label{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-medium)}.rt-workspace-details__toggle-hint{margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-workspace-details__transition-form{display:flex;flex-direction:column;gap:var(--rt-space-md)}.rt-workspace-details__transition-submit{align-self:flex-start}.rt-workspace-details__audit{display:flex;flex-direction:column;gap:var(--rt-space-md)}.rt-workspace-details__audit-loading,.rt-workspace-details__audit-more{align-self:center}.rt-workspace-details__footer{display:flex;flex:0 0 auto;flex-direction:column;padding:var(--rt-space-md) var(--rt-space-lg);border-block-start:var(--rt-workspace-details-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-sm)}.rt-workspace-details__footer:empty{display:none}.rt-workspace-details__footer-action{justify-content:center;inline-size:100%}.rt-workspace-details__error{margin-inline:var(--rt-space-lg)}}\n"],
|
|
302
302
|
dependencies: [
|
|
303
303
|
{
|
|
@@ -496,6 +496,7 @@ var RtWorkspaceDetailsComponent = class RtWorkspaceDetailsComponent {
|
|
|
496
496
|
"options",
|
|
497
497
|
"placeholder",
|
|
498
498
|
"iconLeft",
|
|
499
|
+
"floatingLabel",
|
|
499
500
|
"filter",
|
|
500
501
|
"filterPlaceholder",
|
|
501
502
|
"panelWidth",
|
|
@@ -525,6 +526,7 @@ var RtWorkspaceDetailsComponent = class RtWorkspaceDetailsComponent {
|
|
|
525
526
|
"label",
|
|
526
527
|
"titleTemplate",
|
|
527
528
|
"icon",
|
|
529
|
+
"glyph",
|
|
528
530
|
"iconColor",
|
|
529
531
|
"badge",
|
|
530
532
|
"badgeTitle",
|
|
@@ -532,7 +534,11 @@ var RtWorkspaceDetailsComponent = class RtWorkspaceDetailsComponent {
|
|
|
532
534
|
"disabled",
|
|
533
535
|
"hidden",
|
|
534
536
|
"invalid",
|
|
535
|
-
"invalidMessage"
|
|
537
|
+
"invalidMessage",
|
|
538
|
+
"tooltip",
|
|
539
|
+
"closable",
|
|
540
|
+
"closeTooltip",
|
|
541
|
+
"closeTooltipPlacement"
|
|
536
542
|
]
|
|
537
543
|
},
|
|
538
544
|
{
|
|
@@ -543,9 +549,16 @@ var RtWorkspaceDetailsComponent = class RtWorkspaceDetailsComponent {
|
|
|
543
549
|
"activeId",
|
|
544
550
|
"direction",
|
|
545
551
|
"stretch",
|
|
546
|
-
"contentScrollable"
|
|
552
|
+
"contentScrollable",
|
|
553
|
+
"headerOnly",
|
|
554
|
+
"preserveContent",
|
|
555
|
+
"activation",
|
|
556
|
+
"scrollArrows",
|
|
557
|
+
"scrollStep",
|
|
558
|
+
"animationDuration",
|
|
559
|
+
"contentTabIndex"
|
|
547
560
|
],
|
|
548
|
-
outputs: ["activeIdChange"]
|
|
561
|
+
outputs: ["activeIdChange", "tabClose"]
|
|
549
562
|
},
|
|
550
563
|
{
|
|
551
564
|
kind: "component",
|
|
@@ -555,7 +568,9 @@ var RtWorkspaceDetailsComponent = class RtWorkspaceDetailsComponent {
|
|
|
555
568
|
"placeholder",
|
|
556
569
|
"readonly",
|
|
557
570
|
"rows",
|
|
558
|
-
"resize"
|
|
571
|
+
"resize",
|
|
572
|
+
"appearance",
|
|
573
|
+
"maxlength"
|
|
559
574
|
]
|
|
560
575
|
},
|
|
561
576
|
{
|
|
@@ -639,7 +654,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
639
654
|
ElemDirective
|
|
640
655
|
],
|
|
641
656
|
host: { class: BEM_BLOCK },
|
|
642
|
-
template: "<ng-container rtBlock=\"rt-workspace-details\">\n @if (title(); as headTitle) {\n <header rtElem=\"head\">\n <span rtElem=\"head-title\" qa-dataid=\"workspace-details-title\">{{ headTitle }}</span>\n </header>\n }\n\n @if (hasTabs()) {\n <rt-tabs rtElem=\"tabs\" qa-dataid=\"workspace-details-tabs\">\n <ng-template rtTab=\"details\" [label]=\"t().uiDetails\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </ng-template>\n\n <ng-template rtTab=\"transition\" [label]=\"t().uiStageTransition\" [hidden]=\"transition() === null\">\n @if (transition(); as stageTransition) {\n @if (stageTransition.currentStageLabel; as stageLabel) {\n <rt-detail-list>\n <rt-detail-row qa-dataid=\"workspace-details-current-stage\" [label]=\"t().uiCurrentStage\">\n {{ stageLabel }}\n </rt-detail-row>\n </rt-detail-list>\n }\n\n @if (noTransitions()) {\n <rt-note qa-dataid=\"workspace-details-no-transitions\">{{ stageTransition.noTransitionsText }}</rt-note>\n } @else {\n <form\n rtElem=\"transition-form\"\n qa-dataid=\"workspace-details-transition-form\"\n [formGroup]=\"transitionForm\"\n (ngSubmit)=\"onTransitionSubmit()\">\n <rt-field\n [label]=\"t().uiTargetStage\"\n [loading]=\"stageTransition.loading\"\n [errors]=\"{ required: t().uiTargetStageRequired }\">\n <rt-select\n formControlName=\"to_key\"\n qa-dataid=\"workspace-details-transition-stage\"\n [placeholder]=\"t().uiPickTransition\"\n [options]=\"stageTransition.options\" />\n </rt-field>\n\n <rt-field [label]=\"t().uiCommentOptional\" [hint]=\"t().uiStageNoteHint\" [loading]=\"stageTransition.loading\">\n <rt-textarea formControlName=\"note\" qa-dataid=\"workspace-details-transition-note\" rows=\"3\" />\n </rt-field>\n\n <button\n rtButton\n rtElem=\"transition-submit\"\n qa-dataid=\"workspace-details-transition-submit\"\n type=\"submit\"\n [label]=\"t().uiMoveStage\"\n [attr.aria-label]=\"t().uiMoveStageAria\"\n [loading]=\"stageTransition.submitting\"\n [disabled]=\"stageTransition.loading || busy()\"></button>\n </form>\n }\n }\n </ng-template>\n\n <ng-template rtTab=\"audit\" [label]=\"t().uiHistory\" [hidden]=\"audit() === null\">\n @if (audit(); as auditFeed) {\n <div rtElem=\"audit\" qa-dataid=\"workspace-details-audit\">\n @if (auditFeed.loading) {\n <rt-spinner rtElem=\"audit-loading\" qa-dataid=\"workspace-details-audit-loading\" />\n } @else if (auditFeed.steps.length === 0) {\n <rt-empty-state\n qa-dataid=\"workspace-details-audit-empty\"\n icon=\"history\"\n [description]=\"t().uiAuditEmptyHint\"\n [title]=\"auditFeed.emptyText\" />\n } @else {\n <rt-timeline qa-dataid=\"workspace-details-audit-timeline\" [steps]=\"auditFeed.steps\" />\n }\n\n @if (auditFeed.hasMore) {\n <button\n rtButton\n rtElem=\"audit-more\"\n qa-dataid=\"workspace-details-audit-more\"\n type=\"button\"\n appearance=\"text\"\n [label]=\"t().uiLoadMore\"\n [attr.aria-label]=\"t().uiLoadMore\"\n [loading]=\"auditFeed.loadingMore\"\n [disabled]=\"auditFeed.loadingMore\"\n (click)=\"onAuditLoadMore()\"></button>\n }\n </div>\n }\n </ng-template>\n </rt-tabs>\n } @else {\n <div rtElem=\"body\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </div>\n }\n\n <ng-template #detailsTpl>\n @if (rows().length > 0) {\n <rt-detail-list>\n @for (row of rows(); track row.label) {\n <rt-detail-row qa-dataid=\"workspace-details-row\" [label]=\"row.label\" [loading]=\"loading()\">\n @if (row.agent && agentEdit(); as edit) {\n @if (!editingAgent()) {\n <div rtElem=\"agent-view\">\n <span rtElem=\"agent-name\" qa-dataid=\"workspace-details-agent-name\">{{ edit.currentLabel }}</span>\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-edit\"\n icon=\"pencil\"\n size=\"sm\"\n [ariaLabel]=\"t().uiChangeAgent\"\n [tooltip]=\"edit.canEdit ? edit.editTooltip : edit.cannotEditTooltip\"\n [disabled]=\"!edit.canEdit || busy()\"\n (clicked)=\"startEditAgent()\" />\n </div>\n } @else {\n <div rtElem=\"agent-edit\">\n <rt-select\n qa-dataid=\"workspace-details-agent-select\"\n [placeholder]=\"t().uiPickAgent\"\n [ngModel]=\"selectedAgentId()\"\n [options]=\"edit.options\"\n [clearable]=\"false\"\n (ngModelChange)=\"onSelectedAgentChange($event)\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-save\"\n icon=\"check\"\n size=\"sm\"\n rtConfirmTone=\"primary\"\n [ariaLabel]=\"t().uiSaveNewAgent\"\n [rtConfirmTitle]=\"t().uiReplaceAgentTitle\"\n [rtConfirmLabel]=\"t().uiReplace\"\n [tooltip]=\"canSaveReassign() ? t().uiSaveNewAgent : t().uiPickAnotherAgent\"\n [loading]=\"edit.loading\"\n [disabled]=\"!canSaveReassign() || busy()\"\n [rtConfirm]=\"edit.confirmText\"\n [rtConfirmDisabled]=\"!canSaveReassign() || busy()\"\n (confirmed)=\"onReassign()\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-cancel\"\n icon=\"ico-close\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRevert\"\n [tooltip]=\"t().uiRevert\"\n [disabled]=\"edit.loading\"\n (clicked)=\"cancelEditAgent()\" />\n </div>\n }\n } @else {\n {{ row.value }}\n }\n </rt-detail-row>\n }\n </rt-detail-list>\n }\n\n @if (money().length > 0) {\n <rt-money-list>\n @for (moneyRow of money(); track moneyRow.label) {\n <rt-money-row\n qa-dataid=\"workspace-details-money-row\"\n [label]=\"moneyRow.label\"\n [total]=\"moneyRow.total ?? false\"\n [loading]=\"loading()\">\n {{ moneyRow.amount | number: moneyRow.format ?? '1.0-0' }} ₽\n </rt-money-row>\n }\n </rt-money-list>\n }\n\n @if (toggles().length > 0 || toggleHint()) {\n <rt-aside-section>\n @for (toggle of toggles(); track toggle.id) {\n <div rtElem=\"toggle-row\" qa-dataid=\"workspace-details-toggle-row\" [attr.data-id]=\"toggle.id\">\n <span rtElem=\"toggle-label\" qa-dataid=\"workspace-details-toggle-label\">{{ toggle.label }}</span>\n <rt-toggle-switch\n qa-dataid=\"workspace-details-toggle\"\n [inputId]=\"toggle.id\"\n [ariaLabel]=\"toggle.label\"\n [ngModel]=\"toggle.value\"\n [disabled]=\"(toggle.disabled ?? false) || busy()\"\n (ngModelChange)=\"onToggleChange(toggle, $event)\" />\n </div>\n }\n @if (toggleHint(); as hint) {\n <p rtElem=\"toggle-hint\" qa-dataid=\"workspace-details-toggle-hint\">{{ hint }}</p>\n }\n </rt-aside-section>\n }\n </ng-template>\n\n <footer rtElem=\"footer\">\n @for (panelAction of actions(); track panelAction.id) {\n @if (panelAction.confirm; as confirm) {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [rtConfirmTitle]=\"confirm.title\"\n [rtConfirmLabel]=\"confirm.label\"\n [rtConfirmTone]=\"confirm.tone\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n [rtConfirm]=\"confirm.text\"\n [rtConfirmDisabled]=\"(panelAction.disabled ?? false) || busy()\"\n (confirmed)=\"onAction(panelAction)\"></button>\n } @else {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n (click)=\"onAction(panelAction)\"></button>\n }\n }\n </footer>\n</ng-container>\n",
|
|
657
|
+
template: "<ng-container rtBlock=\"rt-workspace-details\">\n @if (title(); as headTitle) {\n <header rtElem=\"head\">\n <span rtElem=\"head-title\" qa-dataid=\"workspace-details-title\">{{ headTitle }}</span>\n </header>\n }\n\n @if (hasTabs()) {\n <rt-tabs rtElem=\"tabs\" qa-dataid=\"workspace-details-tabs\">\n <ng-template rtTab=\"details\" [label]=\"t().uiDetails\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </ng-template>\n\n <ng-template rtTab=\"transition\" [label]=\"t().uiStageTransition\" [hidden]=\"transition() === null\">\n @if (transition(); as stageTransition) {\n @if (stageTransition.currentStageLabel; as stageLabel) {\n <rt-detail-list>\n <rt-detail-row qa-dataid=\"workspace-details-current-stage\" [label]=\"t().uiCurrentStage\">\n {{ stageLabel }}\n </rt-detail-row>\n </rt-detail-list>\n }\n\n @if (noTransitions()) {\n <rt-note qa-dataid=\"workspace-details-no-transitions\">{{ stageTransition.noTransitionsText }}</rt-note>\n } @else {\n <form\n rtElem=\"transition-form\"\n qa-dataid=\"workspace-details-transition-form\"\n [formGroup]=\"transitionForm\"\n (ngSubmit)=\"onTransitionSubmit()\">\n <rt-field\n [label]=\"t().uiTargetStage\"\n [loading]=\"stageTransition.loading\"\n [errors]=\"{ required: t().uiTargetStageRequired }\">\n <rt-select\n formControlName=\"to_key\"\n qa-dataid=\"workspace-details-transition-stage\"\n [placeholder]=\"t().uiPickTransition\"\n [options]=\"stageTransition.options\" />\n </rt-field>\n\n <rt-field [label]=\"t().uiCommentOptional\" [hint]=\"t().uiStageNoteHint\" [loading]=\"stageTransition.loading\">\n <rt-textarea formControlName=\"note\" qa-dataid=\"workspace-details-transition-note\" rows=\"3\" />\n </rt-field>\n\n <button\n rtButton\n rtElem=\"transition-submit\"\n qa-dataid=\"workspace-details-transition-submit\"\n type=\"submit\"\n [label]=\"t().uiMoveStage\"\n [attr.aria-label]=\"t().uiMoveStageAria\"\n [loading]=\"stageTransition.submitting\"\n [disabled]=\"stageTransition.loading || busy()\"></button>\n </form>\n }\n }\n </ng-template>\n\n <ng-template rtTab=\"audit\" [label]=\"t().uiHistory\" [hidden]=\"audit() === null\">\n @if (audit(); as auditFeed) {\n <div rtElem=\"audit\" qa-dataid=\"workspace-details-audit\">\n @if (auditFeed.loading) {\n <rt-spinner rtElem=\"audit-loading\" qa-dataid=\"workspace-details-audit-loading\" />\n } @else if (auditFeed.steps.length === 0) {\n <rt-empty-state\n qa-dataid=\"workspace-details-audit-empty\"\n icon=\"history\"\n [description]=\"t().uiAuditEmptyHint\"\n [title]=\"auditFeed.emptyText\" />\n } @else {\n <rt-timeline qa-dataid=\"workspace-details-audit-timeline\" [steps]=\"auditFeed.steps\" />\n }\n\n @if (auditFeed.hasMore) {\n <button\n rtButton\n rtElem=\"audit-more\"\n qa-dataid=\"workspace-details-audit-more\"\n type=\"button\"\n appearance=\"text\"\n [label]=\"t().uiLoadMore\"\n [attr.aria-label]=\"t().uiLoadMore\"\n [loading]=\"auditFeed.loadingMore\"\n [disabled]=\"auditFeed.loadingMore\"\n (click)=\"onAuditLoadMore()\"></button>\n }\n </div>\n }\n </ng-template>\n </rt-tabs>\n } @else {\n <div rtElem=\"body\">\n <ng-container [ngTemplateOutlet]=\"detailsTpl\" />\n </div>\n }\n\n <ng-template #detailsTpl>\n @if (rows().length > 0) {\n <rt-detail-list>\n @for (row of rows(); track row.label) {\n <rt-detail-row qa-dataid=\"workspace-details-row\" [label]=\"row.label\" [loading]=\"loading()\">\n @if (row.agent && agentEdit(); as edit) {\n @if (!editingAgent()) {\n <div rtElem=\"agent-view\">\n <span rtElem=\"agent-name\" qa-dataid=\"workspace-details-agent-name\">{{ edit.currentLabel }}</span>\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-edit\"\n icon=\"pencil\"\n size=\"sm\"\n [ariaLabel]=\"t().uiChangeAgent\"\n [tooltip]=\"edit.canEdit ? edit.editTooltip : edit.cannotEditTooltip\"\n [disabled]=\"!edit.canEdit || busy()\"\n (clicked)=\"startEditAgent()\" />\n </div>\n } @else {\n <div rtElem=\"agent-edit\">\n <rt-select\n qa-dataid=\"workspace-details-agent-select\"\n [placeholder]=\"t().uiPickAgent\"\n [ngModel]=\"selectedAgentId()\"\n [ngModelOptions]=\"{ standalone: true }\"\n [options]=\"edit.options\"\n [clearable]=\"false\"\n (ngModelChange)=\"onSelectedAgentChange($event)\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-save\"\n icon=\"check\"\n size=\"sm\"\n rtConfirmTone=\"primary\"\n [ariaLabel]=\"t().uiSaveNewAgent\"\n [rtConfirmTitle]=\"t().uiReplaceAgentTitle\"\n [rtConfirmLabel]=\"t().uiReplace\"\n [tooltip]=\"canSaveReassign() ? t().uiSaveNewAgent : t().uiPickAnotherAgent\"\n [loading]=\"edit.loading\"\n [disabled]=\"!canSaveReassign() || busy()\"\n [rtConfirm]=\"edit.confirmText\"\n [rtConfirmDisabled]=\"!canSaveReassign() || busy()\"\n (confirmed)=\"onReassign()\" />\n <rt-icon-button\n qa-dataid=\"workspace-details-agent-cancel\"\n icon=\"ico-close\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRevert\"\n [tooltip]=\"t().uiRevert\"\n [disabled]=\"edit.loading\"\n (clicked)=\"cancelEditAgent()\" />\n </div>\n }\n } @else {\n {{ row.value }}\n }\n </rt-detail-row>\n }\n </rt-detail-list>\n }\n\n @if (money().length > 0) {\n <rt-money-list>\n @for (moneyRow of money(); track moneyRow.label) {\n <rt-money-row\n qa-dataid=\"workspace-details-money-row\"\n [label]=\"moneyRow.label\"\n [total]=\"moneyRow.total ?? false\"\n [loading]=\"loading()\">\n {{ moneyRow.amount | number: moneyRow.format ?? '1.0-0' }} ₽\n </rt-money-row>\n }\n </rt-money-list>\n }\n\n @if (toggles().length > 0 || toggleHint()) {\n <rt-aside-section>\n @for (toggle of toggles(); track toggle.id) {\n <div rtElem=\"toggle-row\" qa-dataid=\"workspace-details-toggle-row\" [attr.data-id]=\"toggle.id\">\n <span rtElem=\"toggle-label\" qa-dataid=\"workspace-details-toggle-label\">{{ toggle.label }}</span>\n <rt-toggle-switch\n qa-dataid=\"workspace-details-toggle\"\n [inputId]=\"toggle.id\"\n [ariaLabel]=\"toggle.label\"\n [ngModel]=\"toggle.value\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"(toggle.disabled ?? false) || busy()\"\n (ngModelChange)=\"onToggleChange(toggle, $event)\" />\n </div>\n }\n @if (toggleHint(); as hint) {\n <p rtElem=\"toggle-hint\" qa-dataid=\"workspace-details-toggle-hint\">{{ hint }}</p>\n }\n </rt-aside-section>\n }\n </ng-template>\n\n <footer rtElem=\"footer\">\n @for (panelAction of actions(); track panelAction.id) {\n @if (panelAction.confirm; as confirm) {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [rtConfirmTitle]=\"confirm.title\"\n [rtConfirmLabel]=\"confirm.label\"\n [rtConfirmTone]=\"confirm.tone\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n [rtConfirm]=\"confirm.text\"\n [rtConfirmDisabled]=\"(panelAction.disabled ?? false) || busy()\"\n (confirmed)=\"onAction(panelAction)\"></button>\n } @else {\n <button\n rtButton\n rtElem=\"footer-action\"\n qa-dataid=\"workspace-details-action\"\n type=\"button\"\n [attr.data-id]=\"panelAction.id\"\n [theme]=\"panelAction.theme ?? 'primary'\"\n [appearance]=\"panelAction.appearance ?? 'filled'\"\n [label]=\"panelAction.label\"\n [icon]=\"panelAction.icon\"\n [attr.aria-label]=\"panelAction.label\"\n [loading]=\"panelAction.loading ?? false\"\n [disabled]=\"(panelAction.disabled ?? false) || busy()\"\n (click)=\"onAction(panelAction)\"></button>\n }\n }\n </footer>\n</ng-container>\n",
|
|
643
658
|
styles: ["@layer rt-kit.components{.rt-workspace-details{--rt-workspace-details-border-width: var(--rt-border-width-thin);display:flex;flex-direction:column;block-size:100%;min-block-size:0}.rt-workspace-details__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-workspace-details-border-width) solid var(--rt-color-border-strong);padding-inline:var(--rt-space-lg)}.rt-workspace-details__head-title{color:var(--rt-color-text-primary);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-semibold)}.rt-workspace-details__tabs{flex:1 1 auto;min-block-size:0}.rt-workspace-details__tabs .rt-tabs__header{align-items:flex-end;block-size:56px;border-block-end:var(--rt-workspace-details-border-width) solid var(--rt-color-border-strong);padding-inline:var(--rt-space-lg)}.rt-workspace-details__tabs .rt-tabs__tab-list{border-block-end:0}.rt-workspace-details__tabs .rt-tabs__content{padding-block-end:var(--rt-space-5);padding-inline:var(--rt-space-lg)}.rt-workspace-details__body{display:flex;flex:1 1 auto;flex-direction:column;padding:var(--rt-space-5) var(--rt-space-lg);gap:var(--rt-space-md);min-block-size:0;overflow-y:auto}.rt-workspace-details__agent-view,.rt-workspace-details__agent-edit{display:flex;align-items:center;gap:var(--rt-space-sm)}.rt-workspace-details__agent-name{overflow:hidden;min-inline-size:0;text-overflow:ellipsis;white-space:nowrap}.rt-workspace-details__toggle-row{display:flex;align-items:center;justify-content:space-between;gap:var(--rt-space-md)}.rt-workspace-details__toggle-label{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-medium)}.rt-workspace-details__toggle-hint{margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-workspace-details__transition-form{display:flex;flex-direction:column;gap:var(--rt-space-md)}.rt-workspace-details__transition-submit{align-self:flex-start}.rt-workspace-details__audit{display:flex;flex-direction:column;gap:var(--rt-space-md)}.rt-workspace-details__audit-loading,.rt-workspace-details__audit-more{align-self:center}.rt-workspace-details__footer{display:flex;flex:0 0 auto;flex-direction:column;padding:var(--rt-space-md) var(--rt-space-lg);border-block-start:var(--rt-workspace-details-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-sm)}.rt-workspace-details__footer:empty{display:none}.rt-workspace-details__footer-action{justify-content:center;inline-size:100%}.rt-workspace-details__error{margin-inline:var(--rt-space-lg)}}\n"]
|
|
644
659
|
}]
|
|
645
660
|
}],
|