@futo-org/backups-orchestrator-ui 0.1.71

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 (192) hide show
  1. package/LICENSE +41 -0
  2. package/dist/components/backends/BackendItem.svelte +64 -0
  3. package/dist/components/backends/BackendItem.svelte.d.ts +10 -0
  4. package/dist/components/backends/BackendsList.svelte +73 -0
  5. package/dist/components/backends/BackendsList.svelte.d.ts +7 -0
  6. package/dist/components/backends/CreateLocalBackend.svelte +46 -0
  7. package/dist/components/backends/CreateLocalBackend.svelte.d.ts +7 -0
  8. package/dist/components/backends/OAuthDeviceFlow.svelte +78 -0
  9. package/dist/components/backends/OAuthDeviceFlow.svelte.d.ts +9 -0
  10. package/dist/components/backups/BackupItem.svelte +59 -0
  11. package/dist/components/backups/BackupItem.svelte.d.ts +7 -0
  12. package/dist/components/backups/BackupsList.svelte +82 -0
  13. package/dist/components/backups/BackupsList.svelte.d.ts +8 -0
  14. package/dist/components/backups/dialogs/ConfigureRepositoryModal.svelte +102 -0
  15. package/dist/components/backups/dialogs/ConfigureRepositoryModal.svelte.d.ts +8 -0
  16. package/dist/components/backups/dialogs/CreateRepositoryModal.svelte +59 -0
  17. package/dist/components/backups/dialogs/CreateRepositoryModal.svelte.d.ts +6 -0
  18. package/dist/components/backups/dialogs/ImportRepositoryModal.svelte +62 -0
  19. package/dist/components/backups/dialogs/ImportRepositoryModal.svelte.d.ts +8 -0
  20. package/dist/components/backups/dialogs/RestoreSnapshotModal.svelte +109 -0
  21. package/dist/components/backups/dialogs/RestoreSnapshotModal.svelte.d.ts +8 -0
  22. package/dist/components/backups/dialogs/ViewLogModal.svelte +208 -0
  23. package/dist/components/backups/dialogs/ViewLogModal.svelte.d.ts +7 -0
  24. package/dist/components/backups/metrics-history/MetricsHistoryModal.svelte +166 -0
  25. package/dist/components/backups/metrics-history/MetricsHistoryModal.svelte.d.ts +8 -0
  26. package/dist/components/backups/run-history/RepositoryRunHistory.svelte +39 -0
  27. package/dist/components/backups/run-history/RepositoryRunHistory.svelte.d.ts +7 -0
  28. package/dist/components/backups/run-history/RepositoryRunHistoryItem.svelte +45 -0
  29. package/dist/components/backups/run-history/RepositoryRunHistoryItem.svelte.d.ts +7 -0
  30. package/dist/components/backups/run-history/RunHistoryModal.svelte +18 -0
  31. package/dist/components/backups/run-history/RunHistoryModal.svelte.d.ts +8 -0
  32. package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte +53 -0
  33. package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte.d.ts +7 -0
  34. package/dist/components/backups/snapshots-list/RepositorySnapshotsListItem.svelte +41 -0
  35. package/dist/components/backups/snapshots-list/RepositorySnapshotsListItem.svelte.d.ts +8 -0
  36. package/dist/components/backups/snapshots-list/SnapshotsListModal.svelte +18 -0
  37. package/dist/components/backups/snapshots-list/SnapshotsListModal.svelte.d.ts +8 -0
  38. package/dist/components/dashboard/Dashboard.svelte +52 -0
  39. package/dist/components/dashboard/Dashboard.svelte.d.ts +9 -0
  40. package/dist/components/dashboard/DashboardAvgBackupTime.svelte +34 -0
  41. package/dist/components/dashboard/DashboardAvgBackupTime.svelte.d.ts +7 -0
  42. package/dist/components/dashboard/DashboardBackupHealth.svelte +91 -0
  43. package/dist/components/dashboard/DashboardBackupHealth.svelte.d.ts +9 -0
  44. package/dist/components/dashboard/DashboardCurrentUsage.svelte +10 -0
  45. package/dist/components/dashboard/DashboardCurrentUsage.svelte.d.ts +18 -0
  46. package/dist/components/dashboard/DashboardDailyBackupTime.svelte +31 -0
  47. package/dist/components/dashboard/DashboardDailyBackupTime.svelte.d.ts +7 -0
  48. package/dist/components/dashboard/DashboardInstall.svelte +15 -0
  49. package/dist/components/dashboard/DashboardInstall.svelte.d.ts +18 -0
  50. package/dist/components/dashboard/DashboardRecentBackups.svelte +104 -0
  51. package/dist/components/dashboard/DashboardRecentBackups.svelte.d.ts +8 -0
  52. package/dist/components/dashboard/DashboardTotalStored.svelte +27 -0
  53. package/dist/components/dashboard/DashboardTotalStored.svelte.d.ts +7 -0
  54. package/dist/components/integrations/immich/ImmichBackupsPage.svelte +14 -0
  55. package/dist/components/integrations/immich/ImmichBackupsPage.svelte.d.ts +6 -0
  56. package/dist/components/integrations/immich/ImmichConfigureBackup.svelte +402 -0
  57. package/dist/components/integrations/immich/ImmichConfigureBackup.svelte.d.ts +9 -0
  58. package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte +80 -0
  59. package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte.d.ts +8 -0
  60. package/dist/components/integrations/immich/ImmichManageBackup.svelte +77 -0
  61. package/dist/components/integrations/immich/ImmichManageBackup.svelte.d.ts +3 -0
  62. package/dist/components/integrations/immich/ImmichManageBackupOverview.svelte +100 -0
  63. package/dist/components/integrations/immich/ImmichManageBackupOverview.svelte.d.ts +8 -0
  64. package/dist/components/integrations/immich/ImmichOnboardingRestoreFlow.svelte +75 -0
  65. package/dist/components/integrations/immich/ImmichOnboardingRestoreFlow.svelte.d.ts +7 -0
  66. package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte +113 -0
  67. package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte.d.ts +8 -0
  68. package/dist/components/onboarding/OnboardingGate.svelte +48 -0
  69. package/dist/components/onboarding/OnboardingGate.svelte.d.ts +9 -0
  70. package/dist/components/onboarding/RecoveryKeyDisplay.svelte +103 -0
  71. package/dist/components/onboarding/RecoveryKeyDisplay.svelte.d.ts +6 -0
  72. package/dist/components/onboarding/SampleOnboarding.svelte +98 -0
  73. package/dist/components/onboarding/SampleOnboarding.svelte.d.ts +9 -0
  74. package/dist/components/onboarding/dialogs/BackupsRecoveryKeyModal.svelte +43 -0
  75. package/dist/components/onboarding/dialogs/BackupsRecoveryKeyModal.svelte.d.ts +6 -0
  76. package/dist/components/onboarding/restore-point-flow/RestorePointFlow.svelte +96 -0
  77. package/dist/components/onboarding/restore-point-flow/RestorePointFlow.svelte.d.ts +8 -0
  78. package/dist/components/onboarding/restore-point-flow/RestorePointFlow2SelectSnapshot.svelte +83 -0
  79. package/dist/components/onboarding/restore-point-flow/RestorePointFlow2SelectSnapshot.svelte.d.ts +9 -0
  80. package/dist/components/onboarding/restore-point-flow/RestorePointFlow3ConfirmRestore.svelte +118 -0
  81. package/dist/components/onboarding/restore-point-flow/RestorePointFlow3ConfirmRestore.svelte.d.ts +10 -0
  82. package/dist/components/onboarding/restore-point-flow/RestorePointFlow4Restore.svelte +59 -0
  83. package/dist/components/onboarding/restore-point-flow/RestorePointFlow4Restore.svelte.d.ts +8 -0
  84. package/dist/components/onboarding/stages/OnboardingStageBackupServices.svelte +82 -0
  85. package/dist/components/onboarding/stages/OnboardingStageBackupServices.svelte.d.ts +8 -0
  86. package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte +56 -0
  87. package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte.d.ts +9 -0
  88. package/dist/components/onboarding/stages/OnboardingStageKeyImport.svelte +57 -0
  89. package/dist/components/onboarding/stages/OnboardingStageKeyImport.svelte.d.ts +8 -0
  90. package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte +50 -0
  91. package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte.d.ts +7 -0
  92. package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte +44 -0
  93. package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte.d.ts +8 -0
  94. package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte +56 -0
  95. package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte.d.ts +9 -0
  96. package/dist/components/onboarding/stages/SampleCreateFirstBackup.svelte +43 -0
  97. package/dist/components/onboarding/stages/SampleCreateFirstBackup.svelte.d.ts +7 -0
  98. package/dist/components/onboarding/stages/SampleCreateFirstSchedule.svelte +49 -0
  99. package/dist/components/onboarding/stages/SampleCreateFirstSchedule.svelte.d.ts +7 -0
  100. package/dist/components/schedules/RepositoryPicker.svelte +105 -0
  101. package/dist/components/schedules/RepositoryPicker.svelte.d.ts +6 -0
  102. package/dist/components/schedules/ScheduleItem.svelte +47 -0
  103. package/dist/components/schedules/ScheduleItem.svelte.d.ts +8 -0
  104. package/dist/components/schedules/ScheduleList.svelte +51 -0
  105. package/dist/components/schedules/ScheduleList.svelte.d.ts +3 -0
  106. package/dist/components/schedules/dialogs/ConfigureScheduleModal.svelte +48 -0
  107. package/dist/components/schedules/dialogs/ConfigureScheduleModal.svelte.d.ts +8 -0
  108. package/dist/components/schedules/dialogs/CreateScheduleModal.svelte +43 -0
  109. package/dist/components/schedules/dialogs/CreateScheduleModal.svelte.d.ts +6 -0
  110. package/dist/components/test/ImmichTestUi.svelte +183 -0
  111. package/dist/components/test/ImmichTestUi.svelte.d.ts +6 -0
  112. package/dist/components/test/TestUi.svelte +134 -0
  113. package/dist/components/test/TestUi.svelte.d.ts +6 -0
  114. package/dist/components/test/dashboard/ActiveJobs.svelte +380 -0
  115. package/dist/components/test/dashboard/ActiveJobs.svelte.d.ts +3 -0
  116. package/dist/components/test/dashboard/BackupHealth.svelte +95 -0
  117. package/dist/components/test/dashboard/BackupHealth.svelte.d.ts +7 -0
  118. package/dist/components/test/dashboard/BackupStats.svelte +117 -0
  119. package/dist/components/test/dashboard/BackupStats.svelte.d.ts +8 -0
  120. package/dist/components/test/dashboard/Dashboard.svelte +76 -0
  121. package/dist/components/test/dashboard/Dashboard.svelte.d.ts +6 -0
  122. package/dist/components/test/dashboard/RecentBackups.svelte +96 -0
  123. package/dist/components/test/dashboard/RecentBackups.svelte.d.ts +8 -0
  124. package/dist/components/ui/PageLayout.svelte +67 -0
  125. package/dist/components/ui/PageLayout.svelte.d.ts +10 -0
  126. package/dist/components/ui/PathListField.svelte +83 -0
  127. package/dist/components/ui/PathListField.svelte.d.ts +17 -0
  128. package/dist/components/ui/PathPickerField.svelte +74 -0
  129. package/dist/components/ui/PathPickerField.svelte.d.ts +15 -0
  130. package/dist/components/ui/PathPickerModal.svelte +219 -0
  131. package/dist/components/ui/PathPickerModal.svelte.d.ts +14 -0
  132. package/dist/components/ui/StackList.svelte +30 -0
  133. package/dist/components/ui/StackList.svelte.d.ts +30 -0
  134. package/dist/components/ui/StackListItem.svelte +64 -0
  135. package/dist/components/ui/StackListItem.svelte.d.ts +13 -0
  136. package/dist/components/ui/VisualisationGauge.svelte +25 -0
  137. package/dist/components/ui/VisualisationGauge.svelte.d.ts +10 -0
  138. package/dist/components/ui/VisualisationSegmentedBar.svelte +48 -0
  139. package/dist/components/ui/VisualisationSegmentedBar.svelte.d.ts +14 -0
  140. package/dist/components/util/OnEvents.svelte +31 -0
  141. package/dist/components/util/OnEvents.svelte.d.ts +7 -0
  142. package/dist/components/util/RelativeTime.svelte +21 -0
  143. package/dist/components/util/RelativeTime.svelte.d.ts +6 -0
  144. package/dist/components/util/Suspense.svelte +21 -0
  145. package/dist/components/util/Suspense.svelte.d.ts +29 -0
  146. package/dist/components/util/TimedButton.svelte +37 -0
  147. package/dist/components/util/TimedButton.svelte.d.ts +7 -0
  148. package/dist/components/util/YuccaContext.svelte +26 -0
  149. package/dist/components/util/YuccaContext.svelte.d.ts +8 -0
  150. package/dist/events.d.ts +6 -0
  151. package/dist/events.js +47 -0
  152. package/dist/fetch-client.d.ts +289 -0
  153. package/dist/fetch-client.js +233 -0
  154. package/dist/index.d.ts +28 -0
  155. package/dist/index.js +28 -0
  156. package/dist/options.d.ts +5 -0
  157. package/dist/options.js +6 -0
  158. package/dist/providers.d.ts +11 -0
  159. package/dist/providers.js +35 -0
  160. package/dist/query-client.d.ts +2 -0
  161. package/dist/query-client.js +2 -0
  162. package/dist/services/backend.service.d.ts +18 -0
  163. package/dist/services/backend.service.js +61 -0
  164. package/dist/services/filesystem.service.d.ts +2 -0
  165. package/dist/services/filesystem.service.js +11 -0
  166. package/dist/services/immich.integration.service.d.ts +6 -0
  167. package/dist/services/immich.integration.service.js +24 -0
  168. package/dist/services/integrations.service.d.ts +13 -0
  169. package/dist/services/integrations.service.js +42 -0
  170. package/dist/services/log.service.svelte.d.ts +53 -0
  171. package/dist/services/log.service.svelte.js +93 -0
  172. package/dist/services/metricsHistory.service.d.ts +4 -0
  173. package/dist/services/metricsHistory.service.js +12 -0
  174. package/dist/services/onboarding.service.d.ts +11 -0
  175. package/dist/services/onboarding.service.js +56 -0
  176. package/dist/services/repository.service.d.ts +45 -0
  177. package/dist/services/repository.service.js +157 -0
  178. package/dist/services/runHistory.service.d.ts +26 -0
  179. package/dist/services/runHistory.service.js +54 -0
  180. package/dist/services/schedule.service.d.ts +35 -0
  181. package/dist/services/schedule.service.js +126 -0
  182. package/dist/services/snapshot.service.d.ts +29 -0
  183. package/dist/services/snapshot.service.js +108 -0
  184. package/dist/services/task.service.d.ts +3 -0
  185. package/dist/services/task.service.js +20 -0
  186. package/dist/utils/actions.d.ts +2 -0
  187. package/dist/utils/actions.js +3 -0
  188. package/dist/utils/format.d.ts +2 -0
  189. package/dist/utils/format.js +24 -0
  190. package/dist/utils/handle-error.d.ts +9 -0
  191. package/dist/utils/handle-error.js +42 -0
  192. package/package.json +79 -0
@@ -0,0 +1,83 @@
1
+ <script lang="ts">
2
+ import StackList from "../../ui/StackList.svelte";
3
+ import RelativeTime from "../../util/RelativeTime.svelte";
4
+ import type {
5
+ InspectedLocalRepositoryDto,
6
+ SnapshotDto,
7
+ } from "../../../fetch-client";
8
+ import { humanizeBackupPath } from "../../../utils/format";
9
+ import {
10
+ Button,
11
+ FormatBytes,
12
+ HStack,
13
+ Modal,
14
+ ModalBody,
15
+ ModalFooter,
16
+ Stack,
17
+ Text,
18
+ } from "@immich/ui";
19
+ import RestorePointFlow3ConfirmRestore from "./RestorePointFlow3ConfirmRestore.svelte";
20
+
21
+ type Props = {
22
+ onBack: () => void;
23
+ onFinish: () => void;
24
+
25
+ repository: InspectedLocalRepositoryDto;
26
+ };
27
+
28
+ const { onBack, onFinish, repository }: Props = $props();
29
+
30
+ let selectedSnapshot: SnapshotDto | undefined = $state();
31
+ </script>
32
+
33
+ {#if selectedSnapshot}
34
+ <RestorePointFlow3ConfirmRestore
35
+ onBack={() => (selectedSnapshot = undefined)}
36
+ {onFinish}
37
+ {repository}
38
+ snapshot={selectedSnapshot}
39
+ />
40
+ {:else}
41
+ <Modal
42
+ title={`Restore from ${repository.name}`}
43
+ size="medium"
44
+ onClose={onBack}
45
+ >
46
+ <ModalBody>
47
+ <StackList>
48
+ {#each repository.snapshots.toSorted((a, b) => new Date(b.time).getTime() - new Date(a.time).getTime()) as snapshot (snapshot.id)}
49
+ <HStack gap={2} class="px-4 py-3">
50
+ <Stack gap={0} class="grow min-w-0">
51
+ <HStack
52
+ ><RelativeTime time={snapshot.time} />
53
+ {#if snapshot.summary}
54
+ <Text size="small" color="secondary">
55
+ &middot; <FormatBytes bytes={snapshot.summary.totalBytes} />
56
+ </Text>
57
+ {/if}</HStack
58
+ >
59
+ <Text size="small" color="muted"
60
+ >{[...new Set(snapshot.paths.map(humanizeBackupPath))].join(
61
+ ", ",
62
+ )}</Text
63
+ >
64
+ </Stack>
65
+ <Button onclick={() => (selectedSnapshot = snapshot)}>
66
+ Restore
67
+ </Button>
68
+ </HStack>
69
+ {/each}
70
+ {#if repository.snapshots.length === 0}
71
+ <Text class="text-center py-6" color="muted">
72
+ No snapshots in this repository.
73
+ </Text>
74
+ {/if}
75
+ </StackList>
76
+ </ModalBody>
77
+ <ModalFooter>
78
+ <HStack>
79
+ <Button variant="ghost" onclick={onBack}>Back</Button>
80
+ </HStack>
81
+ </ModalFooter>
82
+ </Modal>
83
+ {/if}
@@ -0,0 +1,9 @@
1
+ import type { InspectedLocalRepositoryDto } from "../../../fetch-client";
2
+ type Props = {
3
+ onBack: () => void;
4
+ onFinish: () => void;
5
+ repository: InspectedLocalRepositoryDto;
6
+ };
7
+ declare const RestorePointFlow2SelectSnapshot: import("svelte").Component<Props, {}, "">;
8
+ type RestorePointFlow2SelectSnapshot = ReturnType<typeof RestorePointFlow2SelectSnapshot>;
9
+ export default RestorePointFlow2SelectSnapshot;
@@ -0,0 +1,118 @@
1
+ <script lang="ts">
2
+ import type {
3
+ InspectedLocalRepositoryDto,
4
+ SnapshotDto,
5
+ } from "../../../fetch-client";
6
+ import { handleRestoreFromPoint } from "../../../services/snapshot.service";
7
+ import {
8
+ Button,
9
+ Checkbox,
10
+ HStack,
11
+ Modal,
12
+ ModalBody,
13
+ ModalFooter,
14
+ Select,
15
+ Stack,
16
+ Text,
17
+ } from "@immich/ui";
18
+ import { SvelteSet } from "svelte/reactivity";
19
+ import RestorePointFlow4Restore from "./RestorePointFlow4Restore.svelte";
20
+
21
+ type Props = {
22
+ onBack: () => void;
23
+ onFinish: () => void;
24
+
25
+ repository: InspectedLocalRepositoryDto;
26
+ snapshot: SnapshotDto;
27
+ };
28
+
29
+ const { onBack, onFinish, repository, snapshot }: Props = $props();
30
+
31
+ const yuccaConfigOptions = $derived(
32
+ snapshot.paths
33
+ .filter((path) => path.includes("yucca"))
34
+ .map((value) => ({
35
+ value,
36
+ label: value,
37
+ })),
38
+ );
39
+
40
+ // svelte-ignore state_referenced_locally
41
+ let yuccaConfig: string | undefined = $state(
42
+ snapshot.paths.find((path) => path.includes("yucca")),
43
+ );
44
+
45
+ // svelte-ignore state_referenced_locally
46
+ let includePaths = new SvelteSet<string>(
47
+ snapshot.paths.filter((path) => !path.includes("yucca")),
48
+ );
49
+
50
+ let logId: string | undefined = $state();
51
+
52
+ async function handleRestore() {
53
+ ({ logId } = await handleRestoreFromPoint(
54
+ repository.id,
55
+ snapshot.id,
56
+ repository.backends!.primary.id,
57
+ {
58
+ yuccaConfig,
59
+ include: [...includePaths].filter((path) => path !== yuccaConfig),
60
+ },
61
+ ));
62
+ }
63
+ </script>
64
+
65
+ {#if logId}
66
+ <RestorePointFlow4Restore {onFinish} {logId} taskId={repository.id} />
67
+ {:else}
68
+ <Modal title="Confirm restore from snapshot" size="small" onClose={onBack}>
69
+ <ModalBody>
70
+ <Stack>
71
+ <Stack gap={2}>
72
+ <Text fontWeight="bold">Restore configuration</Text>
73
+ <HStack>
74
+ <Select
75
+ options={yuccaConfigOptions}
76
+ bind:value={yuccaConfig}
77
+ placeholder="Not restoring backup configuration"
78
+ class="flex-1"
79
+ />
80
+ {#if yuccaConfig}
81
+ <Button variant="ghost" onclick={() => (yuccaConfig = undefined)}>
82
+ Clear
83
+ </Button>
84
+ {/if}
85
+ </HStack>
86
+ </Stack>
87
+
88
+ <Stack gap={2}>
89
+ <Text fontWeight="bold">Backup includes</Text>
90
+ {#each snapshot.paths as path}
91
+ {@const forced = path === yuccaConfig}
92
+ <label class="select-none flex gap-2 items-center">
93
+ <Checkbox
94
+ checked={forced || includePaths.has(path)}
95
+ disabled={forced}
96
+ onCheckedChange={() =>
97
+ includePaths.has(path)
98
+ ? includePaths.delete(path)
99
+ : includePaths.add(path)}
100
+ />
101
+ {path}
102
+ </label>
103
+ {/each}
104
+ </Stack>
105
+
106
+ <Text size="small" color="muted">
107
+ Files will be restored to their exact paths.
108
+ </Text>
109
+ </Stack>
110
+ </ModalBody>
111
+ <ModalFooter>
112
+ <HStack>
113
+ <Button variant="ghost" onclick={onBack}>Back</Button>
114
+ <Button onclick={handleRestore}>Restore</Button>
115
+ </HStack>
116
+ </ModalFooter>
117
+ </Modal>
118
+ {/if}
@@ -0,0 +1,10 @@
1
+ import type { InspectedLocalRepositoryDto, SnapshotDto } from "../../../fetch-client";
2
+ type Props = {
3
+ onBack: () => void;
4
+ onFinish: () => void;
5
+ repository: InspectedLocalRepositoryDto;
6
+ snapshot: SnapshotDto;
7
+ };
8
+ declare const RestorePointFlow3ConfirmRestore: import("svelte").Component<Props, {}, "">;
9
+ type RestorePointFlow3ConfirmRestore = ReturnType<typeof RestorePointFlow3ConfirmRestore>;
10
+ export default RestorePointFlow3ConfirmRestore;
@@ -0,0 +1,59 @@
1
+ <script lang="ts">
2
+ import OnEvents from "../../util/OnEvents.svelte";
3
+ import type { SocketEvent } from "../../../events";
4
+ import { createLogObserver } from "../../../services/log.service.svelte";
5
+ import { Alert, Modal, ModalBody, ProgressBar, Stack, Text } from "@immich/ui";
6
+ import { onDestroy } from "svelte";
7
+
8
+ type Props = {
9
+ onFinish: () => void;
10
+
11
+ taskId: string;
12
+ logId: string;
13
+ };
14
+
15
+ const { onFinish, taskId, logId }: Props = $props();
16
+
17
+ // svelte-ignore state_referenced_locally
18
+ const log = createLogObserver(logId);
19
+ onDestroy(() => log.destroy());
20
+
21
+ const onTaskEnd = (event: SocketEvent<{ parentId: string }>) => {
22
+ if (event.data.parentId === taskId && log.errors.length === 0) {
23
+ onFinish();
24
+ }
25
+ };
26
+ </script>
27
+
28
+ <OnEvents {onTaskEnd} />
29
+
30
+ <Modal
31
+ title={log.errors.length > 0 ? "Restore failed" : "Restoring"}
32
+ size="small"
33
+ onClose={log.errors.length > 0 ? onFinish : undefined}
34
+ >
35
+ <ModalBody>
36
+ <Stack gap={2}>
37
+ {#each log.errors as error}
38
+ <Alert color="danger">{error}</Alert>
39
+ {/each}
40
+
41
+ <ProgressBar progress={log.status.progress} size="large">
42
+ <Text
43
+ size="small"
44
+ class={log.status.progress > 0.5 ? "text-light" : "text-dark"}
45
+ >
46
+ {log.status.text}
47
+ </Text>
48
+ </ProgressBar>
49
+
50
+ {#if log.status.currentFiles.length > 0}
51
+ <Stack gap={1}>
52
+ {#each log.status.currentFiles as file}
53
+ <Text size="tiny" class="text-nowrap">{file}</Text>
54
+ {/each}
55
+ </Stack>
56
+ {/if}
57
+ </Stack>
58
+ </ModalBody>
59
+ </Modal>
@@ -0,0 +1,8 @@
1
+ type Props = {
2
+ onFinish: () => void;
3
+ taskId: string;
4
+ logId: string;
5
+ };
6
+ declare const RestorePointFlow4Restore: import("svelte").Component<Props, {}, "">;
7
+ type RestorePointFlow4Restore = ReturnType<typeof RestorePointFlow4Restore>;
8
+ export default RestorePointFlow4Restore;
@@ -0,0 +1,82 @@
1
+ <script lang="ts">
2
+ import StackList from "../../ui/StackList.svelte";
3
+ import StackListItem from "../../ui/StackListItem.svelte";
4
+ import {
5
+ handleSetupLocalStorage,
6
+ handleYuccaLogin,
7
+ } from "../../../services/backend.service";
8
+ import {
9
+ Button,
10
+ HStack,
11
+ Icon,
12
+ Modal,
13
+ ModalBody,
14
+ ModalFooter,
15
+ Stack,
16
+ Text,
17
+ } from "@immich/ui";
18
+ import { mdiChevronRight, mdiHarddisk, mdiShieldCheck } from "@mdi/js";
19
+
20
+ type Props = {
21
+ restore?: boolean;
22
+ onNext: (backendId: string) => void;
23
+ onCancel: () => void;
24
+ };
25
+
26
+ const { restore = false, onNext, onCancel }: Props = $props();
27
+
28
+ function onFutoBackups() {
29
+ handleYuccaLogin(onNext);
30
+ }
31
+
32
+ function onLocalBackups() {
33
+ handleSetupLocalStorage(onNext);
34
+ }
35
+
36
+ // TODO: show existing backends if any configured!
37
+ </script>
38
+
39
+ <Modal
40
+ size="small"
41
+ title={restore ? "Where would you like to restore from?" : "Backup options"}
42
+ onClose={onCancel}
43
+ icon={false}
44
+ >
45
+ <ModalBody>
46
+ <StackList>
47
+ <StackListItem onclick={onFutoBackups}>
48
+ {#snippet icon()}
49
+ <Icon icon={mdiShieldCheck} size="36px" />
50
+ {/snippet}
51
+
52
+ <Stack gap={0}>
53
+ <Text class="font-bold">FUTO Backups</Text>
54
+ <Text>Simple, hosted backups.</Text>
55
+ </Stack>
56
+
57
+ {#snippet trailing()}
58
+ <Icon icon={mdiChevronRight} />
59
+ {/snippet}
60
+ </StackListItem>
61
+ <StackListItem onclick={onLocalBackups}>
62
+ {#snippet icon()}
63
+ <Icon icon={mdiHarddisk} size="36px" />
64
+ {/snippet}
65
+
66
+ <Stack gap={0}>
67
+ <Text class="font-bold">Local Storage</Text>
68
+ <Text>A folder on this computer.</Text>
69
+ </Stack>
70
+
71
+ {#snippet trailing()}
72
+ <Icon icon={mdiChevronRight} />
73
+ {/snippet}
74
+ </StackListItem>
75
+ </StackList>
76
+ </ModalBody>
77
+ <ModalFooter>
78
+ <HStack>
79
+ <Button variant="ghost" onclick={onCancel}>Cancel</Button>
80
+ </HStack>
81
+ </ModalFooter>
82
+ </Modal>
@@ -0,0 +1,8 @@
1
+ type Props = {
2
+ restore?: boolean;
3
+ onNext: (backendId: string) => void;
4
+ onCancel: () => void;
5
+ };
6
+ declare const OnboardingStageBackupServices: import("svelte").Component<Props, {}, "">;
7
+ type OnboardingStageBackupServices = ReturnType<typeof OnboardingStageBackupServices>;
8
+ export default OnboardingStageBackupServices;
@@ -0,0 +1,56 @@
1
+ <script lang="ts">
2
+ import {
3
+ Button,
4
+ Field,
5
+ HStack,
6
+ Input,
7
+ Modal,
8
+ ModalBody,
9
+ ModalFooter,
10
+ Stack,
11
+ Text,
12
+ } from "@immich/ui";
13
+
14
+ type Props = {
15
+ code: string;
16
+
17
+ onConfirmKey: () => Promise<void>;
18
+ onBack: () => void;
19
+ onCancel: () => void;
20
+ };
21
+
22
+ const { code, onConfirmKey, onBack, onCancel }: Props = $props();
23
+
24
+ let value = $state("");
25
+
26
+ const strip = (key: string) => {
27
+ return key.replace(/\s/g, "").toLowerCase().trim();
28
+ };
29
+ </script>
30
+
31
+ <Modal
32
+ size="small"
33
+ title="Confirm recovery key"
34
+ onClose={onCancel}
35
+ icon={false}
36
+ >
37
+ <ModalBody>
38
+ <Stack>
39
+ <Text size="small" class="text-muted text-left"
40
+ >Ensure you've saved the key properly.</Text
41
+ >
42
+
43
+ <Field label="Recovery Key">
44
+ <Input bind:value />
45
+ </Field>
46
+ </Stack>
47
+ </ModalBody>
48
+ <ModalFooter>
49
+ <HStack>
50
+ <Button disabled={strip(code) !== strip(value)} onclick={onConfirmKey}
51
+ >Confirm</Button
52
+ >
53
+ <Button variant="ghost" onclick={onBack}>See the key again</Button>
54
+ </HStack>
55
+ </ModalFooter>
56
+ </Modal>
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ code: string;
3
+ onConfirmKey: () => Promise<void>;
4
+ onBack: () => void;
5
+ onCancel: () => void;
6
+ };
7
+ declare const OnboardingStageKeyConfirm: import("svelte").Component<Props, {}, "">;
8
+ type OnboardingStageKeyConfirm = ReturnType<typeof OnboardingStageKeyConfirm>;
9
+ export default OnboardingStageKeyConfirm;
@@ -0,0 +1,57 @@
1
+ <script lang="ts">
2
+ import { handleImportRecoveryKey } from "../../../services/onboarding.service";
3
+ import {
4
+ Button,
5
+ Field,
6
+ HStack,
7
+ Input,
8
+ Modal,
9
+ ModalBody,
10
+ ModalFooter,
11
+ VStack,
12
+ } from "@immich/ui";
13
+
14
+ type Props = {
15
+ onImported: (key: string) => void;
16
+ onStart?: () => void;
17
+ onCancel: () => void;
18
+ };
19
+
20
+ const { onImported, onStart, onCancel }: Props = $props();
21
+
22
+ let value = $state("");
23
+
24
+ const strip = (key: string) => {
25
+ return key.replace(/\s/g, "").toLowerCase().trim();
26
+ };
27
+
28
+ const isValidValue = () => /^[a-f0-9]{64}$/.test(strip(value));
29
+
30
+ const onSave = async () => {
31
+ const recoveryKey = strip(value);
32
+
33
+ await handleImportRecoveryKey({ recoveryKey });
34
+
35
+ onImported(recoveryKey);
36
+ };
37
+ </script>
38
+
39
+ <Modal size="small" title="Import recovery key" onClose={onCancel}>
40
+ <ModalBody>
41
+ <VStack>
42
+ <Field label="Recovery Key">
43
+ <Input bind:value />
44
+ </Field>
45
+ </VStack>
46
+ </ModalBody>
47
+ <ModalFooter>
48
+ <HStack>
49
+ <Button disabled={!isValidValue()} onclick={onSave}>Save</Button>
50
+ {#if onStart}
51
+ <Button variant="ghost" onclick={onStart}>Back</Button>
52
+ {:else}
53
+ <Button variant="ghost" onclick={onCancel}>Cancel</Button>
54
+ {/if}
55
+ </HStack>
56
+ </ModalFooter>
57
+ </Modal>
@@ -0,0 +1,8 @@
1
+ type Props = {
2
+ onImported: (key: string) => void;
3
+ onStart?: () => void;
4
+ onCancel: () => void;
5
+ };
6
+ declare const OnboardingStageKeyImport: import("svelte").Component<Props, {}, "">;
7
+ type OnboardingStageKeyImport = ReturnType<typeof OnboardingStageKeyImport>;
8
+ export default OnboardingStageKeyImport;
@@ -0,0 +1,50 @@
1
+ <script lang="ts">
2
+ import TimedButton from "../../util/TimedButton.svelte";
3
+ import {
4
+ Button,
5
+ HStack,
6
+ Icon,
7
+ Modal,
8
+ ModalBody,
9
+ ModalFooter,
10
+ Stack,
11
+ Text,
12
+ } from "@immich/ui";
13
+ import { mdiKey, mdiSecurity } from "@mdi/js";
14
+
15
+ type Props = {
16
+ onNext: () => void;
17
+ onCancel: () => void;
18
+ };
19
+
20
+ const { onNext, onCancel }: Props = $props();
21
+ </script>
22
+
23
+ <Modal
24
+ size="small"
25
+ title="Keeping your photos private"
26
+ onClose={onCancel}
27
+ icon={false}
28
+ >
29
+ <ModalBody>
30
+ <Stack>
31
+ <HStack>
32
+ <Icon icon={mdiKey} class="shrink-0 place-self-start mt-1" />
33
+ <Text
34
+ >You are about to be given a code which you need to put in a safe
35
+ place.</Text
36
+ >
37
+ </HStack>
38
+ <HStack>
39
+ <Icon icon={mdiSecurity} class="shrink-0 place-self-start mt-1" />
40
+ <Text>If you lose the key, your backup is gone.</Text>
41
+ </HStack>
42
+ </Stack>
43
+ </ModalBody>
44
+ <ModalFooter>
45
+ <HStack>
46
+ <TimedButton text="Next" onclick={onNext} />
47
+ <Button variant="ghost" onclick={onCancel}>Cancel</Button>
48
+ </HStack>
49
+ </ModalFooter>
50
+ </Modal>
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ onNext: () => void;
3
+ onCancel: () => void;
4
+ };
5
+ declare const OnboardingStageKeyIntro: import("svelte").Component<Props, {}, "">;
6
+ type OnboardingStageKeyIntro = ReturnType<typeof OnboardingStageKeyIntro>;
7
+ export default OnboardingStageKeyIntro;
@@ -0,0 +1,44 @@
1
+ <script lang="ts">
2
+ import {
3
+ Button,
4
+ HStack,
5
+ LoadingSpinner,
6
+ Modal,
7
+ ModalBody,
8
+ ModalFooter,
9
+ Stack,
10
+ Text,
11
+ } from "@immich/ui";
12
+ import RecoveryKeyDisplay from "../RecoveryKeyDisplay.svelte";
13
+
14
+ type Props = {
15
+ code: string;
16
+
17
+ onNext: () => void;
18
+ onCancel: () => void;
19
+ };
20
+
21
+ const { code, onNext, onCancel }: Props = $props();
22
+ </script>
23
+
24
+ <Modal size="small" title="Your recovery key" onClose={onCancel} icon={false}>
25
+ <ModalBody>
26
+ <Stack gap={4}>
27
+ <Text size="small" class="text-muted text-left">
28
+ Save this key somewhere safe, it will be used to restore your backups.
29
+ </Text>
30
+
31
+ {#if code}
32
+ <RecoveryKeyDisplay {code} />
33
+ {:else}
34
+ <LoadingSpinner />
35
+ {/if}
36
+ </Stack>
37
+ </ModalBody>
38
+ <ModalFooter>
39
+ <HStack>
40
+ <Button onclick={onNext}>Next</Button>
41
+ <Button variant="ghost" onclick={onCancel}>Cancel</Button>
42
+ </HStack>
43
+ </ModalFooter>
44
+ </Modal>
@@ -0,0 +1,8 @@
1
+ type Props = {
2
+ code: string;
3
+ onNext: () => void;
4
+ onCancel: () => void;
5
+ };
6
+ declare const OnboardingStageKeySave: import("svelte").Component<Props, {}, "">;
7
+ type OnboardingStageKeySave = ReturnType<typeof OnboardingStageKeySave>;
8
+ export default OnboardingStageKeySave;
@@ -0,0 +1,56 @@
1
+ <script lang="ts">
2
+ import {
3
+ Button,
4
+ HStack,
5
+ Icon,
6
+ Modal,
7
+ ModalBody,
8
+ ModalFooter,
9
+ Stack,
10
+ Text,
11
+ } from "@immich/ui";
12
+ import { mdiImageAlbum, mdiInformation, mdiLock } from "@mdi/js";
13
+
14
+ type Props = {
15
+ onNext: () => void;
16
+ onImportKey: () => void;
17
+ onCancel: () => void;
18
+ icon?: boolean;
19
+ };
20
+
21
+ const { onNext, onImportKey, onCancel, icon = true }: Props = $props();
22
+ </script>
23
+
24
+ <Modal size="small" title="Welcome to FUTO Backups" onClose={onCancel} {icon}>
25
+ <ModalBody>
26
+ <Stack>
27
+ <HStack>
28
+ <Icon icon={mdiImageAlbum} class="shrink-0 place-self-start mt-1" />
29
+ <Text>
30
+ Keep your most precious memories safe and away from prying eyes.</Text
31
+ >
32
+ </HStack>
33
+ <HStack>
34
+ <Icon icon={mdiLock} class="shrink-0 place-self-start mt-1" />
35
+ <Text>
36
+ You will be guided through setting up a secure way to keep your photos
37
+ private.</Text
38
+ >
39
+ </HStack>
40
+ <HStack>
41
+ <Icon icon={mdiInformation} class="shrink-0 place-self-start mt-1" />
42
+ <Text>
43
+ You'll be able to choose to use our backups service or your own
44
+ storage.</Text
45
+ >
46
+ </HStack>
47
+ </Stack>
48
+ </ModalBody>
49
+ <ModalFooter>
50
+ <HStack>
51
+ <Button onclick={onNext}>Next</Button>
52
+ <Button variant="ghost" onclick={onImportKey}>Import Key</Button>
53
+ <Button variant="ghost" onclick={onCancel}>Cancel</Button>
54
+ </HStack>
55
+ </ModalFooter>
56
+ </Modal>