feat(client): improve linkTo field Initializer

This commit is contained in:
chenos 2022-03-02 13:22:30 +08:00
parent 86065fa208
commit 9db654047a
11 changed files with 285 additions and 32 deletions

View File

@ -39,12 +39,12 @@ export const useCollectionFilterOptions = (collectionName: string) => {
operators: fieldInterface.operators || [], operators: fieldInterface.operators || [],
}; };
return option; return option;
} };
fields.forEach(field => { fields.forEach((field) => {
options.push(field2option(field)); options.push(field2option(field));
}); });
return options; return options;
} };
export const useFilterDataSource = (options) => { export const useFilterDataSource = (options) => {
const { name } = useCollection(); const { name } = useCollection();
@ -56,17 +56,20 @@ export const useFilterDataSource = (options) => {
}), }),
options, options,
); );
} };
export const useFilterAction = () => { export const useFilterAction = () => {
const { run, params } = useResourceActionContext();
const form = useForm(); const form = useForm();
const ctx = useActionContext(); const ctx = useActionContext();
const [first, ...others] = params;
return { return {
async run() { async run() {
run({ ...first, filter: form.values.filter }, ...others);
ctx.setVisible(false); ctx.setVisible(false);
}, },
}; };
} };
export const useCreateAction = () => { export const useCreateAction = () => {
const form = useForm(); const form = useForm();

View File

@ -14,6 +14,7 @@ export const chinaRegion: IField = {
type: 'belongsToMany', type: 'belongsToMany',
target: 'chinaRegions', target: 'chinaRegions',
targetKey: 'code', targetKey: 'code',
sortBy: 'level',
// name, // name,
uiSchema: { uiSchema: {
type: 'array', type: 'array',

View File

@ -13,10 +13,16 @@ export const linkTo: IField = {
type: 'belongsToMany', type: 'belongsToMany',
// name, // name,
uiSchema: { uiSchema: {
type: 'array',
// title, // title,
'x-component': 'RecordPicker', 'x-component': 'RecordPicker',
'x-component-props': {}, 'x-component-props': {
// mode: 'tags',
multiple: true,
fieldNames: {
label: 'id',
value: 'id',
},
},
}, },
}, },
initialize: (values: any) => { initialize: (values: any) => {

View File

@ -24,6 +24,7 @@
"Icon": "图标", "Icon": "图标",
"Group": "分组", "Group": "分组",
"Link": "链接", "Link": "链接",
"Save conditions": "保存筛选条件",
"Edit menu item": "编辑菜单项", "Edit menu item": "编辑菜单项",
"Move to": "移动到", "Move to": "移动到",
"Insert left": "在左边插入", "Insert left": "在左边插入",

View File

@ -7,9 +7,12 @@ import { useDesignable } from '../../hooks';
export const SaveDefaultValue = (props) => { export const SaveDefaultValue = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { dn, refresh } = useDesignable(); const { designable, dn, refresh } = useDesignable();
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const form = useForm(); const form = useForm();
if (!designable) {
return null;
}
return ( return (
<Button <Button
className={css` className={css`

View File

@ -19,23 +19,26 @@ import { useTranslation } from 'react-i18next';
import { useAttach } from '../../hooks/useAttach'; import { useAttach } from '../../hooks/useAttach';
import { ActionContext, useActionContext } from '../action'; import { ActionContext, useActionContext } from '../action';
const findRowSelection = (fieldSchema) => {
return fieldSchema.reduceProperties((buf, s) => {
if (s['x-component'] === 'Table.RowSelection') {
return s;
}
const r = findRowSelection(s);
if (r) {
return r;
}
return buf;
}, null);
};
const InputRecordPicker: React.FC<any> = (props) => { const InputRecordPicker: React.FC<any> = (props) => {
const { onChange } = props; const { multiple, onChange } = props;
const fieldNames = { label: 'label', value: 'value', ...props.fieldNames }; const fieldNames = { label: 'label', value: 'value', ...props.fieldNames };
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const field = useField<Field>(); const field = useField<Field>();
const s = fieldSchema.reduceProperties((buf, s) => { const s = findRowSelection(fieldSchema);
if (s['x-component'] === 'RecordPicker.Options') {
return s.reduceProperties((buf, s) => {
if (s['x-component'] === 'Table.RowSelection') {
return s;
}
return buf;
}, null);
}
return buf;
}, null);
const [value, setValue] = useState(field.value); const [value, setValue] = useState(field.value);
const form = useMemo( const form = useMemo(
() => () =>
@ -76,7 +79,7 @@ const InputRecordPicker: React.FC<any> = (props) => {
<div> <div>
<Select <Select
size={props.size} size={props.size}
mode={props.mode} mode={multiple ? 'multiple' : props.mode}
fieldNames={fieldNames} fieldNames={fieldNames}
onClick={() => { onClick={() => {
setVisible(true); setVisible(true);

View File

@ -17,7 +17,6 @@ Schema.silent(true);
const Registry = { const Registry = {
silent: true, silent: true,
compile(expression: string, scope = {}) { compile(expression: string, scope = {}) {
console.log('expression', expression);
if (Registry.silent) { if (Registry.silent) {
try { try {
return new Function('$root', `with($root) { return (${expression}); }`)(scope); return new Function('$root', `with($root) { return (${expression}); }`)(scope);

View File

@ -23,7 +23,9 @@ const schema = {
properties: { properties: {
filter: { filter: {
type: 'object', type: 'object',
default: {}, default: {
$and: [{}],
},
'x-component': 'Filter', 'x-component': 'Filter',
'x-component-props': { 'x-component-props': {
useDataSource: '{{cm.useFilterDataSource}}', useDataSource: '{{cm.useFilterDataSource}}',

View File

@ -0,0 +1,205 @@
import { Switch } from 'antd';
import React from 'react';
import { SchemaInitializer } from '../../SchemaInitializer';
import { useCurrentSchema } from '../utils';
export const LinkToFieldInitializer = (props) => {
const { item, insert } = props;
const { exists, remove } = useCurrentSchema(
item.schema['x-collection-field'],
'x-collection-field',
item.find,
item.remove,
);
return (
<SchemaInitializer.Item
onClick={() => {
console.log(item, exists);
if (exists) {
return remove();
}
insert({
...item.schema,
default: [
{ id: 1, name: 'name1' },
{ id: 2, name: 'name2' },
],
// 'x-decorator': 'FormItem',
'x-component': 'CollectionField',
'x-component-props': {
mode: 'tags',
fieldNames: {
label: 'name',
value: 'id',
},
},
properties: {
options: {
'x-component': 'RecordPicker.Options',
type: 'void',
title: 'Drawer Title',
properties: {
block: {
type: 'void',
'x-collection': 'collections',
'x-decorator': 'ResourceActionProvider',
'x-decorator-props': {
collection: item.field.target,
request: {
resource: item.field.target,
action: 'list',
params: {
pageSize: 20,
filter: {},
// sort: ['sort'],
appends: [],
},
},
},
'x-designer': 'Table.Void.Designer',
'x-component': 'CardItem',
properties: {
actions: {
type: 'void',
'x-initializer': 'TableActionInitializers',
'x-component': 'ActionBar',
'x-component-props': {
style: {
marginBottom: 16,
},
},
properties: {},
},
table: {
// type: 'void',
'x-component': 'Table.RowSelection',
'x-component-props': {
rowKey: 'id',
objectValue: true,
rowSelection: {
type: 'checkbox',
},
useDataSource: '{{ cm.useDataSourceFromRAC }}',
},
'x-initializer': 'TableColumnInitializers',
properties: {
actions: {
type: 'void',
title: '{{ t("Actions") }}',
'x-decorator': 'Table.Column.ActionBar',
'x-component': 'Table.Column',
'x-designer': 'Table.RowActionDesigner',
'x-initializer': 'TableRecordActionInitializers',
properties: {
actions: {
type: 'void',
'x-decorator': 'DndContext',
'x-component': 'Space',
'x-component-props': {
split: '|',
},
properties: {},
},
},
},
},
},
},
},
// input: {
// type: 'array',
// title: `编辑模式`,
// 'x-component': 'Table.RowSelection',
// 'x-component-props': {
// rowKey: 'id',
// objectValue: true,
// rowSelection: {
// type: 'checkbox',
// },
// dataSource: [
// { id: 1, name: 'Name1' },
// { id: 2, name: 'Name2' },
// { id: 3, name: 'Name3' },
// ],
// },
// properties: {
// column1: {
// type: 'void',
// title: 'Name',
// 'x-component': 'Table.Column',
// properties: {
// name: {
// type: 'string',
// 'x-component': 'Input',
// 'x-read-pretty': true,
// },
// },
// },
// },
// },
},
},
item: {
'x-component': 'RecordPicker.SelectedItem',
properties: {
drawer1: {
'x-component': 'Action.Drawer',
type: 'void',
title: 'Drawer Title',
properties: {
details: {
type: 'void',
'x-collection': 'collections',
'x-decorator': 'ResourceActionProvider',
'x-decorator-props': {
collection: item.field.target,
request: {
resource: item.field.target,
action: 'get',
params: {},
},
},
'x-designer': 'Form.Designer',
'x-component': 'CardItem',
properties: {
form: {
type: 'void',
'x-decorator': 'Form',
'x-decorator-props': {},
properties: {
actions: {
type: 'void',
'x-initializer': 'FormActionInitializers',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
style: {
marginBottom: 16,
},
},
properties: {},
},
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'GridFormItemInitializers',
properties: {},
},
},
},
},
},
},
},
},
},
},
});
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
{item.title} <Switch style={{ marginLeft: 20 }} size={'small'} checked={exists} />
</div>
</SchemaInitializer.Item>
);
};

View File

@ -5,6 +5,7 @@ export * from './CollectionFieldInitializer';
export * from './FilterActionInitializer'; export * from './FilterActionInitializer';
export * from './FormBlockInitializer'; export * from './FormBlockInitializer';
export * from './GeneralInitializer'; export * from './GeneralInitializer';
export * from './LinkToCollectionFieldInitializer';
export * from './MarkdownBlockInitializer'; export * from './MarkdownBlockInitializer';
export * from './SubTableFieldInitializer'; export * from './SubTableFieldInitializer';
export * from './TableBlockInitializer'; export * from './TableBlockInitializer';

View File

@ -58,29 +58,58 @@ const findTableColumn = (schema: Schema, key: string, action: string, deepth: nu
export const useTableColumnInitializerFields = () => { export const useTableColumnInitializerFields = () => {
const { name, fields } = useCollection(); const { name, fields } = useCollection();
return ( return fields
fields .filter((field) => field?.interface !== 'subTable')
// .filter((field) => field?.uiSchema?.title) .map((field) => {
.map((field) => { if (field.interface === 'linkTo') {
return { return {
field,
type: 'item', type: 'item',
title: field?.uiSchema?.title || field.name, title: field?.uiSchema?.title || field.name,
find: findTableColumn,
remove: removeTableColumn,
component: 'LinkToFieldInitializer',
schema: { schema: {
name: field.name, name: field.name,
'x-collection-field': `${name}.${field.name}`, 'x-collection-field': `${name}.${field.name}`,
'x-component': 'CollectionField', 'x-component': 'CollectionField',
}, },
component: 'CollectionFieldInitializer',
find: findTableColumn,
remove: removeTableColumn,
} as SchemaInitializerItemOptions; } as SchemaInitializerItemOptions;
}) }
); return {
type: 'item',
title: field?.uiSchema?.title || field.name,
component: 'CollectionFieldInitializer',
find: findTableColumn,
remove: removeTableColumn,
schema: {
name: field.name,
'x-collection-field': `${name}.${field.name}`,
'x-component': 'CollectionField',
},
} as SchemaInitializerItemOptions;
});
}; };
export const useFormItemInitializerFields = () => { export const useFormItemInitializerFields = () => {
const { name, fields } = useCollection(); const { name, fields } = useCollection();
return fields?.map((field) => { return fields?.map((field) => {
if (field.interface === 'linkTo') {
return {
type: 'item',
title: field?.uiSchema?.title || field.name,
component: 'LinkToFieldInitializer',
remove: removeGridFormItem,
field,
schema: {
name: field.name,
'x-designer': 'FormItem.Designer',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': `${name}.${field.name}`,
},
} as SchemaInitializerItemOptions;
}
if (field.interface === 'subTable') { if (field.interface === 'subTable') {
return { return {
type: 'item', type: 'item',