diff --git a/frontend/src/components/TableDesigner.tsx b/frontend/src/components/TableDesigner.tsx index 0df2840..2697949 100644 --- a/frontend/src/components/TableDesigner.tsx +++ b/frontend/src/components/TableDesigner.tsx @@ -121,7 +121,7 @@ const ResizableTitle = (props: any) => { nextStyle.width = width; } - if (!width) { + if (!onResizeStart) { return ; } @@ -415,11 +415,6 @@ const TableDesigner: React.FC<{ tab: TabData }> = ({ tab }) => { // Initial Columns Definition useEffect(() => { const initialCols = [ - ...(readOnly ? [] : [{ - key: 'sort', - width: 40, - render: () => , - }]), { title: '名', dataIndex: 'name', @@ -2020,13 +2015,60 @@ END;`; }; // Merge columns with resize handler - const resizableColumns = tableColumns.map((col, index) => ({ + const resizableColumns = useMemo(() => tableColumns.map((col, index) => ({ ...col, onHeaderCell: (column: any) => ({ width: column.width, onResizeStart: handleResizeStart(index), }), - })); + })), [tableColumns]); + + // 字段表 Checkbox 选择列(不参与 resize,支持全选) + const allColumnKeys = useMemo(() => columns.map(c => c._key), [columns]); + const isAllColumnsSelected = allColumnKeys.length > 0 && selectedColumnRowKeys.length === allColumnKeys.length; + const isColumnsIndeterminate = selectedColumnRowKeys.length > 0 && selectedColumnRowKeys.length < allColumnKeys.length; + + const columnSelectCol = useMemo(() => ({ + title: () => ( + setSelectedColumnRowKeys(e.target.checked ? allColumnKeys : [])} + style={{ margin: 0 }} + /> + ), + dataIndex: '_select', + key: '_select', + width: 48, + render: (_: any, record: any) => ( + { + e.stopPropagation(); + setSelectedColumnRowKeys((prev: string[]) => + e.target.checked + ? [...prev, record._key] + : prev.filter((k: string) => k !== record._key) + ); + }} + style={{ margin: 0 }} + /> + ), + }), [selectedColumnRowKeys, allColumnKeys, isAllColumnsSelected, isColumnsIndeterminate]); + + // sort 拖拽列(不参与 resize) + const sortColumn = useMemo(() => ({ + key: 'sort', + width: 40, + render: () => , + }), []); + + const columnsWithSelect = useMemo(() => + readOnly + ? resizableColumns + : [columnSelectCol, sortColumn, ...resizableColumns], + [readOnly, columnSelectCol, sortColumn, resizableColumns] + ); // --- Index Columns Init --- useEffect(() => { @@ -2153,7 +2195,7 @@ END;`; {readOnly ? ( record._key === focusColumnKey ? 'table-designer-focus-row' : ''} size="small" @@ -2172,11 +2214,7 @@ END;`; c._key)} strategy={verticalListSortingStrategy}>
setSelectedColumnRowKeys(nextSelectedRowKeys as string[]), - }} + columns={columnsWithSelect} rowKey="_key" rowClassName={(record: EditableColumn) => record._key === focusColumnKey ? 'table-designer-focus-row' : ''} size="small" @@ -2203,11 +2241,13 @@ END;`; .table-designer-shell .ant-table-container { background: transparent !important; } - .table-designer-shell .ant-table-wrapper, - .table-designer-shell .ant-table-container { + .table-designer-shell .ant-table-wrapper { border: none !important; overflow: hidden !important; } + .table-designer-shell .ant-table-container { + border: none !important; + } .table-designer-shell .ant-table-thead > tr > th { background: transparent !important; border-bottom: 1px solid ${darkMode ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'} !important; @@ -2219,6 +2259,13 @@ END;`; border-bottom: 1px solid ${darkMode ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)'} !important; border-inline-end: 1px solid transparent !important; } + .table-designer-shell .ant-table-tbody td .ant-input { + padding-left: 0 !important; + padding-right: 0 !important; + } + .table-designer-shell .ant-table-tbody td .ant-select .ant-select-selector { + padding-left: 0 !important; + } .table-designer-shell .ant-table-thead > tr > th::before { display: none !important; } @@ -2237,6 +2284,13 @@ END;`; .table-designer-shell .ant-tabs-nav::before { border-bottom-color: ${darkMode ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.08)'} !important; } + .table-designer-shell .ant-tabs-ink-bar { + will-change: transform; + transition: width 0.15s ease, left 0.15s ease, transform 0.15s ease !important; + } + .table-designer-shell .ant-tabs-tab { + transition: color 0.15s ease !important; + } .table-designer-shell .ant-tabs-content-holder, .table-designer-shell .ant-tabs-content, .table-designer-shell .ant-tabs-tabpane { @@ -2343,7 +2397,7 @@ END;`; React.startTransition(() => setActiveKey(key))} style={{ flex: 1, minHeight: 0,