@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.
Files changed (156) hide show
  1. package/dist/components/backends/BackendItem.svelte +28 -24
  2. package/dist/components/backends/BackendsList.svelte +33 -34
  3. package/dist/components/backends/BackendsList.svelte.d.ts +1 -0
  4. package/dist/components/backends/dialogs/SelectBackendModal.svelte +44 -55
  5. package/dist/components/backups/BackupItem.svelte +33 -26
  6. package/dist/components/backups/BackupStatus.svelte +200 -0
  7. package/dist/components/backups/BackupStatus.svelte.d.ts +19 -0
  8. package/dist/components/backups/BackupsList.svelte +17 -11
  9. package/dist/components/backups/dialogs/RestoreSnapshotModal.svelte +2 -2
  10. package/dist/components/backups/dialogs/SelectRepositoryModal.svelte +26 -36
  11. package/dist/components/backups/dialogs/ViewStatusModal.svelte +175 -0
  12. package/dist/components/backups/dialogs/ViewStatusModal.svelte.d.ts +8 -0
  13. package/dist/components/backups/run-history/RepositoryRunHistory.svelte +22 -10
  14. package/dist/components/backups/run-history/RepositoryRunHistory.svelte.d.ts +2 -0
  15. package/dist/components/backups/run-history/RepositoryRunHistoryItem.svelte +46 -20
  16. package/dist/components/backups/run-history/RepositoryRunHistoryPage.svelte +135 -0
  17. package/dist/components/backups/run-history/RepositoryRunHistoryPage.svelte.d.ts +8 -0
  18. package/dist/components/backups/run-history/RunHistoryModal.svelte +2 -2
  19. package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte +22 -10
  20. package/dist/components/backups/snapshots-list/RepositorySnapshotsList.svelte.d.ts +2 -0
  21. package/dist/components/backups/snapshots-list/RepositorySnapshotsListItem.svelte +23 -21
  22. package/dist/components/backups/snapshots-list/RepositorySnapshotsPage.svelte +115 -0
  23. package/dist/components/backups/snapshots-list/RepositorySnapshotsPage.svelte.d.ts +9 -0
  24. package/dist/components/backups/snapshots-list/SnapshotsListModal.svelte +2 -2
  25. package/dist/components/dashboard/Dashboard.svelte +14 -7
  26. package/dist/components/dashboard/Dashboard.svelte.d.ts +1 -1
  27. package/dist/components/dashboard/DashboardAvgBackupTime.svelte +1 -1
  28. package/dist/components/dashboard/DashboardBackupHealth.svelte +5 -9
  29. package/dist/components/dashboard/DashboardBackupHealth.svelte.d.ts +1 -1
  30. package/dist/components/dashboard/DashboardCurrentUsage.svelte +1 -1
  31. package/dist/components/dashboard/DashboardDailyBackupTime.svelte +1 -1
  32. package/dist/components/dashboard/DashboardInstall.svelte +1 -1
  33. package/dist/components/dashboard/DashboardRecentBackups.svelte +47 -78
  34. package/dist/components/dashboard/DashboardTotalStored.svelte +1 -1
  35. package/dist/components/integrations/immich/ImmichBackupSettings.svelte +12 -0
  36. package/dist/components/integrations/immich/ImmichBackupSettings.svelte.d.ts +18 -0
  37. package/dist/components/integrations/immich/ImmichBackupsCard.svelte +73 -0
  38. package/dist/components/integrations/immich/ImmichBackupsCard.svelte.d.ts +12 -0
  39. package/dist/components/integrations/immich/ImmichBackupsNavButton.svelte +55 -0
  40. package/dist/components/integrations/immich/ImmichBackupsNavButton.svelte.d.ts +10 -0
  41. package/dist/components/integrations/immich/ImmichBackupsPage.svelte +15 -3
  42. package/dist/components/integrations/immich/ImmichBackupsPage.svelte.d.ts +7 -1
  43. package/dist/components/integrations/immich/ImmichBackupsSidebarItem.svelte +66 -0
  44. package/dist/components/integrations/immich/ImmichBackupsSidebarItem.svelte.d.ts +8 -0
  45. package/dist/components/integrations/immich/ImmichManageBackup.svelte +53 -14
  46. package/dist/components/integrations/immich/ImmichManageBackupOverview.svelte +45 -71
  47. package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte +123 -82
  48. package/dist/components/integrations/immich/ImmichOnboardingSetupFlow.svelte.d.ts +1 -1
  49. package/dist/components/integrations/immich/settings/ImmichSettingsBackupContents.svelte +313 -0
  50. package/dist/components/integrations/immich/settings/ImmichSettingsBackupContents.svelte.d.ts +3 -0
  51. package/dist/components/integrations/immich/settings/ImmichSettingsSchedule.svelte +218 -0
  52. package/dist/components/integrations/immich/settings/ImmichSettingsSchedule.svelte.d.ts +3 -0
  53. package/dist/components/integrations/immich/settings/ImmichSettingsStorage.svelte +207 -0
  54. package/dist/components/integrations/immich/settings/ImmichSettingsStorage.svelte.d.ts +3 -0
  55. package/dist/components/onboarding/RecoveryKeyDisplay.svelte +34 -20
  56. package/dist/components/onboarding/SampleOnboarding.svelte +57 -38
  57. package/dist/components/onboarding/stages/OnboardingStageBackupServices.svelte +10 -24
  58. package/dist/components/onboarding/steps/OnboardingStep1FinishSetup.svelte +44 -0
  59. package/dist/components/onboarding/steps/OnboardingStep1FinishSetup.svelte.d.ts +7 -0
  60. package/dist/components/onboarding/steps/OnboardingStep2ConnectAccount.svelte +50 -0
  61. package/dist/components/onboarding/steps/OnboardingStep2ConnectAccount.svelte.d.ts +7 -0
  62. package/dist/components/onboarding/steps/OnboardingStep3SaveRecoveryKey.svelte +45 -0
  63. package/dist/components/onboarding/steps/OnboardingStep3SaveRecoveryKey.svelte.d.ts +8 -0
  64. package/dist/components/onboarding/steps/OnboardingStep4FirstBackup.svelte +67 -0
  65. package/dist/components/onboarding/steps/OnboardingStep4FirstBackup.svelte.d.ts +9 -0
  66. package/dist/components/onboarding/steps/OnboardingStepLayout.svelte +58 -0
  67. package/dist/components/onboarding/steps/OnboardingStepLayout.svelte.d.ts +19 -0
  68. package/dist/components/onboarding/upsell/UpsellBackupFeaturesGrid.svelte +52 -0
  69. package/dist/components/onboarding/upsell/UpsellBackupFeaturesGrid.svelte.d.ts +18 -0
  70. package/dist/components/onboarding/upsell/UpsellExplainFutoBackups.svelte +33 -0
  71. package/dist/components/onboarding/upsell/UpsellExplainFutoBackups.svelte.d.ts +8 -0
  72. package/dist/components/onboarding/upsell/UpsellFrequentlyAskedQuestions.svelte +27 -0
  73. package/dist/components/onboarding/upsell/UpsellFrequentlyAskedQuestions.svelte.d.ts +10 -0
  74. package/dist/components/onboarding/upsell/UpsellFutoBackupsBadge.svelte +7 -0
  75. package/dist/components/onboarding/upsell/UpsellFutoBackupsBadge.svelte.d.ts +18 -0
  76. package/dist/components/onboarding/upsell/UpsellHowItWorks.svelte +46 -0
  77. package/dist/components/onboarding/upsell/UpsellHowItWorks.svelte.d.ts +6 -0
  78. package/dist/components/onboarding/upsell/UpsellModal.svelte +43 -0
  79. package/dist/components/onboarding/upsell/UpsellModal.svelte.d.ts +9 -0
  80. package/dist/components/onboarding/upsell/UpsellPage.svelte +39 -0
  81. package/dist/components/onboarding/upsell/UpsellPage.svelte.d.ts +13 -0
  82. package/dist/components/onboarding/upsell/UpsellProtectYourImmichLibrary.svelte +58 -0
  83. package/dist/components/onboarding/upsell/UpsellProtectYourImmichLibrary.svelte.d.ts +8 -0
  84. package/dist/components/schedules/RepositoryPicker.svelte +45 -38
  85. package/dist/components/schedules/ScheduleItem.svelte +32 -26
  86. package/dist/components/schedules/ScheduleList.svelte +16 -10
  87. package/dist/components/settings/GlobalSettings.svelte +8 -0
  88. package/dist/components/settings/GlobalSettings.svelte.d.ts +18 -0
  89. package/dist/components/settings/SettingsBackends.svelte +16 -0
  90. package/dist/components/settings/SettingsBackends.svelte.d.ts +18 -0
  91. package/dist/components/settings/SettingsBilling.svelte +69 -0
  92. package/dist/components/settings/SettingsBilling.svelte.d.ts +6 -0
  93. package/dist/components/settings/SettingsNotifications.svelte +47 -0
  94. package/dist/components/settings/SettingsNotifications.svelte.d.ts +6 -0
  95. package/dist/components/test/ImmichTestUi.svelte +129 -27
  96. package/dist/components/test/TestUi.svelte +4 -4
  97. package/dist/components/test/dashboard/ActiveJobs.svelte +2 -2
  98. package/dist/components/test/immich/MockImmichPhotos.svelte +36 -0
  99. package/dist/components/test/immich/MockImmichPhotos.svelte.d.ts +18 -0
  100. package/dist/components/test/immich/MockImmichPurchaseInfo.svelte +29 -0
  101. package/dist/components/test/immich/MockImmichPurchaseInfo.svelte.d.ts +18 -0
  102. package/dist/components/test/immich/MockImmichStorageSpace.svelte +37 -0
  103. package/dist/components/test/immich/MockImmichStorageSpace.svelte.d.ts +6 -0
  104. package/dist/components/ui/Accordion.svelte +67 -0
  105. package/dist/components/ui/Accordion.svelte.d.ts +11 -0
  106. package/dist/components/ui/ListToolbar.svelte +60 -0
  107. package/dist/components/ui/ListToolbar.svelte.d.ts +16 -0
  108. package/dist/components/ui/PageLayout.svelte +21 -9
  109. package/dist/components/ui/PageLayout.svelte.d.ts +1 -0
  110. package/dist/components/ui/Pagination.svelte +80 -0
  111. package/dist/components/ui/Pagination.svelte.d.ts +8 -0
  112. package/dist/components/ui/PathListField.svelte +17 -14
  113. package/dist/components/ui/StackList.svelte +18 -18
  114. package/dist/components/ui/StackList.svelte.d.ts +6 -27
  115. package/dist/components/ui/StackListItem.svelte +47 -25
  116. package/dist/components/ui/StackListItem.svelte.d.ts +5 -2
  117. package/dist/components/ui/StackListOption.svelte +33 -0
  118. package/dist/components/ui/StackListOption.svelte.d.ts +11 -0
  119. package/dist/components/ui/StackListPlaceholder.svelte +12 -0
  120. package/dist/components/ui/StackListPlaceholder.svelte.d.ts +7 -0
  121. package/dist/components/ui/StepNumber.svelte +20 -0
  122. package/dist/components/ui/StepNumber.svelte.d.ts +7 -0
  123. package/dist/components/util/Suspense.svelte +7 -3
  124. package/dist/components/util/YuccaContext.svelte +1 -1
  125. package/dist/events.js +1 -1
  126. package/dist/fetch-client.d.ts +2 -0
  127. package/dist/index.d.ts +6 -1
  128. package/dist/index.js +6 -1
  129. package/dist/services/backend.service.js +3 -0
  130. package/dist/services/immich.integration.service.d.ts +1 -1
  131. package/dist/services/immich.integration.service.js +2 -3
  132. package/dist/services/integrations.service.d.ts +1 -0
  133. package/dist/services/integrations.service.js +2 -1
  134. package/dist/services/log.service.svelte.d.ts +12 -0
  135. package/dist/services/log.service.svelte.js +15 -1
  136. package/dist/services/repository.service.js +9 -3
  137. package/dist/services/runHistory.service.js +2 -2
  138. package/dist/utils/format.d.ts +1 -1
  139. package/dist/utils/format.js +2 -2
  140. package/package.json +3 -3
  141. package/dist/components/backups/dialogs/ViewLogModal.svelte +0 -208
  142. package/dist/components/backups/dialogs/ViewLogModal.svelte.d.ts +0 -7
  143. package/dist/components/integrations/immich/ImmichConfigureBackup.svelte +0 -403
  144. package/dist/components/integrations/immich/ImmichConfigureBackup.svelte.d.ts +0 -9
  145. package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte +0 -80
  146. package/dist/components/integrations/immich/ImmichConfirmDefaultBackup.svelte.d.ts +0 -8
  147. package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte +0 -56
  148. package/dist/components/onboarding/stages/OnboardingStageKeyConfirm.svelte.d.ts +0 -9
  149. package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte +0 -50
  150. package/dist/components/onboarding/stages/OnboardingStageKeyIntro.svelte.d.ts +0 -7
  151. package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte +0 -44
  152. package/dist/components/onboarding/stages/OnboardingStageKeySave.svelte.d.ts +0 -8
  153. package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte +0 -56
  154. package/dist/components/onboarding/stages/OnboardingStageWelcome.svelte.d.ts +0 -9
  155. package/dist/components/util/TimedButton.svelte +0 -37
  156. package/dist/components/util/TimedButton.svelte.d.ts +0 -7
@@ -1,43 +1,69 @@
1
1
  <script lang="ts">
2
2
  import { hasActions } from "../../utils/actions";
3
- import { ContextMenuButton, HStack, type ActionItem } from "@immich/ui";
3
+ import {
4
+ ContextMenuButton,
5
+ HStack,
6
+ Stack,
7
+ Text,
8
+ type ActionItem,
9
+ } from "@immich/ui";
4
10
  import { mdiDotsVertical } from "@mdi/js";
5
11
  import type { Snippet } from "svelte";
6
12
 
13
+ type Color = "primary" | "success" | "warning" | "danger";
14
+
7
15
  type Props = {
8
16
  class?: string;
17
+ title?: string;
18
+ color?: Color;
9
19
  icon?: Snippet;
10
20
  children: Snippet;
11
21
  trailing?: Snippet;
22
+ footer?: Snippet;
23
+ footerColor?: Color;
12
24
  actions?: ActionItem[];
13
- disabled?: boolean;
14
- onclick?: () => void;
15
25
  };
16
26
 
17
27
  const {
18
28
  class: className,
29
+ title,
30
+ color = "primary",
19
31
  icon,
20
32
  children,
21
33
  trailing,
34
+ footer,
35
+ footerColor = "primary",
22
36
  actions = [],
23
- disabled = false,
24
- onclick,
25
37
  }: Props = $props();
38
+
39
+ const tints: Record<Color, string> = {
40
+ primary: "bg-primary-50 text-primary",
41
+ success: "bg-success-50 text-success-700",
42
+ warning: "bg-warning-50 text-warning-800",
43
+ danger: "bg-danger-50 text-danger-700",
44
+ };
26
45
  </script>
27
46
 
28
- {#snippet body()}
29
- <HStack gap={4} class={`${className} items-center px-4 py-3`}>
47
+ <div>
48
+ <HStack gap={4} class={`${className} items-center px-5 py-4`}>
30
49
  {#if icon}
31
50
  <div
32
- class="flex p-2 items-center justify-center rounded-lg bg-subtle text-lg"
51
+ class={`flex size-10 shrink-0 items-center justify-center rounded-lg text-xl ${tints[color]}`}
33
52
  >
34
- {@render icon?.()}
53
+ {@render icon()}
35
54
  </div>
36
55
  {/if}
37
56
 
38
- <HStack gap={1} class="flex-1 items-baseline">
39
- {@render children()}
40
- </HStack>
57
+ {#if title}
58
+ <Stack gap={0} class="flex-1 min-w-0">
59
+ <Text class="truncate">{title}</Text>
60
+ <Text size="small" color="muted">{@render children()}</Text>
61
+ </Stack>
62
+ {:else}
63
+ <HStack gap={1} class="flex-1 items-baseline">
64
+ {@render children()}
65
+ </HStack>
66
+ {/if}
41
67
 
42
68
  {@render trailing?.()}
43
69
 
@@ -51,17 +77,13 @@
51
77
  />
52
78
  {/if}
53
79
  </HStack>
54
- {/snippet}
55
80
 
56
- {#if onclick}
57
- <button
58
- {onclick}
59
- {disabled}
60
- type="button"
61
- class="block w-full text-left rounded-lg hover:bg-subtle focus-visible:outline-2 focus-visible:outline-primary-500 cursor-pointer disabled:cursor-not-allowed disabled:opacity-60"
62
- >
63
- {@render body()}
64
- </button>
65
- {:else}
66
- {@render body()}
67
- {/if}
81
+ {#if footer}
82
+ <HStack
83
+ gap={2}
84
+ class={`items-center border-t px-5 py-3 ${tints[footerColor]}`}
85
+ >
86
+ {@render footer()}
87
+ </HStack>
88
+ {/if}
89
+ </div>
@@ -1,13 +1,16 @@
1
1
  import { type ActionItem } from "@immich/ui";
2
2
  import type { Snippet } from "svelte";
3
+ type Color = "primary" | "success" | "warning" | "danger";
3
4
  type Props = {
4
5
  class?: string;
6
+ title?: string;
7
+ color?: Color;
5
8
  icon?: Snippet;
6
9
  children: Snippet;
7
10
  trailing?: Snippet;
11
+ footer?: Snippet;
12
+ footerColor?: Color;
8
13
  actions?: ActionItem[];
9
- disabled?: boolean;
10
- onclick?: () => void;
11
14
  };
12
15
  declare const StackListItem: import("svelte").Component<Props, {}, "">;
13
16
  type StackListItem = ReturnType<typeof StackListItem>;
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import { Icon } from "@immich/ui";
3
+ import { mdiChevronRight } from "@mdi/js";
4
+ import type { Snippet } from "svelte";
5
+ import StackListItem from "./StackListItem.svelte";
6
+
7
+ type Props = {
8
+ title: string;
9
+ icon?: Snippet;
10
+ children: Snippet;
11
+ disabled?: boolean;
12
+ onclick: () => void;
13
+ };
14
+
15
+ const { title, icon, children, disabled = false, onclick }: Props = $props();
16
+ </script>
17
+
18
+ <button
19
+ type="button"
20
+ {disabled}
21
+ {onclick}
22
+ class="block w-full cursor-pointer text-left hover:bg-subtle focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-primary-500 disabled:cursor-not-allowed disabled:opacity-60"
23
+ >
24
+ <StackListItem {title} {icon}>
25
+ {@render children()}
26
+
27
+ {#snippet trailing()}
28
+ {#if !disabled}
29
+ <Icon icon={mdiChevronRight} />
30
+ {/if}
31
+ {/snippet}
32
+ </StackListItem>
33
+ </button>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from "svelte";
2
+ type Props = {
3
+ title: string;
4
+ icon?: Snippet;
5
+ children: Snippet;
6
+ disabled?: boolean;
7
+ onclick: () => void;
8
+ };
9
+ declare const StackListOption: import("svelte").Component<Props, {}, "">;
10
+ type StackListOption = ReturnType<typeof StackListOption>;
11
+ export default StackListOption;
@@ -0,0 +1,12 @@
1
+ <script lang="ts">
2
+ import { Text } from "@immich/ui";
3
+ import type { Snippet } from "svelte";
4
+
5
+ type Props = {
6
+ children: Snippet;
7
+ };
8
+
9
+ const { children }: Props = $props();
10
+ </script>
11
+
12
+ <Text class="block text-center py-8" color="muted">{@render children()}</Text>
@@ -0,0 +1,7 @@
1
+ import type { Snippet } from "svelte";
2
+ type Props = {
3
+ children: Snippet;
4
+ };
5
+ declare const StackListPlaceholder: import("svelte").Component<Props, {}, "">;
6
+ type StackListPlaceholder = ReturnType<typeof StackListPlaceholder>;
7
+ export default StackListPlaceholder;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ type Props = {
3
+ step: number;
4
+ size?: "small" | "medium";
5
+ };
6
+
7
+ const { step, size = "medium" }: Props = $props();
8
+
9
+ const sizes = {
10
+ small: "size-5 text-xs",
11
+ medium: "size-8 text-lg",
12
+ };
13
+ </script>
14
+
15
+ <span
16
+ class={`bg-primary text-light flex shrink-0 items-center justify-center rounded-full tabular-nums ${sizes[size]}`}
17
+ aria-hidden="true"
18
+ >
19
+ {step}
20
+ </span>
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ step: number;
3
+ size?: "small" | "medium";
4
+ };
5
+ declare const StepNumber: import("svelte").Component<Props, {}, "">;
6
+ type StepNumber = ReturnType<typeof StepNumber>;
7
+ export default StepNumber;
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" generics="T extends object">
2
2
  import { getReadableErrorMessage } from "../../utils/handle-error";
3
- import { Alert, LoadingSpinner } from "@immich/ui";
3
+ import { Alert, HStack, LoadingSpinner } from "@immich/ui";
4
4
  import type { CreateQueryResult } from "@tanstack/svelte-query";
5
5
  import type { Snippet } from "svelte";
6
6
 
@@ -13,9 +13,13 @@
13
13
  </script>
14
14
 
15
15
  {#if query.isLoading}
16
- <LoadingSpinner />
16
+ <HStack class="justify-center p-8">
17
+ <LoadingSpinner />
18
+ </HStack>
17
19
  {:else if query.isError}
18
- <Alert color="danger">{getReadableErrorMessage(query.error)}</Alert>
20
+ <div class="p-4">
21
+ <Alert color="danger">{getReadableErrorMessage(query.error)}</Alert>
22
+ </div>
19
23
  {:else if query.isSuccess}
20
24
  {@render children(query.data)}
21
25
  {/if}
@@ -12,7 +12,7 @@
12
12
  const { baseUrl, children }: Props = $props();
13
13
 
14
14
  // svelte-ignore state_referenced_locally
15
- if (baseUrl) {
15
+ if (typeof baseUrl === "string") {
16
16
  orchestrationDefaults.baseUrl = baseUrl;
17
17
  }
18
18
 
package/dist/events.js CHANGED
@@ -10,7 +10,7 @@ export class SocketEvent extends Event {
10
10
  }
11
11
  }
12
12
  function createSocket() {
13
- socket = io(defaults.baseUrl, {
13
+ socket = io(defaults.baseUrl || undefined, {
14
14
  path: '/api/yucca/socket.io',
15
15
  transports: ['websocket'],
16
16
  autoConnect: false,
@@ -81,6 +81,7 @@ export type ConfigureImmichIntegrationRequestDto = {
81
81
  backupConfiguration: boolean;
82
82
  libraries: "all" | string[];
83
83
  retentionPolicy?: (RetentionPolicyDto) | null;
84
+ paused?: boolean;
84
85
  };
85
86
  export type ImmichRollbackRequestDto = {
86
87
  repositoryId: string;
@@ -185,6 +186,7 @@ export type RepositoryInspectResponseDto = {
185
186
  };
186
187
  export type RepositoryUpdateRequestDto = {
187
188
  name?: string;
189
+ worm?: boolean;
188
190
  paths?: string[];
189
191
  retentionPolicy?: (RetentionPolicyDto) | null;
190
192
  };
package/dist/index.d.ts CHANGED
@@ -1,13 +1,18 @@
1
1
  export { default as BackendsList } from './components/backends/BackendsList.svelte';
2
2
  export { default as BackupsList } from './components/backups/BackupsList.svelte';
3
- export { default as ViewLogModal } from './components/backups/dialogs/ViewLogModal.svelte';
3
+ export { default as ViewStatusModal } from './components/backups/dialogs/ViewStatusModal.svelte';
4
4
  export { default as Dashboard } from './components/dashboard/Dashboard.svelte';
5
+ export { default as ImmichBackupsNavButton } from './components/integrations/immich/ImmichBackupsNavButton.svelte';
5
6
  export { default as ImmichBackupsPage } from './components/integrations/immich/ImmichBackupsPage.svelte';
7
+ export { default as ImmichBackupsSidebarItem } from './components/integrations/immich/ImmichBackupsSidebarItem.svelte';
6
8
  export { default as ImmichManageBackup } from './components/integrations/immich/ImmichManageBackup.svelte';
7
9
  export { default as ImmichOnboardingRestoreFlow } from './components/integrations/immich/ImmichOnboardingRestoreFlow.svelte';
8
10
  export { default as ImmichOnboardingSetupFlow } from './components/integrations/immich/ImmichOnboardingSetupFlow.svelte';
9
11
  export { default as OnboardingGate } from './components/onboarding/OnboardingGate.svelte';
12
+ export { default as UpsellModal } from './components/onboarding/upsell/UpsellModal.svelte';
13
+ export { default as UpsellPage } from './components/onboarding/upsell/UpsellPage.svelte';
10
14
  export { default as ScheduleList } from './components/schedules/ScheduleList.svelte';
15
+ export { default as GlobalSettings } from './components/settings/GlobalSettings.svelte';
11
16
  export { default as VisualisationGauge } from './components/ui/VisualisationGauge.svelte';
12
17
  export { default as VisualisationSegmentedBar } from './components/ui/VisualisationSegmentedBar.svelte';
13
18
  export { default as OnEvents } from './components/util/OnEvents.svelte';
package/dist/index.js CHANGED
@@ -1,13 +1,18 @@
1
1
  export { default as BackendsList } from './components/backends/BackendsList.svelte';
2
2
  export { default as BackupsList } from './components/backups/BackupsList.svelte';
3
- export { default as ViewLogModal } from './components/backups/dialogs/ViewLogModal.svelte';
3
+ export { default as ViewStatusModal } from './components/backups/dialogs/ViewStatusModal.svelte';
4
4
  export { default as Dashboard } from './components/dashboard/Dashboard.svelte';
5
+ export { default as ImmichBackupsNavButton } from './components/integrations/immich/ImmichBackupsNavButton.svelte';
5
6
  export { default as ImmichBackupsPage } from './components/integrations/immich/ImmichBackupsPage.svelte';
7
+ export { default as ImmichBackupsSidebarItem } from './components/integrations/immich/ImmichBackupsSidebarItem.svelte';
6
8
  export { default as ImmichManageBackup } from './components/integrations/immich/ImmichManageBackup.svelte';
7
9
  export { default as ImmichOnboardingRestoreFlow } from './components/integrations/immich/ImmichOnboardingRestoreFlow.svelte';
8
10
  export { default as ImmichOnboardingSetupFlow } from './components/integrations/immich/ImmichOnboardingSetupFlow.svelte';
9
11
  export { default as OnboardingGate } from './components/onboarding/OnboardingGate.svelte';
12
+ export { default as UpsellModal } from './components/onboarding/upsell/UpsellModal.svelte';
13
+ export { default as UpsellPage } from './components/onboarding/upsell/UpsellPage.svelte';
10
14
  export { default as ScheduleList } from './components/schedules/ScheduleList.svelte';
15
+ export { default as GlobalSettings } from './components/settings/GlobalSettings.svelte';
11
16
  export { default as VisualisationGauge } from './components/ui/VisualisationGauge.svelte';
12
17
  export { default as VisualisationSegmentedBar } from './components/ui/VisualisationSegmentedBar.svelte';
13
18
  export { default as OnEvents } from './components/util/OnEvents.svelte';
@@ -23,8 +23,11 @@ export const useDeviceFlow = (uid) => createQuery(() => ({
23
23
  window.open(response.verificationUri, '_blank');
24
24
  return response;
25
25
  },
26
+ gcTime: Infinity,
27
+ retry: 0,
26
28
  refetchOnReconnect: false,
27
29
  refetchOnWindowFocus: false,
30
+ refetchOnMount: true,
28
31
  }), () => queryClient);
29
32
  export const useBackendEventHandler = () => {
30
33
  return {
@@ -1,5 +1,5 @@
1
1
  import { type ActionItem } from '@immich/ui';
2
- export declare const getBackupPageActions: (repositoryId?: string) => {
2
+ export declare const getBackupPageActions: (repositoryId: string | undefined, onConfigure: () => void) => {
3
3
  Configure: ActionItem;
4
4
  ViewRecoveryKey: ActionItem;
5
5
  BackUpNow: ActionItem;
@@ -1,13 +1,12 @@
1
- import ImmichConfigureBackup from '../components/integrations/immich/ImmichConfigureBackup.svelte';
2
1
  import BackupsRecoveryKeyModal from '../components/onboarding/dialogs/BackupsRecoveryKeyModal.svelte';
3
2
  import { modalManager } from '@immich/ui';
4
3
  import { mdiCloudUploadOutline, mdiCogOutline, mdiKeyOutline } from '@mdi/js';
5
4
  import { handleCreateBackup } from './repository.service';
6
- export const getBackupPageActions = (repositoryId) => {
5
+ export const getBackupPageActions = (repositoryId, onConfigure) => {
7
6
  const Configure = {
8
7
  title: 'Configure',
9
8
  icon: mdiCogOutline,
10
- onAction: () => modalManager.show(ImmichConfigureBackup, {}),
9
+ onAction: onConfigure,
11
10
  };
12
11
  const ViewRecoveryKey = {
13
12
  title: 'View recovery key',
@@ -1,5 +1,6 @@
1
1
  import { SocketEvent } from '../events';
2
2
  import { type ConfigureImmichIntegrationRequestDto, type IntegrationsResponseDto } from '../fetch-client';
3
+ export declare const IMMICH_DEFAULT_CRON = "0 3 * * *";
3
4
  export declare const integrationsKeys: {
4
5
  all: readonly ["integrations"];
5
6
  };
@@ -3,6 +3,7 @@ import { configureImmichIntegration, getIntegrations, } from '../fetch-client';
3
3
  import { queryClient } from '../query-client';
4
4
  import { handleError } from '../utils/handle-error';
5
5
  import { createMutation, createQuery } from '@tanstack/svelte-query';
6
+ export const IMMICH_DEFAULT_CRON = '0 3 * * *';
6
7
  export const integrationsKeys = {
7
8
  all: ['integrations'],
8
9
  };
@@ -28,7 +29,7 @@ export const useConfigureImmichDefaults = () => createMutation(() => ({
28
29
  await configureImmichIntegration({
29
30
  name: 'Immich',
30
31
  worm: false,
31
- cron: '0 3 * * *',
32
+ cron: IMMICH_DEFAULT_CRON,
32
33
  dataFolders: immichState.dataFolders,
33
34
  backupConfiguration: true,
34
35
  libraries: 'all',
@@ -32,6 +32,14 @@ type LogEvent = SummaryEvent | {
32
32
  } | {
33
33
  message_type: 'raw';
34
34
  message: string;
35
+ } | {
36
+ message_type: 'yucca_prune_kept';
37
+ id: string;
38
+ time: string;
39
+ } | {
40
+ message_type: 'yucca_prune_removed';
41
+ id: string;
42
+ time: string;
35
43
  } | {
36
44
  message_type: 'status';
37
45
  percent_done: number;
@@ -50,6 +58,10 @@ export declare function createLogObserver(logId: string): {
50
58
  readonly errors: string[];
51
59
  readonly events: LogEvent[];
52
60
  readonly summary: SummaryEvent | undefined;
61
+ readonly pruned: {
62
+ kept: number;
63
+ removed: number;
64
+ };
53
65
  destroy(): void;
54
66
  };
55
67
  export {};
@@ -18,6 +18,7 @@ export function createLogObserver(logId) {
18
18
  errors: [],
19
19
  events: [],
20
20
  summary: undefined,
21
+ pruned: { kept: 0, removed: 0 },
21
22
  });
22
23
  const buffer = [];
23
24
  const flush = debounce(() => {
@@ -68,13 +69,23 @@ export function createLogObserver(logId) {
68
69
  flush.flush();
69
70
  break;
70
71
  }
72
+ case 'yucca_prune_kept': {
73
+ state.pruned.kept++;
74
+ flush();
75
+ break;
76
+ }
77
+ case 'yucca_prune_removed': {
78
+ state.pruned.removed++;
79
+ flush();
80
+ break;
81
+ }
71
82
  default: {
72
83
  flush();
73
84
  break;
74
85
  }
75
86
  }
76
87
  };
77
- const source = new EventSource(new URL(`/api/yucca/logs/${logId}/stream`, defaults.baseUrl));
88
+ const source = new EventSource(`${defaults.baseUrl}/api/yucca/logs/${logId}/stream`);
78
89
  source.addEventListener('message', ({ data }) => onEvent(JSON.parse(data)));
79
90
  return {
80
91
  get status() {
@@ -89,6 +100,9 @@ export function createLogObserver(logId) {
89
100
  get summary() {
90
101
  return state.summary;
91
102
  },
103
+ get pruned() {
104
+ return state.pruned;
105
+ },
92
106
  destroy() {
93
107
  flush.cancel();
94
108
  source.close();
@@ -1,7 +1,7 @@
1
1
  import { sdk } from '..';
2
2
  import ConfigureRepositoryModal from '../components/backups/dialogs/ConfigureRepositoryModal.svelte';
3
3
  import ImportRepositoryModal from '../components/backups/dialogs/ImportRepositoryModal.svelte';
4
- import ViewLogModal from '../components/backups/dialogs/ViewLogModal.svelte';
4
+ import ViewStatusModal from '../components/backups/dialogs/ViewStatusModal.svelte';
5
5
  import MetricsHistoryModal from '../components/backups/metrics-history/MetricsHistoryModal.svelte';
6
6
  import RunHistoryModal from '../components/backups/run-history/RunHistoryModal.svelte';
7
7
  import SnapshotsListModal from '../components/backups/snapshots-list/SnapshotsListModal.svelte';
@@ -84,7 +84,10 @@ export const handleCreateBackup = async (id) => {
84
84
  try {
85
85
  toastManager.info('Started backup');
86
86
  const response = await sdk.createBackup(id);
87
- void modalManager.open(ViewLogModal, { logId: response.logId });
87
+ void modalManager.open(ViewStatusModal, {
88
+ logId: response.logId,
89
+ onRetry: () => void handleCreateBackup(id),
90
+ });
88
91
  return response;
89
92
  }
90
93
  catch (error) {
@@ -96,7 +99,10 @@ export const handlePruneRepository = async (id) => {
96
99
  try {
97
100
  toastManager.info('Cleaning up old backups');
98
101
  const response = await sdk.pruneRepository(id);
99
- void modalManager.open(ViewLogModal, { logId: response.logId });
102
+ void modalManager.open(ViewStatusModal, {
103
+ logId: response.logId,
104
+ onRetry: () => void handlePruneRepository(id),
105
+ });
100
106
  return response;
101
107
  }
102
108
  catch (error) {
@@ -1,5 +1,5 @@
1
1
  import { sdk } from '..';
2
- import ViewLogModal from '../components/backups/dialogs/ViewLogModal.svelte';
2
+ import ViewStatusModal from '../components/backups/dialogs/ViewStatusModal.svelte';
3
3
  import { SocketEvent } from '../events';
4
4
  import { getRun, getRunHistory } from '../fetch-client';
5
5
  import { queryClient } from '../query-client';
@@ -48,7 +48,7 @@ export const handleGetRunHistory = async (id) => {
48
48
  export const getRunActions = (run) => {
49
49
  const ViewLog = {
50
50
  title: 'View Log',
51
- onAction: () => void modalManager.open(ViewLogModal, { logId: run.id }),
51
+ onAction: () => void modalManager.open(ViewStatusModal, { logId: run.id }),
52
52
  };
53
53
  return { ViewLog };
54
54
  };
@@ -1,2 +1,2 @@
1
- export declare const formatDuration: (ms: number) => string;
1
+ export declare const formatDuration: (ms: number, unitDisplay?: "narrow" | "long") => string;
2
2
  export declare const humanizeBackupPath: (path: string) => string;
@@ -1,11 +1,11 @@
1
1
  import { Duration } from 'luxon';
2
- export const formatDuration = (ms) => {
2
+ export const formatDuration = (ms, unitDisplay = 'narrow') => {
3
3
  const seconds = Math.round(ms / 1000);
4
4
  return seconds < 1
5
5
  ? '<1s'
6
6
  : Duration.fromMillis(seconds * 1000)
7
7
  .rescale()
8
- .toHuman({ unitDisplay: 'narrow' });
8
+ .toHuman({ unitDisplay });
9
9
  };
10
10
  const IMMICH_FOLDER_LABELS = {
11
11
  upload: 'Photos and videos',
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@futo-org/backups-orchestrator-ui",
3
3
  "repository": "https://github.com/immich-app/yucca",
4
4
  "description": "Backups orchestrator (UI library)",
5
- "version": "0.27.0",
5
+ "version": "0.28.0",
6
6
  "license": "Source First License 1.1",
7
7
  "files": [
8
8
  "dist",
@@ -55,7 +55,7 @@
55
55
  "svelte"
56
56
  ],
57
57
  "dependencies": {
58
- "@immich/ui": "^0.59.0",
58
+ "@immich/ui": "^0.85.0",
59
59
  "@mdi/js": "^7.4.47",
60
60
  "@oazapfts/runtime": "^1.1.0",
61
61
  "@tanstack/svelte-query": "^6.1.3",
@@ -64,7 +64,7 @@
64
64
  "lodash.debounce": "^4.0.8",
65
65
  "luxon": "^3.7.2",
66
66
  "socket.io-client": "^4.8.3",
67
- "@futo-org/backups-api-client": "^0.27.0"
67
+ "@futo-org/backups-api-client": "^0.28.0"
68
68
  },
69
69
  "scripts": {
70
70
  "dev": "vite dev --port 5174",