mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-06 05:59:25 +08:00
* feat: association field * fix: bug * refactor: association field * style: style improve * style: style improve * refactor: support subtable * refactor: support file collection * refactor: locale improve * refactor: subtable improve * refactor: association select improve * refactor: association select improve * refactor: association select improve * refactor: useAssociationNames * refactor: enable link * refactor: selector * refactor: selector * refactor: locale improve * refactor: on demand loading of relational data * refactor: locale improve * refactor: select button * refactor: association field * refactor: formformBlock provider * refactor: formformBlock provider * refactor: internalSelect recordPicker * refactor: formBlocklockProvider * fix: addNewer schema * fix: useServiceOptions * fix: useCreateActionProps * fix: useCreateActionProps * refactor: nester delete * refactor: nester delete in detail * refactor: subTable suport select * refactor: subTable suport select * style: style improve * style: style improve * chore: fileManger * fix: association readPrety * fix: filemanger * refactor: field mode * refactor: enable link * chore: error message * refactor: association schemaInitialize * refactor: association schemaInitialize * refactor: currentMode * refactor: field mode default value * fix: file manage readPretty * fix: appends * chore: file manage readPretty * fix: updateAssociationValues * fix: updateAssociationValues * fix: updateAssociationValues * fix: nester appends * fix: nester appends * fix: tree collection association fields * fix: tree collection association fields * fix: nester appends * fix: subtable to select field value missing * fix: subtable to select field value missing * fix: compatible with historical blocks * fix: compatible with historical blocks * fix: compatible with historical blocks * feat: add migration * fix: filter block allow add new * fix: compatible with historical blocks * fix: skip if not RecordPicker * fix: compatible with historical blocks * fix: detail block not support nester * fix: association select support data scope and sort setting * fix: appends on demand loading * fix: asociationSelect support multiple * fix: recordPicker -> AssociationField * fix: add migration * fix: audit logs not show assication data * fix: flattenNestedList * refactor: file manager field mode * refactor: field mode refactor * fix: subtable action * fix: subtable appends * refactor: code improve * fix: nester add new * feat: sub table * fix: data scope not effect immediately * fix: association add new * fix: association field failed to add new and mutual influence * style: style improve * style: style improve * refactor: updateAssociationValues * refactor: form init values * refactor: select options * fix: form initialValues * fix: record picker values * fix: field value change when field mode change * fix: select data scope * feat: add migration * fix: table column enable link * fix: table column enable link * refactor: locale improve * fix: migration * fix: mutiple config * fix: readPretty enable link * fix: appends on demand * fix: enable link style * refactor: locale improve * refactor: locale improve * feat: sub-form migration * fix: skip migration * fix: translation * fix: skip migration * fix: getLabelFormatValue * fix: error TS2339: Property 'find' does not exist on type 'string | SchemaEnum<any>' * refactor: remove the logic code for converting old record picker * refactor: locale * refactor: locale * fix: sub-table should not support add new * refactor: code improve * refactor: locale * fix: compatibility history Subtable * fix: improve --------- Co-authored-by: chenos <chenlinxh@gmail.com> Co-authored-by: Chareice <chareice@live.com>
1630 lines
49 KiB
TypeScript
1630 lines
49 KiB
TypeScript
import { ISchema, Schema, useFieldSchema, useForm } from '@formily/react';
|
||
import { uid } from '@formily/shared';
|
||
import React, { useContext, useMemo, useState } from 'react';
|
||
import { useTranslation } from 'react-i18next';
|
||
import { BlockRequestContext, SchemaInitializerItemOptions } from '../';
|
||
import { FieldOptions, useCollection, useCollectionManager } from '../collection-manager';
|
||
import { isAssocField } from '../filter-provider/utils';
|
||
import { useActionContext, useDesignable } from '../schema-component';
|
||
import { useSchemaTemplateManager } from '../schema-templates';
|
||
import { SelectCollection } from './SelectCollection';
|
||
|
||
export const itemsMerge = (items1) => {
|
||
return items1;
|
||
};
|
||
|
||
export const gridRowColWrap = (schema: ISchema) => {
|
||
return {
|
||
type: 'void',
|
||
'x-component': 'Grid.Row',
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-component': 'Grid.Col',
|
||
properties: {
|
||
[schema.name || uid()]: schema,
|
||
},
|
||
},
|
||
},
|
||
};
|
||
};
|
||
|
||
export const removeTableColumn = (schema, cb) => {
|
||
cb(schema.parent);
|
||
};
|
||
|
||
export const removeGridFormItem = (schema, cb) => {
|
||
cb(schema, {
|
||
removeParentsIfNoChildren: true,
|
||
breakRemoveOn: {
|
||
'x-component': 'Grid',
|
||
},
|
||
});
|
||
};
|
||
|
||
export const useRemoveGridFormItem = () => {
|
||
const form = useForm();
|
||
return (schema, cb) => {
|
||
cb(schema, {
|
||
removeParentsIfNoChildren: true,
|
||
breakRemoveOn: {
|
||
'x-component': 'Grid',
|
||
},
|
||
});
|
||
delete form.values?.[schema.name];
|
||
};
|
||
};
|
||
|
||
export const findTableColumn = (schema: Schema, key: string, action: string, deepth = 0) => {
|
||
return schema.reduceProperties((buf, s) => {
|
||
if (s[key] === action) {
|
||
return s;
|
||
}
|
||
const c = s.reduceProperties((buf, s) => {
|
||
if (s[key] === action) {
|
||
return s;
|
||
}
|
||
return buf;
|
||
});
|
||
if (c) {
|
||
return c;
|
||
}
|
||
return buf;
|
||
});
|
||
};
|
||
|
||
export const useTableColumnInitializerFields = () => {
|
||
const { name, currentFields = [] } = useCollection();
|
||
const { getInterface, getCollection } = useCollectionManager();
|
||
return currentFields
|
||
.filter(
|
||
(field) => field?.interface && field?.interface !== 'subTable' && !field?.isForeignKey && !field?.treeChildren,
|
||
)
|
||
.map((field) => {
|
||
const interfaceConfig = getInterface(field.interface);
|
||
const schema = {
|
||
name: field.name,
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
'x-component': 'CollectionField',
|
||
'x-read-pretty': true,
|
||
'x-component-props': {},
|
||
};
|
||
// interfaceConfig?.schemaInitialize?.(schema, { field, readPretty: true, block: 'Table' });
|
||
return {
|
||
type: 'item',
|
||
title: field?.uiSchema?.title || field.name,
|
||
component: 'TableCollectionFieldInitializer',
|
||
find: findTableColumn,
|
||
remove: removeTableColumn,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field,
|
||
readPretty: true,
|
||
block: 'Table',
|
||
targetCollection: getCollection(field.target),
|
||
});
|
||
},
|
||
field,
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
});
|
||
};
|
||
|
||
export const useAssociatedTableColumnInitializerFields = () => {
|
||
const { name, fields } = useCollection();
|
||
const { getInterface, getCollectionFields, getCollection } = useCollectionManager();
|
||
const groups = fields
|
||
?.filter((field) => {
|
||
return ['o2o', 'oho', 'obo', 'm2o'].includes(field.interface);
|
||
})
|
||
?.map((field) => {
|
||
const subFields = getCollectionFields(field.target);
|
||
const items = subFields
|
||
// ?.filter((subField) => subField?.interface && !['o2o', 'oho', 'obo', 'o2m', 'm2o', 'subTable', 'linkTo'].includes(subField?.interface))
|
||
?.filter(
|
||
(subField) => subField?.interface && !['subTable'].includes(subField?.interface) && !subField?.treeChildren,
|
||
)
|
||
?.map((subField) => {
|
||
const interfaceConfig = getInterface(subField.interface);
|
||
const schema = {
|
||
// type: 'string',
|
||
name: `${field.name}.${subField.name}`,
|
||
// title: subField?.uiSchema?.title || subField.name,
|
||
|
||
'x-component': 'CollectionField',
|
||
'x-read-pretty': true,
|
||
'x-collection-field': `${name}.${field.name}.${subField.name}`,
|
||
'x-component-props': {},
|
||
};
|
||
|
||
return {
|
||
type: 'item',
|
||
title: subField?.uiSchema?.title || subField.name,
|
||
component: 'TableCollectionFieldInitializer',
|
||
find: findTableColumn,
|
||
remove: removeTableColumn,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field: subField,
|
||
readPretty: true,
|
||
block: 'Table',
|
||
targetCollection: getCollection(field.target),
|
||
});
|
||
},
|
||
field: subField,
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
});
|
||
return {
|
||
type: 'subMenu',
|
||
title: field.uiSchema?.title,
|
||
children: items,
|
||
} as SchemaInitializerItemOptions;
|
||
});
|
||
|
||
return groups;
|
||
};
|
||
|
||
export const useInheritsTableColumnInitializerFields = () => {
|
||
const { name } = useCollection();
|
||
const { getInterface, getInheritCollections, getCollection, getParentCollectionFields } = useCollectionManager();
|
||
const inherits = getInheritCollections(name);
|
||
return inherits?.map((v) => {
|
||
const fields = getParentCollectionFields(v, name);
|
||
const targetCollection = getCollection(v);
|
||
return {
|
||
[targetCollection?.title]: fields
|
||
?.filter((field) => {
|
||
return field?.interface;
|
||
})
|
||
.map((k) => {
|
||
const interfaceConfig = getInterface(k.interface);
|
||
const schema = {
|
||
name: `${k.name}`,
|
||
'x-component': 'CollectionField',
|
||
'x-read-pretty': true,
|
||
'x-collection-field': `${name}.${k.name}`,
|
||
'x-component-props': {},
|
||
};
|
||
return {
|
||
type: 'item',
|
||
title: k?.uiSchema?.title || k.name,
|
||
component: 'TableCollectionFieldInitializer',
|
||
find: findTableColumn,
|
||
remove: removeTableColumn,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field: k,
|
||
readPretty: true,
|
||
block: 'Table',
|
||
targetCollection: getCollection(k?.target),
|
||
});
|
||
},
|
||
field: k,
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
}),
|
||
};
|
||
});
|
||
};
|
||
|
||
export const useFormItemInitializerFields = (options?: any) => {
|
||
const { name, currentFields, template } = useCollection();
|
||
const { getInterface, getCollection } = useCollectionManager();
|
||
const form = useForm();
|
||
const { readPretty = form.readPretty, block = 'Form' } = options || {};
|
||
const { snapshot, fieldSchema } = useActionContext();
|
||
const action = fieldSchema?.['x-action'];
|
||
|
||
return currentFields
|
||
?.filter((field) => field?.interface && !field?.isForeignKey && !field?.treeChildren)
|
||
?.map((field) => {
|
||
const interfaceConfig = getInterface(field.interface);
|
||
const targetCollection = getCollection(field.target);
|
||
// const component =
|
||
// field.interface === 'o2m' && targetCollection?.template !== 'file' && !snapshot
|
||
// ? 'TableField'
|
||
// : 'CollectionField';
|
||
const schema = {
|
||
type: 'string',
|
||
name: field.name,
|
||
'x-designer': 'FormItem.Designer',
|
||
'x-component': 'CollectionField',
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
'x-component-props': {},
|
||
'x-read-pretty': field?.uiSchema?.['x-read-pretty'],
|
||
};
|
||
// interfaceConfig?.schemaInitialize?.(schema, { field, block: 'Form', readPretty: form.readPretty });
|
||
const resultItem = {
|
||
type: 'item',
|
||
title: field?.uiSchema?.title || field.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: removeGridFormItem,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field,
|
||
block,
|
||
readPretty,
|
||
action,
|
||
targetCollection,
|
||
});
|
||
},
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
if (block == 'Kanban') {
|
||
resultItem['find'] = (schema: Schema, key: string, action: string) => {
|
||
const s = findSchema(schema, 'x-component', block);
|
||
return findSchema(s, key, action);
|
||
};
|
||
}
|
||
|
||
return resultItem;
|
||
});
|
||
};
|
||
|
||
// 筛选表单相关
|
||
export const useFilterFormItemInitializerFields = (options?: any) => {
|
||
const { name, currentFields } = useCollection();
|
||
const { getInterface, getCollection } = useCollectionManager();
|
||
const form = useForm();
|
||
const { readPretty = form.readPretty, block = 'FilterForm' } = options || {};
|
||
const { snapshot, fieldSchema } = useActionContext();
|
||
const action = fieldSchema?.['x-action'];
|
||
|
||
return currentFields
|
||
?.filter((field) => field?.interface && !field?.isForeignKey && getInterface(field.interface)?.filterable)
|
||
?.map((field) => {
|
||
const interfaceConfig = getInterface(field.interface);
|
||
const targetCollection = getCollection(field.target);
|
||
// const component =
|
||
// field.interface === 'o2m' && targetCollection?.template !== 'file' && !snapshot
|
||
// ? 'TableField'
|
||
// : 'CollectionField';
|
||
let schema = {
|
||
type: 'string',
|
||
name: field.name,
|
||
required: false,
|
||
'x-designer': 'FormItem.FilterFormDesigner',
|
||
'x-component': 'CollectionField',
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
'x-component-props': {},
|
||
};
|
||
if (isAssocField(field)) {
|
||
schema = {
|
||
type: 'string',
|
||
name: `${field.name}`,
|
||
required: false,
|
||
'x-designer': 'FormItem.FilterFormDesigner',
|
||
'x-component': 'CollectionField',
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
'x-component-props': field.uiSchema?.['x-component-props'],
|
||
};
|
||
}
|
||
const resultItem = {
|
||
type: 'item',
|
||
title: field?.uiSchema?.title || field.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: removeGridFormItem,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field,
|
||
block,
|
||
readPretty,
|
||
action,
|
||
targetCollection,
|
||
});
|
||
},
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
|
||
return resultItem;
|
||
});
|
||
};
|
||
|
||
export const useAssociatedFormItemInitializerFields = (options?: any) => {
|
||
const { name, fields } = useCollection();
|
||
const { getInterface, getCollectionFields, getCollection } = useCollectionManager();
|
||
const form = useForm();
|
||
const { readPretty = form.readPretty, block = 'Form' } = options || {};
|
||
const interfaces = block === 'Form' ? ['m2o'] : ['o2o', 'oho', 'obo', 'm2o'];
|
||
const groups = fields
|
||
?.filter((field) => {
|
||
return interfaces.includes(field.interface);
|
||
})
|
||
?.map((field) => {
|
||
const subFields = getCollectionFields(field.target);
|
||
const items = subFields
|
||
?.filter(
|
||
(subField) => subField?.interface && !['subTable'].includes(subField?.interface) && !subField.treeChildren,
|
||
)
|
||
?.map((subField) => {
|
||
const interfaceConfig = getInterface(subField.interface);
|
||
const schema = {
|
||
type: 'string',
|
||
name: `${field.name}.${subField.name}`,
|
||
'x-designer': 'FormItem.Designer',
|
||
'x-component': 'CollectionField',
|
||
'x-read-pretty': readPretty,
|
||
'x-component-props': {
|
||
'pattern-disable': block === 'Form' && readPretty,
|
||
},
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}.${subField.name}`,
|
||
};
|
||
return {
|
||
type: 'item',
|
||
title: subField?.uiSchema?.title || subField.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: removeGridFormItem,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field: subField,
|
||
block,
|
||
readPretty,
|
||
targetCollection: getCollection(field.target),
|
||
});
|
||
},
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
});
|
||
|
||
return {
|
||
type: 'subMenu',
|
||
title: field.uiSchema?.title,
|
||
children: items,
|
||
} as SchemaInitializerItemOptions;
|
||
});
|
||
return groups;
|
||
};
|
||
|
||
const getItem = (
|
||
field: FieldOptions,
|
||
schemaName: string,
|
||
collectionName: string,
|
||
getCollectionFields,
|
||
processedCollections: string[],
|
||
) => {
|
||
if (field.interface === 'm2o') {
|
||
if (processedCollections.includes(field.target)) return null;
|
||
|
||
const subFields = getCollectionFields(field.target);
|
||
|
||
return {
|
||
type: 'subMenu',
|
||
title: field.uiSchema?.title,
|
||
children: subFields
|
||
.map((subField) =>
|
||
// 使用 | 分隔,是为了防止 form.values 中出现 { a: { b: 1 } } 的情况
|
||
// 使用 | 分隔后,form.values 中会出现 { 'a|b': 1 } 的情况,这种情况下
|
||
// 就可以知道该字段是一个关系字段中的输入框,进而特殊处理
|
||
getItem(subField, `${schemaName}.${subField.name}`, collectionName, getCollectionFields, [
|
||
...processedCollections,
|
||
field.target,
|
||
]),
|
||
)
|
||
.filter(Boolean),
|
||
} as SchemaInitializerItemOptions;
|
||
}
|
||
|
||
if (isAssocField(field)) return null;
|
||
|
||
const schema = {
|
||
type: 'string',
|
||
name: schemaName,
|
||
'x-designer': 'FormItem.FilterFormDesigner',
|
||
'x-designer-props': {
|
||
// 在 useOperatorList 中使用,用于获取对应的操作符列表
|
||
interface: field.interface,
|
||
},
|
||
'x-component': 'CollectionField',
|
||
'x-read-pretty': false,
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${collectionName}.${schemaName}`,
|
||
};
|
||
|
||
return {
|
||
type: 'item',
|
||
title: field.uiSchema?.title || field.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: removeGridFormItem,
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
};
|
||
|
||
// 筛选表单相关
|
||
export const useFilterAssociatedFormItemInitializerFields = () => {
|
||
const { name, fields } = useCollection();
|
||
const { getCollectionFields } = useCollectionManager();
|
||
const interfaces = ['m2o'];
|
||
const groups = fields
|
||
?.filter((field) => {
|
||
return interfaces.includes(field.interface);
|
||
})
|
||
?.map((field) => getItem(field, field.name, name, getCollectionFields, []));
|
||
return groups;
|
||
};
|
||
|
||
export const useInheritsFormItemInitializerFields = (options?) => {
|
||
const { name } = useCollection();
|
||
const { getInterface, getInheritCollections, getCollection, getParentCollectionFields } = useCollectionManager();
|
||
const inherits = getInheritCollections(name);
|
||
const { snapshot } = useActionContext();
|
||
const form = useForm();
|
||
|
||
return inherits?.map((v) => {
|
||
const fields = getParentCollectionFields(v, name);
|
||
const { readPretty = form.readPretty, block = 'Form' } = options || {};
|
||
const targetCollection = getCollection(v);
|
||
return {
|
||
[targetCollection?.title]: fields
|
||
?.filter((field) => field?.interface && !field?.isForeignKey)
|
||
?.map((field) => {
|
||
const interfaceConfig = getInterface(field.interface);
|
||
const targetCollection = getCollection(field.target);
|
||
// const component =
|
||
// field.interface === 'o2m' && targetCollection?.template !== 'file' && !snapshot
|
||
// ? 'TableField'
|
||
// : 'CollectionField';
|
||
const schema = {
|
||
type: 'string',
|
||
name: field.name,
|
||
title: field?.uiSchema?.title || field.name,
|
||
'x-designer': 'FormItem.Designer',
|
||
'x-component': 'CollectionField',
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
'x-component-props': {},
|
||
'x-read-pretty': field?.uiSchema?.['x-read-pretty'],
|
||
};
|
||
return {
|
||
type: 'item',
|
||
title: field?.uiSchema?.title || field.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: removeGridFormItem,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field,
|
||
block,
|
||
readPretty,
|
||
targetCollection,
|
||
});
|
||
},
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
}),
|
||
};
|
||
});
|
||
};
|
||
|
||
// 筛选表单相关
|
||
export const useFilterInheritsFormItemInitializerFields = (options?) => {
|
||
const { name } = useCollection();
|
||
const { getInterface, getInheritCollections, getCollection, getParentCollectionFields } = useCollectionManager();
|
||
const inherits = getInheritCollections(name);
|
||
const { snapshot } = useActionContext();
|
||
|
||
return inherits?.map((v) => {
|
||
const fields = getParentCollectionFields(v, name);
|
||
const form = useForm();
|
||
const { readPretty = form.readPretty, block = 'Form' } = options || {};
|
||
const targetCollection = getCollection(v);
|
||
return {
|
||
[targetCollection.title]: fields
|
||
?.filter((field) => field?.interface && !field?.isForeignKey && getInterface(field.interface)?.filterable)
|
||
?.map((field) => {
|
||
const interfaceConfig = getInterface(field.interface);
|
||
const targetCollection = getCollection(field.target);
|
||
// const component =
|
||
// field.interface === 'o2m' && targetCollection?.template !== 'file' && !snapshot
|
||
// ? 'TableField'
|
||
// : 'CollectionField';
|
||
const schema = {
|
||
type: 'string',
|
||
name: field.name,
|
||
title: field?.uiSchema?.title || field.name,
|
||
required: false,
|
||
'x-designer': 'FormItem.FilterFormDesigner',
|
||
'x-component': 'CollectionField',
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
'x-component-props': {},
|
||
'x-read-pretty': field?.uiSchema?.['x-read-pretty'],
|
||
};
|
||
return {
|
||
type: 'item',
|
||
title: field?.uiSchema?.title || field.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: removeGridFormItem,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field,
|
||
block,
|
||
readPretty,
|
||
targetCollection,
|
||
});
|
||
},
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
}),
|
||
};
|
||
});
|
||
};
|
||
export const useCustomFormItemInitializerFields = (options?: any) => {
|
||
const { name, currentFields } = useCollection();
|
||
const { getInterface, getCollection } = useCollectionManager();
|
||
const form = useForm();
|
||
const { readPretty = form.readPretty, block = 'Form' } = options || {};
|
||
const remove = useRemoveGridFormItem();
|
||
return currentFields
|
||
?.filter((field) => {
|
||
return (
|
||
field?.interface &&
|
||
!field?.uiSchema?.['x-read-pretty'] &&
|
||
field.interface !== 'snapshot' &&
|
||
field.type !== 'sequence'
|
||
);
|
||
})
|
||
?.map((field) => {
|
||
const interfaceConfig = getInterface(field.interface);
|
||
const schema = {
|
||
type: 'string',
|
||
name: field.name,
|
||
title: field?.uiSchema?.title || field.name,
|
||
'x-designer': 'FormItem.Designer',
|
||
'x-component': 'AssignedField',
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
};
|
||
return {
|
||
type: 'item',
|
||
title: field?.uiSchema?.title || field.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: remove,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field,
|
||
block,
|
||
readPretty,
|
||
targetCollection: getCollection(field.target),
|
||
});
|
||
},
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
});
|
||
};
|
||
|
||
export const useCustomBulkEditFormItemInitializerFields = (options?: any) => {
|
||
const { name, fields } = useCollection();
|
||
const { getInterface, getCollection } = useCollectionManager();
|
||
const form = useForm();
|
||
const { readPretty = form.readPretty, block = 'Form' } = options || {};
|
||
const remove = useRemoveGridFormItem();
|
||
const filterFields = useMemo(
|
||
() =>
|
||
fields
|
||
?.filter((field) => {
|
||
return (
|
||
field?.interface &&
|
||
!field?.uiSchema?.['x-read-pretty'] &&
|
||
field.interface !== 'snapshot' &&
|
||
field.type !== 'sequence'
|
||
);
|
||
})
|
||
.map((field) => {
|
||
const interfaceConfig = getInterface(field.interface);
|
||
const schema = {
|
||
type: 'string',
|
||
name: field.name,
|
||
title: field?.uiSchema?.title || field.name,
|
||
'x-designer': 'FormItem.Designer',
|
||
'x-component': 'BulkEditField',
|
||
'x-decorator': 'FormItem',
|
||
'x-collection-field': `${name}.${field.name}`,
|
||
};
|
||
return {
|
||
type: 'item',
|
||
title: field?.uiSchema?.title || field.name,
|
||
component: 'CollectionFieldInitializer',
|
||
remove: remove,
|
||
schemaInitialize: (s) => {
|
||
interfaceConfig?.schemaInitialize?.(s, {
|
||
field,
|
||
block,
|
||
readPretty,
|
||
targetCollection: getCollection(field.target),
|
||
});
|
||
},
|
||
schema,
|
||
} as SchemaInitializerItemOptions;
|
||
}),
|
||
[fields],
|
||
);
|
||
|
||
return filterFields;
|
||
};
|
||
|
||
const findSchema = (schema: Schema, key: string, action: string) => {
|
||
if (!Schema.isSchemaInstance(schema)) return null;
|
||
return schema.reduceProperties((buf, s) => {
|
||
if (s[key] === action) {
|
||
return s;
|
||
}
|
||
const c = findSchema(s, key, action);
|
||
if (c) {
|
||
return c;
|
||
}
|
||
return buf;
|
||
});
|
||
};
|
||
|
||
const removeSchema = (schema, cb) => {
|
||
return cb(schema);
|
||
};
|
||
|
||
const recursiveParent = (schema: Schema) => {
|
||
if (!schema.parent) return null;
|
||
|
||
if (schema.parent['x-initializer']) return schema.parent;
|
||
|
||
return recursiveParent(schema.parent);
|
||
};
|
||
|
||
export const useCurrentSchema = (action: string, key: string, find = findSchema, rm = removeSchema) => {
|
||
let fieldSchema = useFieldSchema();
|
||
if (!fieldSchema?.['x-initializer']) {
|
||
const recursiveInitializerSchema = recursiveParent(fieldSchema);
|
||
if (recursiveInitializerSchema) {
|
||
fieldSchema = recursiveInitializerSchema;
|
||
}
|
||
}
|
||
const { remove } = useDesignable();
|
||
const schema = find(fieldSchema, key, action);
|
||
const ctx = useContext(BlockRequestContext);
|
||
|
||
return {
|
||
schema,
|
||
exists: !!schema,
|
||
remove() {
|
||
if (ctx.field) {
|
||
ctx.field.data = ctx.field.data || {};
|
||
ctx.field.data.activeFields = ctx.field.data.activeFields || new Set();
|
||
ctx.field.data.activeFields.delete(schema.name);
|
||
}
|
||
schema && rm(schema, remove);
|
||
},
|
||
};
|
||
};
|
||
|
||
export const useRecordCollectionDataSourceItems = (
|
||
componentName,
|
||
item = null,
|
||
collectionName = null,
|
||
resourceName = null,
|
||
) => {
|
||
const { t } = useTranslation();
|
||
const collection = useCollection();
|
||
const { getTemplatesByCollection } = useSchemaTemplateManager();
|
||
const templates = getTemplatesByCollection(collectionName || collection.name)
|
||
.filter((template) => {
|
||
return componentName && template.componentName === componentName;
|
||
})
|
||
.filter((template) => {
|
||
return ['FormItem', 'ReadPrettyFormItem'].includes(componentName) || template.resourceName === resourceName;
|
||
});
|
||
if (!templates.length) {
|
||
return [];
|
||
}
|
||
const index = 0;
|
||
return [
|
||
{
|
||
key: `${collectionName || componentName}_table_blank`,
|
||
type: 'item',
|
||
name: collection.name,
|
||
title: t('Blank block'),
|
||
item,
|
||
},
|
||
{
|
||
type: 'divider',
|
||
},
|
||
{
|
||
key: `${collectionName || componentName}_table_subMenu_${index}_copy`,
|
||
type: 'subMenu',
|
||
name: 'copy',
|
||
title: t('Duplicate template'),
|
||
children: templates.map((template) => {
|
||
const templateName = ['FormItem', 'ReadPrettyFormItem'].includes(template?.componentName)
|
||
? `${template?.name} ${t('(Fields only)')}`
|
||
: template?.name;
|
||
return {
|
||
type: 'item',
|
||
mode: 'copy',
|
||
name: collection.name,
|
||
template,
|
||
item,
|
||
title: templateName || t('Untitled'),
|
||
};
|
||
}),
|
||
},
|
||
{
|
||
key: `${collectionName || componentName}_table_subMenu_${index}_ref`,
|
||
type: 'subMenu',
|
||
name: 'ref',
|
||
title: t('Reference template'),
|
||
children: templates.map((template) => {
|
||
const templateName = ['FormItem', 'ReadPrettyFormItem'].includes(template?.componentName)
|
||
? `${template?.name} ${t('(Fields only)')}`
|
||
: template?.name;
|
||
return {
|
||
type: 'item',
|
||
mode: 'reference',
|
||
name: collection.name,
|
||
template,
|
||
item,
|
||
title: templateName || t('Untitled'),
|
||
};
|
||
}),
|
||
},
|
||
];
|
||
};
|
||
|
||
export const useCollectionDataSourceItems = (componentName) => {
|
||
const { t } = useTranslation();
|
||
const { collections, getCollectionFields } = useCollectionManager();
|
||
const { getTemplatesByCollection } = useSchemaTemplateManager();
|
||
const [selected, setSelected] = useState([]);
|
||
const [value, onChange] = useState(null);
|
||
const clearKeywords = () => {
|
||
setSelected([]);
|
||
onChange(null);
|
||
};
|
||
return [
|
||
{
|
||
key: 'tableBlock',
|
||
type: 'itemGroup',
|
||
title: React.createElement(SelectCollection, {
|
||
value,
|
||
onChange,
|
||
setSelected,
|
||
}),
|
||
children: collections
|
||
?.filter((item) => {
|
||
const b = !value || selected.includes(item.name);
|
||
if (item.inherit) {
|
||
return false;
|
||
}
|
||
const fields = getCollectionFields(item.name);
|
||
if (item.autoGenId === false && !fields.find((v) => v.primaryKey)) {
|
||
return false;
|
||
} else if (['Kanban', 'FormItem'].includes(componentName) && item.template === 'view') {
|
||
return false;
|
||
} else if (item.template === 'file' && ['Kanban', 'FormItem', 'Calendar'].includes(componentName)) {
|
||
return false;
|
||
} else {
|
||
return b && !(item?.isThrough && item?.autoCreate);
|
||
}
|
||
})
|
||
?.map((item, index) => {
|
||
const templates = getTemplatesByCollection(item.name).filter((template) => {
|
||
return (
|
||
componentName &&
|
||
template.componentName === componentName &&
|
||
(!template.resourceName || template.resourceName === item.name)
|
||
);
|
||
});
|
||
if (!templates.length) {
|
||
return {
|
||
type: 'item',
|
||
name: item.name,
|
||
title: item.title,
|
||
clearKeywords,
|
||
};
|
||
}
|
||
return {
|
||
key: `${componentName}_table_subMenu_${index}`,
|
||
type: 'subMenu',
|
||
name: `${item.name}_${index}`,
|
||
title: item.title,
|
||
children: [
|
||
{
|
||
type: 'item',
|
||
name: item.name,
|
||
title: t('Blank block'),
|
||
clearKeywords,
|
||
},
|
||
{
|
||
type: 'divider',
|
||
},
|
||
{
|
||
key: `${componentName}_table_subMenu_${index}_copy`,
|
||
type: 'subMenu',
|
||
name: 'copy',
|
||
title: t('Duplicate template'),
|
||
children: templates.map((template) => {
|
||
const templateName =
|
||
template?.componentName === 'FormItem' ? `${template?.name} ${t('(Fields only)')}` : template?.name;
|
||
return {
|
||
type: 'item',
|
||
mode: 'copy',
|
||
name: item.name,
|
||
template,
|
||
clearKeywords,
|
||
title: templateName || t('Untitled'),
|
||
};
|
||
}),
|
||
},
|
||
{
|
||
key: `${componentName}_table_subMenu_${index}_ref`,
|
||
type: 'subMenu',
|
||
name: 'ref',
|
||
title: t('Reference template'),
|
||
children: templates.map((template) => {
|
||
const templateName =
|
||
template?.componentName === 'FormItem' ? `${template?.name} ${t('(Fields only)')}` : template?.name;
|
||
return {
|
||
type: 'item',
|
||
mode: 'reference',
|
||
clearKeywords,
|
||
name: item.name,
|
||
template,
|
||
title: templateName || t('Untitled'),
|
||
};
|
||
}),
|
||
},
|
||
],
|
||
};
|
||
}),
|
||
},
|
||
];
|
||
};
|
||
|
||
export const createDetailsBlockSchema = (options) => {
|
||
const {
|
||
formItemInitializers = 'ReadPrettyFormItemInitializers',
|
||
actionInitializers = 'DetailsActionInitializers',
|
||
collection,
|
||
association,
|
||
resource,
|
||
template,
|
||
...others
|
||
} = options;
|
||
const resourceName = resource || association || collection;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-acl-action': `${resourceName}:view`,
|
||
'x-decorator': 'DetailsBlockProvider',
|
||
'x-decorator-props': {
|
||
resource: resourceName,
|
||
collection,
|
||
association,
|
||
readPretty: true,
|
||
action: 'list',
|
||
params: {
|
||
pageSize: 1,
|
||
},
|
||
// useParams: '{{ useParamsFromRecord }}',
|
||
...others,
|
||
},
|
||
'x-designer': 'DetailsDesigner',
|
||
'x-component': 'CardItem',
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-component': 'Details',
|
||
'x-read-pretty': true,
|
||
'x-component-props': {
|
||
useProps: '{{ useDetailsBlockProps }}',
|
||
},
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-initializer': actionInitializers,
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
style: {
|
||
marginBottom: 24,
|
||
},
|
||
},
|
||
properties: {},
|
||
},
|
||
grid: template || {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-initializer': formItemInitializers,
|
||
properties: {},
|
||
},
|
||
pagination: {
|
||
type: 'void',
|
||
'x-component': 'Pagination',
|
||
'x-component-props': {
|
||
useProps: '{{ useDetailsPaginationProps }}',
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
console.log(JSON.stringify(schema, null, 2));
|
||
return schema;
|
||
};
|
||
|
||
export const createFormBlockSchema = (options) => {
|
||
const {
|
||
formItemInitializers = 'FormItemInitializers',
|
||
actionInitializers = 'FormActionInitializers',
|
||
collection,
|
||
resource,
|
||
association,
|
||
action,
|
||
template,
|
||
...others
|
||
} = options;
|
||
const resourceName = resource || association || collection;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-acl-action-props': {
|
||
skipScopeCheck: !action,
|
||
},
|
||
'x-acl-action': action ? `${resourceName}:update` : `${resourceName}:create`,
|
||
'x-decorator': 'FormBlockProvider',
|
||
'x-decorator-props': {
|
||
...others,
|
||
action,
|
||
resource: resourceName,
|
||
collection,
|
||
association,
|
||
// action: 'get',
|
||
// useParams: '{{ useParamsFromRecord }}',
|
||
},
|
||
'x-designer': 'FormV2.Designer',
|
||
'x-component': 'CardItem',
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-component': 'FormV2',
|
||
'x-component-props': {
|
||
useProps: '{{ useFormBlockProps }}',
|
||
},
|
||
properties: {
|
||
grid: template || {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-initializer': formItemInitializers,
|
||
properties: {},
|
||
},
|
||
actions: {
|
||
type: 'void',
|
||
'x-initializer': actionInitializers,
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
layout: 'one-column',
|
||
style: {
|
||
marginTop: 24,
|
||
},
|
||
},
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
return schema;
|
||
};
|
||
|
||
export const createFilterFormBlockSchema = (options) => {
|
||
const {
|
||
formItemInitializers = 'FilterFormItemInitializers',
|
||
actionInitializers = 'FilterFormActionInitializers',
|
||
collection,
|
||
resource,
|
||
association,
|
||
action,
|
||
template,
|
||
...others
|
||
} = options;
|
||
const resourceName = resource || association || collection;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-decorator': 'FilterFormBlockProvider',
|
||
'x-decorator-props': {
|
||
...others,
|
||
action,
|
||
resource: resourceName,
|
||
collection,
|
||
association,
|
||
},
|
||
'x-designer': 'FormV2.FilterDesigner',
|
||
'x-component': 'CardItem',
|
||
// 保存当前筛选区块所能过滤的数据区块
|
||
'x-filter-targets': [],
|
||
// 用于存储用户设置的每个字段的运算符,目前仅筛选表单区块支持自定义
|
||
'x-filter-operators': {},
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-component': 'FormV2',
|
||
'x-component-props': {
|
||
useProps: '{{ useFormBlockProps }}',
|
||
},
|
||
properties: {
|
||
grid: template || {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-initializer': formItemInitializers,
|
||
properties: {},
|
||
},
|
||
actions: {
|
||
type: 'void',
|
||
'x-initializer': actionInitializers,
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
layout: 'one-column',
|
||
style: {
|
||
float: 'right',
|
||
},
|
||
},
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
return schema;
|
||
};
|
||
|
||
export const createReadPrettyFormBlockSchema = (options) => {
|
||
const {
|
||
formItemInitializers = 'ReadPrettyFormItemInitializers',
|
||
actionInitializers = 'ReadPrettyFormActionInitializers',
|
||
collection,
|
||
association,
|
||
resource,
|
||
template,
|
||
...others
|
||
} = options;
|
||
const resourceName = resource || association || collection;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-acl-action': `${resourceName}:get`,
|
||
'x-decorator': 'FormBlockProvider',
|
||
'x-decorator-props': {
|
||
resource: resourceName,
|
||
collection,
|
||
association,
|
||
readPretty: true,
|
||
action: 'get',
|
||
useParams: '{{ useParamsFromRecord }}',
|
||
...others,
|
||
},
|
||
'x-designer': 'FormV2.ReadPrettyDesigner',
|
||
'x-component': 'CardItem',
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-component': 'FormV2',
|
||
'x-read-pretty': true,
|
||
'x-component-props': {
|
||
useProps: '{{ useFormBlockProps }}',
|
||
},
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
'x-initializer': actionInitializers,
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
style: {
|
||
marginBottom: 24,
|
||
},
|
||
},
|
||
properties: {},
|
||
},
|
||
grid: template || {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-initializer': formItemInitializers,
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
// console.log(JSON.stringify(schema, null, 2));
|
||
return schema;
|
||
};
|
||
|
||
export const createTableBlockSchema = (options) => {
|
||
const {
|
||
collection,
|
||
resource,
|
||
rowKey,
|
||
tableActionInitializers,
|
||
tableColumnInitializers,
|
||
tableActionColumnInitializers,
|
||
tableBlockProvider,
|
||
disableTemplate,
|
||
TableBlockDesigner,
|
||
blockType,
|
||
pageSize = 20,
|
||
...others
|
||
} = options;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-decorator': tableBlockProvider ?? 'TableBlockProvider',
|
||
'x-acl-action': `${resource || collection}:list`,
|
||
'x-decorator-props': {
|
||
collection,
|
||
resource: resource || collection,
|
||
action: 'list',
|
||
params: {
|
||
pageSize,
|
||
},
|
||
rowKey,
|
||
showIndex: true,
|
||
dragSort: false,
|
||
disableTemplate: disableTemplate ?? false,
|
||
blockType,
|
||
...others,
|
||
},
|
||
'x-designer': TableBlockDesigner ?? 'TableBlockDesigner',
|
||
'x-component': 'CardItem',
|
||
'x-filter-targets': [],
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
'x-initializer': tableActionInitializers ?? 'TableActionInitializers',
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
style: {
|
||
marginBottom: 16,
|
||
},
|
||
},
|
||
properties: {},
|
||
},
|
||
[uid()]: {
|
||
type: 'array',
|
||
'x-initializer': tableColumnInitializers ?? 'TableColumnInitializers',
|
||
'x-component': 'TableV2',
|
||
'x-component-props': {
|
||
rowKey: 'id',
|
||
rowSelection: {
|
||
type: 'checkbox',
|
||
},
|
||
useProps: '{{ useTableBlockProps }}',
|
||
},
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
title: '{{ t("Actions") }}',
|
||
'x-action-column': 'actions',
|
||
'x-decorator': 'TableV2.Column.ActionBar',
|
||
'x-component': 'TableV2.Column',
|
||
'x-designer': 'TableV2.ActionColumnDesigner',
|
||
'x-initializer': tableActionColumnInitializers ?? 'TableActionColumnInitializers',
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
'x-decorator': 'DndContext',
|
||
'x-component': 'Space',
|
||
'x-component-props': {
|
||
split: '|',
|
||
},
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
// console.log(JSON.stringify(schema, null, 2));
|
||
return schema;
|
||
};
|
||
|
||
export const createCollapseBlockSchema = (options) => {
|
||
const { collection, blockType } = options;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-decorator': 'AssociationFilter.Provider',
|
||
'x-decorator-props': {
|
||
collection,
|
||
blockType,
|
||
associationFilterStyle: {
|
||
width: '100%',
|
||
},
|
||
},
|
||
'x-designer': 'AssociationFilter.BlockDesigner',
|
||
'x-component': 'CardItem',
|
||
'x-filter-targets': [],
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-action': 'associateFilter',
|
||
'x-initializer': 'AssociationFilter.FilterBlockInitializer',
|
||
'x-component': 'AssociationFilter',
|
||
properties: {},
|
||
},
|
||
},
|
||
};
|
||
|
||
return schema;
|
||
};
|
||
|
||
export const createTableSelectorSchema = (options) => {
|
||
const { collection, resource, rowKey, ...others } = options;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-acl-action': `${resource || collection}:list`,
|
||
'x-decorator': 'TableSelectorProvider',
|
||
'x-decorator-props': {
|
||
collection,
|
||
resource: resource || collection,
|
||
action: 'list',
|
||
params: {
|
||
pageSize: 20,
|
||
},
|
||
rowKey,
|
||
...others,
|
||
},
|
||
'x-designer': 'TableSelectorDesigner',
|
||
'x-component': 'BlockItem',
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
'x-initializer': 'TableActionInitializers',
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
style: {
|
||
marginBottom: 16,
|
||
},
|
||
},
|
||
properties: {},
|
||
},
|
||
value: {
|
||
type: 'array',
|
||
'x-initializer': 'TableColumnInitializers',
|
||
'x-component': 'TableV2.Selector',
|
||
'x-component-props': {
|
||
rowSelection: {
|
||
type: 'checkbox',
|
||
},
|
||
useProps: '{{ useTableSelectorProps }}',
|
||
},
|
||
properties: {},
|
||
},
|
||
},
|
||
};
|
||
console.log(JSON.stringify(schema, null, 2));
|
||
return schema;
|
||
};
|
||
|
||
export const createCalendarBlockSchema = (options) => {
|
||
const { collection, resource, fieldNames, ...others } = options;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-acl-action': `${resource || collection}:list`,
|
||
'x-decorator': 'CalendarBlockProvider',
|
||
'x-decorator-props': {
|
||
collection: collection,
|
||
resource: resource || collection,
|
||
action: 'list',
|
||
fieldNames: {
|
||
id: 'id',
|
||
...fieldNames,
|
||
},
|
||
params: {
|
||
paginate: false,
|
||
},
|
||
...others,
|
||
},
|
||
'x-designer': 'CalendarV2.Designer',
|
||
'x-component': 'CardItem',
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-component': 'CalendarV2',
|
||
'x-component-props': {
|
||
useProps: '{{ useCalendarBlockProps }}',
|
||
},
|
||
properties: {
|
||
toolBar: {
|
||
type: 'void',
|
||
'x-component': 'CalendarV2.ActionBar',
|
||
'x-component-props': {
|
||
style: {
|
||
marginBottom: 24,
|
||
},
|
||
},
|
||
'x-initializer': 'CalendarActionInitializers',
|
||
properties: {},
|
||
},
|
||
event: {
|
||
type: 'void',
|
||
'x-component': 'CalendarV2.Event',
|
||
properties: {
|
||
drawer: {
|
||
type: 'void',
|
||
'x-component': 'Action.Drawer',
|
||
'x-component-props': {
|
||
className: 'nb-action-popup',
|
||
},
|
||
title: '{{ t("View record") }}',
|
||
properties: {
|
||
tabs: {
|
||
type: 'void',
|
||
'x-component': 'Tabs',
|
||
'x-component-props': {},
|
||
'x-initializer': 'TabPaneInitializers',
|
||
'x-initializer-props': {
|
||
gridInitializer: 'RecordBlockInitializers',
|
||
},
|
||
properties: {
|
||
tab1: {
|
||
type: 'void',
|
||
title: '{{t("Details")}}',
|
||
'x-component': 'Tabs.TabPane',
|
||
'x-designer': 'Tabs.Designer',
|
||
'x-component-props': {},
|
||
properties: {
|
||
grid: {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-initializer-props': {
|
||
actionInitializers: 'CalendarFormActionInitializers',
|
||
},
|
||
'x-initializer': 'RecordBlockInitializers',
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
console.log(JSON.stringify(schema, null, 2));
|
||
return schema;
|
||
};
|
||
|
||
export const createGanttBlockSchema = (options) => {
|
||
const { collection, resource, fieldNames, ...others } = options;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-acl-action': `${resource || collection}:list`,
|
||
'x-decorator': 'GanttBlockProvider',
|
||
'x-decorator-props': {
|
||
collection: collection,
|
||
resource: resource || collection,
|
||
action: 'list',
|
||
fieldNames: {
|
||
id: 'id',
|
||
...fieldNames,
|
||
},
|
||
params: {
|
||
paginate: false,
|
||
},
|
||
...others,
|
||
},
|
||
'x-designer': 'Gantt.Designer',
|
||
'x-component': 'CardItem',
|
||
properties: {
|
||
[uid()]: {
|
||
type: 'void',
|
||
'x-component': 'Gantt',
|
||
'x-component-props': {
|
||
useProps: '{{ useGanttBlockProps }}',
|
||
},
|
||
properties: {
|
||
toolBar: {
|
||
type: 'void',
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
style: {
|
||
marginBottom: 24,
|
||
},
|
||
},
|
||
'x-initializer': 'GanttActionInitializers',
|
||
properties: {},
|
||
},
|
||
table: {
|
||
type: 'array',
|
||
'x-decorator': 'div',
|
||
'x-decorator-props': {
|
||
style: {
|
||
float: 'left',
|
||
maxWidth: '35%',
|
||
},
|
||
},
|
||
|
||
'x-initializer': 'TableColumnInitializers',
|
||
'x-component': 'TableV2',
|
||
'x-component-props': {
|
||
rowKey: 'id',
|
||
rowSelection: {
|
||
type: 'checkbox',
|
||
},
|
||
useProps: '{{ useTableBlockProps }}',
|
||
pagination: false,
|
||
},
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
title: '{{ t("Actions") }}',
|
||
'x-action-column': 'actions',
|
||
'x-decorator': 'TableV2.Column.ActionBar',
|
||
'x-component': 'TableV2.Column',
|
||
'x-designer': 'TableV2.ActionColumnDesigner',
|
||
'x-initializer': 'TableActionColumnInitializers',
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
'x-decorator': 'DndContext',
|
||
'x-component': 'Space',
|
||
'x-component-props': {
|
||
split: '|',
|
||
},
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
detail: {
|
||
type: 'void',
|
||
'x-component': 'Gantt.Event',
|
||
properties: {
|
||
drawer: {
|
||
type: 'void',
|
||
'x-component': 'Action.Drawer',
|
||
'x-component-props': {
|
||
className: 'nb-action-popup',
|
||
},
|
||
title: '{{ t("View record") }}',
|
||
properties: {
|
||
tabs: {
|
||
type: 'void',
|
||
'x-component': 'Tabs',
|
||
'x-component-props': {},
|
||
'x-initializer': 'TabPaneInitializers',
|
||
properties: {
|
||
tab1: {
|
||
type: 'void',
|
||
title: '{{t("Details")}}',
|
||
'x-component': 'Tabs.TabPane',
|
||
'x-designer': 'Tabs.Designer',
|
||
'x-component-props': {},
|
||
properties: {
|
||
grid: {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-initializer': 'RecordBlockInitializers',
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
console.log(JSON.stringify(schema, null, 2));
|
||
return schema;
|
||
};
|
||
export const createKanbanBlockSchema = (options) => {
|
||
const { collection, resource, groupField, ...others } = options;
|
||
const schema: ISchema = {
|
||
type: 'void',
|
||
'x-acl-action': `${resource || collection}:list`,
|
||
'x-decorator': 'KanbanBlockProvider',
|
||
'x-decorator-props': {
|
||
collection: collection,
|
||
resource: resource || collection,
|
||
action: 'list',
|
||
groupField,
|
||
params: {
|
||
paginate: false,
|
||
},
|
||
...others,
|
||
},
|
||
'x-designer': 'Kanban.Designer',
|
||
'x-component': 'CardItem',
|
||
properties: {
|
||
actions: {
|
||
type: 'void',
|
||
'x-initializer': 'KanbanActionInitializers',
|
||
'x-component': 'ActionBar',
|
||
'x-component-props': {
|
||
style: {
|
||
marginBottom: 16,
|
||
},
|
||
},
|
||
properties: {},
|
||
},
|
||
[uid()]: {
|
||
type: 'array',
|
||
'x-component': 'Kanban',
|
||
'x-component-props': {
|
||
useProps: '{{ useKanbanBlockProps }}',
|
||
},
|
||
properties: {
|
||
card: {
|
||
type: 'void',
|
||
'x-read-pretty': true,
|
||
'x-label-disabled': true,
|
||
'x-decorator': 'BlockItem',
|
||
'x-component': 'Kanban.Card',
|
||
'x-component-props': {
|
||
openMode: 'drawer',
|
||
},
|
||
'x-designer': 'Kanban.Card.Designer',
|
||
properties: {
|
||
grid: {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-component-props': { dndContext: false },
|
||
},
|
||
},
|
||
},
|
||
cardViewer: {
|
||
type: 'void',
|
||
title: '{{ t("View") }}',
|
||
'x-designer': 'Action.Designer',
|
||
'x-component': 'Kanban.CardViewer',
|
||
'x-action': 'view',
|
||
'x-component-props': {
|
||
openMode: 'drawer',
|
||
},
|
||
properties: {
|
||
drawer: {
|
||
type: 'void',
|
||
title: '{{ t("View record") }}',
|
||
'x-component': 'Action.Container',
|
||
'x-component-props': {
|
||
className: 'nb-action-popup',
|
||
},
|
||
properties: {
|
||
tabs: {
|
||
type: 'void',
|
||
'x-component': 'Tabs',
|
||
'x-component-props': {},
|
||
'x-initializer': 'TabPaneInitializers',
|
||
properties: {
|
||
tab1: {
|
||
type: 'void',
|
||
title: '{{t("Details")}}',
|
||
'x-component': 'Tabs.TabPane',
|
||
'x-designer': 'Tabs.Designer',
|
||
'x-component-props': {},
|
||
properties: {
|
||
grid: {
|
||
type: 'void',
|
||
'x-component': 'Grid',
|
||
'x-initializer': 'RecordBlockInitializers',
|
||
properties: {},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
};
|
||
return schema;
|
||
};
|