katherinehhh 12f95810d0
fix(linkage rule):multiple select condition judgment failed (#1715)
* fix: linkageCollectionFilterOptions

* fix: multiple select  condition judgment failed

* fix: multiple select  condition judgment failed

* fix: multiple select  condition judgment failed
2023-04-17 17:19:54 +08:00

461 lines
12 KiB
TypeScript

import { useField, useForm } from '@formily/react';
import { message } from 'antd';
import omit from 'lodash/omit';
import { useEffect } from 'react';
import { useCollection, useCollectionManager } from '.';
import { useCompile } from '..';
import { useRequest } from '../api-client';
import { useRecord } from '../record-provider';
import { useActionContext } from '../schema-component';
import { useFilterFieldOptions, useFilterFieldProps } from '../schema-component/antd/filter/useFilterActionProps';
import { useResourceActionContext, useResourceContext } from './ResourceActionProvider';
export const useCancelAction = () => {
const form = useForm();
const ctx = useActionContext();
return {
async run() {
ctx.setVisible(false);
form.reset();
},
};
};
export const useValuesFromRecord = (options) => {
const record = useRecord();
const result = useRequest(() => Promise.resolve({ data: omit(record, ['__parent']) }), {
...options,
manual: true,
});
const ctx = useActionContext();
useEffect(() => {
if (ctx.visible) {
result.run();
}
}, [ctx.visible]);
return result;
};
export const useResetFilterAction = () => {
const { run } = useResourceActionContext();
const form = useForm();
const ctx = useActionContext();
return {
async run() {
form.reset();
run();
ctx.setVisible(false);
},
};
};
export const useKanbanEvents = () => {
const { resource } = useCollection();
return {
async onCardDragEnd({ columns, groupField }, { fromColumnId, fromPosition }, { toColumnId, toPosition }) {
const sourceColumn = columns.find((column) => column.id === fromColumnId);
const destinationColumn = columns.find((column) => column.id === toColumnId);
const sourceCard = sourceColumn?.cards?.[fromPosition];
const targetCard = destinationColumn?.cards?.[toPosition];
const values = {
sourceId: sourceCard.id,
sortField: `${groupField.name}_sort`,
};
if (targetCard) {
values['targetId'] = targetCard.id;
} else {
values['targetScope'] = {
[groupField.name]: toColumnId,
};
}
await resource.move(values);
},
};
};
export const useSortFields = (collectionName: string) => {
const { getCollectionFields, getInterface } = useCollectionManager();
const fields = getCollectionFields(collectionName);
return fields
.filter((field: any) => {
if (!field.interface) {
return false;
}
const fieldInterface = getInterface(field.interface);
if (fieldInterface?.sortable) {
return true;
}
return false;
})
.map((field: any) => {
return {
value: field.name,
label: field?.uiSchema?.title || field.name,
};
});
};
export const useChildrenCollections = (collectionName: string) => {
const { getChildrenCollections } = useCollectionManager();
const childrenCollections = getChildrenCollections(collectionName);
return childrenCollections.map((collection: any) => {
return {
value: collection.name,
label: collection?.title || collection.name,
};
});
};
export const useCollectionFilterOptions = (collectionName: string) => {
const { getCollectionFields, getInterface } = useCollectionManager();
const fields = getCollectionFields(collectionName);
const field2option = (field, depth) => {
if (!field.interface) {
return;
}
const fieldInterface = getInterface(field.interface);
if (!fieldInterface?.filterable) {
return;
}
const { nested, children, operators } = fieldInterface.filterable;
const option = {
name: field.name,
title: field?.uiSchema?.title || field.name,
schema: field?.uiSchema,
operators:
operators?.filter?.((operator) => {
return !operator?.visible || operator.visible(field);
}) || [],
interface: field.interface,
};
if (field.target && depth > 2) {
return;
}
if (depth > 2) {
return option;
}
if (children?.length) {
option['children'] = children;
}
if (nested) {
const targetFields = getCollectionFields(field.target);
const options = getOptions(targetFields, depth + 1).filter(Boolean);
option['children'] = option['children'] || [];
option['children'].push(...options);
}
return option;
};
const getOptions = (fields, depth) => {
const options = [];
fields.forEach((field) => {
const option = field2option(field, depth);
if (option) {
options.push(option);
}
});
return options;
};
const options = getOptions(fields, 1);
const compile = useCompile();
const { getChildrenCollections } = useCollectionManager();
const collection = useCollection();
const childrenCollections = getChildrenCollections(collection.name);
if (childrenCollections.length > 0 && !options.find((v) => v.name == 'tableoid')) {
options.push({
name: 'tableoid',
type: 'string',
title: '{{t("Table OID(Inheritance)")}}',
schema: {
'x-component': 'Select',
enum: [{ value: collection.name, label: compile(collection.title) }].concat(
childrenCollections.map((v) => {
return {
value: v.name,
label: compile(v.title),
};
}),
),
},
operators: [
{
label: '{{t("contains")}}',
value: '$childIn',
schema: {
'x-component': 'Select',
'x-component-props': { mode: 'tags' },
},
},
{
label: '{{t("does not contain")}}',
value: '$childNotIn',
schema: {
'x-component': 'Select',
'x-component-props': { mode: 'tags' },
},
},
],
});
}
return options;
};
export const useLinkageCollectionFilterOptions = (collectionName: string) => {
const { getCollectionFields, getInterface } = useCollectionManager();
const fields = getCollectionFields(collectionName).filter((v)=>!['o2m', 'm2m'].includes(v.interface))
const field2option = (field, depth) => {
if (!field.interface) {
return;
}
const fieldInterface = getInterface(field.interface);
if (!fieldInterface?.filterable) {
return;
}
const { nested, children, operators } = fieldInterface.filterable;
const option = {
name: field.name,
title: field?.uiSchema?.title || field.name,
schema: field?.uiSchema,
operators:
operators?.filter?.((operator) => {
return !operator?.visible || operator.visible(field);
}) || [],
interface: field.interface,
};
if (field.target && depth > 2) {
return;
}
if (depth > 2) {
return option;
}
if (children?.length) {
option['children'] = children;
}
if (nested) {
const targetFields = getCollectionFields(field.target).filter((v)=>!['o2m', 'm2m'].includes(v.interface))
const options = getOptions(targetFields, depth + 1).filter(Boolean);
option['children'] = option['children'] || [];
option['children'].push(...options);
}
return option;
};
const getOptions = (fields, depth) => {
const options = [];
fields.forEach((field) => {
const option = field2option(field, depth);
if (option) {
options.push(option);
}
});
return options;
};
const options = getOptions(fields, 1);
return options;
};
export const useFilterDataSource = (options) => {
const { name } = useCollection();
const data = useCollectionFilterOptions(name);
return useRequest(
() =>
Promise.resolve({
data,
}),
options,
);
};
export const useFilterAction = () => {
const { run, params, defaultRequest } = useResourceActionContext();
const form = useForm();
const ctx = useActionContext();
const [first, ...others] = params;
return {
async run() {
const prevFilter = defaultRequest?.params?.filter;
const filter = prevFilter ? { $and: [prevFilter, form.values.filter] } : form.values.filter;
run({ ...first, filter }, ...others);
ctx.setVisible(false);
},
};
};
export const useCreateAction = () => {
const form = useForm();
const field = useField();
const ctx = useActionContext();
const { refresh } = useResourceActionContext();
const { resource } = useResourceContext();
return {
async run() {
await form.submit();
field.data = field.data || {};
field.data.loading = true;
await resource.create({ values: form.values });
ctx.setVisible(false);
await form.reset();
field.data.loading = false;
refresh();
},
};
};
export const useCreateActionWithoutRefresh = () => {
const form = useForm();
const { resource } = useResourceContext();
return {
async run() {
await form.submit();
await resource.create({ values: form.values });
await form.reset();
},
};
};
export const useUpdateViewAction = () => {
const form = useForm();
const ctx = useActionContext();
// const { refresh } = useResourceActionContext();
const { resource, targetKey } = useResourceContext();
const { [targetKey]: filterByTk } = useRecord();
return {
async run() {
await form.submit();
await resource.update({ filterByTk, values: form.values });
// refresh();
message.success('保存成功');
},
};
};
export const useMoveAction = () => {
const { resource } = useResourceContext();
const { refresh } = useResourceActionContext();
return {
async move(from, to) {
await resource.move({
sourceId: from.id,
targetId: to.id,
});
refresh();
},
};
};
export const useUpdateAction = () => {
const field = useField();
const form = useForm();
const ctx = useActionContext();
const { refresh } = useResourceActionContext();
const { resource, targetKey } = useResourceContext();
const { [targetKey]: filterByTk } = useRecord();
return {
async run() {
await form.submit();
field.data = field.data || {};
field.data.loading = true;
await resource.update({ filterByTk, values: form.values });
ctx.setVisible(false);
await form.reset();
field.data.loading = false;
refresh();
},
};
};
export const useDestroyAction = () => {
const { refresh } = useResourceActionContext();
const { resource, targetKey } = useResourceContext();
const { [targetKey]: filterByTk } = useRecord();
return {
async run() {
await resource.destroy({ filterByTk });
refresh();
},
};
};
export const useBulkDestroyAction = () => {
const { state, setState, refresh } = useResourceActionContext();
const { resource, targetKey } = useResourceContext();
return {
async run() {
await resource.destroy({
filterByTk: state?.selectedRowKeys || [],
});
setState?.({ selectedRowKeys: [] });
refresh();
},
};
};
export const useValuesFromRA = (options) => {
const ctx = useResourceActionContext();
return useRequest(() => Promise.resolve(ctx.data), {
...options,
refreshDeps: [ctx.data],
});
};
export const useCreateActionAndRefreshCM = () => {
const { run } = useCreateAction();
const { refreshCM } = useCollectionManager();
return {
async run() {
await run();
await refreshCM();
},
};
};
export const useUpdateActionAndRefreshCM = () => {
const { run } = useUpdateAction();
const { refreshCM } = useCollectionManager();
return {
async run() {
await run();
await refreshCM();
},
};
};
export const useDestroyActionAndRefreshCM = () => {
const { run } = useDestroyAction();
const { refreshCM } = useCollectionManager();
return {
async run() {
await run();
await refreshCM();
},
};
};
export const useDeleteButtonDisabled = () => {
const { interface: i, deletable = true } = useRecord();
return !deletable || i === 'id';
};
export const useBulkDestroyActionAndRefreshCM = () => {
const { run } = useBulkDestroyAction();
const { refreshCM } = useCollectionManager();
return {
async run() {
await run();
await refreshCM();
},
};
};
export const useFilterActionProps = () => {
const { collection } = useResourceContext();
const options = useFilterFieldOptions(collection.fields);
const service = useResourceActionContext();
return useFilterFieldProps({
options,
params: service.state?.params?.[0] || service.params,
service,
});
};