feat(client): add form disabled context (#1374)
* feat(client): add form disabled context * fix: improve code * fix: improve code * fix: form-v2 disabled Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
246ee04154
commit
00efb38438
@ -1,7 +1,7 @@
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { ObjectField as ObjectFieldModel } from '@formily/core';
|
||||
import { ArrayField, connect, useField } from '@formily/react';
|
||||
import { Select, Space } from 'antd';
|
||||
import { ConfigProvider, Select, Space } from 'antd';
|
||||
import React, { useContext } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { FilterLogicContext, RemoveConditionContext } from './context';
|
||||
@ -20,84 +20,89 @@ export const FilterGroup = connect((props) => {
|
||||
[value]: [...(obj[logic] || [])],
|
||||
};
|
||||
};
|
||||
const mergedDisabled = field.disabled;
|
||||
return (
|
||||
<FilterLogicContext.Provider value={logic}>
|
||||
<div
|
||||
style={
|
||||
bordered
|
||||
? {
|
||||
position: 'relative',
|
||||
border: '1px dashed #dedede',
|
||||
padding: 14,
|
||||
marginBottom: 8,
|
||||
}
|
||||
: {
|
||||
position: 'relative',
|
||||
marginBottom: 8,
|
||||
}
|
||||
}
|
||||
>
|
||||
{remove && (
|
||||
<a>
|
||||
<CloseCircleOutlined
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: 10,
|
||||
top: 10,
|
||||
color: '#bfbfbf',
|
||||
}}
|
||||
onClick={() => remove()}
|
||||
/>
|
||||
</a>
|
||||
)}
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<Trans>
|
||||
{'Meet '}
|
||||
<Select
|
||||
style={{ width: 'auto' }}
|
||||
value={logic}
|
||||
onChange={(value) => {
|
||||
setLogic(value);
|
||||
}}
|
||||
>
|
||||
<Select.Option value={'$and'}>All</Select.Option>
|
||||
<Select.Option value={'$or'}>Any</Select.Option>
|
||||
</Select>
|
||||
{' conditions in the group'}
|
||||
</Trans>
|
||||
<ConfigProvider componentDisabled={mergedDisabled}>
|
||||
<FilterLogicContext.Provider value={logic}>
|
||||
<div
|
||||
style={
|
||||
bordered
|
||||
? {
|
||||
position: 'relative',
|
||||
border: '1px dashed #dedede',
|
||||
padding: 14,
|
||||
marginBottom: 8,
|
||||
}
|
||||
: {
|
||||
position: 'relative',
|
||||
marginBottom: 8,
|
||||
}
|
||||
}
|
||||
>
|
||||
{remove && !mergedDisabled && (
|
||||
<a>
|
||||
<CloseCircleOutlined
|
||||
style={{
|
||||
position: 'absolute',
|
||||
right: 10,
|
||||
top: 10,
|
||||
color: '#bfbfbf',
|
||||
}}
|
||||
onClick={() => remove()}
|
||||
/>
|
||||
</a>
|
||||
)}
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<Trans>
|
||||
{'Meet '}
|
||||
<Select
|
||||
style={{ width: 'auto' }}
|
||||
value={logic}
|
||||
onChange={(value) => {
|
||||
setLogic(value);
|
||||
}}
|
||||
>
|
||||
<Select.Option value={'$and'}>All</Select.Option>
|
||||
<Select.Option value={'$or'}>Any</Select.Option>
|
||||
</Select>
|
||||
{' conditions in the group'}
|
||||
</Trans>
|
||||
</div>
|
||||
<div>
|
||||
<ArrayField name={logic} component={[FilterItems]} disabled={mergedDisabled} />
|
||||
</div>
|
||||
{!mergedDisabled && (
|
||||
<Space size={16} style={{ marginTop: 8, marginBottom: 8 }}>
|
||||
<a
|
||||
onClick={() => {
|
||||
const value = field.value || {};
|
||||
const items = value[logic] || [];
|
||||
items.push({});
|
||||
field.value = {
|
||||
[logic]: items,
|
||||
};
|
||||
}}
|
||||
>
|
||||
{t('Add condition')}
|
||||
</a>
|
||||
<a
|
||||
onClick={() => {
|
||||
const value = field.value || {};
|
||||
const items = value[logic] || [];
|
||||
items.push({
|
||||
$and: [{}],
|
||||
});
|
||||
field.value = {
|
||||
[logic]: items,
|
||||
};
|
||||
}}
|
||||
>
|
||||
{t('Add condition group')}
|
||||
</a>
|
||||
</Space>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<ArrayField name={logic} component={[FilterItems]} />
|
||||
</div>
|
||||
<Space size={16} style={{ marginTop: 8, marginBottom: 8 }}>
|
||||
<a
|
||||
onClick={() => {
|
||||
const value = field.value || {};
|
||||
const items = value[logic] || [];
|
||||
items.push({});
|
||||
field.value = {
|
||||
[logic]: items,
|
||||
};
|
||||
}}
|
||||
>
|
||||
{t('Add condition')}
|
||||
</a>
|
||||
<a
|
||||
onClick={() => {
|
||||
const value = field.value || {};
|
||||
const items = value[logic] || [];
|
||||
items.push({
|
||||
$and: [{}],
|
||||
});
|
||||
field.value = {
|
||||
[logic]: items,
|
||||
};
|
||||
}}
|
||||
>
|
||||
{t('Add condition group')}
|
||||
</a>
|
||||
</Space>
|
||||
</div>
|
||||
</FilterLogicContext.Provider>
|
||||
</FilterLogicContext.Provider>
|
||||
</ConfigProvider>
|
||||
);
|
||||
});
|
||||
|
@ -50,9 +50,11 @@ export const FilterItem = observer((props: any) => {
|
||||
setValue(value);
|
||||
},
|
||||
})}
|
||||
<a>
|
||||
<CloseCircleOutlined onClick={() => remove()} style={{ color: '#bfbfbf' }} />
|
||||
</a>
|
||||
{!props.disabled && (
|
||||
<a>
|
||||
<CloseCircleOutlined onClick={() => remove()} style={{ color: '#bfbfbf' }} />
|
||||
</a>
|
||||
)}
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
|
@ -2,7 +2,7 @@ import { FormLayout } from '@formily/antd';
|
||||
import { createForm, Field, onFormInputChange } from '@formily/core';
|
||||
import { FieldContext, FormContext, observer, RecursionField, useField, useFieldSchema } from '@formily/react';
|
||||
import { uid } from '@formily/shared';
|
||||
import { Spin } from 'antd';
|
||||
import { ConfigProvider, Spin } from 'antd';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useActionContext } from '..';
|
||||
import { useAttach, useComponent } from '../..';
|
||||
@ -32,7 +32,7 @@ const FormComponent: React.FC<FormProps> = (props) => {
|
||||
const Def = (props: any) => props.children;
|
||||
|
||||
const FormDecorator: React.FC<FormProps> = (props) => {
|
||||
const { form, children, ...others } = props;
|
||||
const { form, children, disabled, ...others } = props;
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
// TODO: component 里 useField 会与当前 field 存在偏差
|
||||
@ -65,6 +65,7 @@ const WithForm = (props) => {
|
||||
setFormValueChanged?.(true);
|
||||
});
|
||||
});
|
||||
form.disabled = props.disabled;
|
||||
return () => {
|
||||
form.removeEffects(id);
|
||||
};
|
||||
@ -78,6 +79,7 @@ const WithoutForm = (props) => {
|
||||
const form = useMemo(
|
||||
() =>
|
||||
createForm({
|
||||
disabled: props.disabled,
|
||||
effects() {
|
||||
onFormInputChange((form) => {
|
||||
setFormValueChanged?.(true);
|
||||
@ -95,12 +97,19 @@ const WithoutForm = (props) => {
|
||||
|
||||
export const Form: React.FC<FormProps> & { Designer?: any; ReadPrettyDesigner?: any } = observer((props) => {
|
||||
const field = useField<Field>();
|
||||
const { form, ...others } = useProps(props);
|
||||
const { form, disabled, ...others } = useProps(props);
|
||||
const formDisabled = disabled || field.disabled;
|
||||
return (
|
||||
<form>
|
||||
<Spin spinning={field.loading || false}>
|
||||
{form ? <WithForm form={form} {...others} /> : <WithoutForm {...others} />}
|
||||
</Spin>
|
||||
</form>
|
||||
<ConfigProvider componentDisabled={formDisabled}>
|
||||
<form>
|
||||
<Spin spinning={field.loading || false}>
|
||||
{form ? (
|
||||
<WithForm form={form} {...others} disabled={formDisabled} />
|
||||
) : (
|
||||
<WithoutForm {...others} disabled={formDisabled} />
|
||||
)}
|
||||
</Spin>
|
||||
</form>
|
||||
</ConfigProvider>
|
||||
);
|
||||
});
|
||||
|
@ -2,8 +2,8 @@ import { FormLayout } from '@formily/antd';
|
||||
import { createForm } from '@formily/core';
|
||||
import { FieldContext, FormContext, observer, RecursionField, useField, useFieldSchema } from '@formily/react';
|
||||
import { Options, Result } from 'ahooks/lib/useRequest/src/types';
|
||||
import { Spin } from 'antd';
|
||||
import React, { createContext, useContext, useMemo } from 'react';
|
||||
import { ConfigProvider, Spin } from 'antd';
|
||||
import React, { createContext, useContext, useEffect, useMemo } from 'react';
|
||||
import { useAttach, useComponent } from '../..';
|
||||
import { useRequest } from '../../../api-client';
|
||||
import { useCollection } from '../../../collection-manager';
|
||||
@ -38,25 +38,30 @@ const FormComponent: React.FC<FormProps> = (props) => {
|
||||
const Def = (props: any) => props.children;
|
||||
|
||||
const FormDecorator: React.FC<FormProps> = (props) => {
|
||||
const { form, children, ...others } = props;
|
||||
const { form, children, disabled, ...others } = props;
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
// TODO: component 里 useField 会与当前 field 存在偏差
|
||||
const f = useAttach(form.createVoidField({ ...field.props, basePath: '' }));
|
||||
const Component = useComponent(fieldSchema['x-component'], Def);
|
||||
useEffect(() => {
|
||||
form.disabled = disabled || field.disabled;
|
||||
}, [disabled, field.disabled]);
|
||||
return (
|
||||
<FieldContext.Provider value={undefined}>
|
||||
<FormContext.Provider value={form}>
|
||||
<FormLayout layout={'vertical'} {...others}>
|
||||
<FieldContext.Provider value={f}>
|
||||
<Component {...field.componentProps}>
|
||||
<RecursionField basePath={f.address} schema={fieldSchema} onlyRenderProperties />
|
||||
</Component>
|
||||
</FieldContext.Provider>
|
||||
{/* <FieldContext.Provider value={f}>{children}</FieldContext.Provider> */}
|
||||
</FormLayout>
|
||||
</FormContext.Provider>
|
||||
</FieldContext.Provider>
|
||||
<ConfigProvider componentDisabled={disabled}>
|
||||
<FieldContext.Provider value={undefined}>
|
||||
<FormContext.Provider value={form}>
|
||||
<FormLayout layout={'vertical'} {...others}>
|
||||
<FieldContext.Provider value={f}>
|
||||
<Component {...field.componentProps}>
|
||||
<RecursionField basePath={f.address} schema={fieldSchema} onlyRenderProperties />
|
||||
</Component>
|
||||
</FieldContext.Provider>
|
||||
{/* <FieldContext.Provider value={f}>{children}</FieldContext.Provider> */}
|
||||
</FormLayout>
|
||||
</FormContext.Provider>
|
||||
</FieldContext.Provider>
|
||||
</ConfigProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
} from '@ant-design/icons';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { ISchema, useForm } from '@formily/react';
|
||||
import { Button, message, Modal, Tag } from 'antd';
|
||||
import { Button, message, Modal, Tag, Alert } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import parse from 'json-templates';
|
||||
|
||||
@ -334,6 +334,7 @@ export function NodeDefaultView(props) {
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
disabled: workflow.executed,
|
||||
useValues(options) {
|
||||
const d = useNodeContext();
|
||||
return useRequest(() => {
|
||||
@ -354,7 +355,6 @@ export function NodeDefaultView(props) {
|
||||
name: 'config',
|
||||
'x-component': 'fieldset',
|
||||
'x-component-props': {
|
||||
disabled: workflow.executed,
|
||||
className: css`
|
||||
.ant-select,
|
||||
.ant-cascader-picker,
|
||||
@ -373,11 +373,16 @@ export function NodeDefaultView(props) {
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: workflow.executed
|
||||
? {
|
||||
close: {
|
||||
title: '{{t("Close")}}',
|
||||
'x-component': 'Action',
|
||||
alert: {
|
||||
'x-component': Alert,
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useCancelAction }}',
|
||||
type: 'warning',
|
||||
showIcon: true,
|
||||
message: `{{t("Node in executed workflow cannot be modified", { ns: "${NAMESPACE}" })}}`,
|
||||
className: css`
|
||||
width: 100%;
|
||||
font-size: 85%;
|
||||
`
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { css, cx } from "@emotion/css";
|
||||
import { ISchema, useForm } from "@formily/react";
|
||||
import { Registry } from "@nocobase/utils/client";
|
||||
import { message, Tag } from "antd";
|
||||
import { message, Tag, Alert } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { InfoOutlined } from '@ant-design/icons';
|
||||
@ -159,6 +159,7 @@ export const TriggerConfig = () => {
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
disabled: workflow.executed,
|
||||
useValues(options) {
|
||||
return useRequest(() => Promise.resolve({
|
||||
data: { config },
|
||||
@ -185,11 +186,16 @@ export const TriggerConfig = () => {
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: executed
|
||||
? {
|
||||
close: {
|
||||
title: '{{t("Close")}}',
|
||||
'x-component': 'Action',
|
||||
alert: {
|
||||
'x-component': Alert,
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useCancelAction }}',
|
||||
type: 'warning',
|
||||
showIcon: true,
|
||||
message: `{{t("Trigger in executed workflow cannot be modified", { ns: "${NAMESPACE}" })}}`,
|
||||
className: css`
|
||||
width: 100%;
|
||||
font-size: 85%;
|
||||
`
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user