feat(fe): auto-prepend pinned left No. row-number column in KsDataGrid and harness in AGENTS.md
This commit is contained in:
@@ -101,6 +101,7 @@ All work in this repository MUST follow `docs/CURRENT/WBS_EXECUTION_PROCEDURES.m
|
|||||||
- **[CRITICAL IRON RULE] Standardized Loading Skeleton Rule**: ALL screen-level and section-level data loading MUST render animated `SkeletonLoader` (shimmer mode) matching the expected layout (e.g. `skeletonType="table"` for grids, `skeletonType="card"` for forms/summaries) through `QueryStateBoundary`/`StandardScreenBoundary`. Static text ("불러오는 중...") or empty screen placeholders during loading states are STRICTLY PROHIBITED.
|
- **[CRITICAL IRON RULE] Standardized Loading Skeleton Rule**: ALL screen-level and section-level data loading MUST render animated `SkeletonLoader` (shimmer mode) matching the expected layout (e.g. `skeletonType="table"` for grids, `skeletonType="card"` for forms/summaries) through `QueryStateBoundary`/`StandardScreenBoundary`. Static text ("불러오는 중...") or empty screen placeholders during loading states are STRICTLY PROHIBITED.
|
||||||
- **[CRITICAL IRON RULE] Standardized Empty Data State Rule**: When zero records or empty dataset states occur, ALL grids, lists, and summary cards MUST render standard `EmptyStatePlaceholder` component (`📭` icon, clear title, descriptive helper text, and optional recovery action button). Blank white spaces or plain `<p>데이터가 없습니다</p>` text tags are STRICTLY PROHIBITED.
|
- **[CRITICAL IRON RULE] Standardized Empty Data State Rule**: When zero records or empty dataset states occur, ALL grids, lists, and summary cards MUST render standard `EmptyStatePlaceholder` component (`📭` icon, clear title, descriptive helper text, and optional recovery action button). Blank white spaces or plain `<p>데이터가 없습니다</p>` text tags are STRICTLY PROHIBITED.
|
||||||
- **[CRITICAL IRON RULE] Standardized UI Component Scale & Density Rule**: ALL UI components (grids, inputs, buttons, select, date fields, cards) MUST strictly inherit central Design System Tokens (`tokens.css` / `base.css`). Custom inline height/font overrides are STRICTLY PROHIBITED. Grid header height (`30px`), row height (`28px`), control height (`28px`), and grid font size (`12px`) MUST be universally uniform across all screens.
|
- **[CRITICAL IRON RULE] Standardized UI Component Scale & Density Rule**: ALL UI components (grids, inputs, buttons, select, date fields, cards) MUST strictly inherit central Design System Tokens (`tokens.css` / `base.css`). Custom inline height/font overrides are STRICTLY PROHIBITED. Grid header height (`30px`), row height (`28px`), control height (`28px`), and grid font size (`12px`) MUST be universally uniform across all screens.
|
||||||
|
- **[CRITICAL IRON RULE] Standardized Grid Row Numbering Rule**: Unless explicitly disabled (`showRowNumber: false`), ALL data grids MUST automatically prepend a pinned left `No.` column rendering 1-indexed sequential row numbers (`node.rowIndex + 1`) centered with `54px` fixed width.
|
||||||
|
|
||||||
## v16.0 Gitea API & CI/CD Automation
|
## v16.0 Gitea API & CI/CD Automation
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 63 KiB |
@@ -7,17 +7,38 @@ import type { UiGridColumn } from '../adapter/contracts'
|
|||||||
ModuleRegistry.registerModules([ClientSideRowModelModule, TextFilterModule, RowSelectionModule])
|
ModuleRegistry.registerModules([ClientSideRowModelModule, TextFilterModule, RowSelectionModule])
|
||||||
|
|
||||||
const emit = defineEmits<{ rowSelected: [row: unknown] }>()
|
const emit = defineEmits<{ rowSelected: [row: unknown] }>()
|
||||||
const props = withDefaults(defineProps<{ rows: unknown[]; columns: UiGridColumn[]; loading?: boolean; height?: string; rowSelection?: 'single' | 'multiple' | 'none' }>(), { loading: false, height: '32rem', rowSelection: 'single' })
|
const props = withDefaults(defineProps<{ rows: unknown[]; columns: UiGridColumn[]; loading?: boolean; height?: string; rowSelection?: 'single' | 'multiple' | 'none'; showRowNumber?: boolean }>(), { loading: false, height: '32rem', rowSelection: 'single', showRowNumber: true })
|
||||||
const columnDefs = computed<ColDef[]>(() => props.columns.map(column => ({
|
const columnDefs = computed<ColDef[]>(() => {
|
||||||
field: column.field,
|
const mappedCols: ColDef[] = props.columns.map(column => ({
|
||||||
headerName: column.header,
|
field: column.field,
|
||||||
width: column.width,
|
headerName: column.header,
|
||||||
minWidth: column.minWidth ?? 80,
|
width: column.width,
|
||||||
flex: column.flex ?? (column.width ? undefined : 1),
|
minWidth: column.minWidth ?? 80,
|
||||||
sortable: column.sortable ?? true,
|
flex: column.flex ?? (column.width ? undefined : 1),
|
||||||
filter: column.filterable ?? true,
|
sortable: column.sortable ?? true,
|
||||||
valueFormatter: column.formatter ? params => column.formatter?.(params.value, params.data) ?? '' : undefined
|
filter: column.filterable ?? true,
|
||||||
})))
|
valueFormatter: column.formatter ? params => column.formatter?.(params.value, params.data) ?? '' : undefined
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (props.showRowNumber) {
|
||||||
|
const rowNumCol: ColDef = {
|
||||||
|
headerName: 'No.',
|
||||||
|
valueGetter: 'node.rowIndex + 1',
|
||||||
|
width: 54,
|
||||||
|
minWidth: 50,
|
||||||
|
maxWidth: 65,
|
||||||
|
pinned: 'left',
|
||||||
|
sortable: false,
|
||||||
|
filter: false,
|
||||||
|
resizable: false,
|
||||||
|
cellStyle: { textAlign: 'center', color: 'var(--ks-color-neutral-600)', fontSize: '11px' },
|
||||||
|
headerClass: 'ks-row-number-header'
|
||||||
|
}
|
||||||
|
return [rowNumCol, ...mappedCols]
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappedCols
|
||||||
|
})
|
||||||
const rowSelectionOptions = computed(() => props.rowSelection === 'none' ? undefined : ({ mode: props.rowSelection === 'multiple' ? 'multiRow' : 'singleRow' } as const))
|
const rowSelectionOptions = computed(() => props.rowSelection === 'none' ? undefined : ({ mode: props.rowSelection === 'multiple' ? 'multiRow' : 'singleRow' } as const))
|
||||||
function onRowClicked(event: RowClickedEvent): void {
|
function onRowClicked(event: RowClickedEvent): void {
|
||||||
if (event.data) emit('rowSelected', event.data)
|
if (event.data) emit('rowSelected', event.data)
|
||||||
|
|||||||
Reference in New Issue
Block a user