feat(client/popup): support set drawer and modal popup size (#1224)

This commit is contained in:
lyf-coder 2022-12-12 08:39:21 +08:00 committed by GitHub
parent 41f8e6a285
commit 4d90bc87a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 7 deletions

View File

@ -338,6 +338,10 @@ export default {
"Operation succeeded": "Operation succeeded", "Operation succeeded": "Operation succeeded",
"Operation failed": "Operation failed", "Operation failed": "Operation failed",
"Open mode": "Open mode", "Open mode": "Open mode",
"Set popup size": "Set popup size",
"Small": "Small",
"Middle": "Middle",
"Large": "Large",
"Menu item title": "Menu item title", "Menu item title": "Menu item title",
"Menu item icon": "Menu item icon", "Menu item icon": "Menu item icon",
"Target": "Target", "Target": "Target",

View File

@ -425,6 +425,10 @@ export default {
"Operation succeeded": "操作成功", "Operation succeeded": "操作成功",
"Operation failed": "操作失败", "Operation failed": "操作失败",
"Open mode": "打开方式", "Open mode": "打开方式",
"Set popup size": "设置弹窗尺寸",
"Small": "较窄",
"Middle": "中等",
"Large": "较宽",
'Menu item title': '菜单项名称', 'Menu item title': '菜单项名称',
'Menu item icon': '菜单项图标', 'Menu item icon': '菜单项图标',
'Target': '目标', 'Target': '目标',

View File

@ -1,6 +1,6 @@
import { ISchema, useField, useFieldSchema } from '@formily/react'; import { ISchema, useField, useFieldSchema } from '@formily/react';
import { isValid, uid } from '@formily/shared'; import { isValid, uid } from '@formily/shared';
import { Menu } from 'antd'; import { Menu, Select } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useActionContext, useCompile, useDesignable } from '../..'; import { useActionContext, useCompile, useDesignable } from '../..';
@ -143,6 +143,10 @@ export const ActionDesigner = (props) => {
onChange={(value) => { onChange={(value) => {
field.componentProps.openMode = value; field.componentProps.openMode = value;
fieldSchema['x-component-props']['openMode'] = value; fieldSchema['x-component-props']['openMode'] = value;
// when openMode change, set openSize value to default
delete fieldSchema['x-component-props']['openSize'];
dn.emit('patch', { dn.emit('patch', {
schema: { schema: {
'x-uid': fieldSchema['x-uid'], 'x-uid': fieldSchema['x-uid'],
@ -153,6 +157,37 @@ export const ActionDesigner = (props) => {
}} }}
/> />
)} )}
{isPopupAction && ['modal', 'drawer'].includes(fieldSchema?.['x-component-props']?.['openMode']) && (
<SchemaSettings.Item>
<div style={{ alignItems: 'center', display: 'flex', justifyContent: 'space-between' }}>
{t('Set popup size')}
<Select
bordered={false}
options={[
{ label: t('Small'), value: 'small' },
{ label: t('Middle'), value: 'middle' },
{ label: t('Large'), value: 'large' },
]}
value={
fieldSchema?.['x-component-props']?.['openSize'] ??
(fieldSchema?.['x-component-props']?.['openMode'] == 'modal' ? 'large' : 'middle')
}
onChange={(value) => {
field.componentProps.openSize = value;
fieldSchema['x-component-props']['openSize'] = value;
dn.emit('patch', {
schema: {
'x-uid': fieldSchema['x-uid'],
'x-component-props': fieldSchema['x-component-props'],
},
});
dn.refresh();
}}
style={{ textAlign: 'right', minWidth: 100 }}
/>
</div>
</SchemaSettings.Item>
)}
{isUpdateModePopupAction && ( {isUpdateModePopupAction && (
<SchemaSettings.SelectItem <SchemaSettings.SelectItem
title={t('Data will be updated')} title={t('Data will be updated')}

View File

@ -7,11 +7,17 @@ import { createPortal } from 'react-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useActionContext } from './hooks'; import { useActionContext } from './hooks';
import { ComposedActionDrawer } from './types'; import { ComposedActionDrawer } from './types';
import { OpenSize } from './';
const openSizeWidthMap = new Map<OpenSize, string>([
['small', '30%'],
['middle', '50%'],
['large', '70%'],
]);
export const ActionDrawer: ComposedActionDrawer = observer((props) => { export const ActionDrawer: ComposedActionDrawer = observer((props) => {
const { footerNodeName = 'Action.Drawer.Footer', ...others } = props; const { footerNodeName = 'Action.Drawer.Footer', ...others } = props;
const { t } = useTranslation(); const { t } = useTranslation();
const { visible, setVisible } = useActionContext(); const { visible, setVisible, openSize = 'middle' } = useActionContext();
const schema = useFieldSchema(); const schema = useFieldSchema();
const field = useField(); const field = useField();
const footerSchema = schema.reduceProperties((buf, s) => { const footerSchema = schema.reduceProperties((buf, s) => {
@ -29,7 +35,7 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
}} }}
> >
<Drawer <Drawer
width={'50%'} width={openSizeWidthMap.get(openSize)}
title={field.title} title={field.title}
{...others} {...others}
destroyOnClose destroyOnClose
@ -42,16 +48,20 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
.ant-drawer-header { .ant-drawer-header {
display: none; display: none;
} }
.ant-drawer-body { .ant-drawer-body {
padding-top: 14px; padding-top: 14px;
} }
.ant-drawer-content { .ant-drawer-content {
background: #f0f2f5; background: #f0f2f5;
} }
} }
&.nb-record-picker-selector { &.nb-record-picker-selector {
.nb-block-item { .nb-block-item {
margin-bottom: 24px; margin-bottom: 24px;
.general-schema-designer { .general-schema-designer {
top: -8px; top: -8px;
bottom: -8px; bottom: -8px;
@ -69,6 +79,7 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
width: 100%; width: 100%;
.ant-btn { .ant-btn {
margin-right: 8px; margin-right: 8px;
} }

View File

@ -4,12 +4,18 @@ import { Modal } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { useActionContext } from '.'; import { OpenSize, useActionContext } from '.';
import { ComposedActionDrawer } from './types'; import { ComposedActionDrawer } from './types';
const openSizeWidthMap = new Map<OpenSize, string>([
['small', '40%'],
['middle', '60%'],
['large', '80%'],
]);
export const ActionModal: ComposedActionDrawer = observer((props) => { export const ActionModal: ComposedActionDrawer = observer((props) => {
const { footerNodeName = 'Action.Modal.Footer', width = '80%', ...others } = props; const { footerNodeName = 'Action.Modal.Footer', width, ...others } = props;
const { visible, setVisible } = useActionContext(); const { visible, setVisible, openSize = 'large' } = useActionContext();
const actualWidth = width ?? openSizeWidthMap.get(openSize);
const schema = useFieldSchema(); const schema = useFieldSchema();
const field = useField(); const field = useField();
const footerSchema = schema.reduceProperties((buf, s) => { const footerSchema = schema.reduceProperties((buf, s) => {
@ -27,7 +33,7 @@ export const ActionModal: ComposedActionDrawer = observer((props) => {
}} }}
> >
<Modal <Modal
width={width} width={actualWidth}
title={field.title} title={field.title}
{...others} {...others}
destroyOnClose destroyOnClose
@ -40,12 +46,15 @@ export const ActionModal: ComposedActionDrawer = observer((props) => {
.ant-modal-header { .ant-modal-header {
display: none; display: none;
} }
.ant-modal-body { .ant-modal-body {
padding-top: 16px; padding-top: 16px;
} }
.ant-modal-body { .ant-modal-body {
background: #f0f2f5; background: #f0f2f5;
} }
.ant-modal-close-x { .ant-modal-close-x {
width: 32px; width: 32px;
height: 32px; height: 32px;
@ -61,6 +70,7 @@ export const ActionModal: ComposedActionDrawer = observer((props) => {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
width: 100%; width: 100%;
.ant-btn { .ant-btn {
margin-right: 8px; margin-right: 8px;
} }

View File

@ -89,6 +89,7 @@ export const Action: ComposedAction = observer((props: any) => {
const form = useForm(); const form = useForm();
const designerProps = fieldSchema['x-designer-props']; const designerProps = fieldSchema['x-designer-props'];
const openMode = fieldSchema?.['x-component-props']?.['openMode']; const openMode = fieldSchema?.['x-component-props']?.['openMode'];
const openSize = fieldSchema?.['x-component-props']?.['openSize'];
const renderButton = () => ( const renderButton = () => (
<SortableItem <SortableItem
{...others} {...others}
@ -128,6 +129,7 @@ export const Action: ComposedAction = observer((props: any) => {
formValueChanged, formValueChanged,
setFormValueChanged, setFormValueChanged,
openMode, openMode,
openSize,
containerRefKey, containerRefKey,
fieldSchema, fieldSchema,
}} }}

View File

@ -3,11 +3,13 @@ import { createContext } from 'react';
export const ActionContext = createContext<ActionContextProps>({}); export const ActionContext = createContext<ActionContextProps>({});
export type OpenSize = 'small' | 'middle' | 'large';
export interface ActionContextProps { export interface ActionContextProps {
button?: any; button?: any;
visible?: boolean; visible?: boolean;
setVisible?: (v: boolean) => void; setVisible?: (v: boolean) => void;
openMode?: 'drawer' | 'modal' | 'page'; openMode?: 'drawer' | 'modal' | 'page';
openSize?: OpenSize;
containerRefKey?: string; containerRefKey?: string;
formValueChanged?: boolean; formValueChanged?: boolean;
setFormValueChanged?: (v: boolean) => void; setFormValueChanged?: (v: boolean) => void;