mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 08:21:53 +00: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 { useEditFormBlockDecoratorProps } from '../modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps';
|
||||
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 { useListBlockDecoratorProps } from '../modules/blocks/data-blocks/list/hooks/useListBlockDecoratorProps';
|
||||
import { useTableSelectorDecoratorProps } from '../modules/blocks/data-blocks/table-selector/hooks/useTableSelectorDecoratorProps';
|
||||
@ -85,6 +86,7 @@ export const BlockSchemaComponentProvider: React.FC = (props) => {
|
||||
useFilterFormBlockDecoratorProps,
|
||||
useGridCardBlockDecoratorProps,
|
||||
useFormItemProps,
|
||||
useDataFormItemProps,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
@ -145,6 +147,7 @@ export class BlockSchemaComponentPlugin extends Plugin {
|
||||
useFilterFormBlockDecoratorProps,
|
||||
useGridCardBlockDecoratorProps,
|
||||
useFormItemProps,
|
||||
useDataFormItemProps,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -426,6 +426,7 @@
|
||||
"Option value": "Option value",
|
||||
"Option label": "Option label",
|
||||
"Color": "Color",
|
||||
"Background Color": "Background Color",
|
||||
"Add option": "Add option",
|
||||
"Related collection": "Related collection",
|
||||
"Allow linking to multiple records": "Allow linking to multiple records",
|
||||
@ -552,6 +553,7 @@
|
||||
"Add condition group": "Add condition group",
|
||||
"exists": "exists",
|
||||
"not exists": "not exists",
|
||||
"Style": "Style",
|
||||
"=": "=",
|
||||
"≠": "≠",
|
||||
">": ">",
|
||||
|
@ -447,6 +447,7 @@
|
||||
"Option value": "选项值",
|
||||
"Option label": "选项标签",
|
||||
"Color": "颜色",
|
||||
"Background Color": "背景颜色",
|
||||
"Add option": "添加选项",
|
||||
"Related collection": "关系表",
|
||||
"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',
|
||||
type: 'select',
|
||||
},
|
||||
{
|
||||
title: 'Style',
|
||||
type: 'modal',
|
||||
},
|
||||
{
|
||||
title: 'Set validation rules',
|
||||
type: 'modal',
|
||||
@ -284,6 +288,10 @@ describe('FieldSettingsFormItem', () => {
|
||||
title: 'Pattern',
|
||||
type: 'select',
|
||||
},
|
||||
{
|
||||
title: 'Style',
|
||||
type: 'modal',
|
||||
},
|
||||
{
|
||||
title: 'Field component',
|
||||
type: 'select',
|
||||
|
@ -6,7 +6,7 @@
|
||||
* 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 React from 'react';
|
||||
import { ArrayCollapse, FormLayout } from '@formily/antd-v5';
|
||||
import { Field } from '@formily/core';
|
||||
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
||||
@ -16,6 +16,7 @@ import { useApp, useSchemaToolbar } from '../../../../application';
|
||||
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
||||
import { useFormBlockContext } from '../../../../block-provider/FormBlockProvider';
|
||||
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../../../collection-manager';
|
||||
import { useCollection } from '../../../../data-source';
|
||||
import { useFieldComponentName } from '../../../../common/useFieldComponentName';
|
||||
import { useDesignable, useValidateSchema } from '../../../../schema-component';
|
||||
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 { SchemaSettingsDefaultValue } from '../../../../schema-settings/SchemaSettingsDefaultValue';
|
||||
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({
|
||||
name: 'fieldSettings:FormItem',
|
||||
items: [
|
||||
@ -442,6 +444,25 @@ export const fieldSettingsFormItem = new SchemaSettings({
|
||||
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.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ISchema } from '@formily/json-schema';
|
||||
import { useField, useFieldSchema } from '@formily/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useApp } from '../../../../application';
|
||||
import { useApp, useSchemaToolbar } from '../../../../application';
|
||||
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
||||
import { useCollectionManager_deprecated } from '../../../../collection-manager';
|
||||
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 { SchemaSettingsDefaultValue } from '../../../../schema-settings/SchemaSettingsDefaultValue';
|
||||
import { isPatternDisabled } from '../../../../schema-settings/isPatternDisabled';
|
||||
import { SchemaSettingsLinkageRules } from '../../../../schema-settings';
|
||||
|
||||
export const tableColumnSettings = new SchemaSettings({
|
||||
name: 'fieldSettings:TableColumn',
|
||||
@ -44,7 +46,6 @@ export const tableColumnSettings = new SchemaSettings({
|
||||
const { t } = useTranslation();
|
||||
const columnSchema = useFieldSchema();
|
||||
const { dn } = useDesignable();
|
||||
|
||||
return {
|
||||
title: t('Custom column title'),
|
||||
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',
|
||||
type: 'modal',
|
||||
|
@ -10,7 +10,7 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { IFormItemProps, FormItem as Item } from '@formily/antd-v5';
|
||||
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 { ACLCollectionFieldProvider } from '../../../acl/ACLProvider';
|
||||
import { useApp } from '../../../application';
|
||||
@ -19,14 +19,14 @@ import { Collection_deprecated } from '../../../collection-manager';
|
||||
import { CollectionFieldProvider } from '../../../data-source/collection-field/CollectionFieldProvider';
|
||||
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
|
||||
import { GeneralSchemaDesigner } from '../../../schema-settings';
|
||||
import { useVariables } from '../../../variables';
|
||||
import useContextVariable from '../../../variables/hooks/useContextVariable';
|
||||
import { BlockItem } from '../block-item';
|
||||
import { HTMLEncode } from '../input/shared';
|
||||
import { FilterFormDesigner } from './FormItem.FilterFormDesigner';
|
||||
import { useEnsureOperatorsValid } from './SchemaSettingOptions';
|
||||
import useLazyLoadDisplayAssociationFieldsOfForm from './hooks/useLazyLoadDisplayAssociationFieldsOfForm';
|
||||
import useParseDefaultValue from './hooks/useParseDefaultValue';
|
||||
import { useVariables, useContextVariable } from '../../../variables';
|
||||
import { useDataFormItemProps } from '../../../modules/blocks/data-blocks/form/hooks/useDataFormItemProps';
|
||||
|
||||
Item.displayName = 'FormilyFormItem';
|
||||
|
||||
@ -47,14 +47,14 @@ export const FormItem: any = withDynamicSchemaProps(
|
||||
useEnsureOperatorsValid();
|
||||
const field = useField<Field>();
|
||||
const schema = useFieldSchema();
|
||||
const contextVariable = useContextVariable();
|
||||
const variables = useVariables();
|
||||
const { addActiveFieldName } = useFormActiveFields() || {};
|
||||
|
||||
const form = useForm();
|
||||
const { wrapperStyle } = useDataFormItemProps();
|
||||
const variables = useVariables();
|
||||
const contextVariable = useContextVariable();
|
||||
useEffect(() => {
|
||||
variables?.registerVariable(contextVariable);
|
||||
}, [contextVariable]);
|
||||
|
||||
}, [contextVariable, variables]);
|
||||
// 需要放在注冊完变量之后
|
||||
useParseDefaultValue();
|
||||
useLazyLoadDisplayAssociationFieldsOfForm();
|
||||
@ -87,7 +87,7 @@ export const FormItem: any = withDynamicSchemaProps(
|
||||
<CollectionFieldProvider allowNull={true}>
|
||||
<BlockItem className={'nb-form-item'}>
|
||||
<ACLCollectionFieldProvider>
|
||||
<Item className={className} {...props} extra={extra} />
|
||||
<Item className={className} {...props} extra={extra} wrapperStyle={wrapperStyle} />
|
||||
</ACLCollectionFieldProvider>
|
||||
</BlockItem>
|
||||
</CollectionFieldProvider>
|
||||
|
@ -30,6 +30,9 @@ import { isPatternDisabled } from '../../../schema-settings/isPatternDisabled';
|
||||
import { useCompile, useDesignable, useFieldModeOptions } from '../../hooks';
|
||||
import { useAssociationFieldContext } from '../association-field/hooks';
|
||||
import { removeNullCondition } from '../filter';
|
||||
import { SchemaSettingsLinkageRules } from '../../../schema-settings';
|
||||
import { useCollection } from '../../../data-source';
|
||||
import { useSchemaToolbar } from '../../../application';
|
||||
|
||||
export const useLabelFields = (collectionName?: any) => {
|
||||
// 需要在组件顶层调用
|
||||
@ -98,6 +101,12 @@ export const TableColumnDesigner = (props) => {
|
||||
readOnlyMode = 'read-pretty';
|
||||
}
|
||||
const isSelectFieldMode = isAssociationField && fieldMode === 'Select';
|
||||
|
||||
const StyleSetting = () => {
|
||||
const { name } = useCollection();
|
||||
const { linkageRulesProps } = useSchemaToolbar();
|
||||
return <SchemaSettingsLinkageRules category={'style'} {...{ ...linkageRulesProps, collectionName: name }} />;
|
||||
};
|
||||
return (
|
||||
<GeneralSchemaDesigner disableInitializer>
|
||||
<SchemaSettingsModalItem
|
||||
@ -186,6 +195,7 @@ export const TableColumnDesigner = (props) => {
|
||||
dn.refresh();
|
||||
}}
|
||||
/>
|
||||
<StyleSetting />
|
||||
{interfaceCfg && interfaceCfg.sortable === true && !currentMode && (
|
||||
<SchemaSettingsSwitchItem
|
||||
title={t('Sortable')}
|
||||
|
@ -37,11 +37,11 @@ import {
|
||||
import { useACLFieldWhitelist } from '../../../acl/ACLProvider';
|
||||
import { isNewRecord } from '../../../data-source/collection-record/isNewRecord';
|
||||
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
|
||||
import { useSatisfiedActionValues } from '../../../schema-settings/LinkageRules/useActionValues';
|
||||
import { useToken } from '../__builtins__';
|
||||
import { SubFormProvider } from '../association-field/hooks';
|
||||
import { ColumnFieldProvider } from './components/ColumnFieldProvider';
|
||||
import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils';
|
||||
|
||||
const MemoizedAntdTable = React.memo(AntdTable);
|
||||
|
||||
const useArrayField = (props) => {
|
||||
@ -145,6 +145,9 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) =>
|
||||
</SubFormProvider>
|
||||
);
|
||||
},
|
||||
onCell: (record) => {
|
||||
return { record, schema: s };
|
||||
},
|
||||
} as TableColumnProps<any>;
|
||||
|
||||
// 这里不能把 columnsSchema 作为依赖,因为其每次都会变化,这里使用 hasChangedColumns 作为依赖
|
||||
@ -529,16 +532,17 @@ export const Table: any = withDynamicSchemaProps(
|
||||
const BodyCellComponent = useCallback(
|
||||
(props) => {
|
||||
const isIndex = props.className?.includes('selection-column');
|
||||
|
||||
const { record, schema } = props;
|
||||
const { ref, inView } = useInView({
|
||||
threshold: 0,
|
||||
triggerOnce: true,
|
||||
initialInView: isIndex || !!process.env.__E2E__ || dataSource.length <= 10,
|
||||
skip: isIndex || !!process.env.__E2E__,
|
||||
});
|
||||
const { valueMap: style } = useSatisfiedActionValues({ formValues: record, category: 'style', schema });
|
||||
|
||||
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%' }} />}
|
||||
</td>
|
||||
);
|
||||
|
@ -6,7 +6,7 @@
|
||||
* 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 React from 'react';
|
||||
import { Field } from '@formily/core';
|
||||
import { ISchema, useField, useFieldSchema } from '@formily/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -14,6 +14,9 @@ import { useDesignable } from '../schema-component';
|
||||
import { SchemaSettingOptions } from '../application';
|
||||
import { useSchemaToolbar } from '../application/schema-toolbar';
|
||||
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'] = [
|
||||
{
|
||||
@ -216,4 +219,23 @@ export const generalSettingsItems: SchemaSettingOptions['items'] = [
|
||||
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' },
|
||||
);
|
||||
|
||||
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 { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps';
|
||||
import { useProps } from '../../schema-component/hooks/useProps';
|
||||
import { FormButtonLinkageRuleAction, FormFieldLinkageRuleAction } from './LinkageRuleAction';
|
||||
import {
|
||||
FormButtonLinkageRuleAction,
|
||||
FormFieldLinkageRuleAction,
|
||||
FormStyleLinkageRuleAction,
|
||||
} from './LinkageRuleAction';
|
||||
import { RemoveActionContext } from './context';
|
||||
export const LinkageRuleActions = observer(
|
||||
(props: any): any => {
|
||||
const { type, linkageOptions } = props;
|
||||
const { linkageOptions, category, elementType } = props;
|
||||
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 (
|
||||
<RemoveActionContext.Provider key={index} value={() => field.remove(index)}>
|
||||
<ObjectField
|
||||
name={index}
|
||||
component={[
|
||||
type === 'button' ? FormButtonLinkageRuleAction : FormFieldLinkageRuleAction,
|
||||
{ ...props, options: linkageOptions },
|
||||
]}
|
||||
/>
|
||||
<ObjectField name={index} component={[componentMap[type], { ...props, options: linkageOptions }]} />
|
||||
</RemoveActionContext.Provider>
|
||||
);
|
||||
});
|
||||
@ -37,8 +43,8 @@ export const LinkageRuleActions = observer(
|
||||
{ displayName: 'LinkageRuleActions' },
|
||||
);
|
||||
|
||||
interface LinkageRuleActionGroupProps {
|
||||
type: 'button' | 'field';
|
||||
export interface LinkageRuleActionGroupProps {
|
||||
type: 'button' | 'field' | 'style';
|
||||
linkageOptions: any;
|
||||
collectionName: string;
|
||||
}
|
||||
@ -50,12 +56,11 @@ export const LinkageRuleActionGroup = withDynamicSchemaProps(
|
||||
const logic = 'actions';
|
||||
|
||||
// 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema
|
||||
const { type, linkageOptions, collectionName } = useProps(props);
|
||||
|
||||
const { category, elementType, linkageOptions, collectionName } = useProps(props);
|
||||
const style = useMemo(() => ({ marginLeft: 10 }), []);
|
||||
const components = useMemo(
|
||||
() => [LinkageRuleActions, { type, linkageOptions, collectionName }],
|
||||
[collectionName, linkageOptions, type],
|
||||
() => [LinkageRuleActions, { category, elementType, linkageOptions, collectionName }],
|
||||
[collectionName, linkageOptions, category, elementType],
|
||||
);
|
||||
const spaceStyle = useMemo(() => ({ marginTop: 8, marginBottom: 8 }), []);
|
||||
const onClick = useCallback(() => {
|
||||
|
@ -19,15 +19,17 @@ import { DynamicComponent } from './DynamicComponent';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
export type InputModeType = 'constant' | 'express' | 'empty';
|
||||
interface ValueDynamicComponentProps {
|
||||
fieldValue: any;
|
||||
schema: any;
|
||||
setValue: (value: any) => void;
|
||||
collectionName: string;
|
||||
inputModes?: Array<InputModeType>;
|
||||
}
|
||||
|
||||
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 { t } = useTranslation();
|
||||
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 (
|
||||
<Input.Group compact>
|
||||
<Select
|
||||
@ -126,9 +144,11 @@ export const ValueDynamicComponent = (props: ValueDynamicComponentProps) => {
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Option value="constant">{t('Constant value')}</Option>
|
||||
<Option value="express">{t('Expression')}</Option>
|
||||
<Option value="empty">{t('Empty')}</Option>
|
||||
{options.map((option) => (
|
||||
<Option value={option.value} key={option.value}>
|
||||
{option.label}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
{modeMap[mode]}
|
||||
</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',
|
||||
Value = 'value',
|
||||
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 { FormLinkageRules } from './LinkageRules';
|
||||
import { useLinkageCollectionFieldOptions } from './LinkageRules/action-hooks';
|
||||
import { LinkageRuleDataKeyMap, LinkageRuleCategory } from './LinkageRules/type';
|
||||
|
||||
export interface SchemaSettingsProps {
|
||||
title?: any;
|
||||
@ -983,23 +984,35 @@ export const SchemaSettingsLinkageRules = function LinkageRules(props) {
|
||||
const localVariables = useLocalVariables();
|
||||
const record = useRecord();
|
||||
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 options = useLinkageCollectionFilterOptions(collectionName);
|
||||
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>(
|
||||
() => ({
|
||||
type: 'object',
|
||||
title: t('Linkage rules'),
|
||||
title,
|
||||
properties: {
|
||||
fieldReaction: {
|
||||
'x-component': FormLinkageRules,
|
||||
'x-use-component-props': () => {
|
||||
return {
|
||||
options,
|
||||
defaultValues: gridSchema?.['x-linkage-rules'] || fieldSchema?.['x-linkage-rules'],
|
||||
type,
|
||||
defaultValues: getRules(),
|
||||
linkageOptions,
|
||||
category,
|
||||
elementType,
|
||||
collectionName,
|
||||
form,
|
||||
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 onSubmit = useCallback(
|
||||
@ -1025,25 +1038,18 @@ export const SchemaSettingsLinkageRules = function LinkageRules(props) {
|
||||
const schema = {
|
||||
['x-uid']: uid,
|
||||
};
|
||||
|
||||
gridSchema['x-linkage-rules'] = rules;
|
||||
schema['x-linkage-rules'] = rules;
|
||||
gridSchema[dataKey] = rules;
|
||||
schema[dataKey] = rules;
|
||||
dn.emit('patch', {
|
||||
schema,
|
||||
});
|
||||
dn.refresh();
|
||||
},
|
||||
[dn, getTemplateById, gridSchema],
|
||||
[dn, getTemplateById, gridSchema, dataKey],
|
||||
);
|
||||
|
||||
return (
|
||||
<SchemaSettingsModalItem
|
||||
title={t('Linkage rules')}
|
||||
components={components}
|
||||
width={770}
|
||||
schema={schema}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
<SchemaSettingsModalItem title={title} components={components} width={770} schema={schema} onSubmit={onSubmit} />
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -10,3 +10,4 @@
|
||||
export * from './e2eUtils';
|
||||
export * from './templatesOfCollection';
|
||||
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 区块
|
||||
* 2. 点击 Add new 有一个 Form 区块,里面有一个 sub-table 字段
|
||||
|
Loading…
Reference in New Issue
Block a user