Merge branch 'next' into develop

This commit is contained in:
nocobase[bot] 2024-12-17 03:07:36 +00:00
commit c0871f57d1
3 changed files with 34 additions and 10 deletions

View File

@ -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 = React.memo(({ style = {}, form }: { style?: React.CSSPr
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 = React.memo(({ style = {}, form }: { style?: React.CSSPr
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 = React.memo(({ style = {}, form }: { style?: React.CSSPr
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}`)}
/> />
)} )}
@ -213,12 +216,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,

View File

@ -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;
} }

View File

@ -29,6 +29,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 _ from 'lodash'; import _ from 'lodash';
@ -90,6 +93,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();
@ -98,6 +102,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,
@ -105,7 +119,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) => {
@ -117,7 +131,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,