@trieb.work/payload-plugin-backup-mongodb 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +319 -0
- package/dist/backup-dashboard.css +1132 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +3 -0
- package/dist/client.js.map +1 -0
- package/dist/collections/BackupSettings.d.ts +6 -0
- package/dist/collections/BackupSettings.js +91 -0
- package/dist/collections/BackupSettings.js.map +1 -0
- package/dist/collections/BackupTasks.d.ts +2 -0
- package/dist/collections/BackupTasks.js +56 -0
- package/dist/collections/BackupTasks.js.map +1 -0
- package/dist/components/BackupDashboard/BackupItemActions.client.d.ts +7 -0
- package/dist/components/BackupDashboard/BackupItemActions.client.js +90 -0
- package/dist/components/BackupDashboard/BackupItemActions.client.js.map +1 -0
- package/dist/components/BackupDashboard/BackupListCollapsible.client.d.ts +16 -0
- package/dist/components/BackupDashboard/BackupListCollapsible.client.js +597 -0
- package/dist/components/BackupDashboard/BackupListCollapsible.client.js.map +1 -0
- package/dist/components/BackupDashboard/BackupSettingsModal.client.d.ts +2 -0
- package/dist/components/BackupDashboard/BackupSettingsModal.client.js +939 -0
- package/dist/components/BackupDashboard/BackupSettingsModal.client.js.map +1 -0
- package/dist/components/BackupDashboard/CollectionBackupPreviewBody.client.d.ts +18 -0
- package/dist/components/BackupDashboard/CollectionBackupPreviewBody.client.js +267 -0
- package/dist/components/BackupDashboard/CollectionBackupPreviewBody.client.js.map +1 -0
- package/dist/components/BackupDashboard/ManualBackupDialog.client.d.ts +1 -0
- package/dist/components/BackupDashboard/ManualBackupDialog.client.js +276 -0
- package/dist/components/BackupDashboard/ManualBackupDialog.client.js.map +1 -0
- package/dist/components/BackupDashboard/RestoreBackupDialog.client.d.ts +6 -0
- package/dist/components/BackupDashboard/RestoreBackupDialog.client.js +551 -0
- package/dist/components/BackupDashboard/RestoreBackupDialog.client.js.map +1 -0
- package/dist/components/BackupDashboard/TaskActionButton.client.d.ts +29 -0
- package/dist/components/BackupDashboard/TaskActionButton.client.js +240 -0
- package/dist/components/BackupDashboard/TaskActionButton.client.js.map +1 -0
- package/dist/components/BackupDashboard/backupDashboardInlineCss.d.ts +1 -0
- package/dist/components/BackupDashboard/backupDashboardInlineCss.js +3 -0
- package/dist/components/BackupDashboard/backupDashboardInlineCss.js.map +1 -0
- package/dist/components/BackupDashboard/index.client.d.ts +8 -0
- package/dist/components/BackupDashboard/index.client.js +9 -0
- package/dist/components/BackupDashboard/index.client.js.map +1 -0
- package/dist/components/BackupDashboard/index.d.ts +8 -0
- package/dist/components/BackupDashboard/index.js +196 -0
- package/dist/components/BackupDashboard/index.js.map +1 -0
- package/dist/core/archive.d.ts +8 -0
- package/dist/core/archive.js +47 -0
- package/dist/core/archive.js.map +1 -0
- package/dist/core/backup.d.ts +41 -0
- package/dist/core/backup.js +188 -0
- package/dist/core/backup.js.map +1 -0
- package/dist/core/backupBlobIO.d.ts +54 -0
- package/dist/core/backupBlobIO.js +179 -0
- package/dist/core/backupBlobIO.js.map +1 -0
- package/dist/core/backupBlobTransfer.d.ts +29 -0
- package/dist/core/backupBlobTransfer.js +85 -0
- package/dist/core/backupBlobTransfer.js.map +1 -0
- package/dist/core/backupSettings.d.ts +35 -0
- package/dist/core/backupSettings.js +95 -0
- package/dist/core/backupSettings.js.map +1 -0
- package/dist/core/backupSourcePreview.d.ts +10 -0
- package/dist/core/backupSourcePreview.js +33 -0
- package/dist/core/backupSourcePreview.js.map +1 -0
- package/dist/core/blobTokenValidate.d.ts +14 -0
- package/dist/core/blobTokenValidate.js +75 -0
- package/dist/core/blobTokenValidate.js.map +1 -0
- package/dist/core/db.d.ts +24 -0
- package/dist/core/db.js +12 -0
- package/dist/core/db.js.map +1 -0
- package/dist/core/restore.d.ts +27 -0
- package/dist/core/restore.js +199 -0
- package/dist/core/restore.js.map +1 -0
- package/dist/core/restorePreview.d.ts +64 -0
- package/dist/core/restorePreview.js +266 -0
- package/dist/core/restorePreview.js.map +1 -0
- package/dist/core/taskProgress.d.ts +26 -0
- package/dist/core/taskProgress.js +73 -0
- package/dist/core/taskProgress.js.map +1 -0
- package/dist/core/vercelBackupCron.d.ts +8 -0
- package/dist/core/vercelBackupCron.js +38 -0
- package/dist/core/vercelBackupCron.js.map +1 -0
- package/dist/endpoints/createBackupEndpoints.d.ts +1 -0
- package/dist/endpoints/createBackupEndpoints.js +3 -0
- package/dist/endpoints/createBackupEndpoints.js.map +1 -0
- package/dist/endpoints/index.d.ts +3 -0
- package/dist/endpoints/index.js +34 -0
- package/dist/endpoints/index.js.map +1 -0
- package/dist/endpoints/paths/admin-backup-download.d.ts +8 -0
- package/dist/endpoints/paths/admin-backup-download.js +72 -0
- package/dist/endpoints/paths/admin-backup-download.js.map +1 -0
- package/dist/endpoints/paths/admin-delete.d.ts +3 -0
- package/dist/endpoints/paths/admin-delete.js +55 -0
- package/dist/endpoints/paths/admin-delete.js.map +1 -0
- package/dist/endpoints/paths/admin-manual.d.ts +3 -0
- package/dist/endpoints/paths/admin-manual.js +61 -0
- package/dist/endpoints/paths/admin-manual.js.map +1 -0
- package/dist/endpoints/paths/admin-preview.d.ts +6 -0
- package/dist/endpoints/paths/admin-preview.js +102 -0
- package/dist/endpoints/paths/admin-preview.js.map +1 -0
- package/dist/endpoints/paths/admin-restore.d.ts +3 -0
- package/dist/endpoints/paths/admin-restore.js +74 -0
- package/dist/endpoints/paths/admin-restore.js.map +1 -0
- package/dist/endpoints/paths/admin-seed.d.ts +3 -0
- package/dist/endpoints/paths/admin-seed.js +47 -0
- package/dist/endpoints/paths/admin-seed.js.map +1 -0
- package/dist/endpoints/paths/admin-settings.d.ts +3 -0
- package/dist/endpoints/paths/admin-settings.js +230 -0
- package/dist/endpoints/paths/admin-settings.js.map +1 -0
- package/dist/endpoints/paths/admin-task.d.ts +3 -0
- package/dist/endpoints/paths/admin-task.js +34 -0
- package/dist/endpoints/paths/admin-task.js.map +1 -0
- package/dist/endpoints/paths/admin-validate-blob-token.d.ts +8 -0
- package/dist/endpoints/paths/admin-validate-blob-token.js +26 -0
- package/dist/endpoints/paths/admin-validate-blob-token.js.map +1 -0
- package/dist/endpoints/paths/cron-list.d.ts +2 -0
- package/dist/endpoints/paths/cron-list.js +33 -0
- package/dist/endpoints/paths/cron-list.js.map +1 -0
- package/dist/endpoints/paths/cron-restore.d.ts +2 -0
- package/dist/endpoints/paths/cron-restore.js +61 -0
- package/dist/endpoints/paths/cron-restore.js.map +1 -0
- package/dist/endpoints/paths/cron-run.d.ts +3 -0
- package/dist/endpoints/paths/cron-run.js +45 -0
- package/dist/endpoints/paths/cron-run.js.map +1 -0
- package/dist/endpoints/shared.d.ts +13 -0
- package/dist/endpoints/shared.js +58 -0
- package/dist/endpoints/shared.js.map +1 -0
- package/dist/exports/client.d.ts +1 -0
- package/dist/exports/client.js +3 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/rsc.d.ts +1 -0
- package/dist/exports/rsc.js +3 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +82 -0
- package/dist/plugin.js.map +1 -0
- package/dist/publicApiPaths.d.ts +19 -0
- package/dist/publicApiPaths.js +20 -0
- package/dist/publicApiPaths.js.map +1 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/backupSelection.d.ts +6 -0
- package/dist/utils/backupSelection.js +16 -0
- package/dist/utils/backupSelection.js.map +1 -0
- package/dist/utils/blobName.d.ts +32 -0
- package/dist/utils/blobName.js +99 -0
- package/dist/utils/blobName.js.map +1 -0
- package/dist/utils/dashboardRoleAccess.d.ts +23 -0
- package/dist/utils/dashboardRoleAccess.js +64 -0
- package/dist/utils/dashboardRoleAccess.js.map +1 -0
- package/dist/utils/dialogBackdrop.d.ts +9 -0
- package/dist/utils/dialogBackdrop.js +17 -0
- package/dist/utils/dialogBackdrop.js.map +1 -0
- package/dist/utils/formatBytes.d.ts +2 -0
- package/dist/utils/formatBytes.js +20 -0
- package/dist/utils/formatBytes.js.map +1 -0
- package/dist/utils/hostname.d.ts +2 -0
- package/dist/utils/hostname.js +17 -0
- package/dist/utils/hostname.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/maskBlobToken.d.ts +11 -0
- package/dist/utils/maskBlobToken.js +42 -0
- package/dist/utils/maskBlobToken.js.map +1 -0
- package/package.json +140 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from '@payloadcms/ui';
|
|
4
|
+
import { useRouter } from 'next/navigation';
|
|
5
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { backupPluginPublicApiPaths } from '../../publicApiPaths';
|
|
7
|
+
import { skipMongoNamesFromPreview } from '../../utils/backupSelection';
|
|
8
|
+
import { BACKUP_LABEL_MAX_LENGTH, sanitizeBackupLabel } from '../../utils/blobName';
|
|
9
|
+
import { closeNativeDialogOnBackdropPointer } from '../../utils/dialogBackdrop';
|
|
10
|
+
import { CollectionBackupPreviewBody } from './CollectionBackupPreviewBody.client';
|
|
11
|
+
import { TaskActionButton } from './TaskActionButton.client';
|
|
12
|
+
export const ManualBackupDialog = ()=>{
|
|
13
|
+
const router = useRouter();
|
|
14
|
+
const uid = useId();
|
|
15
|
+
const labelInputId = `${uid}-manual-backup-label`;
|
|
16
|
+
const dialogRef = useRef(null);
|
|
17
|
+
const postSuccessCloseTimerRef = useRef(null);
|
|
18
|
+
const [preview, setPreview] = useState(null);
|
|
19
|
+
const [phase, setPhase] = useState('idle');
|
|
20
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
21
|
+
const [selected, setSelected] = useState({});
|
|
22
|
+
const [includeMediaBlobs, setIncludeMediaBlobs] = useState(true);
|
|
23
|
+
const [backupAllCollections, setBackupAllCollections] = useState(false);
|
|
24
|
+
const [label, setLabel] = useState('');
|
|
25
|
+
const resetState = useCallback(()=>{
|
|
26
|
+
setPreview(null);
|
|
27
|
+
setPhase('idle');
|
|
28
|
+
setErrorMessage(null);
|
|
29
|
+
setSelected({});
|
|
30
|
+
setIncludeMediaBlobs(true);
|
|
31
|
+
setBackupAllCollections(false);
|
|
32
|
+
setLabel('');
|
|
33
|
+
}, []);
|
|
34
|
+
useEffect(()=>{
|
|
35
|
+
const el = dialogRef.current;
|
|
36
|
+
if (!el) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const onClose = ()=>{
|
|
40
|
+
if (postSuccessCloseTimerRef.current) {
|
|
41
|
+
clearTimeout(postSuccessCloseTimerRef.current);
|
|
42
|
+
postSuccessCloseTimerRef.current = null;
|
|
43
|
+
}
|
|
44
|
+
resetState();
|
|
45
|
+
};
|
|
46
|
+
el.addEventListener('close', onClose);
|
|
47
|
+
return ()=>el.removeEventListener('close', onClose);
|
|
48
|
+
}, [
|
|
49
|
+
resetState
|
|
50
|
+
]);
|
|
51
|
+
useEffect(()=>{
|
|
52
|
+
return ()=>{
|
|
53
|
+
if (postSuccessCloseTimerRef.current) {
|
|
54
|
+
clearTimeout(postSuccessCloseTimerRef.current);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}, []);
|
|
58
|
+
useEffect(()=>{
|
|
59
|
+
if (!preview) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
setSelected(Object.fromEntries(preview.groups.map((g)=>[
|
|
63
|
+
g.groupId,
|
|
64
|
+
true
|
|
65
|
+
])));
|
|
66
|
+
setIncludeMediaBlobs(true);
|
|
67
|
+
setBackupAllCollections(false);
|
|
68
|
+
}, [
|
|
69
|
+
preview
|
|
70
|
+
]);
|
|
71
|
+
const loadPreview = useCallback(async ()=>{
|
|
72
|
+
setPhase('loading');
|
|
73
|
+
setErrorMessage(null);
|
|
74
|
+
setPreview(null);
|
|
75
|
+
try {
|
|
76
|
+
const locale = typeof document !== 'undefined' ? (document.documentElement.lang || 'en').slice(0, 2) : 'en';
|
|
77
|
+
const response = await fetch(backupPluginPublicApiPaths.adminBackupPreview, {
|
|
78
|
+
body: JSON.stringify({
|
|
79
|
+
locale
|
|
80
|
+
}),
|
|
81
|
+
headers: {
|
|
82
|
+
'Content-Type': 'application/json'
|
|
83
|
+
},
|
|
84
|
+
method: 'POST'
|
|
85
|
+
});
|
|
86
|
+
const data = await response.json();
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
throw new Error(data.error || 'Could not load collections');
|
|
89
|
+
}
|
|
90
|
+
setPreview(data);
|
|
91
|
+
setPhase('ready');
|
|
92
|
+
} catch (e) {
|
|
93
|
+
setPhase('error');
|
|
94
|
+
setErrorMessage(e instanceof Error ? e.message : 'Could not load collections');
|
|
95
|
+
}
|
|
96
|
+
}, []);
|
|
97
|
+
const openDialog = ()=>{
|
|
98
|
+
setPhase('loading');
|
|
99
|
+
setErrorMessage(null);
|
|
100
|
+
setPreview(null);
|
|
101
|
+
setSelected({});
|
|
102
|
+
setIncludeMediaBlobs(true);
|
|
103
|
+
setBackupAllCollections(false);
|
|
104
|
+
setLabel('');
|
|
105
|
+
dialogRef.current?.showModal();
|
|
106
|
+
void loadPreview();
|
|
107
|
+
};
|
|
108
|
+
const skipCollections = useMemo(()=>{
|
|
109
|
+
if (!preview) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
if (backupAllCollections) {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
return skipMongoNamesFromPreview(preview, selected);
|
|
116
|
+
}, [
|
|
117
|
+
backupAllCollections,
|
|
118
|
+
preview,
|
|
119
|
+
selected
|
|
120
|
+
]);
|
|
121
|
+
const mediaGroupIncluded = preview ? backupAllCollections || selected['media'] !== false : false;
|
|
122
|
+
const hasMediaBlobOption = Boolean(preview && preview.mediaBlobCandidates > 0 && mediaGroupIncluded);
|
|
123
|
+
const includeMedia = useMemo(()=>{
|
|
124
|
+
if (!hasMediaBlobOption) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return includeMediaBlobs;
|
|
128
|
+
}, [
|
|
129
|
+
hasMediaBlobOption,
|
|
130
|
+
includeMediaBlobs
|
|
131
|
+
]);
|
|
132
|
+
const sanitizedLabel = useMemo(()=>sanitizeBackupLabel(label), [
|
|
133
|
+
label
|
|
134
|
+
]);
|
|
135
|
+
const backupBody = useMemo(()=>({
|
|
136
|
+
includeMedia,
|
|
137
|
+
label: sanitizedLabel || undefined,
|
|
138
|
+
skipCollections
|
|
139
|
+
}), [
|
|
140
|
+
includeMedia,
|
|
141
|
+
sanitizedLabel,
|
|
142
|
+
skipCollections
|
|
143
|
+
]);
|
|
144
|
+
const closeModalAfterBackupSuccess = useCallback(()=>{
|
|
145
|
+
if (postSuccessCloseTimerRef.current) {
|
|
146
|
+
clearTimeout(postSuccessCloseTimerRef.current);
|
|
147
|
+
}
|
|
148
|
+
postSuccessCloseTimerRef.current = setTimeout(()=>{
|
|
149
|
+
postSuccessCloseTimerRef.current = null;
|
|
150
|
+
router.refresh();
|
|
151
|
+
dialogRef.current?.close();
|
|
152
|
+
}, 1000);
|
|
153
|
+
}, [
|
|
154
|
+
router
|
|
155
|
+
]);
|
|
156
|
+
const onToggleGroup = useCallback((groupId)=>{
|
|
157
|
+
setSelected((prev)=>{
|
|
158
|
+
const isOn = prev[groupId] !== false;
|
|
159
|
+
return {
|
|
160
|
+
...prev,
|
|
161
|
+
[groupId]: !isOn
|
|
162
|
+
};
|
|
163
|
+
});
|
|
164
|
+
}, []);
|
|
165
|
+
const onToggleBackupAllCollections = useCallback(()=>{
|
|
166
|
+
setBackupAllCollections((prev)=>{
|
|
167
|
+
const next = !prev;
|
|
168
|
+
if (next && preview) {
|
|
169
|
+
setSelected(Object.fromEntries(preview.groups.map((g)=>[
|
|
170
|
+
g.groupId,
|
|
171
|
+
true
|
|
172
|
+
])));
|
|
173
|
+
}
|
|
174
|
+
return next;
|
|
175
|
+
});
|
|
176
|
+
}, [
|
|
177
|
+
preview
|
|
178
|
+
]);
|
|
179
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
180
|
+
children: [
|
|
181
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
182
|
+
buttonStyle: "primary",
|
|
183
|
+
onClick: openDialog,
|
|
184
|
+
size: "small",
|
|
185
|
+
children: "Create manual Backup"
|
|
186
|
+
}),
|
|
187
|
+
/*#__PURE__*/ _jsxs("dialog", {
|
|
188
|
+
className: "backup-confirm-dialog backup-confirm-dialog--manual",
|
|
189
|
+
onMouseDown: (e)=>closeNativeDialogOnBackdropPointer(e, dialogRef),
|
|
190
|
+
ref: dialogRef,
|
|
191
|
+
children: [
|
|
192
|
+
/*#__PURE__*/ _jsx("p", {
|
|
193
|
+
className: "backup-confirm-dialog__title",
|
|
194
|
+
children: "Create manual backup"
|
|
195
|
+
}),
|
|
196
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
197
|
+
className: "manual-backup-label",
|
|
198
|
+
children: [
|
|
199
|
+
/*#__PURE__*/ _jsxs("label", {
|
|
200
|
+
className: "manual-backup-label__label",
|
|
201
|
+
htmlFor: labelInputId,
|
|
202
|
+
children: [
|
|
203
|
+
"Label ",
|
|
204
|
+
/*#__PURE__*/ _jsx("span", {
|
|
205
|
+
className: "manual-backup-label__hint",
|
|
206
|
+
children: "(optional)"
|
|
207
|
+
})
|
|
208
|
+
]
|
|
209
|
+
}),
|
|
210
|
+
/*#__PURE__*/ _jsx("input", {
|
|
211
|
+
"aria-label": "Optional backup label",
|
|
212
|
+
autoComplete: "off",
|
|
213
|
+
className: "manual-backup-label__input",
|
|
214
|
+
id: labelInputId,
|
|
215
|
+
maxLength: BACKUP_LABEL_MAX_LENGTH,
|
|
216
|
+
onChange: (e)=>setLabel(e.target.value),
|
|
217
|
+
placeholder: "e.g. pre-release snapshot",
|
|
218
|
+
spellCheck: false,
|
|
219
|
+
type: "text",
|
|
220
|
+
value: label
|
|
221
|
+
}),
|
|
222
|
+
/*#__PURE__*/ _jsx("p", {
|
|
223
|
+
className: "manual-backup-label__help",
|
|
224
|
+
children: "Shown in the backup list so you can find this backup later."
|
|
225
|
+
})
|
|
226
|
+
]
|
|
227
|
+
}),
|
|
228
|
+
/*#__PURE__*/ _jsx(CollectionBackupPreviewBody, {
|
|
229
|
+
errorMessage: errorMessage,
|
|
230
|
+
includeAllCollections: backupAllCollections,
|
|
231
|
+
includeAllLabel: "Backup all collections",
|
|
232
|
+
includeMediaBlobs: includeMediaBlobs,
|
|
233
|
+
onRetry: loadPreview,
|
|
234
|
+
onToggleGroup: onToggleGroup,
|
|
235
|
+
onToggleIncludeAllCollections: onToggleBackupAllCollections,
|
|
236
|
+
onToggleIncludeMedia: ()=>setIncludeMediaBlobs((v)=>!v),
|
|
237
|
+
phase: phase,
|
|
238
|
+
preview: preview,
|
|
239
|
+
selected: selected
|
|
240
|
+
}),
|
|
241
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
242
|
+
className: "backup-confirm-dialog__actions",
|
|
243
|
+
children: [
|
|
244
|
+
/*#__PURE__*/ _jsx(TaskActionButton, {
|
|
245
|
+
body: backupBody,
|
|
246
|
+
buttonStyle: "primary",
|
|
247
|
+
completeLabel: "Backup created",
|
|
248
|
+
endpoint: backupPluginPublicApiPaths.adminManual,
|
|
249
|
+
idleDisabled: phase !== 'ready' && phase !== 'error',
|
|
250
|
+
idleLabel: "Start backup",
|
|
251
|
+
kind: "backup",
|
|
252
|
+
onComplete: closeModalAfterBackupSuccess,
|
|
253
|
+
pendingLabel: "Creating backup…"
|
|
254
|
+
}),
|
|
255
|
+
/*#__PURE__*/ _jsx("button", {
|
|
256
|
+
"aria-label": "Manual backups will not get automatically deleted",
|
|
257
|
+
className: "backup-help-icon",
|
|
258
|
+
"data-tip": "Manual backups will not get automatically deleted",
|
|
259
|
+
type: "button",
|
|
260
|
+
children: "i"
|
|
261
|
+
}),
|
|
262
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
263
|
+
buttonStyle: "secondary",
|
|
264
|
+
onClick: ()=>dialogRef.current?.close(),
|
|
265
|
+
size: "small",
|
|
266
|
+
children: "Cancel"
|
|
267
|
+
})
|
|
268
|
+
]
|
|
269
|
+
})
|
|
270
|
+
]
|
|
271
|
+
})
|
|
272
|
+
]
|
|
273
|
+
});
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
//# sourceMappingURL=ManualBackupDialog.client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/BackupDashboard/ManualBackupDialog.client.tsx"],"sourcesContent":["'use client'\n\nimport { Button } from '@payloadcms/ui'\nimport { useRouter } from 'next/navigation'\nimport { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react'\n\nimport type { BackupSourcePreviewResponse } from '../../core/backupSourcePreview'\n\nimport { backupPluginPublicApiPaths } from '../../publicApiPaths'\nimport { skipMongoNamesFromPreview } from '../../utils/backupSelection'\nimport { BACKUP_LABEL_MAX_LENGTH, sanitizeBackupLabel } from '../../utils/blobName'\nimport { closeNativeDialogOnBackdropPointer } from '../../utils/dialogBackdrop'\nimport { CollectionBackupPreviewBody } from './CollectionBackupPreviewBody.client'\nimport { TaskActionButton } from './TaskActionButton.client'\n\nexport const ManualBackupDialog: React.FC = () => {\n const router = useRouter()\n const uid = useId()\n const labelInputId = `${uid}-manual-backup-label`\n const dialogRef = useRef<HTMLDialogElement>(null)\n const postSuccessCloseTimerRef = useRef<null | ReturnType<typeof setTimeout>>(null)\n const [preview, setPreview] = useState<BackupSourcePreviewResponse | null>(null)\n const [phase, setPhase] = useState<'error' | 'idle' | 'loading' | 'ready'>('idle')\n const [errorMessage, setErrorMessage] = useState<null | string>(null)\n const [selected, setSelected] = useState<Record<string, boolean>>({})\n const [includeMediaBlobs, setIncludeMediaBlobs] = useState(true)\n const [backupAllCollections, setBackupAllCollections] = useState(false)\n const [label, setLabel] = useState('')\n\n const resetState = useCallback(() => {\n setPreview(null)\n setPhase('idle')\n setErrorMessage(null)\n setSelected({})\n setIncludeMediaBlobs(true)\n setBackupAllCollections(false)\n setLabel('')\n }, [])\n\n useEffect(() => {\n const el = dialogRef.current\n if (!el) {\n return\n }\n const onClose = () => {\n if (postSuccessCloseTimerRef.current) {\n clearTimeout(postSuccessCloseTimerRef.current)\n postSuccessCloseTimerRef.current = null\n }\n resetState()\n }\n el.addEventListener('close', onClose)\n return () => el.removeEventListener('close', onClose)\n }, [resetState])\n\n useEffect(() => {\n return () => {\n if (postSuccessCloseTimerRef.current) {\n clearTimeout(postSuccessCloseTimerRef.current)\n }\n }\n }, [])\n\n useEffect(() => {\n if (!preview) {\n return\n }\n setSelected(Object.fromEntries(preview.groups.map((g) => [g.groupId, true])))\n setIncludeMediaBlobs(true)\n setBackupAllCollections(false)\n }, [preview])\n\n const loadPreview = useCallback(async () => {\n setPhase('loading')\n setErrorMessage(null)\n setPreview(null)\n try {\n const locale =\n typeof document !== 'undefined' ? (document.documentElement.lang || 'en').slice(0, 2) : 'en'\n const response = await fetch(backupPluginPublicApiPaths.adminBackupPreview, {\n body: JSON.stringify({ locale }),\n headers: { 'Content-Type': 'application/json' },\n method: 'POST',\n })\n const data = (await response.json()) as { error?: string } & BackupSourcePreviewResponse\n if (!response.ok) {\n throw new Error(data.error || 'Could not load collections')\n }\n setPreview(data)\n setPhase('ready')\n } catch (e) {\n setPhase('error')\n setErrorMessage(e instanceof Error ? e.message : 'Could not load collections')\n }\n }, [])\n\n const openDialog = () => {\n setPhase('loading')\n setErrorMessage(null)\n setPreview(null)\n setSelected({})\n setIncludeMediaBlobs(true)\n setBackupAllCollections(false)\n setLabel('')\n dialogRef.current?.showModal()\n void loadPreview()\n }\n\n const skipCollections = useMemo(() => {\n if (!preview) {\n return []\n }\n if (backupAllCollections) {\n return []\n }\n return skipMongoNamesFromPreview(preview, selected)\n }, [backupAllCollections, preview, selected])\n\n const mediaGroupIncluded = preview ? backupAllCollections || selected['media'] !== false : false\n const hasMediaBlobOption = Boolean(\n preview && preview.mediaBlobCandidates > 0 && mediaGroupIncluded,\n )\n\n const includeMedia = useMemo(() => {\n if (!hasMediaBlobOption) {\n return false\n }\n return includeMediaBlobs\n }, [hasMediaBlobOption, includeMediaBlobs])\n\n const sanitizedLabel = useMemo(() => sanitizeBackupLabel(label), [label])\n\n const backupBody = useMemo(\n () => ({\n includeMedia,\n label: sanitizedLabel || undefined,\n skipCollections,\n }),\n [includeMedia, sanitizedLabel, skipCollections],\n )\n\n const closeModalAfterBackupSuccess = useCallback(() => {\n if (postSuccessCloseTimerRef.current) {\n clearTimeout(postSuccessCloseTimerRef.current)\n }\n postSuccessCloseTimerRef.current = setTimeout(() => {\n postSuccessCloseTimerRef.current = null\n router.refresh()\n dialogRef.current?.close()\n }, 1000)\n }, [router])\n\n const onToggleGroup = useCallback((groupId: string) => {\n setSelected((prev) => {\n const isOn = prev[groupId] !== false\n return { ...prev, [groupId]: !isOn }\n })\n }, [])\n\n const onToggleBackupAllCollections = useCallback(() => {\n setBackupAllCollections((prev) => {\n const next = !prev\n if (next && preview) {\n setSelected(Object.fromEntries(preview.groups.map((g) => [g.groupId, true])))\n }\n return next\n })\n }, [preview])\n\n return (\n <>\n <Button buttonStyle=\"primary\" onClick={openDialog} size=\"small\">\n Create manual Backup\n </Button>\n\n {/* Native <dialog>: backdrop dismiss; element not in jsx-a11y interactive list */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <dialog\n className=\"backup-confirm-dialog backup-confirm-dialog--manual\"\n onMouseDown={(e) => closeNativeDialogOnBackdropPointer(e, dialogRef)}\n ref={dialogRef}\n >\n <p className=\"backup-confirm-dialog__title\">Create manual backup</p>\n\n <div className=\"manual-backup-label\">\n <label className=\"manual-backup-label__label\" htmlFor={labelInputId}>\n Label <span className=\"manual-backup-label__hint\">(optional)</span>\n </label>\n <input\n aria-label=\"Optional backup label\"\n autoComplete=\"off\"\n className=\"manual-backup-label__input\"\n id={labelInputId}\n maxLength={BACKUP_LABEL_MAX_LENGTH}\n onChange={(e) => setLabel(e.target.value)}\n placeholder=\"e.g. pre-release snapshot\"\n spellCheck={false}\n type=\"text\"\n value={label}\n />\n <p className=\"manual-backup-label__help\">\n Shown in the backup list so you can find this backup later.\n </p>\n </div>\n\n <CollectionBackupPreviewBody\n errorMessage={errorMessage}\n includeAllCollections={backupAllCollections}\n includeAllLabel=\"Backup all collections\"\n includeMediaBlobs={includeMediaBlobs}\n onRetry={loadPreview}\n onToggleGroup={onToggleGroup}\n onToggleIncludeAllCollections={onToggleBackupAllCollections}\n onToggleIncludeMedia={() => setIncludeMediaBlobs((v) => !v)}\n phase={phase}\n preview={preview}\n selected={selected}\n />\n\n <div className=\"backup-confirm-dialog__actions\">\n <TaskActionButton\n body={backupBody}\n buttonStyle=\"primary\"\n completeLabel=\"Backup created\"\n endpoint={backupPluginPublicApiPaths.adminManual}\n idleDisabled={phase !== 'ready' && phase !== 'error'}\n idleLabel=\"Start backup\"\n kind=\"backup\"\n onComplete={closeModalAfterBackupSuccess}\n pendingLabel=\"Creating backup…\"\n />\n <button\n aria-label=\"Manual backups will not get automatically deleted\"\n className=\"backup-help-icon\"\n data-tip=\"Manual backups will not get automatically deleted\"\n type=\"button\"\n >\n i\n </button>\n <Button buttonStyle=\"secondary\" onClick={() => dialogRef.current?.close()} size=\"small\">\n Cancel\n </Button>\n </div>\n </dialog>\n </>\n )\n}\n"],"names":["Button","useRouter","useCallback","useEffect","useId","useMemo","useRef","useState","backupPluginPublicApiPaths","skipMongoNamesFromPreview","BACKUP_LABEL_MAX_LENGTH","sanitizeBackupLabel","closeNativeDialogOnBackdropPointer","CollectionBackupPreviewBody","TaskActionButton","ManualBackupDialog","router","uid","labelInputId","dialogRef","postSuccessCloseTimerRef","preview","setPreview","phase","setPhase","errorMessage","setErrorMessage","selected","setSelected","includeMediaBlobs","setIncludeMediaBlobs","backupAllCollections","setBackupAllCollections","label","setLabel","resetState","el","current","onClose","clearTimeout","addEventListener","removeEventListener","Object","fromEntries","groups","map","g","groupId","loadPreview","locale","document","documentElement","lang","slice","response","fetch","adminBackupPreview","body","JSON","stringify","headers","method","data","json","ok","Error","error","e","message","openDialog","showModal","skipCollections","mediaGroupIncluded","hasMediaBlobOption","Boolean","mediaBlobCandidates","includeMedia","sanitizedLabel","backupBody","undefined","closeModalAfterBackupSuccess","setTimeout","refresh","close","onToggleGroup","prev","isOn","onToggleBackupAllCollections","next","buttonStyle","onClick","size","dialog","className","onMouseDown","ref","p","div","htmlFor","span","input","aria-label","autoComplete","id","maxLength","onChange","target","value","placeholder","spellCheck","type","includeAllCollections","includeAllLabel","onRetry","onToggleIncludeAllCollections","onToggleIncludeMedia","v","completeLabel","endpoint","adminManual","idleDisabled","idleLabel","kind","onComplete","pendingLabel","button","data-tip"],"mappings":"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"}
|