import{i as e}from"./preload-helper-B45gAKPr.js";import{t}from"./iframe-CMLjY6eW.js";import{E as n,a as r,d as i,f as a,l as o,m as s,n as c,p as l,r as u,u as d}from"./blocks-D3IlvJMm.js";import{t as f}from"./mdx-react-shim-DzMf9EAg.js";import{Basic as p,CollapsedByDefault as m,Empty as h,Fetching as g,Loading as _,MultiSelect as v,WithDefaultExpandedBranch as y,WithDisabledRows as b,WithFormattedTreeColumn as x,WithFormulaColumn as S,WithHiddenZero as C,WithMergedDuplicates as w,WithODataMetadataAdapter as T,WithUseODataTableColumnsBuildHook as E,WithUseODataTableColumnsEnrichHook as D,n as O,t as k}from"./TreeTable.stories-GziVUTaf.js";function A(e){let t={code:`code`,h2:`h2`,h3:`h3`,li:`li`,p:`p`,pre:`pre`,ul:`ul`,...n(),...e.components};return(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(o,{of:k,parameters:{docs:{toc:!0}}}),`
`,(0,M.jsx)(l,{children:`TreeTable`}),`
`,(0,M.jsx)(a,{children:`Древовидная таблица для плоских OData-данных на базе TanStack Table`}),`
`,(0,M.jsxs)(t.p,{children:[(0,M.jsx)(t.code,{children:`TreeTable`}),` предназначен для сценариев, где данные приходят плоским списком, но в UI должны выглядеть как дерево.
Компонент использует тот же базовый табличный каркас, что и `,(0,M.jsx)(t.code,{children:`Table`}),`, поэтому у них совпадают базовые states, выбор строк и табличная структура, а различия сосредоточены в tree-логике.
`,(0,M.jsx)(t.code,{children:`TreeTable`}),` использует тот же formatting-runtime, что и `,(0,M.jsx)(t.code,{children:`Table`}),`, но вычисляет formatting до tree-shell, не смешивая его с логикой раскрытия дерева.`]}),`
`,(0,M.jsx)(t.h2,{id:`основной-сценарий`,children:`Основной сценарий`}),`
`,(0,M.jsx)(d,{}),`
`,(0,M.jsx)(r,{of:p}),`
`,(0,M.jsx)(t.pre,{children:(0,M.jsx)(t.code,{className:`language-tsx`,children:`import { TreeTable, type TableColumnDef } from "@/shared/ui";

interface MetricRow {
	id: string;
	parentId: string | null;
	label: string;
	jan: string;
	feb: string;
}

const columns: TableColumnDef<MetricRow>[] = [
	{
		id: "label",
		accessorKey: "label",
		header: "Показатель",
		meta: { width: "18em" }
	},
	{
		id: "jan",
		accessorKey: "jan",
		header: "янв",
		meta: { width: "8em", align: "right" }
	},
	{
		id: "feb",
		accessorKey: "feb",
		header: "фев",
		meta: { width: "8em", align: "right" }
	}
];

export function Example({ rows }: { rows: MetricRow[] }) {
	return (
		<TreeTable
			data={rows}
			columns={columns}
			hierarchy={{
				getRowId: (row) => row.id,
				getParentRowId: (row) => row.parentId
			}}
			selectionMode="single"
			expandFirstLevel
			height="22em"
			indentSize={1}
		/>
	);
}
`})}),`
`,(0,M.jsx)(t.h2,{id:`форматирование-ячеек`,children:`Форматирование ячеек`}),`
`,(0,M.jsxs)(t.p,{children:[(0,M.jsx)(t.code,{children:`TreeTable`}),` поддерживает тот же `,(0,M.jsx)(t.code,{children:`meta.formatting`}),`, что и `,(0,M.jsx)(t.code,{children:`Table`}),`:`]}),`
`,(0,M.jsxs)(t.ul,{children:[`
`,(0,M.jsxs)(t.li,{children:[`typed formatting по `,(0,M.jsx)(t.code,{children:`role/type`}),`;`]}),`
`,(0,M.jsx)(t.li,{children:`formula-based колонки;`}),`
`,(0,M.jsx)(t.li,{children:`pipeline display-formatting;`}),`
`,(0,M.jsxs)(t.li,{children:[(0,M.jsx)(t.code,{children:`emptyWhenZero`}),` для скрытия нулей;`]}),`
`,(0,M.jsxs)(t.li,{children:[`optional OData adapter для автоматического получения `,(0,M.jsx)(t.code,{children:`role/type`}),`.`]}),`
`]}),`
`,(0,M.jsx)(t.p,{children:`Семантика важна:`}),`
`,(0,M.jsxs)(t.ul,{children:[`
`,(0,M.jsx)(t.li,{children:`formatting вычисляется до tree-shell;`}),`
`,(0,M.jsxs)(t.li,{children:[`затем результат заворачивается в древовидную ячейку только для `,(0,M.jsx)(t.code,{children:`treeColumnId`}),`;`]}),`
`,(0,M.jsxs)(t.li,{children:[`кастомный `,(0,M.jsx)(t.code,{children:`cell`}),` по-прежнему важнее `,(0,M.jsx)(t.code,{children:`meta.formatting`}),`;`]}),`
`,(0,M.jsxs)(t.li,{children:[(0,M.jsx)(t.code,{children:`TreeTable`}),` сам не ходит в OData и остаётся пригодным для plain local data.`]}),`
`]}),`
`,(0,M.jsx)(t.pre,{children:(0,M.jsx)(t.code,{className:`language-tsx`,children:`const columns: TableColumnDef<Row>[] = [
	{
		id: "amount",
		accessorKey: "amount",
		header: "Сумма",
		meta: {
			align: "right",
			formatting: {
				role: "measure",
				type: "decimal",
				formattersPipeline: pipelineConfig
			}
		}
	}
];
`})}),`
`,(0,M.jsx)(t.p,{children:`Для OData build-сценария колонки можно сгенерировать из metadata:`}),`
`,(0,M.jsx)(t.pre,{children:(0,M.jsx)(t.code,{className:`language-tsx`,children:`import { createTableColumnsFromODataMetadata } from "@ryuzaki13/react-foundation-lib/table";

const columns = createTableColumnsFromODataMetadata(metadata.columns);
`})}),`
`,(0,M.jsxs)(t.p,{children:[`Тот же сценарий удобнее собрать через `,(0,M.jsx)(t.code,{children:`useODataTableColumns(...)`}),`, а не через ручной вызов helper:`]}),`
`,(0,M.jsx)(t.pre,{children:(0,M.jsx)(t.code,{className:`language-tsx`,children:`import { useODataTableColumns } from "@ryuzaki13/react-foundation-api/odata";
import { TreeTable } from "@/shared/ui";

function FinanceTree({ rows }: { rows: MetricRow[] }) {
	const { columns, metadata, isLoading } = useODataTableColumns<MetricRow>({
		service: "ZFI_REPORTING_SRV",
		entity: "FinanceSet",
		mode: "build"
	});

	return (
		<TreeTable
			title={metadata?.title ?? "Финансовая иерархия"}
			data={rows}
			columns={columns}
			hierarchy={{
				getRowId: (row) => row.id,
				getParentRowId: (row) => row.parentId
			}}
			isLoading={isLoading}
			expandFirstLevel
		/>
	);
}
`})}),`
`,(0,M.jsxs)(t.p,{children:[(0,M.jsx)(t.code,{children:`enrich`}),` для `,(0,M.jsx)(t.code,{children:`TreeTable`}),` работает так же, как и для `,(0,M.jsx)(t.code,{children:`Table`}),`: hook сохраняет ручные колонки дерева и дозаполняет их `,(0,M.jsx)(t.code,{children:`meta.formatting.role/type`}),`.`]}),`
`,(0,M.jsx)(t.h2,{id:`слияние-дубликатов`,children:`Слияние дубликатов`}),`
`,(0,M.jsxs)(t.p,{children:[(0,M.jsx)(t.code,{children:`TreeTable`}),` поддерживает тот же `,(0,M.jsx)(t.code,{children:`meta.mergeDuplicates`}),`, что и плоская таблица, но с дополнительным ограничением: объединение работает только внутри одной глубины `,(0,M.jsx)(t.code,{children:`row.depth`}),`.`]}),`
`,(0,M.jsx)(t.p,{children:`Важно:`}),`
`,(0,M.jsxs)(t.ul,{children:[`
`,(0,M.jsxs)(t.li,{children:[`tree-колонка с expander не участвует в слиянии, даже если на ней включён `,(0,M.jsx)(t.code,{children:`mergeDuplicates`}),`;`]}),`
`,(0,M.jsxs)(t.li,{children:[`сравнение идёт по raw-значению `,(0,M.jsx)(t.code,{children:`cell.getValue()`}),`;`]}),`
`,(0,M.jsx)(t.li,{children:`повторяющееся значение остаётся только в первой строке группы, а ниже рендерятся пустые ячейки;`}),`
`,(0,M.jsx)(t.li,{children:`если между двумя одинаковыми значениями есть строка другой глубины, объединение разрывается.`}),`
`]}),`
`,(0,M.jsx)(t.h2,{id:`что-важно-знать`,children:`Что важно знать`}),`
`,(0,M.jsxs)(t.ul,{children:[`
`,(0,M.jsxs)(t.li,{children:[`Компонент принимает плоский массив строк и сам восстанавливает иерархию по `,(0,M.jsx)(t.code,{children:`id`}),` и `,(0,M.jsx)(t.code,{children:`parentId`}),`.`]}),`
`,(0,M.jsx)(t.li,{children:`Если родитель не найден, строка не теряется и отображается как корневая.`}),`
`,(0,M.jsx)(t.li,{children:`Циклические связи не приводят к бесконечной рекурсии: проблемный фрагмент дерева отсекается.`}),`
`,(0,M.jsxs)(t.li,{children:[(0,M.jsx)(t.code,{children:`defaultExpandedRowIds`}),` дополняет `,(0,M.jsx)(t.code,{children:`expandFirstLevel`}),` только на первом появлении данных.`]}),`
`,(0,M.jsxs)(t.li,{children:[(0,M.jsx)(t.code,{children:`indentSize`}),` можно задавать числом или строкой; число трактуется как `,(0,M.jsx)(t.code,{children:`em`}),`.`]}),`
`,(0,M.jsxs)(t.li,{children:[`Поведение `,(0,M.jsx)(t.code,{children:`selectionMode`}),` совпадает с `,(0,M.jsx)(t.code,{children:`Table`}),`, а различие между компонентами сосредоточено в раскрытии веток и tree-cell.`]}),`
`,(0,M.jsx)(t.li,{children:`Tree-shell и formatting остаются разделёнными слоями: раскрытие веток не зависит от formulas/pipeline.`}),`
`]}),`
`,(0,M.jsx)(t.h2,{id:`сценарии`,children:`Сценарии`}),`
`,(0,M.jsx)(t.h3,{id:`базовый-режим`,children:`Базовый режим`}),`
`,(0,M.jsx)(u,{of:p}),`
`,(0,M.jsx)(t.h3,{id:`множественный-выбор`,children:`Множественный выбор`}),`
`,(0,M.jsx)(u,{of:v}),`
`,(0,M.jsx)(t.h3,{id:`дерево-свёрнуто-по-умолчанию`,children:`Дерево свёрнуто по умолчанию`}),`
`,(0,M.jsx)(u,{of:m}),`
`,(0,M.jsx)(t.h3,{id:`предраскрытая-ветка`,children:`Предраскрытая ветка`}),`
`,(0,M.jsx)(u,{of:y}),`
`,(0,M.jsx)(t.h3,{id:`строки-с-ограничением-выбора`,children:`Строки с ограничением выбора`}),`
`,(0,M.jsx)(u,{of:b}),`
`,(0,M.jsx)(t.h3,{id:`фоновое-обновление-данных`,children:`Фоновое обновление данных`}),`
`,(0,M.jsx)(u,{of:g}),`
`,(0,M.jsx)(t.h3,{id:`пустое-дерево`,children:`Пустое дерево`}),`
`,(0,M.jsx)(u,{of:h}),`
`,(0,M.jsx)(t.h3,{id:`первичная-загрузка`,children:`Первичная загрузка`}),`
`,(0,M.jsx)(u,{of:_}),`
`,(0,M.jsx)(t.h3,{id:`formula-based-колонка`,children:`Formula-based колонка`}),`
`,(0,M.jsx)(u,{of:S}),`
`,(0,M.jsx)(t.h3,{id:`форматирование-tree-колонки`,children:`Форматирование tree-колонки`}),`
`,(0,M.jsx)(u,{of:x}),`
`,(0,M.jsx)(t.h3,{id:`скрытие-нулевых-значений`,children:`Скрытие нулевых значений`}),`
`,(0,M.jsx)(u,{of:C}),`
`,(0,M.jsx)(t.h3,{id:`слияние-дубликатов-1`,children:`Слияние дубликатов`}),`
`,(0,M.jsx)(u,{of:w}),`
`,(0,M.jsx)(t.h3,{id:`odata-metadata-adapter`,children:`OData metadata adapter`}),`
`,(0,M.jsx)(u,{of:T}),`
`,(0,M.jsx)(t.h3,{id:`useodatatablecolumns-build`,children:`useODataTableColumns: build`}),`
`,(0,M.jsx)(u,{of:E}),`
`,(0,M.jsx)(t.h3,{id:`useodatatablecolumns-enrich`,children:`useODataTableColumns: enrich`}),`
`,(0,M.jsx)(u,{of:D}),`
`,(0,M.jsx)(t.h2,{id:`api`,children:`API`}),`
`,(0,M.jsx)(c,{of:k}),`
`,(0,M.jsx)(t.h2,{id:`все-stories`,children:`Все stories`}),`
`,(0,M.jsx)(i,{includePrimary:!1})]})}function j(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,M.jsx)(t,{...e,children:(0,M.jsx)(A,{...e})}):A(e)}var M;e((()=>{M=t(),f(),s(),O()}))();export{j as default};