diff --git a/packages/client/src/components/admin-layout/datatable.tsx b/packages/client/src/components/admin-layout/datatable.tsx
index c74b9a9f7..2902a304e 100644
--- a/packages/client/src/components/admin-layout/datatable.tsx
+++ b/packages/client/src/components/admin-layout/datatable.tsx
@@ -3,8 +3,10 @@ import React from 'react';
import { FormItem } from '@formily/antd';
import { action } from '@formily/reactive';
import { useCollectionsContext } from '../../constate/Collections';
+import { Field } from '@formily/core';
export const useAsyncDataSource = (service: any) => (field: any) => {
+ console.log('loadCollectionFields');
field.loading = true;
service(field).then(
action.bound((data: any) => {
@@ -24,6 +26,22 @@ export default () => {
}));
};
+ const loadCollectionFields = async (field: Field) => {
+ const target = field.query('....target').get('value');
+ const f = field.query('....target').take();
+ console.log('loadCollectionFields', f, field);
+ const collection = collections?.find((item) => item.name === target);
+ if (!collection) {
+ return [];
+ }
+ return collection?.generalFields
+ ?.filter((item) => item?.uiSchema?.title)
+ ?.map((item) => ({
+ label: item?.uiSchema?.title || item.name,
+ value: item.name,
+ }));
+ };
+
const schema = {
type: 'array',
name: 'collections',
@@ -56,7 +74,7 @@ export default () => {
};
return (
diff --git a/packages/client/src/constate/Collections.ts b/packages/client/src/constate/Collections.ts
index bb952e049..512e2c468 100644
--- a/packages/client/src/constate/Collections.ts
+++ b/packages/client/src/constate/Collections.ts
@@ -6,9 +6,14 @@ const [CollectionsProvider, useCollectionsContext] = constate(() => {
formatResult: (result) => result?.data,
});
return {
- ...result, collections: result.data || [], findCollection(name) {
+ ...result, collections: result.data || [],
+ findCollection(name) {
return result?.data?.find((item) => item.name === name);
- }
+ },
+ getFieldsByCollection(collectionName) {
+ const collection = result?.data?.find((item) => item.name === collectionName);
+ return collection?.generalFields;
+ },
};
});
diff --git a/packages/client/src/schemas/add-new/index.tsx b/packages/client/src/schemas/add-new/index.tsx
index 654def2cc..6135815a0 100644
--- a/packages/client/src/schemas/add-new/index.tsx
+++ b/packages/client/src/schemas/add-new/index.tsx
@@ -1437,12 +1437,13 @@ AddNew.FormItem = observer((props: any) => {
default: [],
'x-component-props': {
rowKey: 'id',
- defaultSelectedRowKeys:
- '{{ Select.useSelectedRowKeys() }}',
+ useSelectedRowKeys:
+ '{{ Select.useSelectedRowKeys }}',
onSelect: '{{ Select.useSelect() }}',
+ useRowSelection: '{{ Select.useRowSelection }}',
collectionName: field.target,
// dragSort: true,
- showIndex: true,
+ // showIndex: true,
refreshRequestOnChange: true,
pagination: {
pageSize: 10,
diff --git a/packages/client/src/schemas/form/Field.DesignableBar.tsx b/packages/client/src/schemas/form/Field.DesignableBar.tsx
index 933b92917..04f21463c 100644
--- a/packages/client/src/schemas/form/Field.DesignableBar.tsx
+++ b/packages/client/src/schemas/form/Field.DesignableBar.tsx
@@ -20,7 +20,7 @@ import {
updateSchema,
} from '../';
import get from 'lodash/get';
-import { Button, Dropdown, Menu, Modal, Space, Switch } from 'antd';
+import { Button, Dropdown, Menu, Modal, Select, Space, Switch } from 'antd';
import { MenuOutlined, DragOutlined } from '@ant-design/icons';
import cls from 'classnames';
import { FormDialog, FormLayout } from '@formily/antd';
@@ -33,19 +33,25 @@ import { useEffect } from 'react';
import { uid } from '@formily/shared';
import { getSchemaPath } from '../../components/schema-renderer';
import { RandomNameContext } from '.';
-import { useCollectionContext, useDisplayedMapContext } from '../../constate';
+import {
+ useCollectionContext,
+ useCollectionsContext,
+ useDisplayedMapContext,
+} from '../../constate';
import SwitchMenuItem from '../../components/SwitchMenuItem';
import { DragHandle } from '../../components/Sortable';
+import { set } from 'lodash';
export const FieldDesignableBar = observer((props) => {
const field = useField();
- const { schema, deepRemove } = useDesignable();
+ const { schema, deepRemove, refresh } = useDesignable();
const [visible, setVisible] = useState(false);
const { dragRef } = useContext(DraggableBlockContext);
const randomName = useContext(RandomNameContext);
const displayed = useDisplayedMapContext();
const fieldName = schema['x-component-props']?.['fieldName'];
const { getField } = useCollectionContext();
+ const { getFieldsByCollection } = useCollectionsContext();
const collectionField = getField(fieldName);
@@ -124,6 +130,59 @@ export const FieldDesignableBar = observer((props) => {
>
自定义字段名称
+ {collectionField.interface === 'linkTo' && (
+
+
+ 标签字段{' '}
+
+
+ )}
{
diff --git a/packages/client/src/schemas/form/index.tsx b/packages/client/src/schemas/form/index.tsx
index 8debd27cd..57c214eda 100644
--- a/packages/client/src/schemas/form/index.tsx
+++ b/packages/client/src/schemas/form/index.tsx
@@ -29,7 +29,7 @@ import { DraggableBlockContext } from '../../components/drag-and-drop';
import { isGridRowOrCol } from '../grid';
import constate from 'constate';
import { useEffect } from 'react';
-import { uid } from '@formily/shared';
+import { uid, merge } from '@formily/shared';
import { getSchemaPath } from '../../components/schema-renderer';
import { DesignableBar } from './DesignableBar';
import { FieldDesignableBar } from './Field.DesignableBar';
@@ -183,7 +183,15 @@ Form.Field = observer((props: any) => {
const required = schema['required'] || collectionField?.uiSchema?.required;
const description =
schema['description'] || collectionField?.uiSchema?.description;
- console.log('schema.properties', schema.properties)
+ console.log('schema.properties', schema.properties);
+
+ const componentProps = merge(
+ collectionField?.uiSchema?.['x-component-props'] || {},
+ schema?.['x-component-props'] || {},
+ {
+ arrayMerge: (t, s) => s,
+ },
+ );
return (
{
required,
description,
'x-decorator': 'FormilyFormItem',
+ 'x-component-props': componentProps,
properties: {
...schema.properties,
},
diff --git a/packages/client/src/schemas/select/index.tsx b/packages/client/src/schemas/select/index.tsx
index e7e510efa..3075e1c8c 100644
--- a/packages/client/src/schemas/select/index.tsx
+++ b/packages/client/src/schemas/select/index.tsx
@@ -18,7 +18,7 @@ import { useState } from 'react';
import { useDesignable } from '../';
import { createContext } from 'react';
import { useContext } from 'react';
-import { isEmpty } from 'lodash';
+import { get, isEmpty } from 'lodash';
import { Field, isArrayField, isField } from '@formily/core';
import { Action } from '../action';
import { BlockSchemaContext, VisibleContext } from '../../context';
@@ -28,6 +28,7 @@ import { CollectionFieldContext } from '../table';
import { CollectionProvider, useCollectionContext } from '../../constate';
import { Resource } from '../../resource';
import { useRequest } from 'ahooks';
+import constate from 'constate';
export const Select: any = connect(
(props) => {
@@ -236,11 +237,11 @@ Select.Object = connect(
const OptionTagContext = createContext(null);
-const SelectedRowKeysContext = createContext([]);
+const SelectedRowsContext = createContext(null);
Select.useOkAction = () => {
const { props } = useContext(SelectContext);
- const [selectedRows] = useContext(SelectedRowKeysContext);
+ const { selectedRows } = useContext(SelectedRowsContext);
return {
async run() {
props.onChange(selectedRows);
@@ -249,38 +250,63 @@ Select.useOkAction = () => {
};
};
+Select.useRowSelection = () => {
+ const { props } = useContext(SelectContext);
+ return {
+ type: props.multiple ? 'checkbox' : 'radio',
+ };
+};
+
Select.useSelect = () => {
- const [, setSelectedRows] = useContext(SelectedRowKeysContext);
+ const { setSelectedRows } = useContext(SelectedRowsContext);
return (keys, rows) => {
setSelectedRows(rows);
console.log('Select.onSelect', keys, rows);
};
};
-Select.useSelectedRowKeys = () => {
- const [selectedRows] = useContext(SelectedRowKeysContext);
- return selectedRows?.map((row) => row.id) || [];
+export const useSelectedRowKeys = () => {
+ const { selectedRows } = useContext(SelectedRowsContext);
+ const [selectedRowKeys, setSelectedRowKeys] = useState([]);
+ useEffect(() => {
+ setSelectedRowKeys(selectedRows.map((row) => row.id));
+ }, [selectedRows]);
+ return { selectedRowKeys, setSelectedRowKeys };
};
+Select.useSelectedRowKeys = useSelectedRowKeys;
+
const SelectContext = createContext(null);
Select.Drawer = connect(
(props) => {
const field = useField();
const {
- value,
onChange,
- fieldNames = {
- label: 'id',
- value: 'id',
- },
+ // fieldNames = {
+ // label: 'id',
+ // value: 'id',
+ // },
...others
} = props;
+ let value = props.value;
const [visible, setVisible] = useState(false);
const { schema } = useDesignable();
+ const fieldNames = {
+ label: 'id',
+ value: 'id',
+ ...(get(schema['x-component-props'], 'fieldNames') || {}),
+ };
const options = field?.['dataSource'] || props.options || [];
-
+ if (props.multiple) {
+ Object.assign(others, {
+ mode: 'multiple',
+ });
+ }
let optionValue = undefined;
+ if (props.multiple) {
+ value = toArr(value);
+ }
if (isArr(value)) {
optionValue = value.map((val) => {
return {
@@ -294,6 +320,7 @@ Select.Drawer = connect(
value: value[fieldNames.value],
};
}
+ const [selectedRows, setSelectedRows] = useState(toArr(field.value));
const onFieldChange = (selectValue) => {
if (!isValid(selectValue)) {
@@ -323,9 +350,9 @@ Select.Drawer = connect(
options.find((option) => option[fieldNames.value] === selectValue),
);
}
+ setSelectedRows(toArr(field.value));
};
// const selectedKeys = toArr(optionValue).map((item) => item.value);
- const [selectedRows, setSelectedRows] = useState(toArr(field.value));
console.log({ optionValue, value });
const collectionField = useContext(CollectionFieldContext);
return (
@@ -352,8 +379,8 @@ Select.Drawer = connect(
}
}}
>
-
-
+
);
@@ -391,9 +418,14 @@ Select.Drawer = connect(
observer((props: any) => {
const collectionField = useContext(CollectionFieldContext);
const field = useField();
- const { fieldNames = { label: 'id' }, ...others } = props;
+ const { ...others } = props;
const value = field.value || field.initialValue;
const { schema } = useDesignable();
+ const fieldNames = {
+ label: 'id',
+ value: 'id',
+ ...(get(schema['x-component-props'], 'fieldNames') || {}),
+ };
console.log({ fieldNames, field, value });
if (!value) {
return null;
@@ -437,7 +469,7 @@ Select.Drawer.useResource = ({ onSuccess }) => {
resourceName: collection?.name,
resourceKey: ctx.data.id,
});
- console.log('OptionTagContext', ctx.data.id)
+ console.log('OptionTagContext', ctx.data.id);
const { schema } = useDesignable();
const fieldFields = (schema: Schema) => {
const names = [];
@@ -473,7 +505,7 @@ Select.Drawer.useResource = ({ onSuccess }) => {
}
}, [visible]);
return { resource, service, initialValues: service.data, ...service };
-}
+};
Select.Options = observer((props) => {
return <>{props.children}>;
diff --git a/packages/client/src/schemas/table/index.tsx b/packages/client/src/schemas/table/index.tsx
index 338ab32f8..df89605be 100644
--- a/packages/client/src/schemas/table/index.tsx
+++ b/packages/client/src/schemas/table/index.tsx
@@ -19,7 +19,7 @@ import {
createCollectionField,
ISchema,
} from '..';
-import { uid } from '@formily/shared';
+import { uid, merge } from '@formily/shared';
import useRequest from '@ahooksjs/use-request';
import { BaseResult } from '@ahooksjs/use-request/lib/types';
import cls from 'classnames';
@@ -30,7 +30,6 @@ import {
useSortable,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
-import { CSS } from '@dnd-kit/utilities';
import { Select, Dropdown, Menu, Switch, Button, Space } from 'antd';
import { PlusOutlined, SettingOutlined } from '@ant-design/icons';
import './style.less';
@@ -54,6 +53,7 @@ import {
DisplayedMapProvider,
useCollection,
useCollectionContext,
+ useCollectionsContext,
useDisplayedMapContext,
} from '../../constate';
import { useResource as useGeneralResource } from '../../hooks/useResource';
@@ -140,7 +140,7 @@ function useTableCreateAction() {
const form = useForm();
return {
async run() {
- console.log('useTableCreateAction', resource)
+ console.log('useTableCreateAction', resource);
if (refreshRequestOnChange) {
await resource.create(form.values);
await form.reset();
@@ -457,11 +457,13 @@ function AddColumn() {
default: [],
'x-component-props': {
rowKey: 'id',
- defaultSelectedRowKeys: '{{ Select.useSelectedRowKeys() }}',
+ useRowSelection: '{{ Select.useRowSelection }}',
+ useSelectedRowKeys:
+ '{{ Select.useSelectedRowKeys }}',
onSelect: '{{ Select.useSelect() }}',
collectionName: field.target,
// dragSort: true,
- showIndex: true,
+ // showIndex: true,
refreshRequestOnChange: true,
pagination: {
pageSize: 10,
@@ -634,6 +636,12 @@ function AddColumn() {
);
}
+const useDefaultRowSelection = () => {
+ return {
+ type: 'checkbox',
+ };
+};
+
const useDataSource = () => {
const {
pagination,
@@ -657,13 +665,20 @@ const TableMain = () => {
setSelectedRowKeys,
service,
field,
- props: { rowKey, dragSort, showIndex, onSelect },
+ props: {
+ rowKey,
+ dragSort,
+ showIndex,
+ onSelect,
+ useRowSelection = useDefaultRowSelection,
+ },
refresh,
} = useTable();
const columns = useTableColumns();
const dataSource = useDataSource();
const actionBars = useTableActionBars();
const [html, setHtml] = useState('');
+ const { type } = useRowSelection();
return (
{
},
}}
rowSelection={{
- type: 'checkbox',
+ type: type || 'checkbox',
selectedRowKeys,
onChange: (rowKeys, rows) => {
setSelectedRowKeys(rowKeys);
@@ -815,20 +830,25 @@ const usePagination = () => {
];
};
+const useDefaultSelectedRowKeys = () => {
+ const [selectedRowKeys, setSelectedRowKeys] = useState([]);
+ return { selectedRowKeys, setSelectedRowKeys };
+};
+
const TableProvider = (props: any) => {
const {
rowKey = 'id',
dataRequest,
useResource = useGeneralResource,
defaultSelectedRowKeys,
+ useSelectedRowKeys = useDefaultSelectedRowKeys,
...others
} = props;
const { schema } = useDesignable();
const field = useField();
const [pagination, setPagination] = usePagination();
- const [selectedRowKeys, setSelectedRowKeys] = useState(
- defaultSelectedRowKeys || [],
- );
+ const { selectedRowKeys, setSelectedRowKeys } = useSelectedRowKeys();
+ console.log('props.useSelectedRowKeys', selectedRowKeys);
const [, refresh] = useState(uid());
const { resource } = useResource();
const { sortableField } = useCollectionContext();
@@ -1968,6 +1988,14 @@ Table.Cell = observer((props: any) => {
uiSchema = cloneDeepWith(uiSchema);
set(uiSchema, 'x-component-props.size', 'small');
}
+ const componentProps = merge(
+ uiSchema?.['x-component-props'] || {},
+ schema?.['x-component-props'] || {},
+ {
+ arrayMerge: (t, s) => s,
+ },
+ );
+ console.log('Table.Cell', collectionField?.interface, componentProps);
return (
{
feedbackLayout: 'popover',
},
'x-decorator': 'FormilyFormItem',
+ 'x-component-props': componentProps,
properties: {
...schema?.properties,
},
@@ -2018,10 +2047,12 @@ Table.Column = observer((props: any) => {
Table.Column.DesignableBar = () => {
const field = useField();
+ const { service, refresh: refreshTable } = useTable();
// const fieldSchema = useFieldSchema();
const { schema, remove, refresh, insertAfter } = useDesignable();
const [visible, setVisible] = useState(false);
const displayed = useDisplayedMapContext();
+ const { getFieldsByCollection } = useCollectionsContext();
const collectionField = useContext(CollectionFieldContext);
console.log('displayed.map', displayed.map);
return (
@@ -2088,6 +2119,52 @@ Table.Column.DesignableBar = () => {
>
自定义列名称
+ {collectionField.interface === 'linkTo' && (
+
+
+ 标签字段{' '}
+
+
+ )}
{