mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-02 04:07:50 +08:00
feat: support add group item in detail & form block (#5498)
* feat: support add group item in detail & form block * feat: support add group item in detail & form block * refactor: locale * refactor: orientationMargin * fix: test * fix: test * refactor: locale impeove
This commit is contained in:
parent
14ca792ff0
commit
8d83c13fe7
@ -363,7 +363,7 @@
|
||||
"is empty": "为空",
|
||||
"is not empty": "不为空",
|
||||
"Edit chart": "编辑图表",
|
||||
"Add text": "添加文本",
|
||||
"Add Markdown": "添加 Markdown",
|
||||
"Filterable fields": "可筛选字段",
|
||||
"Edit button": "编辑按钮",
|
||||
"Hide": "隐藏",
|
||||
@ -1007,8 +1007,15 @@
|
||||
"Stay on the current popup or page": "停留在当前弹窗或页面",
|
||||
"Return to the previous popup or page": "返回上一层弹窗或页面",
|
||||
"Action after successful submission": "提交成功后动作",
|
||||
"Allow disassociation":"允许解除已有数据关联",
|
||||
"Allow disassociation": "允许解除已有数据关联",
|
||||
"Layout": "布局",
|
||||
"Vertical": "垂直",
|
||||
"Horizontal": "水平"
|
||||
"Horizontal": "水平",
|
||||
"Edit group title": "编辑分组标题",
|
||||
"Title position": "标题位置",
|
||||
"Dashed": "虚线",
|
||||
"Left": "左",
|
||||
"Center": "居中",
|
||||
"Right": "右",
|
||||
"Divider line color": "分割线颜色"
|
||||
}
|
||||
|
@ -97,9 +97,9 @@ test.describe('configure fields', () => {
|
||||
page.getByLabel('block-item-CollectionField-general-details-general.manyToOne.nickname'),
|
||||
).not.toBeVisible();
|
||||
|
||||
// add text
|
||||
// add markdown
|
||||
await formItemInitializer.hover();
|
||||
await page.getByRole('menuitem', { name: 'Add text' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Add Markdown' }).click();
|
||||
await expect(page.getByLabel('block-item-Markdown.Void-general-details')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
@ -79,7 +79,7 @@ const commonOptions = {
|
||||
},
|
||||
{
|
||||
name: 'addText',
|
||||
title: '{{t("Add text")}}',
|
||||
title: '{{t("Add Markdown")}}',
|
||||
Component: 'BlockItemInitializer',
|
||||
schema: {
|
||||
type: 'void',
|
||||
@ -97,6 +97,21 @@ const commonOptions = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'addDivider',
|
||||
title: '{{t("Add group")}}',
|
||||
Component: 'BlockItemInitializer',
|
||||
schema: {
|
||||
type: 'void',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-toolbar': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:divider',
|
||||
'x-component': 'Divider',
|
||||
'x-component-props': {
|
||||
children: '{{t("Group")}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -87,9 +87,9 @@ test.describe('configure fields', () => {
|
||||
page.getByLabel('block-item-CollectionField-general-form-general.manyToOne.nickname'),
|
||||
).not.toBeVisible();
|
||||
|
||||
// add text
|
||||
// add markdown
|
||||
await page.getByLabel('schema-initializer-Grid-form:configureFields-general').hover();
|
||||
await page.getByRole('menuitem', { name: 'Text' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Add Markdown' }).click();
|
||||
await expect(page.getByLabel('block-item-Markdown.Void-general-form')).toBeVisible();
|
||||
});
|
||||
|
||||
|
@ -36,9 +36,14 @@ const commonOptions = {
|
||||
},
|
||||
{
|
||||
name: 'addText',
|
||||
title: '{{t("Add text")}}',
|
||||
title: '{{t("Add Markdown")}}',
|
||||
Component: 'MarkdownFormItemInitializer',
|
||||
},
|
||||
{
|
||||
name: 'addDivider',
|
||||
title: '{{t("Add group")}}',
|
||||
Component: 'DividerFormItemInitializer',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -182,11 +182,11 @@ test.describe('configure fields', () => {
|
||||
page.getByLabel('block-item-CollectionField-general-grid-card-general.manyToOne.nickname').first(),
|
||||
).not.toBeVisible();
|
||||
|
||||
// add text
|
||||
// add markdown
|
||||
await formItemInitializer.hover();
|
||||
await page.getByRole('menuitem', { name: 'ID', exact: true }).hover();
|
||||
await page.mouse.wheel(0, 300);
|
||||
await page.getByRole('menuitem', { name: 'Add text' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Add Markdown' }).click();
|
||||
|
||||
await expect(page.getByLabel('block-item-Markdown.Void-general-grid-card').first()).toBeVisible();
|
||||
});
|
||||
|
@ -180,9 +180,9 @@ test.describe('configure fields', () => {
|
||||
page.getByLabel('block-item-CollectionField-general-list-general.manyToOne.nickname').first(),
|
||||
).not.toBeVisible();
|
||||
|
||||
// add text
|
||||
// add markdown
|
||||
await formItemInitializer.hover();
|
||||
await page.getByRole('menuitem', { name: 'Add text' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Add Markdown' }).click();
|
||||
await expect(page.getByLabel('block-item-Markdown.Void-general-list').first()).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
@ -75,9 +75,9 @@ test.describe('configure fields', () => {
|
||||
page.getByLabel('block-item-CollectionField-general-filter-form-general.manyToOne.nickname'),
|
||||
).not.toBeVisible();
|
||||
|
||||
// add text
|
||||
// add markdown
|
||||
await formItemInitializer.hover();
|
||||
await page.getByRole('menuitem', { name: 'Add text' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Add Markdown' }).click();
|
||||
|
||||
await expect(page.getByLabel('block-item-Markdown.Void-general-filter-form')).toBeVisible();
|
||||
});
|
||||
|
@ -38,7 +38,7 @@ const commonOptions = {
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
title: '{{t("Add text")}}',
|
||||
title: '{{t("Add Markdown")}}',
|
||||
Component: 'MarkdownFormItemInitializer',
|
||||
name: 'addText',
|
||||
},
|
||||
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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 { LineOutlined } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
|
||||
|
||||
export const DividerFormItemInitializer = () => {
|
||||
const { insert } = useSchemaInitializer();
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
return (
|
||||
<SchemaInitializerItem
|
||||
{...itemConfig}
|
||||
icon={<LineOutlined />}
|
||||
onClick={() => {
|
||||
insert({
|
||||
type: 'void',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-toolbar': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'blockSettings:divider',
|
||||
'x-component': 'Divider',
|
||||
'x-component-props': {
|
||||
children: '{{t("Group")}}',
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
@ -0,0 +1,202 @@
|
||||
/**
|
||||
* 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 { useField, useFieldSchema } from '@formily/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
|
||||
import { SchemaSettingsModalItem } from '../../../../schema-settings';
|
||||
|
||||
import { useDesignable } from '../../../../schema-component/hooks/useDesignable';
|
||||
import { ColorPicker } from '../../../../schema-component';
|
||||
import React from 'react';
|
||||
|
||||
export function GroupTitleEditor(props) {
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { dn } = useDesignable();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<SchemaSettingsModalItem
|
||||
title={t('Edit group title')}
|
||||
schema={{
|
||||
type: 'object',
|
||||
title: t('Edit group title'),
|
||||
properties: {
|
||||
children: {
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
title: t('Group title'),
|
||||
default: field.componentProps.children,
|
||||
'x-component-props': {},
|
||||
},
|
||||
},
|
||||
}}
|
||||
onSubmit={({ children }) => {
|
||||
field.componentProps.children = children;
|
||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||
fieldSchema['x-component-props'].children = children;
|
||||
dn.emit('patch', {
|
||||
schema: {
|
||||
['x-uid']: fieldSchema['x-uid'],
|
||||
'x-component-props': {
|
||||
...fieldSchema['x-component-props'],
|
||||
},
|
||||
},
|
||||
});
|
||||
dn.refresh();
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const dividerSettings = new SchemaSettings({
|
||||
name: 'blockSettings:divider',
|
||||
items: [
|
||||
{
|
||||
name: 'editTitle',
|
||||
type: 'item',
|
||||
Component: GroupTitleEditor,
|
||||
},
|
||||
{
|
||||
name: 'orientation',
|
||||
type: 'select',
|
||||
useComponentProps() {
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { t } = useTranslation();
|
||||
const { dn } = useDesignable();
|
||||
return {
|
||||
title: t('Title position'),
|
||||
value: field.componentProps?.orientation || 'left',
|
||||
options: [
|
||||
{ label: t('Left'), value: 'left' },
|
||||
{ label: t('Center'), value: 'center' },
|
||||
{ label: t('Right'), value: 'right' },
|
||||
],
|
||||
onChange: (orientation) => {
|
||||
field.componentProps = field.componentProps || {};
|
||||
field.componentProps.orientation = orientation;
|
||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||
fieldSchema['x-component-props']['orientation'] = orientation;
|
||||
dn.emit('patch', {
|
||||
schema: {
|
||||
['x-uid']: fieldSchema['x-uid'],
|
||||
'x-component-props': fieldSchema['x-component-props'],
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'dashed',
|
||||
type: 'switch',
|
||||
useComponentProps: () => {
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { t } = useTranslation();
|
||||
const { dn } = useDesignable();
|
||||
|
||||
return {
|
||||
title: t('Dashed'),
|
||||
defaultChecked: true,
|
||||
checked: field.componentProps.dashed,
|
||||
onChange: (flag) => {
|
||||
field.componentProps.dashed = flag;
|
||||
fieldSchema['x-component-props'].dashed = flag;
|
||||
if (flag === false) {
|
||||
fieldSchema['x-component-props'].dashed = false;
|
||||
}
|
||||
dn.emit('patch', {
|
||||
schema: fieldSchema,
|
||||
});
|
||||
dn.refresh();
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'color',
|
||||
type: 'item',
|
||||
useComponentProps: () => {
|
||||
const { t } = useTranslation();
|
||||
const { dn } = useDesignable();
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
return {
|
||||
title: (
|
||||
<div style={{ alignItems: 'center', display: 'flex', justifyContent: 'space-between' }}>
|
||||
{t('Color')}
|
||||
<div style={{ float: 'right' }}>
|
||||
<ColorPicker
|
||||
defaultValue={field.componentProps.color || 'rgba(0, 0, 0, 0.88)'}
|
||||
onChange={(value) => {
|
||||
field.componentProps = field.componentProps || {};
|
||||
field.componentProps.color = value;
|
||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||
fieldSchema['x-component-props'].color = value;
|
||||
dn.emit('patch', {
|
||||
schema: fieldSchema,
|
||||
});
|
||||
dn.refresh();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'borderColor',
|
||||
type: 'item',
|
||||
useComponentProps: () => {
|
||||
const { t } = useTranslation();
|
||||
const { dn } = useDesignable();
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
return {
|
||||
title: (
|
||||
<div style={{ alignItems: 'center', display: 'flex', justifyContent: 'space-between' }}>
|
||||
{t('Divider line color')}
|
||||
<div style={{ float: 'right' }}>
|
||||
<ColorPicker
|
||||
defaultValue={field.componentProps.borderColor || 'rgba(5, 5, 5, 0.06)'}
|
||||
onChange={(value) => {
|
||||
field.componentProps = field.componentProps || {};
|
||||
field.componentProps.borderColor = value;
|
||||
fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {};
|
||||
fieldSchema['x-component-props'].borderColor = value;
|
||||
dn.emit('patch', {
|
||||
schema: fieldSchema,
|
||||
});
|
||||
dn.refresh();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'delete',
|
||||
type: 'remove',
|
||||
useComponentProps() {
|
||||
return {
|
||||
removeParentsIfNoChildren: true,
|
||||
breakRemoveOn: {
|
||||
'x-component': 'Grid',
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
] as any,
|
||||
});
|
@ -28,7 +28,7 @@ export const ColorPicker = connect(
|
||||
trigger="hover"
|
||||
{...others}
|
||||
destroyTooltipOnHide
|
||||
getPopupContainer={(current) => current}
|
||||
// getPopupContainer={(current) => current}
|
||||
presets={[
|
||||
{
|
||||
label: 'Recommended',
|
||||
|
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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 { connect, mapProps } from '@formily/react';
|
||||
import { Divider as AntdDivider } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
export const Divider = connect(
|
||||
(props) => {
|
||||
const { color, borderColor } = props;
|
||||
return <AntdDivider {...props} type="horizontal" style={{ color, borderColor }} orientationMargin="0" />;
|
||||
},
|
||||
mapProps((props) => {
|
||||
return {
|
||||
orientation: 'left',
|
||||
...props,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
export default Divider;
|
@ -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 './Divider';
|
@ -63,5 +63,6 @@ export * from './unix-timestamp';
|
||||
export * from './nanoid-input';
|
||||
export * from './error-fallback';
|
||||
export * from './expiresRadio';
|
||||
export * from './divider';
|
||||
|
||||
import './index.less';
|
||||
|
@ -114,6 +114,8 @@ import { CollectionFieldInitializer } from '../modules/fields/initializer/Collec
|
||||
import { TableCollectionFieldInitializer } from '../modules/fields/initializer/TableCollectionFieldInitializer';
|
||||
import { menuItemInitializer, menuItemInitializer_deprecated } from '../modules/menu/menuItemInitializer';
|
||||
import { blockInitializers, blockInitializers_deprecated } from '../modules/page/BlockInitializers';
|
||||
import { DividerFormItemInitializer } from '../modules/blocks/other-blocks/divider/DividerFormItemInitializer';
|
||||
|
||||
import {
|
||||
customFormItemInitializers,
|
||||
customFormItemInitializers_deprecated,
|
||||
@ -182,6 +184,7 @@ export class SchemaInitializerPlugin extends Plugin {
|
||||
DisassociateActionInitializer,
|
||||
FilterActionInitializer,
|
||||
RefreshActionInitializer,
|
||||
DividerFormItemInitializer,
|
||||
} as any);
|
||||
|
||||
this.app.schemaInitializerManager.add(blockInitializers_deprecated);
|
||||
|
@ -75,6 +75,7 @@ import {
|
||||
import { subTablePopoverComponentFieldSettings } from '../modules/fields/component/SubTable/subTablePopoverComponentFieldSettings';
|
||||
import { tagComponentFieldSettings } from '../modules/fields/component/Tag/tagComponentFieldSettings';
|
||||
import { unixTimestampComponentFieldSettings } from '../modules/fields/component/UnixTimestamp/unixTimestampComponentFieldSettings';
|
||||
import { dividerSettings } from '../modules/blocks/other-blocks/divider/dividerSettings';
|
||||
|
||||
export class SchemaSettingsPlugin extends Plugin {
|
||||
async load() {
|
||||
@ -144,5 +145,6 @@ export class SchemaSettingsPlugin extends Plugin {
|
||||
// this.schemaSettingsManager.add(inputURLComponentFieldSettings);
|
||||
this.schemaSettingsManager.add(uploadAttachmentComponentFieldSettings);
|
||||
this.schemaSettingsManager.add(previewComponentFieldSettings);
|
||||
this.schemaSettingsManager.add(dividerSettings);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ const commonOptions = {
|
||||
},
|
||||
{
|
||||
name: 'addText',
|
||||
title: '{{t("Add text")}}',
|
||||
title: '{{t("Add Markdown")}}',
|
||||
Component: 'BlockItemInitializer',
|
||||
schema: {
|
||||
type: 'void',
|
||||
|
Loading…
Reference in New Issue
Block a user