@rt-tools/ui-kit-v2 0.29.1 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +23 -29
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +223 -3
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +1 -2
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +277 -904
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +35 -48
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-pdf-viewer.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +4 -4
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +37 -181
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-service-block.mjs +131 -0
- package/fesm2022/rt-tools-ui-kit-v2-service-block.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +5 -36
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +2 -3
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +8 -13
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +12 -7
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2.mjs +1 -0
- package/package.json +5 -1
- package/src/lib/components/dynamic-selector/stories/component/test-dynamic-selector-popup-frame.component.scss +6 -0
- package/src/lib/components/page-header/rt-page-header.component.scss +4 -2
- package/src/lib/components/service-block/CONTEXT.md +37 -0
- package/src/lib/components/service-block/rt-service-block.component.scss +61 -0
- package/src/lib/components/tree/CONTEXT.md +1 -1
- package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +1 -1
- package/src/styles/_breakpoints.scss +37 -4
- package/src/styles/_index.scss +0 -4
- package/styles/tokens.css +0 -8
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +4 -3
- package/types/rt-tools-ui-kit-v2-core.d.ts +155 -1
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +51 -269
- package/types/rt-tools-ui-kit-v2-multiselect.d.ts +4 -3
- package/types/rt-tools-ui-kit-v2-select.d.ts +12 -74
- package/types/rt-tools-ui-kit-v2-service-block.d.ts +34 -0
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +5 -20
- package/types/rt-tools-ui-kit-v2-tag.d.ts +2 -3
- package/types/rt-tools-ui-kit-v2-tree-selector.d.ts +0 -2
- package/types/rt-tools-ui-kit-v2-tree.d.ts +7 -9
- package/types/rt-tools-ui-kit-v2.d.ts +1 -0
- package/src/styles/_place.scss +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rt-tools-ui-kit-v2-draggable-tree.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.directives.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.logic.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\n\n/**\n * Разметка приложения вместо подписи строки `rt-draggable-tree`. Узел строки приходит в контексте\n * как `$implicit`.\n */\n@Directive({ selector: 'ng-template[rtDraggableTreeNode]' })\nexport class RtDraggableTreeNodeDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n","import { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\ntype TNodes<TValue> = ReadonlyArray<TNode<TValue>>;\n\n/** Где узел лежит: его соседи, место среди них и значение родителя. */\ninterface ILocation<TValue> {\n readonly node: TNode<TValue>;\n readonly siblings: TNodes<TValue>;\n readonly index: number;\n readonly parent: TValue | null;\n}\n\n/** Контейнер — узел с массивом детей, даже пустым: он принимает узлы внутрь. */\nfunction isContainer<TValue>(node: TNode<TValue>): boolean {\n return Array.isArray(node.children);\n}\n\nfunction locate<TValue>(nodes: TNodes<TValue>, value: TValue, parent: TValue | null = null): ILocation<TValue> | null {\n for (let index: number = 0; index < nodes.length; index++) {\n const node: TNode<TValue> = nodes[index];\n if (node.value === value) {\n return { siblings: nodes, node, index, parent };\n }\n const found: ILocation<TValue> | null = locate(node.children ?? [], value, node.value);\n if (found) {\n return found;\n }\n }\n return null;\n}\n\nfunction holds<TValue>(node: TNode<TValue>, value: TValue): boolean {\n return (node.children ?? []).some((child: TNode<TValue>): boolean => child.value === value || holds(child, value));\n}\n\nfunction without<TValue>(nodes: TNodes<TValue>, value: TValue): TNodes<TValue> {\n return nodes\n .filter((node: TNode<TValue>): boolean => node.value !== value)\n .map((node: TNode<TValue>): TNode<TValue> =>\n node.children && holds(node, value) ? { ...node, children: without(node.children, value) } : node\n );\n}\n\nfunction inserted<TValue>(nodes: TNodes<TValue>, moving: TNode<TValue>, drop: IRtDraggableTree.Drop<TValue>): TNodes<TValue> {\n const at: number = nodes.findIndex((node: TNode<TValue>): boolean => node.value === drop.target);\n if (at >= 0 && drop.place !== 'inside') {\n const index: number = drop.place === 'before' ? at : at + 1;\n return [...nodes.slice(0, index), moving, ...nodes.slice(index)];\n }\n return nodes.map((node: TNode<TValue>): TNode<TValue> => {\n if (node.value === drop.target && drop.place === 'inside') {\n return { ...node, children: [...(node.children ?? []), moving] };\n }\n if (node.children && holds(node, drop.target)) {\n return { ...node, children: inserted(node.children, moving, drop) };\n }\n return node;\n });\n}\n\nfunction siblingPlace<TValue>(here: ILocation<TValue>, step: number): IRtDraggableTree.Drop<TValue> | null {\n const next: TNode<TValue> | undefined = here.siblings[here.index + step];\n return next ? { target: next.value, place: step < 0 ? 'before' : 'after' } : null;\n}\n\nfunction levelPlace<TValue>(here: ILocation<TValue>, out: boolean): IRtDraggableTree.Drop<TValue> | null {\n if (out) {\n return here.parent === null ? null : { target: here.parent, place: 'after' };\n }\n const above: TNode<TValue> | undefined = here.siblings[here.index - 1];\n return above && isContainer(above) ? { target: above.value, place: 'inside' } : null;\n}\n\n/**\n * Место сброса по третям высоты строки: верхняя — перед целью, нижняя — после, средняя — внутрь.\n * Средняя треть листа места не даёт: внутрь принимает только контейнер.\n */\nexport function rtDragPlace<TValue>(target: TNode<TValue>, top: number, height: number, pointer: number): IRtDraggableTree.Place | null {\n const third: number = height / 3;\n const offset: number = pointer - top;\n if (offset < third) {\n return 'before';\n }\n if (offset > 2 * third) {\n return 'after';\n }\n return isContainer(target) ? 'inside' : null;\n}\n\n/**\n * Можно ли поставить узел на место: не на себя, не в своё поддерево, внутрь — только в контейнер, и\n * если приложение не запретило.\n */\nexport function rtDragAllowed<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>,\n canDrop: IRtDraggableTree.CanDrop<TValue> | null = null\n): boolean {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n const target: ILocation<TValue> | null = locate(nodes, drop.target);\n if (!moving || !target || drop.target === value || holds(moving.node, drop.target)) {\n return false;\n }\n if (drop.place === 'inside' && !isContainer(target.node)) {\n return false;\n }\n return canDrop ? canDrop(moving.node, target.node, drop.place) : true;\n}\n\n/** Переносит узел вместе с поддеревом. Узлы на входе не меняются: ветки на пути строятся заново. */\nexport function rtDragMove<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>\n): IRtDraggableTree.MoveResult<TValue> | null {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n if (!moving || !rtDragAllowed(nodes, value, drop)) {\n return null;\n }\n const next: TNodes<TValue> = inserted(without(nodes, value), moving.node, drop);\n const landed: ILocation<TValue> | null = locate(next, value);\n if (!landed) {\n return null;\n }\n return { nodes: next, moved: { node: moving.node, parent: landed.parent, index: landed.index } };\n}\n\n/**\n * Место для переноса клавишей с Alt. Вверх и вниз — среди соседей, влево — сразу после своей ветки,\n * вправо — последним в контейнер, стоящий прямо над узлом. Двигаться некуда — `null`.\n */\nexport function rtDragKeyPlace<TValue>(nodes: TNodes<TValue>, value: TValue, key: string): IRtDraggableTree.Drop<TValue> | null {\n const here: ILocation<TValue> | null = locate(nodes, value);\n if (!here) {\n return null;\n }\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n return siblingPlace(here, key === 'ArrowUp' ? -1 : 1);\n }\n if (key === 'ArrowLeft' || key === 'ArrowRight') {\n return levelPlace(here, key === 'ArrowLeft');\n }\n return null;\n}\n","import { CdkDrag, CdkDragHandle, CdkDragMove, CdkDropList } from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n computed,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n viewChildren,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IRtIcon, RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { rtTreeRows, rtTreeSideKey, rtTreeToggle } from '@rt-tools/ui-kit-v2/select';\nimport { IRtSelect } from '@rt-tools/ui-kit-v2/select';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { RtDraggableTreeNodeDirective } from './rt-draggable-tree.directives';\nimport { rtDragAllowed, rtDragKeyPlace, rtDragMove, rtDragPlace } from './rt-draggable-tree.logic';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\nconst BEM_BLOCK: string = 'rt-draggable-tree';\nconst MOVE_KEYS: ReadonlyArray<string> = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\n/**\n * Дерево, узлы которого человек переставляет: перетаскиванием строки до, после или внутрь другой,\n * или клавишами с Alt.\n *\n * Строки, уровни и раскрытие считает тот же модуль, что у `rt-tree`. Узлы на входе не меняются:\n * перенос пишет в `nodes` новый массив и сообщает `moved`. Место сброса — чистая функция от рамки\n * строки под указателем; документ дерево не читает.\n */\n@Component({\n selector: 'rt-draggable-tree',\n templateUrl: './rt-draggable-tree.component.html',\n styleUrl: './rt-draggable-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n CdkDrag,\n CdkDragHandle,\n CdkDropList,\n RtIconComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'tree',\n tabindex: '0',\n '[attr.aria-label]': 'ariaLabel()',\n '(keydown)': 'handleKeydown($event)',\n },\n})\nexport class RtDraggableTreeComponent<TValue> {\n readonly #highlighted: WritableSignal<TValue | null> = signal<TValue | null>(null);\n readonly #dragged: WritableSignal<TValue | null> = signal<TValue | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly nodeTemplate: Signal<RtDraggableTreeNodeDirective<TValue> | undefined> = contentChild(RtDraggableTreeNodeDirective);\n\n protected readonly rowElements: Signal<ReadonlyArray<ElementRef<HTMLElement>>> = viewChildren<ElementRef<HTMLElement>>('row');\n\n /** Место, куда встанет перетаскиваемый узел; `null` — сейчас места нет. */\n protected readonly drop: WritableSignal<IRtDraggableTree.Drop<TValue> | null> = signal<IRtDraggableTree.Drop<TValue> | null>(null);\n\n /**\n * Раскрытые ветки. Пока приложение их не задало и человек ничего не сворачивал, раскрыты все:\n * порядок виден целиком с первого взгляда.\n */\n protected readonly openBranches: Signal<ReadonlySet<TValue>> = computed((): ReadonlySet<TValue> => {\n const open: ReadonlyArray<TValue> | null = this.open();\n if (open !== null) {\n return new Set<TValue>(open);\n }\n const all: Set<TValue> = new Set<TValue>();\n this.#collectBranches(this.nodes(), all);\n return all;\n });\n\n protected readonly rows: Signal<ReadonlyArray<IRtTree.Row<TValue>>> = computed((): ReadonlyArray<IRtTree.Row<TValue>> =>\n rtTreeRows(this.nodes(), this.openBranches(), '')\n );\n\n protected readonly highlighted: Signal<TValue | null> = this.#highlighted.asReadonly();\n\n public readonly nodes: ModelSignal<ReadonlyArray<IRtTree.Node<TValue>>> = model.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n /** Значения раскрытых веток; `null` — раскрыты все. Пара `openChange` приходит на каждое раскрытие. */\n public readonly open: ModelSignal<ReadonlyArray<TValue> | null> = model<ReadonlyArray<TValue> | null>(null);\n public readonly canDrop: InputSignal<IRtDraggableTree.CanDrop<TValue> | null> = input<IRtDraggableTree.CanDrop<TValue> | null>(null);\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n /** Значок кита над подписью пустого дерева. Без него пустое дерево — одна подпись. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n public readonly moved: OutputEmitterRef<IRtDraggableTree.Moved<TValue>> = output<IRtDraggableTree.Moved<TValue>>();\n public readonly picked: OutputEmitterRef<IRtTree.Node<TValue>> = output<IRtTree.Node<TValue>>();\n\n /** Клавиша для дерева. Отвечает, взята ли она: не взятая идёт дальше нетронутой. */\n public handleKeydown(event: KeyboardEvent): boolean {\n const taken: boolean = event.altKey ? this.#moveByKey(event.key) : this.#walkByKey(event.key);\n if (taken) {\n event.preventDefault();\n event.stopPropagation();\n }\n return taken;\n }\n\n protected onRowClick(row: IRtTree.Row<TValue>): void {\n this.#highlighted.set(row.option.value);\n this.picked.emit(row.option);\n }\n\n protected onToggleClick(event: Event, value: TValue): void {\n event.stopPropagation();\n this.#toggle(value);\n }\n\n protected onDragStarted(value: TValue): void {\n this.#dragged.set(value);\n }\n\n protected onDragMoved(event: CdkDragMove<TValue>): void {\n this.drop.set(this.#dropAt(event.pointerPosition.y));\n }\n\n protected onDropped(): void {\n const dragged: TValue | null = this.#dragged();\n const drop: IRtDraggableTree.Drop<TValue> | null = this.drop();\n this.#dragged.set(null);\n this.drop.set(null);\n if (dragged !== null && drop) {\n this.#apply(dragged, drop);\n }\n }\n\n #dropAt(pointer: number): IRtDraggableTree.Drop<TValue> | null {\n const dragged: TValue | null = this.#dragged();\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const elements: ReadonlyArray<ElementRef<HTMLElement>> = this.rowElements();\n if (dragged === null) {\n return null;\n }\n const index: number = elements.findIndex((element: ElementRef<HTMLElement>, at: number): boolean => {\n const box: DOMRect = element.nativeElement.getBoundingClientRect();\n return rows[at]?.option.value !== dragged && pointer >= box.top && pointer < box.bottom;\n });\n if (index < 0) {\n return null;\n }\n const box: DOMRect = elements[index].nativeElement.getBoundingClientRect();\n const target: IRtTree.Node<TValue> = rows[index].option;\n const place: IRtDraggableTree.Place | null = rtDragPlace(target, box.top, box.height, pointer);\n const drop: IRtDraggableTree.Drop<TValue> | null = place ? { target: target.value, place } : null;\n return drop && rtDragAllowed(this.nodes(), dragged, drop, this.canDrop()) ? drop : null;\n }\n\n #moveByKey(key: string): boolean {\n const value: TValue | null = this.#highlighted();\n if (!MOVE_KEYS.includes(key)) {\n return false;\n }\n const node: IRtTree.Node<TValue> | undefined = this.rows().find(\n (row: IRtTree.Row<TValue>): boolean => row.option.value === value\n )?.option;\n const drop: IRtDraggableTree.Drop<TValue> | null = node && !node.disabled ? rtDragKeyPlace(this.nodes(), node.value, key) : null;\n if (node && drop && rtDragAllowed(this.nodes(), node.value, drop, this.canDrop())) {\n this.#apply(node.value, drop);\n }\n return true;\n }\n\n #walkByKey(key: string): boolean {\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const index: number = rows.findIndex((row: IRtTree.Row<TValue>): boolean => row.option.value === this.#highlighted());\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n return this.#step(rows, index, key === 'ArrowDown' ? 1 : -1);\n }\n if (index < 0) {\n return false;\n }\n if (key === 'ArrowRight' || key === 'ArrowLeft') {\n const answer: IRtSelect.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 return true;\n }\n if (key === 'Enter') {\n this.picked.emit(rows[index].option);\n return true;\n }\n return false;\n }\n\n #step(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 #apply(value: TValue, drop: IRtDraggableTree.Drop<TValue>): void {\n const result: IRtDraggableTree.MoveResult<TValue> | null = rtDragMove(this.nodes(), value, drop);\n if (!result) {\n return;\n }\n this.nodes.set(result.nodes);\n if (drop.place === 'inside' && !this.openBranches().has(drop.target)) {\n this.open.set([...this.openBranches(), drop.target]);\n }\n this.moved.emit(result.moved);\n }\n\n #toggle(value: TValue): void {\n this.open.set([...rtTreeToggle(this.openBranches(), value)]);\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","<ng-container rtBlock=\"rt-draggable-tree\">\n <!--\n Строки берут мышь через (click), клавиатура — на самом дереве (handleKeydown): строки фокус не\n берут, подсвеченная строка — состояние рядом с фокусом. Строку тянут за ручку; список один на\n всё дерево, и место сброса считает компонент по рамке строки под указателем.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div rtElem=\"list\" cdkDropList [cdkDropListSortingDisabled]=\"true\" (cdkDropListDropped)=\"onDropped()\">\n @for (row of rows(); track row.option.value) {\n <div\n #row\n rtElem=\"row\"\n qa-dataid=\"draggable-tree-row\"\n role=\"treeitem\"\n cdkDrag\n [cdkDragData]=\"row.option.value\"\n [cdkDragDisabled]=\"!!row.option.disabled\"\n [attr.data-value]=\"row.option.value\"\n [attr.aria-level]=\"row.level + 1\"\n [attr.aria-expanded]=\"row.branch ? row.open : null\"\n [attr.aria-selected]=\"row.option.value === highlighted()\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n [style.--rt-draggable-tree-level]=\"row.level\"\n [rtMod]=\"{\n highlighted: row.option.value === highlighted(),\n disabled: !!row.option.disabled,\n 'drop-before': drop()?.target === row.option.value && drop()?.place === 'before',\n 'drop-after': drop()?.target === row.option.value && drop()?.place === 'after',\n 'drop-inside': drop()?.target === row.option.value && drop()?.place === 'inside',\n }\"\n (cdkDragStarted)=\"onDragStarted(row.option.value)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (click)=\"onRowClick(row)\">\n @if (row.option.disabled) {\n <span rtElem=\"handle-space\"></span>\n } @else {\n <span rtElem=\"handle\" qa-dataid=\"draggable-tree-handle\" cdkDragHandle aria-hidden=\"true\">\n <rt-icon name=\"bars\" size=\"sm\" color=\"muted\" />\n </span>\n }\n\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"draggable-tree-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"row.open ? t().uiCollapse : t().uiExpand\"\n (click)=\"onToggleClick($event, row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n\n <span rtElem=\"content\" qa-dataid=\"draggable-tree-content\">\n @if (nodeTemplate(); as template) {\n <ng-container [ngTemplateOutlet]=\"template.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row.option }\" />\n } @else {\n <span rtElem=\"label\" qa-dataid=\"draggable-tree-label\" rtTooltipWhenTruncated [rtTooltip]=\"row.option.label\">\n {{ row.option.label }}\n </span>\n }\n </span>\n </div>\n } @empty {\n <div rtElem=\"empty\" qa-dataid=\"draggable-tree-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"draggable-tree-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ t().uiNoOptions }}\n </div>\n }\n </div>\n</ng-container>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-draggable-tree.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.directives.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.logic.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.ts","../../../projects/ui-kit-v2/src/lib/components/draggable-tree/rt-draggable-tree.component.html"],"sourcesContent":["import { inject, Directive, TemplateRef } from '@angular/core';\n\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\n\n/**\n * Разметка приложения вместо подписи строки `rt-draggable-tree`. Узел строки приходит в контексте\n * как `$implicit`.\n */\n@Directive({ selector: 'ng-template[rtDraggableTreeNode]' })\nexport class RtDraggableTreeNodeDirective<TValue> {\n public readonly templateRef: TemplateRef<IRtTree.NodeContext<TValue>> = inject<TemplateRef<IRtTree.NodeContext<TValue>>>(TemplateRef);\n}\n","import { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\ntype TNode<TValue> = IRtTree.Node<TValue>;\ntype TNodes<TValue> = ReadonlyArray<TNode<TValue>>;\n\n/** Где узел лежит: его соседи, место среди них и значение родителя. */\ninterface ILocation<TValue> {\n readonly node: TNode<TValue>;\n readonly siblings: TNodes<TValue>;\n readonly index: number;\n readonly parent: TValue | null;\n}\n\n/** Контейнер — узел с массивом детей, даже пустым: он принимает узлы внутрь. */\nfunction isContainer<TValue>(node: TNode<TValue>): boolean {\n return Array.isArray(node.children);\n}\n\nfunction locate<TValue>(nodes: TNodes<TValue>, value: TValue, parent: TValue | null = null): ILocation<TValue> | null {\n for (let index: number = 0; index < nodes.length; index++) {\n const node: TNode<TValue> = nodes[index];\n if (node.value === value) {\n return { siblings: nodes, node, index, parent };\n }\n const found: ILocation<TValue> | null = locate(node.children ?? [], value, node.value);\n if (found) {\n return found;\n }\n }\n return null;\n}\n\nfunction holds<TValue>(node: TNode<TValue>, value: TValue): boolean {\n return (node.children ?? []).some((child: TNode<TValue>): boolean => child.value === value || holds(child, value));\n}\n\nfunction without<TValue>(nodes: TNodes<TValue>, value: TValue): TNodes<TValue> {\n return nodes\n .filter((node: TNode<TValue>): boolean => node.value !== value)\n .map((node: TNode<TValue>): TNode<TValue> =>\n node.children && holds(node, value) ? { ...node, children: without(node.children, value) } : node\n );\n}\n\nfunction inserted<TValue>(nodes: TNodes<TValue>, moving: TNode<TValue>, drop: IRtDraggableTree.Drop<TValue>): TNodes<TValue> {\n const at: number = nodes.findIndex((node: TNode<TValue>): boolean => node.value === drop.target);\n if (at >= 0 && drop.place !== 'inside') {\n const index: number = drop.place === 'before' ? at : at + 1;\n return [...nodes.slice(0, index), moving, ...nodes.slice(index)];\n }\n return nodes.map((node: TNode<TValue>): TNode<TValue> => {\n if (node.value === drop.target && drop.place === 'inside') {\n return { ...node, children: [...(node.children ?? []), moving] };\n }\n if (node.children && holds(node, drop.target)) {\n return { ...node, children: inserted(node.children, moving, drop) };\n }\n return node;\n });\n}\n\nfunction siblingPlace<TValue>(here: ILocation<TValue>, step: number): IRtDraggableTree.Drop<TValue> | null {\n const next: TNode<TValue> | undefined = here.siblings[here.index + step];\n return next ? { target: next.value, place: step < 0 ? 'before' : 'after' } : null;\n}\n\nfunction levelPlace<TValue>(here: ILocation<TValue>, out: boolean): IRtDraggableTree.Drop<TValue> | null {\n if (out) {\n return here.parent === null ? null : { target: here.parent, place: 'after' };\n }\n const above: TNode<TValue> | undefined = here.siblings[here.index - 1];\n return above && isContainer(above) ? { target: above.value, place: 'inside' } : null;\n}\n\n/**\n * Место сброса по третям высоты строки: верхняя — перед целью, нижняя — после, средняя — внутрь.\n * Средняя треть листа места не даёт: внутрь принимает только контейнер.\n */\nexport function rtDragPlace<TValue>(target: TNode<TValue>, top: number, height: number, pointer: number): IRtDraggableTree.Place | null {\n const third: number = height / 3;\n const offset: number = pointer - top;\n if (offset < third) {\n return 'before';\n }\n if (offset > 2 * third) {\n return 'after';\n }\n return isContainer(target) ? 'inside' : null;\n}\n\n/**\n * Можно ли поставить узел на место: не на себя, не в своё поддерево, внутрь — только в контейнер, и\n * если приложение не запретило.\n */\nexport function rtDragAllowed<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>,\n canDrop: IRtDraggableTree.CanDrop<TValue> | null = null\n): boolean {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n const target: ILocation<TValue> | null = locate(nodes, drop.target);\n if (!moving || !target || drop.target === value || holds(moving.node, drop.target)) {\n return false;\n }\n if (drop.place === 'inside' && !isContainer(target.node)) {\n return false;\n }\n return canDrop ? canDrop(moving.node, target.node, drop.place) : true;\n}\n\n/** Переносит узел вместе с поддеревом. Узлы на входе не меняются: ветки на пути строятся заново. */\nexport function rtDragMove<TValue>(\n nodes: TNodes<TValue>,\n value: TValue,\n drop: IRtDraggableTree.Drop<TValue>\n): IRtDraggableTree.MoveResult<TValue> | null {\n const moving: ILocation<TValue> | null = locate(nodes, value);\n if (!moving || !rtDragAllowed(nodes, value, drop)) {\n return null;\n }\n const next: TNodes<TValue> = inserted(without(nodes, value), moving.node, drop);\n const landed: ILocation<TValue> | null = locate(next, value);\n if (!landed) {\n return null;\n }\n return { nodes: next, moved: { node: moving.node, parent: landed.parent, index: landed.index } };\n}\n\n/**\n * Место для переноса клавишей с Alt. Вверх и вниз — среди соседей, влево — сразу после своей ветки,\n * вправо — последним в контейнер, стоящий прямо над узлом. Двигаться некуда — `null`.\n */\nexport function rtDragKeyPlace<TValue>(nodes: TNodes<TValue>, value: TValue, key: string): IRtDraggableTree.Drop<TValue> | null {\n const here: ILocation<TValue> | null = locate(nodes, value);\n if (!here) {\n return null;\n }\n if (key === 'ArrowUp' || key === 'ArrowDown') {\n return siblingPlace(here, key === 'ArrowUp' ? -1 : 1);\n }\n if (key === 'ArrowLeft' || key === 'ArrowRight') {\n return levelPlace(here, key === 'ArrowLeft');\n }\n return null;\n}\n","import { CdkDrag, CdkDragHandle, CdkDragMove, CdkDropList } from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n computed,\n contentChild,\n inject,\n input,\n model,\n output,\n signal,\n viewChildren,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IRtIcon, RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtOptionTree, rtTreeRows, rtTreeSideKey, rtTreeToggle } from '@rt-tools/ui-kit-v2/core';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtTree } from '@rt-tools/ui-kit-v2/tree';\nimport { RtDraggableTreeNodeDirective } from './rt-draggable-tree.directives';\nimport { rtDragAllowed, rtDragKeyPlace, rtDragMove, rtDragPlace } from './rt-draggable-tree.logic';\nimport { IRtDraggableTree } from './rt-draggable-tree.model';\n\nconst BEM_BLOCK: string = 'rt-draggable-tree';\nconst MOVE_KEYS: ReadonlyArray<string> = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\n/**\n * Дерево, узлы которого человек переставляет: перетаскиванием строки до, после или внутрь другой,\n * или клавишами с Alt.\n *\n * Строки, уровни и раскрытие считает тот же модуль, что у `rt-tree`. Узлы на входе не меняются:\n * перенос пишет в `nodes` новый массив и сообщает `moved`. Место сброса — чистая функция от рамки\n * строки под указателем; документ дерево не читает.\n */\n@Component({\n selector: 'rt-draggable-tree',\n templateUrl: './rt-draggable-tree.component.html',\n styleUrl: './rt-draggable-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n CdkDrag,\n CdkDragHandle,\n CdkDropList,\n RtIconComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'tree',\n tabindex: '0',\n '[attr.aria-label]': 'ariaLabel()',\n '(keydown)': 'handleKeydown($event)',\n },\n})\nexport class RtDraggableTreeComponent<TValue> {\n readonly #highlighted: WritableSignal<TValue | null> = signal<TValue | null>(null);\n readonly #dragged: WritableSignal<TValue | null> = signal<TValue | null>(null);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly nodeTemplate: Signal<RtDraggableTreeNodeDirective<TValue> | undefined> = contentChild(RtDraggableTreeNodeDirective);\n\n protected readonly rowElements: Signal<ReadonlyArray<ElementRef<HTMLElement>>> = viewChildren<ElementRef<HTMLElement>>('row');\n\n /** Место, куда встанет перетаскиваемый узел; `null` — сейчас места нет. */\n protected readonly drop: WritableSignal<IRtDraggableTree.Drop<TValue> | null> = signal<IRtDraggableTree.Drop<TValue> | null>(null);\n\n /**\n * Раскрытые ветки. Пока приложение их не задало и человек ничего не сворачивал, раскрыты все:\n * порядок виден целиком с первого взгляда.\n */\n protected readonly openBranches: Signal<ReadonlySet<TValue>> = computed((): ReadonlySet<TValue> => {\n const open: ReadonlyArray<TValue> | null = this.open();\n if (open !== null) {\n return new Set<TValue>(open);\n }\n const all: Set<TValue> = new Set<TValue>();\n this.#collectBranches(this.nodes(), all);\n return all;\n });\n\n protected readonly rows: Signal<ReadonlyArray<IRtTree.Row<TValue>>> = computed((): ReadonlyArray<IRtTree.Row<TValue>> =>\n rtTreeRows(this.nodes(), this.openBranches(), '')\n );\n\n protected readonly highlighted: Signal<TValue | null> = this.#highlighted.asReadonly();\n\n public readonly nodes: ModelSignal<ReadonlyArray<IRtTree.Node<TValue>>> = model.required<ReadonlyArray<IRtTree.Node<TValue>>>();\n /** Значения раскрытых веток; `null` — раскрыты все. Пара `openChange` приходит на каждое раскрытие. */\n public readonly open: ModelSignal<ReadonlyArray<TValue> | null> = model<ReadonlyArray<TValue> | null>(null);\n public readonly canDrop: InputSignal<IRtDraggableTree.CanDrop<TValue> | null> = input<IRtDraggableTree.CanDrop<TValue> | null>(null);\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n /** Значок кита над подписью пустого дерева. Без него пустое дерево — одна подпись. */\n public readonly emptyIcon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n public readonly moved: OutputEmitterRef<IRtDraggableTree.Moved<TValue>> = output<IRtDraggableTree.Moved<TValue>>();\n public readonly picked: OutputEmitterRef<IRtTree.Node<TValue>> = output<IRtTree.Node<TValue>>();\n\n /** Клавиша для дерева. Отвечает, взята ли она: не взятая идёт дальше нетронутой. */\n public handleKeydown(event: KeyboardEvent): boolean {\n const taken: boolean = event.altKey ? this.#moveByKey(event.key) : this.#walkByKey(event.key);\n if (taken) {\n event.preventDefault();\n event.stopPropagation();\n }\n return taken;\n }\n\n protected onRowClick(row: IRtTree.Row<TValue>): void {\n this.#highlighted.set(row.option.value);\n this.picked.emit(row.option);\n }\n\n protected onToggleClick(event: Event, value: TValue): void {\n event.stopPropagation();\n this.#toggle(value);\n }\n\n protected onDragStarted(value: TValue): void {\n this.#dragged.set(value);\n }\n\n protected onDragMoved(event: CdkDragMove<TValue>): void {\n this.drop.set(this.#dropAt(event.pointerPosition.y));\n }\n\n protected onDropped(): void {\n const dragged: TValue | null = this.#dragged();\n const drop: IRtDraggableTree.Drop<TValue> | null = this.drop();\n this.#dragged.set(null);\n this.drop.set(null);\n if (dragged !== null && drop) {\n this.#apply(dragged, drop);\n }\n }\n\n #dropAt(pointer: number): IRtDraggableTree.Drop<TValue> | null {\n const dragged: TValue | null = this.#dragged();\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const elements: ReadonlyArray<ElementRef<HTMLElement>> = this.rowElements();\n if (dragged === null) {\n return null;\n }\n const index: number = elements.findIndex((element: ElementRef<HTMLElement>, at: number): boolean => {\n const box: DOMRect = element.nativeElement.getBoundingClientRect();\n return rows[at]?.option.value !== dragged && pointer >= box.top && pointer < box.bottom;\n });\n if (index < 0) {\n return null;\n }\n const box: DOMRect = elements[index].nativeElement.getBoundingClientRect();\n const target: IRtTree.Node<TValue> = rows[index].option;\n const place: IRtDraggableTree.Place | null = rtDragPlace(target, box.top, box.height, pointer);\n const drop: IRtDraggableTree.Drop<TValue> | null = place ? { target: target.value, place } : null;\n return drop && rtDragAllowed(this.nodes(), dragged, drop, this.canDrop()) ? drop : null;\n }\n\n #moveByKey(key: string): boolean {\n const value: TValue | null = this.#highlighted();\n if (!MOVE_KEYS.includes(key)) {\n return false;\n }\n const node: IRtTree.Node<TValue> | undefined = this.rows().find(\n (row: IRtTree.Row<TValue>): boolean => row.option.value === value\n )?.option;\n const drop: IRtDraggableTree.Drop<TValue> | null = node && !node.disabled ? rtDragKeyPlace(this.nodes(), node.value, key) : null;\n if (node && drop && rtDragAllowed(this.nodes(), node.value, drop, this.canDrop())) {\n this.#apply(node.value, drop);\n }\n return true;\n }\n\n #walkByKey(key: string): boolean {\n const rows: ReadonlyArray<IRtTree.Row<TValue>> = this.rows();\n const index: number = rows.findIndex((row: IRtTree.Row<TValue>): boolean => row.option.value === this.#highlighted());\n if (key === 'ArrowDown' || key === 'ArrowUp') {\n return this.#step(rows, index, key === 'ArrowDown' ? 1 : -1);\n }\n if (index < 0) {\n return false;\n }\n if (key === 'ArrowRight' || key === 'ArrowLeft') {\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 return true;\n }\n if (key === 'Enter') {\n this.picked.emit(rows[index].option);\n return true;\n }\n return false;\n }\n\n #step(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 #apply(value: TValue, drop: IRtDraggableTree.Drop<TValue>): void {\n const result: IRtDraggableTree.MoveResult<TValue> | null = rtDragMove(this.nodes(), value, drop);\n if (!result) {\n return;\n }\n this.nodes.set(result.nodes);\n if (drop.place === 'inside' && !this.openBranches().has(drop.target)) {\n this.open.set([...this.openBranches(), drop.target]);\n }\n this.moved.emit(result.moved);\n }\n\n #toggle(value: TValue): void {\n this.open.set([...rtTreeToggle(this.openBranches(), value)]);\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","<ng-container rtBlock=\"rt-draggable-tree\">\n <!--\n Строки берут мышь через (click), клавиатура — на самом дереве (handleKeydown): строки фокус не\n берут, подсвеченная строка — состояние рядом с фокусом. Строку тянут за ручку; список один на\n всё дерево, и место сброса считает компонент по рамке строки под указателем.\n -->\n <!-- eslint-disable @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div rtElem=\"list\" cdkDropList [cdkDropListSortingDisabled]=\"true\" (cdkDropListDropped)=\"onDropped()\">\n @for (row of rows(); track row.option.value) {\n <div\n #row\n rtElem=\"row\"\n qa-dataid=\"draggable-tree-row\"\n role=\"treeitem\"\n cdkDrag\n [cdkDragData]=\"row.option.value\"\n [cdkDragDisabled]=\"!!row.option.disabled\"\n [attr.data-value]=\"row.option.value\"\n [attr.aria-level]=\"row.level + 1\"\n [attr.aria-expanded]=\"row.branch ? row.open : null\"\n [attr.aria-selected]=\"row.option.value === highlighted()\"\n [attr.aria-disabled]=\"!!row.option.disabled\"\n [style.--rt-draggable-tree-level]=\"row.level\"\n [rtMod]=\"{\n highlighted: row.option.value === highlighted(),\n disabled: !!row.option.disabled,\n 'drop-before': drop()?.target === row.option.value && drop()?.place === 'before',\n 'drop-after': drop()?.target === row.option.value && drop()?.place === 'after',\n 'drop-inside': drop()?.target === row.option.value && drop()?.place === 'inside',\n }\"\n (cdkDragStarted)=\"onDragStarted(row.option.value)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (click)=\"onRowClick(row)\">\n @if (row.option.disabled) {\n <span rtElem=\"handle-space\"></span>\n } @else {\n <span rtElem=\"handle\" qa-dataid=\"draggable-tree-handle\" cdkDragHandle aria-hidden=\"true\">\n <rt-icon name=\"bars\" size=\"sm\" color=\"muted\" />\n </span>\n }\n\n @if (row.branch) {\n <button\n rtElem=\"toggle\"\n qa-dataid=\"draggable-tree-toggle\"\n type=\"button\"\n tabindex=\"-1\"\n [attr.aria-label]=\"row.open ? t().uiCollapse : t().uiExpand\"\n (click)=\"onToggleClick($event, row.option.value)\">\n <rt-icon size=\"sm\" color=\"muted\" [name]=\"row.open ? 'chevron-down' : 'chevron-right'\" />\n </button>\n } @else {\n <span rtElem=\"toggle-space\"></span>\n }\n\n <span rtElem=\"content\" qa-dataid=\"draggable-tree-content\">\n @if (nodeTemplate(); as template) {\n <ng-container [ngTemplateOutlet]=\"template.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row.option }\" />\n } @else {\n <span rtElem=\"label\" qa-dataid=\"draggable-tree-label\" rtTooltipWhenTruncated [rtTooltip]=\"row.option.label\">\n {{ row.option.label }}\n </span>\n }\n </span>\n </div>\n } @empty {\n <div rtElem=\"empty\" qa-dataid=\"draggable-tree-empty\" [rtMod]=\"{ 'with-icon': !!emptyIcon() }\">\n @if (emptyIcon(); as icon) {\n <rt-icon rtElem=\"empty-icon\" qa-dataid=\"draggable-tree-empty-icon\" size=\"lg\" [name]=\"icon\" />\n }\n {{ t().uiNoOptions }}\n </div>\n }\n </div>\n</ng-container>\n"],"mappings":"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"}
|
|
@@ -371,7 +371,7 @@ var RtDynamicListComponent = class RtDynamicListComponent {
|
|
|
371
371
|
}],
|
|
372
372
|
ngImport: i0,
|
|
373
373
|
template: "<ng-container rtBlock=\"rt-dynamic-list\">\n @if (loading()) {\n <div rtElem=\"loader\" qa-dataid=\"dynamic-list-loader\">\n <rt-spinner />\n </div>\n } @else {\n @if (fetching()) {\n <div rtElem=\"veil\" qa-dataid=\"dynamic-list-veil\">\n <rt-spinner />\n </div>\n }\n\n @if (isToolbarShown()) {\n <div rtElem=\"toolbar\" qa-dataid=\"dynamic-list-toolbar\">\n @if (selectable() || selectorsTpl()) {\n <div rtElem=\"selectors\" qa-dataid=\"dynamic-list-selectors\">\n @if (selectable()) {\n <rt-checkbox\n qa-dataid=\"dynamic-list-select-all\"\n [ariaLabel]=\"t().uiSelectAll\"\n [ngModel]=\"allSelected()\"\n [indeterminate]=\"!allSelected() && someSelected()\"\n [disabled]=\"selectAllDisabled()\"\n (ngModelChange)=\"onSelectAll($event)\" />\n\n @if (selectedCount()) {\n <span rtElem=\"counter\" qa-dataid=\"dynamic-list-selected-count\">\n {{ selectedLabel() }}\n </span>\n }\n }\n\n @if (selectorsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n </div>\n }\n\n <div rtElem=\"right\" qa-dataid=\"dynamic-list-right\">\n <div rtElem=\"actions\">\n @if (actionsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n\n @if (showClearFilters()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-clear-filters\"\n icon=\"filter-slash\"\n size=\"sm\"\n [ariaLabel]=\"t().uiClearFilters\"\n [tooltip]=\"t().uiClearFilters\"\n [disabled]=\"!filtered()\"\n (clicked)=\"onClearFilters()\" />\n }\n\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-refresh\"\n icon=\"refresh\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRefresh\"\n [tooltip]=\"t().uiRefresh\"\n (clicked)=\"refreshed.emit()\" />\n }\n\n @if (showColumnSettings()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-column-settings\"\n icon=\"sliders-v\"\n size=\"sm\"\n [ariaLabel]=\"t().uiColumnSettings\"\n [tooltip]=\"t().uiColumnSettings\"\n (clicked)=\"columnSettingsOpened.emit()\" />\n }\n </div>\n\n @if (showSearch()) {\n <div rtElem=\"search\">\n <rt-input\n qa-dataid=\"dynamic-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"t().uiSearch\"\n [formControl]=\"searchControl\" />\n </div>\n }\n </div>\n </div>\n }\n\n @if (empty()) {\n <rt-empty-state\n rtElem=\"empty\"\n qa-dataid=\"dynamic-list-empty\"\n [icon]=\"emptyIcon()\"\n [title]=\"emptyTitleText()\"\n [description]=\"emptyDescription()\">\n @if (emptyReason() === 'filter') {\n <button\n rtButton\n qa-dataid=\"dynamic-list-empty-clear\"\n type=\"button\"\n icon=\"filter-slash\"\n appearance=\"outlined\"\n size=\"sm\"\n [label]=\"t().uiClearFilters\"\n [attr.aria-label]=\"t().uiClearFilters\"\n (click)=\"onClearFilters()\"></button>\n }\n </rt-empty-state>\n } @else {\n <div rtElem=\"content\" qa-dataid=\"dynamic-list-content\">\n <ng-content />\n </div>\n\n @if (isPaginationShown()) {\n <rt-pagination\n rtElem=\"pagination\"\n qa-dataid=\"dynamic-list-pagination\"\n [pageModel]=\"pageModel()!\"\n [perPageOptions]=\"perPageOptions\"\n [loading]=\"fetching()\"\n (pageChange)=\"pageChange.emit($event)\"\n (perPageChange)=\"perPageChange.emit($event)\" />\n }\n }\n }\n</ng-container>\n",
|
|
374
|
-
styles: ["@layer rt-kit.components{.rt-dynamic-list{--rt-dynamic-list-gap: var(--rt-space-4);--rt-dynamic-list-search-width: var(--rt-size-64);--rt-dynamic-list-veil-bg: var(--rt-color-bg-surface);position:relative;display:flex;flex-direction:column;block-size:100%;gap:var(--rt-dynamic-list-gap);inline-size:100%;min-block-size:0}.rt-dynamic-list__loader{display:flex;flex:1 1 auto;align-items:center;justify-content:center;padding:var(--rt-space-8)}.rt-dynamic-list__veil{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background-color:color-mix(in srgb,var(--rt-dynamic-list-veil-bg) 60%,transparent);inset:0}.rt-dynamic-list__toolbar{display:flex;flex:0 0 auto;flex-wrap:wrap;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__selectors{display:flex;flex:0 1 auto;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__counter{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-dynamic-list__right{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__actions{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-1)}.rt-dynamic-list__search{flex:1 1 auto;max-inline-size:var(--rt-dynamic-list-search-width);min-inline-size:0}.rt-dynamic-list__content{display:flex;overflow:auto;flex:1 1 auto;flex-direction:column;isolation:isolate;min-block-size:0}.rt-dynamic-list__empty{flex:1 1 auto}.rt-dynamic-list__pagination{flex:0 0 auto}@container rt-place (width <= 1080px){.rt-dynamic-list__right{flex-wrap:wrap}.rt-dynamic-list__search{max-inline-size:none}}}\n"],
|
|
374
|
+
styles: ["@layer rt-kit.components{.rt-dynamic-list{--rt-dynamic-list-gap: var(--rt-space-4);--rt-dynamic-list-search-width: var(--rt-size-64);--rt-dynamic-list-veil-bg: var(--rt-color-bg-surface);position:relative;display:flex;flex-direction:column;block-size:100%;gap:var(--rt-dynamic-list-gap);inline-size:100%;min-block-size:0}.rt-dynamic-list__loader{display:flex;flex:1 1 auto;align-items:center;justify-content:center;padding:var(--rt-space-8)}.rt-dynamic-list__veil{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background-color:color-mix(in srgb,var(--rt-dynamic-list-veil-bg) 60%,transparent);inset:0}.rt-dynamic-list__toolbar{display:flex;flex:0 0 auto;flex-wrap:wrap;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__selectors{display:flex;flex:0 1 auto;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__counter{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-dynamic-list__right{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__actions{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-1)}.rt-dynamic-list__search{flex:1 1 auto;max-inline-size:var(--rt-dynamic-list-search-width);min-inline-size:0}.rt-dynamic-list__content{display:flex;overflow:auto;flex:1 1 auto;flex-direction:column;isolation:isolate;min-block-size:0}.rt-dynamic-list__empty{flex:1 1 auto}.rt-dynamic-list__pagination{flex:0 0 auto}@container rt-place (width <= 1080px){.rt-dynamic-list__right{flex-wrap:wrap}.rt-dynamic-list__search{max-inline-size:none}}@media(width<=1080px){:where(html:not(:has(.rt-container))) .rt-dynamic-list__right{flex-wrap:wrap}:where(html:not(:has(.rt-container))) .rt-dynamic-list__search{max-inline-size:none}}}\n"],
|
|
375
375
|
dependencies: [
|
|
376
376
|
{
|
|
377
377
|
kind: "directive",
|
|
@@ -572,7 +572,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
572
572
|
],
|
|
573
573
|
host: { class: BEM_BLOCK },
|
|
574
574
|
template: "<ng-container rtBlock=\"rt-dynamic-list\">\n @if (loading()) {\n <div rtElem=\"loader\" qa-dataid=\"dynamic-list-loader\">\n <rt-spinner />\n </div>\n } @else {\n @if (fetching()) {\n <div rtElem=\"veil\" qa-dataid=\"dynamic-list-veil\">\n <rt-spinner />\n </div>\n }\n\n @if (isToolbarShown()) {\n <div rtElem=\"toolbar\" qa-dataid=\"dynamic-list-toolbar\">\n @if (selectable() || selectorsTpl()) {\n <div rtElem=\"selectors\" qa-dataid=\"dynamic-list-selectors\">\n @if (selectable()) {\n <rt-checkbox\n qa-dataid=\"dynamic-list-select-all\"\n [ariaLabel]=\"t().uiSelectAll\"\n [ngModel]=\"allSelected()\"\n [indeterminate]=\"!allSelected() && someSelected()\"\n [disabled]=\"selectAllDisabled()\"\n (ngModelChange)=\"onSelectAll($event)\" />\n\n @if (selectedCount()) {\n <span rtElem=\"counter\" qa-dataid=\"dynamic-list-selected-count\">\n {{ selectedLabel() }}\n </span>\n }\n }\n\n @if (selectorsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n </div>\n }\n\n <div rtElem=\"right\" qa-dataid=\"dynamic-list-right\">\n <div rtElem=\"actions\">\n @if (actionsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n\n @if (showClearFilters()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-clear-filters\"\n icon=\"filter-slash\"\n size=\"sm\"\n [ariaLabel]=\"t().uiClearFilters\"\n [tooltip]=\"t().uiClearFilters\"\n [disabled]=\"!filtered()\"\n (clicked)=\"onClearFilters()\" />\n }\n\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-refresh\"\n icon=\"refresh\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRefresh\"\n [tooltip]=\"t().uiRefresh\"\n (clicked)=\"refreshed.emit()\" />\n }\n\n @if (showColumnSettings()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-column-settings\"\n icon=\"sliders-v\"\n size=\"sm\"\n [ariaLabel]=\"t().uiColumnSettings\"\n [tooltip]=\"t().uiColumnSettings\"\n (clicked)=\"columnSettingsOpened.emit()\" />\n }\n </div>\n\n @if (showSearch()) {\n <div rtElem=\"search\">\n <rt-input\n qa-dataid=\"dynamic-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"t().uiSearch\"\n [formControl]=\"searchControl\" />\n </div>\n }\n </div>\n </div>\n }\n\n @if (empty()) {\n <rt-empty-state\n rtElem=\"empty\"\n qa-dataid=\"dynamic-list-empty\"\n [icon]=\"emptyIcon()\"\n [title]=\"emptyTitleText()\"\n [description]=\"emptyDescription()\">\n @if (emptyReason() === 'filter') {\n <button\n rtButton\n qa-dataid=\"dynamic-list-empty-clear\"\n type=\"button\"\n icon=\"filter-slash\"\n appearance=\"outlined\"\n size=\"sm\"\n [label]=\"t().uiClearFilters\"\n [attr.aria-label]=\"t().uiClearFilters\"\n (click)=\"onClearFilters()\"></button>\n }\n </rt-empty-state>\n } @else {\n <div rtElem=\"content\" qa-dataid=\"dynamic-list-content\">\n <ng-content />\n </div>\n\n @if (isPaginationShown()) {\n <rt-pagination\n rtElem=\"pagination\"\n qa-dataid=\"dynamic-list-pagination\"\n [pageModel]=\"pageModel()!\"\n [perPageOptions]=\"perPageOptions\"\n [loading]=\"fetching()\"\n (pageChange)=\"pageChange.emit($event)\"\n (perPageChange)=\"perPageChange.emit($event)\" />\n }\n }\n }\n</ng-container>\n",
|
|
575
|
-
styles: ["@layer rt-kit.components{.rt-dynamic-list{--rt-dynamic-list-gap: var(--rt-space-4);--rt-dynamic-list-search-width: var(--rt-size-64);--rt-dynamic-list-veil-bg: var(--rt-color-bg-surface);position:relative;display:flex;flex-direction:column;block-size:100%;gap:var(--rt-dynamic-list-gap);inline-size:100%;min-block-size:0}.rt-dynamic-list__loader{display:flex;flex:1 1 auto;align-items:center;justify-content:center;padding:var(--rt-space-8)}.rt-dynamic-list__veil{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background-color:color-mix(in srgb,var(--rt-dynamic-list-veil-bg) 60%,transparent);inset:0}.rt-dynamic-list__toolbar{display:flex;flex:0 0 auto;flex-wrap:wrap;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__selectors{display:flex;flex:0 1 auto;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__counter{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-dynamic-list__right{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__actions{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-1)}.rt-dynamic-list__search{flex:1 1 auto;max-inline-size:var(--rt-dynamic-list-search-width);min-inline-size:0}.rt-dynamic-list__content{display:flex;overflow:auto;flex:1 1 auto;flex-direction:column;isolation:isolate;min-block-size:0}.rt-dynamic-list__empty{flex:1 1 auto}.rt-dynamic-list__pagination{flex:0 0 auto}@container rt-place (width <= 1080px){.rt-dynamic-list__right{flex-wrap:wrap}.rt-dynamic-list__search{max-inline-size:none}}}\n"]
|
|
575
|
+
styles: ["@layer rt-kit.components{.rt-dynamic-list{--rt-dynamic-list-gap: var(--rt-space-4);--rt-dynamic-list-search-width: var(--rt-size-64);--rt-dynamic-list-veil-bg: var(--rt-color-bg-surface);position:relative;display:flex;flex-direction:column;block-size:100%;gap:var(--rt-dynamic-list-gap);inline-size:100%;min-block-size:0}.rt-dynamic-list__loader{display:flex;flex:1 1 auto;align-items:center;justify-content:center;padding:var(--rt-space-8)}.rt-dynamic-list__veil{position:absolute;z-index:1;display:flex;align-items:center;justify-content:center;background-color:color-mix(in srgb,var(--rt-dynamic-list-veil-bg) 60%,transparent);inset:0}.rt-dynamic-list__toolbar{display:flex;flex:0 0 auto;flex-wrap:wrap;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__selectors{display:flex;flex:0 1 auto;align-items:center;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__counter{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-dynamic-list__right{display:flex;flex:1 1 auto;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--rt-space-2);min-inline-size:0}.rt-dynamic-list__actions{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-1)}.rt-dynamic-list__search{flex:1 1 auto;max-inline-size:var(--rt-dynamic-list-search-width);min-inline-size:0}.rt-dynamic-list__content{display:flex;overflow:auto;flex:1 1 auto;flex-direction:column;isolation:isolate;min-block-size:0}.rt-dynamic-list__empty{flex:1 1 auto}.rt-dynamic-list__pagination{flex:0 0 auto}@container rt-place (width <= 1080px){.rt-dynamic-list__right{flex-wrap:wrap}.rt-dynamic-list__search{max-inline-size:none}}@media(width<=1080px){:where(html:not(:has(.rt-container))) .rt-dynamic-list__right{flex-wrap:wrap}:where(html:not(:has(.rt-container))) .rt-dynamic-list__search{max-inline-size:none}}}\n"]
|
|
576
576
|
}]
|
|
577
577
|
}],
|
|
578
578
|
ctorParameters: () => [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rt-tools-ui-kit-v2-dynamic-list.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/dynamic-list/rt-dynamic-list.directives.ts","../../../projects/ui-kit-v2/src/lib/components/dynamic-list/rt-dynamic-list.component.ts","../../../projects/ui-kit-v2/src/lib/components/dynamic-list/rt-dynamic-list.component.html"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/**\n * Маркеры частей панели инструментов — своим файлом, как у соседних семей.\n *\n * В имени класса стоит слово «Toolbar», хотя в разметке его нет: имя `RtDynamicListSelectorsDirective`\n * в дереве уже занято первым китом, и там оно означает другое — проводку состояния списка, а не\n * маркер стороны полосы. Два одинаковых имени в двух китах проверка дерева не пропускает.\n *\n * Каждый маркер держит свой шаблон и о списке не знает ничего: список читает маркеры среди своего\n * содержимого и берёт у них шаблон. Часть, которую потребитель не объявил, для списка просто\n * отсутствует.\n */\n\n/**\n * Левая сторона панели: то, чем человек отбирает записи.\n *\n * @example\n * ```html\n * <rt-dynamic-list>\n * <ng-container *rtDynamicListSelectors>\n * <rt-select [options]=\"stages()\" />\n * </ng-container>\n * </rt-dynamic-list>\n * ```\n */\n@Directive({\n selector: '[rtDynamicListSelectors]',\n})\nexport class RtDynamicListToolbarSelectorsDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n\n/** Правая сторона панели: действия над разделом. Поле поиска стоит после них и остаётся за семьёй. */\n@Directive({\n selector: '[rtDynamicListActions]',\n})\nexport class RtDynamicListToolbarActionsDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n DestroyRef,\n effect,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n OnInit,\n output,\n OutputEmitterRef,\n Signal,\n untracked,\n ViewEncapsulation,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';\n\nimport { filter, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\nimport { IPageModel, TNullable } from '@rt-tools/utils';\n\nimport { RT_KIT_LABELS, rtKitLabel, TRtKitLabelMap, TRtKitLabelParams } from '@rt-tools/ui-kit-v2/core';\nimport { searchDebounce } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtCheckboxComponent } from '@rt-tools/ui-kit-v2/checkbox';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPaginationComponent } from '@rt-tools/ui-kit-v2/pagination';\nimport { RtSpinnerComponent } from '@rt-tools/ui-kit-v2/spinner';\nimport { RtDynamicListToolbarActionsDirective, RtDynamicListToolbarSelectorsDirective } from './rt-dynamic-list.directives';\nimport { IRtDynamicList } from './rt-dynamic-list.model';\n\nconst BEM_BLOCK: string = 'rt-dynamic-list';\n\n/**\n * Размеры страницы, которые предлагает полоса страниц. Семья передаёт их полосе сама: по наименьшему\n * из них она решает, рисовать ли полосу, и то же решение принимает полоса у себя.\n */\nconst PER_PAGE_OPTIONS: ReadonlyArray<number> = [20, 50, 100];\n\n/**\n * Список записей со своей панелью инструментов.\n *\n * Полосу панели семья раскладывает сама, а не зовёт `rt-toolbar`: у того стороны объявлены\n * нешринкующимися, и на хозяине уже́ содержимого полоса раздаётся шире него и уезжает за край.\n * Семья кладёт в полосу готовые части кита — поле, кнопки, флажок, — а строит её сама.\n *\n * Семья ничего не рисует сама: поиск — поле кита, действия — его кнопки со значком, пустое место —\n * его пустое состояние, страницы — его нумерация. Сами записи проецируются: таблица между панелью\n * и страницами — потребителя, с его колонками, ячейками и действиями строки.\n *\n * Договорённость — `docs/specs/ui-kit-v2/dynamic-list/`.\n */\n@Component({\n selector: 'rt-dynamic-list',\n templateUrl: './rt-dynamic-list.component.html',\n styleUrls: ['./rt-dynamic-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtButtonDirective,\n RtCheckboxComponent,\n RtEmptyStateComponent,\n RtIconButtonComponent,\n RtInputComponent,\n RtPaginationComponent,\n RtSpinnerComponent,\n BlockDirective,\n ElemDirective,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtDynamicListComponent implements OnInit {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n /**\n * Последнее, что знают и потребитель, и поле: отправленное потребителю или поставленное им самим.\n * Одно и то же дважды не спрашивается, а поставленное потребителем не возвращается ему эхом.\n */\n #lastSearch: string = '';\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly searchControl: FormControl<string> = new FormControl<string>('', { nonNullable: true });\n\n protected readonly perPageOptions: ReadonlyArray<number> = PER_PAGE_OPTIONS;\n\n protected readonly selectorsTpl: Signal<TNullable<RtDynamicListToolbarSelectorsDirective>> = contentChild(\n RtDynamicListToolbarSelectorsDirective\n );\n\n protected readonly actionsTpl: Signal<TNullable<RtDynamicListToolbarActionsDirective>> = contentChild(\n RtDynamicListToolbarActionsDirective\n );\n\n /** «Выбрано: N» — подпись с подстановкой, потому её берут не из карты, а вызовом. */\n protected readonly selectedLabel: Signal<string> = rtKitLabel(\n 'uiSelectedCount',\n computed((): TRtKitLabelParams => ({ count: this.selectedCount() }))\n );\n\n /** Отчего пусто. Отбор стоит — значит, записи убрал он, и человеку показывают дорогу назад. */\n protected readonly emptyReason: Signal<IRtDynamicList.EmptyReason> = computed((): IRtDynamicList.EmptyReason =>\n this.filtered() ? 'filter' : 'section'\n );\n\n /** Значок пустого места: под отбором — лупа, у пустого раздела — лоток. */\n protected readonly emptyIcon: Signal<IRtIcon.Name> = computed((): IRtIcon.Name =>\n this.emptyReason() === 'filter' ? 'search' : 'inbox'\n );\n\n /** Подпись пустого места. Своя подпись потребителя сильнее обеих подписей кита. */\n protected readonly emptyTitleText: Signal<string> = computed((): string => {\n if (this.emptyTitle()) {\n return this.emptyTitle();\n }\n\n return this.emptyReason() === 'filter' ? this.t().uiNothingFound : this.t().uiNoRows;\n });\n\n /**\n * Полоса страниц рисуется, пока записей больше наименьшего размера страницы — то же правило, что у\n * самой полосы. Число страниц при нынешнем размере тут не решает: выбравший крупный размер, при\n * котором всё легло на одну страницу, иначе терял вместе с полосой и дорогу к размеру поменьше.\n */\n protected readonly isPaginationShown: Signal<boolean> = computed((): boolean => {\n const page: TNullable<IPageModel> = this.pageModel();\n\n if (!page || this.empty()) {\n return false;\n }\n\n return page.totalCount > Math.min(...PER_PAGE_OPTIONS);\n });\n\n /**\n * Есть ли в панели хоть что-нибудь. Полоса без единой части — это отступ над записями, и\n * место она забирает у них.\n */\n protected readonly isToolbarShown: Signal<boolean> = computed((): boolean =>\n [\n this.showSearch(),\n this.showRefresh(),\n this.showClearFilters(),\n this.showColumnSettings(),\n this.selectable(),\n !!this.selectorsTpl(),\n !!this.actionsTpl(),\n ].some((part: boolean): boolean => part)\n );\n\n /** Записи проецируются, и о числе страниц семья узнаёт только из модели страницы. */\n public readonly pageModel: InputSignal<TNullable<IPageModel>> = input<TNullable<IPageModel>>(null);\n\n /** Первая загрузка: вместо всего содержимого стоит вертушка. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Подгрузка поверх нарисованного: записи остаются на месте, вертушка стоит над ними. */\n public readonly fetching: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Записей нет вовсе. От пустого ответа под отбором отличается входом `filtered`. */\n public readonly empty: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Отбор стоит. Вместе с `empty` даёт вторую причину пустоты — ту, у которой есть дорога назад. */\n public readonly filtered: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Кнопка сброса отбора: показана у раздела с отбором, выключена, пока сбрасывать нечего. */\n public readonly showClearFilters: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly showRefresh: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly showColumnSettings: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly showSearch: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /** Выбор записей: флажок «выбрать все» и счётчик выбранного на левой стороне панели. */\n public readonly selectable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly allSelected: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly someSelected: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly selectAllDisabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly selectedCount: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(0, {\n transform: numberAttribute,\n });\n\n public readonly emptyTitle: InputSignal<string> = input<string>('');\n\n public readonly emptyDescription: InputSignal<string | null> = input<string | null>(null);\n\n /** Поиск потребителя: поле следует за ним при каждой смене и потребителю его не возвращает. */\n public readonly searchTerm: InputSignal<TNullable<string>> = input<TNullable<string>>('');\n\n public readonly searchChange: OutputEmitterRef<string> = output<string>();\n\n public readonly refreshed: OutputEmitterRef<void> = output<void>();\n\n public readonly filtersCleared: OutputEmitterRef<void> = output<void>();\n\n public readonly columnSettingsOpened: OutputEmitterRef<void> = output<void>();\n\n public readonly pageChange: OutputEmitterRef<number> = output<number>();\n\n public readonly perPageChange: OutputEmitterRef<number> = output<number>();\n\n public readonly allSelectedChange: OutputEmitterRef<boolean> = output<boolean>();\n\n constructor() {\n // Поиск потребителя ставится в поле, только когда он отличается от последнего, что список\n // отправил или поставил сам. Эхо отправленного — даже запоздалое, когда человек уже дописал\n // дальше, — поле не трогает: иначе оно стирало бы набранное и сбивало каретку.\n effect((): void => {\n const term: string = this.searchTerm() ?? '';\n\n untracked((): void => {\n if (term.trim() === this.#lastSearch) {\n return;\n }\n\n this.#lastSearch = term.trim();\n this.searchControl.setValue(term, { emitEvent: false });\n });\n });\n }\n\n public ngOnInit(): void {\n // Дебаунс непустого ввода; очистка крестиком применяется сразу — так же, как в списке\n // переписок: оператор один на кит, и два разных ожидания разошлись бы молча.\n this.searchControl.valueChanges\n .pipe(\n map((value: string): string => value.trim()),\n searchDebounce(),\n // Набранное, которое потребитель или сброс отбора успели заменить, уже не в поле.\n filter((value: string): boolean => value === this.searchControl.value.trim()),\n filter((value: string): boolean => value !== this.#lastSearch),\n takeUntilDestroyed(this.#destroyRef)\n )\n .subscribe((value: string): void => {\n this.#lastSearch = value;\n this.searchChange.emit(value);\n });\n }\n\n protected onSelectAll(checked: boolean): void {\n this.allSelectedChange.emit(checked);\n }\n\n /**\n * Сброс отбора снимает и поиск: пустой ответ под поиском — тоже ответ под отбором, и дорога назад\n * без очистки поля вела бы к тому же пустому ответу. Поле очищается молча: `filtersCleared`\n * уже значит «и поиск снят», и отдельный пустой `searchChange` заставил бы потребителя\n * запрашивать список дважды.\n */\n protected onClearFilters(): void {\n this.#lastSearch = '';\n this.searchControl.setValue('', { emitEvent: false });\n this.filtersCleared.emit();\n }\n}\n","<ng-container rtBlock=\"rt-dynamic-list\">\n @if (loading()) {\n <div rtElem=\"loader\" qa-dataid=\"dynamic-list-loader\">\n <rt-spinner />\n </div>\n } @else {\n @if (fetching()) {\n <div rtElem=\"veil\" qa-dataid=\"dynamic-list-veil\">\n <rt-spinner />\n </div>\n }\n\n @if (isToolbarShown()) {\n <div rtElem=\"toolbar\" qa-dataid=\"dynamic-list-toolbar\">\n @if (selectable() || selectorsTpl()) {\n <div rtElem=\"selectors\" qa-dataid=\"dynamic-list-selectors\">\n @if (selectable()) {\n <rt-checkbox\n qa-dataid=\"dynamic-list-select-all\"\n [ariaLabel]=\"t().uiSelectAll\"\n [ngModel]=\"allSelected()\"\n [indeterminate]=\"!allSelected() && someSelected()\"\n [disabled]=\"selectAllDisabled()\"\n (ngModelChange)=\"onSelectAll($event)\" />\n\n @if (selectedCount()) {\n <span rtElem=\"counter\" qa-dataid=\"dynamic-list-selected-count\">\n {{ selectedLabel() }}\n </span>\n }\n }\n\n @if (selectorsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n </div>\n }\n\n <div rtElem=\"right\" qa-dataid=\"dynamic-list-right\">\n <div rtElem=\"actions\">\n @if (actionsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n\n @if (showClearFilters()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-clear-filters\"\n icon=\"filter-slash\"\n size=\"sm\"\n [ariaLabel]=\"t().uiClearFilters\"\n [tooltip]=\"t().uiClearFilters\"\n [disabled]=\"!filtered()\"\n (clicked)=\"onClearFilters()\" />\n }\n\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-refresh\"\n icon=\"refresh\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRefresh\"\n [tooltip]=\"t().uiRefresh\"\n (clicked)=\"refreshed.emit()\" />\n }\n\n @if (showColumnSettings()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-column-settings\"\n icon=\"sliders-v\"\n size=\"sm\"\n [ariaLabel]=\"t().uiColumnSettings\"\n [tooltip]=\"t().uiColumnSettings\"\n (clicked)=\"columnSettingsOpened.emit()\" />\n }\n </div>\n\n @if (showSearch()) {\n <div rtElem=\"search\">\n <rt-input\n qa-dataid=\"dynamic-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"t().uiSearch\"\n [formControl]=\"searchControl\" />\n </div>\n }\n </div>\n </div>\n }\n\n @if (empty()) {\n <rt-empty-state\n rtElem=\"empty\"\n qa-dataid=\"dynamic-list-empty\"\n [icon]=\"emptyIcon()\"\n [title]=\"emptyTitleText()\"\n [description]=\"emptyDescription()\">\n @if (emptyReason() === 'filter') {\n <button\n rtButton\n qa-dataid=\"dynamic-list-empty-clear\"\n type=\"button\"\n icon=\"filter-slash\"\n appearance=\"outlined\"\n size=\"sm\"\n [label]=\"t().uiClearFilters\"\n [attr.aria-label]=\"t().uiClearFilters\"\n (click)=\"onClearFilters()\"></button>\n }\n </rt-empty-state>\n } @else {\n <div rtElem=\"content\" qa-dataid=\"dynamic-list-content\">\n <ng-content />\n </div>\n\n @if (isPaginationShown()) {\n <rt-pagination\n rtElem=\"pagination\"\n qa-dataid=\"dynamic-list-pagination\"\n [pageModel]=\"pageModel()!\"\n [perPageOptions]=\"perPageOptions\"\n [loading]=\"fetching()\"\n (pageChange)=\"pageChange.emit($event)\"\n (perPageChange)=\"perPageChange.emit($event)\" />\n }\n }\n }\n</ng-container>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-dynamic-list.mjs","names":[],"sources":["../../../projects/ui-kit-v2/src/lib/components/dynamic-list/rt-dynamic-list.directives.ts","../../../projects/ui-kit-v2/src/lib/components/dynamic-list/rt-dynamic-list.component.ts","../../../projects/ui-kit-v2/src/lib/components/dynamic-list/rt-dynamic-list.component.html"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/**\n * Маркеры частей панели инструментов — своим файлом, как у соседних семей.\n *\n * В имени класса стоит слово «Toolbar», хотя в разметке его нет: имя `RtDynamicListSelectorsDirective`\n * в дереве уже занято первым китом, и там оно означает другое — проводку состояния списка, а не\n * маркер стороны полосы. Два одинаковых имени в двух китах проверка дерева не пропускает.\n *\n * Каждый маркер держит свой шаблон и о списке не знает ничего: список читает маркеры среди своего\n * содержимого и берёт у них шаблон. Часть, которую потребитель не объявил, для списка просто\n * отсутствует.\n */\n\n/**\n * Левая сторона панели: то, чем человек отбирает записи.\n *\n * @example\n * ```html\n * <rt-dynamic-list>\n * <ng-container *rtDynamicListSelectors>\n * <rt-select [options]=\"stages()\" />\n * </ng-container>\n * </rt-dynamic-list>\n * ```\n */\n@Directive({\n selector: '[rtDynamicListSelectors]',\n})\nexport class RtDynamicListToolbarSelectorsDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n\n/** Правая сторона панели: действия над разделом. Поле поиска стоит после них и остаётся за семьёй. */\n@Directive({\n selector: '[rtDynamicListActions]',\n})\nexport class RtDynamicListToolbarActionsDirective {\n public readonly templateRef: TemplateRef<void> = inject<TemplateRef<void>>(TemplateRef);\n}\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n DestroyRef,\n effect,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n OnInit,\n output,\n OutputEmitterRef,\n Signal,\n untracked,\n ViewEncapsulation,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';\n\nimport { filter, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\nimport { IPageModel, TNullable } from '@rt-tools/utils';\n\nimport { RT_KIT_LABELS, rtKitLabel, TRtKitLabelMap, TRtKitLabelParams } from '@rt-tools/ui-kit-v2/core';\nimport { searchDebounce } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtCheckboxComponent } from '@rt-tools/ui-kit-v2/checkbox';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPaginationComponent } from '@rt-tools/ui-kit-v2/pagination';\nimport { RtSpinnerComponent } from '@rt-tools/ui-kit-v2/spinner';\nimport { RtDynamicListToolbarActionsDirective, RtDynamicListToolbarSelectorsDirective } from './rt-dynamic-list.directives';\nimport { IRtDynamicList } from './rt-dynamic-list.model';\n\nconst BEM_BLOCK: string = 'rt-dynamic-list';\n\n/**\n * Размеры страницы, которые предлагает полоса страниц. Семья передаёт их полосе сама: по наименьшему\n * из них она решает, рисовать ли полосу, и то же решение принимает полоса у себя.\n */\nconst PER_PAGE_OPTIONS: ReadonlyArray<number> = [20, 50, 100];\n\n/**\n * Список записей со своей панелью инструментов.\n *\n * Полосу панели семья раскладывает сама, а не зовёт `rt-toolbar`: у того стороны объявлены\n * нешринкующимися, и на хозяине уже́ содержимого полоса раздаётся шире него и уезжает за край.\n * Семья кладёт в полосу готовые части кита — поле, кнопки, флажок, — а строит её сама.\n *\n * Семья ничего не рисует сама: поиск — поле кита, действия — его кнопки со значком, пустое место —\n * его пустое состояние, страницы — его нумерация. Сами записи проецируются: таблица между панелью\n * и страницами — потребителя, с его колонками, ячейками и действиями строки.\n *\n * Договорённость — `docs/specs/ui-kit-v2/dynamic-list/`.\n */\n@Component({\n selector: 'rt-dynamic-list',\n templateUrl: './rt-dynamic-list.component.html',\n styleUrls: ['./rt-dynamic-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtButtonDirective,\n RtCheckboxComponent,\n RtEmptyStateComponent,\n RtIconButtonComponent,\n RtInputComponent,\n RtPaginationComponent,\n RtSpinnerComponent,\n BlockDirective,\n ElemDirective,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtDynamicListComponent implements OnInit {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n /**\n * Последнее, что знают и потребитель, и поле: отправленное потребителю или поставленное им самим.\n * Одно и то же дважды не спрашивается, а поставленное потребителем не возвращается ему эхом.\n */\n #lastSearch: string = '';\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly searchControl: FormControl<string> = new FormControl<string>('', { nonNullable: true });\n\n protected readonly perPageOptions: ReadonlyArray<number> = PER_PAGE_OPTIONS;\n\n protected readonly selectorsTpl: Signal<TNullable<RtDynamicListToolbarSelectorsDirective>> = contentChild(\n RtDynamicListToolbarSelectorsDirective\n );\n\n protected readonly actionsTpl: Signal<TNullable<RtDynamicListToolbarActionsDirective>> = contentChild(\n RtDynamicListToolbarActionsDirective\n );\n\n /** «Выбрано: N» — подпись с подстановкой, потому её берут не из карты, а вызовом. */\n protected readonly selectedLabel: Signal<string> = rtKitLabel(\n 'uiSelectedCount',\n computed((): TRtKitLabelParams => ({ count: this.selectedCount() }))\n );\n\n /** Отчего пусто. Отбор стоит — значит, записи убрал он, и человеку показывают дорогу назад. */\n protected readonly emptyReason: Signal<IRtDynamicList.EmptyReason> = computed((): IRtDynamicList.EmptyReason =>\n this.filtered() ? 'filter' : 'section'\n );\n\n /** Значок пустого места: под отбором — лупа, у пустого раздела — лоток. */\n protected readonly emptyIcon: Signal<IRtIcon.Name> = computed((): IRtIcon.Name =>\n this.emptyReason() === 'filter' ? 'search' : 'inbox'\n );\n\n /** Подпись пустого места. Своя подпись потребителя сильнее обеих подписей кита. */\n protected readonly emptyTitleText: Signal<string> = computed((): string => {\n if (this.emptyTitle()) {\n return this.emptyTitle();\n }\n\n return this.emptyReason() === 'filter' ? this.t().uiNothingFound : this.t().uiNoRows;\n });\n\n /**\n * Полоса страниц рисуется, пока записей больше наименьшего размера страницы — то же правило, что у\n * самой полосы. Число страниц при нынешнем размере тут не решает: выбравший крупный размер, при\n * котором всё легло на одну страницу, иначе терял вместе с полосой и дорогу к размеру поменьше.\n */\n protected readonly isPaginationShown: Signal<boolean> = computed((): boolean => {\n const page: TNullable<IPageModel> = this.pageModel();\n\n if (!page || this.empty()) {\n return false;\n }\n\n return page.totalCount > Math.min(...PER_PAGE_OPTIONS);\n });\n\n /**\n * Есть ли в панели хоть что-нибудь. Полоса без единой части — это отступ над записями, и\n * место она забирает у них.\n */\n protected readonly isToolbarShown: Signal<boolean> = computed((): boolean =>\n [\n this.showSearch(),\n this.showRefresh(),\n this.showClearFilters(),\n this.showColumnSettings(),\n this.selectable(),\n !!this.selectorsTpl(),\n !!this.actionsTpl(),\n ].some((part: boolean): boolean => part)\n );\n\n /** Записи проецируются, и о числе страниц семья узнаёт только из модели страницы. */\n public readonly pageModel: InputSignal<TNullable<IPageModel>> = input<TNullable<IPageModel>>(null);\n\n /** Первая загрузка: вместо всего содержимого стоит вертушка. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Подгрузка поверх нарисованного: записи остаются на месте, вертушка стоит над ними. */\n public readonly fetching: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Записей нет вовсе. От пустого ответа под отбором отличается входом `filtered`. */\n public readonly empty: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Отбор стоит. Вместе с `empty` даёт вторую причину пустоты — ту, у которой есть дорога назад. */\n public readonly filtered: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Кнопка сброса отбора: показана у раздела с отбором, выключена, пока сбрасывать нечего. */\n public readonly showClearFilters: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly showRefresh: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly showColumnSettings: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly showSearch: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /** Выбор записей: флажок «выбрать все» и счётчик выбранного на левой стороне панели. */\n public readonly selectable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly allSelected: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly someSelected: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly selectAllDisabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly selectedCount: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(0, {\n transform: numberAttribute,\n });\n\n public readonly emptyTitle: InputSignal<string> = input<string>('');\n\n public readonly emptyDescription: InputSignal<string | null> = input<string | null>(null);\n\n /** Поиск потребителя: поле следует за ним при каждой смене и потребителю его не возвращает. */\n public readonly searchTerm: InputSignal<TNullable<string>> = input<TNullable<string>>('');\n\n public readonly searchChange: OutputEmitterRef<string> = output<string>();\n\n public readonly refreshed: OutputEmitterRef<void> = output<void>();\n\n public readonly filtersCleared: OutputEmitterRef<void> = output<void>();\n\n public readonly columnSettingsOpened: OutputEmitterRef<void> = output<void>();\n\n public readonly pageChange: OutputEmitterRef<number> = output<number>();\n\n public readonly perPageChange: OutputEmitterRef<number> = output<number>();\n\n public readonly allSelectedChange: OutputEmitterRef<boolean> = output<boolean>();\n\n constructor() {\n // Поиск потребителя ставится в поле, только когда он отличается от последнего, что список\n // отправил или поставил сам. Эхо отправленного — даже запоздалое, когда человек уже дописал\n // дальше, — поле не трогает: иначе оно стирало бы набранное и сбивало каретку.\n effect((): void => {\n const term: string = this.searchTerm() ?? '';\n\n untracked((): void => {\n if (term.trim() === this.#lastSearch) {\n return;\n }\n\n this.#lastSearch = term.trim();\n this.searchControl.setValue(term, { emitEvent: false });\n });\n });\n }\n\n public ngOnInit(): void {\n // Дебаунс непустого ввода; очистка крестиком применяется сразу — так же, как в списке\n // переписок: оператор один на кит, и два разных ожидания разошлись бы молча.\n this.searchControl.valueChanges\n .pipe(\n map((value: string): string => value.trim()),\n searchDebounce(),\n // Набранное, которое потребитель или сброс отбора успели заменить, уже не в поле.\n filter((value: string): boolean => value === this.searchControl.value.trim()),\n filter((value: string): boolean => value !== this.#lastSearch),\n takeUntilDestroyed(this.#destroyRef)\n )\n .subscribe((value: string): void => {\n this.#lastSearch = value;\n this.searchChange.emit(value);\n });\n }\n\n protected onSelectAll(checked: boolean): void {\n this.allSelectedChange.emit(checked);\n }\n\n /**\n * Сброс отбора снимает и поиск: пустой ответ под поиском — тоже ответ под отбором, и дорога назад\n * без очистки поля вела бы к тому же пустому ответу. Поле очищается молча: `filtersCleared`\n * уже значит «и поиск снят», и отдельный пустой `searchChange` заставил бы потребителя\n * запрашивать список дважды.\n */\n protected onClearFilters(): void {\n this.#lastSearch = '';\n this.searchControl.setValue('', { emitEvent: false });\n this.filtersCleared.emit();\n }\n}\n","<ng-container rtBlock=\"rt-dynamic-list\">\n @if (loading()) {\n <div rtElem=\"loader\" qa-dataid=\"dynamic-list-loader\">\n <rt-spinner />\n </div>\n } @else {\n @if (fetching()) {\n <div rtElem=\"veil\" qa-dataid=\"dynamic-list-veil\">\n <rt-spinner />\n </div>\n }\n\n @if (isToolbarShown()) {\n <div rtElem=\"toolbar\" qa-dataid=\"dynamic-list-toolbar\">\n @if (selectable() || selectorsTpl()) {\n <div rtElem=\"selectors\" qa-dataid=\"dynamic-list-selectors\">\n @if (selectable()) {\n <rt-checkbox\n qa-dataid=\"dynamic-list-select-all\"\n [ariaLabel]=\"t().uiSelectAll\"\n [ngModel]=\"allSelected()\"\n [indeterminate]=\"!allSelected() && someSelected()\"\n [disabled]=\"selectAllDisabled()\"\n (ngModelChange)=\"onSelectAll($event)\" />\n\n @if (selectedCount()) {\n <span rtElem=\"counter\" qa-dataid=\"dynamic-list-selected-count\">\n {{ selectedLabel() }}\n </span>\n }\n }\n\n @if (selectorsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n </div>\n }\n\n <div rtElem=\"right\" qa-dataid=\"dynamic-list-right\">\n <div rtElem=\"actions\">\n @if (actionsTpl(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl.templateRef\" />\n }\n\n @if (showClearFilters()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-clear-filters\"\n icon=\"filter-slash\"\n size=\"sm\"\n [ariaLabel]=\"t().uiClearFilters\"\n [tooltip]=\"t().uiClearFilters\"\n [disabled]=\"!filtered()\"\n (clicked)=\"onClearFilters()\" />\n }\n\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-refresh\"\n icon=\"refresh\"\n size=\"sm\"\n [ariaLabel]=\"t().uiRefresh\"\n [tooltip]=\"t().uiRefresh\"\n (clicked)=\"refreshed.emit()\" />\n }\n\n @if (showColumnSettings()) {\n <rt-icon-button\n qa-dataid=\"dynamic-list-column-settings\"\n icon=\"sliders-v\"\n size=\"sm\"\n [ariaLabel]=\"t().uiColumnSettings\"\n [tooltip]=\"t().uiColumnSettings\"\n (clicked)=\"columnSettingsOpened.emit()\" />\n }\n </div>\n\n @if (showSearch()) {\n <div rtElem=\"search\">\n <rt-input\n qa-dataid=\"dynamic-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"t().uiSearch\"\n [formControl]=\"searchControl\" />\n </div>\n }\n </div>\n </div>\n }\n\n @if (empty()) {\n <rt-empty-state\n rtElem=\"empty\"\n qa-dataid=\"dynamic-list-empty\"\n [icon]=\"emptyIcon()\"\n [title]=\"emptyTitleText()\"\n [description]=\"emptyDescription()\">\n @if (emptyReason() === 'filter') {\n <button\n rtButton\n qa-dataid=\"dynamic-list-empty-clear\"\n type=\"button\"\n icon=\"filter-slash\"\n appearance=\"outlined\"\n size=\"sm\"\n [label]=\"t().uiClearFilters\"\n [attr.aria-label]=\"t().uiClearFilters\"\n (click)=\"onClearFilters()\"></button>\n }\n </rt-empty-state>\n } @else {\n <div rtElem=\"content\" qa-dataid=\"dynamic-list-content\">\n <ng-content />\n </div>\n\n @if (isPaginationShown()) {\n <rt-pagination\n rtElem=\"pagination\"\n qa-dataid=\"dynamic-list-pagination\"\n [pageModel]=\"pageModel()!\"\n [perPageOptions]=\"perPageOptions\"\n [loading]=\"fetching()\"\n (pageChange)=\"pageChange.emit($event)\"\n (perPageChange)=\"perPageChange.emit($event)\" />\n }\n }\n }\n</ng-container>\n"],"mappings":"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"}
|