mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 21:49:25 +08:00
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:
parent
347d43c0c5
commit
0c742fc3ef
@ -2,9 +2,7 @@
|
|||||||
"version": "1.4.10",
|
"version": "1.4.10",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"npmClientArgs": [
|
"npmClientArgs": ["--ignore-engines"],
|
||||||
"--ignore-engines"
|
|
||||||
],
|
|
||||||
"command": {
|
"command": {
|
||||||
"version": {
|
"version": {
|
||||||
"forcePublish": true,
|
"forcePublish": true,
|
||||||
|
@ -19,6 +19,7 @@ import { useCollectionManager_deprecated } from '../../../collection-manager';
|
|||||||
import { compatibleDataId } from '../../../schema-settings/DataTemplates/FormDataTemplates';
|
import { compatibleDataId } from '../../../schema-settings/DataTemplates/FormDataTemplates';
|
||||||
import { useToken } from '../__builtins__';
|
import { useToken } from '../__builtins__';
|
||||||
import { RemoteSelect } from '../remote-select';
|
import { RemoteSelect } from '../remote-select';
|
||||||
|
import { useDataSourceHeaders, useDataSourceKey } from '../../../data-source';
|
||||||
|
|
||||||
export interface ITemplate {
|
export interface ITemplate {
|
||||||
config?: {
|
config?: {
|
||||||
@ -101,11 +102,13 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f
|
|||||||
const [targetTemplateData, setTemplateData] = useState(null);
|
const [targetTemplateData, setTemplateData] = useState(null);
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const dataSource = useDataSourceKey();
|
||||||
|
const headers = useDataSourceHeaders(dataSource);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (enabled && defaultTemplate && form) {
|
if (enabled && defaultTemplate && form) {
|
||||||
form.__template = true;
|
form.__template = true;
|
||||||
if (defaultTemplate.key === 'duplicate') {
|
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();
|
form?.reset();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleTemplateDataChange: any = useCallback(async (value, option) => {
|
const handleTemplateDataChange: any = useCallback(async (value, option, headers) => {
|
||||||
const template = { ...option, dataId: value };
|
const template = { ...option, dataId: value };
|
||||||
setTemplateData(option);
|
setTemplateData(option);
|
||||||
fetchTemplateData(api, template, t)
|
fetchTemplateData(api, template, headers)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (form && data) {
|
if (form && data) {
|
||||||
// 切换之前先把之前的数据清空
|
// 切换之前先把之前的数据清空
|
||||||
@ -194,7 +197,7 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f
|
|||||||
filter: template?.dataScope,
|
filter: template?.dataScope,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onChange={(value) => handleTemplateDataChange(value?.id, { ...value, ...template })}
|
onChange={(value) => handleTemplateDataChange(value?.id, { ...value, ...template }, headers)}
|
||||||
targetField={getCollectionJoinField(`${template?.collection}.${template.titleField}`)}
|
targetField={getCollectionJoinField(`${template?.collection}.${template.titleField}`)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -211,12 +214,16 @@ function findDataTemplates(fieldSchema): ITemplate {
|
|||||||
return {} as 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) {
|
if (template.fields.length === 0 || !template.dataId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return api
|
return api
|
||||||
.resource(template.collection)
|
.resource(template.collection, undefined, headers)
|
||||||
.get({
|
.get({
|
||||||
filterByTk: template.dataId,
|
filterByTk: template.dataId,
|
||||||
fields: template.fields,
|
fields: template.fields,
|
||||||
|
@ -18,7 +18,7 @@ export async function dataTemplate(ctx: Context, next) {
|
|||||||
|
|
||||||
if (isTemplate && actionName === 'get') {
|
if (isTemplate && actionName === 'get') {
|
||||||
ctx.body = traverseJSON(JSON.parse(JSON.stringify(ctx.body)), {
|
ctx.body = traverseJSON(JSON.parse(JSON.stringify(ctx.body)), {
|
||||||
collection: ctx.db.getCollection(resourceName),
|
collection: ctx.getCurrentRepository().collection,
|
||||||
include: [...(fields || []), ...(appends || [])],
|
include: [...(fields || []), ...(appends || [])],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -75,6 +75,7 @@ const traverseJSON = (data, options: TraverseOptions) => {
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { collection, exclude = [], include = [], excludePk = true } = options;
|
const { collection, exclude = [], include = [], excludePk = true } = options;
|
||||||
const map = parseInclude(include);
|
const map = parseInclude(include);
|
||||||
const result = {};
|
const result = {};
|
||||||
@ -94,9 +95,11 @@ const traverseJSON = (data, options: TraverseOptions) => {
|
|||||||
result[key] = data[key];
|
result[key] = data[key];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (field.options.primaryKey && excludePk) {
|
|
||||||
|
if (field.options.primaryKey && excludePk && !collection.isMultiFilterTargetKey()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.options.isForeignKey) {
|
if (field.options.isForeignKey) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,9 @@ import {
|
|||||||
useDesignable,
|
useDesignable,
|
||||||
useFormBlockContext,
|
useFormBlockContext,
|
||||||
useRecord,
|
useRecord,
|
||||||
|
useCollection,
|
||||||
|
useDataSourceHeaders,
|
||||||
|
useDataSourceKey,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import { App, Button } from 'antd';
|
import { App, Button } from 'antd';
|
||||||
import React, { useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
@ -87,6 +90,7 @@ export const DuplicateAction = observer(
|
|||||||
const { duplicateFields, duplicateMode = 'quickDulicate', duplicateCollection } = fieldSchema['x-component-props'];
|
const { duplicateFields, duplicateMode = 'quickDulicate', duplicateCollection } = fieldSchema['x-component-props'];
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
const parentRecordData: any = useCollectionParentRecordData();
|
const parentRecordData: any = useCollectionParentRecordData();
|
||||||
|
const collection = useCollection();
|
||||||
const { id, __collection } = record;
|
const { id, __collection } = record;
|
||||||
const ctx = useActionContext();
|
const ctx = useActionContext();
|
||||||
const { name } = useCollection_deprecated();
|
const { name } = useCollection_deprecated();
|
||||||
@ -95,6 +99,16 @@ export const DuplicateAction = observer(
|
|||||||
const collectionFields = getCollectionFields(__collection || name);
|
const collectionFields = getCollectionFields(__collection || name);
|
||||||
const formctx = useFormBlockContext();
|
const formctx = useFormBlockContext();
|
||||||
const aclCtx = useACLActionParamsContext();
|
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(() => {
|
const buttonStyle = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
opacity: designable && (field?.data?.hidden || !aclCtx) && 0.1,
|
opacity: designable && (field?.data?.hidden || !aclCtx) && 0.1,
|
||||||
@ -102,7 +116,7 @@ export const DuplicateAction = observer(
|
|||||||
}, [designable, field?.data?.hidden]);
|
}, [designable, field?.data?.hidden]);
|
||||||
const template = {
|
const template = {
|
||||||
key: 'duplicate',
|
key: 'duplicate',
|
||||||
dataId: id,
|
dataId,
|
||||||
default: true,
|
default: true,
|
||||||
fields:
|
fields:
|
||||||
duplicateFields?.filter((v) => {
|
duplicateFields?.filter((v) => {
|
||||||
@ -114,7 +128,7 @@ export const DuplicateAction = observer(
|
|||||||
const handelQuickDuplicate = async () => {
|
const handelQuickDuplicate = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const data = await fetchTemplateData(api, template, t);
|
const data = await fetchTemplateData(api, template, headers);
|
||||||
await resource['create']({
|
await resource['create']({
|
||||||
values: {
|
values: {
|
||||||
...data,
|
...data,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user