mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-08 23:19:26 +08:00
feat: add delete filter functionality and improve filter context management
This commit is contained in:
parent
8f8dcb9c05
commit
7cf500bf62
@ -240,11 +240,20 @@ export function Input(props: VariableInputProps) {
|
|||||||
const updateFilterParams = useCallback(
|
const updateFilterParams = useCallback(
|
||||||
({ filterId, params }: { filterId: number; params: any[] }) => {
|
({ filterId, params }: { filterId: number; params: any[] }) => {
|
||||||
const copyedFilters = cloneDeep(filters);
|
const copyedFilters = cloneDeep(filters);
|
||||||
copyedFilters[filterId].args = params.map((val) => JSON.stringify(val));
|
copyedFilters[filterId].args = params;
|
||||||
onChange(composeTemplate({ fullVariable, filters: copyedFilters }));
|
onChange(composeTemplate({ fullVariable, filters: copyedFilters }));
|
||||||
},
|
},
|
||||||
[filters, fullVariable, onChange],
|
[filters, fullVariable, onChange],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const deleteFilter = useCallback(
|
||||||
|
({ filterId }: { filterId: number }) => {
|
||||||
|
const newFilters = filters.filter((_, index) => index !== filterId);
|
||||||
|
onChange(composeTemplate({ fullVariable, filters: newFilters }));
|
||||||
|
},
|
||||||
|
[filters, fullVariable, onChange],
|
||||||
|
);
|
||||||
|
|
||||||
const parsed = useMemo(() => parseValue(variableSegments, parseOptions), [parseOptions, variableSegments]);
|
const parsed = useMemo(() => parseValue(variableSegments, parseOptions), [parseOptions, variableSegments]);
|
||||||
const isConstant = typeof parsed === 'string';
|
const isConstant = typeof parsed === 'string';
|
||||||
const type = isConstant ? parsed : '';
|
const type = isConstant ? parsed : '';
|
||||||
@ -472,7 +481,7 @@ export function Input(props: VariableInputProps) {
|
|||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<FilterContext.Provider value={{ updateFilterParams }}>
|
<FilterContext.Provider value={{ updateFilterParams, deleteFilter }}>
|
||||||
<Filters filters={filters} onFilterChange={onFilterAdd} />
|
<Filters filters={filters} onFilterChange={onFilterAdd} />
|
||||||
|
|
||||||
{variableText.length > 0 && <Addition variable={fullVariable} onFilterAdd={onFilterAdd} />}
|
{variableText.length > 0 && <Addition variable={fullVariable} onFilterAdd={onFilterAdd} />}
|
||||||
|
@ -13,7 +13,7 @@ import { createForm } from '@formily/core';
|
|||||||
import { useForm, useParentForm, FormProvider, useField, FormContext } from '@formily/react';
|
import { useForm, useParentForm, FormProvider, useField, FormContext } from '@formily/react';
|
||||||
import { FormLayout, FormButtonGroup, Submit } from '@formily/antd-v5';
|
import { FormLayout, FormButtonGroup, Submit } from '@formily/antd-v5';
|
||||||
import { FilterOutlined } from '@ant-design/icons';
|
import { FilterOutlined } from '@ant-design/icons';
|
||||||
import { uid } from '@nocobase/utils/client';
|
import { uid, tval } from '@nocobase/utils/client';
|
||||||
import { variableFilters } from '@nocobase/json-templates';
|
import { variableFilters } from '@nocobase/json-templates';
|
||||||
import type { MenuProps } from 'antd';
|
import type { MenuProps } from 'antd';
|
||||||
import { SchemaComponent } from '../../core/SchemaComponent';
|
import { SchemaComponent } from '../../core/SchemaComponent';
|
||||||
@ -60,8 +60,19 @@ export function Filters({ filters, onFilterChange }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Filter({ config, filter, filterId }) {
|
export function Filter({ config, filter, filterId }) {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const hide = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOpenChange = (newOpen: boolean) => {
|
||||||
|
setOpen(newOpen);
|
||||||
|
};
|
||||||
|
|
||||||
const argsMap = Object.fromEntries(config.paramSchema.map((param, index) => [param.name, filter.args[index]]));
|
const argsMap = Object.fromEntries(config.paramSchema.map((param, index) => [param.name, filter.args[index]]));
|
||||||
const form = useMemo(() => createForm({ initialValues: argsMap }), [argsMap]);
|
const form = useMemo(() => createForm({ initialValues: argsMap }), [argsMap]);
|
||||||
|
|
||||||
const useSaveActionProps = () => {
|
const useSaveActionProps = () => {
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
const { updateFilterParams } = useContext(FilterContext);
|
const { updateFilterParams } = useContext(FilterContext);
|
||||||
@ -72,9 +83,24 @@ export function Filter({ config, filter, filterId }) {
|
|||||||
const values = form.values;
|
const values = form.values;
|
||||||
const params = config.paramSchema.map((param) => values[param.name]);
|
const params = config.paramSchema.map((param) => values[param.name]);
|
||||||
updateFilterParams({ filterId, params });
|
updateFilterParams({ filterId, params });
|
||||||
|
setOpen(false);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const useDeleteActionProps = () => {
|
||||||
|
const form = useForm();
|
||||||
|
const { deleteFilter } = useContext(FilterContext);
|
||||||
|
return {
|
||||||
|
type: 'primary',
|
||||||
|
danger: true,
|
||||||
|
onClick: async () => {
|
||||||
|
deleteFilter({ filterId });
|
||||||
|
setOpen(false);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const useFormBlockProps = () => {
|
const useFormBlockProps = () => {
|
||||||
return { form };
|
return { form };
|
||||||
};
|
};
|
||||||
@ -96,12 +122,18 @@ export function Filter({ config, filter, filterId }) {
|
|||||||
),
|
),
|
||||||
actions: {
|
actions: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: 'Save',
|
title: tval('Save'),
|
||||||
'x-component': 'ActionBar',
|
'x-component': 'ActionBar',
|
||||||
properties: {
|
properties: {
|
||||||
|
delete: {
|
||||||
|
type: 'void',
|
||||||
|
title: tval('Delete'),
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-use-component-props': 'useDeleteActionProps',
|
||||||
|
},
|
||||||
save: {
|
save: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: 'Save',
|
title: tval('Save'),
|
||||||
'x-component': 'Action',
|
'x-component': 'Action',
|
||||||
'x-use-component-props': 'useSaveActionProps',
|
'x-use-component-props': 'useSaveActionProps',
|
||||||
},
|
},
|
||||||
@ -109,16 +141,23 @@ export function Filter({ config, filter, filterId }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<span style={{ color: '#bfbfbf', margin: '0 5px' }}>|</span>
|
<span style={{ color: '#bfbfbf', margin: '0 5px' }}>|</span>
|
||||||
<Popover
|
<Popover
|
||||||
|
open={open}
|
||||||
|
onOpenChange={handleOpenChange}
|
||||||
content={
|
content={
|
||||||
<FormContext.Provider value={form}>
|
<FormContext.Provider value={form}>
|
||||||
<SchemaComponent schema={schema} scope={{ useSaveActionProps, useFormBlockProps }} basePath={['']} />
|
<SchemaComponent
|
||||||
|
schema={schema}
|
||||||
|
scope={{ useSaveActionProps, useFormBlockProps, useDeleteActionProps }}
|
||||||
|
basePath={['']}
|
||||||
|
/>
|
||||||
</FormContext.Provider>
|
</FormContext.Provider>
|
||||||
}
|
}
|
||||||
trigger={'click'}
|
trigger={'hover'}
|
||||||
>
|
>
|
||||||
<div style={{ color: '#52c41a', display: 'inline-block', cursor: 'pointer' }}>{config.label}</div>
|
<div style={{ color: '#52c41a', display: 'inline-block', cursor: 'pointer' }}>{config.label}</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
@ -128,8 +167,10 @@ export function Filter({ config, filter, filterId }) {
|
|||||||
|
|
||||||
type FilterContextType = {
|
type FilterContextType = {
|
||||||
updateFilterParams: (args: { filterId: number; params: any[] }) => any;
|
updateFilterParams: (args: { filterId: number; params: any[] }) => any;
|
||||||
|
deleteFilter: (args: { filterId: number }) => any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FilterContext = React.createContext<FilterContextType>({
|
export const FilterContext = React.createContext<FilterContextType>({
|
||||||
updateFilterParams: (params: any) => {},
|
updateFilterParams: (params: any) => {},
|
||||||
|
deleteFilter: (params: any) => {},
|
||||||
});
|
});
|
||||||
|
@ -183,7 +183,7 @@ export const getShouldChange = ({
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastOption = optionPath[optionPath.length - 1];
|
const lastOption = Array.isArray(optionPath) ? optionPath[optionPath.length - 1] : null;
|
||||||
|
|
||||||
// 点击叶子节点时,必须更新 value
|
// 点击叶子节点时,必须更新 value
|
||||||
if (lastOption && _.isEmpty(lastOption.children) && !lastOption.loadChildren) {
|
if (lastOption && _.isEmpty(lastOption.children) && !lastOption.loadChildren) {
|
||||||
|
@ -34,7 +34,9 @@ export function extractTemplateElements(template: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const composeFilterTemplate = (filter: Filter) => {
|
const composeFilterTemplate = (filter: Filter) => {
|
||||||
const value = `${filter.name}${filter.args.length ? `:${filter.args.join(',')}` : ''}`;
|
const value = `${filter.name}${
|
||||||
|
filter.args.length ? `:${filter.args.map((val) => JSON.stringify(val)).join(',')}` : ''
|
||||||
|
}`;
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user