fix: missing x-data-source parameter in duplicate request template for external data source block (#5882)

* fix: issue with external data source collection duplicate failing to get data template

* fix: missing x-data-source parameter in duplicate request template for external data source block

* fix: date template with external data source

* fix: bug

* fix: data template with multi primary keys

---------

Co-authored-by: Chareice <chareice@live.com>
This commit is contained in:
Katherine 2024-12-17 11:06:51 +08:00 committed by GitHub
parent 347d43c0c5
commit 0c742fc3ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 35 additions and 13 deletions

View File

@ -2,9 +2,7 @@
"version": "1.4.10",
"npmClient": "yarn",
"useWorkspaces": true,
"npmClientArgs": [
"--ignore-engines"
],
"npmClientArgs": ["--ignore-engines"],
"command": {
"version": {
"forcePublish": true,

View File

@ -19,6 +19,7 @@ import { useCollectionManager_deprecated } from '../../../collection-manager';
import { compatibleDataId } from '../../../schema-settings/DataTemplates/FormDataTemplates';
import { useToken } from '../__builtins__';
import { RemoteSelect } from '../remote-select';
import { useDataSourceHeaders, useDataSourceKey } from '../../../data-source';
export interface ITemplate {
config?: {
@ -101,11 +102,13 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f
const [targetTemplateData, setTemplateData] = useState(null);
const api = useAPIClient();
const { t } = useTranslation();
const dataSource = useDataSourceKey();
const headers = useDataSourceHeaders(dataSource);
useEffect(() => {
if (enabled && defaultTemplate && form) {
form.__template = true;
if (defaultTemplate.key === 'duplicate') {
handleTemplateDataChange(defaultTemplate.dataId, defaultTemplate);
handleTemplateDataChange(defaultTemplate.dataId, defaultTemplate, headers);
}
}
}, []);
@ -139,10 +142,10 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f
form?.reset();
}, []);
const handleTemplateDataChange: any = useCallback(async (value, option) => {
const handleTemplateDataChange: any = useCallback(async (value, option, headers) => {
const template = { ...option, dataId: value };
setTemplateData(option);
fetchTemplateData(api, template, t)
fetchTemplateData(api, template, headers)
.then((data) => {
if (form && data) {
// 切换之前先把之前的数据清空
@ -194,7 +197,7 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f
filter: template?.dataScope,
},
}}
onChange={(value) => handleTemplateDataChange(value?.id, { ...value, ...template })}
onChange={(value) => handleTemplateDataChange(value?.id, { ...value, ...template }, headers)}
targetField={getCollectionJoinField(`${template?.collection}.${template.titleField}`)}
/>
)}
@ -211,12 +214,16 @@ function findDataTemplates(fieldSchema): ITemplate {
return {} as ITemplate;
}
export async function fetchTemplateData(api, template: { collection: string; dataId: number; fields: string[] }, t) {
export async function fetchTemplateData(
api,
template: { collection: string; dataId: number; fields: string[] },
headers?,
) {
if (template.fields.length === 0 || !template.dataId) {
return;
}
return api
.resource(template.collection)
.resource(template.collection, undefined, headers)
.get({
filterByTk: template.dataId,
fields: template.fields,

View File

@ -18,7 +18,7 @@ export async function dataTemplate(ctx: Context, next) {
if (isTemplate && actionName === 'get') {
ctx.body = traverseJSON(JSON.parse(JSON.stringify(ctx.body)), {
collection: ctx.db.getCollection(resourceName),
collection: ctx.getCurrentRepository().collection,
include: [...(fields || []), ...(appends || [])],
});
}
@ -75,6 +75,7 @@ const traverseJSON = (data, options: TraverseOptions) => {
if (!data) {
return data;
}
const { collection, exclude = [], include = [], excludePk = true } = options;
const map = parseInclude(include);
const result = {};
@ -94,9 +95,11 @@ const traverseJSON = (data, options: TraverseOptions) => {
result[key] = data[key];
continue;
}
if (field.options.primaryKey && excludePk) {
if (field.options.primaryKey && excludePk && !collection.isMultiFilterTargetKey()) {
continue;
}
if (field.options.isForeignKey) {
continue;
}

View File

@ -27,6 +27,9 @@ import {
useDesignable,
useFormBlockContext,
useRecord,
useCollection,
useDataSourceHeaders,
useDataSourceKey,
} from '@nocobase/client';
import { App, Button } from 'antd';
import React, { useMemo, useState } from 'react';
@ -87,6 +90,7 @@ export const DuplicateAction = observer(
const { duplicateFields, duplicateMode = 'quickDulicate', duplicateCollection } = fieldSchema['x-component-props'];
const record = useRecord();
const parentRecordData: any = useCollectionParentRecordData();
const collection = useCollection();
const { id, __collection } = record;
const ctx = useActionContext();
const { name } = useCollection_deprecated();
@ -95,6 +99,16 @@ export const DuplicateAction = observer(
const collectionFields = getCollectionFields(__collection || name);
const formctx = useFormBlockContext();
const aclCtx = useACLActionParamsContext();
const dataSource = useDataSourceKey();
const headers = useDataSourceHeaders(dataSource);
const dataId = Array.isArray(collection.filterTargetKey)
? Object.assign(
{},
...collection.filterTargetKey.map((v) => {
return { [v]: record[v] };
}),
)
: record[collection.filterTargetKey] || id;
const buttonStyle = useMemo(() => {
return {
opacity: designable && (field?.data?.hidden || !aclCtx) && 0.1,
@ -102,7 +116,7 @@ export const DuplicateAction = observer(
}, [designable, field?.data?.hidden]);
const template = {
key: 'duplicate',
dataId: id,
dataId,
default: true,
fields:
duplicateFields?.filter((v) => {
@ -114,7 +128,7 @@ export const DuplicateAction = observer(
const handelQuickDuplicate = async () => {
setLoading(true);
try {
const data = await fetchTemplateData(api, template, t);
const data = await fetchTemplateData(api, template, headers);
await resource['create']({
values: {
...data,