Skip to content

Commit fb521ef

Browse files
feat: update Onboarding (#955)
1 parent 698456e commit fb521ef

File tree

6 files changed

+73
-35
lines changed

6 files changed

+73
-35
lines changed

src/app/onboarding/Setup/Items.tsx

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import Help from "@/assets/icons/help.svg?react";
21
import { Codesnippet } from "@/components/CodeSnippet";
32
import { HelpBox } from "@/components/fallback-pages/Helpbox";
43
import { ChecklistItem } from "@/components/onboarding/ChecklistItem";
54
import { useServerInfo } from "@/data/server/info-query";
65
import { getLoginCommand } from "@/lib/login-command";
76
import { OnboardingStep } from "@/types/onboarding";
8-
import { Box, Skeleton, buttonVariants } from "@zenml-io/react-component-library";
7+
import { Skeleton } from "@zenml-io/react-component-library";
8+
import { OnboardingHelpBox } from "./helpbox";
99
import { PipelineSnippet } from "./pipeline-snippet";
1010
import { SetProject } from "./set-project";
1111

@@ -23,7 +23,7 @@ export function ConnectZenMLStep({ completed, hasDownstreamStep, active }: Onboa
2323
<div>
2424
<p className="mb-1 text-text-sm text-theme-text-secondary">Install ZenML</p>
2525
<Codesnippet
26-
code={`pip install "zenml==${data ? data.version : <Skeleton className="w-7" />}"`}
26+
code={`uv pip install "zenml==${data ? data.version : <Skeleton className="w-7" />}"`}
2727
/>
2828
</div>
2929
<div>
@@ -51,32 +51,30 @@ export function RunFirstPipeline({ active, completed, hasDownstreamStep }: Onboa
5151
<p className="mb-1 text-text-sm text-theme-text-secondary">Run the training pipeline.</p>
5252
<Codesnippet code="python run.py" />
5353
</div>
54-
<Box className="flex w-full flex-wrap items-center justify-between gap-y-1 p-2">
55-
<div className="flex items-center gap-[10px]">
56-
<div className="flex h-7 w-7 items-center justify-center rounded-sm bg-teal-25">
57-
<Help className="h-5 w-5 fill-teal-400" />
58-
</div>
59-
<p>Do you need help?</p>
60-
</div>
61-
<div className="flex items-center gap-1">
62-
<a
63-
target="_blank"
64-
rel="noopener noreferrer"
65-
className={buttonVariants({ intent: "secondary", emphasis: "subtle", size: "md" })}
66-
href="https://github.com/zenml-io/zenml/blob/main/examples/quickstart/README.md"
67-
>
68-
Open the Readme
69-
</a>
70-
<a
71-
target="_blank"
72-
rel="noopener noreferrer"
73-
className={buttonVariants({ intent: "primary", emphasis: "subtle", size: "md" })}
74-
href="https://docs.zenml.io/user-guides/starter-guide/create-an-ml-pipeline"
75-
>
76-
Browse our docs
77-
</a>
78-
</div>
79-
</Box>
54+
<OnboardingHelpBox href="https://docs.zenml.io/user-guides/starter-guide/create-an-ml-pipeline" />
55+
</div>
56+
</ChecklistItem>
57+
);
58+
}
59+
60+
export function DeployPipeline({ active, completed, hasDownstreamStep }: OnboardingStep) {
61+
return (
62+
<ChecklistItem
63+
active={active}
64+
hasDownstream={hasDownstreamStep}
65+
completed={completed}
66+
title="Deploy your pipeline (2 min)"
67+
>
68+
<div className="flex flex-col gap-5">
69+
<div className="space-y-1">
70+
<p>Deploy the pipeline</p>
71+
<p className="text-text-sm text-theme-text-secondary">
72+
Deploying your pipeline provides you with an API endpoint that you can call to trigger a
73+
pipeline run.
74+
</p>
75+
</div>
76+
<Codesnippet code="zenml pipeline deploy run.hello_pipeline" />
77+
<OnboardingHelpBox href="https://docs.zenml.io/concepts/deployment" />
8078
</div>
8179
</ChecklistItem>
8280
);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Help from "@/assets/icons/help.svg?react";
2+
import { Box, buttonVariants } from "@zenml-io/react-component-library";
3+
4+
type OnboardingHelpBoxProps = {
5+
href: string;
6+
};
7+
8+
export function OnboardingHelpBox({ href }: OnboardingHelpBoxProps) {
9+
return (
10+
<Box className="flex w-full flex-wrap items-center justify-between gap-y-1 p-2">
11+
<div className="flex items-center gap-[10px]">
12+
<div className="flex h-7 w-7 items-center justify-center rounded-sm bg-teal-25">
13+
<Help className="h-5 w-5 fill-teal-400" />
14+
</div>
15+
<p>Do you need help?</p>
16+
</div>
17+
<a
18+
target="_blank"
19+
rel="noopener noreferrer"
20+
className={buttonVariants({ intent: "primary", emphasis: "subtle", size: "md" })}
21+
href={href}
22+
>
23+
Browse our docs
24+
</a>
25+
</Box>
26+
);
27+
}

src/app/onboarding/Setup/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { OnboardingResponse } from "@/types/onboarding";
77
import { Skeleton } from "@zenml-io/react-component-library";
88
import { useEffect, useRef } from "react";
99
import { useNavigate } from "react-router-dom";
10-
import { ConnectZenMLStep, RunFirstPipeline } from "./Items";
10+
import { ConnectZenMLStep, DeployPipeline, RunFirstPipeline } from "./Items";
1111

1212
export function OnboardingSetupList() {
1313
const onboarding = useOnboarding({ refetchInterval: 5000 });
@@ -32,6 +32,7 @@ function OnboardingSetupListContent({ onboarding, isLocalServer }: Props) {
3232
const { getItem, isFinished } = getOnboardingSetup(onboarding, isLocalServer);
3333
const connectStep = getItem("device_verified");
3434
const pipelineStep = getItem("pipeline_run");
35+
const deployStep = getItem("pipeline_deployed");
3536
const isInitialFinished = useRef(isFinished);
3637

3738
useEffect(() => {
@@ -58,6 +59,13 @@ function OnboardingSetupListContent({ onboarding, isLocalServer }: Props) {
5859
hasDownstreamStep={pipelineStep.hasDownStreamStep}
5960
/>
6061
</li>
62+
<li>
63+
<DeployPipeline
64+
active={deployStep.isActive}
65+
completed={deployStep.isCompleted}
66+
hasDownstreamStep={deployStep.hasDownStreamStep}
67+
/>
68+
</li>
6169
</ul>
6270
);
6371
}

src/lib/onboarding.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ describe("returns the correct items based on the deployment type", () => {
66
test("doesnt return connect step for local deployment", () => {
77
const isLocal = true;
88
const items = getSetupItems(isLocal);
9-
expect(items).toEqual(["pipeline_run"]);
9+
expect(items).toEqual(["pipeline_run", "pipeline_deployed"]);
1010
});
1111

1212
test("includes the connect step for non-local deployments", () => {
1313
const isLocal = false;
1414
const items = getSetupItems(isLocal);
15-
expect(items).toEqual(["device_verified", "pipeline_run"]);
15+
expect(items).toEqual(["device_verified", "pipeline_run", "pipeline_deployed"]);
1616
});
1717
});
1818

@@ -75,11 +75,11 @@ describe("checks if the correct length is returned", () => {
7575
test("returns correct value for local starter setup", () => {
7676
const isLocal = true;
7777
const items = getOnboardingLength(isLocal);
78-
expect(items).toBe(1);
78+
expect(items).toBe(2);
7979
});
8080
test("returns correct value for non-local starter setup", () => {
8181
const isLocal = false;
8282
const items = getOnboardingLength(isLocal);
83-
expect(items).toBe(2);
83+
expect(items).toBe(3);
8484
});
8585
});

src/lib/onboarding.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { OnboardingChecklistItemName, OnboardingResponse } from "@/types/onboarding";
22

33
export function getSetupItems(isLocal: boolean): OnboardingChecklistItemName[] {
4-
return [...(isLocal ? [] : ["device_verified" as OnboardingChecklistItemName]), "pipeline_run"];
4+
return [
5+
...(isLocal ? [] : ["device_verified" as OnboardingChecklistItemName]),
6+
"pipeline_run",
7+
"pipeline_deployed"
8+
];
59
}
610

711
const finalStep: OnboardingChecklistItemName = "oss_onboarding_completed";

src/types/onboarding.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export type OnboardingChecklistItemName =
22
| "device_verified"
33
| "pipeline_run"
4+
| "pipeline_deployed"
45
| "oss_onboarding_completed";
56

67
export type OnboardingResponse = OnboardingChecklistItemName[];

0 commit comments

Comments
 (0)