diff --git a/ui/v2.5/src/components/Setup/Setup.tsx b/ui/v2.5/src/components/Setup/Setup.tsx
index 9168907949e..1f8ec4614a4 100644
--- a/ui/v2.5/src/components/Setup/Setup.tsx
+++ b/ui/v2.5/src/components/Setup/Setup.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useContext } from "react";
+import React, { useState, useContext, useCallback } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import {
Alert,
@@ -29,45 +29,55 @@ import {
import { releaseNotes } from "src/docs/en/ReleaseNotes";
import { ExternalLink } from "../Shared/ExternalLink";
-export const Setup: React.FC = () => {
- const { configuration, loading: configLoading } =
- useContext(ConfigurationContext);
- const [saveUI] = useConfigureUI();
+interface ISetupContextState {
+ configuration: GQL.ConfigDataFragment;
+ systemStatus: GQL.SystemStatusQuery;
- const [step, setStep] = useState(0);
- const [setupInWorkDir, setSetupInWorkDir] = useState(false);
- const [stashes, setStashes] = useState([]);
- const [showStashAlert, setShowStashAlert] = useState(false);
- const [databaseFile, setDatabaseFile] = useState("");
- const [generatedLocation, setGeneratedLocation] = useState("");
- const [cacheLocation, setCacheLocation] = useState("");
- const [storeBlobsInDatabase, setStoreBlobsInDatabase] = useState(false);
- const [blobsLocation, setBlobsLocation] = useState("");
- const [loading, setLoading] = useState(false);
- const [setupError, setSetupError] = useState();
- const [downloadFFmpeg, setDownloadFFmpeg] = useState(true);
+ setupState: Partial;
+ setupError: string | undefined;
- const intl = useIntl();
- const history = useHistory();
+ pathJoin: (...paths: string[]) => string;
+ pathDir(path: string): string;
- const [showGeneratedSelectDialog, setShowGeneratedSelectDialog] =
- useState(false);
- const [showCacheSelectDialog, setShowCacheSelectDialog] = useState(false);
- const [showBlobsDialog, setShowBlobsDialog] = useState(false);
+ homeDir: string;
+ windows: boolean;
+ macApp: boolean;
+ homeDirPath: string;
+ pwd: string;
+ workingDir: string;
+}
- const { data: systemStatus, loading: statusLoading } = useSystemStatus();
- const status = systemStatus?.systemStatus;
+const SetupStateContext = React.createContext(null);
- const [mutateDownloadFFMpeg] = GQL.useDownloadFfMpegMutation();
+const useSetupContext = () => {
+ const context = React.useContext(SetupStateContext);
+
+ if (context === null) {
+ throw new Error("useSettings must be used within a SettingsContext");
+ }
+
+ return context;
+};
+
+const SetupContext: React.FC<{
+ setupState: Partial;
+ setupError: string | undefined;
+ systemStatus: GQL.SystemStatusQuery;
+ configuration: GQL.ConfigDataFragment;
+}> = ({ setupState, setupError, systemStatus, configuration, children }) => {
+ const status = systemStatus?.systemStatus;
const windows = status?.os === "windows";
const pathSep = windows ? "\\" : "/";
const homeDir = windows ? "%USERPROFILE%" : "$HOME";
const pwd = windows ? "%CD%" : "$PWD";
- function pathJoin(...paths: string[]) {
- return paths.join(pathSep);
- }
+ const pathJoin = useCallback(
+ (...paths: string[]) => {
+ return paths.join(pathSep);
+ },
+ [pathSep]
+ );
// simply returns everything preceding the last path separator
function pathDir(path: string) {
@@ -83,528 +93,877 @@ export const Setup: React.FC = () => {
// so in this situation disallow setting up in the working directory.
const macApp = status?.os === "darwin" && workingDir === "/";
- const fallbackStashDir = pathJoin(homeDir, ".stash");
- const fallbackConfigPath = pathJoin(fallbackStashDir, "config.yml");
+ const homeDirPath = pathJoin(status?.homeDir ?? homeDir, ".stash");
+
+ const state: ISetupContextState = {
+ systemStatus,
+ configuration,
+ windows,
+ macApp,
+ pathJoin,
+ pathDir,
+ homeDir,
+ homeDirPath,
+ pwd,
+ workingDir,
+ setupState,
+ setupError,
+ };
- const overrideConfig = status?.configPath;
- const overrideGenerated = configuration?.general.generatedPath;
- const overrideCache = configuration?.general.cachePath;
- const overrideBlobs = configuration?.general.blobsPath;
- const overrideDatabase = configuration?.general.databasePath;
+ return (
+
+ {children}
+
+ );
+};
- useEffect(() => {
- if (configuration) {
- const configStashes = configuration.general.stashes;
- if (configStashes.length > 0) {
- setStashes(
- configStashes.map((s) => {
- const { __typename, ...withoutTypename } = s;
- return withoutTypename;
- })
- );
- }
- }
- }, [configuration]);
+interface IWizardStep {
+ next: (input?: Partial) => void;
+ goBack: () => void;
+}
- const discordLink = (
- Discord
- );
- const githubLink = (
-
-
-
- );
+const WelcomeSpecificConfig: React.FC = ({ next }) => {
+ const { systemStatus } = useSetupContext();
+ const status = systemStatus?.systemStatus;
+ const overrideConfig = status?.configPath;
- function onConfigLocationChosen(inWorkDir: boolean) {
- setSetupInWorkDir(inWorkDir);
- next();
+ function onNext() {
+ next({ configLocation: overrideConfig! });
}
- function goBack(n?: number) {
- let dec = n;
- if (!dec) {
- dec = 1;
- }
- setStep(Math.max(0, step - dec));
- }
+ return (
+ <>
+
+
+
+
+
+
+
+
+ {chunks}
,
+ }}
+ />
+
+
+
+
+
+
+
+ >
+ );
+};
- function next() {
- setStep(step + 1);
- }
+const DefaultWelcomeStep: React.FC = ({ next }) => {
+ const { pathJoin, homeDir, macApp, homeDirPath, pwd, workingDir } =
+ useSetupContext();
- function confirmPaths() {
- if (stashes.length > 0) {
- next();
- return;
- }
+ const fallbackStashDir = pathJoin(homeDir, ".stash");
+ const fallbackConfigPath = pathJoin(fallbackStashDir, "config.yml");
- setShowStashAlert(true);
+ function onConfigLocationChosen(inWorkingDir: boolean) {
+ const configLocation = inWorkingDir ? "config.yml" : "";
+ next({ configLocation });
}
- function maybeRenderStashAlert() {
- if (!showStashAlert) {
- return;
- }
-
- return (
- {
- setShowStashAlert(false);
- next();
- },
- }}
- cancel={{ onClick: () => setShowStashAlert(false) }}
- >
+ return (
+ <>
+
+
+
+
+
+
+
-
+ {chunks}
,
+ fallback_path: fallbackConfigPath,
+ }}
+ />
-
- );
- }
-
- const WelcomeSpecificConfig = () => {
- return (
- <>
-
-
-
-
-
-
-
-
- {chunks}
,
- }}
- />
-
-
-
-
-
-
-
- >
- );
- };
+
+ {chunks}
,
+ }}
+ />
+
+
+
+
+
- function DefaultWelcomeStep() {
- const homeDirPath = pathJoin(status?.homeDir ?? homeDir, ".stash");
+
+
+
+
- return (
- <>
-
-
-
-
-
-
-
-
- {chunks}
,
- fallback_path: fallbackConfigPath,
- }}
- />
-
-
+
+
onConfigLocationChosen(false)}
+ >
{chunks}
,
+ path: fallbackStashDir,
}}
/>
-
-
-
-
-
-
-
-
-
-
-
-
- onConfigLocationChosen(false)}
- >
- {chunks}
,
- path: fallbackStashDir,
- }}
- />
-
- {homeDirPath}
-
- onConfigLocationChosen(true)}
- disabled={macApp}
- >
- {macApp ? (
- <>
- {chunks}
,
- path: pwd,
- }}
- />
-
-
- {chunks}
,
- br: () => ,
- }}
- />
-
- >
- ) : (
- <>
+
+ {homeDirPath}
+
+ onConfigLocationChosen(true)}
+ disabled={macApp}
+ >
+ {macApp ? (
+ <>
+ {chunks}
,
+ path: pwd,
+ }}
+ />
+
+
{chunks}
,
- path: pwd,
+ br: () => ,
}}
/>
-
- {workingDir}
- >
- )}
-
-
-
- >
- );
- }
+
+ >
+ ) : (
+ <>
+ {chunks}
,
+ path: pwd,
+ }}
+ />
+
+ {workingDir}
+ >
+ )}
+
+
+
+ >
+ );
+};
- function onGeneratedSelectClosed(d?: string) {
- if (d) {
- setGeneratedLocation(d);
- }
+const WelcomeStep: React.FC = (props) => {
+ const { systemStatus } = useSetupContext();
+ const status = systemStatus?.systemStatus;
+ const overrideConfig = status?.configPath;
- setShowGeneratedSelectDialog(false);
- }
+ return overrideConfig ? (
+
+ ) : (
+
+ );
+};
- function maybeRenderGeneratedSelectDialog() {
- if (!showGeneratedSelectDialog) {
- return;
- }
+const StashAlert: React.FC<{ close: (confirm: boolean) => void }> = ({
+ close,
+}) => {
+ const intl = useIntl();
- return ;
- }
+ return (
+ close(true),
+ }}
+ cancel={{ onClick: () => close(false) }}
+ >
+
+
+
+
+ );
+};
- function onBlobsClosed(d?: string) {
- if (d) {
- setBlobsLocation(d);
- }
+const DatabaseSection: React.FC<{
+ databaseFile: string;
+ setDatabaseFile: React.Dispatch>;
+}> = ({ databaseFile, setDatabaseFile }) => {
+ const intl = useIntl();
- setShowBlobsDialog(false);
- }
+ return (
+
+
+
+
+
+ {chunks}
,
+ }}
+ />
+
+ {chunks} ,
+ }}
+ />
+
+ setDatabaseFile(e.currentTarget.value)}
+ />
+
+ );
+};
- function maybeRenderBlobsSelectDialog() {
- if (!showBlobsDialog) {
- return;
+const DirectorySelector: React.FC<{
+ value: string;
+ setValue: React.Dispatch>;
+ placeholder: string;
+ disabled?: boolean;
+}> = ({ value, setValue, placeholder, disabled = false }) => {
+ const [showSelectDialog, setShowSelectDialog] = useState(false);
+
+ function onSelectClosed(dir?: string) {
+ if (dir) {
+ setValue(dir);
}
-
- return ;
+ setShowSelectDialog(false);
}
- function maybeRenderDatabase() {
- if (overrideDatabase) return;
-
- return (
-
-
-
-
-
- {chunks}
,
- }}
- />
-
- {chunks} ,
- }}
- />
-
+ return (
+ <>
+ {showSelectDialog ? (
+
+ ) : null}
+
setValue(e.currentTarget.value)}
+ disabled={disabled}
+ />
+
+ setShowSelectDialog(true)}
+ disabled={disabled}
+ >
+
+
+
+
+ >
+ );
+};
+
+const GeneratedSection: React.FC<{
+ generatedLocation: string;
+ setGeneratedLocation: React.Dispatch>;
+}> = ({ generatedLocation, setGeneratedLocation }) => {
+ const intl = useIntl();
+
+ return (
+
+
+
+
+
+ {chunks}
,
+ }}
+ />
+
+
+
+ );
+};
+
+const CacheSection: React.FC<{
+ cacheLocation: string;
+ setCacheLocation: React.Dispatch>;
+}> = ({ cacheLocation, setCacheLocation }) => {
+ const intl = useIntl();
+
+ return (
+
+
+
+
+
+ {chunks}
,
+ }}
+ />
+
+
+
+ );
+};
+
+const BlobsSection: React.FC<{
+ blobsLocation: string;
+ setBlobsLocation: React.Dispatch>;
+ storeBlobsInDatabase: boolean;
+ setStoreBlobsInDatabase: React.Dispatch>;
+}> = ({
+ blobsLocation,
+ setBlobsLocation,
+ storeBlobsInDatabase,
+ setStoreBlobsInDatabase,
+}) => {
+ const intl = useIntl();
+
+ return (
+
+
+
+
+
+ {chunks}
,
+ }}
+ />
+
+
+ {chunks}
,
+ strong: (chunks: string) => {chunks} ,
+ }}
+ />
+
+
+
+
setStoreBlobsInDatabase(!storeBlobsInDatabase)}
+ />
+
+
+
+ setDatabaseFile(e.currentTarget.value)}
+ disabled={storeBlobsInDatabase}
/>
-
- );
+
+
+ );
+};
+
+const SetPathsStep: React.FC = ({ goBack, next }) => {
+ const { configuration } = useSetupContext();
+
+ const [showStashAlert, setShowStashAlert] = useState(false);
+
+ const [stashes, setStashes] = useState([]);
+ const [databaseFile, setDatabaseFile] = useState("");
+ const [generatedLocation, setGeneratedLocation] = useState("");
+ const [cacheLocation, setCacheLocation] = useState("");
+ const [storeBlobsInDatabase, setStoreBlobsInDatabase] = useState(false);
+ const [blobsLocation, setBlobsLocation] = useState("");
+
+ const overrideDatabase = configuration?.general.databasePath;
+ const overrideGenerated = configuration?.general.generatedPath;
+ const overrideCache = configuration?.general.cachePath;
+ const overrideBlobs = configuration?.general.blobsPath;
+
+ function preNext() {
+ if (stashes.length === 0) {
+ setShowStashAlert(true);
+ } else {
+ onNext();
+ }
}
- function maybeRenderGenerated() {
- if (overrideGenerated) return;
+ function onNext() {
+ const input: Partial = {
+ stashes,
+ databaseFile,
+ generatedLocation,
+ cacheLocation,
+ blobsLocation: storeBlobsInDatabase ? "" : blobsLocation,
+ storeBlobsInDatabase,
+ };
+ next(input);
+ }
- return (
-
-
-
-
+ return (
+ <>
+ {showStashAlert ? (
+ {
+ setShowStashAlert(false);
+ if (confirm) {
+ onNext();
+ }
+ }}
+ />
+ ) : null}
+
+
+
+
- {chunks}
,
- }}
- />
+
-
- setGeneratedLocation(e.currentTarget.value)}
+
+
+
+
+
+
+
+
+
+
+ setStashes(s)}
+ />
+
+
+ {overrideDatabase ? null : (
+
-
- setShowGeneratedSelectDialog(true)}
- >
-
-
-
-
-
- );
- }
+ )}
+ {overrideGenerated ? null : (
+
+ )}
+ {overrideCache ? null : (
+
+ )}
+ {overrideBlobs ? null : (
+
+ )}
+
+
+
+ goBack()}>
+
+
+ preNext()}>
+
+
+
+
+ >
+ );
+};
- function onCacheSelectClosed(d?: string) {
- if (d) {
- setCacheLocation(d);
- }
+const StashExclusions: React.FC<{ stash: GQL.StashConfig }> = ({ stash }) => {
+ if (!stash.excludeImage && !stash.excludeVideo) {
+ return null;
+ }
- setShowCacheSelectDialog(false);
+ const excludes = [];
+ if (stash.excludeVideo) {
+ excludes.push("videos");
+ }
+ if (stash.excludeImage) {
+ excludes.push("images");
}
- function maybeRenderCacheSelectDialog() {
- if (!showCacheSelectDialog) {
- return;
- }
+ return {`(excludes ${excludes.join(" and ")})`} ;
+};
+
+const ConfirmStep: React.FC = ({ goBack, next }) => {
+ const { configuration, pathDir, pathJoin, pwd, setupState } =
+ useSetupContext();
+
+ const cfgFile = setupState.configLocation
+ ? setupState.configLocation
+ : pathJoin(pwd, "config.yml");
+ const cfgDir = pathDir(cfgFile);
+ const stashes = setupState.stashes ?? [];
+ const {
+ databaseFile,
+ generatedLocation,
+ cacheLocation,
+ blobsLocation,
+ storeBlobsInDatabase,
+ } = setupState;
- return ;
+ const overrideDatabase = configuration?.general.databasePath;
+ const overrideGenerated = configuration?.general.generatedPath;
+ const overrideCache = configuration?.general.cachePath;
+ const overrideBlobs = configuration?.general.blobsPath;
+
+ function joinCfgDir(path: string) {
+ if (cfgDir) {
+ return pathJoin(cfgDir, path);
+ } else {
+ return path;
+ }
}
- function maybeRenderCache() {
- if (overrideCache) return;
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ {cfgFile}
+
+
+
+
+
+
+
+
+ {stashes.map((s) => (
+
+ {s.path}
+
+
+ ))}
+
+
+
+ {!overrideDatabase && (
+
+
+
+
+
+ {databaseFile || joinCfgDir("stash-go.sqlite")}
+
+
+ )}
+ {!overrideGenerated && (
+
+
+
+
+
+ {generatedLocation || joinCfgDir("generated")}
+
+
+ )}
+ {!overrideCache && (
+
+
+
+
+
+ {cacheLocation || joinCfgDir("cache")}
+
+
+ )}
+ {!overrideBlobs && (
+
+
+
+
+
+
+ {storeBlobsInDatabase ? (
+
+ ) : (
+ blobsLocation || joinCfgDir("blobs")
+ )}
+
+
+
+ )}
+
+
+
+ goBack()}>
+
+
+ next()}>
+
+
+
+
+ >
+ );
+};
- return (
-
-
-
-
+const DiscordLink = (
+ Discord
+);
+const GithubLink = (
+
+
+
+);
+
+const ErrorStep: React.FC<{ error: string; goBack: () => void }> = ({
+ error,
+ goBack,
+}) => {
+ return (
+ <>
+
+
+
+
{chunks}
,
- }}
+ id="setup.errors.something_went_wrong_while_setting_up_your_system"
+ values={{ error: {error} }}
/>
-
- setCacheLocation(e.currentTarget.value)}
+
+
-
- setShowCacheSelectDialog(true)}
- >
-
-
-
-
-
- );
- }
+
+
+
+ >
+ );
+};
- function maybeRenderBlobs() {
- if (overrideBlobs) return;
+const SuccessStep: React.FC<{}> = () => {
+ const intl = useIntl();
+ const history = useHistory();
- return (
-
-
-
-
+ const [mutateDownloadFFMpeg] = GQL.useDownloadFfMpegMutation();
+
+ const [downloadFFmpeg, setDownloadFFmpeg] = useState(true);
+
+ const { systemStatus } = useSetupContext();
+ const status = systemStatus?.systemStatus;
+
+ function onFinishClick() {
+ if ((!status?.ffmpegPath || !status?.ffprobePath) && downloadFFmpeg) {
+ mutateDownloadFFMpeg();
+ }
+
+ history.push("/settings?tab=library");
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+
{chunks}
,
+ localized_task: intl.formatMessage({
+ id: "config.categories.tasks",
+ }),
+ localized_scan: intl.formatMessage({ id: "actions.scan" }),
}}
/>
+ {!status?.ffmpegPath || !status?.ffprobePath ? (
+ <>
+
+ {chunks}
,
+ }}
+ />
+
+
+
setDownloadFFmpeg(!downloadFFmpeg)}
+ />
+
+ >
+ ) : null}
+
+
+
+
+
+
+
+ {chunks}
,
- strong: (chunks: string) => {chunks} ,
+ open_collective_link: (
+
+ Open Collective
+
+ ),
}}
/>
-
-
setStoreBlobsInDatabase(!storeBlobsInDatabase)}
- />
+
+
+
+
+
+ onFinishClick()}>
+
+
+
+
+ >
+ );
+};
- {!storeBlobsInDatabase && (
-
- setBlobsLocation(e.currentTarget.value)}
- disabled={storeBlobsInDatabase}
- />
-
- setShowBlobsDialog(true)}
- disabled={storeBlobsInDatabase}
- >
-
-
-
-
- )}
-
- );
- }
+const FinishStep: React.FC = ({ goBack }) => {
+ const { setupError } = useSetupContext();
- function SetPathsStep() {
- return (
- <>
- {maybeRenderStashAlert()}
-
-
-
-
-
-
-
-
-
-
- setStashes(s)}
- />
-
-
- {maybeRenderDatabase()}
- {maybeRenderGenerated()}
- {maybeRenderCache()}
- {maybeRenderBlobs()}
-
-
-
- goBack()}>
-
-
- confirmPaths()}>
-
-
-
-
- >
- );
+ if (setupError !== undefined) {
+ return ;
}
- function maybeRenderExclusions(s: GQL.StashConfig) {
- if (!s.excludeImage && !s.excludeVideo) {
- return;
- }
+ return ;
+};
- const excludes = [];
- if (s.excludeVideo) {
- excludes.push("videos");
- }
- if (s.excludeImage) {
- excludes.push("images");
- }
+export const Setup: React.FC = () => {
+ const intl = useIntl();
+ const { configuration, loading: configLoading } =
+ useContext(ConfigurationContext);
- return `(excludes ${excludes.join(" and ")})`;
- }
+ const [saveUI] = useConfigureUI();
- async function onSave() {
- let configLocation = overrideConfig;
- if (!configLocation) {
- configLocation = setupInWorkDir ? "config.yml" : "";
- }
+ const {
+ data: systemStatus,
+ loading: statusLoading,
+ error: statusError,
+ } = useSystemStatus();
+
+ const [step, setStep] = useState(0);
+ const [setupInput, setSetupInput] = useState>({});
+ const [creating, setCreating] = useState(false);
+ const [setupError, setSetupError] = useState(undefined);
+
+ const history = useHistory();
+ const steps: React.FC[] = [
+ WelcomeStep,
+ SetPathsStep,
+ ConfirmStep,
+ FinishStep,
+ ];
+ const Step = steps[step];
+
+ async function createSystem() {
try {
- setLoading(true);
- await mutateSetup({
- configLocation,
- databaseFile,
- generatedLocation,
- cacheLocation,
- storeBlobsInDatabase,
- blobsLocation,
- stashes,
- });
+ setCreating(true);
+ setSetupError(undefined);
+ await mutateSetup(setupInput as GQL.SetupInput);
// Set lastNoteSeen to hide release notes dialog
await saveUI({
variables: {
@@ -621,318 +980,95 @@ export const Setup: React.FC = () => {
setSetupError(String(e));
}
} finally {
- setLoading(false);
- next();
- }
- }
-
- function ConfirmStep() {
- let cfgDir: string;
- let config: string;
- if (overrideConfig) {
- cfgDir = pathDir(overrideConfig);
- config = overrideConfig;
- } else {
- cfgDir = setupInWorkDir ? pwd : fallbackStashDir;
- config = pathJoin(cfgDir, "config.yml");
+ setCreating(false);
+ setStep(step + 1);
}
-
- function joinCfgDir(path: string) {
- if (cfgDir) {
- return pathJoin(cfgDir, path);
- } else {
- return path;
- }
- }
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
- {config}
-
-
-
-
-
-
-
-
- {stashes.map((s) => (
-
- {s.path}
- {maybeRenderExclusions(s)}
-
- ))}
-
-
-
- {!overrideDatabase && (
-
-
-
-
-
- {databaseFile || joinCfgDir("stash-go.sqlite")}
-
-
- )}
- {!overrideGenerated && (
-
-
-
-
-
- {generatedLocation || joinCfgDir("generated")}
-
-
- )}
- {!overrideCache && (
-
-
-
-
-
- {cacheLocation || joinCfgDir("cache")}
-
-
- )}
- {!overrideBlobs && (
-
-
-
-
-
-
- {storeBlobsInDatabase ? (
-
- ) : (
- blobsLocation || joinCfgDir("blobs")
- )}
-
-
-
- )}
-
-
-
- goBack()}>
-
-
- onSave()}>
-
-
-
-
- >
- );
}
- function ErrorStep() {
- function onBackClick() {
- setSetupError(undefined);
- goBack(2);
- }
-
- return (
- <>
-
-
-
-
-
- {setupError} }}
- />
-
-
-
-
-
-
- >
- );
- }
+ function next(input?: Partial) {
+ setSetupInput({ ...setupInput, ...input });
- function onFinishClick() {
- if ((!status?.ffmpegPath || !status?.ffprobePath) && downloadFFmpeg) {
- mutateDownloadFFMpeg();
+ if (Step === ConfirmStep) {
+ // create the system
+ createSystem();
+ } else {
+ setStep(step + 1);
}
-
- history.push("/settings?tab=library");
}
- function SuccessStep() {
- return (
- <>
-
-
-
-
-
-
-
-
- {chunks}
,
- localized_task: intl.formatMessage({
- id: "config.categories.tasks",
- }),
- localized_scan: intl.formatMessage({ id: "actions.scan" }),
- }}
- />
-
- {!status?.ffmpegPath || !status?.ffprobePath ? (
- <>
-
- {chunks}
,
- }}
- />
-
-
-
setDownloadFFmpeg(!downloadFFmpeg)}
- />
-
- >
- ) : null}
-
-
-
-
-
-
- }}
- />
-
-
-
-
-
-
-
-
-
-
-
- Open Collective
-
- ),
- }}
- />
-
-
-
-
-
-
-
-
- onFinishClick()}>
-
-
-
-
- >
- );
- }
-
- function FinishStep() {
- if (setupError !== undefined) {
- return ;
+ function goBack() {
+ if (Step === FinishStep) {
+ // go back to the step before ConfirmStep
+ setStep(step - 2);
+ } else {
+ setStep(step - 1);
}
-
- return ;
}
- // only display setup wizard if system is not setup
- if (statusLoading || configLoading) {
+ if (configLoading || statusLoading) {
return ;
}
- if (step === 0 && status && status.status !== GQL.SystemStatusEnum.Setup) {
+ if (
+ step === 0 &&
+ systemStatus &&
+ systemStatus.systemStatus.status !== GQL.SystemStatusEnum.Setup
+ ) {
// redirect to main page
history.push("/");
return ;
}
- const WelcomeStep = overrideConfig
- ? WelcomeSpecificConfig
- : DefaultWelcomeStep;
- const steps = [WelcomeStep, SetPathsStep, ConfirmStep, FinishStep];
- const Step = steps[step];
+ if (statusError) {
+ return (
+
+
+
+
+
+ );
+ }
- function renderCreating() {
+ if (!configuration || !systemStatus) {
return (
-
-
-
+
+
+
+
+
);
}
return (
-
- {maybeRenderGeneratedSelectDialog()}
- {maybeRenderCacheSelectDialog()}
- {maybeRenderBlobsSelectDialog()}
-
-
-
- {loading ? (
- renderCreating()
- ) : (
+
+
+
+
+
-
+ {creating ? (
+
+ ) : (
+
+ )}
- )}
-
+
+
);
};
diff --git a/ui/v2.5/src/components/Setup/styles.scss b/ui/v2.5/src/components/Setup/styles.scss
index 36db2798a57..0eceeb8e521 100644
--- a/ui/v2.5/src/components/Setup/styles.scss
+++ b/ui/v2.5/src/components/Setup/styles.scss
@@ -24,3 +24,10 @@
margin-left: 0.5rem;
}
}
+
+.setup-wizard {
+ #blobs > div {
+ margin-bottom: 1rem;
+ margin-top: 0;
+ }
+}
diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json
index edad1c8e7cf..784579c95b8 100644
--- a/ui/v2.5/src/locales/en-GB.json
+++ b/ui/v2.5/src/locales/en-GB.json
@@ -1298,7 +1298,9 @@
"errors": {
"something_went_wrong": "Oh no! Something went wrong!",
"something_went_wrong_description": "If this looks like a problem with your inputs, go ahead and click back to fix them up. Otherwise, raise a bug on the {githubLink} or seek help in the {discordLink}.",
- "something_went_wrong_while_setting_up_your_system": "Something went wrong while setting up your system. Here is the error we received: {error}"
+ "something_went_wrong_while_setting_up_your_system": "Something went wrong while setting up your system. Here is the error we received: {error}",
+ "unable_to_retrieve_system_status": "Unable to retrieve system status: {error}",
+ "unexpected_error": "An unexpected error occurred: {error}"
},
"folder": {
"file_path": "File path",