tachybase_todo/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/utils.tsx
2024-01-11 15:19:44 +08:00

139 lines
4.8 KiB
TypeScript

import {
useBlockRequestContext,
useTableBlockContext,
useCompile,
useRecord,
useVariables,
useCollection,
useLocalVariables,
isVariable,
transformVariableValue,
TableFieldResource,
} from '@nocobase/client';
import { isURL } from '@nocobase/utils/client';
import { SchemaExpressionScopeContext, useFieldSchema, useField } from '@formily/react';
import { useNavigate } from 'react-router-dom';
import { App, message } from 'antd';
import { useContext } from 'react';
import { useBulkUpdateTranslation } from './locale';
export const useCustomizeBulkUpdateActionProps = () => {
const { field, resource, __parent, service } = useBlockRequestContext();
const expressionScope = useContext(SchemaExpressionScopeContext);
const actionSchema = useFieldSchema();
const tableBlockContext = useTableBlockContext();
const { rowKey } = tableBlockContext;
const selectedRecordKeys =
tableBlockContext.field?.data?.selectedRowKeys ?? expressionScope?.selectedRecordKeys ?? {};
const navigate = useNavigate();
const compile = useCompile();
const { t } = useBulkUpdateTranslation();
const actionField: any = useField();
const { modal } = App.useApp();
const variables = useVariables();
const record = useRecord();
const { name, getField } = useCollection();
const localVariables = useLocalVariables({ currentRecord: { __parent: record, __collectionName: name } });
return {
async onClick() {
const {
assignedValues: originalAssignedValues = {},
onSuccess,
updateMode,
} = actionSchema?.['x-action-settings'] ?? {};
actionField.data = field.data || {};
actionField.data.loading = true;
const assignedValues = {};
const waitList = Object.keys(originalAssignedValues).map(async (key) => {
const value = originalAssignedValues[key];
const collectionField = getField(key);
if (process.env.NODE_ENV !== 'production') {
if (!collectionField) {
throw new Error(`useCustomizeBulkUpdateActionProps: field "${key}" not found in collection "${name}"`);
}
}
if (isVariable(value)) {
const result = await variables?.parseVariable(value, localVariables);
if (result) {
assignedValues[key] = transformVariableValue(result, { targetCollectionField: collectionField });
}
} else if (value != null && value !== '') {
assignedValues[key] = value;
}
});
await Promise.all(waitList);
modal.confirm({
title: t('Bulk update', { ns: 'client' }),
content:
updateMode === 'selected'
? t('Update selected data?', { ns: 'client' })
: t('Update all data?', { ns: 'client' }),
async onOk() {
const { filter } = service.params?.[0] ?? {};
const updateData: { filter?: any; values: any; forceUpdate: boolean } = {
values: { ...assignedValues },
filter,
forceUpdate: false,
};
if (updateMode === 'selected') {
if (!selectedRecordKeys?.length) {
message.error(t('Please select the records to be updated'));
actionField.data.loading = false;
return;
}
updateData.filter = { $and: [{ [rowKey || 'id']: { $in: selectedRecordKeys } }] };
}
if (!updateData.filter) {
updateData.forceUpdate = true;
}
try {
await resource.update(updateData);
} catch (error) {
/* empty */
} finally {
actionField.data.loading = false;
}
service?.refresh?.();
if (!(resource instanceof TableFieldResource)) {
__parent?.service?.refresh?.();
}
if (!onSuccess?.successMessage) {
return;
}
if (onSuccess?.manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
onOk: async () => {
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
} else {
navigate(onSuccess.redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
} else {
navigate(onSuccess.redirectTo);
}
}
}
},
async onCancel() {
actionField.data.loading = false;
},
});
},
};
};