feat: table block support hiding the index column (default visible) (#6416)

* feat: table block supports hiding the selection column (default visible)

* fix: bug

* fix: bug

* fix: bug

* fix: bug

* test: table block setting
This commit is contained in:
Katherine 2025-03-13 16:58:01 +08:00 committed by GitHub
parent e140b0a7d1
commit 430036905a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 212 additions and 124 deletions

View File

@ -62,6 +62,7 @@ interface Props {
children?: any; children?: any;
expandFlag?: boolean; expandFlag?: boolean;
dragSortBy?: string; dragSortBy?: string;
enableIndexÏColumn?: boolean;
} }
const InternalTableBlockProvider = (props: Props) => { const InternalTableBlockProvider = (props: Props) => {
@ -74,6 +75,7 @@ const InternalTableBlockProvider = (props: Props) => {
expandFlag: propsExpandFlag = false, expandFlag: propsExpandFlag = false,
fieldNames, fieldNames,
collection, collection,
enableIndexÏColumn,
} = props; } = props;
const field: any = useField(); const field: any = useField();
const { resource, service } = useBlockRequestContext(); const { resource, service } = useBlockRequestContext();
@ -131,6 +133,7 @@ const InternalTableBlockProvider = (props: Props) => {
allIncludesChildren, allIncludesChildren,
setExpandFlag: setExpandFlagValue, setExpandFlag: setExpandFlagValue,
heightProps, heightProps,
enableIndexÏColumn,
}), }),
[ [
allIncludesChildren, allIncludesChildren,
@ -146,6 +149,7 @@ const InternalTableBlockProvider = (props: Props) => {
service, service,
setExpandFlagValue, setExpandFlagValue,
showIndex, showIndex,
enableIndexÏColumn,
], ],
); );

View File

@ -1081,5 +1081,6 @@
"If selected, the route will be displayed in the menu.": "如果选中,该路由将显示在菜单中。", "If selected, the route will be displayed in the menu.": "如果选中,该路由将显示在菜单中。",
"Are you sure you want to hide this tab?": "你确定要隐藏该标签页吗?", "Are you sure you want to hide this tab?": "你确定要隐藏该标签页吗?",
"After hiding, this tab will no longer appear in the tab bar. To show it again, you need to go to the route management page to set it.": "隐藏后,该标签将不再显示在标签栏中。要想再次显示它,你需要到路由管理页面进行设置。", "After hiding, this tab will no longer appear in the tab bar. To show it again, you need to go to the route management page to set it.": "隐藏后,该标签将不再显示在标签栏中。要想再次显示它,你需要到路由管理页面进行设置。",
"Date scope":"日期范围" "Date scope":"日期范围",
"Enable index column": "启用序号列"
} }

View File

@ -25,6 +25,33 @@ import { setDefaultSortingRulesSchemaSettingsItem } from '../../../../schema-set
import { setTheDataScopeSchemaSettingsItem } from '../../../../schema-settings/setTheDataScopeSchemaSettingsItem'; import { setTheDataScopeSchemaSettingsItem } from '../../../../schema-settings/setTheDataScopeSchemaSettingsItem';
import { useBlockTemplateContext } from '../../../../schema-templates/BlockTemplateProvider'; import { useBlockTemplateContext } from '../../../../schema-templates/BlockTemplateProvider';
import { setDataLoadingModeSettingsItem } from '../details-multi/setDataLoadingModeSettingsItem'; import { setDataLoadingModeSettingsItem } from '../details-multi/setDataLoadingModeSettingsItem';
import { SchemaSettingsItemType } from '../../../../application';
const enabledIndexColumn: SchemaSettingsItemType = {
name: 'enableIndexColumn',
type: 'switch',
useComponentProps: () => {
const field = useField();
const fieldSchema = useFieldSchema();
const { t } = useTranslation();
const { dn } = useDesignable();
return {
title: t('Enable index column'),
checked: field.decoratorProps.enableSelectColumn !== false,
onChange: async (enableIndexÏColumn) => {
field.decoratorProps = field.decoratorProps || {};
field.decoratorProps.enableIndexÏColumn = enableIndexÏColumn;
fieldSchema['x-decorator-props'].enableIndexÏColumn = enableIndexÏColumn;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-decorator-props': fieldSchema['x-decorator-props'],
},
});
},
};
},
};
export const tableBlockSettings = new SchemaSettings({ export const tableBlockSettings = new SchemaSettings({
name: 'blockSettings:table', name: 'blockSettings:table',
@ -139,6 +166,7 @@ export const tableBlockSettings = new SchemaSettings({
}; };
}, },
}, },
enabledIndexColumn,
{ {
name: 'SortField', name: 'SortField',
Component: SchemaSettingsSortField, Component: SchemaSettingsSortField,

View File

@ -28,7 +28,33 @@ import { isSubMode } from '../../../../schema-component/antd/association-field/u
import { useIsAssociationField } from '../../../../schema-component/antd/form-item'; import { useIsAssociationField } from '../../../../schema-component/antd/form-item';
import { FormLinkageRules } from '../../../../schema-settings/LinkageRules'; import { FormLinkageRules } from '../../../../schema-settings/LinkageRules';
import { SchemaSettingsLinkageRules } from '../../../../schema-settings/SchemaSettings'; import { SchemaSettingsLinkageRules } from '../../../../schema-settings/SchemaSettings';
import { SchemaSettingsItemType } from '../../../../application';
const enabledIndexColumn: SchemaSettingsItemType = {
name: 'enableIndexColumn',
type: 'switch',
useComponentProps: () => {
const field = useField();
const fieldSchema = useFieldSchema();
const { t } = useTranslation();
const { dn } = useDesignable();
return {
title: t('Enable index column'),
checked: field.componentProps.enableIndexÏColumn !== false,
onChange: async (enableIndexÏColumn) => {
field.componentProps = field.componentProps || {};
field.componentProps.enableIndexÏColumn = enableIndexÏColumn;
fieldSchema['x-component-props'].enableIndexÏColumn = enableIndexÏColumn;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-component-props': fieldSchema['x-component-props'],
},
});
},
};
},
};
const fieldComponent: any = { const fieldComponent: any = {
name: 'fieldComponent', name: 'fieldComponent',
type: 'select', type: 'select',
@ -365,6 +391,7 @@ export const subTablePopoverComponentFieldSettings = new SchemaSettings({
allowSelectExistingRecord, allowSelectExistingRecord,
allowDisassociation, allowDisassociation,
setDefaultSortingRules, setDefaultSortingRules,
enabledIndexColumn,
linkageRules, linkageRules,
recordPerPage, recordPerPage,
], ],

View File

@ -97,7 +97,7 @@ export const SubTable: any = observer(
const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label');
const recordV2 = useCollectionRecord(); const recordV2 = useCollectionRecord();
const collection = useCollection(); const collection = useCollection();
const { allowSelectExistingRecord, allowAddnew, allowDisassociation } = field.componentProps; const { allowSelectExistingRecord, allowAddnew, allowDisassociation, enableIndexÏColumn } = field.componentProps;
useSubTableSpecialCase({ rootField: field, rootSchema: schema }); useSubTableSpecialCase({ rootField: field, rootSchema: schema });
@ -218,7 +218,7 @@ export const SubTable: any = observer(
}, },
}; };
}; };
console.log(props);
return ( return (
<div className={subTableContainer}> <div className={subTableContainer}>
<FlagProvider isInSubTable> <FlagProvider isInSubTable>
@ -252,6 +252,7 @@ export const SubTable: any = observer(
locale={{ locale={{
emptyText: <span> {field.editable ? t('Please add or select record') : t('No data')}</span>, emptyText: <span> {field.editable ? t('Please add or select record') : t('No data')}</span>,
}} }}
enableIndexÏColumn={enableIndexÏColumn !== false}
/> />
{field.editable && ( {field.editable && (
<Space <Space

View File

@ -679,6 +679,7 @@ export const Table: any = withDynamicSchemaProps(
onExpand, onExpand,
loading, loading,
onClickRow, onClickRow,
enableIndexÏColumn,
...others ...others
} = { ...others1, ...others2 } as any; } = { ...others1, ...others2 } as any;
const field = useArrayField(others); const field = useArrayField(others);
@ -831,65 +832,67 @@ export const Table: any = withDynamicSchemaProps(
const restProps = useMemo( const restProps = useMemo(
() => ({ () => ({
rowSelection: memoizedRowSelection rowSelection: enableIndexÏColumn
? { ? memoizedRowSelection
type: 'checkbox', ? {
selectedRowKeys: selectedRowKeys, type: 'checkbox',
onChange(selectedRowKeys: any[], selectedRows: any[]) { selectedRowKeys: selectedRowKeys,
field.data = field.data || {}; onChange(selectedRowKeys: any[], selectedRows: any[]) {
field.data.selectedRowKeys = selectedRowKeys; field.data = field.data || {};
field.data.selectedRowData = selectedRows; field.data.selectedRowKeys = selectedRowKeys;
setSelectedRowKeys(selectedRowKeys); field.data.selectedRowData = selectedRows;
onRowSelectionChange?.(selectedRowKeys, selectedRows); setSelectedRowKeys(selectedRowKeys);
}, onRowSelectionChange?.(selectedRowKeys, selectedRows);
getCheckboxProps(record) { },
return { getCheckboxProps(record) {
'aria-label': `checkbox`, return {
}; 'aria-label': `checkbox`,
}, };
renderCell: (checked, record, index, originNode) => { },
if (!dragSort && !showIndex) { renderCell: (checked, record, index, originNode) => {
return originNode; if (!dragSort && !showIndex) {
} return originNode;
const current = paginationProps?.current; }
const current = paginationProps?.current;
const pageSize = paginationProps?.pageSize || 20; const pageSize = paginationProps?.pageSize || 20;
if (current) { if (current) {
index = index + (current - 1) * pageSize + 1; index = index + (current - 1) * pageSize + 1;
} else { } else {
index = index + 1; index = index + 1;
} }
if (record.__index) { if (record.__index) {
index = extractIndex(record.__index); index = extractIndex(record.__index);
} }
return ( return (
<div <div
role="button" role="button"
aria-label={`table-index-${index}`} aria-label={`table-index-${index}`}
className={classNames(checked ? 'checked' : null, rowSelectCheckboxWrapperClass, { className={classNames(checked ? 'checked' : null, rowSelectCheckboxWrapperClass, {
[rowSelectCheckboxWrapperClassHover]: isRowSelect, [rowSelectCheckboxWrapperClassHover]: isRowSelect,
})} })}
> >
<div className={classNames(checked ? 'checked' : null, rowSelectCheckboxContentClass)}> <div className={classNames(checked ? 'checked' : null, rowSelectCheckboxContentClass)}>
{dragSort && <SortHandle id={getRowKey(record)} />} {dragSort && <SortHandle id={getRowKey(record)} />}
{showIndex && <TableIndex index={index} />} {showIndex && <TableIndex index={index} />}
</div>
{isRowSelect && (
<div
className={classNames(
'nb-origin-node',
checked ? 'checked' : null,
rowSelectCheckboxCheckedClassHover,
)}
>
{originNode}
</div> </div>
)} {isRowSelect && (
</div> <div
); className={classNames(
}, 'nb-origin-node',
...memoizedRowSelection, checked ? 'checked' : null,
} rowSelectCheckboxCheckedClassHover,
)}
>
{originNode}
</div>
)}
</div>
);
},
...memoizedRowSelection,
}
: undefined
: undefined, : undefined,
}), }),
[ [
@ -903,6 +906,7 @@ export const Table: any = withDynamicSchemaProps(
isRowSelect, isRowSelect,
memoizedRowSelection, memoizedRowSelection,
paginationProps, paginationProps,
enableIndexÏColumn,
], ],
); );

View File

@ -851,7 +851,7 @@ export const Table: any = withDynamicSchemaProps(
const collection = useCollection(); const collection = useCollection();
const isTableSelector = schema?.parent?.['x-decorator'] === 'TableSelectorProvider'; const isTableSelector = schema?.parent?.['x-decorator'] === 'TableSelectorProvider';
const ctx = isTableSelector ? useTableSelectorContext() : useTableBlockContext(); const ctx = isTableSelector ? useTableSelectorContext() : useTableBlockContext();
const { expandFlag, allIncludesChildren } = ctx; const { expandFlag, allIncludesChildren, enableIndexÏColumn } = ctx;
const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => {})); const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => {}));
const paginationProps = usePaginationProps(pagination1, pagination2, props); const paginationProps = usePaginationProps(pagination1, pagination2, props);
const columns = useTableColumns(others, paginationProps); const columns = useTableColumns(others, paginationProps);
@ -1016,73 +1016,76 @@ export const Table: any = withDynamicSchemaProps(
const restProps = useMemo( const restProps = useMemo(
() => ({ () => ({
rowSelection: memoizedRowSelection rowSelection:
? { enableIndexÏColumn !== false
type: 'checkbox', ? memoizedRowSelection
selectedRowKeys: selectedRowKeys, ? {
onChange(selectedRowKeys: any[], selectedRows: any[]) { type: 'checkbox',
field.data = field.data || {}; selectedRowKeys: selectedRowKeys,
field.data.selectedRowKeys = selectedRowKeys; onChange(selectedRowKeys: any[], selectedRows: any[]) {
field.data.selectedRowData = selectedRows; field.data = field.data || {};
setSelectedRowKeys(selectedRowKeys); field.data.selectedRowKeys = selectedRowKeys;
onRowSelectionChange?.(selectedRowKeys, selectedRows, setSelectedRowKeys); field.data.selectedRowData = selectedRows;
}, setSelectedRowKeys(selectedRowKeys);
onSelect: (record, selected: boolean, selectedRows, nativeEvent) => { onRowSelectionChange?.(selectedRowKeys, selectedRows, setSelectedRowKeys);
if (tableBlockContextBasicValue) { },
tableBlockContextBasicValue.field.data = tableBlockContextBasicValue.field?.data || {}; onSelect: (record, selected: boolean, selectedRows, nativeEvent) => {
tableBlockContextBasicValue.field.data.selectedRecord = record; if (tableBlockContextBasicValue) {
tableBlockContextBasicValue.field.data.selected = selected; tableBlockContextBasicValue.field.data = tableBlockContextBasicValue.field?.data || {};
} tableBlockContextBasicValue.field.data.selectedRecord = record;
}, tableBlockContextBasicValue.field.data.selected = selected;
getCheckboxProps(record) { }
return { },
'aria-label': `checkbox`, getCheckboxProps(record) {
}; return {
}, 'aria-label': `checkbox`,
renderCell: (checked, record, index, originNode) => { };
if (!dragSort && !showIndex) { },
return originNode; renderCell: (checked, record, index, originNode) => {
} if (!dragSort && !showIndex) {
const current = paginationProps?.current; return originNode;
}
const current = paginationProps?.current;
const pageSize = paginationProps?.pageSize || 20; const pageSize = paginationProps?.pageSize || 20;
if (current) { if (current) {
index = index + (current - 1) * pageSize + 1; index = index + (current - 1) * pageSize + 1;
} else { } else {
index = index + 1; index = index + 1;
} }
if (record.__index) { if (record.__index) {
index = extractIndex(record.__index); index = extractIndex(record.__index);
} }
return ( return (
<div
role="button"
aria-label={`table-index-${index}`}
className={classNames(checked ? 'checked' : null, rowSelectCheckboxWrapperClass, {
[rowSelectCheckboxWrapperClassHover]: isRowSelect,
})}
>
<div className={classNames(checked ? 'checked' : null, rowSelectCheckboxContentClass)}>
{dragSort && <SortHandle id={getRowKey(record)} />}
{showIndex && <TableIndex index={index} />}
</div>
{isRowSelect && (
<div <div
className={classNames( role="button"
'nb-origin-node', aria-label={`table-index-${index}`}
checked ? 'checked' : null, className={classNames(checked ? 'checked' : null, rowSelectCheckboxWrapperClass, {
rowSelectCheckboxCheckedClassHover, [rowSelectCheckboxWrapperClassHover]: isRowSelect,
)} })}
> >
{originNode} <div className={classNames(checked ? 'checked' : null, rowSelectCheckboxContentClass)}>
{dragSort && <SortHandle id={getRowKey(record)} />}
{showIndex && <TableIndex index={index} />}
</div>
{isRowSelect && (
<div
className={classNames(
'nb-origin-node',
checked ? 'checked' : null,
rowSelectCheckboxCheckedClassHover,
)}
>
{originNode}
</div>
)}
</div> </div>
)} );
</div> },
); ...memoizedRowSelection,
}, }
...memoizedRowSelection, : undefined
} : undefined,
: undefined,
}), }),
[ [
memoizedRowSelection, memoizedRowSelection,
@ -1096,6 +1099,7 @@ export const Table: any = withDynamicSchemaProps(
memoizedRowSelection, memoizedRowSelection,
paginationProps, paginationProps,
tableBlockContextBasicValue, tableBlockContextBasicValue,
enableIndexÏColumn,
], ],
); );

View File

@ -176,6 +176,21 @@ export const TableBlockDesigner = () => {
}); });
}} }}
/> />
<SchemaSettingsSwitchItem
title={t('Enable index column')}
checked={field.decoratorProps?.enableSelectColumn !== false}
onChange={async (enableIndexÏColumn) => {
field.decoratorProps = field.decoratorProps || {};
field.decoratorProps.enableIndexÏColumn = enableIndexÏColumn;
fieldSchema['x-decorator-props'].enableIndexÏColumn = enableIndexÏColumn;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-decorator-props': fieldSchema['x-decorator-props'],
},
});
}}
/>
{field.decoratorProps.dragSort && <EditSortField />} {field.decoratorProps.dragSort && <EditSortField />}
<SchemaSettingsDataScope <SchemaSettingsDataScope
collectionName={name} collectionName={name}

View File

@ -72,6 +72,10 @@ describe('Table.settings', () => {
expect(screen.queryByText('Drag and drop sorting field')).not.toBeInTheDocument(); expect(screen.queryByText('Drag and drop sorting field')).not.toBeInTheDocument();
}, },
}, },
{
title: 'Enable index column',
type: 'switch',
},
// { // {
// title: 'Fix block', // title: 'Fix block',
// type: 'switch', // type: 'switch',