* fix: bug * test: kanban test * test: gantt block test * test: gantt test * test: gantt test * test: gantt test * refactor: convert parameters to destructured object * test: add tests choices * test: add tests media * test: add tests for datetime in creating form * feat(plugin-mock-collection): generate faker time * test: add tests for datetime in editing form * test: add tests for datetime in details form * test: gantt block test * test: gantt test * test: gantt test * test: gantt test * fix: bug * feat: improve code * test: add tests for relation fields * refactor: style improve * fix: rename SchemaSettings * fix: type bug * refactor: useDesinger() * fix: bug * fix: bug * fix: build tip * refactor: kanban setting * refactor: gantt setting * refactor: bulk update setting * refactor: bulk update setting * refactor: bulk edit settings * refactor: duplicate settings * refactor: print action setting * refactor: duplicate settings * refactor: bulk update refactor * refactor: bulk update refactor * fix: designableState * fix: bug * fix: designable * refactor: bulk update * fix: designable * test: add tests for relation fields * test: add tests for relation fields * test: add tests for relation fields * feat: client api doc * test: add tests for relation fields * test: avoid errors * test: make tests passing * fix: bug * test: gantt test * test: make tests passing * test: add tests for advanced fields * test: increase e2e timeout-minutes to 60 * fix: bug * fix: improve code * feat: add schema initailizer component demos * test: make tests passing * fix: schema settings demos * feat: shallowMerge & deepMerge * test: reduce number of tests * test: make tests passing * feat: updates * fix: add Initializer Internal * demos: useSchemaSettingsRender * test: make tests passing * test: make tests passing * test: bulk update test * refactor: useSchemaToolbar * fix: improve docs * fix: bug * test: duplicate action test * test: duplicate action test * test: duplicate action test * test: duplicate action test * chore: upgrade dumi theme * test: make tests passing * test: add tests for linkage rules * test: add test for form data templates * test: add tests for default value * test: reduce number of tests * refactor: bulk edit setting * test: bulk edit action test * test: bulk edit action test * fix: dn.deepMerge * fix: bug * test: bulk edit action test * test: kanban test * refactor: bulk update version * refactor: print action version * fix: bug * fix: toolbar * fix: docs ssr * test: add tests for system fields * test: add tests for actions * fix: bug * test: add tests for lazy loading of variables * test: make testing more stable * test: bulk edit test * test: bulk update action test * fix: update docs * test: print test * test: kanban test * test: kanban test * refactor: duplicate version * fix: merge bug * refactor: bulk update * fix: merge bug * refactor: bulk edit * refactor: import * refactor: export action * refactor: code improve * refactor: kanban code improve * fix: merge bug * refactor: readPrettyFormActionInitializers * test: print action test * test: print action test * refactor: print action * test: action test * refactor: gantt date change * style: gantt style improve * test: gantt &bulkUpdate test * test: bulk update test * test: duplicate action test * test: print action test * test: bulk edit action test * test: gantt block test * test: kanban block test * test: test file name * test: test file name * test: bulk update action tst * refactor: rename test file name * refactor: bulk update action * refactor: gantt test * fix: block template * fix: block template * fix: useFieldModeOptions * refactor: code improve * fix: merge bug --------- Co-authored-by: dream2023 <1098626505@qq.com> Co-authored-by: Rain <958414905@qq.com> Co-authored-by: chenos <chenlinxh@gmail.com>
197 lines
5.7 KiB
TypeScript
197 lines
5.7 KiB
TypeScript
import { css, cx } from '@emotion/css';
|
|
import { RecursionField, observer, useField, useFieldSchema } from '@formily/react';
|
|
import { App, Button } from 'antd';
|
|
import React, { useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import {
|
|
ActionContextProvider,
|
|
CollectionProvider,
|
|
RecordProvider,
|
|
useAPIClient,
|
|
useActionContext,
|
|
useBlockRequestContext,
|
|
useCollection,
|
|
useCollectionManager,
|
|
useDesignable,
|
|
useRecord,
|
|
fetchTemplateData,
|
|
FormBlockContext,
|
|
useFormBlockContext,
|
|
} from '@nocobase/client';
|
|
|
|
export const actionDesignerCss = css`
|
|
position: relative;
|
|
&:hover {
|
|
.general-schema-designer {
|
|
display: block;
|
|
}
|
|
}
|
|
.general-schema-designer {
|
|
position: absolute;
|
|
z-index: 999;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
display: none;
|
|
background: var(--colorBgSettingsHover);
|
|
border: 0;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
pointer-events: none;
|
|
> .general-schema-designer-icons {
|
|
position: absolute;
|
|
right: 2px;
|
|
top: 2px;
|
|
line-height: 16px;
|
|
pointer-events: all;
|
|
.ant-space-item {
|
|
background-color: var(--colorSettings);
|
|
color: #fff;
|
|
line-height: 16px;
|
|
width: 16px;
|
|
padding-left: 1px;
|
|
align-self: stretch;
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
export const DuplicateAction = observer(
|
|
(props: any) => {
|
|
const { children } = props;
|
|
const { message } = App.useApp();
|
|
const field = useField();
|
|
const fieldSchema = useFieldSchema();
|
|
const api = useAPIClient();
|
|
const disabled: boolean = field.disabled || props.disabled;
|
|
const { designable } = useDesignable();
|
|
const [visible, setVisible] = useState(false);
|
|
const [loading, setLoading] = useState(false);
|
|
const { service, __parent, block } = useBlockRequestContext();
|
|
const { duplicateFields, duplicateMode = 'quickDulicate', duplicateCollection } = fieldSchema['x-component-props'];
|
|
const record = useRecord();
|
|
const { id, __collection } = record;
|
|
const ctx = useActionContext();
|
|
const { name } = useCollection();
|
|
const { getCollectionFields } = useCollectionManager();
|
|
const { t } = useTranslation();
|
|
const collectionFields = getCollectionFields(__collection || name);
|
|
const formctx = useFormBlockContext();
|
|
const template = {
|
|
key: 'duplicate',
|
|
dataId: id,
|
|
default: true,
|
|
fields:
|
|
duplicateFields?.filter((v) => {
|
|
return collectionFields.find((k) => v.includes(k.name));
|
|
}) || [],
|
|
collection: __collection || name,
|
|
};
|
|
const isLinkBtn = fieldSchema['x-component'] === 'Action.Link';
|
|
const handelQuickDuplicate = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const data = await fetchTemplateData(api, template, t);
|
|
await api.resource(__collection || name).create({
|
|
values: {
|
|
...data,
|
|
},
|
|
});
|
|
message.success(t('Saved successfully'));
|
|
if (block === 'form') {
|
|
__parent?.service?.refresh?.();
|
|
} else {
|
|
await service?.refresh?.();
|
|
}
|
|
setLoading(false);
|
|
} catch (error) {
|
|
setLoading(false);
|
|
console.error(error); // Handle or log the error appropriately
|
|
}
|
|
};
|
|
const handelDuplicate = () => {
|
|
if (!disabled && !loading) {
|
|
if (duplicateFields?.length > 0) {
|
|
if (duplicateMode === 'quickDulicate') {
|
|
handelQuickDuplicate();
|
|
} else {
|
|
setVisible(true);
|
|
}
|
|
} else {
|
|
message.error(t('Please configure the duplicate fields'));
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={cx(actionDesignerCss, {
|
|
[css`
|
|
.general-schema-designer {
|
|
top: -10px;
|
|
bottom: -10px;
|
|
left: -10px;
|
|
right: -10px;
|
|
}
|
|
`]: isLinkBtn,
|
|
})}
|
|
>
|
|
<FormBlockContext.Provider
|
|
value={{
|
|
...formctx,
|
|
duplicateData: {
|
|
display: false,
|
|
enabled: true,
|
|
defaultTemplate: template,
|
|
},
|
|
}}
|
|
>
|
|
<div>
|
|
{isLinkBtn ? (
|
|
<a
|
|
role={props.role}
|
|
aria-label={props['aria-label']}
|
|
//@ts-ignore
|
|
disabled={disabled}
|
|
style={{
|
|
opacity: designable && field?.data?.hidden && 0.1,
|
|
cursor: loading ? 'not-allowed' : 'pointer',
|
|
}}
|
|
onClick={handelDuplicate}
|
|
>
|
|
{loading ? t('Duplicating') : children || t('Duplicate')}
|
|
</a>
|
|
) : (
|
|
<Button
|
|
role={props.role}
|
|
aria-label={props['aria-label']}
|
|
disabled={disabled}
|
|
style={{
|
|
opacity: designable && field?.data?.hidden && 0.1,
|
|
}}
|
|
{...props}
|
|
onClick={handelDuplicate}
|
|
>
|
|
{loading ? t('Duplicating') : children || t('Duplicate')}
|
|
</Button>
|
|
)}
|
|
<CollectionProvider name={duplicateCollection || name}>
|
|
<RecordProvider record={{ ...record, __collection: duplicateCollection || __collection }}>
|
|
<ActionContextProvider value={{ ...ctx, visible, setVisible }}>
|
|
<RecursionField schema={fieldSchema} basePath={field.address} onlyRenderProperties />
|
|
</ActionContextProvider>
|
|
</RecordProvider>
|
|
</CollectionProvider>
|
|
</div>
|
|
</FormBlockContext.Provider>
|
|
</div>
|
|
);
|
|
},
|
|
{
|
|
displayName: 'DuplicateAction',
|
|
},
|
|
);
|