mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 22:49:26 +08:00
142 lines
3.6 KiB
TypeScript
142 lines
3.6 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import { ArrayField, Field } from '@formily/core';
|
|
import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react';
|
|
import { Table, TableColumnProps } from 'antd';
|
|
import cls from 'classnames';
|
|
import React, { useState } from 'react';
|
|
import { DndContext } from '../..';
|
|
import { RecordIndexProvider, RecordProvider, useRequest, useSchemaInitializer } from '../../../';
|
|
|
|
const isColumnComponent = (schema: Schema) => {
|
|
return schema['x-component']?.endsWith('.Column') > -1;
|
|
};
|
|
|
|
const useTableColumns = () => {
|
|
const field = useField<ArrayField>();
|
|
const schema = useFieldSchema();
|
|
const { exists, render } = useSchemaInitializer(schema['x-initializer']);
|
|
const columns = schema
|
|
.reduceProperties((buf, s) => {
|
|
if (isColumnComponent(s)) {
|
|
return buf.concat([s]);
|
|
}
|
|
}, [])
|
|
.map((s: Schema) => {
|
|
return {
|
|
title: <RecursionField name={s.name} schema={s} onlyRenderSelf />,
|
|
dataIndex: s.name,
|
|
key: s.name,
|
|
render: (v, record) => {
|
|
const index = field.value?.indexOf(record);
|
|
return (
|
|
<RecordIndexProvider index={index}>
|
|
<RecordProvider record={record}>
|
|
<RecursionField schema={s} name={index} onlyRenderProperties />
|
|
</RecordProvider>
|
|
</RecordIndexProvider>
|
|
);
|
|
},
|
|
} as TableColumnProps<any>;
|
|
});
|
|
console.log(columns);
|
|
if (!exists) {
|
|
return columns;
|
|
}
|
|
return columns.concat({
|
|
title: render(),
|
|
dataIndex: 'TABLE_COLUMN_INITIALIZER',
|
|
key: 'TABLE_COLUMN_INITIALIZER',
|
|
});
|
|
};
|
|
|
|
export const components = {
|
|
header: {
|
|
wrapper: (props) => {
|
|
return (
|
|
<DndContext>
|
|
<thead {...props} />
|
|
</DndContext>
|
|
);
|
|
},
|
|
cell: (props) => {
|
|
return (
|
|
<th
|
|
{...props}
|
|
className={cls(
|
|
props.className,
|
|
css`
|
|
&:hover .general-schema-designer {
|
|
display: block;
|
|
}
|
|
`,
|
|
)}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
body: {
|
|
wrapper: (props) => {
|
|
return (
|
|
<DndContext>
|
|
<tbody {...props} />
|
|
</DndContext>
|
|
);
|
|
},
|
|
},
|
|
};
|
|
|
|
const useDef = () => {
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
|
return [selectedRowKeys, setSelectedRowKeys];
|
|
};
|
|
|
|
const useDefDataSource = (options, props) => {
|
|
const field = useField<Field>();
|
|
return useRequest(() => {
|
|
return Promise.resolve({
|
|
data: field.value,
|
|
});
|
|
}, options);
|
|
};
|
|
|
|
export const TableArray: React.FC<any> = observer((props) => {
|
|
const field = useField<ArrayField>();
|
|
const columns = useTableColumns();
|
|
const { useSelectedRowKeys = useDef, useDataSource = useDefDataSource, onChange, ...others } = props;
|
|
const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys();
|
|
useDataSource({
|
|
onSuccess(data) {
|
|
field.value = data?.data || [];
|
|
},
|
|
});
|
|
const restProps = {
|
|
rowSelection: props.rowSelection
|
|
? {
|
|
type: 'checkbox',
|
|
selectedRowKeys,
|
|
onChange(selectedRowKeys: any[]) {
|
|
setSelectedRowKeys(selectedRowKeys);
|
|
},
|
|
...props.rowSelection,
|
|
}
|
|
: undefined,
|
|
};
|
|
|
|
const defaultRowKey = (record: any) => {
|
|
return field.value?.indexOf?.(record);
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<Table
|
|
rowKey={defaultRowKey}
|
|
{...others}
|
|
{...restProps}
|
|
components={components}
|
|
columns={columns}
|
|
dataSource={field?.value?.slice?.()}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|