import{i as e}from"./preload-helper-B45gAKPr.js";import{E as t,a as n,d as r,f as i,l as a,m as o,n as s,p as c,r as l,u}from"./blocks-DsN3hykK.js";import{t as d}from"./jsx-runtime-BBQGix-2.js";import{t as f}from"./mdx-react-shim-CdXPOrRW.js";import{Basic as p,Empty as m,Fetching as h,Loading as g,MultiSelect as _,ReachEnd as v,WithColumnPinning as y,WithDisabledRows as b,WithFormattingPipeline 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"./Table.stories-sckp-lho.js";function A(e){let o={code:`code`,h2:`h2`,h3:`h3`,li:`li`,p:`p`,pre:`pre`,ul:`ul`,...t(),...e.components};return(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(a,{of:k,parameters:{docs:{toc:!0}}}),`
`,(0,M.jsx)(c,{children:`Table`}),`
`,(0,M.jsxs)(i,{children:[`Плоская таблица как React-альтернатива `,(0,M.jsx)(o.code,{children:`sap.m.Table`})]}),`
`,(0,M.jsxs)(o.p,{children:[(0,M.jsx)(o.code,{children:`Table`}),` предназначен для плоских данных и по поведению осознанно сближен с `,(0,M.jsx)(o.code,{children:`TreeTable`}),`.
Оба компонента используют общий табличный каркас, поэтому здесь совпадают states загрузки, визуальная структура, обработка выбора строк и клавиатурная активация.
`,(0,M.jsx)(o.code,{children:`Table`}),` также поддерживает декларативное форматирование через `,(0,M.jsx)(o.code,{children:`meta.formatting`}),`, formulas, безопасное pipeline-formatting и optional OData adapter.`]}),`
`,(0,M.jsx)(o.h2,{id:`основной-сценарий`,children:`Основной сценарий`}),`
`,(0,M.jsx)(u,{}),`
`,(0,M.jsx)(n,{of:p}),`
`,(0,M.jsx)(o.pre,{children:(0,M.jsx)(o.code,{className:`language-tsx`,children:`import { Table, type TableColumnDef } from "@/shared/ui";

interface DealRow {
	id: string;
	number: string;
	client: string;
	amount: string;
}

const columns: TableColumnDef<DealRow>[] = [
	{
		id: "number",
		accessorKey: "number",
		header: "Номер",
		meta: { width: "9em" }
	},
	{
		id: "client",
		accessorKey: "client",
		header: "Клиент",
		meta: { width: "14em" }
	},
	{
		id: "amount",
		accessorKey: "amount",
		header: "Сумма",
		meta: { width: "10em", align: "right" }
	}
];

export function Example({ rows }: { rows: DealRow[] }) {
	return <Table data={rows} columns={columns} getRowId={(row) => row.id} selectionMode="single" height="20em" />;
}
`})}),`
`,(0,M.jsx)(o.h2,{id:`форматирование-ячеек`,children:`Форматирование ячеек`}),`
`,(0,M.jsxs)(o.p,{children:[(0,M.jsx)(o.code,{children:`meta.formatting`}),` добавляет к колонке декларативный runtime-контракт:`]}),`
`,(0,M.jsxs)(o.ul,{children:[`
`,(0,M.jsxs)(o.li,{children:[`typed formatting по `,(0,M.jsx)(o.code,{children:`role/type`}),`;`]}),`
`,(0,M.jsx)(o.li,{children:`formula-based вычисление значения;`}),`
`,(0,M.jsxs)(o.li,{children:[`pipeline display-formatting (`,(0,M.jsx)(o.code,{children:`normalizeLeadingZeros`}),`, `,(0,M.jsx)(o.code,{children:`resolveValueState`}),`, `,(0,M.jsx)(o.code,{children:`typedValueFormat`}),`);`]}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`emptyWhenZero`}),` для скрытия нулевых значений;`]}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`overflowTooltip`}),` для длинного текста.`]}),`
`]}),`
`,(0,M.jsx)(o.p,{children:`Важно:`}),`
`,(0,M.jsxs)(o.ul,{children:[`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`meta.formatting`}),` применяется только если у колонки нет кастомного `,(0,M.jsx)(o.code,{children:`cell`}),`;`]}),`
`,(0,M.jsx)(o.li,{children:`formulas и pipeline компилируются один раз на снимок колонок;`}),`
`,(0,M.jsxs)(o.li,{children:[`ошибки formula/pipeline не роняют таблицу и не подставляют универсальный `,(0,M.jsx)(o.code,{children:`0`}),`;`]}),`
`,(0,M.jsxs)(o.li,{children:[`OData adapter остаётся внешней прослойкой, а не частью `,(0,M.jsx)(o.code,{children:`Table`}),`.`]}),`
`]}),`
`,(0,M.jsx)(o.pre,{children:(0,M.jsx)(o.code,{className:`language-tsx`,children:`const columns: TableColumnDef<Row>[] = [
	{
		id: "amount",
		accessorKey: "amount",
		header: "Сумма",
		meta: {
			align: "right",
			formatting: {
				role: "measure",
				type: "decimal",
				emptyWhenZero: true
			}
		}
	}
];
`})}),`
`,(0,M.jsxs)(o.p,{children:[`Для OData-сценариев можно не прописывать `,(0,M.jsx)(o.code,{children:`role/type`}),` вручную, а обогатить колонки через adapter:`]}),`
`,(0,M.jsx)(o.pre,{children:(0,M.jsx)(o.code,{className:`language-tsx`,children:`import { enrichTableColumnsWithODataFormatting } from "@ryuzaki13/react-foundation-lib/table";

const columns = enrichTableColumnsWithODataFormatting(manualColumns, metadata.columns);
`})}),`
`,(0,M.jsx)(o.h2,{id:`слияние-дубликатов`,children:`Слияние дубликатов`}),`
`,(0,M.jsxs)(o.p,{children:[(0,M.jsx)(o.code,{children:`meta.mergeDuplicates`}),` включает display-only слияние подряд идущих одинаковых raw-значений без изменения структуры строк.`]}),`
`,(0,M.jsx)(o.p,{children:`Важно:`}),`
`,(0,M.jsxs)(o.ul,{children:[`
`,(0,M.jsxs)(o.li,{children:[`сравнение идёт по `,(0,M.jsx)(o.code,{children:`cell.getValue()`}),`, а не по formatted display;`]}),`
`,(0,M.jsx)(o.li,{children:`объединяются только подряд идущие строки;`}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`null`}),`, `,(0,M.jsx)(o.code,{children:`undefined`}),` и пустая строка `,(0,M.jsx)(o.code,{children:`""`}),` не объединяются;`]}),`
`,(0,M.jsx)(o.li,{children:`повторяющееся значение остаётся только в первой строке группы, а ниже рендерятся пустые ячейки;`}),`
`,(0,M.jsx)(o.li,{children:`если сервер не отсортировал данные так, чтобы дубликаты шли подряд, слияния не будет.`}),`
`]}),`
`,(0,M.jsx)(o.pre,{children:(0,M.jsx)(o.code,{className:`language-tsx`,children:`const columns: TableColumnDef<Row>[] = [
	{
		id: "division",
		accessorKey: "division",
		header: "Дивизион",
		meta: {
			mergeDuplicates: true
		}
	}
];
`})}),`
`,(0,M.jsxs)(o.h2,{id:`хук-useodatatablecolumns`,children:[`Хук `,(0,M.jsx)(o.code,{children:`useODataTableColumns`})]}),`
`,(0,M.jsxs)(o.p,{children:[`Наиболее частый кейс - работать не с pure-helper напрямую, а с hook-слоем `,(0,M.jsx)(o.code,{children:`useODataTableColumns(...)`}),`.`]}),`
`,(0,M.jsxs)(o.p,{children:[(0,M.jsx)(o.code,{children:`build`}),` стоит выбирать, когда колонки можно полностью собрать из `,(0,M.jsx)(o.code,{children:`metadata.columns`}),`:`]}),`
`,(0,M.jsx)(o.pre,{children:(0,M.jsx)(o.code,{className:`language-tsx`,children:`import { useODataTableColumns } from "@ryuzaki13/react-foundation-api/odata";
import { Table } from "@/shared/ui";

function DealsTable({ rows }: { rows: DealRow[] }) {
	const { columns, metadata, isLoading } = useODataTableColumns<DealRow>({
		service: "ZSD_SALES_SRV",
		entity: "DealSet",
		mode: "build"
	});

	return (
		<Table
			title={metadata?.title ?? "Сделки"}
			data={rows}
			columns={columns}
			isLoading={isLoading}
			getRowId={(row) => row.id}
			selectionMode="single"
		/>
	);
}
`})}),`
`,(0,M.jsxs)(o.p,{children:[(0,M.jsx)(o.code,{children:`enrich`}),` подходит, когда колонки уже описаны вручную и нужно только дозаполнить `,(0,M.jsx)(o.code,{children:`meta.formatting.role/type`}),`:`]}),`
`,(0,M.jsx)(o.pre,{children:(0,M.jsx)(o.code,{className:`language-tsx`,children:`import { useODataTableColumns } from "@ryuzaki13/react-foundation-api/odata";
import { Table } from "@/shared/ui";

const manualColumns: TableColumnDef<DealRow>[] = [
	{ id: "product", accessorKey: "product", header: "Позиция" },
	{ id: "createdAt", accessorKey: "createdAt", header: "Создано" },
	{ id: "totalAmount", accessorKey: "totalAmount", header: "Итог", meta: { align: "right" } }
];

function DealsTable({ rows }: { rows: DealRow[] }) {
	const { columns, isLoading } = useODataTableColumns<DealRow>({
		service: "ZSD_SALES_SRV",
		entity: "DealSet",
		mode: "enrich",
		columns: manualColumns
	});

	return <Table data={rows} columns={columns} isLoading={isLoading} getRowId={(row) => row.id} selectionMode="single" />;
}
`})}),`
`,(0,M.jsx)(o.p,{children:`Практическая семантика хука:`}),`
`,(0,M.jsxs)(o.ul,{children:[`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`columns`}),` уже готовы для прямой передачи в `,(0,M.jsx)(o.code,{children:`Table`}),`;`]}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`metadata`}),` можно использовать для заголовка, пустых состояний или дополнительной UI-подписи;`]}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`isLoading`}),` нужно прокидывать в `,(0,M.jsx)(o.code,{children:`Table`}),`, чтобы сохранить единое табличное состояние загрузки;`]}),`
`,(0,M.jsxs)(o.li,{children:[`сам `,(0,M.jsx)(o.code,{children:`Table`}),` остаётся OData-независимым и получает только готовые `,(0,M.jsx)(o.code,{children:`columns`}),`.`]}),`
`]}),`
`,(0,M.jsx)(o.h2,{id:`что-важно-знать`,children:`Что важно знать`}),`
`,(0,M.jsxs)(o.ul,{children:[`
`,(0,M.jsx)(o.li,{children:`Компонент принимает именно плоский массив строк и не содержит древовидной логики.`}),`
`,(0,M.jsxs)(o.li,{children:[`Поведение `,(0,M.jsx)(o.code,{children:`selectionMode`}),` идентично `,(0,M.jsx)(o.code,{children:`TreeTable`}),`: `,(0,M.jsx)(o.code,{children:`single`}),` не снимает выбор повторным кликом по уже выбранной строке.`]}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`height`}),` и ширины колонок можно задавать строками в `,(0,M.jsx)(o.code,{children:`em`}),`, `,(0,M.jsx)(o.code,{children:`rem`}),`, `,(0,M.jsx)(o.code,{children:`%`}),` и других CSS-единицах; числовые значения трактуются как `,(0,M.jsx)(o.code,{children:`em`}),`.`]}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`onReachEnd`}),` срабатывает внутри scroll-контейнера и подходит для постепенной догрузки длинного списка.`]}),`
`,(0,M.jsxs)(o.li,{children:[(0,M.jsx)(o.code,{children:`Table`}),` не зависит от OData напрямую и продолжает работать на plain local data без metadata.`]}),`
`]}),`
`,(0,M.jsx)(o.h2,{id:`сценарии`,children:`Сценарии`}),`
`,(0,M.jsx)(o.h3,{id:`базовый-режим`,children:`Базовый режим`}),`
`,(0,M.jsx)(l,{of:p}),`
`,(0,M.jsx)(o.h3,{id:`left-pinning-столбцов`,children:`Left-pinning столбцов`}),`
`,(0,M.jsx)(l,{of:y}),`
`,(0,M.jsx)(o.h3,{id:`множественный-выбор`,children:`Множественный выбор`}),`
`,(0,M.jsx)(l,{of:_}),`
`,(0,M.jsx)(o.h3,{id:`строки-с-ограничением-выбора`,children:`Строки с ограничением выбора`}),`
`,(0,M.jsx)(l,{of:b}),`
`,(0,M.jsx)(o.h3,{id:`фоновое-обновление-данных`,children:`Фоновое обновление данных`}),`
`,(0,M.jsx)(l,{of:h}),`
`,(0,M.jsx)(o.h3,{id:`пустая-таблица`,children:`Пустая таблица`}),`
`,(0,M.jsx)(l,{of:m}),`
`,(0,M.jsx)(o.h3,{id:`достижение-конца-списка`,children:`Достижение конца списка`}),`
`,(0,M.jsx)(l,{of:v}),`
`,(0,M.jsx)(o.h3,{id:`первичная-загрузка`,children:`Первичная загрузка`}),`
`,(0,M.jsx)(l,{of:g}),`
`,(0,M.jsx)(o.h3,{id:`formula-based-колонка`,children:`Formula-based колонка`}),`
`,(0,M.jsx)(l,{of:S}),`
`,(0,M.jsx)(o.h3,{id:`pipeline-display-formatting`,children:`Pipeline display-formatting`}),`
`,(0,M.jsx)(l,{of:x}),`
`,(0,M.jsx)(o.h3,{id:`скрытие-нулевых-значений`,children:`Скрытие нулевых значений`}),`
`,(0,M.jsx)(l,{of:C}),`
`,(0,M.jsx)(o.h3,{id:`слияние-дубликатов-1`,children:`Слияние дубликатов`}),`
`,(0,M.jsx)(l,{of:w}),`
`,(0,M.jsx)(o.h3,{id:`odata-metadata-adapter`,children:`OData metadata adapter`}),`
`,(0,M.jsx)(l,{of:T}),`
`,(0,M.jsx)(o.h3,{id:`useodatatablecolumns-build`,children:`useODataTableColumns: build`}),`
`,(0,M.jsx)(l,{of:E}),`
`,(0,M.jsx)(o.h3,{id:`useodatatablecolumns-enrich`,children:`useODataTableColumns: enrich`}),`
`,(0,M.jsx)(l,{of:D}),`
`,(0,M.jsx)(o.h2,{id:`api`,children:`API`}),`
`,(0,M.jsx)(s,{of:k}),`
`,(0,M.jsx)(o.h2,{id:`все-stories`,children:`Все stories`}),`
`,(0,M.jsx)(r,{includePrimary:!1})]})}function j(e={}){let{wrapper:n}={...t(),...e.components};return n?(0,M.jsx)(n,{...e,children:(0,M.jsx)(A,{...e})}):A(e)}var M;e((()=>{M=d(),f(),o(),O()}))();export{j as default};