Skip to content

Commit 26f92d9

Browse files
authored
feat: copy versions to new docs (#751)
1 parent e40d038 commit 26f92d9

File tree

3 files changed

+63
-8
lines changed

3 files changed

+63
-8
lines changed

.changeset/wise-ways-pretend.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@blinkk/root-cms': patch
3+
---
4+
5+
feat: copy versions to new docs (#751)

packages/root-cms/ui/components/CopyDocModal/CopyDocModal.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {useState} from 'preact/hooks';
55
import {route} from 'preact-router';
66
import {isSlugValid, normalizeSlug} from '../../../shared/slug.js';
77
import {useModalTheme} from '../../hooks/useModalTheme.js';
8-
import {cmsCopyDoc} from '../../utils/doc.js';
8+
import {cmsCopyDoc, cmsCreateDoc} from '../../utils/doc.js';
99
import {SlugInput} from '../SlugInput/SlugInput.js';
1010
import {Text} from '../Text/Text.js';
1111
import './CopyDocModal.css';
@@ -15,16 +15,19 @@ const MODAL_ID = 'CopyDocModal';
1515
export interface CopyDocModalProps {
1616
[key: string]: unknown;
1717
fromDocId: string;
18+
fields?: Record<string, any>;
19+
fromLabel?: string;
20+
onSuccess?: (newDocId: string) => void;
1821
}
1922

2023
export function useCopyDocModal(props: CopyDocModalProps) {
2124
const modals = useModals();
2225
const modalTheme = useModalTheme();
2326
return {
24-
open: () => {
27+
open: (overrideProps?: Partial<CopyDocModalProps>) => {
2528
modals.openContextModal(MODAL_ID, {
2629
...modalTheme,
27-
innerProps: props,
30+
innerProps: {...props, ...overrideProps},
2831
});
2932
},
3033
};
@@ -40,6 +43,7 @@ export function CopyDocModal(modalProps: ContextModalProps<CopyDocModalProps>) {
4043

4144
const fromDocId = props.fromDocId;
4245
const fromCollectionId = fromDocId.split('/')[0];
46+
const sourceLabel = props.fromLabel || fromDocId;
4347

4448
async function onSubmit(e: Event) {
4549
e.preventDefault();
@@ -61,13 +65,23 @@ export function CopyDocModal(modalProps: ContextModalProps<CopyDocModalProps>) {
6165

6266
const toDocId = `${toCollectionId}/${cleanSlug}`;
6367
try {
64-
await cmsCopyDoc(fromDocId, toDocId, {overwrite: confirmOverwrite});
68+
if (props.fields) {
69+
await cmsCreateDoc(toDocId, {
70+
fields: props.fields,
71+
overwrite: confirmOverwrite,
72+
});
73+
} else {
74+
await cmsCopyDoc(fromDocId, toDocId, {overwrite: confirmOverwrite});
75+
}
6576
context.closeModal(id);
6677
showNotification({
6778
title: 'Copied!',
68-
message: `Succesfully copied ${fromDocId} to ${toDocId}.`,
79+
message: `Succesfully copied ${sourceLabel} to ${toDocId}.`,
6980
autoClose: 5000,
7081
});
82+
if (props.onSuccess) {
83+
props.onSuccess(toDocId);
84+
}
7185
} catch (err) {
7286
const errMsg = String(err);
7387
setError(errMsg);
@@ -93,7 +107,7 @@ export function CopyDocModal(modalProps: ContextModalProps<CopyDocModalProps>) {
93107
From:
94108
</Text>
95109
<Text className="CopyDocModal__from__value" size="body-sm">
96-
<code>{props.fromDocId}</code>
110+
<code>{sourceLabel}</code>
97111
</Text>
98112
</div>
99113

packages/root-cms/ui/components/VersionHistoryModal/VersionHistoryModal.tsx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import {Button, Loader, Table} from '@mantine/core';
22
import {ContextModalProps, useModals} from '@mantine/modals';
33
import {showNotification} from '@mantine/notifications';
4-
import {IconArrowUpRight, IconHistory} from '@tabler/icons-preact';
4+
import {IconArrowUpRight, IconCopy, IconHistory} from '@tabler/icons-preact';
55
import {useEffect, useState} from 'preact/hooks';
66
import {useModalTheme} from '../../hooks/useModalTheme.js';
77
import {Version, cmsListVersions, cmsRestoreVersion} from '../../utils/doc.js';
8+
import {useCopyDocModal} from '../CopyDocModal/CopyDocModal.js';
89
import {Heading} from '../Heading/Heading.js';
910
import {Text} from '../Text/Text.js';
1011
import './VersionHistoryModal.css';
@@ -34,10 +35,11 @@ export function useVersionHistoryModal(props: VersionHistoryModalProps) {
3435
export function VersionHistoryModal(
3536
modalProps: ContextModalProps<VersionHistoryModalProps>
3637
) {
37-
const {innerProps: props} = modalProps;
38+
const {innerProps: props, context, id} = modalProps;
3839
const docId = props.docId;
3940
const [loading, setLoading] = useState(true);
4041
const [versions, setVersions] = useState<Version[]>([]);
42+
const copyDocModal = useCopyDocModal({fromDocId: docId});
4143

4244
const dateFormat = new Intl.DateTimeFormat('en-US', {
4345
year: 'numeric',
@@ -68,6 +70,22 @@ export function VersionHistoryModal(
6870
}
6971
}
7072

73+
function copyToNewDoc(version: Version) {
74+
let label = `${docId}@${version._versionId}`;
75+
const modifiedAt = version.sys?.modifiedAt?.toDate();
76+
if (modifiedAt) {
77+
const isoDate = formatIsoDate(modifiedAt);
78+
label = `${docId}@${isoDate}`;
79+
}
80+
copyDocModal.open({
81+
fields: version.fields || {},
82+
fromLabel: label,
83+
onSuccess: () => {
84+
context.closeModal(id);
85+
},
86+
});
87+
}
88+
7189
function getCompareUrl(version: Version) {
7290
const left = toUrlParam(docId, version._versionId);
7391
const right = toUrlParam(docId, 'draft');
@@ -128,6 +146,15 @@ export function VersionHistoryModal(
128146
>
129147
restore
130148
</Button>
149+
<Button
150+
variant="default"
151+
size="xs"
152+
compact
153+
onClick={() => copyToNewDoc(version)}
154+
leftIcon={<IconCopy size={12} />}
155+
>
156+
copy to doc
157+
</Button>
131158
<Button
132159
className="VersionHistoryModal__versions__buttons__compare"
133160
component="a"
@@ -157,4 +184,13 @@ function toUrlParam(docId: string, versionId: string): string {
157184
.replaceAll('%40', '@');
158185
}
159186

187+
function formatIsoDate(date: Date): string {
188+
const year = date.getFullYear();
189+
const month = String(date.getMonth() + 1).padStart(2, '0');
190+
const day = String(date.getDate()).padStart(2, '0');
191+
const hours = String(date.getHours()).padStart(2, '0');
192+
const minutes = String(date.getMinutes()).padStart(2, '0');
193+
return `${year}-${month}-${day}T${hours}:${minutes}`;
194+
}
195+
160196
VersionHistoryModal.id = MODAL_ID;

0 commit comments

Comments
 (0)