kokotable 0.95.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/LICENSE +21 -0
- package/README.md +320 -0
- package/contract/table-request.schema.json +424 -0
- package/dist/core/src/adapters/sources.d.ts +59 -0
- package/dist/core/src/adapters/sources.js +235 -0
- package/dist/core/src/client/aggregate.d.ts +94 -0
- package/dist/core/src/client/aggregate.js +222 -0
- package/dist/core/src/client/groupRows.d.ts +40 -0
- package/dist/core/src/client/groupRows.js +145 -0
- package/dist/core/src/client/runClientQuery.d.ts +67 -0
- package/dist/core/src/client/runClientQuery.js +157 -0
- package/dist/core/src/columns/ColumnBuilder.d.ts +121 -0
- package/dist/core/src/columns/ColumnBuilder.js +273 -0
- package/dist/core/src/columns/cascade.d.ts +24 -0
- package/dist/core/src/columns/cascade.js +93 -0
- package/dist/core/src/columns/deriveOperators.d.ts +38 -0
- package/dist/core/src/columns/deriveOperators.js +94 -0
- package/dist/core/src/columns/expandSorting.d.ts +19 -0
- package/dist/core/src/columns/expandSorting.js +52 -0
- package/dist/core/src/columns/helper.d.ts +196 -0
- package/dist/core/src/columns/helper.js +250 -0
- package/dist/core/src/columns/labels.d.ts +12 -0
- package/dist/core/src/columns/labels.js +21 -0
- package/dist/core/src/contract.d.ts +12 -0
- package/dist/core/src/contract.js +12 -0
- package/dist/core/src/contracts/aiColumnMeta.d.ts +102 -0
- package/dist/core/src/contracts/aiColumnMeta.js +197 -0
- package/dist/core/src/contracts/describeColumns.d.ts +48 -0
- package/dist/core/src/contracts/describeColumns.js +40 -0
- package/dist/core/src/contracts/exportData.d.ts +150 -0
- package/dist/core/src/contracts/exportData.js +228 -0
- package/dist/core/src/contracts/index.d.ts +6 -0
- package/dist/core/src/contracts/index.js +12 -0
- package/dist/core/src/contracts/legacyUrl.d.ts +47 -0
- package/dist/core/src/contracts/legacyUrl.js +156 -0
- package/dist/core/src/contracts/preset.d.ts +104 -0
- package/dist/core/src/contracts/preset.js +141 -0
- package/dist/core/src/contracts/presetStore.d.ts +81 -0
- package/dist/core/src/contracts/presetStore.js +146 -0
- package/dist/core/src/contracts/usePresets.d.ts +51 -0
- package/dist/core/src/contracts/usePresets.js +170 -0
- package/dist/core/src/defaults.d.ts +7 -0
- package/dist/core/src/defaults.js +9 -0
- package/dist/core/src/filters/codec.d.ts +20 -0
- package/dist/core/src/filters/codec.js +61 -0
- package/dist/core/src/filters/date.d.ts +30 -0
- package/dist/core/src/filters/date.js +179 -0
- package/dist/core/src/filters/describe.d.ts +45 -0
- package/dist/core/src/filters/describe.js +189 -0
- package/dist/core/src/filters/kind.d.ts +52 -0
- package/dist/core/src/filters/kind.js +110 -0
- package/dist/core/src/filters/kinds/_list.d.ts +13 -0
- package/dist/core/src/filters/kinds/_list.js +42 -0
- package/dist/core/src/filters/kinds/boolean.d.ts +3 -0
- package/dist/core/src/filters/kinds/boolean.js +21 -0
- package/dist/core/src/filters/kinds/cascade.d.ts +6 -0
- package/dist/core/src/filters/kinds/cascade.js +16 -0
- package/dist/core/src/filters/kinds/commonCode.d.ts +3 -0
- package/dist/core/src/filters/kinds/commonCode.js +13 -0
- package/dist/core/src/filters/kinds/date.d.ts +9 -0
- package/dist/core/src/filters/kinds/date.js +32 -0
- package/dist/core/src/filters/kinds/enum.d.ts +4 -0
- package/dist/core/src/filters/kinds/enum.js +13 -0
- package/dist/core/src/filters/kinds/index.d.ts +49 -0
- package/dist/core/src/filters/kinds/index.js +39 -0
- package/dist/core/src/filters/kinds/linear.d.ts +5 -0
- package/dist/core/src/filters/kinds/linear.js +16 -0
- package/dist/core/src/filters/kinds/number.d.ts +5 -0
- package/dist/core/src/filters/kinds/number.js +19 -0
- package/dist/core/src/filters/kinds/period.d.ts +4 -0
- package/dist/core/src/filters/kinds/period.js +17 -0
- package/dist/core/src/filters/kinds/relation.d.ts +5 -0
- package/dist/core/src/filters/kinds/relation.js +17 -0
- package/dist/core/src/filters/kinds/schedule.d.ts +5 -0
- package/dist/core/src/filters/kinds/schedule.js +16 -0
- package/dist/core/src/filters/kinds/text.d.ts +4 -0
- package/dist/core/src/filters/kinds/text.js +18 -0
- package/dist/core/src/filters/linear.d.ts +33 -0
- package/dist/core/src/filters/linear.js +65 -0
- package/dist/core/src/filters/list.d.ts +32 -0
- package/dist/core/src/filters/list.js +87 -0
- package/dist/core/src/filters/number.d.ts +17 -0
- package/dist/core/src/filters/number.js +82 -0
- package/dist/core/src/filters/registry.d.ts +23 -0
- package/dist/core/src/filters/registry.js +121 -0
- package/dist/core/src/filters/relation.d.ts +26 -0
- package/dist/core/src/filters/relation.js +75 -0
- package/dist/core/src/filters/schedule.d.ts +21 -0
- package/dist/core/src/filters/schedule.js +60 -0
- package/dist/core/src/filters/text.d.ts +44 -0
- package/dist/core/src/filters/text.js +127 -0
- package/dist/core/src/hooks/index.d.ts +6 -0
- package/dist/core/src/hooks/index.js +6 -0
- package/dist/core/src/hooks/useDataTable.d.ts +13 -0
- package/dist/core/src/hooks/useDataTable.js +109 -0
- package/dist/core/src/hooks/useGrouping.d.ts +33 -0
- package/dist/core/src/hooks/useGrouping.js +57 -0
- package/dist/core/src/hooks/useSearchHistory.d.ts +20 -0
- package/dist/core/src/hooks/useSearchHistory.js +52 -0
- package/dist/core/src/hooks/useTableData.d.ts +25 -0
- package/dist/core/src/hooks/useTableData.js +49 -0
- package/dist/core/src/hooks/useTableFromDefinition.d.ts +47 -0
- package/dist/core/src/hooks/useTableFromDefinition.js +174 -0
- package/dist/core/src/hooks/useTableSearch.d.ts +10 -0
- package/dist/core/src/hooks/useTableSearch.js +434 -0
- package/dist/core/src/hooks/useUrlSync.d.ts +64 -0
- package/dist/core/src/hooks/useUrlSync.js +145 -0
- package/dist/core/src/index.d.ts +38 -0
- package/dist/core/src/index.js +43 -0
- package/dist/core/src/pivot/runClientPivot.d.ts +101 -0
- package/dist/core/src/pivot/runClientPivot.js +230 -0
- package/dist/core/src/pivot/transforms.d.ts +19 -0
- package/dist/core/src/pivot/transforms.js +105 -0
- package/dist/core/src/registry.d.ts +46 -0
- package/dist/core/src/registry.js +67 -0
- package/dist/core/src/types/column.d.ts +213 -0
- package/dist/core/src/types/column.js +1 -0
- package/dist/core/src/types/data.d.ts +63 -0
- package/dist/core/src/types/data.js +1 -0
- package/dist/core/src/types/definition.d.ts +239 -0
- package/dist/core/src/types/definition.js +59 -0
- package/dist/core/src/types/filter.d.ts +94 -0
- package/dist/core/src/types/filter.js +1 -0
- package/dist/core/src/types/filterKind.d.ts +204 -0
- package/dist/core/src/types/filterKind.js +1 -0
- package/dist/core/src/types/grouping.d.ts +80 -0
- package/dist/core/src/types/grouping.js +4 -0
- package/dist/core/src/types/index.d.ts +8 -0
- package/dist/core/src/types/index.js +8 -0
- package/dist/core/src/types/operators.d.ts +64 -0
- package/dist/core/src/types/operators.js +108 -0
- package/dist/core/src/types/request.d.ts +114 -0
- package/dist/core/src/types/request.js +1 -0
- package/dist/core/src/types/search.d.ts +112 -0
- package/dist/core/src/types/search.js +1 -0
- package/dist/core/src/types/sources.d.ts +84 -0
- package/dist/core/src/types/sources.js +1 -0
- package/dist/core/src/types/table.d.ts +40 -0
- package/dist/core/src/types/table.js +1 -0
- package/dist/core/src/utils/compare.d.ts +13 -0
- package/dist/core/src/utils/compare.js +53 -0
- package/dist/core/src/utils/dateText.d.ts +12 -0
- package/dist/core/src/utils/dateText.js +30 -0
- package/dist/core/src/utils/getValue.d.ts +9 -0
- package/dist/core/src/utils/getValue.js +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/mui/src/TableLayout.d.ts +75 -0
- package/dist/mui/src/TableLayout.js +162 -0
- package/dist/mui/src/TableScreen.d.ts +70 -0
- package/dist/mui/src/TableScreen.js +174 -0
- package/dist/mui/src/addons/FilterModal.d.ts +45 -0
- package/dist/mui/src/addons/FilterModal.js +39 -0
- package/dist/mui/src/addons/FilterStatusModal.d.ts +40 -0
- package/dist/mui/src/addons/FilterStatusModal.js +68 -0
- package/dist/mui/src/addons/PresetBar.d.ts +56 -0
- package/dist/mui/src/addons/PresetBar.js +145 -0
- package/dist/mui/src/addons/ShareDropdown.d.ts +35 -0
- package/dist/mui/src/addons/ShareDropdown.js +41 -0
- package/dist/mui/src/addons/searchStore.d.ts +44 -0
- package/dist/mui/src/addons/searchStore.js +112 -0
- package/dist/mui/src/addons/searchSummary.d.ts +106 -0
- package/dist/mui/src/addons/searchSummary.js +109 -0
- package/dist/mui/src/columns/displayColumns.d.ts +100 -0
- package/dist/mui/src/columns/displayColumns.js +174 -0
- package/dist/mui/src/content/CardContent.d.ts +24 -0
- package/dist/mui/src/content/CardContent.js +25 -0
- package/dist/mui/src/content/ColumnMenu.d.ts +43 -0
- package/dist/mui/src/content/ColumnMenu.js +40 -0
- package/dist/mui/src/content/ColumnVisibilityMenu.d.ts +14 -0
- package/dist/mui/src/content/ColumnVisibilityMenu.js +37 -0
- package/dist/mui/src/content/EditCell.d.ts +19 -0
- package/dist/mui/src/content/EditCell.js +61 -0
- package/dist/mui/src/content/HeaderCell.d.ts +59 -0
- package/dist/mui/src/content/HeaderCell.js +88 -0
- package/dist/mui/src/content/SelectionActionBar.d.ts +17 -0
- package/dist/mui/src/content/SelectionActionBar.js +19 -0
- package/dist/mui/src/content/SortControl.d.ts +17 -0
- package/dist/mui/src/content/SortControl.js +45 -0
- package/dist/mui/src/content/TableContent.d.ts +191 -0
- package/dist/mui/src/content/TableContent.js +525 -0
- package/dist/mui/src/content/TableErrorFallback.d.ts +24 -0
- package/dist/mui/src/content/TableErrorFallback.js +29 -0
- package/dist/mui/src/content/cellError.d.ts +13 -0
- package/dist/mui/src/content/cellError.js +20 -0
- package/dist/mui/src/content/cellRenderers.d.ts +71 -0
- package/dist/mui/src/content/cellRenderers.js +127 -0
- package/dist/mui/src/content/cellValue.d.ts +27 -0
- package/dist/mui/src/content/cellValue.js +82 -0
- package/dist/mui/src/content/columnOrder.d.ts +7 -0
- package/dist/mui/src/content/columnOrder.js +48 -0
- package/dist/mui/src/content/density.d.ts +13 -0
- package/dist/mui/src/content/density.js +12 -0
- package/dist/mui/src/content/menuItems.d.ts +118 -0
- package/dist/mui/src/content/menuItems.js +128 -0
- package/dist/mui/src/content/pinning.d.ts +17 -0
- package/dist/mui/src/content/pinning.js +65 -0
- package/dist/mui/src/exporters/index.d.ts +1 -0
- package/dist/mui/src/exporters/index.js +1 -0
- package/dist/mui/src/exporters/useExportFormatters.d.ts +13 -0
- package/dist/mui/src/exporters/useExportFormatters.js +17 -0
- package/dist/mui/src/filter/FilterArea.d.ts +40 -0
- package/dist/mui/src/filter/FilterArea.js +37 -0
- package/dist/mui/src/filter/FilterInput.d.ts +14 -0
- package/dist/mui/src/filter/FilterInput.js +18 -0
- package/dist/mui/src/filter/inputs/DateFilterInput.d.ts +14 -0
- package/dist/mui/src/filter/inputs/DateFilterInput.js +112 -0
- package/dist/mui/src/filter/inputs/LinearFilterInput.d.ts +10 -0
- package/dist/mui/src/filter/inputs/LinearFilterInput.js +35 -0
- package/dist/mui/src/filter/inputs/NumberFilterInput.d.ts +12 -0
- package/dist/mui/src/filter/inputs/NumberFilterInput.js +111 -0
- package/dist/mui/src/filter/inputs/OperatorMenu.d.ts +14 -0
- package/dist/mui/src/filter/inputs/OperatorMenu.js +25 -0
- package/dist/mui/src/filter/inputs/RelationFilterInput.d.ts +11 -0
- package/dist/mui/src/filter/inputs/RelationFilterInput.js +67 -0
- package/dist/mui/src/filter/inputs/ScheduleFilterInput.d.ts +8 -0
- package/dist/mui/src/filter/inputs/ScheduleFilterInput.js +17 -0
- package/dist/mui/src/filter/inputs/SelectFilterInput.d.ts +16 -0
- package/dist/mui/src/filter/inputs/SelectFilterInput.js +57 -0
- package/dist/mui/src/filter/inputs/TextFilterInput.d.ts +13 -0
- package/dist/mui/src/filter/inputs/TextFilterInput.js +55 -0
- package/dist/mui/src/filter/kinds.d.ts +58 -0
- package/dist/mui/src/filter/kinds.js +103 -0
- package/dist/mui/src/grouping/AggregateChip.d.ts +55 -0
- package/dist/mui/src/grouping/AggregateChip.js +128 -0
- package/dist/mui/src/grouping/AggregationChips.d.ts +49 -0
- package/dist/mui/src/grouping/AggregationChips.js +80 -0
- package/dist/mui/src/grouping/AggregationSettingsButton.d.ts +14 -0
- package/dist/mui/src/grouping/AggregationSettingsButton.js +19 -0
- package/dist/mui/src/grouping/GroupingBar.d.ts +59 -0
- package/dist/mui/src/grouping/GroupingBar.js +267 -0
- package/dist/mui/src/grouping/StepExpandButton.d.ts +12 -0
- package/dist/mui/src/grouping/StepExpandButton.js +18 -0
- package/dist/mui/src/grouping/groupRow.d.ts +68 -0
- package/dist/mui/src/grouping/groupRow.js +129 -0
- package/dist/mui/src/headers/defaultHeader.d.ts +28 -0
- package/dist/mui/src/headers/defaultHeader.js +90 -0
- package/dist/mui/src/headers/defineHeader.d.ts +21 -0
- package/dist/mui/src/headers/defineHeader.js +68 -0
- package/dist/mui/src/headers/index.d.ts +5 -0
- package/dist/mui/src/headers/index.js +3 -0
- package/dist/mui/src/headers/meta.d.ts +18 -0
- package/dist/mui/src/headers/meta.js +11 -0
- package/dist/mui/src/headers/types.d.ts +84 -0
- package/dist/mui/src/headers/types.js +1 -0
- package/dist/mui/src/index.d.ts +110 -0
- package/dist/mui/src/index.js +79 -0
- package/dist/mui/src/layout/ResizeHandle.d.ts +30 -0
- package/dist/mui/src/layout/ResizeHandle.js +66 -0
- package/dist/mui/src/menus/columnMenu.d.ts +45 -0
- package/dist/mui/src/menus/columnMenu.js +144 -0
- package/dist/mui/src/menus/copy.d.ts +5 -0
- package/dist/mui/src/menus/copy.js +25 -0
- package/dist/mui/src/menus/index.d.ts +6 -0
- package/dist/mui/src/menus/index.js +4 -0
- package/dist/mui/src/menus/resolve.d.ts +15 -0
- package/dist/mui/src/menus/resolve.js +60 -0
- package/dist/mui/src/menus/rowMenu.d.ts +46 -0
- package/dist/mui/src/menus/rowMenu.js +76 -0
- package/dist/mui/src/pagination/PaginationArea.d.ts +16 -0
- package/dist/mui/src/pagination/PaginationArea.js +23 -0
- package/dist/mui/src/pivot/PivotTable.d.ts +18 -0
- package/dist/mui/src/pivot/PivotTable.js +100 -0
- package/dist/mui/src/provider/KokoTableProvider.d.ts +184 -0
- package/dist/mui/src/provider/KokoTableProvider.js +118 -0
- package/dist/mui/src/provider/labels.d.ts +85 -0
- package/dist/mui/src/provider/labels.js +104 -0
- package/dist/mui/src/registry.d.ts +30 -0
- package/dist/mui/src/registry.js +5 -0
- package/dist/mui/src/toolbar/GlobalFilterField.d.ts +36 -0
- package/dist/mui/src/toolbar/GlobalFilterField.js +78 -0
- package/dist/mui/src/virtual/VirtualTableContent.d.ts +41 -0
- package/dist/mui/src/virtual/VirtualTableContent.js +58 -0
- package/dist/mui/src/virtual/VirtualTableScreen.d.ts +13 -0
- package/dist/mui/src/virtual/VirtualTableScreen.js +23 -0
- package/dist/mui/src/virtual.d.ts +4 -0
- package/dist/mui/src/virtual.js +4 -0
- package/dist/mui/src/virtualColumns/VirtualColumnCard.d.ts +26 -0
- package/dist/mui/src/virtualColumns/VirtualColumnCard.js +29 -0
- package/dist/mui/src/virtualColumns/VirtualColumnDialog.d.ts +27 -0
- package/dist/mui/src/virtualColumns/VirtualColumnDialog.js +154 -0
- package/dist/mui/src/virtualColumns/VirtualColumnSection.d.ts +31 -0
- package/dist/mui/src/virtualColumns/VirtualColumnSection.js +55 -0
- package/dist/mui/src/virtualColumns/expression.d.ts +68 -0
- package/dist/mui/src/virtualColumns/expression.js +489 -0
- package/dist/mui/src/virtualColumns/useVirtualColumns.d.ts +67 -0
- package/dist/mui/src/virtualColumns/useVirtualColumns.js +111 -0
- package/dist/mui/src/virtualColumns/virtualColumnDefs.d.ts +29 -0
- package/dist/mui/src/virtualColumns/virtualColumnDefs.js +51 -0
- package/dist/mui-virtual.d.ts +1 -0
- package/dist/mui-virtual.js +2 -0
- package/dist/mui.d.ts +1 -0
- package/dist/mui.js +2 -0
- package/dist/query/src/index.d.ts +6 -0
- package/dist/query/src/index.js +7 -0
- package/dist/query/src/serverPivot.d.ts +42 -0
- package/dist/query/src/serverPivot.js +153 -0
- package/dist/query/src/useServerGrouping.d.ts +52 -0
- package/dist/query/src/useServerGrouping.js +186 -0
- package/dist/query/src/useServerTable.d.ts +20 -0
- package/dist/query/src/useServerTable.js +106 -0
- package/dist/query/src/useServerTableData.d.ts +48 -0
- package/dist/query/src/useServerTableData.js +64 -0
- package/dist/query/src/wire.d.ts +16 -0
- package/dist/query/src/wire.js +32 -0
- package/dist/query.d.ts +1 -0
- package/dist/query.js +2 -0
- package/package.json +125 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 컬럼 정의 시 받는 타입 — 한눈에 보는 표.
|
|
3
|
+
*
|
|
4
|
+
* `TableColumnDef<T, V, Ext>` = TanStack `ColumnDef<T, V>` + 아래 세 필드.
|
|
5
|
+
* `V` 는 셀 값 타입(helper 프리셋은 `key` 의 값 타입으로 추론한다. 점 경로는 `unknown`),
|
|
6
|
+
* `Ext` 는 `meta.custom` 의 타입(소비 앱 확장 슬롯. 기본 `{}`).
|
|
7
|
+
*
|
|
8
|
+
* | 위치 | 필드 | 뜻 |
|
|
9
|
+
* |---|---|---|
|
|
10
|
+
* | `TableColumnDef` | `id` / `accessorKey` / `accessorFn` | 컬럼 키·값 접근 (TanStack) |
|
|
11
|
+
* | `TableColumnDef` | `header` / `cell` / `footer` | 렌더 (TanStack) |
|
|
12
|
+
* | `TableColumnDef` | `size` / `minSize` / `maxSize` / `enableSorting` / `enableGrouping` … | TanStack 옵션 통과 |
|
|
13
|
+
* | `TableColumnDef` | `meta?: ColumnMeta<Ext>` | 렌더·집계·종속 선언 (아래) |
|
|
14
|
+
* | `TableColumnDef` | `filter?: FilterSpec<V>` | 필터 선언 (아래) |
|
|
15
|
+
* | `TableColumnDef` | `filterLabel?: ReactNode` | 필터 패널 전용 라벨 (헤더가 ReactNode 일 때) |
|
|
16
|
+
* | `ColumnMeta` | `dataType` | `"number" \| "text" \| "date" \| "datetime" \| "boolean" \| "enum"` — 필터 variant·포맷·집계 기본값의 근거 |
|
|
17
|
+
* | `ColumnMeta` | `isVisible` / `forceHidden` | 기본 숨김 / 값 보관 전용(토글·프리셋으로도 안 살아남) |
|
|
18
|
+
* | `ColumnMeta` | `align` / `headerAlign` / `headerTooltip` | 셀 정렬 · 헤더 정렬 · 헤더 툴팁 (렌더러가 읽는다) |
|
|
19
|
+
* | `ColumnMeta` | `ellipsis` / `decimals` / `currency` / `endAdornment` / `chip` / `placeholder` / `link` | 표시 보조 |
|
|
20
|
+
* | `ColumnMeta` | `selectOptions` | select/multiSelect 선택지 |
|
|
21
|
+
* | `ColumnMeta` | `enableAgg` / `aggregations` / `aggRender` | 그룹 집계 활성 · 함수 목록 · 커스텀 집계 렌더러 |
|
|
22
|
+
* | `ColumnMeta` | `sortExpandsTo` / `cascadeFilterLevels` / `relationColumns` / `dependentFilter` / `customCascadeFilter` / `commonCodeParentPath` / `scheduleFields` / `linearConfig` | 서버 필드 매핑 · 종속/통합 컬럼 |
|
|
23
|
+
* | `ColumnMeta` | `edit?: EditSpec` | 편집 선언 (`enabled` · `kind` · `variant` · `options` · `onCommit` · `inputProps`) |
|
|
24
|
+
* | `ColumnMeta` | `custom?: Ext` | 소비 앱 확장 슬롯 — `columnMetaOf<Ext>(def)?.custom` 으로 읽는다 |
|
|
25
|
+
* | `FilterSpec` | `kind` | 필터 kind (`defineFilterKind` 객체 또는 등록된 id) — 있으면 연산자·판정·직렬화·문구·codec 의 근거 |
|
|
26
|
+
* | `FilterSpec` | `variant` / `operators` / `defaultOperator` | 필터 UI 종류 · 허용 연산자 · 기본 연산자 (kind 가 있으면 kind 의 연산자로 좁혀진다) |
|
|
27
|
+
* | `FilterSpec` | `render` / `hidden` / `detail` | 커스텀 입력 · 필터 제외 · "상세 조건" 그룹 |
|
|
28
|
+
* | `FilterSpec` | `applyOnChange` / `debounceMs` | 값 변경 즉시 조회 · 그 지연(ms, 컬럼 단위가 `TableSearchOptions.debounceMs` 보다 우선) |
|
|
29
|
+
* | `FilterSpec` | `defaultValue` | 초기값 |
|
|
30
|
+
*
|
|
31
|
+
* 필터 값 타입은 셀 값 타입 `V` 와 **독립**이다(숫자 컬럼의 범위 필터는 `[number, number]`).
|
|
32
|
+
* `filter.kind` 가 있으면 필터 값·연산자 타입은 kind 가 정한다(`FilterSpecOf<K>`, `FilterSpecInput`).
|
|
33
|
+
* kind 가 없는 variant 경로에서만 `FilterSpec<V>` 의 `V` 가 `render`/`defaultValue` 의 편의 타입이며,
|
|
34
|
+
* 다르면 `FilterSpec<any>` 로 둔다.
|
|
35
|
+
*/
|
|
36
|
+
import type { ReactNode } from "react";
|
|
37
|
+
import type { ColumnDef, RowData } from "@tanstack/react-table";
|
|
38
|
+
import type { FilterSpecInput } from "./filter";
|
|
39
|
+
/** 편집 선언 — `ColumnMeta.edit` 와 `ColumnBuilder.setEdit` 가 같은 타입을 쓴다 */
|
|
40
|
+
export interface EditSpec<T extends RowData = any> {
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
kind?: "text" | "number" | "select";
|
|
43
|
+
variant?: "dropdown" | "chip" | "button";
|
|
44
|
+
options?: SelectOption[] | ((row: T) => SelectOption[]);
|
|
45
|
+
color?: string;
|
|
46
|
+
size?: "small" | "medium";
|
|
47
|
+
/** 미지정 시 `row[key]` 에 직접 반영한다. 렌더러는 세 번째 인자로 columnId 를 준다 */
|
|
48
|
+
onCommit?: (value: unknown, row: T, columnId?: string) => void;
|
|
49
|
+
/** 렌더러가 그대로 전달할 입력 props */
|
|
50
|
+
inputProps?: Record<string, unknown>;
|
|
51
|
+
}
|
|
52
|
+
/** select/multiSelect 필터의 선택지 (MRT `DropdownOption` 대체) */
|
|
53
|
+
export interface SelectOption {
|
|
54
|
+
label: string;
|
|
55
|
+
value: string;
|
|
56
|
+
/** 계층 옵션의 상위 체인 표시용 ("대분류 > 중분류") */
|
|
57
|
+
ancestorChain?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 컬럼의 실제 데이터 타입. 필터 UI 종류(`FilterVariant`)와는 직교다.
|
|
61
|
+
* `"select"` 는 `"enum"` 의 별칭이다(모든 판정에서 같게 취급) — 새 코드는 `"enum"` 을 쓴다.
|
|
62
|
+
*/
|
|
63
|
+
export type ColumnDataType = "number" | "text" | "date" | "datetime" | "boolean" | "enum" | "select";
|
|
64
|
+
export type DateFilterMode = "month" | "quarter" | "year" | "range" | "period";
|
|
65
|
+
/** 상위 컬럼 값에 종속되는 필터 (CommonCode 계층) */
|
|
66
|
+
export interface DependentFilterMeta {
|
|
67
|
+
dependsOn: string;
|
|
68
|
+
parentCodePath?: string;
|
|
69
|
+
allChildOptions: Array<{
|
|
70
|
+
idx: number;
|
|
71
|
+
name: string;
|
|
72
|
+
parentIdx: number;
|
|
73
|
+
ancestorChain?: string;
|
|
74
|
+
}>;
|
|
75
|
+
isMultiSelect: boolean;
|
|
76
|
+
}
|
|
77
|
+
/** CommonCode 가 아닌 컬럼의 커스텀 종속 필터 */
|
|
78
|
+
export interface CustomCascadeFilterMeta {
|
|
79
|
+
/** 상위 컬럼 키 (상위 → 하위 순서) */
|
|
80
|
+
ancestorKeys: string[];
|
|
81
|
+
/** 상위 필터값을 `ancestorKeys` 순서대로 받아 옵션을 반환. 전부 null 이면 전체 옵션 */
|
|
82
|
+
getOptions: (...parentFilterValues: (number[] | null)[]) => SelectOption[];
|
|
83
|
+
isMultiSelect: boolean;
|
|
84
|
+
}
|
|
85
|
+
/** 통합 cascade 트리가 실제로 필터를 거는 레벨 필드들 */
|
|
86
|
+
export interface CascadeFilterLevel {
|
|
87
|
+
key: string;
|
|
88
|
+
operator: string;
|
|
89
|
+
operatorOptions: string[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 컬럼 메타 — 렌더/집계/종속에 관한 선언.
|
|
93
|
+
*
|
|
94
|
+
* 기존 `ColumnMetaData` 에서 **필터 관련 항목은 `FilterSpec` 으로 옮겼다**
|
|
95
|
+
* (`hideFilter` → `filter.hidden`, `isVisible=false` 파생 → `filter.detail`,
|
|
96
|
+
* `dateFilterMode` → `filter.variant` + 자체 옵션).
|
|
97
|
+
* 여기 남은 `isVisible` 은 순수하게 **컬럼 표시** 여부다.
|
|
98
|
+
*/
|
|
99
|
+
export type CellAlign = "left" | "center" | "right";
|
|
100
|
+
/** `meta.aggRender` 가 받는 값 — ERP `AggValues` / mui `AggRenderProps` 와 같은 모양 */
|
|
101
|
+
export interface AggRenderValues {
|
|
102
|
+
/** 선택된(또는 첫) 집계 함수의 값 */
|
|
103
|
+
value: unknown;
|
|
104
|
+
columnId: string;
|
|
105
|
+
/** 이 그룹 노드의 집계 전체 (`node.aggregates`) — 다른 컬럼의 값도 볼 수 있다 */
|
|
106
|
+
allAggregates: Record<string, Record<string, unknown>>;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 커스텀 집계 렌더러 — ERP `AggCustomRender` 와 같은 `(values, column)` 규약.
|
|
110
|
+
* `column` 은 렌더러 패키지의 컬럼 인스턴스(TanStack `Column`)라 코어에서는 `unknown` 이다.
|
|
111
|
+
*/
|
|
112
|
+
export type AggRenderFn = (values: AggRenderValues, column?: unknown) => ReactNode;
|
|
113
|
+
export interface ColumnMeta<Ext = {}> {
|
|
114
|
+
dataType?: ColumnDataType;
|
|
115
|
+
/** 기본 숨김 — 사용자 토글·프리셋으로 다시 켜질 수 있다 */
|
|
116
|
+
isVisible?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* 값 보관 전용 — 절대 표시되지 않는다.
|
|
119
|
+
* `isVisible: false` 는 초기값일 뿐이라 토글로 되살아나므로,
|
|
120
|
+
* 헤더가 없는 컬럼(통합 cascade 에 흡수된 레벨 등)은 이 플래그를 쓴다.
|
|
121
|
+
*/
|
|
122
|
+
forceHidden?: boolean;
|
|
123
|
+
/** 이 컬럼으로 정렬할 때 서버에 대신 보낼 실제 필드 (상위 → 하위) */
|
|
124
|
+
sortExpandsTo?: string[];
|
|
125
|
+
cascadeFilterLevels?: CascadeFilterLevel[];
|
|
126
|
+
/** 1:N 관계 컬럼의 하위 필드 — 컬럼 정의만 읽는 쪽(AI 컨텍스트 등)이 구조를 알 수 있게 */
|
|
127
|
+
relationColumns?: Array<{
|
|
128
|
+
key: string;
|
|
129
|
+
label: string;
|
|
130
|
+
type?: string;
|
|
131
|
+
}>;
|
|
132
|
+
dependentFilter?: DependentFilterMeta;
|
|
133
|
+
commonCodeParentPath?: string;
|
|
134
|
+
customCascadeFilter?: CustomCascadeFilterMeta;
|
|
135
|
+
dateFilterMode?: DateFilterMode;
|
|
136
|
+
selectOptions?: SelectOption[];
|
|
137
|
+
/** 집계 활성 여부 */
|
|
138
|
+
enableAgg?: boolean;
|
|
139
|
+
aggregations?: string[];
|
|
140
|
+
/** 좁은 컬럼 말줄임 — 렌더러가 읽는다 */
|
|
141
|
+
ellipsis?: boolean;
|
|
142
|
+
/** 숫자 표시 보조 — 렌더러가 읽는다 */
|
|
143
|
+
decimals?: number;
|
|
144
|
+
currency?: string;
|
|
145
|
+
endAdornment?: unknown;
|
|
146
|
+
/** 값을 칩으로 감싼다 */
|
|
147
|
+
chip?: boolean;
|
|
148
|
+
/** 값이 비었을 때 대신 그릴 것 */
|
|
149
|
+
placeholder?: string;
|
|
150
|
+
/** 링크 컬럼 — `to` 는 "/" 로 시작하는 절대 경로를 반환해야 한다 */
|
|
151
|
+
link?: {
|
|
152
|
+
to: (props: unknown) => string;
|
|
153
|
+
};
|
|
154
|
+
/** 일정 통합 컬럼의 필드 매핑 */
|
|
155
|
+
scheduleFields?: {
|
|
156
|
+
plannedStart: string;
|
|
157
|
+
plannedEnd: string;
|
|
158
|
+
actualStart: string;
|
|
159
|
+
actualEnd: string;
|
|
160
|
+
};
|
|
161
|
+
/** 선형결합 필터 기본 설정 */
|
|
162
|
+
linearConfig?: unknown;
|
|
163
|
+
/** 합성 집계 행 렌더러 — `({ value, columnId, allAggregates }, column)` 로 불린다 */
|
|
164
|
+
aggRender?: AggRenderFn;
|
|
165
|
+
/** 셀 내용 정렬 — 렌더러가 읽는다. 미지정 시 number 는 오른쪽, 나머지 왼쪽이 관례 */
|
|
166
|
+
align?: CellAlign;
|
|
167
|
+
/** 헤더 정렬 — 미지정 시 `align` 을 따른다 */
|
|
168
|
+
headerAlign?: CellAlign;
|
|
169
|
+
/** 헤더에 마우스를 올리면 보이는 설명 */
|
|
170
|
+
headerTooltip?: string;
|
|
171
|
+
/**
|
|
172
|
+
* 소비 앱 확장 슬롯. 코어·렌더러는 읽지 않는다.
|
|
173
|
+
* `TableColumnDef<T, V, Ext>` / `columnMetaOf<Ext>(def)` 로 타입을 살린다.
|
|
174
|
+
*/
|
|
175
|
+
custom?: Ext;
|
|
176
|
+
/**
|
|
177
|
+
* 편집 선언. 실제 입력 컴포넌트는 렌더러 패키지가 그린다 —
|
|
178
|
+
* 코어가 MUI 를 모르는 채로 편집 가능 여부·방식을 표현하기 위한 자리다.
|
|
179
|
+
*/
|
|
180
|
+
edit?: EditSpec<any>;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 이 패키지의 컬럼 정의 = TanStack `ColumnDef` + `meta` + `filter`.
|
|
184
|
+
*
|
|
185
|
+
* 교차 타입으로 얹는 이유: `ColumnDef` 는 유니온이라 `interface extends` 가 안 되고,
|
|
186
|
+
* 전역 module augmentation 은 이 패키지를 쓰지 않는 소비자에게까지 새어 나간다.
|
|
187
|
+
*
|
|
188
|
+
* `V` 의 기본값이 `any` 인 이유: `ColumnDef<T, V>` 는 `cell` 콜백 때문에 `V` 에 반변이라
|
|
189
|
+
* `TableColumnDef<T, number>` 가 `TableColumnDef<T, unknown>` 에 들어가지 않는다.
|
|
190
|
+
* helper 가 값 타입을 추론해 내놓는 컬럼을 `TableColumnDef<T>` 파라미터가 그대로 받으려면
|
|
191
|
+
* 기본값이 `any` 여야 한다 (기존 호출부는 전부 `TableColumnDef<T, any>` 를 받고 있었다).
|
|
192
|
+
*/
|
|
193
|
+
export type TableColumnDef<T extends RowData, V = any, Ext = {}> = ColumnDef<T, V> & {
|
|
194
|
+
meta?: ColumnMeta<Ext>;
|
|
195
|
+
/** 필터 선언 — kind 별로 좁혀진 유니온. 읽을 때는 `FilterSpec` 모양으로 보면 된다 */
|
|
196
|
+
filter?: FilterSpecInput<V>;
|
|
197
|
+
/** 필터 라벨 전용 오버라이드 — 헤더가 ReactNode 일 때 사용 */
|
|
198
|
+
filterLabel?: ReactNode;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* 행 타입 `T` 에서 키 `K` 의 값 타입. `keyof T` 가 아니면(점 경로·동적 문자열) `unknown`.
|
|
202
|
+
* helper 프리셋이 `key` 리터럴로 `TableColumnDef<T, V>` 의 `V` 를 추론하는 데 쓴다.
|
|
203
|
+
*/
|
|
204
|
+
export type ValueOfKey<T, K extends string> = K extends keyof T ? T[K] : unknown;
|
|
205
|
+
/**
|
|
206
|
+
* 이종 컬럼 배열.
|
|
207
|
+
*
|
|
208
|
+
* 컬럼마다 필터 값 타입이 다른데(텍스트는 string, 상태는 string[], 기간은 [Date, Date])
|
|
209
|
+
* 동종 배열 하나로는 "원소마다 각자의 V" 를 표현할 수 없다 — 존재 타입이 필요한데
|
|
210
|
+
* TS 에 없다. TanStack 이 `ColumnDef<T, any>[]` 를 권장하는 것과 같은 이유이고,
|
|
211
|
+
* 같은 관례를 따른다. 개별 컬럼을 만들 때는 `TableColumnDef<T, V>` 로 V 를 살린다.
|
|
212
|
+
*/
|
|
213
|
+
export type TableColumnDefs<T extends RowData, Ext = {}> = Array<TableColumnDef<T, any, Ext>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { RowData } from "@tanstack/react-table";
|
|
2
|
+
import type { SelectionSource } from "./filter";
|
|
3
|
+
import type { GroupsResult, TableRequest, TableResponse, TableResponseMeta } from "./request";
|
|
4
|
+
/**
|
|
5
|
+
* `"server"` — 요청을 그대로 서버에 보낸다 (필터/정렬/페이지 전부 서버 계산).
|
|
6
|
+
* `"client"` — 메모리 배열에 같은 요청을 적용한다.
|
|
7
|
+
* 미지정이면 `queryFn` 유무로 판단한다 (기존 `useTableQuery` 규칙 그대로).
|
|
8
|
+
*/
|
|
9
|
+
export type TableMode = "client" | "server";
|
|
10
|
+
/**
|
|
11
|
+
* 서버 조회 함수 — 요청 본문과 취소 신호를 받아 응답을 돌려준다.
|
|
12
|
+
*
|
|
13
|
+
* `kokotable/query` 의 `useServerTableData` / `useServerGrouping` 과 테이블 정의
|
|
14
|
+
* (`TableDefinition.server.queryFn`) 가 같은 타입을 쓴다. 두 번째 인자를 무시하는
|
|
15
|
+
* `(request) => Promise<TableResponse<T>>` 도 그대로 대입된다.
|
|
16
|
+
*/
|
|
17
|
+
export type TableQueryFn<T> = (request: TableRequest, context: {
|
|
18
|
+
signal: AbortSignal;
|
|
19
|
+
}) => Promise<TableResponse<T>>;
|
|
20
|
+
export interface TableDataOptions<T extends RowData> {
|
|
21
|
+
request: TableRequest;
|
|
22
|
+
/** 서버 모드 */
|
|
23
|
+
queryFn?: TableQueryFn<T>;
|
|
24
|
+
queryKey?: readonly unknown[];
|
|
25
|
+
/** 클라이언트 모드 원본 배열 */
|
|
26
|
+
data?: T[];
|
|
27
|
+
mode?: TableMode;
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
staleTime?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 2층 — 데이터. **테이블 인스턴스가 없어도 동작한다.**
|
|
33
|
+
* 카드/차트 화면은 여기까지만 쓰고 3층을 만들지 않는다.
|
|
34
|
+
*/
|
|
35
|
+
export interface TableData<T extends RowData> {
|
|
36
|
+
rows: T[];
|
|
37
|
+
/** 서버 총 건수. 클라이언트 모드면 필터 적용 후 길이 */
|
|
38
|
+
total: number;
|
|
39
|
+
meta?: TableResponseMeta | null;
|
|
40
|
+
/** 서버 그룹 조회 응답의 `groups` (백엔드 `GroupsResult`). 클라이언트 모드면 null */
|
|
41
|
+
groups?: GroupsResult | null;
|
|
42
|
+
isLoading: boolean;
|
|
43
|
+
/** 첫 로드 여부 — 이후 refetch 는 기존 행을 유지한 채 갱신된다 */
|
|
44
|
+
isInitialLoading: boolean;
|
|
45
|
+
isError: boolean;
|
|
46
|
+
error?: Error;
|
|
47
|
+
/**
|
|
48
|
+
* 조회 실패를 렌더 중 throw 하지 않는 이유:
|
|
49
|
+
* 상위 ErrorBoundary 가 테이블 트리를 파괴하면 리마운트가 캐시의 error 를
|
|
50
|
+
* 다시 읽어 즉시 재-throw 하므로 경계 리셋으로 복구가 안 된다.
|
|
51
|
+
* 에러는 여기 실어 보내고 레이아웃이 제자리에서 재시도 UI 를 그린다.
|
|
52
|
+
*/
|
|
53
|
+
refetch: () => void;
|
|
54
|
+
readonly mode: TableMode;
|
|
55
|
+
}
|
|
56
|
+
/** 행 단위 필드 에러 (react-hook-form `FieldErrors` 호환) */
|
|
57
|
+
export type FieldErrors = {
|
|
58
|
+
[index: number]: Record<string, {
|
|
59
|
+
message?: string;
|
|
60
|
+
type?: string;
|
|
61
|
+
}> | undefined;
|
|
62
|
+
} | undefined;
|
|
63
|
+
export type { SelectionSource };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { Row, RowData, Table, TableOptions } from "@tanstack/react-table";
|
|
3
|
+
import type { TableColumnDefs } from "./column";
|
|
4
|
+
import type { FieldErrors, TableData, TableMode, TableQueryFn } from "./data";
|
|
5
|
+
import type { FilterOperator } from "./operators";
|
|
6
|
+
import type { TableRequest, TableResponse } from "./request";
|
|
7
|
+
import type { SearchState, TableSearch } from "./search";
|
|
8
|
+
import type { DataTable } from "./table";
|
|
9
|
+
import type { ExpandState, FlatItem, GroupPath } from "./grouping";
|
|
10
|
+
import type { AggregationSpec } from "../client/aggregate";
|
|
11
|
+
import type { UrlSync } from "../hooks/useUrlSync";
|
|
12
|
+
import type { SearchHistory } from "../hooks/useSearchHistory";
|
|
13
|
+
/**
|
|
14
|
+
* 테이블 정의 — **화면 하나를 선언하는 객체.**
|
|
15
|
+
*
|
|
16
|
+
* 소비자는 필요한 것만 채운다: 컬럼·기본값·서버 연결·기능 토글·그룹핑·URL 동기화.
|
|
17
|
+
* 조립은 `useTableFromDefinition(definition)`(클라이언트 모드, core) 또는
|
|
18
|
+
* `useServerTable(definition)`(서버 모드, `kokotable/query`) 이 하고, 렌더는
|
|
19
|
+
* `<TableScreen bundle={…} />`(`kokotable/mui`) 이 정의의 `features` 대로 한다.
|
|
20
|
+
*
|
|
21
|
+
* 기존 ERP `useTable(UseTableOptions)` 의 옵션 모양(columns/data/mode/queryFn/queryKey/
|
|
22
|
+
* syncWithUrl/initialExpand/fieldErrors/initialSearchParams/groupBatchSize)을 그대로
|
|
23
|
+
* 옮기되 MRT 옵션(`mrtOptions`, `enable*`)은 `features` 로 모았다.
|
|
24
|
+
*
|
|
25
|
+
* 정의 객체는 **참조가 안정적**이어야 한다 — 모듈 상수(`defineTable`)나 `useMemo` 로 만든다.
|
|
26
|
+
* 렌더마다 새로 만들면 컬럼 참조가 흔들려 검색 상태·컬럼 표시가 매번 다시 파생된다.
|
|
27
|
+
*/
|
|
28
|
+
export interface TableDefinition<T extends RowData> {
|
|
29
|
+
/** 화면 식별자 — 서버 캐시 키 접두·URL·프리셋 저장 키의 기준 */
|
|
30
|
+
key: string;
|
|
31
|
+
columns: TableColumnDefs<T>;
|
|
32
|
+
/** 미지정이면 `server` 유무로 판단한다 */
|
|
33
|
+
mode?: TableMode;
|
|
34
|
+
/** 클라이언트 모드 원본 배열 */
|
|
35
|
+
data?: T[];
|
|
36
|
+
/** 서버 모드 — `queryFn` 이 있어야 한다 */
|
|
37
|
+
server?: TableServerOptions<T>;
|
|
38
|
+
initial?: Partial<SearchState>;
|
|
39
|
+
/** 컬럼 기본 연산자를 덮어쓸 초기값 */
|
|
40
|
+
initialOperators?: Record<string, FilterOperator>;
|
|
41
|
+
/** 전역검색 입력 디바운스(ms) — `useTableSearch` 가 지원할 때만 전달된다 */
|
|
42
|
+
debounceMs?: number;
|
|
43
|
+
/** 클라이언트 모드 전역검색 대상 경로. 미지정이면 선언된 텍스트 계열 컬럼 전부 */
|
|
44
|
+
globalFilterFields?: string[];
|
|
45
|
+
/** `inPeriod` 기준 시각 (클라이언트 모드) */
|
|
46
|
+
now?: Date;
|
|
47
|
+
/** URL 동기화(`tp=`). `true` 면 기본 키, 객체면 키·구 스킴 키 지정 */
|
|
48
|
+
urlSync?: boolean | TableUrlSyncOptions;
|
|
49
|
+
/** 검색 조건 이력(뒤로/앞으로) */
|
|
50
|
+
history?: boolean | {
|
|
51
|
+
limit?: number;
|
|
52
|
+
};
|
|
53
|
+
grouping?: TableGroupingOptions;
|
|
54
|
+
features?: TableFeatures<T>;
|
|
55
|
+
/** 행 식별자. 서버 모드에서 선택·확장 상태가 재조회 후에도 유지되려면 **필수**다 */
|
|
56
|
+
getRowId?: (row: T, index: number, parent?: Row<T>) => string;
|
|
57
|
+
fieldErrors?: FieldErrors;
|
|
58
|
+
/** TanStack 원본 옵션 통과구 — `features` 가 만든 값 위에 덮인다 */
|
|
59
|
+
tableOptions?: Partial<TableOptions<T>>;
|
|
60
|
+
}
|
|
61
|
+
export interface TableServerOptions<T extends RowData> {
|
|
62
|
+
queryFn: TableQueryFn<T>;
|
|
63
|
+
/** 캐시 구분 키. `definition.key` 뒤에 붙는다 */
|
|
64
|
+
queryKey?: readonly unknown[];
|
|
65
|
+
staleTime?: number;
|
|
66
|
+
enabled?: boolean;
|
|
67
|
+
/** 응답 가공 — 캐시에 들어가기 전에 한 번 적용된다 (`select` 와 달리 렌더마다 돌지 않는다) */
|
|
68
|
+
transformResponse?: (response: TableResponse<T>, request: TableRequest) => TableResponse<T>;
|
|
69
|
+
/** 조건이 바뀌어 재조회하는 동안 이전 행을 유지한다 (기본 true) */
|
|
70
|
+
keepPreviousData?: boolean;
|
|
71
|
+
refetchInterval?: number | false;
|
|
72
|
+
retry?: boolean | number | ((failureCount: number, error: Error) => boolean);
|
|
73
|
+
}
|
|
74
|
+
export interface TableUrlSyncOptions {
|
|
75
|
+
/** 기본 `tp` */
|
|
76
|
+
paramKey?: string;
|
|
77
|
+
/** 구 스킴 키 (기본 `["filter"]`) */
|
|
78
|
+
legacyParamKeys?: readonly string[];
|
|
79
|
+
}
|
|
80
|
+
export interface TableGroupingOptions {
|
|
81
|
+
enabled: boolean;
|
|
82
|
+
/** 마운트 시 그룹 컬럼 (상위 → 하위). `initial.grouping` 이 있으면 그쪽이 우선 */
|
|
83
|
+
initial?: string[];
|
|
84
|
+
/** 서버 그룹핑 "더 보기" 배치 크기 (기본 50) */
|
|
85
|
+
batchSize?: number;
|
|
86
|
+
/** 집계 명세. 미지정이면 컬럼 `meta.enableAgg/aggregations` 에서 파생한다 */
|
|
87
|
+
aggregation?: AggregationSpec;
|
|
88
|
+
/** 클라이언트 그룹핑: 마운트 시 전부 펼침 */
|
|
89
|
+
initialExpanded?: boolean;
|
|
90
|
+
}
|
|
91
|
+
export interface TableRowNumbersFeature {
|
|
92
|
+
header?: ReactNode;
|
|
93
|
+
size?: number;
|
|
94
|
+
id?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface TableSelectionFeature<T extends RowData> {
|
|
97
|
+
/** 다중 선택 (기본 true). false 면 라디오 */
|
|
98
|
+
multi?: boolean;
|
|
99
|
+
/** 행 아무 곳을 눌러도 토글 */
|
|
100
|
+
selectOnRowClick?: boolean;
|
|
101
|
+
/** 헤더 전체 선택 (기본 true) */
|
|
102
|
+
selectAll?: boolean;
|
|
103
|
+
/** 선택 가능한 행 판정 */
|
|
104
|
+
canSelect?: (row: Row<T>) => boolean;
|
|
105
|
+
}
|
|
106
|
+
export interface TableExpandFeature<T extends RowData> {
|
|
107
|
+
/** 헤더 "모두 펼치기" (기본 true) */
|
|
108
|
+
expandAll?: boolean;
|
|
109
|
+
/** 펼칠 수 있는 행 판정 */
|
|
110
|
+
canExpand?: (row: Row<T>) => boolean;
|
|
111
|
+
}
|
|
112
|
+
/** `kokotable/mui` 의 `RowActionsColumnOptions<T>` 와 구조가 같다 */
|
|
113
|
+
export interface TableRowActionsFeature<T extends RowData> {
|
|
114
|
+
render: (row: Row<T>, table: Table<T>) => ReactNode;
|
|
115
|
+
position?: "first" | "last";
|
|
116
|
+
header?: ReactNode;
|
|
117
|
+
size?: number;
|
|
118
|
+
id?: string;
|
|
119
|
+
}
|
|
120
|
+
export interface TableVirtualizeFeature {
|
|
121
|
+
/** 행 가상화 (기본 true) */
|
|
122
|
+
rows?: boolean | {
|
|
123
|
+
estimateRowHeight?: number;
|
|
124
|
+
overscan?: number;
|
|
125
|
+
};
|
|
126
|
+
/** 열 가상화 (기본 false) */
|
|
127
|
+
columns?: boolean | {
|
|
128
|
+
overscan?: number;
|
|
129
|
+
};
|
|
130
|
+
estimateRowHeight?: number;
|
|
131
|
+
/** 스크롤 컨테이너 높이 — 가상화에 필수. 기본 520 */
|
|
132
|
+
maxHeight?: number | string;
|
|
133
|
+
}
|
|
134
|
+
export interface TableVirtualColumnsFeature {
|
|
135
|
+
/** 슬롯 상한 (기본 10) */
|
|
136
|
+
maxSlots?: number;
|
|
137
|
+
/** true(기본) — 카드 변경이 즉시 조회된다. false — 검색 버튼으로 적용 */
|
|
138
|
+
applyImmediately?: boolean;
|
|
139
|
+
/** 카드에 필터 입력을 붙인다 (기본 true) */
|
|
140
|
+
enableFilter?: boolean;
|
|
141
|
+
}
|
|
142
|
+
export interface TableFeatures<T extends RowData> {
|
|
143
|
+
/** 행 번호 열 */
|
|
144
|
+
rowNumbers?: boolean | TableRowNumbersFeature;
|
|
145
|
+
/** 행 선택 열 + 선택 액션바 */
|
|
146
|
+
selection?: boolean | TableSelectionFeature<T>;
|
|
147
|
+
/** 확장 토글 열 — `TableScreen slots.detailPanel` 과 짝. 슬롯만 줘도 켜진다 */
|
|
148
|
+
expand?: boolean | TableExpandFeature<T>;
|
|
149
|
+
/** 행 액션 열 — `slots.rowActions` 가 있으면 그쪽 렌더가 우선한다 */
|
|
150
|
+
rowActions?: TableRowActionsFeature<T>;
|
|
151
|
+
/** 표시 전용 열 id 를 MRT 것(`mrt-row-*`)으로 — 저장된 프리셋 호환 */
|
|
152
|
+
legacyIds?: boolean;
|
|
153
|
+
/** 그룹핑 중 그룹 컬럼 배치 (기본 reorder) */
|
|
154
|
+
groupedColumnMode?: "reorder" | "remove" | false;
|
|
155
|
+
/**
|
|
156
|
+
* 행(·열) 가상화 — `kokotable/mui/virtual` 의 `VirtualTableScreen` 만 그린다.
|
|
157
|
+
* 메인 `TableScreen` 은 무시하고 경고만 낸다 (`@tanstack/react-virtual` 이 optional peer 라서).
|
|
158
|
+
*/
|
|
159
|
+
virtualize?: boolean | TableVirtualizeFeature;
|
|
160
|
+
density?: "comfortable" | "compact" | "spacious";
|
|
161
|
+
/** 헤더 컬럼 메뉴 (기본 true) */
|
|
162
|
+
columnMenu?: boolean;
|
|
163
|
+
/** 툴바 왼쪽 전역검색 입력 */
|
|
164
|
+
globalFilter?: boolean;
|
|
165
|
+
/** 툴바 오른쪽 "적용 조건" 버튼(필터 상태 모달) */
|
|
166
|
+
filterStatus?: boolean;
|
|
167
|
+
/** 툴바 오른쪽 컬럼 표시 토글 */
|
|
168
|
+
columnVisibilityMenu?: boolean;
|
|
169
|
+
/** 필터 구역 끝의 가상 열 섹션 — 서버가 식을 평가해 응답 행에 값을 실어 준다 */
|
|
170
|
+
virtualColumns?: boolean | TableVirtualColumnsFeature;
|
|
171
|
+
}
|
|
172
|
+
/** `mode` 미지정 시의 판정 — `server` 가 있으면 서버 모드 */
|
|
173
|
+
export declare function resolveDefinitionMode<T extends RowData>(definition: TableDefinition<T>): TableMode;
|
|
174
|
+
/**
|
|
175
|
+
* 정의 검증 — 잘못된 정의는 **마운트 전에** 던진다.
|
|
176
|
+
*
|
|
177
|
+
* - 중복 컬럼 id: 필터·정렬 상태가 한 키에 두 컬럼을 매달아 조용히 어긋난다
|
|
178
|
+
* - 서버 모드인데 `queryFn` 없음
|
|
179
|
+
* - 서버 모드 + 선택/확장인데 `getRowId` 없음: 재조회 후 행 순번이 바뀌면 선택이 다른 행으로
|
|
180
|
+
* 옮겨 간다 — 던지지 않고 경고만 한다 (읽기 전용 화면은 문제가 없다)
|
|
181
|
+
*/
|
|
182
|
+
export declare function validateTableDefinition<T extends RowData>(definition: TableDefinition<T>): void;
|
|
183
|
+
/**
|
|
184
|
+
* 타입 추론용 identity + 검증. 잘못된 정의는 여기서 던진다.
|
|
185
|
+
*
|
|
186
|
+
* ```ts
|
|
187
|
+
* const salesTable = defineTable<SalesRow>({ key: "sales", columns, data });
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
export declare function defineTable<T extends RowData>(definition: TableDefinition<T>): TableDefinition<T>;
|
|
191
|
+
export interface TableBundleGrouping<T extends RowData> {
|
|
192
|
+
/** 그룹 컬럼이 하나라도 있는가 */
|
|
193
|
+
readonly enabled: boolean;
|
|
194
|
+
/** 현재 그룹 컬럼 (상위 → 하위) = `search.params.grouping` */
|
|
195
|
+
grouping: string[];
|
|
196
|
+
setGrouping: (grouping: string[]) => void;
|
|
197
|
+
/** 화면 순서대로 평탄화된 항목 — `TableContent groupItems` */
|
|
198
|
+
items: Array<FlatItem<T>>;
|
|
199
|
+
expand: ExpandState;
|
|
200
|
+
/** 서버 그룹핑 "더 보기" */
|
|
201
|
+
loadMore?: (path: GroupPath) => void;
|
|
202
|
+
/** 3층에 실린 말단 행 (서버 헤더 우선 모드에서는 펼쳐서 받은 행) */
|
|
203
|
+
rows: T[];
|
|
204
|
+
/** 서버 그룹핑 배치 크기 */
|
|
205
|
+
batchSize?: number;
|
|
206
|
+
setBatchSize?: (size: number) => void;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* 조립 결과 — 클라이언트(`useTableFromDefinition`)·서버(`useServerTable`) 모두 이 모양이다.
|
|
210
|
+
* 렌더러(`TableScreen`)는 어느 쪽에서 왔는지 몰라도 된다.
|
|
211
|
+
*/
|
|
212
|
+
export interface TableBundle<T extends RowData> {
|
|
213
|
+
definition: TableDefinition<T>;
|
|
214
|
+
readonly mode: TableMode;
|
|
215
|
+
search: TableSearch<T>;
|
|
216
|
+
/** 3층에 실린 데이터 — 서버 헤더 우선 그룹핑에서는 `rows` 가 펼쳐서 받은 말단 행이다 */
|
|
217
|
+
data: TableData<T>;
|
|
218
|
+
table: DataTable<T>;
|
|
219
|
+
/** `definition.grouping.enabled` 일 때만 */
|
|
220
|
+
grouping?: TableBundleGrouping<T>;
|
|
221
|
+
/** `definition.urlSync` 일 때만 */
|
|
222
|
+
urlSync?: UrlSync;
|
|
223
|
+
/** `definition.history` 일 때만 */
|
|
224
|
+
history?: SearchHistory;
|
|
225
|
+
/** = `search.request` */
|
|
226
|
+
request: TableRequest;
|
|
227
|
+
/**
|
|
228
|
+
* 3층(TanStack)에 실린 컬럼. 기본은 `definition.columns` 이고, 렌더러가 `setTableColumns` 로
|
|
229
|
+
* 표시 전용 열·가상 컬럼을 끼운 목록을 등록하면 그것이 된다.
|
|
230
|
+
*/
|
|
231
|
+
tableColumns: TableColumnDefs<T>;
|
|
232
|
+
/** 3층 컬럼 등록 — `null` 이면 `definition.columns` 로 되돌린다 */
|
|
233
|
+
setTableColumns: (columns: TableColumnDefs<T> | null) => void;
|
|
234
|
+
/**
|
|
235
|
+
* 현재 조건의 **전체 행**(페이지 무시). 내보내기용 — 클라이언트 모드는 필터·정렬 결과,
|
|
236
|
+
* 서버 모드는 `pagination` 없이 한 번 더 조회한 응답이다.
|
|
237
|
+
*/
|
|
238
|
+
fetchAllRows: () => Promise<T[]>;
|
|
239
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { columnKey } from "../columns/deriveOperators";
|
|
2
|
+
// ── 검증 ──
|
|
3
|
+
/** `mode` 미지정 시의 판정 — `server` 가 있으면 서버 모드 */
|
|
4
|
+
export function resolveDefinitionMode(definition) {
|
|
5
|
+
if (definition.mode)
|
|
6
|
+
return definition.mode;
|
|
7
|
+
return definition.server ? "server" : "client";
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 정의 검증 — 잘못된 정의는 **마운트 전에** 던진다.
|
|
11
|
+
*
|
|
12
|
+
* - 중복 컬럼 id: 필터·정렬 상태가 한 키에 두 컬럼을 매달아 조용히 어긋난다
|
|
13
|
+
* - 서버 모드인데 `queryFn` 없음
|
|
14
|
+
* - 서버 모드 + 선택/확장인데 `getRowId` 없음: 재조회 후 행 순번이 바뀌면 선택이 다른 행으로
|
|
15
|
+
* 옮겨 간다 — 던지지 않고 경고만 한다 (읽기 전용 화면은 문제가 없다)
|
|
16
|
+
*/
|
|
17
|
+
export function validateTableDefinition(definition) {
|
|
18
|
+
if (!definition.key || typeof definition.key !== "string") {
|
|
19
|
+
throw new Error("[koko-table] defineTable: `key` 는 비어 있지 않은 문자열이어야 합니다.");
|
|
20
|
+
}
|
|
21
|
+
if (!Array.isArray(definition.columns)) {
|
|
22
|
+
throw new Error(`[koko-table] defineTable("${definition.key}"): \`columns\` 배열이 필요합니다.`);
|
|
23
|
+
}
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
for (const column of definition.columns) {
|
|
26
|
+
const id = columnKey(column);
|
|
27
|
+
if (!id)
|
|
28
|
+
continue;
|
|
29
|
+
if (seen.has(id)) {
|
|
30
|
+
throw new Error(`[koko-table] defineTable("${definition.key}"): 컬럼 id "${id}" 가 중복됩니다.`);
|
|
31
|
+
}
|
|
32
|
+
seen.add(id);
|
|
33
|
+
}
|
|
34
|
+
const mode = resolveDefinitionMode(definition);
|
|
35
|
+
if (mode === "server" && typeof definition.server?.queryFn !== "function") {
|
|
36
|
+
throw new Error(`[koko-table] defineTable("${definition.key}"): 서버 모드는 \`server.queryFn\` 이 필요합니다.`);
|
|
37
|
+
}
|
|
38
|
+
if (mode === "client" && definition.server) {
|
|
39
|
+
throw new Error(`[koko-table] defineTable("${definition.key}"): mode "client" 인데 \`server\` 가 있습니다 — 하나만 두세요.`);
|
|
40
|
+
}
|
|
41
|
+
const features = definition.features;
|
|
42
|
+
const needsRowId = !!features && (!!features.selection || !!features.expand);
|
|
43
|
+
const hasRowId = !!definition.getRowId || !!definition.tableOptions?.getRowId;
|
|
44
|
+
if (mode === "server" && needsRowId && !hasRowId && typeof console !== "undefined") {
|
|
45
|
+
console.warn(`[koko-table] defineTable("${definition.key}"): 서버 모드에서 선택·확장 상태를 재조회 뒤에도 유지하려면 ` +
|
|
46
|
+
"`getRowId` 가 필요합니다. 없으면 행 순번(index) 이 id 가 되어 캐시 갱신 후 다른 행에 선택이 옮겨 갑니다.");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 타입 추론용 identity + 검증. 잘못된 정의는 여기서 던진다.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* const salesTable = defineTable<SalesRow>({ key: "sales", columns, data });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function defineTable(definition) {
|
|
57
|
+
validateTableDefinition(definition);
|
|
58
|
+
return definition;
|
|
59
|
+
}
|