@futo-org/backups-orchestrator-ui 0.44.0 → 0.46.0

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 (43) hide show
  1. package/dist/components/backups/BackupStatus.svelte +14 -3
  2. package/dist/components/backups/BackupStatus.svelte.d.ts +1 -1
  3. package/dist/components/backups/dialogs/ViewStatusModal.svelte +6 -0
  4. package/dist/components/backups/metrics-history/MetricsHistoryModal.svelte +8 -0
  5. package/dist/components/backups/run-history/RepositoryRunHistoryItem.svelte +10 -3
  6. package/dist/components/dashboard/{Dashboard.svelte.d.ts → DashboardPage.svelte.d.ts} +3 -3
  7. package/dist/components/integrations/immich/ImmichBackupAttemptsPage.svelte +19 -0
  8. package/dist/components/integrations/immich/ImmichBackupAttemptsPage.svelte.d.ts +6 -0
  9. package/dist/components/integrations/immich/ImmichBackupSettingsPage.svelte +25 -0
  10. package/dist/components/integrations/immich/ImmichBackupSettingsPage.svelte.d.ts +6 -0
  11. package/dist/components/integrations/immich/ImmichBackupsPage.svelte +13 -3
  12. package/dist/components/integrations/immich/ImmichBackupsPage.svelte.d.ts +3 -0
  13. package/dist/components/integrations/immich/ImmichBackupsSidebarItem.svelte +12 -2
  14. package/dist/components/integrations/immich/ImmichConfiguredGate.svelte +32 -0
  15. package/dist/components/integrations/immich/ImmichConfiguredGate.svelte.d.ts +9 -0
  16. package/dist/components/integrations/immich/ImmichDatabaseDumpAlert.svelte +42 -0
  17. package/dist/components/integrations/immich/{ImmichBackupSettings.svelte.d.ts → ImmichDatabaseDumpAlert.svelte.d.ts} +3 -3
  18. package/dist/components/integrations/immich/ImmichManageBackupOverview.svelte +28 -10
  19. package/dist/components/integrations/immich/ImmichManageBackupPage.svelte +52 -0
  20. package/dist/components/integrations/immich/ImmichManageBackupPage.svelte.d.ts +8 -0
  21. package/dist/components/integrations/immich/ImmichSnapshotsPage.svelte +19 -0
  22. package/dist/components/integrations/immich/ImmichSnapshotsPage.svelte.d.ts +6 -0
  23. package/dist/components/integrations/immich/settings/ImmichSettingsBandwidth.svelte +150 -0
  24. package/dist/components/integrations/immich/settings/ImmichSettingsBandwidth.svelte.d.ts +3 -0
  25. package/dist/components/test/ImmichTestUi.svelte +30 -3
  26. package/dist/components/test/TestUi.svelte +2 -2
  27. package/dist/fetch-client.d.ts +28 -3
  28. package/dist/fetch-client.js +30 -0
  29. package/dist/index.d.ts +5 -2
  30. package/dist/index.js +5 -2
  31. package/dist/services/config.service.d.ts +6 -0
  32. package/dist/services/config.service.js +16 -0
  33. package/dist/services/immich.integration.service.d.ts +5 -1
  34. package/dist/services/immich.integration.service.js +27 -2
  35. package/dist/services/runHistory.service.d.ts +1 -0
  36. package/dist/services/runHistory.service.js +6 -1
  37. package/dist/utils/backup-status.d.ts +1 -1
  38. package/dist/utils/backup-status.js +3 -0
  39. package/package.json +2 -2
  40. package/dist/components/integrations/immich/ImmichBackupSettings.svelte +0 -12
  41. package/dist/components/integrations/immich/ImmichManageBackup.svelte +0 -76
  42. package/dist/components/integrations/immich/ImmichManageBackup.svelte.d.ts +0 -3
  43. /package/dist/components/dashboard/{Dashboard.svelte → DashboardPage.svelte} +0 -0
@@ -6,7 +6,8 @@
6
6
  | "running"
7
7
  | "complete"
8
8
  | "warned"
9
- | "failed";
9
+ | "failed"
10
+ | "cancelled";
10
11
  </script>
11
12
 
12
13
  <script lang="ts">
@@ -75,6 +76,12 @@
75
76
  forget: "Old backups could not be pruned",
76
77
  };
77
78
 
79
+ const cancelled: Record<BackupStatusType, string> = {
80
+ backup: "Your backup was cancelled",
81
+ restore: "Your restore was cancelled",
82
+ forget: "Pruning old backups was cancelled",
83
+ };
84
+
78
85
  const reassurance: Record<BackupStatusType, string> = {
79
86
  backup: "No changes were made to your existing backups.",
80
87
  restore: "Your backups are untouched — nothing was lost.",
@@ -106,6 +113,9 @@
106
113
  case "failed": {
107
114
  return failed[type];
108
115
  }
116
+ case "cancelled": {
117
+ return cancelled[type];
118
+ }
109
119
  case "complete": {
110
120
  return succeeded[type];
111
121
  }
@@ -121,7 +131,7 @@
121
131
  const titleColor = $derived(
122
132
  backupState === "complete"
123
133
  ? "success"
124
- : backupState === "warned"
134
+ : backupState === "warned" || backupState === "cancelled"
125
135
  ? "warning"
126
136
  : backupState === "failed"
127
137
  ? "danger"
@@ -131,7 +141,8 @@
131
141
  const terminal = $derived(
132
142
  backupState === "complete" ||
133
143
  backupState === "warned" ||
134
- backupState === "failed",
144
+ backupState === "failed" ||
145
+ backupState === "cancelled",
135
146
  );
136
147
  </script>
137
148
 
@@ -1,5 +1,5 @@
1
1
  export type BackupStatusType = "backup" | "restore" | "forget";
2
- export type BackupStatusState = "connecting" | "running" | "complete" | "warned" | "failed";
2
+ export type BackupStatusState = "connecting" | "running" | "complete" | "warned" | "failed" | "cancelled";
3
3
  import type { Snippet } from "svelte";
4
4
  type Props = {
5
5
  title: string;
@@ -64,6 +64,9 @@
64
64
  case "failed": {
65
65
  return "failed";
66
66
  }
67
+ case "cancelled": {
68
+ return "cancelled";
69
+ }
67
70
  case "warn": {
68
71
  return "warned";
69
72
  }
@@ -109,6 +112,9 @@
109
112
  case "failed": {
110
113
  return `${titles[type].done} failed`;
111
114
  }
115
+ case "cancelled": {
116
+ return `${titles[type].done} cancelled`;
117
+ }
112
118
  default: {
113
119
  return titles[type].running;
114
120
  }
@@ -120,6 +120,14 @@
120
120
  />
121
121
  <Text>Backup finished</Text>
122
122
  <Badge size="tiny" color="danger">Failed</Badge>
123
+ {:else if status === 'cancelled'}
124
+ <Icon
125
+ icon={mdiAlertCircleOutline}
126
+ size="18"
127
+ class="text-warning-500"
128
+ />
129
+ <Text>Backup cancelled</Text>
130
+ <Badge size="tiny" color="warning">Cancelled</Badge>
123
131
  {:else if isEnd}
124
132
  <Icon
125
133
  icon={mdiAlertCircleOutline}
@@ -15,7 +15,7 @@
15
15
  };
16
16
 
17
17
  const { run }: Props = $props();
18
- const { ViewLog } = $derived(getRunActions(run));
18
+ const { ViewLog, DownloadLog } = $derived(getRunActions(run));
19
19
 
20
20
  const nouns = {
21
21
  restore: { name: "restore", running: "Restore", done: "Restored" },
@@ -38,6 +38,13 @@
38
38
  icon: mdiCloudOffOutline,
39
39
  } as const;
40
40
  }
41
+ case "cancelled": {
42
+ return {
43
+ title: `Cancelled ${noun.name}`,
44
+ color: "warning",
45
+ icon: mdiCloudOffOutline,
46
+ } as const;
47
+ }
41
48
  case "warn": {
42
49
  return {
43
50
  title: `${noun.done} with warnings`,
@@ -63,14 +70,14 @@
63
70
  });
64
71
  </script>
65
72
 
66
- <StackListItem title={status.title} color={status.color} actions={[ViewLog]}>
73
+ <StackListItem title={status.title} color={status.color} actions={[ViewLog, DownloadLog]}>
67
74
  {#snippet icon()}
68
75
  <Icon icon={status.icon} />
69
76
  {/snippet}
70
77
 
71
78
  {#if run.status === "incomplete"}
72
79
  Started <RelativeTime time={run.start} />
73
- {:else if run.status === "failed"}
80
+ {:else if run.status === "failed" || run.status === "cancelled"}
74
81
  Attempted {#if run.end}<RelativeTime time={run.end} />{/if}
75
82
  {:else}
76
83
  {noun.done} {#if run.end}<RelativeTime time={run.end} />{/if}
@@ -3,6 +3,6 @@ type Props = {
3
3
  initialData?: RepositoryListResponseDto;
4
4
  onViewBackups?: () => void;
5
5
  };
6
- declare const Dashboard: import("svelte").Component<Props, {}, "">;
7
- type Dashboard = ReturnType<typeof Dashboard>;
8
- export default Dashboard;
6
+ declare const DashboardPage: import("svelte").Component<Props, {}, "">;
7
+ type DashboardPage = ReturnType<typeof DashboardPage>;
8
+ export default DashboardPage;
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import RepositoryRunHistoryPage from "../../backups/run-history/RepositoryRunHistoryPage.svelte";
3
+ import { Container } from "@immich/ui";
4
+ import ImmichConfiguredGate from "./ImmichConfiguredGate.svelte";
5
+
6
+ type Props = {
7
+ onUnconfigured: () => void;
8
+ };
9
+
10
+ const { onUnconfigured }: Props = $props();
11
+ </script>
12
+
13
+ <ImmichConfiguredGate {onUnconfigured}>
14
+ {#snippet children(repository)}
15
+ <Container size="medium" center>
16
+ <RepositoryRunHistoryPage {repository} />
17
+ </Container>
18
+ {/snippet}
19
+ </ImmichConfiguredGate>
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ onUnconfigured: () => void;
3
+ };
4
+ declare const ImmichBackupAttemptsPage: import("svelte").Component<Props, {}, "">;
5
+ type ImmichBackupAttemptsPage = ReturnType<typeof ImmichBackupAttemptsPage>;
6
+ export default ImmichBackupAttemptsPage;
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import { Container } from "@immich/ui";
3
+ import ImmichConfiguredGate from "./ImmichConfiguredGate.svelte";
4
+ import ImmichSettingsBackupContents from "./settings/ImmichSettingsBackupContents.svelte";
5
+ import ImmichSettingsBandwidth from "./settings/ImmichSettingsBandwidth.svelte";
6
+ import ImmichSettingsSchedule from "./settings/ImmichSettingsSchedule.svelte";
7
+ import ImmichSettingsStorage from "./settings/ImmichSettingsStorage.svelte";
8
+
9
+ type Props = {
10
+ onUnconfigured: () => void;
11
+ };
12
+
13
+ const { onUnconfigured }: Props = $props();
14
+ </script>
15
+
16
+ <ImmichConfiguredGate {onUnconfigured}>
17
+ {#snippet children()}
18
+ <Container size="large" center>
19
+ <ImmichSettingsBackupContents />
20
+ <ImmichSettingsSchedule />
21
+ <ImmichSettingsBandwidth />
22
+ <ImmichSettingsStorage />
23
+ </Container>
24
+ {/snippet}
25
+ </ImmichConfiguredGate>
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ onUnconfigured: () => void;
3
+ };
4
+ declare const ImmichBackupSettingsPage: import("svelte").Component<Props, {}, "">;
5
+ type ImmichBackupSettingsPage = ReturnType<typeof ImmichBackupSettingsPage>;
6
+ export default ImmichBackupSettingsPage;
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from "svelte";
3
3
  import UpsellPage from "../../onboarding/upsell/UpsellPage.svelte";
4
- import ImmichManageBackup from "./ImmichManageBackup.svelte";
4
+ import ImmichManageBackupPage from "./ImmichManageBackupPage.svelte";
5
5
  import ImmichOnboardingSetupFlow from "./ImmichOnboardingSetupFlow.svelte";
6
6
 
7
7
  type Question = {
@@ -13,9 +13,19 @@
13
13
  price: string;
14
14
  includedStorage: string;
15
15
  questions: Question[];
16
+ onConfigure: () => void;
17
+ onViewAttempts: () => void;
18
+ onViewSnapshots: () => void;
16
19
  };
17
20
 
18
- const { price, includedStorage, questions }: Props = $props();
21
+ const {
22
+ price,
23
+ includedStorage,
24
+ questions,
25
+ onConfigure,
26
+ onViewAttempts,
27
+ onViewSnapshots,
28
+ }: Props = $props();
19
29
  </script>
20
30
 
21
31
  <ImmichOnboardingSetupFlow>
@@ -23,5 +33,5 @@
23
33
  <UpsellPage {price} {includedStorage} {questions} onGetStarted={onStart} />
24
34
  {/snippet}
25
35
 
26
- <ImmichManageBackup />
36
+ <ImmichManageBackupPage {onConfigure} {onViewAttempts} {onViewSnapshots} />
27
37
  </ImmichOnboardingSetupFlow>
@@ -7,6 +7,9 @@ type Props = {
7
7
  price: string;
8
8
  includedStorage: string;
9
9
  questions: Question[];
10
+ onConfigure: () => void;
11
+ onViewAttempts: () => void;
12
+ onViewSnapshots: () => void;
10
13
  };
11
14
  declare const ImmichBackupsPage: import("svelte").Component<Props, {}, "">;
12
15
  type ImmichBackupsPage = ReturnType<typeof ImmichBackupsPage>;
@@ -7,6 +7,7 @@
7
7
  } from "../../../services/immich.integration.service";
8
8
  import { HStack, Icon, LoadingSpinner, Text } from "@immich/ui";
9
9
  import {
10
+ mdiAlertCircleOutline,
10
11
  mdiChevronRight,
11
12
  mdiCloudAlertOutline,
12
13
  mdiCloudCheckVariantOutline,
@@ -29,6 +30,10 @@
29
30
  const configured = $derived(status.kind !== "unconfigured");
30
31
 
31
32
  const appearance = $derived.by(() => {
33
+ if (backup.needsAttention) {
34
+ return { color: "warning", icon: mdiAlertCircleOutline } as const;
35
+ }
36
+
32
37
  switch (status.kind) {
33
38
  case "loading": {
34
39
  return { color: "secondary", icon: undefined } as const;
@@ -44,7 +49,8 @@
44
49
  case "warn": {
45
50
  return { color: "warning", icon: mdiCloudCheckVariantOutline } as const;
46
51
  }
47
- case "incomplete": {
52
+ case "incomplete":
53
+ case "cancelled": {
48
54
  return { color: "warning", icon: mdiCloudAlertOutline } as const;
49
55
  }
50
56
  case "paused": {
@@ -84,7 +90,9 @@
84
90
  {/if}
85
91
 
86
92
  <Text size="tiny" class="flex-1 leading-tight">
87
- {#if status.kind === "loading"}
93
+ {#if backup.needsAttention}
94
+ Needs attention
95
+ {:else if status.kind === "loading"}
88
96
  Checking backup status
89
97
  {:else if status.kind === "offline"}
90
98
  Backup service is offline
@@ -98,6 +106,8 @@
98
106
  Backed up with warnings <RelativeTime time={status.lastBackup} />
99
107
  {:else if status.kind === "incomplete"}
100
108
  Backup did not complete <RelativeTime time={status.lastBackup} />
109
+ {:else if status.kind === "cancelled"}
110
+ Backup was cancelled <RelativeTime time={status.lastBackup} />
101
111
  {:else if status.kind === "paused"}
102
112
  Backups paused
103
113
  {:else if status.kind === "unconfigured"}
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import OnEvents from "../../util/OnEvents.svelte";
3
+ import type { LocalRepositoryDto } from "../../../fetch-client";
4
+ import {
5
+ useImmichBackupStatus,
6
+ useImmichBackupStatusEventHandler,
7
+ } from "../../../services/immich.integration.service";
8
+ import type { Snippet } from "svelte";
9
+
10
+ type Props = {
11
+ children: Snippet<[LocalRepositoryDto]>;
12
+ onUnconfigured: () => void;
13
+ };
14
+
15
+ const { children, onUnconfigured }: Props = $props();
16
+
17
+ const backup = useImmichBackupStatus();
18
+
19
+ const { repository, status } = $derived(backup);
20
+
21
+ $effect(() => {
22
+ if (status.kind === "unconfigured") {
23
+ onUnconfigured();
24
+ }
25
+ });
26
+ </script>
27
+
28
+ <OnEvents {...useImmichBackupStatusEventHandler()} />
29
+
30
+ {#if repository}
31
+ {@render children(repository)}
32
+ {/if}
@@ -0,0 +1,9 @@
1
+ import type { LocalRepositoryDto } from "../../../fetch-client";
2
+ import type { Snippet } from "svelte";
3
+ type Props = {
4
+ children: Snippet<[LocalRepositoryDto]>;
5
+ onUnconfigured: () => void;
6
+ };
7
+ declare const ImmichConfiguredGate: import("svelte").Component<Props, {}, "">;
8
+ type ImmichConfiguredGate = ReturnType<typeof ImmichConfiguredGate>;
9
+ export default ImmichConfiguredGate;
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ import {
3
+ useConfigureImmichDatabaseDump,
4
+ useIgnoreImmichDatabaseDumpWarning,
5
+ useImmichBackupStatus,
6
+ } from "../../../services/immich.integration.service";
7
+ import { Alert, Button, HStack, Stack, Text } from "@immich/ui";
8
+
9
+ const backup = useImmichBackupStatus();
10
+ const configure = useConfigureImmichDatabaseDump();
11
+ const ignore = useIgnoreImmichDatabaseDumpWarning();
12
+ </script>
13
+
14
+ {#if backup.needsAttention}
15
+ <Alert color="warning" title="Immich database backups are still enabled">
16
+ <Stack gap={3}>
17
+ <Text size="small">
18
+ FUTO Backups already creates the same database backups as Immich.
19
+ <br />
20
+ Most users should select "use FUTO Backups only".
21
+ </Text>
22
+ <HStack gap={2}>
23
+ <Button
24
+ size="small"
25
+ color="primary"
26
+ loading={configure.isPending}
27
+ onclick={() => configure.mutate({ enabled: false })}
28
+ >
29
+ Use FUTO Backups only
30
+ </Button>
31
+ <Button
32
+ size="small"
33
+ variant="ghost"
34
+ loading={ignore.isPending}
35
+ onclick={() => ignore.mutate()}
36
+ >
37
+ Ignore
38
+ </Button>
39
+ </HStack>
40
+ </Stack>
41
+ </Alert>
42
+ {/if}
@@ -11,8 +11,8 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
11
11
  };
12
12
  z_$$bindings?: Bindings;
13
13
  }
14
- declare const ImmichBackupSettings: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
14
+ declare const ImmichDatabaseDumpAlert: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
15
  [evt: string]: CustomEvent<any>;
16
16
  }, {}, {}, string>;
17
- type ImmichBackupSettings = InstanceType<typeof ImmichBackupSettings>;
18
- export default ImmichBackupSettings;
17
+ type ImmichDatabaseDumpAlert = InstanceType<typeof ImmichDatabaseDumpAlert>;
18
+ export default ImmichDatabaseDumpAlert;
@@ -5,6 +5,7 @@
5
5
  import type { LocalRepositoryDto, ScheduleDto } from "../../../fetch-client";
6
6
  import type { ImmichBackupStatus } from "../../../services/immich.integration.service";
7
7
  import { handleCreateBackup } from "../../../services/repository.service";
8
+ import { handleCancelTask } from "../../../services/task.service";
8
9
  import { Button, FormatBytes, Icon } from "@immich/ui";
9
10
  import {
10
11
  mdiAlert,
@@ -13,6 +14,7 @@
13
14
  mdiCloudUploadOutline,
14
15
  mdiInformation,
15
16
  mdiProgressUpload,
17
+ mdiStopCircleOutline,
16
18
  } from "@mdi/js";
17
19
  import cronstrue from "cronstrue";
18
20
 
@@ -37,7 +39,8 @@
37
39
  case "warn": {
38
40
  return { color: "warning", icon: mdiAlert } as const;
39
41
  }
40
- case "incomplete": {
42
+ case "incomplete":
43
+ case "cancelled": {
41
44
  return { color: "warning", icon: mdiAlert } as const;
42
45
  }
43
46
  case "complete": {
@@ -67,15 +70,28 @@
67
70
  </span>
68
71
 
69
72
  {#snippet trailing()}
70
- <Button
71
- variant="ghost"
72
- size="small"
73
- class="whitespace-nowrap"
74
- leadingIcon={mdiCloudUploadOutline}
75
- onclick={() => void handleCreateBackup(repository.id)}
76
- >
77
- Back up now
78
- </Button>
73
+ {#if status.kind === "running"}
74
+ <Button
75
+ variant="ghost"
76
+ size="small"
77
+ color="danger"
78
+ class="whitespace-nowrap"
79
+ leadingIcon={mdiStopCircleOutline}
80
+ onclick={() => void handleCancelTask(repository.id)}
81
+ >
82
+ Cancel backup
83
+ </Button>
84
+ {:else}
85
+ <Button
86
+ variant="ghost"
87
+ size="small"
88
+ class="whitespace-nowrap"
89
+ leadingIcon={mdiCloudUploadOutline}
90
+ onclick={() => void handleCreateBackup(repository.id)}
91
+ >
92
+ Back up now
93
+ </Button>
94
+ {/if}
79
95
  {/snippet}
80
96
 
81
97
  {#snippet footer()}
@@ -93,6 +109,8 @@
93
109
  Last backup finished with warnings <RelativeTime time={status.lastBackup} />
94
110
  {:else if status.kind === "incomplete"}
95
111
  Last backup did not complete <RelativeTime time={status.lastBackup} />
112
+ {:else if status.kind === "cancelled"}
113
+ Last backup was cancelled <RelativeTime time={status.lastBackup} />
96
114
  {:else if status.kind === "complete"}
97
115
  Last backup successful <RelativeTime time={status.lastBackup} />
98
116
  {:else if status.kind === "paused"}
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import BackendsList from "../../backends/BackendsList.svelte";
3
+ import RepositoryRunHistory from "../../backups/run-history/RepositoryRunHistory.svelte";
4
+ import RepositorySnapshotsList from "../../backups/snapshots-list/RepositorySnapshotsList.svelte";
5
+ import PageLayout from "../../ui/PageLayout.svelte";
6
+ import OnEvents from "../../util/OnEvents.svelte";
7
+ import {
8
+ getBackupPageActions,
9
+ useImmichBackupStatus,
10
+ useImmichBackupStatusEventHandler,
11
+ } from "../../../services/immich.integration.service";
12
+ import { Container, Stack } from "@immich/ui";
13
+ import ImmichDatabaseDumpAlert from "./ImmichDatabaseDumpAlert.svelte";
14
+ import ImmichManageBackupOverview from "./ImmichManageBackupOverview.svelte";
15
+
16
+ type Props = {
17
+ onConfigure: () => void;
18
+ onViewAttempts: () => void;
19
+ onViewSnapshots: () => void;
20
+ };
21
+
22
+ const { onConfigure, onViewAttempts, onViewSnapshots }: Props = $props();
23
+
24
+ const backup = useImmichBackupStatus();
25
+
26
+ const { repository, schedule } = $derived(backup);
27
+
28
+ const { ViewRecoveryKey, Configure } = $derived(
29
+ getBackupPageActions(repository?.id, onConfigure),
30
+ );
31
+ </script>
32
+
33
+ <OnEvents {...useImmichBackupStatusEventHandler()} />
34
+
35
+ <PageLayout title="Backups" actions={[ViewRecoveryKey, Configure]}>
36
+ <Container size="medium" center>
37
+ {#if repository && schedule}
38
+ <Stack class="mt-4" gap={6}>
39
+ <ImmichDatabaseDumpAlert />
40
+ <ImmichManageBackupOverview {repository} {schedule} status={backup.status} />
41
+ <BackendsList {repository} />
42
+ <RepositoryRunHistory {repository} onViewAll={onViewAttempts} />
43
+ <RepositorySnapshotsList
44
+ {repository}
45
+ immich
46
+ limit={5}
47
+ onViewAll={onViewSnapshots}
48
+ />
49
+ </Stack>
50
+ {/if}
51
+ </Container>
52
+ </PageLayout>
@@ -0,0 +1,8 @@
1
+ type Props = {
2
+ onConfigure: () => void;
3
+ onViewAttempts: () => void;
4
+ onViewSnapshots: () => void;
5
+ };
6
+ declare const ImmichManageBackupPage: import("svelte").Component<Props, {}, "">;
7
+ type ImmichManageBackupPage = ReturnType<typeof ImmichManageBackupPage>;
8
+ export default ImmichManageBackupPage;
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import RepositorySnapshotsPage from "../../backups/snapshots-list/RepositorySnapshotsPage.svelte";
3
+ import { Container } from "@immich/ui";
4
+ import ImmichConfiguredGate from "./ImmichConfiguredGate.svelte";
5
+
6
+ type Props = {
7
+ onUnconfigured: () => void;
8
+ };
9
+
10
+ const { onUnconfigured }: Props = $props();
11
+ </script>
12
+
13
+ <ImmichConfiguredGate {onUnconfigured}>
14
+ {#snippet children(repository)}
15
+ <Container size="medium" center>
16
+ <RepositorySnapshotsPage {repository} immich />
17
+ </Container>
18
+ {/snippet}
19
+ </ImmichConfiguredGate>
@@ -0,0 +1,6 @@
1
+ type Props = {
2
+ onUnconfigured: () => void;
3
+ };
4
+ declare const ImmichSnapshotsPage: import("svelte").Component<Props, {}, "">;
5
+ type ImmichSnapshotsPage = ReturnType<typeof ImmichSnapshotsPage>;
6
+ export default ImmichSnapshotsPage;