@futo-org/backups-orchestrator-ui 0.27.0 → 0.28.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.
- package/dist/components/backends/BackendItem.svelte +28 -24
- package/dist/components/backends/BackendsList.svelte +33 -34
- package/dist/components/backends/BackendsList.svelte.d.ts +1 -0
- package/dist/components/backends/dialogs/SelectBackendModal.svelte +44 -55
- package/dist/components/backups/BackupItem.svelte +33 -26
- package/dist/components/backups/BackupStatus.svelte +200 -0
- package/dist/components/backups/BackupStatus.svelte.d.ts +19 -0
- package/dist/components/backups/BackupsList.svelte +17 -11
- package/dist/components/backups/dialogs/RestoreSnapshotModal.svelte +2 -2
- package/dist/components/backups/dialogs/SelectRepositoryModal.svelte +26 -36
- package/dist/components/backups/dialogs/ViewStatusModal.svelte +175 -0
- package/dist/components/backups/dialogs/ViewStatusModal.svelte.d.ts +8 -0
- package/dist/components/backups/run-history/RepositoryRunHistory.svelte +22 -10
- package/dist/components/backups/run-history/RepositoryRunHistory.svelte.d.ts +2 -0
- package/dist/components/backups/run-history/RepositoryRunHistoryItem.svelte +46 -20
- package/dist/components/backups/run-history/RepositoryRunHistoryPage.svelte +135 -0
- package/dist/components/backups/run-history/RepositoryRunHistoryPage.svelte.d.ts +8 -0
- package/dist/components/backups/run-history/RunHistoryModal.svelte +2 -2
- package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte +22 -10
- package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte.d.ts +2 -0
- package/dist/components/backups/snapshots-list/RepositorySnapshotsListItem.svelte +23 -21
- package/dist/components/backups/snapshots-list/RepositorySnapshotsPage.svelte +115 -0
- package/dist/components/backups/snapshots-list/RepositorySnapshotsPage.svelte.d.ts +9 -0
- package/dist/components/backups/snapshots-list/SnapshotsListModal.svelte +2 -2
- package/dist/components/dashboard/Dashboard.svelte +14 -7
- package/dist/components/dashboard/Dashboard.svelte.d.ts +1 -1
- package/dist/components/dashboard/DashboardAvgBackupTime.svelte +1 -1
- package/dist/components/dashboard/DashboardBackupHealth.svelte +5 -9
- package/dist/components/dashboard/DashboardBackupHealth.svelte.d.ts +1 -1
- package/dist/components/dashboard/DashboardCurrentUsage.svelte +1 -1
- package/dist/components/dashboard/DashboardDailyBackupTime.svelte +1 -1
- package/dist/components/dashboard/DashboardInstall.svelte +1 -1
- package/dist/components/dashboard/DashboardRecentBackups.svelte +47 -78
- package/dist/components/dashboard/DashboardTotalStored.svelte +1 -1
- package/dist/components/integrations/immich/ImmichBackupSettings.svelte +12 -0
- package/dist/components/integrations/immich/ImmichBackupSettings.svelte.d.ts +18 -0
- package/dist/components/integrations/immich/ImmichBackupsCard.svelte +73 -0
- package/dist/components/integrations/immich/ImmichBackupsCard.svelte.d.ts +12 -0
- package/dist/components/integrations/immich/ImmichBackupsNavButton.svelte +55 -0
- package/dist/components/integrations/immich/ImmichBackupsNavButton.svelte.d.ts +10 -0
- package/dist/components/integrations/immich/ImmichBackupsPage.svelte +15 -3
- package/dist/components/integrations/immich/ImmichBackupsPage.svelte.d.ts +7 -1
- package/dist/components/integrations/immich/ImmichBackupsSidebarItem.svelte +66 -0
- package/dist/components/integrations/immich/ImmichBackupsSidebarItem.svelte.d.ts +8 -0
- package/dist/components/integrations/immich/ImmichManageBackup.svelte +53 -14
- package/dist/components/integrations/immich/ImmichManageBackupOverview.svelte +45 -71
- package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte +123 -82
- package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte.d.ts +1 -1
- package/dist/components/integrations/immich/settings/ImmichSettingsBackupContents.svelte +313 -0
- package/dist/components/integrations/immich/settings/ImmichSettingsBackupContents.svelte.d.ts +3 -0
- package/dist/components/integrations/immich/settings/ImmichSettingsSchedule.svelte +218 -0
- package/dist/components/integrations/immich/settings/ImmichSettingsSchedule.svelte.d.ts +3 -0
- package/dist/components/integrations/immich/settings/ImmichSettingsStorage.svelte +207 -0
- package/dist/components/integrations/immich/settings/ImmichSettingsStorage.svelte.d.ts +3 -0
- package/dist/components/onboarding/RecoveryKeyDisplay.svelte +34 -20
- package/dist/components/onboarding/SampleOnboarding.svelte +57 -38
- package/dist/components/onboarding/stages/OnboardingStageBackupServices.svelte +10 -24
- package/dist/components/onboarding/steps/OnboardingStep1FinishSetup.svelte +44 -0
- package/dist/components/onboarding/steps/OnboardingStep1FinishSetup.svelte.d.ts +7 -0
- package/dist/components/onboarding/steps/OnboardingStep2ConnectAccount.svelte +50 -0
- package/dist/components/onboarding/steps/OnboardingStep2ConnectAccount.svelte.d.ts +7 -0
- package/dist/components/onboarding/steps/OnboardingStep3SaveRecoveryKey.svelte +45 -0
- package/dist/components/onboarding/steps/OnboardingStep3SaveRecoveryKey.svelte.d.ts +8 -0
- package/dist/components/onboarding/steps/OnboardingStep4FirstBackup.svelte +67 -0
- package/dist/components/onboarding/steps/OnboardingStep4FirstBackup.svelte.d.ts +9 -0
- package/dist/components/onboarding/steps/OnboardingStepLayout.svelte +58 -0
- package/dist/components/onboarding/steps/OnboardingStepLayout.svelte.d.ts +19 -0
- package/dist/components/onboarding/upsell/UpsellBackupFeaturesGrid.svelte +52 -0
- package/dist/components/onboarding/upsell/UpsellBackupFeaturesGrid.svelte.d.ts +18 -0
- package/dist/components/onboarding/upsell/UpsellExplainFutoBackups.svelte +33 -0
- package/dist/components/onboarding/upsell/UpsellExplainFutoBackups.svelte.d.ts +8 -0
- package/dist/components/onboarding/upsell/UpsellFrequentlyAskedQuestions.svelte +27 -0
- package/dist/components/onboarding/upsell/UpsellFrequentlyAskedQuestions.svelte.d.ts +10 -0
- package/dist/components/onboarding/upsell/UpsellFutoBackupsBadge.svelte +7 -0
- package/dist/components/onboarding/upsell/UpsellFutoBackupsBadge.svelte.d.ts +18 -0
- package/dist/components/onboarding/upsell/UpsellHowItWorks.svelte +46 -0
- package/dist/components/onboarding/upsell/UpsellHowItWorks.svelte.d.ts +6 -0
- package/dist/components/onboarding/upsell/UpsellModal.svelte +43 -0
- package/dist/components/onboarding/upsell/UpsellModal.svelte.d.ts +9 -0
- package/dist/components/onboarding/upsell/UpsellPage.svelte +39 -0
- package/dist/components/onboarding/upsell/UpsellPage.svelte.d.ts +13 -0
- package/dist/components/onboarding/upsell/UpsellProtectYourImmichLibrary.svelte +58 -0
- package/dist/components/onboarding/upsell/UpsellProtectYourImmichLibrary.svelte.d.ts +8 -0
- package/dist/components/schedules/RepositoryPicker.svelte +45 -38
- package/dist/components/schedules/ScheduleItem.svelte +32 -26
- package/dist/components/schedules/ScheduleList.svelte +16 -10
- package/dist/components/settings/GlobalSettings.svelte +8 -0
- package/dist/components/settings/GlobalSettings.svelte.d.ts +18 -0
- package/dist/components/settings/SettingsBackends.svelte +16 -0
- package/dist/components/settings/SettingsBackends.svelte.d.ts +18 -0
- package/dist/components/settings/SettingsBilling.svelte +69 -0
- package/dist/components/settings/SettingsBilling.svelte.d.ts +6 -0
- package/dist/components/settings/SettingsNotifications.svelte +47 -0
- package/dist/components/settings/SettingsNotifications.svelte.d.ts +6 -0
- package/dist/components/test/ImmichTestUi.svelte +129 -27
- package/dist/components/test/TestUi.svelte +4 -4
- package/dist/components/test/dashboard/ActiveJobs.svelte +2 -2
- package/dist/components/test/immich/MockImmichPhotos.svelte +36 -0
- package/dist/components/test/immich/MockImmichPhotos.svelte.d.ts +18 -0
- package/dist/components/test/immich/MockImmichPurchaseInfo.svelte +29 -0
- package/dist/components/test/immich/MockImmichPurchaseInfo.svelte.d.ts +18 -0
- package/dist/components/test/immich/MockImmichStorageSpace.svelte +37 -0
- package/dist/components/test/immich/MockImmichStorageSpace.svelte.d.ts +6 -0
- package/dist/components/ui/Accordion.svelte +67 -0
- package/dist/components/ui/Accordion.svelte.d.ts +11 -0
- package/dist/components/ui/ListToolbar.svelte +60 -0
- package/dist/components/ui/ListToolbar.svelte.d.ts +16 -0
- package/dist/components/ui/PageLayout.svelte +21 -9
- package/dist/components/ui/PageLayout.svelte.d.ts +1 -0
- package/dist/components/ui/Pagination.svelte +80 -0
- package/dist/components/ui/Pagination.svelte.d.ts +8 -0
- package/dist/components/ui/PathListField.svelte +17 -14
- package/dist/components/ui/StackList.svelte +18 -18
- package/dist/components/ui/StackList.svelte.d.ts +6 -27
- package/dist/components/ui/StackListItem.svelte +47 -25
- package/dist/components/ui/StackListItem.svelte.d.ts +5 -2
- package/dist/components/ui/StackListOption.svelte +33 -0
- package/dist/components/ui/StackListOption.svelte.d.ts +11 -0
- package/dist/components/ui/StackListPlaceholder.svelte +12 -0
- package/dist/components/ui/StackListPlaceholder.svelte.d.ts +7 -0
- package/dist/components/ui/StepNumber.svelte +20 -0
- package/dist/components/ui/StepNumber.svelte.d.ts +7 -0
- package/dist/components/util/Suspense.svelte +7 -3
- package/dist/components/util/YuccaContext.svelte +1 -1
- package/dist/events.js +1 -1
- package/dist/fetch-client.d.ts +2 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/services/backend.service.js +3 -0
- package/dist/services/immich.integration.service.d.ts +1 -1
- package/dist/services/immich.integration.service.js +2 -3
- package/dist/services/integrations.service.d.ts +1 -0
- package/dist/services/integrations.service.js +2 -1
- package/dist/services/log.service.svelte.d.ts +12 -0
- package/dist/services/log.service.svelte.js +15 -1
- package/dist/services/repository.service.js +9 -3
- package/dist/services/runHistory.service.js +2 -2
- package/dist/utils/format.d.ts +1 -1
- package/dist/utils/format.js +2 -2
- package/package.json +3 -3
- package/dist/components/backups/dialogs/ViewLogModal.svelte +0 -208
- package/dist/components/backups/dialogs/ViewLogModal.svelte.d.ts +0 -7
- package/dist/components/integrations/immich/ImmichConfigureBackup.svelte +0 -403
- package/dist/components/integrations/immich/ImmichConfigureBackup.svelte.d.ts +0 -9
- package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte +0 -80
- package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte.d.ts +0 -8
- package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte +0 -56
- package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte.d.ts +0 -9
- package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte +0 -50
- package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte.d.ts +0 -7
- package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte +0 -44
- package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte.d.ts +0 -8
- package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte +0 -56
- package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte.d.ts +0 -9
- package/dist/components/util/TimedButton.svelte +0 -37
- package/dist/components/util/TimedButton.svelte.d.ts +0 -7
|
@@ -2,6 +2,8 @@ import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
|
2
2
|
type Props = {
|
|
3
3
|
repository: LocalRepositoryDto;
|
|
4
4
|
immich?: boolean;
|
|
5
|
+
limit?: number;
|
|
6
|
+
onViewAll?: () => void;
|
|
5
7
|
};
|
|
6
8
|
declare const RepositorySnapshotsList: import("svelte").Component<Props, {}, "">;
|
|
7
9
|
type RepositorySnapshotsList = ReturnType<typeof RepositorySnapshotsList>;
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import RelativeTime from "../../util/RelativeTime.svelte";
|
|
4
4
|
import type { SnapshotDto } from "../../../fetch-client";
|
|
5
5
|
import { getSnapshotActions } from "../../../services/snapshot.service";
|
|
6
|
-
import { FormatBytes,
|
|
6
|
+
import { FormatBytes, Icon } from "@immich/ui";
|
|
7
|
+
import { mdiHistory } from "@mdi/js";
|
|
8
|
+
import { DateTime } from "luxon";
|
|
7
9
|
|
|
8
10
|
type Props = {
|
|
9
11
|
repositoryId: string;
|
|
@@ -15,29 +17,29 @@
|
|
|
15
17
|
const { Restore, Rollback, Delete } = $derived(
|
|
16
18
|
getSnapshotActions(repositoryId, snapshot, immich),
|
|
17
19
|
);
|
|
20
|
+
|
|
21
|
+
const title = $derived(
|
|
22
|
+
DateTime.fromISO(snapshot.time).toLocaleString(DateTime.DATE_FULL),
|
|
23
|
+
);
|
|
18
24
|
</script>
|
|
19
25
|
|
|
20
|
-
<StackListItem actions={[Restore, Rollback, Delete]}>
|
|
21
|
-
|
|
22
|
-
<
|
|
26
|
+
<StackListItem {title} actions={[Restore, Rollback, Delete]}>
|
|
27
|
+
{#snippet icon()}
|
|
28
|
+
<Icon icon={mdiHistory} />
|
|
29
|
+
{/snippet}
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
<Text color="secondary">
|
|
26
|
-
· {snapshot.summary.totalFiles.toLocaleString()}
|
|
27
|
-
{snapshot.summary.totalFiles > 1 ? "files" : "file"} ·
|
|
28
|
-
<FormatBytes bytes={snapshot.summary.totalBytes} />
|
|
29
|
-
</Text>
|
|
31
|
+
<RelativeTime time={snapshot.time} />
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
{
|
|
33
|
+
{#if snapshot.summary}
|
|
34
|
+
· {snapshot.summary.totalFiles.toLocaleString()}
|
|
35
|
+
{snapshot.summary.totalFiles > 1 ? "files" : "file"} ·
|
|
36
|
+
<FormatBytes bytes={snapshot.summary.totalBytes} />
|
|
37
|
+
|
|
38
|
+
{#if snapshot.summary.filesNew > 0}
|
|
39
|
+
· {snapshot.summary.filesNew.toLocaleString()} new
|
|
40
|
+
{/if}
|
|
41
|
+
{#if snapshot.summary.filesChanged > 0}
|
|
42
|
+
· {snapshot.summary.filesChanged.toLocaleString()} changed
|
|
41
43
|
{/if}
|
|
42
|
-
|
|
44
|
+
{/if}
|
|
43
45
|
</StackListItem>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ListToolbar from "../../ui/ListToolbar.svelte";
|
|
3
|
+
import Pagination from "../../ui/Pagination.svelte";
|
|
4
|
+
import StackList from "../../ui/StackList.svelte";
|
|
5
|
+
import StackListPlaceholder from "../../ui/StackListPlaceholder.svelte";
|
|
6
|
+
import OnEvents from "../../util/OnEvents.svelte";
|
|
7
|
+
import Suspense from "../../util/Suspense.svelte";
|
|
8
|
+
import type { LocalRepositoryDto, SnapshotDto } from "../../../fetch-client";
|
|
9
|
+
import {
|
|
10
|
+
useSnapshotEventHandler,
|
|
11
|
+
useSnapshots,
|
|
12
|
+
} from "../../../services/snapshot.service";
|
|
13
|
+
import { Stack, type ActionItem } from "@immich/ui";
|
|
14
|
+
import { mdiRadioboxBlank, mdiRadioboxMarked } from "@mdi/js";
|
|
15
|
+
import { DateTime } from "luxon";
|
|
16
|
+
import RepositorySnapshotsListItem from "./RepositorySnapshotsListItem.svelte";
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
repository: LocalRepositoryDto;
|
|
20
|
+
immich?: boolean;
|
|
21
|
+
pageSize?: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
let { repository, immich = false, pageSize = 10 }: Props = $props();
|
|
25
|
+
|
|
26
|
+
// svelte-ignore state_referenced_locally
|
|
27
|
+
const query = useSnapshots(repository.id);
|
|
28
|
+
const { onRunUpdate } = useSnapshotEventHandler();
|
|
29
|
+
|
|
30
|
+
let search = $state("");
|
|
31
|
+
let newestFirst = $state(true);
|
|
32
|
+
let page = $state(1);
|
|
33
|
+
|
|
34
|
+
const onSearch = (value: string) => {
|
|
35
|
+
search = value;
|
|
36
|
+
page = 1;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const sortOptions = [
|
|
40
|
+
{ newest: true, title: "Newest first" },
|
|
41
|
+
{ newest: false, title: "Oldest first" },
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const sort = $derived({
|
|
45
|
+
label: newestFirst ? "Newest first" : "Oldest first",
|
|
46
|
+
items: sortOptions.map(
|
|
47
|
+
(option): ActionItem => ({
|
|
48
|
+
title: option.title,
|
|
49
|
+
icon: newestFirst === option.newest
|
|
50
|
+
? mdiRadioboxMarked
|
|
51
|
+
: mdiRadioboxBlank,
|
|
52
|
+
onAction: () => (newestFirst = option.newest),
|
|
53
|
+
}),
|
|
54
|
+
),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const matches = (snapshot: SnapshotDto) => {
|
|
58
|
+
const term = search.trim().toLowerCase();
|
|
59
|
+
|
|
60
|
+
if (!term) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const date = DateTime.fromISO(snapshot.time).toLocaleString(
|
|
65
|
+
DateTime.DATE_FULL,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
return [date, ...snapshot.paths, ...(snapshot.tags ?? [])]
|
|
69
|
+
.join(" ")
|
|
70
|
+
.toLowerCase()
|
|
71
|
+
.includes(term);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const filtered = $derived(
|
|
75
|
+
(query.data ?? [])
|
|
76
|
+
.filter(matches)
|
|
77
|
+
.toSorted((a, b) =>
|
|
78
|
+
newestFirst
|
|
79
|
+
? +new Date(b.time) - +new Date(a.time)
|
|
80
|
+
: +new Date(a.time) - +new Date(b.time),
|
|
81
|
+
),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const pageCount = $derived(
|
|
85
|
+
Math.max(Math.ceil(filtered.length / pageSize), 1),
|
|
86
|
+
);
|
|
87
|
+
const current = $derived(Math.min(page, pageCount));
|
|
88
|
+
const visible = $derived(
|
|
89
|
+
filtered.slice((current - 1) * pageSize, current * pageSize),
|
|
90
|
+
);
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<OnEvents {onRunUpdate} />
|
|
94
|
+
|
|
95
|
+
<Stack gap={4}>
|
|
96
|
+
<ListToolbar placeholder="Search snapshots" {search} {onSearch} {sort} />
|
|
97
|
+
|
|
98
|
+
<StackList>
|
|
99
|
+
<Suspense {query}>
|
|
100
|
+
{#each visible as snapshot (snapshot.id)}
|
|
101
|
+
<RepositorySnapshotsListItem
|
|
102
|
+
repositoryId={repository.id}
|
|
103
|
+
{snapshot}
|
|
104
|
+
{immich}
|
|
105
|
+
/>
|
|
106
|
+
{/each}
|
|
107
|
+
|
|
108
|
+
{#if filtered.length === 0}
|
|
109
|
+
<StackListPlaceholder>No snapshots found</StackListPlaceholder>
|
|
110
|
+
{/if}
|
|
111
|
+
</Suspense>
|
|
112
|
+
</StackList>
|
|
113
|
+
|
|
114
|
+
<Pagination page={current} {pageCount} onChange={(next) => (page = next)} />
|
|
115
|
+
</Stack>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repository: LocalRepositoryDto;
|
|
4
|
+
immich?: boolean;
|
|
5
|
+
pageSize?: number;
|
|
6
|
+
};
|
|
7
|
+
declare const RepositorySnapshotsPage: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type RepositorySnapshotsPage = ReturnType<typeof RepositorySnapshotsPage>;
|
|
9
|
+
export default RepositorySnapshotsPage;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
3
3
|
import { Modal, ModalBody } from "@immich/ui";
|
|
4
|
-
import
|
|
4
|
+
import RepositorySnapshotsPage from "./RepositorySnapshotsPage.svelte";
|
|
5
5
|
|
|
6
6
|
type Props = {
|
|
7
7
|
repository: LocalRepositoryDto;
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
<Modal title={`Snapshots for ${repository.name}`} size="giant" {onClose}>
|
|
15
15
|
<ModalBody>
|
|
16
|
-
<
|
|
16
|
+
<RepositorySnapshotsPage {repository} />
|
|
17
17
|
</ModalBody>
|
|
18
18
|
</Modal>
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
type Props = {
|
|
19
19
|
local?: boolean;
|
|
20
20
|
initialData?: RepositoryListResponseDto;
|
|
21
|
-
|
|
21
|
+
onViewBackups?: () => void;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
const { local, initialData,
|
|
24
|
+
const { local, initialData, onViewBackups }: Props = $props();
|
|
25
25
|
|
|
26
26
|
// svelte-ignore state_referenced_locally
|
|
27
27
|
const query = useRepositories(initialData?.repositories);
|
|
@@ -36,12 +36,19 @@
|
|
|
36
36
|
{:else if query.isError}
|
|
37
37
|
<Alert color="danger">{getReadableErrorMessage(query.error)}</Alert>
|
|
38
38
|
{:else if query.isSuccess}
|
|
39
|
-
<Stack>
|
|
40
|
-
<Stack direction="row">
|
|
41
|
-
<DashboardBackupHealth
|
|
42
|
-
|
|
39
|
+
<Stack gap={6}>
|
|
40
|
+
<Stack direction="row" gap={4}>
|
|
41
|
+
<DashboardBackupHealth
|
|
42
|
+
repositories={query.data}
|
|
43
|
+
{local}
|
|
44
|
+
{onViewBackups}
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
{#if !local}
|
|
48
|
+
<DashboardInstall />
|
|
49
|
+
{/if}
|
|
43
50
|
</Stack>
|
|
44
|
-
<Stack direction="row">
|
|
51
|
+
<Stack direction="row" gap={4}>
|
|
45
52
|
<DashboardAvgBackupTime repositories={query.data} />
|
|
46
53
|
<DashboardDailyBackupTime repositories={query.data} />
|
|
47
54
|
<DashboardTotalStored repositories={query.data} />
|
|
@@ -2,7 +2,7 @@ import type { RepositoryListResponseDto } from "../../fetch-client";
|
|
|
2
2
|
type Props = {
|
|
3
3
|
local?: boolean;
|
|
4
4
|
initialData?: RepositoryListResponseDto;
|
|
5
|
-
|
|
5
|
+
onViewBackups?: () => void;
|
|
6
6
|
};
|
|
7
7
|
declare const Dashboard: import("svelte").Component<Props, {}, "">;
|
|
8
8
|
type Dashboard = ReturnType<typeof Dashboard>;
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
type Props = {
|
|
14
14
|
repositories: LocalRepositoryDto[];
|
|
15
15
|
local?: boolean;
|
|
16
|
-
|
|
16
|
+
onViewBackups?: () => void;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const { repositories, local,
|
|
19
|
+
const { repositories, local, onViewBackups }: Props = $props();
|
|
20
20
|
|
|
21
21
|
const total = $derived(repositories.length);
|
|
22
22
|
|
|
@@ -41,16 +41,12 @@
|
|
|
41
41
|
);
|
|
42
42
|
</script>
|
|
43
43
|
|
|
44
|
-
<Card>
|
|
44
|
+
<Card class="border-primary-100 shadow-none">
|
|
45
45
|
<CardHeader>
|
|
46
46
|
<HStack class="justify-between">
|
|
47
47
|
<CardTitle>Your Backups</CardTitle>
|
|
48
|
-
{#if
|
|
49
|
-
<Button
|
|
50
|
-
variant="outline"
|
|
51
|
-
size="tiny"
|
|
52
|
-
onclick={() => onNavigate("backups")}
|
|
53
|
-
>
|
|
48
|
+
{#if onViewBackups}
|
|
49
|
+
<Button variant="outline" size="tiny" onclick={onViewBackups}>
|
|
54
50
|
View all
|
|
55
51
|
</Button>
|
|
56
52
|
{/if}
|
|
@@ -2,7 +2,7 @@ import type { LocalRepositoryDto } from "../../fetch-client";
|
|
|
2
2
|
type Props = {
|
|
3
3
|
repositories: LocalRepositoryDto[];
|
|
4
4
|
local?: boolean;
|
|
5
|
-
|
|
5
|
+
onViewBackups?: () => void;
|
|
6
6
|
};
|
|
7
7
|
declare const DashboardBackupHealth: import("svelte").Component<Props, {}, "">;
|
|
8
8
|
type DashboardBackupHealth = ReturnType<typeof DashboardBackupHealth>;
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
3
|
+
import { Icon, modalManager, type ActionItem } from "@immich/ui";
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
CardHeader,
|
|
7
|
-
CardTitle,
|
|
8
|
-
ContextMenuButton,
|
|
9
|
-
HStack,
|
|
10
|
-
Icon,
|
|
11
|
-
modalManager,
|
|
12
|
-
Text,
|
|
13
|
-
type ActionItem,
|
|
14
|
-
} from "@immich/ui";
|
|
15
|
-
import {
|
|
16
|
-
mdiAlertCircleOutline,
|
|
17
|
-
mdiCheckCircleOutline,
|
|
18
|
-
mdiDotsVertical,
|
|
5
|
+
mdiCloudCheckOutline,
|
|
6
|
+
mdiCloudOffOutline,
|
|
19
7
|
mdiHistory,
|
|
20
8
|
} from "@mdi/js";
|
|
21
|
-
import RelativeTime from "../util/RelativeTime.svelte";
|
|
22
9
|
import MetricsHistoryModal from "../backups/metrics-history/MetricsHistoryModal.svelte";
|
|
10
|
+
import StackList from "../ui/StackList.svelte";
|
|
11
|
+
import StackListPlaceholder from "../ui/StackListPlaceholder.svelte";
|
|
12
|
+
import StackListItem from "../ui/StackListItem.svelte";
|
|
13
|
+
import RelativeTime from "../util/RelativeTime.svelte";
|
|
23
14
|
|
|
24
15
|
type Props = {
|
|
25
16
|
repositories: LocalRepositoryDto[];
|
|
@@ -38,67 +29,45 @@
|
|
|
38
29
|
.slice(0, 5),
|
|
39
30
|
);
|
|
40
31
|
|
|
41
|
-
const getActions = (repository: LocalRepositoryDto): ActionItem[] =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
const getActions = (repository: LocalRepositoryDto): ActionItem[] =>
|
|
33
|
+
local
|
|
34
|
+
? []
|
|
35
|
+
: [
|
|
36
|
+
{
|
|
37
|
+
title: "View history",
|
|
38
|
+
icon: mdiHistory,
|
|
39
|
+
onAction: () =>
|
|
40
|
+
void modalManager.open(MetricsHistoryModal, { repository }),
|
|
41
|
+
},
|
|
42
|
+
];
|
|
49
43
|
</script>
|
|
50
44
|
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class="text-danger-500"
|
|
81
|
-
/>
|
|
82
|
-
{/if}
|
|
83
|
-
<Text>{repo.name}</Text>
|
|
84
|
-
</HStack>
|
|
85
|
-
<HStack class="gap-1">
|
|
86
|
-
<Text color="secondary" size="small">
|
|
87
|
-
<RelativeTime time={repo.metrics.lastBackup!} />
|
|
88
|
-
</Text>
|
|
89
|
-
{#if !local}
|
|
90
|
-
<ContextMenuButton
|
|
91
|
-
icon={mdiDotsVertical}
|
|
92
|
-
aria-label="Options"
|
|
93
|
-
items={getActions(repo)}
|
|
94
|
-
variant="ghost"
|
|
95
|
-
color="secondary"
|
|
96
|
-
/>
|
|
97
|
-
{/if}
|
|
98
|
-
</HStack>
|
|
99
|
-
</HStack>
|
|
100
|
-
{/each}
|
|
101
|
-
</div>
|
|
102
|
-
{/if}
|
|
103
|
-
</CardBody>
|
|
104
|
-
</Card>
|
|
45
|
+
<StackList>
|
|
46
|
+
{#snippet title()}
|
|
47
|
+
Recent backups
|
|
48
|
+
{/snippet}
|
|
49
|
+
|
|
50
|
+
{#if recentAttempts.length === 0}
|
|
51
|
+
<StackListPlaceholder>
|
|
52
|
+
Completed backups will appear here once your first backup runs.
|
|
53
|
+
</StackListPlaceholder>
|
|
54
|
+
{/if}
|
|
55
|
+
|
|
56
|
+
{#each recentAttempts as repository (repository.id)}
|
|
57
|
+
{@const successful =
|
|
58
|
+
repository.metrics.lastBackup === repository.metrics.lastSuccessfulBackup}
|
|
59
|
+
|
|
60
|
+
<StackListItem
|
|
61
|
+
title={repository.name}
|
|
62
|
+
color={successful ? "success" : "danger"}
|
|
63
|
+
actions={getActions(repository)}
|
|
64
|
+
>
|
|
65
|
+
{#snippet icon()}
|
|
66
|
+
<Icon icon={successful ? mdiCloudCheckOutline : mdiCloudOffOutline} />
|
|
67
|
+
{/snippet}
|
|
68
|
+
|
|
69
|
+
{successful ? "Backed up" : "Attempted"}
|
|
70
|
+
<RelativeTime time={repository.metrics.lastBackup!} />
|
|
71
|
+
</StackListItem>
|
|
72
|
+
{/each}
|
|
73
|
+
</StackList>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Container } from "@immich/ui";
|
|
3
|
+
import ImmichSettingsBackupContents from "./settings/ImmichSettingsBackupContents.svelte";
|
|
4
|
+
import ImmichSettingsSchedule from "./settings/ImmichSettingsSchedule.svelte";
|
|
5
|
+
import ImmichSettingsStorage from "./settings/ImmichSettingsStorage.svelte";
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<Container size="large" center>
|
|
9
|
+
<ImmichSettingsBackupContents />
|
|
10
|
+
<ImmichSettingsSchedule />
|
|
11
|
+
<ImmichSettingsStorage />
|
|
12
|
+
</Container>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const ImmichBackupSettings: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type ImmichBackupSettings = InstanceType<typeof ImmichBackupSettings>;
|
|
18
|
+
export default ImmichBackupSettings;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import RelativeTime from "../../util/RelativeTime.svelte";
|
|
3
|
+
import { FormatBytes, Icon, Stack, Text } from "@immich/ui";
|
|
4
|
+
import { mdiChevronRight, mdiCloudAlertOutline, mdiCloudUpload } from "@mdi/js";
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
configured: boolean;
|
|
8
|
+
lastBackup?: string;
|
|
9
|
+
failed?: boolean;
|
|
10
|
+
sizeBytes?: number;
|
|
11
|
+
href?: string;
|
|
12
|
+
onclick?: () => void;
|
|
13
|
+
class?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const {
|
|
17
|
+
configured,
|
|
18
|
+
lastBackup,
|
|
19
|
+
failed = false,
|
|
20
|
+
sizeBytes,
|
|
21
|
+
href,
|
|
22
|
+
onclick,
|
|
23
|
+
class: className,
|
|
24
|
+
}: Props = $props();
|
|
25
|
+
|
|
26
|
+
const shell =
|
|
27
|
+
"border-primary/25 hover:bg-primary/5 flex w-full items-center gap-3 rounded-xl border px-3 py-2.5 text-start transition-colors";
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
{#snippet body()}
|
|
31
|
+
<Icon
|
|
32
|
+
icon={failed ? mdiCloudAlertOutline : mdiCloudUpload}
|
|
33
|
+
size="2em"
|
|
34
|
+
class="{failed ? 'text-danger' : 'text-primary'} shrink-0"
|
|
35
|
+
/>
|
|
36
|
+
|
|
37
|
+
{#if !configured}
|
|
38
|
+
<Text color="primary" fontWeight="medium" class="flex-1 whitespace-nowrap">
|
|
39
|
+
Set up Backups
|
|
40
|
+
</Text>
|
|
41
|
+
{:else}
|
|
42
|
+
<Stack gap={0} class="min-w-0 flex-1">
|
|
43
|
+
<Text fontWeight="medium" color={failed ? "danger" : "primary"}>
|
|
44
|
+
{failed ? "Backup failed" : "Last Backup"}
|
|
45
|
+
</Text>
|
|
46
|
+
|
|
47
|
+
<Text size="small" color="muted" class="truncate">
|
|
48
|
+
{#if lastBackup}
|
|
49
|
+
<RelativeTime time={lastBackup} />
|
|
50
|
+
{#if sizeBytes !== undefined}
|
|
51
|
+
· <FormatBytes bytes={sizeBytes} />
|
|
52
|
+
{/if}
|
|
53
|
+
{:else}
|
|
54
|
+
No backups yet
|
|
55
|
+
{/if}
|
|
56
|
+
</Text>
|
|
57
|
+
</Stack>
|
|
58
|
+
|
|
59
|
+
<Icon icon={mdiChevronRight} size="1.4em" class="text-muted shrink-0" />
|
|
60
|
+
{/if}
|
|
61
|
+
{/snippet}
|
|
62
|
+
|
|
63
|
+
<div class={className ?? ""}>
|
|
64
|
+
{#if href}
|
|
65
|
+
<a {href} {onclick} class={shell}>
|
|
66
|
+
{@render body()}
|
|
67
|
+
</a>
|
|
68
|
+
{:else}
|
|
69
|
+
<button type="button" {onclick} class={shell}>
|
|
70
|
+
{@render body()}
|
|
71
|
+
</button>
|
|
72
|
+
{/if}
|
|
73
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
configured: boolean;
|
|
3
|
+
lastBackup?: string;
|
|
4
|
+
failed?: boolean;
|
|
5
|
+
sizeBytes?: number;
|
|
6
|
+
href?: string;
|
|
7
|
+
onclick?: () => void;
|
|
8
|
+
class?: string;
|
|
9
|
+
};
|
|
10
|
+
declare const ImmichBackupsCard: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type ImmichBackupsCard = ReturnType<typeof ImmichBackupsCard>;
|
|
12
|
+
export default ImmichBackupsCard;
|