Skip to content

Commit

Permalink
feat: support duplicate template
Browse files Browse the repository at this point in the history
  • Loading branch information
airslice committed Nov 18, 2024
1 parent 765f987 commit 7e5cc3a
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type TemplateHeaderProps = {
templateNames: string[];
onTemplateRename?: (templateName: string) => void;
onTemplateRemove?: (templateId: string) => void;
onTemplateDuplicate?: (templateName: string) => void;
};

export const TemplateHeader: React.FC<TemplateHeaderProps> = ({
Expand All @@ -25,6 +26,7 @@ export const TemplateHeader: React.FC<TemplateHeaderProps> = ({
templateNames,
onTemplateRename,
onTemplateRemove,
onTemplateDuplicate,
}) => {
const [menuOpen, setMenuOpen] = useState(false);
const anchorRef = useRef<HTMLButtonElement>(null);
Expand Down Expand Up @@ -85,6 +87,38 @@ export const TemplateHeader: React.FC<TemplateHeaderProps> = ({
setRenameTemplateOpen(false);
}, [newTemplateName, onTemplateRename]);

const [duplicateTemplateOpen, setDuplicateTemplateOpen] = useState(false);
const handleOpenDuplicateTemplate = useCallback(() => {
setDuplicateTemplateOpen(true);
setMenuOpen(false);
}, []);
const handleCloseDuplicateTemplate = useCallback(() => {
setDuplicateTemplateOpen(false);
setDuplicatedTemplateName(generateDuplicateTemplateName(templateName));
}, [templateName]);

const [duplicatedTemplateName, setDuplicatedTemplateName] = useState(
generateDuplicateTemplateName(templateName),
);
const handleDuplicatedTemplateNameChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setDuplicatedTemplateName(e.target.value);
},
[],
);
const duplicatedTemplateNameValid = useMemo(() => {
return (
templateNames.includes(duplicatedTemplateName) ||
duplicatedTemplateName === "" ||
duplicatedTemplateName.endsWith("/") ||
duplicatedTemplateName.split("/").some(p => p === "")
);
}, [duplicatedTemplateName, templateNames]);
const handleTemplateDuplicate = useCallback(() => {
onTemplateDuplicate?.(duplicatedTemplateName);
setDuplicateTemplateOpen(false);
}, [duplicatedTemplateName, onTemplateDuplicate]);

return (
<EditorClickAwayListener onClickAway={handleClickAway}>
<Wrapper>
Expand All @@ -102,6 +136,9 @@ export const TemplateHeader: React.FC<TemplateHeaderProps> = ({
<EditorPopperListItemButton onClick={handleOpenRenameTemplate}>
Rename
</EditorPopperListItemButton>
<EditorPopperListItemButton onClick={handleOpenDuplicateTemplate}>
Duplicate
</EditorPopperListItemButton>
<EditorPopperListItemButton onClick={handleOpenRemoveTemplate}>
Delete
</EditorPopperListItemButton>
Expand Down Expand Up @@ -138,6 +175,22 @@ export const TemplateHeader: React.FC<TemplateHeaderProps> = ({
onChange={handleNewTemplateNameChange}
/>
</EditorDialog>
<EditorDialog
title="Duplicate Template"
open={duplicateTemplateOpen}
fullWidth
primaryButtonText="Duplicate"
onClose={handleCloseDuplicateTemplate}
onSubmit={handleTemplateDuplicate}
submitDisabled={duplicatedTemplateNameValid}>
<EditorTextField
autoFocus
label="Full path:"
fullWidth
value={duplicatedTemplateName}
onChange={handleDuplicatedTemplateNameChange}
/>
</EditorDialog>
</Wrapper>
</EditorClickAwayListener>
);
Expand Down Expand Up @@ -167,3 +220,7 @@ const StyledButton = styled(Button)(({ theme }) => ({
borderRadius: "0",
},
}));

function generateDuplicateTemplateName(ori: string) {
return `${ori} (copy-${new Date().getTime()})`;
}
38 changes: 38 additions & 0 deletions extension/src/editor/containers/component-template/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,43 @@ export const EditorFieldComponentsTemplateSection: React.FC<
[editorNoticeRef, removeTemplate],
);

const handleTemplateDuplicate = useCallback(
async (newTemplateName: string) => {
if (!template) return;
const newTemplate = {
name: newTemplateName,
type: "component",
groups: template.groups.map(g => ({
...g,
id: generateID(),
components: g.components.map(c => ({
...c,
id: generateID(),
})),
})),
} as unknown as ComponentTemplate;

setIsSaving(true);
await saveTemplate(newTemplate)
.then(() => {
editorNoticeRef?.current?.show({
severity: "success",
message: "Template duplicated!",
});
})
.catch(() => {
editorNoticeRef?.current?.show({
severity: "error",
message: "Template duplicate failed!",
});
})
.finally(() => {
setIsSaving(false);
});
},
[editorNoticeRef, saveTemplate, template],
);

return (
<EditorSection
sidebarMain={
Expand Down Expand Up @@ -230,6 +267,7 @@ export const EditorFieldComponentsTemplateSection: React.FC<
templateNames={templateNames}
onTemplateRename={handleTemplateRename}
onTemplateRemove={handleTemplateRemove}
onTemplateDuplicate={handleTemplateDuplicate}
/>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useMemo, useState, useCallback, useEffect } from "react";

import { useTemplateAPI } from "../../../shared/api";
import { EmphasisPropertyTemplate } from "../../../shared/api/types";
import { generateID } from "../../../shared/utils";
import { TemplateAddButton } from "../common/commonTemplate/TemplateAddButton";
import { TemplateHeader } from "../common/commonTemplate/TemplateHeader";
import { EditorSection, EditorTree, EditorTreeSelection } from "../ui-components";
Expand Down Expand Up @@ -188,6 +189,36 @@ export const EditorInspectorEmphasisPropertyTemplateSection: React.FC<
[editorNoticeRef, removeTemplate],
);

const handleTemplateDuplicate = useCallback(
async (newTemplateName: string) => {
if (!template) return;
const newTemplate = {
name: newTemplateName,
type: "emphasis",
properties: template.properties.map(p => ({ ...p, id: generateID() })),
} as unknown as EmphasisPropertyTemplate;

setIsSaving(true);
await saveTemplate(newTemplate)
.then(() => {
editorNoticeRef?.current?.show({
severity: "success",
message: "Template duplicated!",
});
})
.catch(() => {
editorNoticeRef?.current?.show({
severity: "error",
message: "Template duplicate failed!",
});
})
.finally(() => {
setIsSaving(false);
});
},
[editorNoticeRef, saveTemplate, template],
);

return (
<EditorSection
sidebarMain={
Expand Down Expand Up @@ -223,6 +254,7 @@ export const EditorInspectorEmphasisPropertyTemplateSection: React.FC<
templateNames={templateNames}
onTemplateRename={handleTemplateRename}
onTemplateRemove={handleTemplateRemove}
onTemplateDuplicate={handleTemplateDuplicate}
/>
)
}
Expand Down

0 comments on commit 7e5cc3a

Please sign in to comment.