feat: refactor Helper components for improved state management and UI updates

This commit is contained in:
sheldon66 2025-03-16 11:39:01 +08:00
parent 6218a3c7ce
commit dd2c1b64c6
4 changed files with 79 additions and 31 deletions

View File

@ -7,8 +7,8 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import React, { useState } from 'react';
import { Popover } from 'antd'; import { Popover } from 'antd';
import React, { useState } from 'react';
import { HelperConfiguator } from './HelperConfiguator'; import { HelperConfiguator } from './HelperConfiguator';
const WithPropOver = ({ children, index }) => { const WithPropOver = ({ children, index }) => {
@ -21,7 +21,7 @@ const WithPropOver = ({ children, index }) => {
<Popover <Popover
open={open} open={open}
onOpenChange={handleOpenChange} onOpenChange={handleOpenChange}
content={<HelperConfiguator index={index} onDelete={() => setOpen(false)} />} content={<HelperConfiguator index={index} close={() => setOpen(false)} />}
trigger={'click'} trigger={'click'}
> >
{children} {children}

View File

@ -7,22 +7,26 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import React from 'react';
import { useForm, observer } from '@formily/react';
import { createForm, onFormValuesChange } from '@formily/core'; import { createForm, onFormValuesChange } from '@formily/core';
import { uid, tval } from '@nocobase/utils/client'; import { observer, useForm } from '@formily/react';
import { Router } from 'react-router-dom'; import { tval, uid } from '@nocobase/utils/client';
import { Tag } from 'antd';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import { SchemaComponent } from '../../../core';
import { helpersObs, rawHelpersObs, removeHelper } from './observables';
import { useVariable } from '../VariableProvider';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import React from 'react';
import { Router } from 'react-router-dom';
import { useApp } from '../../../../application';
import { SchemaComponent } from '../../../core/SchemaComponent';
import { useVariable } from '../VariableProvider';
import { helpersObs, rawHelpersObs, removeHelper } from './observables';
export const HelperConfiguator = observer( export const HelperConfiguator = observer(
({ index, onDelete }: { index: number; onDelete: () => void }) => { ({ index, close }: { index: number; close: () => void }) => {
const app = useApp();
const helper = helpersObs.value[index]; const helper = helpersObs.value[index];
const rawHelper = rawHelpersObs.value[index]; const rawHelper = rawHelpersObs.value[index];
const config = helper.config; const helperConfigs = app.jsonTemplateParser.filters;
const helperConfig = helperConfigs.find((item) => item.name === helper.name);
const history = createMemoryHistory(); const history = createMemoryHistory();
const previousHelpers = helpersObs.value.slice(0, index); const previousHelpers = helpersObs.value.slice(0, index);
const { value } = useVariable(); const { value } = useVariable();
@ -33,6 +37,14 @@ export const HelperConfiguator = observer(
return helper.handler(value, ...helper.args); return helper.handler(value, ...helper.args);
}, value); }, value);
const InputValue = () => {
return <Tag color="red">{JSON.stringify(inputValue).slice(1, -1)}</Tag>;
};
const OuputValue = () => {
return <Tag color="green">{JSON.stringify(outputValue).slice(1, -1)}</Tag>;
};
const useFormBlockProps = () => { const useFormBlockProps = () => {
return { return {
form: createForm({ form: createForm({
@ -56,7 +68,15 @@ export const HelperConfiguator = observer(
danger: true, danger: true,
onClick: async () => { onClick: async () => {
removeHelper({ index: index }); removeHelper({ index: index });
onDelete(); close();
},
};
};
const useCloseActionProps = () => {
return {
onClick: async () => {
close();
}, },
}; };
}; };
@ -74,13 +94,12 @@ export const HelperConfiguator = observer(
properties: { properties: {
'$input-value': { '$input-value': {
type: 'void', type: 'void',
'x-component': 'div', 'x-component': 'InputValue',
'x-content': '{{ inputValue }}',
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
title: tval('Input Value'), title: tval('Input value', { ns: 'client' }),
}, },
...Object.fromEntries( ...Object.fromEntries(
config.uiSchema.map((param) => [ helperConfig.uiSchema.map((param) => [
param.name, param.name,
{ {
...param, ...param,
@ -88,12 +107,11 @@ export const HelperConfiguator = observer(
}, },
]), ]),
), ),
'$return-value': { '$output-value': {
type: 'void', type: 'void',
'x-component': 'div', 'x-component': 'OuputValue',
'x-content': '{{ outputValue }}',
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
title: tval('Return Value'), title: tval('Output value', { ns: 'client' }),
}, },
actions: { actions: {
type: 'void', type: 'void',
@ -106,6 +124,12 @@ export const HelperConfiguator = observer(
'x-component': 'Action', 'x-component': 'Action',
'x-use-component-props': 'useDeleteActionProps', 'x-use-component-props': 'useDeleteActionProps',
}, },
close: {
type: 'void',
title: tval('Close'),
'x-component': 'Action',
'x-use-component-props': 'useCloseActionProps',
},
}, },
}, },
}, },
@ -115,12 +139,13 @@ export const HelperConfiguator = observer(
return ( return (
<Router location={history.location} navigator={history}> <Router location={history.location} navigator={history}>
<SchemaComponent <SchemaComponent
components={{ InputValue, OuputValue }}
schema={schema} schema={schema}
scope={{ scope={{
t: app.i18n.t,
useFormBlockProps, useFormBlockProps,
useDeleteActionProps, useDeleteActionProps,
outputValue: JSON.stringify(outputValue), useCloseActionProps,
inputValue: JSON.stringify(inputValue),
}} }}
basePath={['']} basePath={['']}
/> />

View File

@ -37,15 +37,34 @@ dayjs.extend(customParseFormat);
dayjs.extend(advancedFormat); dayjs.extend(advancedFormat);
export function dateFormat(initialValue: any, format: string) { export function dateFormat(initialValue: any, format: string) {
return dayjs.isDayjs(initialValue) ? initialValue.format(format) : dayjs(initialValue).format(format); const handler = (value: any) => {
return dayjs.isDayjs(value) ? value.format(format) : dayjs(value).format(format);
};
if (Array.isArray(initialValue)) {
return initialValue.map(handler);
} else {
return handler(initialValue);
}
} }
export function dateAdd(initialValue: any, number: number, unit: any) { export function dateAdd(initialValue: any, number: number, unit: any) {
const value = dayjs.isDayjs(initialValue) ? initialValue : dayjs(initialValue); const handler = (value: any) => {
return value.add(number, unit); return dayjs.isDayjs(value) ? value.add(number, unit) : dayjs(value).add(number, unit);
};
if (Array.isArray(initialValue)) {
return initialValue.map(handler);
} else {
return handler(initialValue);
}
} }
export function dateSubtract(initialValue: any, number: number, unit: any) { export function dateSubtract(initialValue: any, number: number, unit: any) {
const value = dayjs.isDayjs(initialValue) ? initialValue : dayjs(initialValue); const handler = (value: any) => {
return value.subtract(number, unit); return dayjs.isDayjs(value) ? value.subtract(number, unit) : dayjs(value).subtract(number, unit);
};
if (Array.isArray(initialValue)) {
return initialValue.map(handler);
} else {
return handler(initialValue);
}
} }

View File

@ -7,10 +7,14 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import { dateFormat, dateAdd, dateSubtract } from './date'; import { first } from './array';
import { first, last } from './array'; import { dateAdd, dateFormat, dateSubtract } from './date';
const NAMESPACE = 'variable-filters'; const NAMESPACE = 'variable-filters';
const tval = (key) => `{{t('${key}', { ns: '${NAMESPACE}', nsMode: 'fallback' })}}`;
function tval(text: string) {
return `{{t(${JSON.stringify(text)}, ${JSON.stringify({ ns: NAMESPACE, nsMode: 'fallback' })})}}`;
}
export const variableFilters = [ export const variableFilters = [
{ {
name: 'date_format', name: 'date_format',
@ -69,7 +73,7 @@ export const variableFilters = [
uiSchema: [ uiSchema: [
{ {
name: 'number', name: 'number',
title: tval('Number'), title: tval('Amount'),
type: 'number', type: 'number',
'x-component': 'InputNumber', 'x-component': 'InputNumber',
required: true, required: true,