Merge pull request #529 from smartxworks/feat/arco-widget

support for automatic generation of `rowKey` or setting from columns
This commit is contained in:
tanbowensg 2022-07-25 13:49:59 +08:00 committed by GitHub
commit 0ea1a9edbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 109 additions and 5 deletions

View File

@ -21,7 +21,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"typings": "tsc --emitDeclarationOnly", "typings": "tsc --emitDeclarationOnly",
"build": "tsup src/index.ts --format cjs,esm,iife --legacy-output --inject ./react-import.js --clean --no-splitting --sourcemap", "build": "tsup src/index.ts src/widgets/index.ts --format cjs,esm,iife --legacy-output --inject ./react-import.js --clean --no-splitting --sourcemap",
"serve": "vite preview", "serve": "vite preview",
"lint": "eslint ./src --ext .ts --ext .tsx", "lint": "eslint ./src --ext .ts --ext .tsx",
"fix-lint": "eslint --fix ./src --ext .ts --ext .tsx", "fix-lint": "eslint --fix ./src --ext .ts --ext .tsx",

View File

@ -74,6 +74,14 @@ const rowClickStyle = css`
export const exampleProperties: Static<typeof TablePropsSpec> = { export const exampleProperties: Static<typeof TablePropsSpec> = {
columns: [ columns: [
{
title: 'Key',
dataIndex: 'key',
type: 'text',
displayValue: '',
filter: false,
componentSlotIndex: 0,
},
{ {
title: 'Name', title: 'Name',
dataIndex: 'name', dataIndex: 'name',
@ -107,11 +115,12 @@ export const exampleProperties: Static<typeof TablePropsSpec> = {
data: Array(13) data: Array(13)
.fill('') .fill('')
.map((_, index) => ({ .map((_, index) => ({
key: `key ${index}`, key: index,
name: `${Math.random() > 0.5 ? 'Kevin Sandra' : 'Naomi Cook'}${index}`, name: `${Math.random() > 0.5 ? 'Kevin Sandra' : 'Naomi Cook'}${index}`,
link: `link${Math.random() > 0.5 ? '-A' : '-B'}`, link: `link${Math.random() > 0.5 ? '-A' : '-B'}`,
salary: Math.floor(Math.random() * 1000), salary: Math.floor(Math.random() * 1000),
})), })),
rowKey: 'key',
checkCrossPage: true, checkCrossPage: true,
pagination: { pagination: {
enablePagination: true, enablePagination: true,
@ -172,8 +181,15 @@ export const Table = implementRuntimeComponent({
} = props; } = props;
const ref = useRef<TableInstance | null>(null); const ref = useRef<TableInstance | null>(null);
const { pagination, rowClick, useDefaultFilter, useDefaultSort, data, ...cProps } = const {
getComponentProps(props); pagination,
rowKey,
rowClick,
useDefaultFilter,
useDefaultSort,
data,
...cProps
} = getComponentProps(props);
const { const {
pageSize, pageSize,
@ -186,6 +202,7 @@ export const Table = implementRuntimeComponent({
} = pagination; } = pagination;
const rowSelectionType = rowSelectionTypeMap[cProps.rowSelectionType]; const rowSelectionType = rowSelectionTypeMap[cProps.rowSelectionType];
const currentChecked = useRef<(string | number)[]>([]);
const [currentPage, setCurrentPage] = useStateValue<number>( const [currentPage, setCurrentPage] = useStateValue<number>(
defaultCurrent ?? 1, defaultCurrent ?? 1,
@ -196,6 +213,7 @@ export const Table = implementRuntimeComponent({
useEffect(() => { useEffect(() => {
mergeState({ pageSize }); mergeState({ pageSize });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
const [sortRule, setSortRule] = useState<SortRule | null>(null); const [sortRule, setSortRule] = useState<SortRule | null>(null);
@ -236,9 +254,29 @@ export const Table = implementRuntimeComponent({
// Otherwise it will automatically paginate on the front end based on the current page // Otherwise it will automatically paginate on the front end based on the current page
return sortedData?.slice(0, pageSize); return sortedData?.slice(0, pageSize);
} }
return sortedData; return sortedData;
}, [pageSize, sortedData, enablePagination, useCustomPagination]); }, [pageSize, sortedData, enablePagination, useCustomPagination]);
// reset state when data changed
useEffect(() => {
if (!currentPageData.length) {
mergeState({
selectedRowKeys: [],
selectedRows: [],
sortRule: {},
filterRule: undefined,
currentPage: undefined,
});
}
mergeState({
selectedRows: currentPageData.filter(d =>
currentChecked.current.includes(d[rowKey])
),
});
}, [currentPageData, mergeState, rowKey]);
useEffect(() => { useEffect(() => {
setColumns( setColumns(
cProps.columns!.map((column, i) => { cProps.columns!.map((column, i) => {
@ -466,6 +504,7 @@ export const Table = implementRuntimeComponent({
return ( return (
<BaseTable <BaseTable
ref={ref} ref={ref}
rowKey={rowKey}
className={css` className={css`
${customStyle?.content} ${customStyle?.content}
${rowClick ? rowClickStyle : ''} ${rowClick ? rowClickStyle : ''}
@ -503,6 +542,7 @@ export const Table = implementRuntimeComponent({
}); });
}, },
onChange(selectedRowKeys, selectedRows) { onChange(selectedRowKeys, selectedRows) {
currentChecked.current = selectedRowKeys;
mergeState({ mergeState({
selectedRowKeys: selectedRowKeys as string[], selectedRowKeys: selectedRowKeys as string[],
selectedRows, selectedRows,

View File

@ -0,0 +1 @@
export const ARCO_V1_VERSION = 'arco/v1';

View File

@ -301,6 +301,13 @@ export const TablePropsSpec = Type.Object({
}, },
weight: 0, weight: 0,
}), }),
rowKey: Type.Any({
title: 'RowKey',
category: Category.Columns,
widget: 'arco/v1/primaryKey',
description:
'This optional is used to select a unique key for any given row from columns.',
}),
tableLayoutFixed: Type.Boolean({ tableLayoutFixed: Type.Boolean({
title: 'Layout Fixed', title: 'Layout Fixed',
description: description:

View File

@ -0,0 +1,49 @@
import React from 'react';
import { WidgetProps, implementWidget } from '@sunmao-ui/editor-sdk';
import { ColumnSpec } from '../generated/types/Table';
import { Static } from '@sinclair/typebox';
import { Select } from '@arco-design/web-react';
import { ARCO_V1_VERSION } from '../constants/widgets';
type TablePrimaryKeyWidget = 'arco/v1/primaryKey';
declare module '@sunmao-ui/editor-sdk' {
interface WidgetOptionsMap {
'arco/v1/primaryKey': Record<string, unknown>;
}
}
export const TablePrimaryKeyWidget: React.FC<
WidgetProps<TablePrimaryKeyWidget, string>
> = props => {
const { value, onChange, component } = props;
const { properties } = component;
const columns = properties.columns as Static<typeof ColumnSpec>[];
const keys = columns.map(c => c.dataIndex);
return (
<Select
value={value}
defaultValue="auto"
onChange={value => {
onChange(value);
}}
>
{keys.map(key => {
return (
<Select.Option key={key} value={key}>
{key}
</Select.Option>
);
})}
</Select>
);
};
export default implementWidget<TablePrimaryKeyWidget>({
version: ARCO_V1_VERSION,
metadata: {
name: 'primaryKey',
},
})(TablePrimaryKeyWidget);

View File

@ -0,0 +1,3 @@
import TablePrimaryKeyWidget from './TablePrimaryKeyWidget';
export const widgets = [TablePrimaryKeyWidget];

View File

@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import { RegistryInterface } from '@sunmao-ui/runtime'; import { RegistryInterface } from '@sunmao-ui/runtime';
import { sunmaoChakraUILib } from '@sunmao-ui/chakra-ui-lib'; import { sunmaoChakraUILib } from '@sunmao-ui/chakra-ui-lib';
import { widgets as chakraWidgets } from '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index'; import { widgets as chakraWidgets } from '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index';
import { widgets as arcoWidgets } from '@sunmao-ui/arco-lib/dist/esm/widgets/index';
import { ArcoDesignLib } from '@sunmao-ui/arco-lib'; import { ArcoDesignLib } from '@sunmao-ui/arco-lib';
import { initSunmaoUIEditor } from './init'; import { initSunmaoUIEditor } from './init';
import { LocalStorageManager } from './LocalStorageManager'; import { LocalStorageManager } from './LocalStorageManager';
@ -17,7 +18,7 @@ type Options = Partial<{
const lsManager = new LocalStorageManager(); const lsManager = new LocalStorageManager();
const { Editor, registry } = initSunmaoUIEditor({ const { Editor, registry } = initSunmaoUIEditor({
widgets: [...chakraWidgets], widgets: [...chakraWidgets, ...arcoWidgets],
storageHandler: { storageHandler: {
onSaveApp(app) { onSaveApp(app) {
lsManager.saveAppInLS(app); lsManager.saveAppInLS(app);

View File

@ -1,3 +1,6 @@
declare module '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index' { declare module '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index' {
export * from '@sunmao-ui/chakra-ui-lib/lib/widgets/index'; export * from '@sunmao-ui/chakra-ui-lib/lib/widgets/index';
} }
declare module '@sunmao-ui/arco-lib/dist/esm/widgets/index' {
export * from '@sunmao-ui/arco-lib/lib/widgets/index';
}