Skip to content

Commit

Permalink
chore: minor bugfixes (#579)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cahllagerfeld committed Apr 30, 2024
1 parent e121daa commit ff75470
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 41 deletions.
15 changes: 11 additions & 4 deletions src/app/onboarding/ProductionSetup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import ChevronDown from "@/assets/icons/chevron-down.svg?react";
import { Tick } from "@/components/Tick";
import { useServerSettings } from "@/data/server/get-server-settings";
import { useServerInfo } from "@/data/server/info-query";
import { PRODUCTION_SETUP_ITEMS } from "@/lib/constants";
import { getOnboardingState, getProgress, getStarterSetupItems } from "@/lib/onboarding";
import { checkIsLocalServer } from "@/lib/server";
import {
Collapsible,
CollapsibleContent,
Expand All @@ -10,21 +14,24 @@ import {
cn
} from "@zenml-io/react-component-library";
import { useState } from "react";
import { getOnboardingState, getProgress } from "@/lib/onboarding";
import {
CreateArtifactStore,
CreateNewStack,
CreateServiceConnector,
RunNewPipeline
} from "./Items";
import { PRODUCTION_SETUP_ITEMS, STARTER_SETUP_ITEMS } from "@/lib/constants";

export function ProductionSetupChecklist() {
const { isError, isPending, data } = useServerSettings({ throwOnError: true });
const serverInfo = useServerInfo();
const [open, setOpen] = useState(true);

if (isPending) return <Skeleton className="h-[200px] w-full" />;
if (isError) return null;
if (isPending || serverInfo.isPending) return <Skeleton className="h-[200px] w-full" />;
if (isError || serverInfo.isError) return null;

const STARTER_SETUP_ITEMS = getStarterSetupItems(
checkIsLocalServer(serverInfo.data.deployment_type || "other")
);

const onboardingState = getOnboardingState(data);
const isStarterSetupFinished =
Expand Down
6 changes: 6 additions & 0 deletions src/app/onboarding/StarterSetup/Items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ export function RunFirstPipeline({ onboardingState }: Props) {
</p>
<Codesnippet code="git clone --depth 1 https://github.com/zenml-io/zenml.git && cd zenml/examples/quickstart" />
</div>
<div>
<p className="mb-1 text-text-sm text-theme-text-secondary">
Initialize ZenML in the current directory
</p>
<Codesnippet code="zenml init" />
</div>
<div>
<p className="mb-1 text-text-sm text-theme-text-secondary">
Install the remaining requirements apart from ZenML
Expand Down
27 changes: 17 additions & 10 deletions src/app/onboarding/StarterSetup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import ChevronDown from "@/assets/icons/chevron-down.svg?react";
import { Tick } from "@/components/Tick";
import { useServerSettings } from "@/data/server/get-server-settings";
import { useServerInfo } from "@/data/server/info-query";
import { getOnboardingState, getProgress, getStarterSetupItems } from "@/lib/onboarding";
import { checkIsLocalServer } from "@/lib/server";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
RadialProgress,
Skeleton
} from "@zenml-io/react-component-library";
import ChevronDown from "@/assets/icons/chevron-down.svg?react";
import { useState } from "react";
import { useServerSettings } from "@/data/server/get-server-settings";
import { ConnectZenMLStep, RunFirstPipeline } from "./Items";
import { Tick } from "@/components/Tick";
import { getOnboardingState, getProgress } from "@/lib/onboarding";
import { STARTER_SETUP_ITEMS } from "@/lib/constants";

export function StarterSetupList() {
const { isError, isPending, data } = useServerSettings({ throwOnError: true });
const serverInfo = useServerInfo();
const [open, setOpen] = useState(true);

if (isPending) return <Skeleton className="h-[200px] w-full" />;
if (isError) return null;
if (isPending || serverInfo.isPending) return <Skeleton className="h-[200px] w-full" />;
if (isError || serverInfo.isError) return null;

const isLocalServer = checkIsLocalServer(serverInfo.data.deployment_type || "other");
const STARTER_SETUP_ITEMS = getStarterSetupItems(isLocalServer);

const doneItems = getProgress(getOnboardingState(data), STARTER_SETUP_ITEMS);
const progress = (doneItems / STARTER_SETUP_ITEMS.length) * 100;
Expand Down Expand Up @@ -60,9 +65,11 @@ export function StarterSetupList() {
</CollapsibleTrigger>
<CollapsibleContent className="border-t border-theme-border-moderate p-5">
<ul className="divide-y divide-theme-border-moderate">
<li className="py-5 first:pt-0 last:pb-0">
<ConnectZenMLStep onboardingState={getOnboardingState(data)} />
</li>
{!isLocalServer && (
<li className="py-5 first:pt-0 last:pb-0">
<ConnectZenMLStep onboardingState={getOnboardingState(data)} />
</li>
)}
<li className="py-5 first:pt-0 last:pb-0">
<RunFirstPipeline onboardingState={getOnboardingState(data)} />
</li>
Expand Down
2 changes: 1 addition & 1 deletion src/app/onboarding/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FallbackSupportCard, ResourcesCard } from "@/components/fallback-pages/Cards";
import { HeaderOnboardingBox } from "./Header";
import { StarterSetupList } from "./StarterSetup";
import { ProductionSetupChecklist } from "./ProductionSetup";
import { StarterSetupList } from "./StarterSetup";

export default function OnboardingPage() {
return (
Expand Down
40 changes: 24 additions & 16 deletions src/components/onboarding/ChecklistItem.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import Check from "@/assets/icons/check.svg?react";
import ChevronDown from "@/assets/icons/chevron-down.svg?react";
import { getServerSettingsKey, useServerSettings } from "@/data/server/get-server-settings";
import { useUpdateServerSettings } from "@/data/server/update-server-settings-mutation";
import { OnboardingChecklistItemName, OnboardingState } from "@/types/onboarding";
import { useQueryClient } from "@tanstack/react-query";
import {
Button,
Collapsible,
Expand All @@ -7,12 +13,6 @@ import {
} from "@zenml-io/react-component-library";
import { PropsWithChildren, ReactNode, useState } from "react";
import { Tick } from "../Tick";
import { useQueryClient } from "@tanstack/react-query";
import { useUpdateServerSettings } from "@/data/server/update-server-settings-mutation";
import { getServerSettingsKey, useServerSettings } from "@/data/server/get-server-settings";
import { OnboardingChecklistItemName, OnboardingState } from "@/types/onboarding";
import ChevronDown from "@/assets/icons/chevron-down.svg?react";
import Check from "@/assets/icons/check.svg?react";

type Props = {
completed: boolean;
Expand All @@ -37,10 +37,10 @@ export function ChecklistItem({
}
});

function markAsDone() {
function toggleItem(isDone: boolean) {
const newOnboardingState: OnboardingState = {
...data?.metadata?.onboarding_state,
[itemName]: true
[itemName]: isDone
};
mutate({ onboarding_state: newOnboardingState });
}
Expand All @@ -49,25 +49,34 @@ export function ChecklistItem({
<Collapsible open={open} onOpenChange={setOpen}>
<div className="flex w-full flex-col gap-3">
<div className="flex w-full justify-between gap-2">
{completed ? (
<button onClick={() => toggleItem(false)}>
<Tick className="shrink-0" />
</button>
) : (
<ProgressOutstanding className="shrink-0" />
)}
<CollapsibleTrigger className="w-full">
<ChecklistHeader title={title} completed={completed} />
</CollapsibleTrigger>
<div className="flex items-center gap-1">
{!completed && active && (
<Button
onClick={markAsDone}
onClick={() => toggleItem(true)}
className="items-center whitespace-nowrap"
intent="primary"
emphasis="subtle"
>
<Check className="h-5 w-5 fill-primary-600" /> <span>Mark as done</span>
</Button>
)}
<ChevronDown
className={` ${
open ? "" : "-rotate-90"
} h-5 w-5 shrink-0 rounded-md fill-neutral-500`}
/>
<CollapsibleTrigger>
<ChevronDown
className={` ${
open ? "" : "-rotate-90"
} h-5 w-5 shrink-0 rounded-md fill-neutral-500`}
/>
</CollapsibleTrigger>
</div>
</div>
{children && (
Expand All @@ -90,8 +99,7 @@ type HeaderProps = {
export function ChecklistHeader({ completed, title }: HeaderProps) {
return (
<div className="flex w-full items-center justify-between gap-2">
<div className="flex w-full items-center gap-2">
{completed ? <Tick /> : <ProgressOutstanding />}
<div className="flex w-full items-center">
<div
className={`font-semibold ${
completed ? "text-theme-text-tertiary line-through decoration-theme-text-tertiary" : ""
Expand Down
18 changes: 13 additions & 5 deletions src/layouts/AuthenticatedLayout/OnboardingItem.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import ChevronRight from "@/assets/icons/chevron-right.svg?react";
import { useServerSettings } from "@/data/server/get-server-settings";
import { PRODUCTION_SETUP_ITEMS, STARTER_SETUP_ITEMS } from "@/lib/constants";
import { getOnboardingState, getProgress } from "@/lib/onboarding";
import { useServerInfo } from "@/data/server/info-query";
import { PRODUCTION_SETUP_ITEMS } from "@/lib/constants";
import { getOnboardingState, getProgress, getStarterSetupItems } from "@/lib/onboarding";
import { checkIsLocalServer } from "@/lib/server";
import { routes } from "@/router/routes";
import { Box, ProgressBar, Skeleton, useSidebarContext } from "@zenml-io/react-component-library";
import { Link } from "react-router-dom";
import ChevronRight from "@/assets/icons/chevron-right.svg?react";

export function OnboardingItem() {
const { isPending, isError, data } = useServerSettings({ throwOnError: true });
const serverInfo = useServerInfo();
const { isOpen } = useSidebarContext();
if (isError) return null;
if (isPending) {
if (isError || serverInfo.isError) return null;
if (isPending || serverInfo.isPending) {
return (
<Box className="w-full rounded-md p-2">
<Skeleton className="h-5" />
</Box>
);
}

const STARTER_SETUP_ITEMS = getStarterSetupItems(
checkIsLocalServer(serverInfo.data.deployment_type || "other")
);

const onboardingState = getOnboardingState(data || {});
const isStarterSetupFinished =
getProgress(onboardingState, STARTER_SETUP_ITEMS) === STARTER_SETUP_ITEMS.length;
Expand Down
5 changes: 0 additions & 5 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ export const StackComponentTypes: StackComponentType[] = [
"model_registry"
];

export const STARTER_SETUP_ITEMS: OnboardingChecklistItemName[] = [
"connect_zenml",
"run_first_pipeline"
];

export const PRODUCTION_SETUP_ITEMS: OnboardingChecklistItemName[] = [
"create_service_connector",
"create_remote_artifact_store",
Expand Down
16 changes: 16 additions & 0 deletions src/lib/onboarding.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { describe, test, expect } from "vitest";
import { getStarterSetupItems } from "./onboarding";

describe("returns the correct items for the starter setup based on the deployment type", () => {
test("doesnt return connect step for local deployment", () => {
const isLocal = true;
const items = getStarterSetupItems(isLocal);
expect(items).toEqual(["run_first_pipeline"]);
});

test("includes the connect step for non-local deployments", () => {
const isLocal = false;
const items = getStarterSetupItems(isLocal);
expect(items).toEqual(["connect_zenml", "run_first_pipeline"]);
});
});
7 changes: 7 additions & 0 deletions src/lib/onboarding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ export function getProgress(
) {
return checklistItems.filter((item) => onboardingState[item]).length;
}

export function getStarterSetupItems(isLocal: boolean): OnboardingChecklistItemName[] {
return [
...(isLocal ? [] : ["connect_zenml" as OnboardingChecklistItemName]),
"run_first_pipeline"
];
}
23 changes: 23 additions & 0 deletions src/lib/server.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { DeploymentType } from "@/types/server";
import { describe, test, expect } from "vitest";
import { checkIsLocalServer } from "./server";

describe("returns if the server is deployed locally or not", () => {
test("returns true if the deployment type is local", () => {
const deploymentType: DeploymentType = "local";
const isLocal = checkIsLocalServer(deploymentType);
expect(isLocal).toBe(true);
});

test("returns true if the deployment type is docker", () => {
const deploymentType: DeploymentType = "docker";
const isLocal = checkIsLocalServer(deploymentType);
expect(isLocal).toBe(true);
});

test("returns false if the deployment type is not local and not docker", () => {
const deploymentType: DeploymentType = "other";
const isLocal = checkIsLocalServer(deploymentType);
expect(isLocal).toBe(false);
});
});
5 changes: 5 additions & 0 deletions src/lib/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { DeploymentType } from "@/types/server";

export function checkIsLocalServer(deploymentType: DeploymentType) {
return deploymentType === "local" || deploymentType === "docker";
}
1 change: 1 addition & 0 deletions src/types/server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { components } from "./core";

export type ServerInfo = components["schemas"]["ServerModel"];
export type DeploymentType = components["schemas"]["ServerDeploymentType"];

export type ServerSettings = components["schemas"]["ServerSettingsResponse"];
export type ServerSettigsUpdate = components["schemas"]["ServerSettingsUpdate"];
Expand Down

0 comments on commit ff75470

Please sign in to comment.