tachybase_todo/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateAction.tsx
katherinehhh b1610e6994
feat: kanban& gantt&bulk edit& bulk update& duplicate& print action pluggable (#3019)
* 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>
2023-12-16 21:59:33 +08:00

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',
},
);