-
Welcome to ZenML
-
- You successfully installed the ZenML dashboard. Now you can get started with your new
- ZenML server.
+
+
+
+ Welcome to ZenML
+
+
+
+ You can start by following your quick setup.
- {/*
*/}
-
+
+
);
}
+
+function Username() {
+ const user = useCurrentUser();
+
+ if (user.isError) return null;
+ if (user.isPending) return
;
+ const name = getUsername(user.data);
+ return <>{name ? `, ${name}` : ""}>;
+}
diff --git a/src/app/onboarding/ProductionSetup/ArtifactStore.tsx b/src/app/onboarding/ProductionSetup/ArtifactStore.tsx
deleted file mode 100644
index 79a61f336..000000000
--- a/src/app/onboarding/ProductionSetup/ArtifactStore.tsx
+++ /dev/null
@@ -1,207 +0,0 @@
-import { Codesnippet } from "@/components/CodeSnippet";
-import { buttonVariants } from "@zenml-io/react-component-library";
-import { LearnMoreLink } from "./Items";
-import { CloudProvider } from "./ProviderSelect";
-
-function AWSStore() {
- return (
- <>
-
-
- Install the AWS CLI on your machine
-
-
-
-
-
- Create a AWS bucket or identify an existing one{" "}
- (Optional) {" "}
-
-
-
-
-
-
Install the S3 ZenML integration
-
-
-
-
Register the artifact store
-
-
- >
- );
-}
-
-function GCPStore() {
- return (
- <>
-
-
- Install the Google Cloud CLI on your machine
-
-
-
-
-
- Create a GCP bucket or identify an existing one{" "}
- (Optional) {" "}
-
-
-
-
-
-
Install the GCP ZenML integration
-
-
-
-
Register the artifact store
-
-
- >
- );
-}
-
-function AzureStore() {
- return (
- <>
-
-
- Install the Azure CLI on your machine
-
-
-
-
-
- Create a Azure bucket or identify an existing one{" "}
- (Optional) {" "}
-
-
-
-
-
-
- Install the Azure ZenML integration{" "}
-
-
-
-
-
Register the artifact store
-
-
- >
- );
-}
-
-function OtherStore() {
- return (
-
-
- Create a remote artifact in any environment following our guides.
-
-
-
- );
-}
-
-export function getArtifactStoreStep(provider: CloudProvider) {
- switch (provider) {
- case "gcp":
- return
;
- case "aws":
- return
;
- case "azure":
- return
;
- case "other":
- return
;
- default:
- break;
- }
-}
diff --git a/src/app/onboarding/ProductionSetup/ConnectorContent.tsx b/src/app/onboarding/ProductionSetup/ConnectorContent.tsx
deleted file mode 100644
index 45a5227fc..000000000
--- a/src/app/onboarding/ProductionSetup/ConnectorContent.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import { Codesnippet } from "@/components/CodeSnippet";
-import { LearnMoreLink } from "./Items";
-import { CloudProvider } from "./ProviderSelect";
-
-function AWSConnector() {
- return (
- <>
-
-
- Create a AWS service connector using the IAM Method{" "}
-
-
-
-
- >
- );
-}
-
-function GCPConnector() {
- return (
- <>
-
-
- Create a GCP service connector using the Service Account Method{" "}
-
-
-
-
- >
- );
-}
-
-function AzureStore() {
- return (
- <>
-
-
- Create an Azure service connector using the Service Principal Method{" "}
-
-
-
-
- >
- );
-}
-
-export function getServiceConnectorStep(provider: CloudProvider) {
- switch (provider) {
- case "gcp":
- return
;
- case "aws":
- return
;
- case "azure":
- return
;
- default:
- break;
- }
-}
diff --git a/src/app/onboarding/ProductionSetup/Items.tsx b/src/app/onboarding/ProductionSetup/Items.tsx
deleted file mode 100644
index 0986ece7a..000000000
--- a/src/app/onboarding/ProductionSetup/Items.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import Plus from "@/assets/icons/plus.svg?react";
-import { Codesnippet } from "@/components/CodeSnippet";
-import { HelpBox } from "@/components/fallback-pages/Helpbox";
-import { ChecklistItem } from "@/components/onboarding/ChecklistItem";
-import {} from "@/lib/onboarding";
-import { routes } from "@/router/routes";
-import { OnboardingStep } from "@/types/onboarding";
-import { Button } from "@zenml-io/react-component-library";
-import { Link } from "react-router-dom";
-
-export function CreateNewStack({ completed, active, hasDownstreamStep }: OnboardingStep) {
- const link =
- routes.stacks.create.index + "?" + new URLSearchParams({ origin: "onboarding" }).toString();
- return (
-
-
- A stack configures how a pipeline is executed{" "}
-
-
-
-
-
Connect your Cloud to deploy your ZenML pipelines in a remote stack.
-
-
-
- Register a stack
-
-
-
-
-
-
- );
-}
-
-export function RunNewPipeline({ active, completed, hasDownstreamStep }: OnboardingStep) {
- return (
-
-
-
- );
-}
-
-export function LearnMoreLink({ href }: { href: string }) {
- return (
-
- Learn more
-
- );
-}
diff --git a/src/app/onboarding/ProductionSetup/ProviderSelect.tsx b/src/app/onboarding/ProductionSetup/ProviderSelect.tsx
deleted file mode 100644
index a0d69ca57..000000000
--- a/src/app/onboarding/ProductionSetup/ProviderSelect.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import Aws from "@/assets/icons/services/aws.svg?react";
-import Gcp from "@/assets/icons/services/gcp.svg?react";
-import Azure from "@/assets/icons/services/azure.svg?react";
-import Cloud from "@/assets/icons/cloud.svg?react";
-import {
- Select,
- SelectContent,
- SelectItem,
- SelectTrigger,
- SelectValue
-} from "@zenml-io/react-component-library";
-
-type Props = {
- displayOther?: boolean;
- setValue?: (value: CloudProvider) => void;
- value?: CloudProvider;
- id: string;
-};
-
-export type CloudProvider = "gcp" | "aws" | "azure" | "other";
-
-export function ProviderSelect({ displayOther = false, setValue, value, id }: Props) {
- return (
-
-
-
-
-
-
-
-
-
- {" "}
-
-
- GCP
-
-
-
-
-
- {displayOther && (
-
-
-
- Other
-
-
- )}
-
-
- );
-}
diff --git a/src/app/onboarding/ProductionSetup/index.tsx b/src/app/onboarding/ProductionSetup/index.tsx
deleted file mode 100644
index 3d8c60deb..000000000
--- a/src/app/onboarding/ProductionSetup/index.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import ChevronDown from "@/assets/icons/chevron-down.svg?react";
-import { Tick } from "@/components/Tick";
-import { useServerInfo } from "@/data/server/info-query";
-import { useOnboarding } from "@/data/server/onboarding-state";
-import { getProductionSetup, getStarterSetup } from "@/lib/onboarding";
-import { checkIsLocalServer } from "@/lib/server";
-import {
- Collapsible,
- CollapsibleContent,
- CollapsibleTrigger,
- RadialProgress,
- Skeleton,
- cn
-} from "@zenml-io/react-component-library";
-import { useState } from "react";
-import { CreateNewStack, RunNewPipeline } from "./Items";
-
-export function ProductionSetupChecklist() {
- const onboarding = useOnboarding({ refetchInterval: 5000 });
- const serverInfo = useServerInfo();
- const [open, setOpen] = useState(true);
-
- if (onboarding.isPending || serverInfo.isPending)
- return
;
- if (onboarding.isError || serverInfo.isError) return null;
-
- const starterSetup = getStarterSetup(
- onboarding.data,
- checkIsLocalServer(serverInfo.data.deployment_type || "other")
- );
-
- const { progress, totalItems, itemsDone, getItem } = getProductionSetup(onboarding.data);
-
- const stackStep = getItem("stack_with_remote_orchestrator_created");
- const pipelineStep = getItem("pipeline_run_with_remote_orchestrator");
-
- return (
- <>
-
-
-
- {progress >= 100 ? (
-
- ) : (
-
-
- {itemsDone}/{totalItems}
-
-
- )}
-
-
-
- Production Setup{" "}
- (10 min)
-
-
- {starterSetup.isFinished ? (
- "Level up your skills in a production setting."
- ) : (
-
- Complete the Starter Setup to enable the production setup.
-
- )}
-
-
-
-
-
-
-
-
-
- >
- );
-}
diff --git a/src/app/onboarding/ProgressIndicator.tsx b/src/app/onboarding/ProgressIndicator.tsx
new file mode 100644
index 000000000..a9964cfe8
--- /dev/null
+++ b/src/app/onboarding/ProgressIndicator.tsx
@@ -0,0 +1,26 @@
+import { useServerInfo } from "@/data/server/info-query";
+import { useOnboarding } from "@/data/server/onboarding-state";
+import { getOnboardingSetup } from "@/lib/onboarding";
+import { checkIsLocalServer } from "@/lib/server";
+import { Badge, Skeleton } from "@zenml-io/react-component-library";
+
+export function ProgressIndicatior() {
+ const onboarding = useOnboarding();
+ const serverInfo = useServerInfo();
+
+ if (onboarding.isPending || serverInfo.isPending)
+ return
;
+ if (onboarding.isError || serverInfo.isError) {
+ return null;
+ }
+ const isLocalServer = checkIsLocalServer(serverInfo.data.deployment_type || "other");
+ const onboardingSetup = getOnboardingSetup(onboarding.data, isLocalServer);
+ const completedItems = onboardingSetup.itemsDone;
+ const totalItems = onboardingSetup.totalItems;
+
+ return (
+
+ {completedItems}/{totalItems} steps completed
+
+ );
+}
diff --git a/src/app/onboarding/StarterSetup/Items.tsx b/src/app/onboarding/Setup/Items.tsx
similarity index 58%
rename from src/app/onboarding/StarterSetup/Items.tsx
rename to src/app/onboarding/Setup/Items.tsx
index cee207441..214bae6c1 100644
--- a/src/app/onboarding/StarterSetup/Items.tsx
+++ b/src/app/onboarding/Setup/Items.tsx
@@ -1,10 +1,13 @@
import Help from "@/assets/icons/help.svg?react";
+import Plus from "@/assets/icons/plus.svg?react";
import { Codesnippet } from "@/components/CodeSnippet";
import { HelpBox } from "@/components/fallback-pages/Helpbox";
import { ChecklistItem } from "@/components/onboarding/ChecklistItem";
import { useServerInfo } from "@/data/server/info-query";
+import { routes } from "@/router/routes";
import { OnboardingStep } from "@/types/onboarding";
-import { Box, Skeleton, buttonVariants } from "@zenml-io/react-component-library";
+import { Box, Button, Skeleton, buttonVariants } from "@zenml-io/react-component-library";
+import { Link } from "react-router-dom";
export function ConnectZenMLStep({ completed, hasDownstreamStep, active }: OnboardingStep) {
const { data } = useServerInfo({ throwOnError: true });
@@ -13,7 +16,7 @@ export function ConnectZenMLStep({ completed, hasDownstreamStep, active }: Onboa
active={active}
hasDownstream={hasDownstreamStep}
completed={completed}
- title="Connect to ZenML"
+ title="Install and Connect ZenML (5 min)"
>
@@ -38,7 +41,7 @@ export function RunFirstPipeline({ active, completed, hasDownstreamStep }: Onboa
active={active}
hasDownstream={hasDownstreamStep}
completed={completed}
- title="Run your first pipeline"
+ title="Run a pipeline (2 min)"
>
@@ -98,3 +101,71 @@ export function RunFirstPipeline({ active, completed, hasDownstreamStep }: Onboa
);
}
+
+export function CreateNewStack({ completed, active, hasDownstreamStep }: OnboardingStep) {
+ const link =
+ routes.stacks.create.index + "?" + new URLSearchParams({ origin: "onboarding" }).toString();
+ return (
+
+
+ A stack configures how a pipeline is executed{" "}
+
+
+
+
+
Connect your Cloud to deploy your ZenML pipelines in a remote stack.
+
+
+
+ Register a stack
+
+
+
+
+
+
+ );
+}
+
+export function RunNewPipeline({ active, completed, hasDownstreamStep }: OnboardingStep) {
+ return (
+
+
+
+ );
+}
+
+function LearnMoreLink({ href }: { href: string }) {
+ return (
+
+ Learn more
+
+ );
+}
diff --git a/src/app/onboarding/Setup/index.tsx b/src/app/onboarding/Setup/index.tsx
new file mode 100644
index 000000000..9a3d02422
--- /dev/null
+++ b/src/app/onboarding/Setup/index.tsx
@@ -0,0 +1,57 @@
+import { useServerInfo } from "@/data/server/info-query";
+import { useOnboarding } from "@/data/server/onboarding-state";
+import { getOnboardingSetup } from "@/lib/onboarding";
+import { checkIsLocalServer } from "@/lib/server";
+import { Skeleton } from "@zenml-io/react-component-library";
+import { ConnectZenMLStep, CreateNewStack, RunFirstPipeline, RunNewPipeline } from "./Items";
+
+export function OnboardingSetupList() {
+ const onboarding = useOnboarding({ refetchInterval: 5000 });
+ const serverInfo = useServerInfo();
+
+ if (onboarding.isPending || serverInfo.isPending)
+ return
;
+ if (onboarding.isError || serverInfo.isError) return null;
+
+ const isLocalServer = checkIsLocalServer(serverInfo.data.deployment_type || "other");
+ const { getItem } = getOnboardingSetup(onboarding.data, isLocalServer);
+ const connectStep = getItem("device_verified");
+ const pipelineStep = getItem("pipeline_run");
+ const stackStep = getItem("stack_with_remote_orchestrator_created");
+ const remotePipelineStep = getItem("pipeline_run_with_remote_orchestrator");
+
+ return (
+
+ {!isLocalServer && (
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/onboarding/StarterSetup/index.tsx b/src/app/onboarding/StarterSetup/index.tsx
deleted file mode 100644
index 94a143a4d..000000000
--- a/src/app/onboarding/StarterSetup/index.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import ChevronDown from "@/assets/icons/chevron-down.svg?react";
-import { Tick } from "@/components/Tick";
-import { useServerInfo } from "@/data/server/info-query";
-import { useOnboarding } from "@/data/server/onboarding-state";
-import { getStarterSetup } from "@/lib/onboarding";
-import { checkIsLocalServer } from "@/lib/server";
-import {
- Collapsible,
- CollapsibleContent,
- CollapsibleTrigger,
- RadialProgress,
- Skeleton
-} from "@zenml-io/react-component-library";
-import { useState } from "react";
-import { ConnectZenMLStep, RunFirstPipeline } from "./Items";
-
-export function StarterSetupList() {
- const onboarding = useOnboarding({ refetchInterval: 5000 });
- const serverInfo = useServerInfo();
- const [open, setOpen] = useState(true);
-
- if (onboarding.isPending || serverInfo.isPending)
- return
;
- if (onboarding.isError || serverInfo.isError) return null;
-
- const isLocalServer = checkIsLocalServer(serverInfo.data.deployment_type || "other");
- const { progress, itemsDone, totalItems, getItem } = getStarterSetup(
- onboarding.data,
- isLocalServer
- );
- const connectStep = getItem("device_verified");
- const pipelineStep = getItem("pipeline_run");
-
- return (
-
-
-
- {progress >= 100 ? (
-
- ) : (
-
-
- {itemsDone}/{totalItems}
-
-
- )}
-
-
-
- Starter Setup{" "}
- (2 min)
-
-
- Follow these steps to make sure your client is connected and run your first MLOps
- pipeline with ZenML
-
-
-
-
-
-
-
- {!isLocalServer && (
-
-
-
- )}
-
-
-
-
-
-
- );
-}
diff --git a/src/app/onboarding/page.tsx b/src/app/onboarding/page.tsx
index 2b99ab0a4..beada81fe 100644
--- a/src/app/onboarding/page.tsx
+++ b/src/app/onboarding/page.tsx
@@ -1,7 +1,6 @@
-import { FallbackSupportCard, ResourcesCard } from "@/components/fallback-pages/Cards";
+import { SupportCard, ResourcesCard } from "@/components/fallback-pages/Cards";
import { HeaderOnboardingBox } from "./Header";
-import { ProductionSetupChecklist } from "./ProductionSetup";
-import { StarterSetupList } from "./StarterSetup";
+import { OnboardingSetupList } from "./Setup";
import { useTourContext } from "@/components/tour/TourContext";
import { useEffect } from "react";
@@ -21,11 +20,10 @@ export default function OnboardingPage() {
diff --git a/src/assets/icons/message-chat-square.svg b/src/assets/icons/message-chat-square.svg
new file mode 100644
index 000000000..2f3531457
--- /dev/null
+++ b/src/assets/icons/message-chat-square.svg
@@ -0,0 +1,4 @@
+
+
+
diff --git a/src/components/fallback-pages/Cards.tsx b/src/components/fallback-pages/Cards.tsx
index e13ae768b..fcf2d688d 100644
--- a/src/components/fallback-pages/Cards.tsx
+++ b/src/components/fallback-pages/Cards.tsx
@@ -1,111 +1,96 @@
-import { Box } from "@zenml-io/react-component-library";
-import { ReactNode } from "react";
-import ZenMLLogo from "@/assets/icons/zenml-icon.svg?react";
-import Slack from "@/assets/icons/services/slack.svg?react";
-import Mail from "@/assets/icons/mail.svg?react";
-import FileQuestion from "@/assets/icons/file-question.svg?react";
import FileText from "@/assets/icons/file-text.svg?react";
import File from "@/assets/icons/file.svg?react";
-import Terminal from "@/assets/icons/terminal.svg?react";
+import Mail from "@/assets/icons/mail.svg?react";
+import Chat from "@/assets/icons/message-chat-square.svg?react";
import Package from "@/assets/icons/package.svg?react";
+import Terminal from "@/assets/icons/terminal.svg?react";
+import { Button } from "@zenml-io/react-component-library";
-export function FallbackSupportCard() {
- const links: CardLinkProps[] = [
- {
- text: "Connect with Slack",
- href: "https://zenml.io/slack",
- icon:
- },
+export function SupportCard() {
+ const links = [
{
text: "Send us a message",
href: "mailto:cloud@zenml.io",
- icon:
+ icon:
+ },
+
+ {
+ text: "Join our Slack Community",
+ href: "https://zenml.io/slack",
+ icon:
}
];
return (
-
-
-
-
-
-
Need support?
-
- Schedule a call with us, connect with our Slack community or send us a message.
-
-
- {links.map((link, i) => (
-
-
-
- ))}
-
-
-
+
);
}
-
export function ResourcesCard() {
- const links: CardLinkProps[] = [
+ const links = [
{
text: "Browse our docs",
href: "https://docs.zenml.io",
- icon:
+ icon:
},
{
text: "Discover projects",
href: "https://github.com/zenml-io/zenml-projects",
- icon:
+ icon:
},
{
text: "Navigate our examples",
href: "https://github.com/zenml-io/zenml/tree/main/examples/",
- icon:
+ icon:
},
{
text: "Read our blog",
href: "https://zenml.io/blog",
- icon:
+ icon:
}
];
return (
-
-
-
-
-
-
Resources
-
- Need help? Follow our extensive documentation to get started.
-
-
- {links.map((link, i) => (
-
-
-
- ))}
-
-
-
- );
-}
+
+
Resources
-type CardLinkProps = {
- href: string;
- text: ReactNode;
- icon?: ReactNode;
-};
-function CardLink({ href, text, icon }: CardLinkProps) {
- return (
-
- {icon && icon}
- {text}
-
+
+
);
}
diff --git a/src/components/onboarding/ChecklistItem.tsx b/src/components/onboarding/ChecklistItem.tsx
index e6afefeec..d9a3d5727 100644
--- a/src/components/onboarding/ChecklistItem.tsx
+++ b/src/components/onboarding/ChecklistItem.tsx
@@ -1,12 +1,12 @@
-import ChevronDown from "@/assets/icons/chevron-down.svg?react";
import {
- Collapsible,
CollapsibleContent,
+ CollapsiblePanel,
CollapsibleTrigger,
ProgressOutstanding,
cn
} from "@zenml-io/react-component-library";
-import { PropsWithChildren, ReactNode, useState } from "react";
+import ChevronDown from "@/assets/icons/chevron-down.svg?react";
+import { PropsWithChildren, ReactNode, useEffect, useState } from "react";
import { Tick } from "../Tick";
import { SkippedStep } from "./SkippedStep";
@@ -21,13 +21,21 @@ export function ChecklistItem({
title,
children,
hasDownstream,
- active
+ active = false
}: PropsWithChildren
) {
const [open, setOpen] = useState(active);
+ useEffect(() => {
+ setOpen(active);
+ }, [active]);
+
return (
-
-
+
+
{completed ? (
@@ -37,7 +45,12 @@ export function ChecklistItem({
)}
-
+
@@ -49,16 +62,17 @@ export function ChecklistItem({
- {children && (
-
-
-
- )}
-
+
+ {children && (
+
+
+
+ )}
+
);
}
@@ -66,17 +80,19 @@ type HeaderProps = {
completed: boolean;
title: ReactNode;
skipped: boolean;
+ active?: boolean;
};
-export function ChecklistHeader({ completed, title, skipped }: HeaderProps) {
+export function ChecklistHeader({ completed, title, skipped, active }: HeaderProps) {
return (
{title}
diff --git a/src/data/api.ts b/src/data/api.ts
index 303e6e99d..caf6cc2ee 100644
--- a/src/data/api.ts
+++ b/src/data/api.ts
@@ -24,8 +24,7 @@ export const apiPaths = {
},
runs: {
all: "/runs",
- detail: (id: string) => `/runs/${id}`,
- graph: (runId: string) => `/runs/${runId}/graph`
+ detail: (id: string) => `/runs/${id}`
},
pipeline_builds: {
all: "/pipeline_builds",
diff --git a/src/layouts/AuthenticatedLayout/OnboardingItem.tsx b/src/layouts/AuthenticatedLayout/OnboardingItem.tsx
index 325d125e3..815874b61 100644
--- a/src/layouts/AuthenticatedLayout/OnboardingItem.tsx
+++ b/src/layouts/AuthenticatedLayout/OnboardingItem.tsx
@@ -1,7 +1,7 @@
import ChevronRight from "@/assets/icons/chevron-right.svg?react";
import { useServerInfo } from "@/data/server/info-query";
import { useOnboarding } from "@/data/server/onboarding-state";
-import { getProductionSetup, getStarterSetup } from "@/lib/onboarding";
+import { getOnboardingSetup } from "@/lib/onboarding";
import { checkIsLocalServer } from "@/lib/server";
import { routes } from "@/router/routes";
import { Box, ProgressBar, Skeleton, useSidebarContext } from "@zenml-io/react-component-library";
@@ -20,20 +20,17 @@ export function OnboardingItem() {
);
}
- const starterSetup = getStarterSetup(
+ const onboardingSetup = getOnboardingSetup(
onboarding.data,
checkIsLocalServer(serverInfo.data.deployment_type || "other")
);
- const productionSetup = getProductionSetup(onboarding.data);
- const title = starterSetup.isFinished ? "Production Setup" : "Starter Setup";
- const completedItems = starterSetup.isFinished
- ? productionSetup.itemsDone
- : starterSetup.itemsDone;
- const totalItems = starterSetup.isFinished ? productionSetup.totalItems : starterSetup.totalItems;
- const progress = starterSetup.isFinished ? productionSetup.progress : starterSetup.progress;
+ const title = "Quick Setup";
+ const completedItems = onboardingSetup.itemsDone;
+ const totalItems = onboardingSetup.totalItems;
+ const progress = onboardingSetup.progress;
- if (starterSetup.isFinished && productionSetup.isFinished) return null;
+ if (onboardingSetup.isFinished) return null;
return (
diff --git a/src/lib/onboarding.spec.ts b/src/lib/onboarding.spec.ts
index 975270076..0e94724b1 100644
--- a/src/lib/onboarding.spec.ts
+++ b/src/lib/onboarding.spec.ts
@@ -1,55 +1,52 @@
import { OnboardingChecklistItemName, OnboardingResponse } from "@/types/onboarding";
import { describe, expect, test } from "vitest";
-import {
- checkDownstreamStep,
- getProgress,
- getStarterSetupItems,
- getOnboardingLength
-} from "./onboarding";
+import { checkDownstreamStep, getProgress, getSetupItems, getOnboardingLength } from "./onboarding";
-describe("returns the correct items for the starter setup based on the deployment type", () => {
+describe("returns the correct items based on the deployment type", () => {
test("doesnt return connect step for local deployment", () => {
const isLocal = true;
- const items = getStarterSetupItems(isLocal);
- expect(items).toEqual(["pipeline_run"]);
+ const items = getSetupItems(isLocal);
+ expect(items).toEqual([
+ "pipeline_run",
+ "stack_with_remote_orchestrator_created",
+ "pipeline_run_with_remote_orchestrator"
+ ]);
});
test("includes the connect step for non-local deployments", () => {
const isLocal = false;
- const items = getStarterSetupItems(isLocal);
- expect(items).toEqual(["device_verified", "pipeline_run"]);
+ const items = getSetupItems(isLocal);
+ expect(items).toEqual([
+ "device_verified",
+ "pipeline_run",
+ "stack_with_remote_orchestrator_created",
+ "pipeline_run_with_remote_orchestrator"
+ ]);
});
});
describe("returns the correct progress, depending on the current state", () => {
test("returns 2 if the first two steps are done", () => {
const state: OnboardingResponse = ["device_verified", "pipeline_run"];
- const flow = "starter";
- const progress = getProgress(state, flow, false);
+ const progress = getProgress(state, false);
expect(progress).toBe(2);
});
test("returns 0 if no steps are done", () => {
const onboardingState: OnboardingChecklistItemName[] = [];
- const progress = getProgress(onboardingState, "starter", false);
+ const progress = getProgress(onboardingState, false);
expect(progress).toBe(0);
});
test("returns 2 if only the second step is run", () => {
const onboardingState: OnboardingChecklistItemName[] = ["pipeline_run"];
- const progress = getProgress(onboardingState, "starter", false);
- expect(progress).toBe(2);
- });
-
- test("returns 2 if only the finalStep is there", () => {
- const onboardingState: OnboardingChecklistItemName[] = ["starter_setup_completed"];
- const progress = getProgress(onboardingState, "starter", false);
+ const progress = getProgress(onboardingState, false);
expect(progress).toBe(2);
});
test("returns correct value if flow is local", () => {
const onboardingState: OnboardingChecklistItemName[] = ["device_verified"];
- const progress = getProgress(onboardingState, "starter", true);
+ const progress = getProgress(onboardingState, true);
expect(progress).toBe(0);
});
});
@@ -57,37 +54,28 @@ describe("returns the correct progress, depending on the current state", () => {
describe("checks if the item has downstream items", () => {
test("returns true if a downstream step is there", () => {
const itemName = "device_verified";
- const onboardingState: OnboardingChecklistItemName[] = [
- "device_verified",
- "pipeline_run",
- "starter_setup_completed"
- ];
- const hasDownStreamFinishded = checkDownstreamStep(itemName, onboardingState, "starter", false);
+ const onboardingState: OnboardingChecklistItemName[] = ["device_verified", "pipeline_run"];
+ const hasDownStreamFinishded = checkDownstreamStep(itemName, onboardingState, false);
expect(hasDownStreamFinishded).toBe(true);
});
test("returns false if there is no downstream step", () => {
const itemName = "pipeline_run";
const onboardingState: OnboardingChecklistItemName[] = ["pipeline_run"];
- const hasDownStreamFinishded = checkDownstreamStep(itemName, onboardingState, "starter", false);
+ const hasDownStreamFinishded = checkDownstreamStep(itemName, onboardingState, false);
expect(hasDownStreamFinishded).toBe(false);
});
test("returns correct value if starter setup is local", () => {
const itemName = "device_verified";
const onboardingState: OnboardingChecklistItemName[] = ["device_verified", "pipeline_run"];
- const hasDownStreamFinishded = checkDownstreamStep(itemName, onboardingState, "starter", true);
+ const hasDownStreamFinishded = checkDownstreamStep(itemName, onboardingState, true);
expect(hasDownStreamFinishded).toBe(false);
});
test("only final step is there", () => {
const itemName: OnboardingChecklistItemName = "stack_with_remote_orchestrator_created";
const onboarding_state: OnboardingChecklistItemName[] = ["production_setup_completed"];
- const hasDownStreamFinished = checkDownstreamStep(
- itemName,
- onboarding_state,
- "production",
- false
- );
+ const hasDownStreamFinished = checkDownstreamStep(itemName, onboarding_state, false);
expect(hasDownStreamFinished).toBe(true);
});
});
@@ -95,12 +83,12 @@ describe("checks if the item has downstream items", () => {
describe("checks if the correct length is returned", () => {
test("returns correct value for local starter setup", () => {
const isLocal = true;
- const items = getOnboardingLength("starter", isLocal);
- expect(items).toBe(1);
+ const items = getOnboardingLength(isLocal);
+ expect(items).toBe(3);
});
test("returns correct value for non-local starter setup", () => {
const isLocal = false;
- const items = getOnboardingLength("starter", isLocal);
- expect(items).toBe(2);
+ const items = getOnboardingLength(isLocal);
+ expect(items).toBe(4);
});
});
diff --git a/src/lib/onboarding.ts b/src/lib/onboarding.ts
index 778f479fe..658c50215 100644
--- a/src/lib/onboarding.ts
+++ b/src/lib/onboarding.ts
@@ -1,67 +1,36 @@
import { OnboardingChecklistItemName, OnboardingResponse } from "@/types/onboarding";
-export type Flow = "starter" | "production";
-
-export function getStarterSetupItems(isLocal: boolean): OnboardingChecklistItemName[] {
- return [...(isLocal ? [] : ["device_verified" as OnboardingChecklistItemName]), "pipeline_run"];
-}
-
-function getProductionSetupItems(): OnboardingChecklistItemName[] {
- return ["stack_with_remote_orchestrator_created", "pipeline_run_with_remote_orchestrator"];
+export function getSetupItems(isLocal: boolean): OnboardingChecklistItemName[] {
+ return [
+ ...(isLocal ? [] : ["device_verified" as OnboardingChecklistItemName]),
+ "pipeline_run",
+ "stack_with_remote_orchestrator_created",
+ "pipeline_run_with_remote_orchestrator"
+ ];
}
-const finalSteps: {
- starter: OnboardingChecklistItemName;
- production: OnboardingChecklistItemName;
-} = {
- starter: "starter_setup_completed",
- production: "production_setup_completed"
-};
-
-export function getStarterSetup(data: OnboardingResponse, isLocal: boolean) {
- const flowType: Flow = "starter";
- const finalStep = finalSteps[flowType];
- const itemsDone = getProgress(data, flowType, isLocal);
- const totalItems = getOnboardingLength(flowType, isLocal);
- return {
- itemsDone,
- totalItems,
- items: getStarterSetupItems(isLocal),
- isFinished: data.includes(finalStep),
- progress: (itemsDone / totalItems) * 100,
- finalStep: finalSteps.starter,
- hasItem: (item: OnboardingChecklistItemName) => hasOnboardingItem(item, data),
- getItem: (item: OnboardingChecklistItemName) => getItem(item, data, flowType)
- };
-}
+const finalStep: OnboardingChecklistItemName = "production_setup_completed";
-export function getProductionSetup(data: OnboardingResponse) {
- const flowType: Flow = "production";
- const finalStep = finalSteps[flowType];
- const itemsDone = getProgress(data, flowType);
- const totalItems = getOnboardingLength(flowType);
+export function getOnboardingSetup(data: OnboardingResponse, isLocal: boolean) {
+ const itemsDone = getProgress(data, isLocal);
+ const totalItems = getOnboardingLength(isLocal);
return {
itemsDone,
totalItems,
- items: getProductionSetupItems(),
+ items: getSetupItems(isLocal),
isFinished: data.includes(finalStep),
progress: (itemsDone / totalItems) * 100,
- finalStep: finalSteps.starter,
+ finalStep: finalStep,
hasItem: (item: OnboardingChecklistItemName) => hasOnboardingItem(item, data),
- getItem: (item: OnboardingChecklistItemName) => getItem(item, data, flowType)
+ getItem: (item: OnboardingChecklistItemName) => getItem(item, data)
};
}
-function getItem(
- item: OnboardingChecklistItemName,
- state: OnboardingResponse,
- flow: Flow,
- isLocal?: boolean
-) {
+function getItem(item: OnboardingChecklistItemName, state: OnboardingResponse, isLocal?: boolean) {
return {
isCompleted: state.includes(item),
- hasDownStreamStep: checkDownstreamStep(item, state, flow, isLocal || false),
- isActive: isStepActive(item, state, flow, isLocal || false)
+ hasDownStreamStep: checkDownstreamStep(item, state, isLocal || false),
+ isActive: isStepActive(item, state, isLocal || false)
};
}
@@ -72,12 +41,10 @@ function hasOnboardingItem(item: OnboardingChecklistItemName, state: OnboardingR
export function checkDownstreamStep(
item: OnboardingChecklistItemName,
state: OnboardingResponse,
- flow: Flow,
- isLocal?: boolean
+ isLocal: boolean
) {
- const order =
- flow === "starter" ? getStarterSetupItems(isLocal || false) : getProductionSetupItems();
- const withFinalStep = [...order, finalSteps[flow]];
+ const order = getSetupItems(isLocal);
+ const withFinalStep = [...order, finalStep];
const currentIndex = withFinalStep.indexOf(item);
if (currentIndex === -1) {
return false; // If the item is not found in the order array, return false
@@ -89,10 +56,9 @@ export function checkDownstreamStep(
function isStepActive(
step: OnboardingChecklistItemName,
state: OnboardingResponse,
- flowType: Flow,
isLocal: boolean
): boolean {
- const flow = flowType === "starter" ? getStarterSetupItems(isLocal) : getProductionSetupItems();
+ const flow = getSetupItems(isLocal);
if (flow.length === 0) {
return false;
}
@@ -119,10 +85,9 @@ function isStepActive(
return state.includes(previousStep);
}
-export function getProgress(onboardingState: OnboardingResponse, flow: Flow, isLocal?: boolean) {
- const items =
- flow === "starter" ? getStarterSetupItems(isLocal || false) : getProductionSetupItems();
- const finalStep = finalSteps[flow];
+export function getProgress(onboardingState: OnboardingResponse, isLocal: boolean) {
+ const items = getSetupItems(isLocal);
+
// Filter out the finalStep from the checklist items
const filteredItems = items.filter((item) => item !== finalStep);
@@ -143,8 +108,7 @@ export function getProgress(onboardingState: OnboardingResponse, flow: Flow, isL
return highestIndex + 1;
}
-export function getOnboardingLength(flow: Flow, isLocal?: boolean) {
- const items =
- flow === "starter" ? getStarterSetupItems(isLocal || false) : getProductionSetupItems();
+export function getOnboardingLength(isLocal: boolean) {
+ const items = getSetupItems(isLocal);
return items.length;
}
diff --git a/src/types/onboarding.ts b/src/types/onboarding.ts
index e90d1c9c7..d7b2777f2 100644
--- a/src/types/onboarding.ts
+++ b/src/types/onboarding.ts
@@ -1,7 +1,6 @@
export type OnboardingChecklistItemName =
| "device_verified"
| "pipeline_run"
- | "starter_setup_completed"
| "stack_with_remote_orchestrator_created"
| "pipeline_run_with_remote_orchestrator"
| "production_setup_completed";