@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.
Files changed (165) hide show
  1. package/README.md +319 -0
  2. package/dist/backup-dashboard.css +1132 -0
  3. package/dist/client.d.ts +3 -0
  4. package/dist/client.js +3 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/collections/BackupSettings.d.ts +6 -0
  7. package/dist/collections/BackupSettings.js +91 -0
  8. package/dist/collections/BackupSettings.js.map +1 -0
  9. package/dist/collections/BackupTasks.d.ts +2 -0
  10. package/dist/collections/BackupTasks.js +56 -0
  11. package/dist/collections/BackupTasks.js.map +1 -0
  12. package/dist/components/BackupDashboard/BackupItemActions.client.d.ts +7 -0
  13. package/dist/components/BackupDashboard/BackupItemActions.client.js +90 -0
  14. package/dist/components/BackupDashboard/BackupItemActions.client.js.map +1 -0
  15. package/dist/components/BackupDashboard/BackupListCollapsible.client.d.ts +16 -0
  16. package/dist/components/BackupDashboard/BackupListCollapsible.client.js +597 -0
  17. package/dist/components/BackupDashboard/BackupListCollapsible.client.js.map +1 -0
  18. package/dist/components/BackupDashboard/BackupSettingsModal.client.d.ts +2 -0
  19. package/dist/components/BackupDashboard/BackupSettingsModal.client.js +939 -0
  20. package/dist/components/BackupDashboard/BackupSettingsModal.client.js.map +1 -0
  21. package/dist/components/BackupDashboard/CollectionBackupPreviewBody.client.d.ts +18 -0
  22. package/dist/components/BackupDashboard/CollectionBackupPreviewBody.client.js +267 -0
  23. package/dist/components/BackupDashboard/CollectionBackupPreviewBody.client.js.map +1 -0
  24. package/dist/components/BackupDashboard/ManualBackupDialog.client.d.ts +1 -0
  25. package/dist/components/BackupDashboard/ManualBackupDialog.client.js +276 -0
  26. package/dist/components/BackupDashboard/ManualBackupDialog.client.js.map +1 -0
  27. package/dist/components/BackupDashboard/RestoreBackupDialog.client.d.ts +6 -0
  28. package/dist/components/BackupDashboard/RestoreBackupDialog.client.js +551 -0
  29. package/dist/components/BackupDashboard/RestoreBackupDialog.client.js.map +1 -0
  30. package/dist/components/BackupDashboard/TaskActionButton.client.d.ts +29 -0
  31. package/dist/components/BackupDashboard/TaskActionButton.client.js +240 -0
  32. package/dist/components/BackupDashboard/TaskActionButton.client.js.map +1 -0
  33. package/dist/components/BackupDashboard/backupDashboardInlineCss.d.ts +1 -0
  34. package/dist/components/BackupDashboard/backupDashboardInlineCss.js +3 -0
  35. package/dist/components/BackupDashboard/backupDashboardInlineCss.js.map +1 -0
  36. package/dist/components/BackupDashboard/index.client.d.ts +8 -0
  37. package/dist/components/BackupDashboard/index.client.js +9 -0
  38. package/dist/components/BackupDashboard/index.client.js.map +1 -0
  39. package/dist/components/BackupDashboard/index.d.ts +8 -0
  40. package/dist/components/BackupDashboard/index.js +196 -0
  41. package/dist/components/BackupDashboard/index.js.map +1 -0
  42. package/dist/core/archive.d.ts +8 -0
  43. package/dist/core/archive.js +47 -0
  44. package/dist/core/archive.js.map +1 -0
  45. package/dist/core/backup.d.ts +41 -0
  46. package/dist/core/backup.js +188 -0
  47. package/dist/core/backup.js.map +1 -0
  48. package/dist/core/backupBlobIO.d.ts +54 -0
  49. package/dist/core/backupBlobIO.js +179 -0
  50. package/dist/core/backupBlobIO.js.map +1 -0
  51. package/dist/core/backupBlobTransfer.d.ts +29 -0
  52. package/dist/core/backupBlobTransfer.js +85 -0
  53. package/dist/core/backupBlobTransfer.js.map +1 -0
  54. package/dist/core/backupSettings.d.ts +35 -0
  55. package/dist/core/backupSettings.js +95 -0
  56. package/dist/core/backupSettings.js.map +1 -0
  57. package/dist/core/backupSourcePreview.d.ts +10 -0
  58. package/dist/core/backupSourcePreview.js +33 -0
  59. package/dist/core/backupSourcePreview.js.map +1 -0
  60. package/dist/core/blobTokenValidate.d.ts +14 -0
  61. package/dist/core/blobTokenValidate.js +75 -0
  62. package/dist/core/blobTokenValidate.js.map +1 -0
  63. package/dist/core/db.d.ts +24 -0
  64. package/dist/core/db.js +12 -0
  65. package/dist/core/db.js.map +1 -0
  66. package/dist/core/restore.d.ts +27 -0
  67. package/dist/core/restore.js +199 -0
  68. package/dist/core/restore.js.map +1 -0
  69. package/dist/core/restorePreview.d.ts +64 -0
  70. package/dist/core/restorePreview.js +266 -0
  71. package/dist/core/restorePreview.js.map +1 -0
  72. package/dist/core/taskProgress.d.ts +26 -0
  73. package/dist/core/taskProgress.js +73 -0
  74. package/dist/core/taskProgress.js.map +1 -0
  75. package/dist/core/vercelBackupCron.d.ts +8 -0
  76. package/dist/core/vercelBackupCron.js +38 -0
  77. package/dist/core/vercelBackupCron.js.map +1 -0
  78. package/dist/endpoints/createBackupEndpoints.d.ts +1 -0
  79. package/dist/endpoints/createBackupEndpoints.js +3 -0
  80. package/dist/endpoints/createBackupEndpoints.js.map +1 -0
  81. package/dist/endpoints/index.d.ts +3 -0
  82. package/dist/endpoints/index.js +34 -0
  83. package/dist/endpoints/index.js.map +1 -0
  84. package/dist/endpoints/paths/admin-backup-download.d.ts +8 -0
  85. package/dist/endpoints/paths/admin-backup-download.js +72 -0
  86. package/dist/endpoints/paths/admin-backup-download.js.map +1 -0
  87. package/dist/endpoints/paths/admin-delete.d.ts +3 -0
  88. package/dist/endpoints/paths/admin-delete.js +55 -0
  89. package/dist/endpoints/paths/admin-delete.js.map +1 -0
  90. package/dist/endpoints/paths/admin-manual.d.ts +3 -0
  91. package/dist/endpoints/paths/admin-manual.js +61 -0
  92. package/dist/endpoints/paths/admin-manual.js.map +1 -0
  93. package/dist/endpoints/paths/admin-preview.d.ts +6 -0
  94. package/dist/endpoints/paths/admin-preview.js +102 -0
  95. package/dist/endpoints/paths/admin-preview.js.map +1 -0
  96. package/dist/endpoints/paths/admin-restore.d.ts +3 -0
  97. package/dist/endpoints/paths/admin-restore.js +74 -0
  98. package/dist/endpoints/paths/admin-restore.js.map +1 -0
  99. package/dist/endpoints/paths/admin-seed.d.ts +3 -0
  100. package/dist/endpoints/paths/admin-seed.js +47 -0
  101. package/dist/endpoints/paths/admin-seed.js.map +1 -0
  102. package/dist/endpoints/paths/admin-settings.d.ts +3 -0
  103. package/dist/endpoints/paths/admin-settings.js +230 -0
  104. package/dist/endpoints/paths/admin-settings.js.map +1 -0
  105. package/dist/endpoints/paths/admin-task.d.ts +3 -0
  106. package/dist/endpoints/paths/admin-task.js +34 -0
  107. package/dist/endpoints/paths/admin-task.js.map +1 -0
  108. package/dist/endpoints/paths/admin-validate-blob-token.d.ts +8 -0
  109. package/dist/endpoints/paths/admin-validate-blob-token.js +26 -0
  110. package/dist/endpoints/paths/admin-validate-blob-token.js.map +1 -0
  111. package/dist/endpoints/paths/cron-list.d.ts +2 -0
  112. package/dist/endpoints/paths/cron-list.js +33 -0
  113. package/dist/endpoints/paths/cron-list.js.map +1 -0
  114. package/dist/endpoints/paths/cron-restore.d.ts +2 -0
  115. package/dist/endpoints/paths/cron-restore.js +61 -0
  116. package/dist/endpoints/paths/cron-restore.js.map +1 -0
  117. package/dist/endpoints/paths/cron-run.d.ts +3 -0
  118. package/dist/endpoints/paths/cron-run.js +45 -0
  119. package/dist/endpoints/paths/cron-run.js.map +1 -0
  120. package/dist/endpoints/shared.d.ts +13 -0
  121. package/dist/endpoints/shared.js +58 -0
  122. package/dist/endpoints/shared.js.map +1 -0
  123. package/dist/exports/client.d.ts +1 -0
  124. package/dist/exports/client.js +3 -0
  125. package/dist/exports/client.js.map +1 -0
  126. package/dist/exports/rsc.d.ts +1 -0
  127. package/dist/exports/rsc.js +3 -0
  128. package/dist/exports/rsc.js.map +1 -0
  129. package/dist/index.d.ts +18 -0
  130. package/dist/index.js +14 -0
  131. package/dist/index.js.map +1 -0
  132. package/dist/plugin.d.ts +3 -0
  133. package/dist/plugin.js +82 -0
  134. package/dist/plugin.js.map +1 -0
  135. package/dist/publicApiPaths.d.ts +19 -0
  136. package/dist/publicApiPaths.js +20 -0
  137. package/dist/publicApiPaths.js.map +1 -0
  138. package/dist/types.d.ts +21 -0
  139. package/dist/types.js +3 -0
  140. package/dist/types.js.map +1 -0
  141. package/dist/utils/backupSelection.d.ts +6 -0
  142. package/dist/utils/backupSelection.js +16 -0
  143. package/dist/utils/backupSelection.js.map +1 -0
  144. package/dist/utils/blobName.d.ts +32 -0
  145. package/dist/utils/blobName.js +99 -0
  146. package/dist/utils/blobName.js.map +1 -0
  147. package/dist/utils/dashboardRoleAccess.d.ts +23 -0
  148. package/dist/utils/dashboardRoleAccess.js +64 -0
  149. package/dist/utils/dashboardRoleAccess.js.map +1 -0
  150. package/dist/utils/dialogBackdrop.d.ts +9 -0
  151. package/dist/utils/dialogBackdrop.js +17 -0
  152. package/dist/utils/dialogBackdrop.js.map +1 -0
  153. package/dist/utils/formatBytes.d.ts +2 -0
  154. package/dist/utils/formatBytes.js +20 -0
  155. package/dist/utils/formatBytes.js.map +1 -0
  156. package/dist/utils/hostname.d.ts +2 -0
  157. package/dist/utils/hostname.js +17 -0
  158. package/dist/utils/hostname.js.map +1 -0
  159. package/dist/utils/index.d.ts +5 -0
  160. package/dist/utils/index.js +7 -0
  161. package/dist/utils/index.js.map +1 -0
  162. package/dist/utils/maskBlobToken.d.ts +11 -0
  163. package/dist/utils/maskBlobToken.js +42 -0
  164. package/dist/utils/maskBlobToken.js.map +1 -0
  165. 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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"}
@@ -0,0 +1,6 @@
1
+ type RestoreBackupDialogProps = {
2
+ downloadUrl: string;
3
+ pathname: string;
4
+ };
5
+ export declare const RestoreBackupDialog: React.FC<RestoreBackupDialogProps>;
6
+ export {};