feat: table column support fixed right or fixed left (#4260)

* feat: table column support fixed right or fixed left

* fix: bug

* fix: bug

* fix: bug

* fix: bug
This commit is contained in:
katherinehhh 2024-05-09 10:07:55 +08:00 committed by GitHub
parent 2014729e01
commit 68a0c96fd0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 108 additions and 10 deletions

View File

@ -934,5 +934,9 @@
"Refresh data on action": "执行后刷新数据", "Refresh data on action": "执行后刷新数据",
"This variable has been deprecated and can be replaced with \"Current form\"": "该变量已被弃用,可以使用“当前表单”替代", "This variable has been deprecated and can be replaced with \"Current form\"": "该变量已被弃用,可以使用“当前表单”替代",
"Unknown field type": "未知字段类型", "Unknown field type": "未知字段类型",
"The following field types are not compatible and do not support output and display": "以下字段类型未适配,不支持输出和显示" "The following field types are not compatible and do not support output and display": "以下字段类型未适配,不支持输出和显示",
"Not fixed":"不固定",
"Left fixed":"左固定",
"Right fixed":"右固定",
"Fixed":"固定列"
} }

View File

@ -8,7 +8,7 @@
*/ */
import { MenuOutlined } from '@ant-design/icons'; import { MenuOutlined } from '@ant-design/icons';
import { ISchema, useFieldSchema } from '@formily/react'; import { ISchema, useFieldSchema, useField } from '@formily/react';
import _ from 'lodash'; import _ from 'lodash';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -21,6 +21,7 @@ import { useCollection_deprecated } from '../../../../collection-manager';
import { useDataBlockProps } from '../../../../data-source'; import { useDataBlockProps } from '../../../../data-source';
import { createDesignable, useDesignable } from '../../../../schema-component'; import { createDesignable, useDesignable } from '../../../../schema-component';
import { useGetAriaLabelOfDesigner } from '../../../../schema-settings/hooks/useGetAriaLabelOfDesigner'; import { useGetAriaLabelOfDesigner } from '../../../../schema-settings/hooks/useGetAriaLabelOfDesigner';
import { SelectWithTitle } from '../../../../common/SelectWithTitle';
export const Resizable = () => { export const Resizable = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@ -75,6 +76,42 @@ export const Resizable = () => {
); );
}; };
export const SchemaSettingsFixed = () => {
const field = useField();
const fieldSchema = useFieldSchema();
const { t } = useTranslation();
const { dn } = useDesignable();
const options = [
{ label: t('Not fixed'), value: 'none' },
{ label: t('Left fixed'), value: 'left' },
{ label: t('Right fixed'), value: 'right' },
];
return (
<SchemaInitializerItem>
<SelectWithTitle
key="fixed"
title={t('Fixed')}
options={options}
defaultValue={field.componentProps?.fixed || 'none'}
onChange={(fixed) => {
const schema = {
['x-uid']: fieldSchema['x-uid'],
};
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
fieldSchema['x-component-props']['fixed'] = fixed;
schema['x-component-props'] = fieldSchema['x-component-props'];
field.componentProps = field.componentProps || {};
field.componentProps.fixed = fixed;
void dn.emit('patch', {
schema,
});
dn.refresh();
}}
/>
</SchemaInitializerItem>
);
};
const commonOptions = { const commonOptions = {
insertPosition: 'beforeEnd', insertPosition: 'beforeEnd',
useInsert: function useInsert() { useInsert: function useInsert() {
@ -245,6 +282,12 @@ const commonOptions = {
name: 'divider2', name: 'divider2',
type: 'divider', type: 'divider',
}, },
{
name: 'fixed',
title: 't("Fixed")',
type: 'item',
Component: SchemaSettingsFixed,
},
{ {
type: 'item', type: 'item',
name: 'columnWidth', name: 'columnWidth',

View File

@ -292,6 +292,39 @@ export const tableColumnSettings = new SchemaSettings({
}; };
}, },
}, },
{
name: 'fixed',
type: 'select',
useComponentProps() {
const { t } = useTranslation();
const field = useField();
const fieldSchema = useFieldSchema();
const { dn } = useDesignable();
return {
title: t('Fixed'),
options: [
{ label: t('Not fixed'), value: 'none' },
{ label: t('Left fixed'), value: 'left' },
{ label: t('Right fixed'), value: 'right' },
],
value: field.componentProps?.fixed || 'none',
onChange(fixed) {
const schema = {
['x-uid']: fieldSchema['x-uid'],
};
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
fieldSchema['x-component-props']['fixed'] = fixed;
schema['x-component-props'] = fieldSchema['x-component-props'];
field.componentProps = field.componentProps || {};
field.componentProps.fixed = fixed;
void dn.emit('patch', {
schema,
});
dn.refresh();
},
};
},
},
], ],
}, },
{ {

View File

@ -52,6 +52,23 @@ const useArrayField = (props) => {
function getSchemaArrJSON(schemaArr: Schema[]) { function getSchemaArrJSON(schemaArr: Schema[]) {
return schemaArr.map((item) => (item.name === 'actions' ? omit(item.toJSON(), 'properties') : item.toJSON())); return schemaArr.map((item) => (item.name === 'actions' ? omit(item.toJSON(), 'properties') : item.toJSON()));
} }
function adjustColumnOrder(columns) {
const leftFixedColumns = [];
const normalColumns = [];
const rightFixedColumns = [];
columns.forEach((column) => {
if (column.fixed === 'left') {
leftFixedColumns.push(column);
} else if (column.fixed === 'right') {
rightFixedColumns.push(column);
} else {
normalColumns.push(column);
}
});
return [...leftFixedColumns, ...normalColumns, ...rightFixedColumns];
}
export const useColumnsDeepMemoized = (columns: any[]) => { export const useColumnsDeepMemoized = (columns: any[]) => {
const columnsJSON = getSchemaArrJSON(columns); const columnsJSON = getSchemaArrJSON(columns);
@ -140,15 +157,16 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
if (!exists) { if (!exists) {
return columns; return columns;
} }
const res = [ const res = [...columns];
...columns, if (designable) {
{ res.push({
title: render(), title: render(),
dataIndex: 'TABLE_COLUMN_INITIALIZER', dataIndex: 'TABLE_COLUMN_INITIALIZER',
key: 'TABLE_COLUMN_INITIALIZER', key: 'TABLE_COLUMN_INITIALIZER',
render: designable ? () => <div style={{ minWidth: 300 }} /> : null, render: () => <div style={{ minWidth: 180 }} />,
}, fixed: 'right',
]; });
}
if (props.showDel) { if (props.showDel) {
res.push({ res.push({
title: '', title: '',
@ -177,7 +195,7 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
}); });
} }
return res; return adjustColumnOrder(res);
}, [columns, exists, field, render, props.showDel, designable]); }, [columns, exists, field, render, props.showDel, designable]);
return tableColumns; return tableColumns;
@ -517,7 +535,7 @@ export const Table: any = withDynamicSchemaProps(
return ( return (
<td {...props} ref={ref} className={classNames(props.className, cellClass)}> <td {...props} ref={ref} className={classNames(props.className, cellClass)}>
{inView || isIndex ? props.children : <Skeleton.Button />} {inView || isIndex ? props.children : <Skeleton.Button style={{ height: '100%' }} />}
</td> </td>
); );
}, },