mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 21:49:25 +08:00
feat(client): support linkage style in table and form (#4467)
* feat: support linkage style in table and form * fix: removed linkage rule in table column, fixed formitem style not refreshing, use colorpicker * chore: remove unused functions and improve effect execution performance * feat: add some e2e test for linkage style in table, extract linkage style logic to hooks * feat: add some e2e test * fix: fix some e2e test error * test: fix e2e tests * fix: replace deprecated api * chore: give color picker a empty string as default value * chore: improve some code * refactor: remove useless code * fix: fix some incompatibility problem of old schema * fix: fix some e2e test errors --------- Co-authored-by: Zeke Zhang <958414905@qq.com>
This commit is contained in:
parent
05cf9986b0
commit
95749f3d88
@ -21,6 +21,7 @@ import { useCreateFormBlockDecoratorProps } from '../modules/blocks/data-blocks/
|
|||||||
import { useCreateFormBlockProps } from '../modules/blocks/data-blocks/form/hooks/useCreateFormBlockProps';
|
import { useCreateFormBlockProps } from '../modules/blocks/data-blocks/form/hooks/useCreateFormBlockProps';
|
||||||
import { useEditFormBlockDecoratorProps } from '../modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps';
|
import { useEditFormBlockDecoratorProps } from '../modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps';
|
||||||
import { useEditFormBlockProps } from '../modules/blocks/data-blocks/form/hooks/useEditFormBlockProps';
|
import { useEditFormBlockProps } from '../modules/blocks/data-blocks/form/hooks/useEditFormBlockProps';
|
||||||
|
import { useDataFormItemProps } from '../modules/blocks/data-blocks/form/hooks/useDataFormItemProps';
|
||||||
import { useGridCardBlockDecoratorProps } from '../modules/blocks/data-blocks/grid-card/hooks/useGridCardBlockDecoratorProps';
|
import { useGridCardBlockDecoratorProps } from '../modules/blocks/data-blocks/grid-card/hooks/useGridCardBlockDecoratorProps';
|
||||||
import { useListBlockDecoratorProps } from '../modules/blocks/data-blocks/list/hooks/useListBlockDecoratorProps';
|
import { useListBlockDecoratorProps } from '../modules/blocks/data-blocks/list/hooks/useListBlockDecoratorProps';
|
||||||
import { useTableSelectorDecoratorProps } from '../modules/blocks/data-blocks/table-selector/hooks/useTableSelectorDecoratorProps';
|
import { useTableSelectorDecoratorProps } from '../modules/blocks/data-blocks/table-selector/hooks/useTableSelectorDecoratorProps';
|
||||||
@ -85,6 +86,7 @@ export const BlockSchemaComponentProvider: React.FC = (props) => {
|
|||||||
useFilterFormBlockDecoratorProps,
|
useFilterFormBlockDecoratorProps,
|
||||||
useGridCardBlockDecoratorProps,
|
useGridCardBlockDecoratorProps,
|
||||||
useFormItemProps,
|
useFormItemProps,
|
||||||
|
useDataFormItemProps,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
@ -145,6 +147,7 @@ export class BlockSchemaComponentPlugin extends Plugin {
|
|||||||
useFilterFormBlockDecoratorProps,
|
useFilterFormBlockDecoratorProps,
|
||||||
useGridCardBlockDecoratorProps,
|
useGridCardBlockDecoratorProps,
|
||||||
useFormItemProps,
|
useFormItemProps,
|
||||||
|
useDataFormItemProps,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,6 +426,7 @@
|
|||||||
"Option value": "Option value",
|
"Option value": "Option value",
|
||||||
"Option label": "Option label",
|
"Option label": "Option label",
|
||||||
"Color": "Color",
|
"Color": "Color",
|
||||||
|
"Background Color": "Background Color",
|
||||||
"Add option": "Add option",
|
"Add option": "Add option",
|
||||||
"Related collection": "Related collection",
|
"Related collection": "Related collection",
|
||||||
"Allow linking to multiple records": "Allow linking to multiple records",
|
"Allow linking to multiple records": "Allow linking to multiple records",
|
||||||
@ -552,6 +553,7 @@
|
|||||||
"Add condition group": "Add condition group",
|
"Add condition group": "Add condition group",
|
||||||
"exists": "exists",
|
"exists": "exists",
|
||||||
"not exists": "not exists",
|
"not exists": "not exists",
|
||||||
|
"Style": "Style",
|
||||||
"=": "=",
|
"=": "=",
|
||||||
"≠": "≠",
|
"≠": "≠",
|
||||||
">": ">",
|
">": ">",
|
||||||
|
@ -447,6 +447,7 @@
|
|||||||
"Option value": "选项值",
|
"Option value": "选项值",
|
||||||
"Option label": "选项标签",
|
"Option label": "选项标签",
|
||||||
"Color": "颜色",
|
"Color": "颜色",
|
||||||
|
"Background Color": "背景颜色",
|
||||||
"Add option": "添加选项",
|
"Add option": "添加选项",
|
||||||
"Related collection": "关系表",
|
"Related collection": "关系表",
|
||||||
"Allow linking to multiple records": "允许关联多条记录",
|
"Allow linking to multiple records": "允许关联多条记录",
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { expect, commonFormViewPage, test } from '@nocobase/test/e2e';
|
||||||
|
|
||||||
|
test.describe('field schema settings', () => {
|
||||||
|
test('linkage style color', async ({ page, mockPage, mockRecord }) => {
|
||||||
|
const nocoPage = await mockPage(commonFormViewPage).waitForInit();
|
||||||
|
await mockRecord('general', { singleLineText: 'asdfcedg' });
|
||||||
|
await nocoPage.goto();
|
||||||
|
await page.getByText('asdfcedg', { exact: true }).hover();
|
||||||
|
await page.getByLabel('block-item-CollectionField-general-details-general.singleLineText-singleLineText').hover();
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByLabel('designer-schema-settings-CollectionField-fieldSettings:FormItem-general-general.singleLineText', {
|
||||||
|
exact: true,
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Style' }).click();
|
||||||
|
await page.getByRole('button', { name: 'plus Add linkage rule' }).click();
|
||||||
|
await page.getByText('Add property').click();
|
||||||
|
await page.getByTestId('select-linkage-properties').click();
|
||||||
|
await page.getByText('Color', { exact: true }).click();
|
||||||
|
await page.getByLabel('color-picker-normal').click();
|
||||||
|
await page.locator('input[type="text"]').fill('A34FCC');
|
||||||
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
const cell = await page
|
||||||
|
.getByLabel('block-item-CollectionField-general-details-general.singleLineText-singleLineText')
|
||||||
|
.locator('div.ant-formily-item-control-content-component');
|
||||||
|
await expect(cell).toHaveCSS('color', 'rgb(163, 79, 204)');
|
||||||
|
});
|
||||||
|
test('linkage style background color', async ({ page, mockPage, mockRecord }) => {
|
||||||
|
const nocoPage = await mockPage(commonFormViewPage).waitForInit();
|
||||||
|
await mockRecord('general', { singleLineText: 'asdfcedg' });
|
||||||
|
await nocoPage.goto();
|
||||||
|
await page.getByText('asdfcedg', { exact: true }).hover();
|
||||||
|
await page.getByLabel('block-item-CollectionField-general-details-general.singleLineText-singleLineText').hover();
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByLabel('designer-schema-settings-CollectionField-fieldSettings:FormItem-general-general.singleLineText', {
|
||||||
|
exact: true,
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Style' }).click();
|
||||||
|
await page.getByRole('button', { name: 'plus Add linkage rule' }).click();
|
||||||
|
await page.getByText('Add property').click();
|
||||||
|
await page.getByTestId('select-linkage-properties').click();
|
||||||
|
await page.getByText('Background Color', { exact: true }).click();
|
||||||
|
await page.getByLabel('color-picker-normal').click();
|
||||||
|
await page.locator('input[type="text"]').fill('A34FCC');
|
||||||
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
const cell = await page
|
||||||
|
.getByLabel('block-item-CollectionField-general-details-general.singleLineText-singleLineText')
|
||||||
|
.locator('div.ant-formily-item-control-content-component');
|
||||||
|
await expect(cell).toHaveCSS('background-color', 'rgb(163, 79, 204)');
|
||||||
|
});
|
||||||
|
});
|
@ -242,6 +242,10 @@ describe('FieldSettingsFormItem', () => {
|
|||||||
title: 'Pattern',
|
title: 'Pattern',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Style',
|
||||||
|
type: 'modal',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Set validation rules',
|
title: 'Set validation rules',
|
||||||
type: 'modal',
|
type: 'modal',
|
||||||
@ -284,6 +288,10 @@ describe('FieldSettingsFormItem', () => {
|
|||||||
title: 'Pattern',
|
title: 'Pattern',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Style',
|
||||||
|
type: 'modal',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Field component',
|
title: 'Field component',
|
||||||
type: 'select',
|
type: 'select',
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
import React from 'react';
|
||||||
import { ArrayCollapse, FormLayout } from '@formily/antd-v5';
|
import { ArrayCollapse, FormLayout } from '@formily/antd-v5';
|
||||||
import { Field } from '@formily/core';
|
import { Field } from '@formily/core';
|
||||||
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
||||||
@ -16,6 +16,7 @@ import { useApp, useSchemaToolbar } from '../../../../application';
|
|||||||
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
||||||
import { useFormBlockContext } from '../../../../block-provider/FormBlockProvider';
|
import { useFormBlockContext } from '../../../../block-provider/FormBlockProvider';
|
||||||
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../../../collection-manager';
|
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../../../collection-manager';
|
||||||
|
import { useCollection } from '../../../../data-source';
|
||||||
import { useFieldComponentName } from '../../../../common/useFieldComponentName';
|
import { useFieldComponentName } from '../../../../common/useFieldComponentName';
|
||||||
import { useDesignable, useValidateSchema } from '../../../../schema-component';
|
import { useDesignable, useValidateSchema } from '../../../../schema-component';
|
||||||
import { useIsFormReadPretty } from '../../../../schema-component/antd/form-item/FormItem.Settings';
|
import { useIsFormReadPretty } from '../../../../schema-component/antd/form-item/FormItem.Settings';
|
||||||
@ -24,7 +25,8 @@ import { isPatternDisabled } from '../../../../schema-settings';
|
|||||||
import { ActionType } from '../../../../schema-settings/LinkageRules/type';
|
import { ActionType } from '../../../../schema-settings/LinkageRules/type';
|
||||||
import { SchemaSettingsDefaultValue } from '../../../../schema-settings/SchemaSettingsDefaultValue';
|
import { SchemaSettingsDefaultValue } from '../../../../schema-settings/SchemaSettingsDefaultValue';
|
||||||
import { useIsAllowToSetDefaultValue } from '../../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
import { useIsAllowToSetDefaultValue } from '../../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
||||||
|
import { SchemaSettingsLinkageRules } from '../../../../schema-settings';
|
||||||
|
import { useIsFieldReadPretty } from '../../../../schema-component/antd/form-item/FormItem.Settings';
|
||||||
export const fieldSettingsFormItem = new SchemaSettings({
|
export const fieldSettingsFormItem = new SchemaSettings({
|
||||||
name: 'fieldSettings:FormItem',
|
name: 'fieldSettings:FormItem',
|
||||||
items: [
|
items: [
|
||||||
@ -442,6 +444,25 @@ export const fieldSettingsFormItem = new SchemaSettings({
|
|||||||
return form && !isFormReadPretty && validateSchema;
|
return form && !isFormReadPretty && validateSchema;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'style',
|
||||||
|
Component: (props) => {
|
||||||
|
const localProps = { ...props, category: 'style' };
|
||||||
|
return <SchemaSettingsLinkageRules {...localProps} />;
|
||||||
|
},
|
||||||
|
useVisible() {
|
||||||
|
const isFieldReadPretty = useIsFieldReadPretty();
|
||||||
|
return isFieldReadPretty;
|
||||||
|
},
|
||||||
|
useComponentProps() {
|
||||||
|
const { name } = useCollection();
|
||||||
|
const { linkageRulesProps } = useSchemaToolbar();
|
||||||
|
return {
|
||||||
|
...linkageRulesProps,
|
||||||
|
collectionName: name,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useForm } from '@formily/react';
|
||||||
|
import { useSatisfiedActionValues } from '../../../../../schema-settings/LinkageRules/useActionValues';
|
||||||
|
export function useDataFormItemProps() {
|
||||||
|
const form = useForm();
|
||||||
|
const { valueMap: style } = useSatisfiedActionValues({ category: 'style', formValues: form?.values });
|
||||||
|
return { wrapperStyle: style };
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { expect, oneTableBlockWithIntegerAndIDColumn, test } from '@nocobase/test/e2e';
|
||||||
|
|
||||||
|
test.describe('view', () => {
|
||||||
|
test('linkage style color', async ({ page, mockPage, mockRecord }) => {
|
||||||
|
const nocoPage = await mockPage(oneTableBlockWithIntegerAndIDColumn).waitForInit();
|
||||||
|
await mockRecord('general', { integer: '423' });
|
||||||
|
await nocoPage.goto();
|
||||||
|
|
||||||
|
await page.getByText('integer', { exact: true }).hover();
|
||||||
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'designer-schema-settings-TableV2.Column-fieldSettings:TableColumn-general',
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Style' }).click();
|
||||||
|
await page.getByRole('button', { name: 'plus Add linkage rule' }).click();
|
||||||
|
await page.getByText('Add property').click();
|
||||||
|
await page.getByTestId('select-linkage-properties').click();
|
||||||
|
await page.getByText('Color', { exact: true }).click();
|
||||||
|
await page.getByLabel('color-picker-normal').click();
|
||||||
|
await page.locator('input[type="text"]').fill('A34FCC');
|
||||||
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
const cell = page.getByRole('button', { name: '423' });
|
||||||
|
const color = await cell.evaluate((el) => getComputedStyle(el).color);
|
||||||
|
expect(color).toContain('163, 79, 204');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('linkage style background color', async ({ page, mockPage, mockRecord }) => {
|
||||||
|
const nocoPage = await mockPage(oneTableBlockWithIntegerAndIDColumn).waitForInit();
|
||||||
|
await mockRecord('general', { integer: '423' });
|
||||||
|
await nocoPage.goto();
|
||||||
|
await page.getByText('integer', { exact: true }).hover();
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByRole('button', {
|
||||||
|
name: 'designer-schema-settings-TableV2.Column-fieldSettings:TableColumn-general',
|
||||||
|
})
|
||||||
|
.click();
|
||||||
|
await page.getByRole('menuitem', { name: 'Style' }).click();
|
||||||
|
await page.getByRole('button', { name: 'plus Add linkage rule' }).click();
|
||||||
|
await page.getByText('Add property').click();
|
||||||
|
await page.getByTestId('select-linkage-properties').click();
|
||||||
|
await page.getByText('Background Color', { exact: true }).click();
|
||||||
|
await page.getByLabel('color-picker-normal').click();
|
||||||
|
await page.locator('input[type="text"]').fill('A34FCC');
|
||||||
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
const cell = page.getByRole('button', { name: '423' });
|
||||||
|
const bgColor = await cell.evaluate((el) => getComputedStyle(el.parentElement).backgroundColor);
|
||||||
|
expect(bgColor).toContain('163, 79, 204');
|
||||||
|
});
|
||||||
|
});
|
@ -7,10 +7,11 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
import { ISchema } from '@formily/json-schema';
|
import { ISchema } from '@formily/json-schema';
|
||||||
import { useField, useFieldSchema } from '@formily/react';
|
import { useField, useFieldSchema } from '@formily/react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useApp } from '../../../../application';
|
import { useApp, useSchemaToolbar } from '../../../../application';
|
||||||
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
||||||
import { useCollectionManager_deprecated } from '../../../../collection-manager';
|
import { useCollectionManager_deprecated } from '../../../../collection-manager';
|
||||||
import { useFieldComponentName } from '../../../../common/useFieldComponentName';
|
import { useFieldComponentName } from '../../../../common/useFieldComponentName';
|
||||||
@ -20,6 +21,7 @@ import { useAssociationFieldContext } from '../../../../schema-component/antd/as
|
|||||||
import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator';
|
import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator';
|
||||||
import { SchemaSettingsDefaultValue } from '../../../../schema-settings/SchemaSettingsDefaultValue';
|
import { SchemaSettingsDefaultValue } from '../../../../schema-settings/SchemaSettingsDefaultValue';
|
||||||
import { isPatternDisabled } from '../../../../schema-settings/isPatternDisabled';
|
import { isPatternDisabled } from '../../../../schema-settings/isPatternDisabled';
|
||||||
|
import { SchemaSettingsLinkageRules } from '../../../../schema-settings';
|
||||||
|
|
||||||
export const tableColumnSettings = new SchemaSettings({
|
export const tableColumnSettings = new SchemaSettings({
|
||||||
name: 'fieldSettings:TableColumn',
|
name: 'fieldSettings:TableColumn',
|
||||||
@ -44,7 +46,6 @@ export const tableColumnSettings = new SchemaSettings({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const columnSchema = useFieldSchema();
|
const columnSchema = useFieldSchema();
|
||||||
const { dn } = useDesignable();
|
const { dn } = useDesignable();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: t('Custom column title'),
|
title: t('Custom column title'),
|
||||||
schema: {
|
schema: {
|
||||||
@ -79,6 +80,30 @@ export const tableColumnSettings = new SchemaSettings({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'style',
|
||||||
|
Component: (props) => {
|
||||||
|
const localProps = { ...props, category: 'style' };
|
||||||
|
return <SchemaSettingsLinkageRules {...localProps} />;
|
||||||
|
},
|
||||||
|
useVisible() {
|
||||||
|
const { fieldSchema } = useColumnSchema();
|
||||||
|
const field: any = useField();
|
||||||
|
const path = field.path?.splice(field.path?.length - 1, 1);
|
||||||
|
if (fieldSchema) {
|
||||||
|
const isReadPretty = field.form.query(`${path.concat(`*.` + fieldSchema.name)}`).get('readPretty');
|
||||||
|
return isReadPretty;
|
||||||
|
} else return false;
|
||||||
|
},
|
||||||
|
useComponentProps() {
|
||||||
|
const { name } = useCollection();
|
||||||
|
const { linkageRulesProps } = useSchemaToolbar();
|
||||||
|
return {
|
||||||
|
...linkageRulesProps,
|
||||||
|
collectionName: name,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'columnWidth',
|
name: 'columnWidth',
|
||||||
type: 'modal',
|
type: 'modal',
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
import { css, cx } from '@emotion/css';
|
import { css, cx } from '@emotion/css';
|
||||||
import { IFormItemProps, FormItem as Item } from '@formily/antd-v5';
|
import { IFormItemProps, FormItem as Item } from '@formily/antd-v5';
|
||||||
import { Field } from '@formily/core';
|
import { Field } from '@formily/core';
|
||||||
import { observer, useField, useFieldSchema } from '@formily/react';
|
import { observer, useField, useFieldSchema, useForm } from '@formily/react';
|
||||||
import React, { useEffect, useMemo } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import { ACLCollectionFieldProvider } from '../../../acl/ACLProvider';
|
import { ACLCollectionFieldProvider } from '../../../acl/ACLProvider';
|
||||||
import { useApp } from '../../../application';
|
import { useApp } from '../../../application';
|
||||||
@ -19,14 +19,14 @@ import { Collection_deprecated } from '../../../collection-manager';
|
|||||||
import { CollectionFieldProvider } from '../../../data-source/collection-field/CollectionFieldProvider';
|
import { CollectionFieldProvider } from '../../../data-source/collection-field/CollectionFieldProvider';
|
||||||
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
|
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
|
||||||
import { GeneralSchemaDesigner } from '../../../schema-settings';
|
import { GeneralSchemaDesigner } from '../../../schema-settings';
|
||||||
import { useVariables } from '../../../variables';
|
|
||||||
import useContextVariable from '../../../variables/hooks/useContextVariable';
|
|
||||||
import { BlockItem } from '../block-item';
|
import { BlockItem } from '../block-item';
|
||||||
import { HTMLEncode } from '../input/shared';
|
import { HTMLEncode } from '../input/shared';
|
||||||
import { FilterFormDesigner } from './FormItem.FilterFormDesigner';
|
import { FilterFormDesigner } from './FormItem.FilterFormDesigner';
|
||||||
import { useEnsureOperatorsValid } from './SchemaSettingOptions';
|
import { useEnsureOperatorsValid } from './SchemaSettingOptions';
|
||||||
import useLazyLoadDisplayAssociationFieldsOfForm from './hooks/useLazyLoadDisplayAssociationFieldsOfForm';
|
import useLazyLoadDisplayAssociationFieldsOfForm from './hooks/useLazyLoadDisplayAssociationFieldsOfForm';
|
||||||
import useParseDefaultValue from './hooks/useParseDefaultValue';
|
import useParseDefaultValue from './hooks/useParseDefaultValue';
|
||||||
|
import { useVariables, useContextVariable } from '../../../variables';
|
||||||
|
import { useDataFormItemProps } from '../../../modules/blocks/data-blocks/form/hooks/useDataFormItemProps';
|
||||||
|
|
||||||
Item.displayName = 'FormilyFormItem';
|
Item.displayName = 'FormilyFormItem';
|
||||||
|
|
||||||
@ -47,14 +47,14 @@ export const FormItem: any = withDynamicSchemaProps(
|
|||||||
useEnsureOperatorsValid();
|
useEnsureOperatorsValid();
|
||||||
const field = useField<Field>();
|
const field = useField<Field>();
|
||||||
const schema = useFieldSchema();
|
const schema = useFieldSchema();
|
||||||
const contextVariable = useContextVariable();
|
|
||||||
const variables = useVariables();
|
|
||||||
const { addActiveFieldName } = useFormActiveFields() || {};
|
const { addActiveFieldName } = useFormActiveFields() || {};
|
||||||
|
const form = useForm();
|
||||||
|
const { wrapperStyle } = useDataFormItemProps();
|
||||||
|
const variables = useVariables();
|
||||||
|
const contextVariable = useContextVariable();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
variables?.registerVariable(contextVariable);
|
variables?.registerVariable(contextVariable);
|
||||||
}, [contextVariable]);
|
}, [contextVariable, variables]);
|
||||||
|
|
||||||
// 需要放在注冊完变量之后
|
// 需要放在注冊完变量之后
|
||||||
useParseDefaultValue();
|
useParseDefaultValue();
|
||||||
useLazyLoadDisplayAssociationFieldsOfForm();
|
useLazyLoadDisplayAssociationFieldsOfForm();
|
||||||
@ -87,7 +87,7 @@ export const FormItem: any = withDynamicSchemaProps(
|
|||||||
<CollectionFieldProvider allowNull={true}>
|
<CollectionFieldProvider allowNull={true}>
|
||||||
<BlockItem className={'nb-form-item'}>
|
<BlockItem className={'nb-form-item'}>
|
||||||
<ACLCollectionFieldProvider>
|
<ACLCollectionFieldProvider>
|
||||||
<Item className={className} {...props} extra={extra} />
|
<Item className={className} {...props} extra={extra} wrapperStyle={wrapperStyle} />
|
||||||
</ACLCollectionFieldProvider>
|
</ACLCollectionFieldProvider>
|
||||||
</BlockItem>
|
</BlockItem>
|
||||||
</CollectionFieldProvider>
|
</CollectionFieldProvider>
|
||||||
|
@ -30,6 +30,9 @@ import { isPatternDisabled } from '../../../schema-settings/isPatternDisabled';
|
|||||||
import { useCompile, useDesignable, useFieldModeOptions } from '../../hooks';
|
import { useCompile, useDesignable, useFieldModeOptions } from '../../hooks';
|
||||||
import { useAssociationFieldContext } from '../association-field/hooks';
|
import { useAssociationFieldContext } from '../association-field/hooks';
|
||||||
import { removeNullCondition } from '../filter';
|
import { removeNullCondition } from '../filter';
|
||||||
|
import { SchemaSettingsLinkageRules } from '../../../schema-settings';
|
||||||
|
import { useCollection } from '../../../data-source';
|
||||||
|
import { useSchemaToolbar } from '../../../application';
|
||||||
|
|
||||||
export const useLabelFields = (collectionName?: any) => {
|
export const useLabelFields = (collectionName?: any) => {
|
||||||
// 需要在组件顶层调用
|
// 需要在组件顶层调用
|
||||||
@ -98,6 +101,12 @@ export const TableColumnDesigner = (props) => {
|
|||||||
readOnlyMode = 'read-pretty';
|
readOnlyMode = 'read-pretty';
|
||||||
}
|
}
|
||||||
const isSelectFieldMode = isAssociationField && fieldMode === 'Select';
|
const isSelectFieldMode = isAssociationField && fieldMode === 'Select';
|
||||||
|
|
||||||
|
const StyleSetting = () => {
|
||||||
|
const { name } = useCollection();
|
||||||
|
const { linkageRulesProps } = useSchemaToolbar();
|
||||||
|
return <SchemaSettingsLinkageRules category={'style'} {...{ ...linkageRulesProps, collectionName: name }} />;
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<GeneralSchemaDesigner disableInitializer>
|
<GeneralSchemaDesigner disableInitializer>
|
||||||
<SchemaSettingsModalItem
|
<SchemaSettingsModalItem
|
||||||
@ -186,6 +195,7 @@ export const TableColumnDesigner = (props) => {
|
|||||||
dn.refresh();
|
dn.refresh();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<StyleSetting />
|
||||||
{interfaceCfg && interfaceCfg.sortable === true && !currentMode && (
|
{interfaceCfg && interfaceCfg.sortable === true && !currentMode && (
|
||||||
<SchemaSettingsSwitchItem
|
<SchemaSettingsSwitchItem
|
||||||
title={t('Sortable')}
|
title={t('Sortable')}
|
||||||
|
@ -37,11 +37,11 @@ import {
|
|||||||
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
|
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
|
||||||
import { isNewRecord } from '../../../data-source/collection-record/isNewRecord';
|
import { isNewRecord } from '../../../data-source/collection-record/isNewRecord';
|
||||||
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
|
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
|
||||||
|
import { useSatisfiedActionValues } from '../../../schema-settings/LinkageRules/useActionValues';
|
||||||
import { useToken } from '../__builtins__';
|
import { useToken } from '../__builtins__';
|
||||||
import { SubFormProvider } from '../association-field/hooks';
|
import { SubFormProvider } from '../association-field/hooks';
|
||||||
import { ColumnFieldProvider } from './components/ColumnFieldProvider';
|
import { ColumnFieldProvider } from './components/ColumnFieldProvider';
|
||||||
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
|
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
|
||||||
|
|
||||||
const MemoizedAntdTable = React.memo(AntdTable);
|
const MemoizedAntdTable = React.memo(AntdTable);
|
||||||
|
|
||||||
const useArrayField = (props) => {
|
const useArrayField = (props) => {
|
||||||
@ -145,6 +145,9 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
|
|||||||
</SubFormProvider>
|
</SubFormProvider>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
onCell: (record) => {
|
||||||
|
return { record, schema: s };
|
||||||
|
},
|
||||||
} as TableColumnProps<any>;
|
} as TableColumnProps<any>;
|
||||||
|
|
||||||
// 这里不能把 columnsSchema 作为依赖,因为其每次都会变化,这里使用 hasChangedColumns 作为依赖
|
// 这里不能把 columnsSchema 作为依赖,因为其每次都会变化,这里使用 hasChangedColumns 作为依赖
|
||||||
@ -529,16 +532,17 @@ export const Table: any = withDynamicSchemaProps(
|
|||||||
const BodyCellComponent = useCallback(
|
const BodyCellComponent = useCallback(
|
||||||
(props) => {
|
(props) => {
|
||||||
const isIndex = props.className?.includes('selection-column');
|
const isIndex = props.className?.includes('selection-column');
|
||||||
|
const { record, schema } = props;
|
||||||
const { ref, inView } = useInView({
|
const { ref, inView } = useInView({
|
||||||
threshold: 0,
|
threshold: 0,
|
||||||
triggerOnce: true,
|
triggerOnce: true,
|
||||||
initialInView: isIndex || !!process.env.__E2E__ || dataSource.length <= 10,
|
initialInView: isIndex || !!process.env.__E2E__ || dataSource.length <= 10,
|
||||||
skip: isIndex || !!process.env.__E2E__,
|
skip: isIndex || !!process.env.__E2E__,
|
||||||
});
|
});
|
||||||
|
const { valueMap: style } = useSatisfiedActionValues({ formValues: record, category: 'style', schema });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<td {...props} ref={ref} className={classNames(props.className, cellClass)}>
|
<td {...props} ref={ref} className={classNames(props.className, cellClass)} style={style}>
|
||||||
{inView || isIndex ? props.children : <Skeleton.Button style={{ height: '100%' }} />}
|
{inView || isIndex ? props.children : <Skeleton.Button style={{ height: '100%' }} />}
|
||||||
</td>
|
</td>
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
import React from 'react';
|
||||||
import { Field } from '@formily/core';
|
import { Field } from '@formily/core';
|
||||||
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -14,6 +14,9 @@ import { useDesignable } from '../schema-component';
|
|||||||
import { SchemaSettingOptions } from '../application';
|
import { SchemaSettingOptions } from '../application';
|
||||||
import { useSchemaToolbar } from '../application/schema-toolbar';
|
import { useSchemaToolbar } from '../application/schema-toolbar';
|
||||||
import { useCollection_deprecated, useCollectionManager_deprecated } from '../collection-manager';
|
import { useCollection_deprecated, useCollectionManager_deprecated } from '../collection-manager';
|
||||||
|
import { SchemaSettingsLinkageRules } from '../schema-settings';
|
||||||
|
import { useIsFieldReadPretty } from '../schema-component';
|
||||||
|
import { useCollection } from '../data-source';
|
||||||
|
|
||||||
export const generalSettingsItems: SchemaSettingOptions['items'] = [
|
export const generalSettingsItems: SchemaSettingOptions['items'] = [
|
||||||
{
|
{
|
||||||
@ -216,4 +219,23 @@ export const generalSettingsItems: SchemaSettingOptions['items'] = [
|
|||||||
return !field.readPretty && fieldSchema['x-component'] !== 'FormField' && required;
|
return !field.readPretty && fieldSchema['x-component'] !== 'FormField' && required;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'style',
|
||||||
|
Component: (props) => {
|
||||||
|
const localProps = { ...props, category: 'style' };
|
||||||
|
return <SchemaSettingsLinkageRules {...localProps} />;
|
||||||
|
},
|
||||||
|
useVisible() {
|
||||||
|
const isFieldReadPretty = useIsFieldReadPretty();
|
||||||
|
return isFieldReadPretty;
|
||||||
|
},
|
||||||
|
useComponentProps() {
|
||||||
|
const { name } = useCollection();
|
||||||
|
const { linkageRulesProps } = useSchemaToolbar();
|
||||||
|
return {
|
||||||
|
...linkageRulesProps,
|
||||||
|
collectionName: name,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
@ -184,3 +184,67 @@ export const FormButtonLinkageRuleAction = observer(
|
|||||||
},
|
},
|
||||||
{ displayName: 'FormButtonLinkageRuleAction' },
|
{ displayName: 'FormButtonLinkageRuleAction' },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const FormStyleLinkageRuleAction = observer(
|
||||||
|
(props: any) => {
|
||||||
|
const { value, options, collectionName } = props;
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const compile = useCompile();
|
||||||
|
const remove = useContext(RemoveActionContext);
|
||||||
|
const { operator, setOperator, value: fieldValue, setValue } = useValues(options);
|
||||||
|
const operators = useMemo(
|
||||||
|
() =>
|
||||||
|
compile([
|
||||||
|
{ label: t('Color'), value: ActionType.Color, schema: {} },
|
||||||
|
{ label: t('Background Color'), value: ActionType.BackgroundColor, schema: {} },
|
||||||
|
]),
|
||||||
|
[compile, t],
|
||||||
|
);
|
||||||
|
const schema = {
|
||||||
|
type: 'string',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'ColorPicker',
|
||||||
|
'x-component-props': {
|
||||||
|
defaultValue: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChange = useCallback(
|
||||||
|
(value) => {
|
||||||
|
setOperator(value);
|
||||||
|
},
|
||||||
|
[setOperator],
|
||||||
|
);
|
||||||
|
|
||||||
|
const closeStyle = useMemo(() => ({ color: '#bfbfbf' }), []);
|
||||||
|
return (
|
||||||
|
<div style={{ marginBottom: 8 }}>
|
||||||
|
<Space>
|
||||||
|
<Select
|
||||||
|
data-testid="select-linkage-properties"
|
||||||
|
popupMatchSelectWidth={false}
|
||||||
|
value={operator}
|
||||||
|
options={operators}
|
||||||
|
onChange={onChange}
|
||||||
|
placeholder={t('action')}
|
||||||
|
/>
|
||||||
|
{[ActionType.Color, ActionType.BackgroundColor].includes(operator) && (
|
||||||
|
<ValueDynamicComponent
|
||||||
|
fieldValue={fieldValue}
|
||||||
|
schema={schema}
|
||||||
|
setValue={setValue}
|
||||||
|
collectionName={collectionName}
|
||||||
|
inputModes={['constant']}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!props.disabled && (
|
||||||
|
<a role="button" aria-label="icon-close">
|
||||||
|
<CloseCircleOutlined onClick={remove} style={closeStyle} />
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'FormStyleLinkageRuleAction' },
|
||||||
|
);
|
||||||
|
@ -14,22 +14,28 @@ import React, { useCallback, useMemo } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps';
|
import { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps';
|
||||||
import { useProps } from '../../schema-component/hooks/useProps';
|
import { useProps } from '../../schema-component/hooks/useProps';
|
||||||
import { FormButtonLinkageRuleAction, FormFieldLinkageRuleAction } from './LinkageRuleAction';
|
import {
|
||||||
|
FormButtonLinkageRuleAction,
|
||||||
|
FormFieldLinkageRuleAction,
|
||||||
|
FormStyleLinkageRuleAction,
|
||||||
|
} from './LinkageRuleAction';
|
||||||
import { RemoveActionContext } from './context';
|
import { RemoveActionContext } from './context';
|
||||||
export const LinkageRuleActions = observer(
|
export const LinkageRuleActions = observer(
|
||||||
(props: any): any => {
|
(props: any): any => {
|
||||||
const { type, linkageOptions } = props;
|
const { linkageOptions, category, elementType } = props;
|
||||||
const field = useField<ArrayFieldModel>();
|
const field = useField<ArrayFieldModel>();
|
||||||
|
const type = category === 'default' ? elementType : category;
|
||||||
|
const componentMap: {
|
||||||
|
[key in LinkageRuleActionGroupProps['type']]: any;
|
||||||
|
} = {
|
||||||
|
button: FormButtonLinkageRuleAction,
|
||||||
|
field: FormFieldLinkageRuleAction,
|
||||||
|
style: FormStyleLinkageRuleAction,
|
||||||
|
};
|
||||||
return field?.value?.map((item, index) => {
|
return field?.value?.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<RemoveActionContext.Provider key={index} value={() => field.remove(index)}>
|
<RemoveActionContext.Provider key={index} value={() => field.remove(index)}>
|
||||||
<ObjectField
|
<ObjectField name={index} component={[componentMap[type], { ...props, options: linkageOptions }]} />
|
||||||
name={index}
|
|
||||||
component={[
|
|
||||||
type === 'button' ? FormButtonLinkageRuleAction : FormFieldLinkageRuleAction,
|
|
||||||
{ ...props, options: linkageOptions },
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</RemoveActionContext.Provider>
|
</RemoveActionContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -37,8 +43,8 @@ export const LinkageRuleActions = observer(
|
|||||||
{ displayName: 'LinkageRuleActions' },
|
{ displayName: 'LinkageRuleActions' },
|
||||||
);
|
);
|
||||||
|
|
||||||
interface LinkageRuleActionGroupProps {
|
export interface LinkageRuleActionGroupProps {
|
||||||
type: 'button' | 'field';
|
type: 'button' | 'field' | 'style';
|
||||||
linkageOptions: any;
|
linkageOptions: any;
|
||||||
collectionName: string;
|
collectionName: string;
|
||||||
}
|
}
|
||||||
@ -50,12 +56,11 @@ export const LinkageRuleActionGroup = withDynamicSchemaProps(
|
|||||||
const logic = 'actions';
|
const logic = 'actions';
|
||||||
|
|
||||||
// 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema
|
// 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema
|
||||||
const { type, linkageOptions, collectionName } = useProps(props);
|
const { category, elementType, linkageOptions, collectionName } = useProps(props);
|
||||||
|
|
||||||
const style = useMemo(() => ({ marginLeft: 10 }), []);
|
const style = useMemo(() => ({ marginLeft: 10 }), []);
|
||||||
const components = useMemo(
|
const components = useMemo(
|
||||||
() => [LinkageRuleActions, { type, linkageOptions, collectionName }],
|
() => [LinkageRuleActions, { category, elementType, linkageOptions, collectionName }],
|
||||||
[collectionName, linkageOptions, type],
|
[collectionName, linkageOptions, category, elementType],
|
||||||
);
|
);
|
||||||
const spaceStyle = useMemo(() => ({ marginTop: 8, marginBottom: 8 }), []);
|
const spaceStyle = useMemo(() => ({ marginTop: 8, marginBottom: 8 }), []);
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
|
@ -19,15 +19,17 @@ import { DynamicComponent } from './DynamicComponent';
|
|||||||
|
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
|
|
||||||
|
export type InputModeType = 'constant' | 'express' | 'empty';
|
||||||
interface ValueDynamicComponentProps {
|
interface ValueDynamicComponentProps {
|
||||||
fieldValue: any;
|
fieldValue: any;
|
||||||
schema: any;
|
schema: any;
|
||||||
setValue: (value: any) => void;
|
setValue: (value: any) => void;
|
||||||
collectionName: string;
|
collectionName: string;
|
||||||
|
inputModes?: Array<InputModeType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ValueDynamicComponent = (props: ValueDynamicComponentProps) => {
|
export const ValueDynamicComponent = (props: ValueDynamicComponentProps) => {
|
||||||
const { fieldValue, schema, setValue, collectionName } = props;
|
const { fieldValue, schema, setValue, collectionName, inputModes } = props;
|
||||||
const [mode, setMode] = useState(fieldValue?.mode || 'constant');
|
const [mode, setMode] = useState(fieldValue?.mode || 'constant');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { form } = useFormBlockContext();
|
const { form } = useFormBlockContext();
|
||||||
@ -111,6 +113,22 @@ export const ValueDynamicComponent = (props: ValueDynamicComponentProps) => {
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isModeContained = (mode: InputModeType) => {
|
||||||
|
if (!inputModes) return true;
|
||||||
|
else {
|
||||||
|
return inputModes.indexOf(mode) > -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
type Options = Array<{ value: InputModeType; label: string }>;
|
||||||
|
|
||||||
|
const options: Options = (
|
||||||
|
[
|
||||||
|
{ value: 'constant', label: t('Constant value') },
|
||||||
|
{ value: 'express', label: t('Expression') },
|
||||||
|
{ value: 'empty', label: t('Empty') },
|
||||||
|
] as const
|
||||||
|
).filter((option) => isModeContained(option.value));
|
||||||
return (
|
return (
|
||||||
<Input.Group compact>
|
<Input.Group compact>
|
||||||
<Select
|
<Select
|
||||||
@ -126,9 +144,11 @@ export const ValueDynamicComponent = (props: ValueDynamicComponentProps) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Option value="constant">{t('Constant value')}</Option>
|
{options.map((option) => (
|
||||||
<Option value="express">{t('Expression')}</Option>
|
<Option value={option.value} key={option.value}>
|
||||||
<Option value="empty">{t('Empty')}</Option>
|
{option.label}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
{modeMap[mode]}
|
{modeMap[mode]}
|
||||||
</Input.Group>
|
</Input.Group>
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ActionType } from './type';
|
||||||
|
import { InputModeType } from './ValueDynamicComponent';
|
||||||
|
import { conditionAnalyses } from '../../schema-component/common/utils/uitls';
|
||||||
|
const getActionValue = (operator, value) => {
|
||||||
|
const getValueByMode = (value) => {
|
||||||
|
const mode = value?.mode as InputModeType;
|
||||||
|
if (mode === 'constant') {
|
||||||
|
return value.value;
|
||||||
|
} else return null;
|
||||||
|
};
|
||||||
|
switch (true) {
|
||||||
|
case [ActionType.Color, ActionType.BackgroundColor].includes(operator):
|
||||||
|
return getValueByMode(value);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSatisfiedActions = async ({ rules, variables, localVariables }) => {
|
||||||
|
const satisfiedRules = (
|
||||||
|
await Promise.all(
|
||||||
|
rules
|
||||||
|
.filter((k) => !k.disabled)
|
||||||
|
.map(async (rule) => {
|
||||||
|
if (await conditionAnalyses({ ruleGroup: rule.condition, variables, localVariables })) {
|
||||||
|
return rule;
|
||||||
|
} else return null;
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
).filter(Boolean);
|
||||||
|
return satisfiedRules.map((rule) => rule.actions).flat();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSatisfiedValues = async ({ rules, variables, localVariables }) => {
|
||||||
|
return (await getSatisfiedActions({ rules, variables, localVariables })).map((action) => ({
|
||||||
|
...action,
|
||||||
|
value: getActionValue(action.operator, action.value),
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSatisfiedValueMap = async ({ rules, variables, localVariables }) => {
|
||||||
|
const values = await getSatisfiedValues({ rules, variables, localVariables });
|
||||||
|
const valueMap = values.reduce((a, v) => ({ ...a, [v.operator]: v.value }), {});
|
||||||
|
return valueMap;
|
||||||
|
};
|
@ -19,4 +19,16 @@ export enum ActionType {
|
|||||||
Disabled = 'disabled',
|
Disabled = 'disabled',
|
||||||
Value = 'value',
|
Value = 'value',
|
||||||
Active = 'enabled',
|
Active = 'enabled',
|
||||||
|
Color = 'color',
|
||||||
|
BackgroundColor = 'backgroundColor',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum LinkageRuleCategory {
|
||||||
|
default = 'default',
|
||||||
|
style = 'style',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LinkageRuleDataKeyMap: Record<`${LinkageRuleCategory}`, string> = {
|
||||||
|
[LinkageRuleCategory.style]: 'x-linkage-style-rules',
|
||||||
|
[LinkageRuleCategory.default]: 'x-linkage-rules',
|
||||||
|
};
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useVariables, useLocalVariables } from '../../variables';
|
||||||
|
import { useFieldSchema } from '@formily/react';
|
||||||
|
import { LinkageRuleCategory, LinkageRuleDataKeyMap } from './type';
|
||||||
|
import { getSatisfiedValueMap } from './compute-rules';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
export function useSatisfiedActionValues({
|
||||||
|
formValues,
|
||||||
|
category = 'default',
|
||||||
|
rules,
|
||||||
|
schema,
|
||||||
|
}: {
|
||||||
|
category: `${LinkageRuleCategory}`;
|
||||||
|
formValues: Record<string, any>;
|
||||||
|
rules?: any;
|
||||||
|
schema?: any;
|
||||||
|
}) {
|
||||||
|
const [valueMap, setValueMap] = useState({});
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
const variables = useVariables();
|
||||||
|
const localVariables = useLocalVariables({ currentForm: { values: formValues } as any });
|
||||||
|
const localSchema = schema ?? fieldSchema;
|
||||||
|
const linkageRules = rules ?? localSchema[LinkageRuleDataKeyMap[category]];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (linkageRules && formValues) {
|
||||||
|
getSatisfiedValueMap({ rules: linkageRules, variables, localVariables })
|
||||||
|
.then((valueMap) => {
|
||||||
|
if (!isEmpty(valueMap)) {
|
||||||
|
setValueMap(valueMap);
|
||||||
|
} else setValueMap({});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
throw new Error(err.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [variables, localVariables, formValues, linkageRules]);
|
||||||
|
return { valueMap };
|
||||||
|
}
|
@ -101,6 +101,7 @@ import { EnableChildCollections } from './EnableChildCollections';
|
|||||||
import { ChildDynamicComponent } from './EnableChildCollections/DynamicComponent';
|
import { ChildDynamicComponent } from './EnableChildCollections/DynamicComponent';
|
||||||
import { FormLinkageRules } from './LinkageRules';
|
import { FormLinkageRules } from './LinkageRules';
|
||||||
import { useLinkageCollectionFieldOptions } from './LinkageRules/action-hooks';
|
import { useLinkageCollectionFieldOptions } from './LinkageRules/action-hooks';
|
||||||
|
import { LinkageRuleDataKeyMap, LinkageRuleCategory } from './LinkageRules/type';
|
||||||
|
|
||||||
export interface SchemaSettingsProps {
|
export interface SchemaSettingsProps {
|
||||||
title?: any;
|
title?: any;
|
||||||
@ -983,23 +984,35 @@ export const SchemaSettingsLinkageRules = function LinkageRules(props) {
|
|||||||
const localVariables = useLocalVariables();
|
const localVariables = useLocalVariables();
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
const { type: formBlockType } = useFormBlockType();
|
const { type: formBlockType } = useFormBlockType();
|
||||||
const type = props?.type || fieldSchema?.['x-action'] ? 'button' : 'field';
|
const category = props?.category ?? LinkageRuleCategory.default;
|
||||||
|
const elementType = ['Action', 'Action.Link'].includes(fieldSchema['x-component']) ? 'button' : 'field';
|
||||||
|
|
||||||
const gridSchema = findGridSchema(fieldSchema) || fieldSchema;
|
const gridSchema = findGridSchema(fieldSchema) || fieldSchema;
|
||||||
const options = useLinkageCollectionFilterOptions(collectionName);
|
const options = useLinkageCollectionFilterOptions(collectionName);
|
||||||
const linkageOptions = useLinkageCollectionFieldOptions(collectionName, readPretty);
|
const linkageOptions = useLinkageCollectionFieldOptions(collectionName, readPretty);
|
||||||
|
const titleMap = {
|
||||||
|
[LinkageRuleCategory.default]: t('Linkage rules'),
|
||||||
|
[LinkageRuleCategory.style]: t('Style'),
|
||||||
|
};
|
||||||
|
const dataKey = LinkageRuleDataKeyMap[category];
|
||||||
|
const getRules = useCallback(() => {
|
||||||
|
return gridSchema?.[dataKey] || fieldSchema?.[dataKey] || [];
|
||||||
|
}, [gridSchema, fieldSchema, dataKey]);
|
||||||
|
const title = titleMap[category];
|
||||||
const schema = useMemo<ISchema>(
|
const schema = useMemo<ISchema>(
|
||||||
() => ({
|
() => ({
|
||||||
type: 'object',
|
type: 'object',
|
||||||
title: t('Linkage rules'),
|
title,
|
||||||
properties: {
|
properties: {
|
||||||
fieldReaction: {
|
fieldReaction: {
|
||||||
'x-component': FormLinkageRules,
|
'x-component': FormLinkageRules,
|
||||||
'x-use-component-props': () => {
|
'x-use-component-props': () => {
|
||||||
return {
|
return {
|
||||||
options,
|
options,
|
||||||
defaultValues: gridSchema?.['x-linkage-rules'] || fieldSchema?.['x-linkage-rules'],
|
defaultValues: getRules(),
|
||||||
type,
|
|
||||||
linkageOptions,
|
linkageOptions,
|
||||||
|
category,
|
||||||
|
elementType,
|
||||||
collectionName,
|
collectionName,
|
||||||
form,
|
form,
|
||||||
variables,
|
variables,
|
||||||
@ -1011,7 +1024,7 @@ export const SchemaSettingsLinkageRules = function LinkageRules(props) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
[collectionName, fieldSchema, form, gridSchema, localVariables, record, t, type, variables],
|
[collectionName, fieldSchema, form, gridSchema, localVariables, record, t, variables, getRules],
|
||||||
);
|
);
|
||||||
const components = useMemo(() => ({ ArrayCollapse, FormLayout }), []);
|
const components = useMemo(() => ({ ArrayCollapse, FormLayout }), []);
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
@ -1025,25 +1038,18 @@ export const SchemaSettingsLinkageRules = function LinkageRules(props) {
|
|||||||
const schema = {
|
const schema = {
|
||||||
['x-uid']: uid,
|
['x-uid']: uid,
|
||||||
};
|
};
|
||||||
|
gridSchema[dataKey] = rules;
|
||||||
gridSchema['x-linkage-rules'] = rules;
|
schema[dataKey] = rules;
|
||||||
schema['x-linkage-rules'] = rules;
|
|
||||||
dn.emit('patch', {
|
dn.emit('patch', {
|
||||||
schema,
|
schema,
|
||||||
});
|
});
|
||||||
dn.refresh();
|
dn.refresh();
|
||||||
},
|
},
|
||||||
[dn, getTemplateById, gridSchema],
|
[dn, getTemplateById, gridSchema, dataKey],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SchemaSettingsModalItem
|
<SchemaSettingsModalItem title={title} components={components} width={770} schema={schema} onSubmit={onSubmit} />
|
||||||
title={t('Linkage rules')}
|
|
||||||
components={components}
|
|
||||||
width={770}
|
|
||||||
schema={schema}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,3 +10,4 @@
|
|||||||
export * from './e2eUtils';
|
export * from './e2eUtils';
|
||||||
export * from './templatesOfCollection';
|
export * from './templatesOfCollection';
|
||||||
export * from './templatesOfPage';
|
export * from './templatesOfPage';
|
||||||
|
export * from './templates';
|
||||||
|
551
packages/core/test/src/e2e/templates/form-view/commonView.ts
Normal file
551
packages/core/test/src/e2e/templates/form-view/commonView.ts
Normal file
@ -0,0 +1,551 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个通用表单详情
|
||||||
|
* 显示 email, number, integer, singleLineText, longText
|
||||||
|
* password, percent, phone
|
||||||
|
*/
|
||||||
|
import { generalWithBasic } from '../../templatesOfCollection';
|
||||||
|
export const commonFormViewPage = {
|
||||||
|
collections: generalWithBasic,
|
||||||
|
pageSchema: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Page',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
nyayqbdi6fw: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'page:addBlock',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
udrskvvihwz: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
sic837d78ru: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
j3tcb77zrjs: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-acl-action': 'general:view',
|
||||||
|
'x-decorator': 'DetailsBlockProvider',
|
||||||
|
'x-use-decorator-props': 'useDetailsWithPaginationDecoratorProps',
|
||||||
|
'x-decorator-props': {
|
||||||
|
dataSource: 'main',
|
||||||
|
collection: 'general',
|
||||||
|
readPretty: true,
|
||||||
|
action: 'list',
|
||||||
|
params: {
|
||||||
|
pageSize: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-toolbar': 'BlockSchemaToolbar',
|
||||||
|
'x-settings': 'blockSettings:detailsWithPagination',
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
hgde2qiovq4: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Details',
|
||||||
|
'x-read-pretty': true,
|
||||||
|
'x-use-component-props': 'useDetailsWithPaginationProps',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
xaaixt3ikr2: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-initializer': 'details:configureActions',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
marginBottom: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
zc467d4k8pe: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Edit") }}',
|
||||||
|
'x-action': 'update',
|
||||||
|
'x-toolbar': 'ActionSchemaToolbar',
|
||||||
|
'x-settings': 'actionSettings:edit',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-component-props': {
|
||||||
|
openMode: 'drawer',
|
||||||
|
icon: 'EditOutlined',
|
||||||
|
type: 'primary',
|
||||||
|
},
|
||||||
|
'x-decorator': 'ACLActionProvider',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
drawer: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Edit record") }}',
|
||||||
|
'x-component': 'Action.Container',
|
||||||
|
'x-component-props': {
|
||||||
|
className: 'nb-action-popup',
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
tabs: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Tabs',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-initializer': 'popup:addTab',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
tab1: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{t("Edit")}}',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-designer': 'Tabs.Designer',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'popup:common:addBlock',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': 'tbxcoz6blxo',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'x4gthikn85e',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'dlcr60v0lae',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'goi3ac29a92',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'xhu94zjv18h',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'dotl8t82ufw',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'details:configureFields',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
qbd9sojqba9: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
'6fi8dxh1515': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
email: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.email',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': '1ht8ymnfc18',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '2y8bzf9fa92',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'mszcq97x37n',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
'5qwtnq93h4m': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
woxnz7b32ms: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
number: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.number',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': 'lg2wluayh2c',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'awljxm8hh55',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'g8raovgeqjc',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
v7ht9slmzwn: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
ijjcbuis4tv: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
integer: {
|
||||||
|
'x-uid': 'dhdtfo7nrxn',
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.integer',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-linkage-style-rules': [],
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '9rd5u4d3lhj',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ii6w1eqf21k',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 3,
|
||||||
|
},
|
||||||
|
fekkqosx4q6: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
nmpljskg642: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
singleLineText: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.singleLineText',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': '88cqngc9wzf',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '44pljtolwui',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'zq7dfy9uvrj',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 4,
|
||||||
|
},
|
||||||
|
p318qpfu85n: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
'1fayljjx90o': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
longText: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.longText',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': 'y6rf9v4iz8o',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '1vhh859rxwx',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '19lk0gejxo3',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 5,
|
||||||
|
},
|
||||||
|
'6t21tyr1aun': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
'3h1hp3t902r': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
password: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.password',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': '2zgn6ew5mwy',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'i3twoaoewde',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'uvsong5fn8l',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 6,
|
||||||
|
},
|
||||||
|
inytkbn0nae: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
h8e5m0gy2ei: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
percent: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.percent',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': '2maem18o31o',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'jtbdipyy5sc',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'as7c9lme7mm',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 7,
|
||||||
|
},
|
||||||
|
'81q1yw3hkkn': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
ykobkj6pe8n: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
properties: {
|
||||||
|
phone: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar': 'FormItemSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props': 'useDataFormItemProps',
|
||||||
|
'x-collection-field': 'general.phone',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': 'e66n6ewz0hi',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ai34z8y2eb4',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'eltj0z2txug',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '7crv1u0i3co',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
pagination: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Pagination',
|
||||||
|
'x-use-component-props': 'useDetailsPaginationProps',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-uid': 'jfs3ntlghyo',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'buvsjjof9pw',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '9ruom7jpm1h',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '3pl1k9mqhy8',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '0eax0yvji6y',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'cs71v511x7o',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'welnfb52obj',
|
||||||
|
'x-async': true,
|
||||||
|
},
|
||||||
|
};
|
10
packages/core/test/src/e2e/templates/form-view/index.ts
Normal file
10
packages/core/test/src/e2e/templates/form-view/index.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './commonView';
|
10
packages/core/test/src/e2e/templates/index.ts
Normal file
10
packages/core/test/src/e2e/templates/index.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* This file is part of the NocoBase (R) project.
|
||||||
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||||
|
* Authors: NocoBase Team.
|
||||||
|
*
|
||||||
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||||
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './form-view';
|
@ -5839,6 +5839,569 @@ export const oneTableBlockWithAddNewAndViewAndEditAndBasicFields: PageConfig = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. 一个 Table 区块
|
||||||
|
* 2. 显示ID和一个整数列
|
||||||
|
* 3. 查看详情: email integer number phone
|
||||||
|
*/
|
||||||
|
export const oneTableBlockWithIntegerAndIDColumn: PageConfig = {
|
||||||
|
collections: generalWithBasic,
|
||||||
|
pageSchema: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Page',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
nyayqbdi6fw: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'page:addBlock',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
a7zqokjj6gt: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
'3lbci797d7d': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
wvjxlk9dpcp: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'TableBlockProvider',
|
||||||
|
'x-acl-action': 'general:list',
|
||||||
|
'x-use-decorator-props': 'useTableBlockDecoratorProps',
|
||||||
|
'x-decorator-props': {
|
||||||
|
collection: 'general',
|
||||||
|
dataSource: 'main',
|
||||||
|
action: 'list',
|
||||||
|
params: {
|
||||||
|
pageSize: 20,
|
||||||
|
},
|
||||||
|
rowKey: 'id',
|
||||||
|
showIndex: true,
|
||||||
|
dragSort: false,
|
||||||
|
},
|
||||||
|
'x-toolbar': 'BlockSchemaToolbar',
|
||||||
|
'x-settings': 'blockSettings:table',
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
'x-filter-targets': [],
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-initializer': 'table:configureActions',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
marginBottom: 'var(--nb-spacing)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'uafyrboeeeh',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
xpv8gfkv0w4: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'array',
|
||||||
|
'x-initializer': 'table:configureColumns',
|
||||||
|
'x-component': 'TableV2',
|
||||||
|
'x-use-component-props': 'useTableBlockProps',
|
||||||
|
'x-component-props': {
|
||||||
|
rowKey: 'id',
|
||||||
|
rowSelection: {
|
||||||
|
type: 'checkbox',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 2,
|
||||||
|
properties: {
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Actions") }}',
|
||||||
|
'x-action-column': 'actions',
|
||||||
|
'x-decorator': 'TableV2.Column.ActionBar',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-designer': 'TableV2.ActionColumnDesigner',
|
||||||
|
'x-initializer': 'table:configureItemActions',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
c3br6p1m4ay: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'DndContext',
|
||||||
|
'x-component': 'Space',
|
||||||
|
'x-component-props': {
|
||||||
|
split: '|',
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
ycbfg04aq1u: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("View") }}',
|
||||||
|
'x-action': 'view',
|
||||||
|
'x-toolbar': 'ActionSchemaToolbar',
|
||||||
|
'x-settings': 'actionSettings:view',
|
||||||
|
'x-component': 'Action.Link',
|
||||||
|
'x-component-props': {
|
||||||
|
openMode: 'drawer',
|
||||||
|
},
|
||||||
|
'x-decorator': 'ACLActionProvider',
|
||||||
|
'x-designer-props': {
|
||||||
|
linkageAction: true,
|
||||||
|
},
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
drawer: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("View record") }}',
|
||||||
|
'x-component': 'Action.Container',
|
||||||
|
'x-component-props': {
|
||||||
|
className: 'nb-action-popup',
|
||||||
|
},
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
tabs: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Tabs',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-initializer': 'popup:addTab',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
tab1: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '{{t("Details")}}',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-designer': 'Tabs.Designer',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'popup:common:addBlock',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
fecjkwzjrlc: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
u5047nn630n: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
g6nol2a8f0v: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-acl-action': 'general:get',
|
||||||
|
'x-decorator': 'DetailsBlockProvider',
|
||||||
|
'x-use-decorator-props': 'useDetailsDecoratorProps',
|
||||||
|
'x-decorator-props': {
|
||||||
|
dataSource: 'main',
|
||||||
|
collection: 'general',
|
||||||
|
readPretty: true,
|
||||||
|
action: 'get',
|
||||||
|
},
|
||||||
|
'x-toolbar': 'BlockSchemaToolbar',
|
||||||
|
'x-settings': 'blockSettings:details',
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
qe6uvivhlcs: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Details',
|
||||||
|
'x-read-pretty': true,
|
||||||
|
'x-use-component-props': 'useDetailsProps',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
'1ul3ug1mjn1': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-initializer': 'details:configureActions',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
marginBottom: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'tx7ej82dtav',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'details:configureFields',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 2,
|
||||||
|
properties: {
|
||||||
|
i4gnqtwjsmo: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
kpg3nd9z03j: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
email: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar':
|
||||||
|
'FormItemSchemaToolbar',
|
||||||
|
'x-settings':
|
||||||
|
'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props':
|
||||||
|
'useDataFormItemProps',
|
||||||
|
'x-collection-field':
|
||||||
|
'general.email',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'igz2roi2lgf',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'twtz1r704we',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '4yltx4dtlwa',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
'0j7ky7h63km': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 2,
|
||||||
|
properties: {
|
||||||
|
'1yq1bw53408': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
integer: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar':
|
||||||
|
'FormItemSchemaToolbar',
|
||||||
|
'x-settings':
|
||||||
|
'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props':
|
||||||
|
'useDataFormItemProps',
|
||||||
|
'x-collection-field':
|
||||||
|
'general.integer',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'kz1wgswubq6',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'hxdhhdrttal',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'h3df5v19yer',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
tqgzzposgug: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 3,
|
||||||
|
properties: {
|
||||||
|
j88upzin86t: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
number: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar':
|
||||||
|
'FormItemSchemaToolbar',
|
||||||
|
'x-settings':
|
||||||
|
'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props':
|
||||||
|
'useDataFormItemProps',
|
||||||
|
'x-collection-field':
|
||||||
|
'general.number',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'lb582vapwrl',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'b9hxznmlw4y',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ccemewjagrc',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
zsifuulhfj8: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 4,
|
||||||
|
properties: {
|
||||||
|
'94mix5vzskc': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
phone: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-toolbar':
|
||||||
|
'FormItemSchemaToolbar',
|
||||||
|
'x-settings':
|
||||||
|
'fieldSettings:FormItem',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-use-decorator-props':
|
||||||
|
'useDataFormItemProps',
|
||||||
|
'x-collection-field':
|
||||||
|
'general.phone',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'b9sth7gi9co',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '24nb1vhc3c8',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'q3fdeysf8i0',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'w2d78a9y0s2',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'cjtl8872i5s',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'x79v0wahp73',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'z5k8x76thiv',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'dz7694elunl',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'dpyxl72qav7',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ejoaawmib5s',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'vqu7oj3nsba',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '80o560bno10',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'as0562wfiri',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'ipotr34hb0r',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'hy58uesiqfe',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
'2tygi2ob18k': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
|
'x-toolbar': 'TableColumnSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:TableColumn',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 2,
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
'x-collection-field': 'general.id',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-read-pretty': true,
|
||||||
|
'x-decorator': null,
|
||||||
|
'x-decorator-props': {
|
||||||
|
labelStyle: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'uxtounspwze',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'yvfmjf6tzk7',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
t8rlom0c3ju: {
|
||||||
|
'x-uid': 'jt87by9dks1',
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
|
'x-toolbar': 'TableColumnSchemaToolbar',
|
||||||
|
'x-settings': 'fieldSettings:TableColumn',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 3,
|
||||||
|
'x-linkage-style-rules': [],
|
||||||
|
properties: {
|
||||||
|
integer: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
'x-collection-field': 'general.integer',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-read-pretty': true,
|
||||||
|
'x-decorator': null,
|
||||||
|
'x-decorator-props': {
|
||||||
|
labelStyle: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-app-version': '1.0.0-alpha.17',
|
||||||
|
'x-index': 1,
|
||||||
|
'x-uid': 'd3fvg9v46yu',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'nwqvi9i433x',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'qf53grjobl2',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'c95omaoid1m',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'h70lk7jikxa',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'iylotyrenoo',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '7z81p33jsb1',
|
||||||
|
'x-async': true,
|
||||||
|
},
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* 1. 一个 Table 区块
|
* 1. 一个 Table 区块
|
||||||
* 2. 点击 Add new 有一个 Form 区块,里面有一个 sub-table 字段
|
* 2. 点击 Add new 有一个 Form 区块,里面有一个 sub-table 字段
|
||||||
|
Loading…
x
Reference in New Issue
Block a user