@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.
- package/LICENSE +41 -0
- package/dist/components/backends/BackendItem.svelte +64 -0
- package/dist/components/backends/BackendItem.svelte.d.ts +10 -0
- package/dist/components/backends/BackendsList.svelte +73 -0
- package/dist/components/backends/BackendsList.svelte.d.ts +7 -0
- package/dist/components/backends/CreateLocalBackend.svelte +46 -0
- package/dist/components/backends/CreateLocalBackend.svelte.d.ts +7 -0
- package/dist/components/backends/OAuthDeviceFlow.svelte +78 -0
- package/dist/components/backends/OAuthDeviceFlow.svelte.d.ts +9 -0
- package/dist/components/backups/BackupItem.svelte +59 -0
- package/dist/components/backups/BackupItem.svelte.d.ts +7 -0
- package/dist/components/backups/BackupsList.svelte +82 -0
- package/dist/components/backups/BackupsList.svelte.d.ts +8 -0
- package/dist/components/backups/dialogs/ConfigureRepositoryModal.svelte +102 -0
- package/dist/components/backups/dialogs/ConfigureRepositoryModal.svelte.d.ts +8 -0
- package/dist/components/backups/dialogs/CreateRepositoryModal.svelte +59 -0
- package/dist/components/backups/dialogs/CreateRepositoryModal.svelte.d.ts +6 -0
- package/dist/components/backups/dialogs/ImportRepositoryModal.svelte +62 -0
- package/dist/components/backups/dialogs/ImportRepositoryModal.svelte.d.ts +8 -0
- package/dist/components/backups/dialogs/RestoreSnapshotModal.svelte +109 -0
- package/dist/components/backups/dialogs/RestoreSnapshotModal.svelte.d.ts +8 -0
- package/dist/components/backups/dialogs/ViewLogModal.svelte +208 -0
- package/dist/components/backups/dialogs/ViewLogModal.svelte.d.ts +7 -0
- package/dist/components/backups/metrics-history/MetricsHistoryModal.svelte +166 -0
- package/dist/components/backups/metrics-history/MetricsHistoryModal.svelte.d.ts +8 -0
- package/dist/components/backups/run-history/RepositoryRunHistory.svelte +39 -0
- package/dist/components/backups/run-history/RepositoryRunHistory.svelte.d.ts +7 -0
- package/dist/components/backups/run-history/RepositoryRunHistoryItem.svelte +45 -0
- package/dist/components/backups/run-history/RepositoryRunHistoryItem.svelte.d.ts +7 -0
- package/dist/components/backups/run-history/RunHistoryModal.svelte +18 -0
- package/dist/components/backups/run-history/RunHistoryModal.svelte.d.ts +8 -0
- package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte +53 -0
- package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte.d.ts +7 -0
- package/dist/components/backups/snapshots-list/RepositorySnapshotsListItem.svelte +41 -0
- package/dist/components/backups/snapshots-list/RepositorySnapshotsListItem.svelte.d.ts +8 -0
- package/dist/components/backups/snapshots-list/SnapshotsListModal.svelte +18 -0
- package/dist/components/backups/snapshots-list/SnapshotsListModal.svelte.d.ts +8 -0
- package/dist/components/dashboard/Dashboard.svelte +52 -0
- package/dist/components/dashboard/Dashboard.svelte.d.ts +9 -0
- package/dist/components/dashboard/DashboardAvgBackupTime.svelte +34 -0
- package/dist/components/dashboard/DashboardAvgBackupTime.svelte.d.ts +7 -0
- package/dist/components/dashboard/DashboardBackupHealth.svelte +91 -0
- package/dist/components/dashboard/DashboardBackupHealth.svelte.d.ts +9 -0
- package/dist/components/dashboard/DashboardCurrentUsage.svelte +10 -0
- package/dist/components/dashboard/DashboardCurrentUsage.svelte.d.ts +18 -0
- package/dist/components/dashboard/DashboardDailyBackupTime.svelte +31 -0
- package/dist/components/dashboard/DashboardDailyBackupTime.svelte.d.ts +7 -0
- package/dist/components/dashboard/DashboardInstall.svelte +15 -0
- package/dist/components/dashboard/DashboardInstall.svelte.d.ts +18 -0
- package/dist/components/dashboard/DashboardRecentBackups.svelte +104 -0
- package/dist/components/dashboard/DashboardRecentBackups.svelte.d.ts +8 -0
- package/dist/components/dashboard/DashboardTotalStored.svelte +27 -0
- package/dist/components/dashboard/DashboardTotalStored.svelte.d.ts +7 -0
- package/dist/components/integrations/immich/ImmichBackupsPage.svelte +14 -0
- package/dist/components/integrations/immich/ImmichBackupsPage.svelte.d.ts +6 -0
- package/dist/components/integrations/immich/ImmichConfigureBackup.svelte +402 -0
- package/dist/components/integrations/immich/ImmichConfigureBackup.svelte.d.ts +9 -0
- package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte +80 -0
- package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte.d.ts +8 -0
- package/dist/components/integrations/immich/ImmichManageBackup.svelte +77 -0
- package/dist/components/integrations/immich/ImmichManageBackup.svelte.d.ts +3 -0
- package/dist/components/integrations/immich/ImmichManageBackupOverview.svelte +100 -0
- package/dist/components/integrations/immich/ImmichManageBackupOverview.svelte.d.ts +8 -0
- package/dist/components/integrations/immich/ImmichOnboardingRestoreFlow.svelte +75 -0
- package/dist/components/integrations/immich/ImmichOnboardingRestoreFlow.svelte.d.ts +7 -0
- package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte +113 -0
- package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte.d.ts +8 -0
- package/dist/components/onboarding/OnboardingGate.svelte +48 -0
- package/dist/components/onboarding/OnboardingGate.svelte.d.ts +9 -0
- package/dist/components/onboarding/RecoveryKeyDisplay.svelte +103 -0
- package/dist/components/onboarding/RecoveryKeyDisplay.svelte.d.ts +6 -0
- package/dist/components/onboarding/SampleOnboarding.svelte +98 -0
- package/dist/components/onboarding/SampleOnboarding.svelte.d.ts +9 -0
- package/dist/components/onboarding/dialogs/BackupsRecoveryKeyModal.svelte +43 -0
- package/dist/components/onboarding/dialogs/BackupsRecoveryKeyModal.svelte.d.ts +6 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow.svelte +96 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow.svelte.d.ts +8 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow2SelectSnapshot.svelte +83 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow2SelectSnapshot.svelte.d.ts +9 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow3ConfirmRestore.svelte +118 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow3ConfirmRestore.svelte.d.ts +10 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow4Restore.svelte +59 -0
- package/dist/components/onboarding/restore-point-flow/RestorePointFlow4Restore.svelte.d.ts +8 -0
- package/dist/components/onboarding/stages/OnboardingStageBackupServices.svelte +82 -0
- package/dist/components/onboarding/stages/OnboardingStageBackupServices.svelte.d.ts +8 -0
- package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte +56 -0
- package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte.d.ts +9 -0
- package/dist/components/onboarding/stages/OnboardingStageKeyImport.svelte +57 -0
- package/dist/components/onboarding/stages/OnboardingStageKeyImport.svelte.d.ts +8 -0
- package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte +50 -0
- package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte.d.ts +7 -0
- package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte +44 -0
- package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte.d.ts +8 -0
- package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte +56 -0
- package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte.d.ts +9 -0
- package/dist/components/onboarding/stages/SampleCreateFirstBackup.svelte +43 -0
- package/dist/components/onboarding/stages/SampleCreateFirstBackup.svelte.d.ts +7 -0
- package/dist/components/onboarding/stages/SampleCreateFirstSchedule.svelte +49 -0
- package/dist/components/onboarding/stages/SampleCreateFirstSchedule.svelte.d.ts +7 -0
- package/dist/components/schedules/RepositoryPicker.svelte +105 -0
- package/dist/components/schedules/RepositoryPicker.svelte.d.ts +6 -0
- package/dist/components/schedules/ScheduleItem.svelte +47 -0
- package/dist/components/schedules/ScheduleItem.svelte.d.ts +8 -0
- package/dist/components/schedules/ScheduleList.svelte +51 -0
- package/dist/components/schedules/ScheduleList.svelte.d.ts +3 -0
- package/dist/components/schedules/dialogs/ConfigureScheduleModal.svelte +48 -0
- package/dist/components/schedules/dialogs/ConfigureScheduleModal.svelte.d.ts +8 -0
- package/dist/components/schedules/dialogs/CreateScheduleModal.svelte +43 -0
- package/dist/components/schedules/dialogs/CreateScheduleModal.svelte.d.ts +6 -0
- package/dist/components/test/ImmichTestUi.svelte +183 -0
- package/dist/components/test/ImmichTestUi.svelte.d.ts +6 -0
- package/dist/components/test/TestUi.svelte +134 -0
- package/dist/components/test/TestUi.svelte.d.ts +6 -0
- package/dist/components/test/dashboard/ActiveJobs.svelte +380 -0
- package/dist/components/test/dashboard/ActiveJobs.svelte.d.ts +3 -0
- package/dist/components/test/dashboard/BackupHealth.svelte +95 -0
- package/dist/components/test/dashboard/BackupHealth.svelte.d.ts +7 -0
- package/dist/components/test/dashboard/BackupStats.svelte +117 -0
- package/dist/components/test/dashboard/BackupStats.svelte.d.ts +8 -0
- package/dist/components/test/dashboard/Dashboard.svelte +76 -0
- package/dist/components/test/dashboard/Dashboard.svelte.d.ts +6 -0
- package/dist/components/test/dashboard/RecentBackups.svelte +96 -0
- package/dist/components/test/dashboard/RecentBackups.svelte.d.ts +8 -0
- package/dist/components/ui/PageLayout.svelte +67 -0
- package/dist/components/ui/PageLayout.svelte.d.ts +10 -0
- package/dist/components/ui/PathListField.svelte +83 -0
- package/dist/components/ui/PathListField.svelte.d.ts +17 -0
- package/dist/components/ui/PathPickerField.svelte +74 -0
- package/dist/components/ui/PathPickerField.svelte.d.ts +15 -0
- package/dist/components/ui/PathPickerModal.svelte +219 -0
- package/dist/components/ui/PathPickerModal.svelte.d.ts +14 -0
- package/dist/components/ui/StackList.svelte +30 -0
- package/dist/components/ui/StackList.svelte.d.ts +30 -0
- package/dist/components/ui/StackListItem.svelte +64 -0
- package/dist/components/ui/StackListItem.svelte.d.ts +13 -0
- package/dist/components/ui/VisualisationGauge.svelte +25 -0
- package/dist/components/ui/VisualisationGauge.svelte.d.ts +10 -0
- package/dist/components/ui/VisualisationSegmentedBar.svelte +48 -0
- package/dist/components/ui/VisualisationSegmentedBar.svelte.d.ts +14 -0
- package/dist/components/util/OnEvents.svelte +31 -0
- package/dist/components/util/OnEvents.svelte.d.ts +7 -0
- package/dist/components/util/RelativeTime.svelte +21 -0
- package/dist/components/util/RelativeTime.svelte.d.ts +6 -0
- package/dist/components/util/Suspense.svelte +21 -0
- package/dist/components/util/Suspense.svelte.d.ts +29 -0
- package/dist/components/util/TimedButton.svelte +37 -0
- package/dist/components/util/TimedButton.svelte.d.ts +7 -0
- package/dist/components/util/YuccaContext.svelte +26 -0
- package/dist/components/util/YuccaContext.svelte.d.ts +8 -0
- package/dist/events.d.ts +6 -0
- package/dist/events.js +47 -0
- package/dist/fetch-client.d.ts +289 -0
- package/dist/fetch-client.js +233 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +28 -0
- package/dist/options.d.ts +5 -0
- package/dist/options.js +6 -0
- package/dist/providers.d.ts +11 -0
- package/dist/providers.js +35 -0
- package/dist/query-client.d.ts +2 -0
- package/dist/query-client.js +2 -0
- package/dist/services/backend.service.d.ts +18 -0
- package/dist/services/backend.service.js +61 -0
- package/dist/services/filesystem.service.d.ts +2 -0
- package/dist/services/filesystem.service.js +11 -0
- package/dist/services/immich.integration.service.d.ts +6 -0
- package/dist/services/immich.integration.service.js +24 -0
- package/dist/services/integrations.service.d.ts +13 -0
- package/dist/services/integrations.service.js +42 -0
- package/dist/services/log.service.svelte.d.ts +53 -0
- package/dist/services/log.service.svelte.js +93 -0
- package/dist/services/metricsHistory.service.d.ts +4 -0
- package/dist/services/metricsHistory.service.js +12 -0
- package/dist/services/onboarding.service.d.ts +11 -0
- package/dist/services/onboarding.service.js +56 -0
- package/dist/services/repository.service.d.ts +45 -0
- package/dist/services/repository.service.js +157 -0
- package/dist/services/runHistory.service.d.ts +26 -0
- package/dist/services/runHistory.service.js +54 -0
- package/dist/services/schedule.service.d.ts +35 -0
- package/dist/services/schedule.service.js +126 -0
- package/dist/services/snapshot.service.d.ts +29 -0
- package/dist/services/snapshot.service.js +108 -0
- package/dist/services/task.service.d.ts +3 -0
- package/dist/services/task.service.js +20 -0
- package/dist/utils/actions.d.ts +2 -0
- package/dist/utils/actions.js +3 -0
- package/dist/utils/format.d.ts +2 -0
- package/dist/utils/format.js +24 -0
- package/dist/utils/handle-error.d.ts +9 -0
- package/dist/utils/handle-error.js +42 -0
- package/package.json +79 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
3
|
+
import { Modal, ModalBody } from "@immich/ui";
|
|
4
|
+
import RepositoryRunHistory from "./RepositoryRunHistory.svelte";
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
repository: LocalRepositoryDto;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
let { repository, onClose }: Props = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<Modal title={`Run History for ${repository.name}`} size="giant" {onClose}>
|
|
15
|
+
<ModalBody>
|
|
16
|
+
<RepositoryRunHistory {repository} />
|
|
17
|
+
</ModalBody>
|
|
18
|
+
</Modal>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repository: LocalRepositoryDto;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
};
|
|
6
|
+
declare const RunHistoryModal: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type RunHistoryModal = ReturnType<typeof RunHistoryModal>;
|
|
8
|
+
export default RunHistoryModal;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import StackList from "../../ui/StackList.svelte";
|
|
3
|
+
import OnEvents from "../../util/OnEvents.svelte";
|
|
4
|
+
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
5
|
+
import { options } from "../../../options";
|
|
6
|
+
import { handlePruneRepository } from "../../../services/repository.service";
|
|
7
|
+
import {
|
|
8
|
+
useSnapshotEventHandler,
|
|
9
|
+
useSnapshots,
|
|
10
|
+
} from "../../../services/snapshot.service";
|
|
11
|
+
import { Button, HStack, Text } from "@immich/ui";
|
|
12
|
+
import RepositorySnapshotsListItem from "./RepositorySnapshotsListItem.svelte";
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
repository: LocalRepositoryDto;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
let { repository }: Props = $props();
|
|
19
|
+
|
|
20
|
+
const { advanced } = options;
|
|
21
|
+
// svelte-ignore state_referenced_locally
|
|
22
|
+
const query = useSnapshots(repository.id);
|
|
23
|
+
const { onRunUpdate } = useSnapshotEventHandler();
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<OnEvents {onRunUpdate} />
|
|
27
|
+
|
|
28
|
+
<StackList {query}>
|
|
29
|
+
{#snippet title()}
|
|
30
|
+
Snapshots
|
|
31
|
+
{/snippet}
|
|
32
|
+
|
|
33
|
+
{#snippet children(snapshots)}
|
|
34
|
+
{#if snapshots.length === 0}
|
|
35
|
+
<Text class="text-center py-6" color="muted">No backups yet</Text>
|
|
36
|
+
{:else}
|
|
37
|
+
{#each snapshots as snapshot (snapshot.id)}
|
|
38
|
+
<RepositorySnapshotsListItem repositoryId={repository.id} {snapshot} />
|
|
39
|
+
{/each}
|
|
40
|
+
{/if}
|
|
41
|
+
{/snippet}
|
|
42
|
+
</StackList>
|
|
43
|
+
|
|
44
|
+
{#if $advanced}
|
|
45
|
+
<HStack>
|
|
46
|
+
<Button
|
|
47
|
+
size="small"
|
|
48
|
+
variant="outline"
|
|
49
|
+
onclick={() => handlePruneRepository(repository.id)}
|
|
50
|
+
>Clean up old backups now</Button
|
|
51
|
+
>
|
|
52
|
+
</HStack>
|
|
53
|
+
{/if}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repository: LocalRepositoryDto;
|
|
4
|
+
};
|
|
5
|
+
declare const RepositorySnapshotsList: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type RepositorySnapshotsList = ReturnType<typeof RepositorySnapshotsList>;
|
|
7
|
+
export default RepositorySnapshotsList;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import StackListItem from "../../ui/StackListItem.svelte";
|
|
3
|
+
import RelativeTime from "../../util/RelativeTime.svelte";
|
|
4
|
+
import type { SnapshotDto } from "../../../fetch-client";
|
|
5
|
+
import { getSnapshotActions } from "../../../services/snapshot.service";
|
|
6
|
+
import { FormatBytes, HStack, Text } from "@immich/ui";
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
repositoryId: string;
|
|
10
|
+
snapshot: SnapshotDto;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const { repositoryId, snapshot }: Props = $props();
|
|
14
|
+
const { Restore, Delete } = $derived(
|
|
15
|
+
getSnapshotActions(repositoryId, snapshot),
|
|
16
|
+
);
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<StackListItem actions={[Restore, Delete]}>
|
|
20
|
+
<HStack>
|
|
21
|
+
<RelativeTime time={snapshot.time} />
|
|
22
|
+
|
|
23
|
+
{#if snapshot.summary}
|
|
24
|
+
<Text color="secondary">
|
|
25
|
+
· {snapshot.summary.totalFiles.toLocaleString()} files ·
|
|
26
|
+
<FormatBytes bytes={snapshot.summary.totalBytes} />
|
|
27
|
+
</Text>
|
|
28
|
+
|
|
29
|
+
{#if snapshot.summary.filesNew > 0 || snapshot.summary.filesChanged > 0}
|
|
30
|
+
<Text color="muted" size="tiny">
|
|
31
|
+
{#if snapshot.summary.filesNew > 0}
|
|
32
|
+
· {snapshot.summary.filesNew.toLocaleString()} new
|
|
33
|
+
{/if}
|
|
34
|
+
{#if snapshot.summary.filesChanged > 0}
|
|
35
|
+
· {snapshot.summary.filesChanged.toLocaleString()} changed
|
|
36
|
+
{/if}
|
|
37
|
+
</Text>
|
|
38
|
+
{/if}
|
|
39
|
+
{/if}
|
|
40
|
+
</HStack>
|
|
41
|
+
</StackListItem>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SnapshotDto } from "../../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repositoryId: string;
|
|
4
|
+
snapshot: SnapshotDto;
|
|
5
|
+
};
|
|
6
|
+
declare const RepositorySnapshotsListItem: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type RepositorySnapshotsListItem = ReturnType<typeof RepositorySnapshotsListItem>;
|
|
8
|
+
export default RepositorySnapshotsListItem;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
3
|
+
import { Modal, ModalBody } from "@immich/ui";
|
|
4
|
+
import RepositorySnapshotsList from "./RepositorySnapshotsList.svelte";
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
repository: LocalRepositoryDto;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
let { repository, onClose }: Props = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<Modal title={`Snapshots for ${repository.name}`} size="giant" {onClose}>
|
|
15
|
+
<ModalBody>
|
|
16
|
+
<RepositorySnapshotsList {repository} />
|
|
17
|
+
</ModalBody>
|
|
18
|
+
</Modal>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repository: LocalRepositoryDto;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
};
|
|
6
|
+
declare const SnapshotsListModal: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type SnapshotsListModal = ReturnType<typeof SnapshotsListModal>;
|
|
8
|
+
export default SnapshotsListModal;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { RepositoryListResponseDto } from "../../fetch-client";
|
|
3
|
+
import {
|
|
4
|
+
useRepositories,
|
|
5
|
+
useRepositoryEventHandler,
|
|
6
|
+
} from "../../services/repository.service";
|
|
7
|
+
import { getReadableErrorMessage } from "../../utils/handle-error";
|
|
8
|
+
import { Alert, LoadingSpinner, Stack } from "@immich/ui";
|
|
9
|
+
import OnEvents from "../util/OnEvents.svelte";
|
|
10
|
+
import DashboardAvgBackupTime from "./DashboardAvgBackupTime.svelte";
|
|
11
|
+
import DashboardBackupHealth from "./DashboardBackupHealth.svelte";
|
|
12
|
+
import DashboardCurrentUsage from "./DashboardCurrentUsage.svelte";
|
|
13
|
+
import DashboardDailyBackupTime from "./DashboardDailyBackupTime.svelte";
|
|
14
|
+
import DashboardInstall from "./DashboardInstall.svelte";
|
|
15
|
+
import DashboardRecentBackups from "./DashboardRecentBackups.svelte";
|
|
16
|
+
import DashboardTotalStored from "./DashboardTotalStored.svelte";
|
|
17
|
+
|
|
18
|
+
type Props = {
|
|
19
|
+
local?: boolean;
|
|
20
|
+
initialData?: RepositoryListResponseDto;
|
|
21
|
+
onNavigate?: (route: string) => void;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const { local, initialData, onNavigate }: Props = $props();
|
|
25
|
+
|
|
26
|
+
// svelte-ignore state_referenced_locally
|
|
27
|
+
const query = useRepositories(initialData?.repositories);
|
|
28
|
+
const { onRepositoryCreate, onRepositoryUpdate } =
|
|
29
|
+
useRepositoryEventHandler();
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<OnEvents {onRepositoryCreate} {onRepositoryUpdate} />
|
|
33
|
+
|
|
34
|
+
{#if query.isLoading}
|
|
35
|
+
<LoadingSpinner />
|
|
36
|
+
{:else if query.isError}
|
|
37
|
+
<Alert color="danger">{getReadableErrorMessage(query.error)}</Alert>
|
|
38
|
+
{:else if query.isSuccess}
|
|
39
|
+
<Stack>
|
|
40
|
+
<Stack direction="row">
|
|
41
|
+
<DashboardBackupHealth repositories={query.data} {local} {onNavigate} />
|
|
42
|
+
<DashboardInstall />
|
|
43
|
+
</Stack>
|
|
44
|
+
<Stack direction="row">
|
|
45
|
+
<DashboardAvgBackupTime repositories={query.data} />
|
|
46
|
+
<DashboardDailyBackupTime repositories={query.data} />
|
|
47
|
+
<DashboardTotalStored repositories={query.data} />
|
|
48
|
+
<DashboardCurrentUsage />
|
|
49
|
+
</Stack>
|
|
50
|
+
<DashboardRecentBackups repositories={query.data} {local} />
|
|
51
|
+
</Stack>
|
|
52
|
+
{/if}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RepositoryListResponseDto } from "../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
local?: boolean;
|
|
4
|
+
initialData?: RepositoryListResponseDto;
|
|
5
|
+
onNavigate?: (route: string) => void;
|
|
6
|
+
};
|
|
7
|
+
declare const Dashboard: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type Dashboard = ReturnType<typeof Dashboard>;
|
|
9
|
+
export default Dashboard;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
3
|
+
import { formatDuration } from "../../utils/format";
|
|
4
|
+
import { Card, CardBody } from "@immich/ui";
|
|
5
|
+
import VisualisationGauge from "../ui/VisualisationGauge.svelte";
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
repositories: LocalRepositoryDto[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const { repositories }: Props = $props();
|
|
12
|
+
|
|
13
|
+
const durations = $derived(
|
|
14
|
+
repositories
|
|
15
|
+
.map((repo) => repo.metrics?.lastBackupDuration)
|
|
16
|
+
.filter((duration): duration is number => duration != null),
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const avgBackupTime = $derived(
|
|
20
|
+
durations.length > 0
|
|
21
|
+
? durations.reduce((sum, duration) => sum + duration, 0) /
|
|
22
|
+
durations.length
|
|
23
|
+
: undefined,
|
|
24
|
+
);
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<Card>
|
|
28
|
+
<CardBody>
|
|
29
|
+
<VisualisationGauge
|
|
30
|
+
title="Avg. Backup Time"
|
|
31
|
+
content={avgBackupTime != null ? formatDuration(avgBackupTime) : "—"}
|
|
32
|
+
/>
|
|
33
|
+
</CardBody>
|
|
34
|
+
</Card>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repositories: LocalRepositoryDto[];
|
|
4
|
+
};
|
|
5
|
+
declare const DashboardAvgBackupTime: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type DashboardAvgBackupTime = ReturnType<typeof DashboardAvgBackupTime>;
|
|
7
|
+
export default DashboardAvgBackupTime;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
Card,
|
|
6
|
+
CardBody,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle,
|
|
9
|
+
HStack,
|
|
10
|
+
} from "@immich/ui";
|
|
11
|
+
import VisualisationSegmentedBar from "../ui/VisualisationSegmentedBar.svelte";
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
repositories: LocalRepositoryDto[];
|
|
15
|
+
local?: boolean;
|
|
16
|
+
onNavigate?: (route: string) => void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const { repositories, local, onNavigate }: Props = $props();
|
|
20
|
+
|
|
21
|
+
const total = $derived(repositories.length);
|
|
22
|
+
|
|
23
|
+
const status = $derived(
|
|
24
|
+
repositories.reduce(
|
|
25
|
+
(tally, repo) => {
|
|
26
|
+
if (local && !repo.backends?.primary.online) {
|
|
27
|
+
tally.offline++;
|
|
28
|
+
} else if (!repo.metrics?.lastBackup) {
|
|
29
|
+
tally.neverRun++;
|
|
30
|
+
} else if (
|
|
31
|
+
repo.metrics.lastBackup === repo.metrics.lastSuccessfulBackup
|
|
32
|
+
) {
|
|
33
|
+
tally.success++;
|
|
34
|
+
} else {
|
|
35
|
+
tally.failed++;
|
|
36
|
+
}
|
|
37
|
+
return tally;
|
|
38
|
+
},
|
|
39
|
+
{ success: 0, offline: 0, failed: 0, neverRun: 0 },
|
|
40
|
+
),
|
|
41
|
+
);
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<Card>
|
|
45
|
+
<CardHeader>
|
|
46
|
+
<HStack class="justify-between">
|
|
47
|
+
<CardTitle>Your Backups</CardTitle>
|
|
48
|
+
{#if onNavigate}
|
|
49
|
+
<Button
|
|
50
|
+
variant="outline"
|
|
51
|
+
size="tiny"
|
|
52
|
+
onclick={() => onNavigate("backups")}
|
|
53
|
+
>
|
|
54
|
+
View all
|
|
55
|
+
</Button>
|
|
56
|
+
{/if}
|
|
57
|
+
</HStack>
|
|
58
|
+
</CardHeader>
|
|
59
|
+
<CardBody>
|
|
60
|
+
<VisualisationSegmentedBar
|
|
61
|
+
title="Backup Health"
|
|
62
|
+
summary="{status.success} of {total} successful"
|
|
63
|
+
segments={[
|
|
64
|
+
{
|
|
65
|
+
value: status.success,
|
|
66
|
+
label: "Successful",
|
|
67
|
+
color: "var(--immich-ui-success-500)",
|
|
68
|
+
badge: "success",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
value: status.offline,
|
|
72
|
+
label: "Offline",
|
|
73
|
+
color: "var(--immich-ui-warning-500)",
|
|
74
|
+
badge: "warning",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
value: status.failed,
|
|
78
|
+
label: "Failed",
|
|
79
|
+
color: "var(--immich-ui-danger-500)",
|
|
80
|
+
badge: "danger",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
value: status.neverRun,
|
|
84
|
+
label: "Never Run",
|
|
85
|
+
color: "var(--immich-ui-light-400)",
|
|
86
|
+
badge: "secondary",
|
|
87
|
+
},
|
|
88
|
+
]}
|
|
89
|
+
/>
|
|
90
|
+
</CardBody>
|
|
91
|
+
</Card>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repositories: LocalRepositoryDto[];
|
|
4
|
+
local?: boolean;
|
|
5
|
+
onNavigate?: (route: string) => void;
|
|
6
|
+
};
|
|
7
|
+
declare const DashboardBackupHealth: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type DashboardBackupHealth = ReturnType<typeof DashboardBackupHealth>;
|
|
9
|
+
export default DashboardBackupHealth;
|
|
@@ -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 DashboardCurrentUsage: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type DashboardCurrentUsage = InstanceType<typeof DashboardCurrentUsage>;
|
|
18
|
+
export default DashboardCurrentUsage;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
3
|
+
import { formatDuration } from "../../utils/format";
|
|
4
|
+
import { Card, CardBody } from "@immich/ui";
|
|
5
|
+
import VisualisationGauge from "../ui/VisualisationGauge.svelte";
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
repositories: LocalRepositoryDto[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const { repositories }: Props = $props();
|
|
12
|
+
|
|
13
|
+
const dailyBackupTime = $derived(
|
|
14
|
+
repositories
|
|
15
|
+
.map((repo) => repo.metrics?.lastBackupDuration)
|
|
16
|
+
.filter((duration): duration is number => duration != null)
|
|
17
|
+
.reduce<number | undefined>(
|
|
18
|
+
(sum, duration) => (sum ?? 0) + duration,
|
|
19
|
+
undefined,
|
|
20
|
+
),
|
|
21
|
+
);
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<Card>
|
|
25
|
+
<CardBody>
|
|
26
|
+
<VisualisationGauge
|
|
27
|
+
title="Daily Backup Time"
|
|
28
|
+
content={dailyBackupTime != null ? formatDuration(dailyBackupTime) : "—"}
|
|
29
|
+
/>
|
|
30
|
+
</CardBody>
|
|
31
|
+
</Card>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repositories: LocalRepositoryDto[];
|
|
4
|
+
};
|
|
5
|
+
declare const DashboardDailyBackupTime: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type DashboardDailyBackupTime = ReturnType<typeof DashboardDailyBackupTime>;
|
|
7
|
+
export default DashboardDailyBackupTime;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Button, Card, CardBody, CardHeader, CardTitle, Logo } from "@immich/ui";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<Card>
|
|
6
|
+
<CardHeader>
|
|
7
|
+
<CardTitle>Install FUTO Backups</CardTitle>
|
|
8
|
+
</CardHeader>
|
|
9
|
+
<CardBody>
|
|
10
|
+
<Button variant="outline" size="small">
|
|
11
|
+
<Logo variant="icon" size="tiny" />
|
|
12
|
+
Setup on Immich
|
|
13
|
+
</Button>
|
|
14
|
+
</CardBody>
|
|
15
|
+
</Card>
|
|
@@ -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 DashboardInstall: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type DashboardInstall = InstanceType<typeof DashboardInstall>;
|
|
18
|
+
export default DashboardInstall;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardBody,
|
|
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,
|
|
19
|
+
mdiHistory,
|
|
20
|
+
} from "@mdi/js";
|
|
21
|
+
import RelativeTime from "../util/RelativeTime.svelte";
|
|
22
|
+
import MetricsHistoryModal from "../backups/metrics-history/MetricsHistoryModal.svelte";
|
|
23
|
+
|
|
24
|
+
type Props = {
|
|
25
|
+
repositories: LocalRepositoryDto[];
|
|
26
|
+
local?: boolean;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const { repositories, local }: Props = $props();
|
|
30
|
+
|
|
31
|
+
const recentAttempts = $derived(
|
|
32
|
+
repositories
|
|
33
|
+
.filter((repo) => repo.metrics.lastBackup)
|
|
34
|
+
.toSorted(
|
|
35
|
+
(a, b) =>
|
|
36
|
+
+new Date(b.metrics.lastBackup!) - +new Date(a.metrics.lastBackup!),
|
|
37
|
+
)
|
|
38
|
+
.slice(0, 5),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const getActions = (repository: LocalRepositoryDto): ActionItem[] => [
|
|
42
|
+
{
|
|
43
|
+
title: "View history",
|
|
44
|
+
icon: mdiHistory,
|
|
45
|
+
onAction: () =>
|
|
46
|
+
void modalManager.open(MetricsHistoryModal, { repository }),
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<Card>
|
|
52
|
+
<CardHeader>
|
|
53
|
+
<CardTitle>Recent Backups</CardTitle>
|
|
54
|
+
</CardHeader>
|
|
55
|
+
<CardBody>
|
|
56
|
+
{#if recentAttempts.length === 0}
|
|
57
|
+
<Text color="secondary">
|
|
58
|
+
Completed backups will appear here once your first backup runs.
|
|
59
|
+
</Text>
|
|
60
|
+
{:else}
|
|
61
|
+
<div>
|
|
62
|
+
{#each recentAttempts as repo, index (repo.id)}
|
|
63
|
+
{#if index > 0}
|
|
64
|
+
<hr
|
|
65
|
+
style="border: none; border-top: 1px solid var(--immich-ui-default-border);"
|
|
66
|
+
/>
|
|
67
|
+
{/if}
|
|
68
|
+
<HStack class="justify-between py-2">
|
|
69
|
+
<HStack class="gap-2">
|
|
70
|
+
{#if repo.metrics.lastBackup === repo.metrics.lastSuccessfulBackup}
|
|
71
|
+
<Icon
|
|
72
|
+
icon={mdiCheckCircleOutline}
|
|
73
|
+
size="16"
|
|
74
|
+
class="text-success-500"
|
|
75
|
+
/>
|
|
76
|
+
{:else}
|
|
77
|
+
<Icon
|
|
78
|
+
icon={mdiAlertCircleOutline}
|
|
79
|
+
size="16"
|
|
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>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repositories: LocalRepositoryDto[];
|
|
4
|
+
local?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare const DashboardRecentBackups: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type DashboardRecentBackups = ReturnType<typeof DashboardRecentBackups>;
|
|
8
|
+
export default DashboardRecentBackups;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
3
|
+
import { Card, CardBody, getByteUnitString } from "@immich/ui";
|
|
4
|
+
import VisualisationGauge from "../ui/VisualisationGauge.svelte";
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
repositories: LocalRepositoryDto[];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const { repositories }: Props = $props();
|
|
11
|
+
|
|
12
|
+
const totalStored = $derived(
|
|
13
|
+
repositories.reduce(
|
|
14
|
+
(sum, repo) => sum + (repo.metrics?.sizeBytes ?? 0),
|
|
15
|
+
0,
|
|
16
|
+
),
|
|
17
|
+
);
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<Card>
|
|
21
|
+
<CardBody>
|
|
22
|
+
<VisualisationGauge
|
|
23
|
+
title="Total Stored"
|
|
24
|
+
content={getByteUnitString(totalStored)}
|
|
25
|
+
/>
|
|
26
|
+
</CardBody>
|
|
27
|
+
</Card>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LocalRepositoryDto } from "../../fetch-client";
|
|
2
|
+
type Props = {
|
|
3
|
+
repositories: LocalRepositoryDto[];
|
|
4
|
+
};
|
|
5
|
+
declare const DashboardTotalStored: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type DashboardTotalStored = ReturnType<typeof DashboardTotalStored>;
|
|
7
|
+
export default DashboardTotalStored;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ImmichManageBackup from "./ImmichManageBackup.svelte";
|
|
3
|
+
import ImmichOnboardingSetupFlow from "./ImmichOnboardingSetupFlow.svelte";
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
onExit: () => void;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const { onExit }: Props = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<ImmichOnboardingSetupFlow {onExit}>
|
|
13
|
+
<ImmichManageBackup />
|
|
14
|
+
</ImmichOnboardingSetupFlow>
|