mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-09 15:39:24 +08:00
feat: refactor helper configuration and enhance date formatting component
This commit is contained in:
parent
2116f2d424
commit
f93029e990
@ -9,7 +9,7 @@
|
|||||||
import { createForm, onFormValuesChange } from '@formily/core';
|
import { createForm, onFormValuesChange } from '@formily/core';
|
||||||
import { observer, useForm } from '@formily/react';
|
import { observer, useForm } from '@formily/react';
|
||||||
import { dayjs, tval, uid } from '@nocobase/utils/client';
|
import { dayjs, tval, uid } from '@nocobase/utils/client';
|
||||||
import { Tag } from 'antd';
|
import { Button, Card, Space, Tag } from 'antd';
|
||||||
import { createMemoryHistory } from 'history';
|
import { createMemoryHistory } from 'history';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import minimatch from 'minimatch';
|
import minimatch from 'minimatch';
|
||||||
@ -72,8 +72,9 @@ const Configurator = observer(
|
|||||||
const { helpersObs, rawHelpersObs, removeHelper } = helperObservables;
|
const { helpersObs, rawHelpersObs, removeHelper } = helperObservables;
|
||||||
const helper = helpersObs.value[index];
|
const helper = helpersObs.value[index];
|
||||||
const rawHelper = rawHelpersObs.value[index];
|
const rawHelper = rawHelpersObs.value[index];
|
||||||
const helperConfigs = app.jsonTemplateParser.filters;
|
const helperConfigs = app.jsonTemplateParser.helpers;
|
||||||
const helperConfig = helperConfigs.find((item) => item.name === helper.name);
|
const helperConfig = helperConfigs.find((item) => item.name === helper.name);
|
||||||
|
const HelperComponent = helperConfig.Component;
|
||||||
const previousHelpers = helpersObs.value.slice(0, index);
|
const previousHelpers = helpersObs.value.slice(0, index);
|
||||||
const inputValue = previousHelpers.reduce((value, helper) => {
|
const inputValue = previousHelpers.reduce((value, helper) => {
|
||||||
return helper.handler(value, ...helper.args);
|
return helper.handler(value, ...helper.args);
|
||||||
@ -184,7 +185,16 @@ const Configurator = observer(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return HelperComponent ? (
|
||||||
|
<>
|
||||||
|
<HelperComponent
|
||||||
|
value={helper.argsMap}
|
||||||
|
onChange={(values) => (rawHelper.argsMap = values)}
|
||||||
|
inputValue={inputValue}
|
||||||
|
/>
|
||||||
|
<MyButtons onDelete={() => removeHelper({ index: index })} onClose={close} />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
<SchemaComponent
|
<SchemaComponent
|
||||||
components={{ InputValue, OuputValue }}
|
components={{ InputValue, OuputValue }}
|
||||||
schema={schema}
|
schema={schema}
|
||||||
@ -201,6 +211,23 @@ const Configurator = observer(
|
|||||||
{ displayName: 'Configurator' },
|
{ displayName: 'Configurator' },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add a new component for custom delete and close buttons
|
||||||
|
export const MyButtons = observer(
|
||||||
|
({ onDelete, onClose }: { onDelete: () => void; onClose: () => void }) => {
|
||||||
|
const app = useApp();
|
||||||
|
const t = app.i18n.t;
|
||||||
|
return (
|
||||||
|
<Space style={{ display: 'flex', justifyContent: 'flex-end', marginTop: '16px' }}>
|
||||||
|
<Button type="primary" danger onClick={onDelete}>
|
||||||
|
{t('Delete', { ns: 'client' })}
|
||||||
|
</Button>
|
||||||
|
<Button onClick={onClose}>{t('Close', { ns: 'client' })}</Button>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ displayName: 'MyButtons' },
|
||||||
|
);
|
||||||
|
|
||||||
const WithRouter = observer(
|
const WithRouter = observer(
|
||||||
({ children }: { children: React.ReactNode }) => {
|
({ children }: { children: React.ReactNode }) => {
|
||||||
const history = createMemoryHistory();
|
const history = createMemoryHistory();
|
||||||
|
@ -22,7 +22,7 @@ type RawHelper = {
|
|||||||
|
|
||||||
const parser = createJSONTemplateParser();
|
const parser = createJSONTemplateParser();
|
||||||
|
|
||||||
export const allHelpersConfigObs = observable<{ value: any[] }>({ value: parser.filters });
|
export const allHelpersConfigObs = observable<{ value: any[] }>({ value: parser.helpers });
|
||||||
|
|
||||||
export const createHelperObservables = () => {
|
export const createHelperObservables = () => {
|
||||||
const rawHelpersObs = observable<{ value: RawHelper[] }>({ value: [] });
|
const rawHelpersObs = observable<{ value: RawHelper[] }>({ value: [] });
|
||||||
@ -38,6 +38,7 @@ export const createHelperObservables = () => {
|
|||||||
config,
|
config,
|
||||||
args,
|
args,
|
||||||
handler: config.handler,
|
handler: config.handler,
|
||||||
|
Component: config.Component,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}) as { value: Helper[] };
|
}) as { value: Helper[] };
|
||||||
|
@ -10,21 +10,13 @@
|
|||||||
import { Liquid, TokenKind } from 'liquidjs';
|
import { Liquid, TokenKind } from 'liquidjs';
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { escape, revertEscape } from '../escape';
|
import { escape, revertEscape } from '../escape';
|
||||||
|
import { Helper } from '../types';
|
||||||
type FilterGroup = {
|
type FilterGroup = {
|
||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
sort: number;
|
sort: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Helper = {
|
|
||||||
name: string;
|
|
||||||
title: string;
|
|
||||||
handler: (...args: any[]) => any;
|
|
||||||
group: string;
|
|
||||||
uiSchema?: any;
|
|
||||||
sort: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ScopeFnWrapperResult = {
|
type ScopeFnWrapperResult = {
|
||||||
getValue: (params: { field: string[]; keys: string[] }) => any;
|
getValue: (params: { field: string[]; keys: string[] }) => any;
|
||||||
afterApplyHelpers: (params: { field: string[]; keys: string[]; value: any }) => any;
|
afterApplyHelpers: (params: { field: string[]; keys: string[]; value: any }) => any;
|
||||||
@ -48,7 +40,7 @@ export class JSONTemplateParser {
|
|||||||
this._filters = [];
|
this._filters = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
get filters(): Array<Helper> {
|
get helpers(): Array<Helper> {
|
||||||
return this._filters;
|
return this._filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,5 +18,5 @@ export type Helper = {
|
|||||||
sort: number;
|
sort: number;
|
||||||
args: string[];
|
args: string[];
|
||||||
uiSchema?: any[];
|
uiSchema?: any[];
|
||||||
Component?: React.FC<{ value: any; onChange: (value: any) => void }>;
|
Component?: React.FC<{ value: any; onChange: (value: any) => void; inputValue: any }>;
|
||||||
};
|
};
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { Checkbox, Input, Radio, Space } from 'antd';
|
import { Checkbox, Input, Radio, Space } from 'antd';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
|
|
||||||
// Component for displaying a date format preview
|
// Component for displaying a date format preview
|
||||||
const DateFormatPreview = ({ format }) => {
|
const DateFormatPreview = ({ format, date }) => {
|
||||||
const content = format ? dayjs().format(format) : null;
|
const content = format ? date.format(format) : null;
|
||||||
|
|
||||||
if (!content) return null;
|
if (!content) return null;
|
||||||
|
|
||||||
@ -38,16 +38,24 @@ const DateFormatPreview = ({ format }) => {
|
|||||||
const DateFormat = ({
|
const DateFormat = ({
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
|
inputValue,
|
||||||
picker = 'date',
|
picker = 'date',
|
||||||
showTimeToggle = true,
|
showTimeToggle = true,
|
||||||
defaultShowTime = false,
|
defaultShowTime = false,
|
||||||
timeFormat: initialTimeFormat = 'HH:mm:ss',
|
timeFormat: initialTimeFormat = 'HH:mm:ss',
|
||||||
dateFormat: initialDateFormat = 'YYYY-MM-DD',
|
dateFormat: initialDateFormat = 'YYYY-MM-DD',
|
||||||
}) => {
|
}) => {
|
||||||
const [selectedFormat, setSelectedFormat] = useState(value || initialDateFormat);
|
const [selectedFormat, setSelectedFormat] = useState(value.format || initialDateFormat);
|
||||||
const [isCustom, setIsCustom] = useState(false);
|
const [isCustom, setIsCustom] = useState(false);
|
||||||
const [showTime, setShowTime] = useState(defaultShowTime);
|
const [showTime, setShowTime] = useState(defaultShowTime);
|
||||||
const [timeFormat, setTimeFormat] = useState(initialTimeFormat);
|
const [timeFormat, setTimeFormat] = useState(initialTimeFormat);
|
||||||
|
const date = dayjs.isDayjs(inputValue) ? inputValue : dayjs(inputValue);
|
||||||
|
const onFormatChange = useCallback(
|
||||||
|
(format) => {
|
||||||
|
onChange?.({ format });
|
||||||
|
},
|
||||||
|
[onChange],
|
||||||
|
);
|
||||||
|
|
||||||
// Date format options
|
// Date format options
|
||||||
const dateFormatOptions = [
|
const dateFormatOptions = [
|
||||||
@ -55,7 +63,7 @@ const DateFormat = ({
|
|||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<span>MMMM Do YYYY</span>
|
<span>MMMM Do YYYY</span>
|
||||||
<DateFormatPreview format="MMMM Do YYYY" />
|
<DateFormatPreview date={date} format="MMMM Do YYYY" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
value: 'MMMM Do YYYY',
|
value: 'MMMM Do YYYY',
|
||||||
@ -64,7 +72,7 @@ const DateFormat = ({
|
|||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<span>YYYY-MM-DD</span>
|
<span>YYYY-MM-DD</span>
|
||||||
<DateFormatPreview format="YYYY-MM-DD" />
|
<DateFormatPreview date={date} format="YYYY-MM-DD" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
value: 'YYYY-MM-DD',
|
value: 'YYYY-MM-DD',
|
||||||
@ -73,7 +81,7 @@ const DateFormat = ({
|
|||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<span>MM/DD/YY</span>
|
<span>MM/DD/YY</span>
|
||||||
<DateFormatPreview format="MM/DD/YY" />
|
<DateFormatPreview date={date} format="MM/DD/YY" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
value: 'MM/DD/YY',
|
value: 'MM/DD/YY',
|
||||||
@ -82,7 +90,7 @@ const DateFormat = ({
|
|||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<span>YYYY/MM/DD</span>
|
<span>YYYY/MM/DD</span>
|
||||||
<DateFormatPreview format="YYYY/MM/DD" />
|
<DateFormatPreview date={date} format="YYYY/MM/DD" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
value: 'YYYY/MM/DD',
|
value: 'YYYY/MM/DD',
|
||||||
@ -91,7 +99,7 @@ const DateFormat = ({
|
|||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<span>DD/MM/YYYY</span>
|
<span>DD/MM/YYYY</span>
|
||||||
<DateFormatPreview format="DD/MM/YYYY" />
|
<DateFormatPreview date={date} format="DD/MM/YYYY" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
value: 'DD/MM/YYYY',
|
value: 'DD/MM/YYYY',
|
||||||
@ -105,7 +113,7 @@ const DateFormat = ({
|
|||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<span>hh:mm:ss a</span>
|
<span>hh:mm:ss a</span>
|
||||||
<DateFormatPreview format="hh:mm:ss a" />
|
<DateFormatPreview date={date} format="hh:mm:ss a" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
value: 'hh:mm:ss a',
|
value: 'hh:mm:ss a',
|
||||||
@ -114,7 +122,7 @@ const DateFormat = ({
|
|||||||
label: (
|
label: (
|
||||||
<>
|
<>
|
||||||
<span>HH:mm:ss</span>
|
<span>HH:mm:ss</span>
|
||||||
<DateFormatPreview format="HH:mm:ss" />
|
<DateFormatPreview date={date} format="HH:mm:ss" />
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
value: 'HH:mm:ss',
|
value: 'HH:mm:ss',
|
||||||
@ -143,10 +151,10 @@ const DateFormat = ({
|
|||||||
if (picker !== 'date') {
|
if (picker !== 'date') {
|
||||||
const newFormat = getPickerFormat(picker);
|
const newFormat = getPickerFormat(picker);
|
||||||
setSelectedFormat(newFormat);
|
setSelectedFormat(newFormat);
|
||||||
onChange?.(newFormat);
|
onFormatChange(newFormat);
|
||||||
setShowTime(false);
|
setShowTime(false);
|
||||||
}
|
}
|
||||||
}, [picker]);
|
}, [picker, onFormatChange]);
|
||||||
|
|
||||||
// Update parent component with combined format
|
// Update parent component with combined format
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -156,8 +164,8 @@ const DateFormat = ({
|
|||||||
finalFormat = `${selectedFormat} ${timeFormat}`;
|
finalFormat = `${selectedFormat} ${timeFormat}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange?.(finalFormat);
|
onFormatChange(finalFormat);
|
||||||
}, [selectedFormat, showTime, timeFormat]);
|
}, [selectedFormat, showTime, timeFormat, onFormatChange, picker]);
|
||||||
|
|
||||||
// Handle date format change
|
// Handle date format change
|
||||||
const handleDateFormatChange = (e) => {
|
const handleDateFormatChange = (e) => {
|
||||||
@ -209,7 +217,7 @@ const DateFormat = ({
|
|||||||
onChange={handleCustomFormatChange}
|
onChange={handleCustomFormatChange}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
/>
|
/>
|
||||||
<DateFormatPreview format={selectedFormat} />
|
<DateFormatPreview date={date} format={selectedFormat} />
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
option.label
|
option.label
|
||||||
@ -251,7 +259,7 @@ const DateFormat = ({
|
|||||||
onChange={(e) => setTimeFormat(e.target.value)}
|
onChange={(e) => setTimeFormat(e.target.value)}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
/>
|
/>
|
||||||
<DateFormatPreview format={timeFormat} />
|
<DateFormatPreview date={date} format={timeFormat} />
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
option.label
|
option.label
|
||||||
|
@ -77,8 +77,7 @@ export function dateOffset(initialValue: any, action: 'add' | 'subtract', number
|
|||||||
return dayjs.isDayjs(value) ? value.add(number, unit) : dayjs(value).add(number, unit);
|
return dayjs.isDayjs(value) ? value.add(number, unit) : dayjs(value).add(number, unit);
|
||||||
} else if (action === 'subtract') {
|
} else if (action === 'subtract') {
|
||||||
return dayjs.isDayjs(value) ? value.subtract(number, unit) : dayjs(value).subtract(number, unit);
|
return dayjs.isDayjs(value) ? value.subtract(number, unit) : dayjs(value).subtract(number, unit);
|
||||||
}
|
} else return initialValue;
|
||||||
throw new Error('Invalid action');
|
|
||||||
};
|
};
|
||||||
return handler(initialValue);
|
return handler(initialValue);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user