Skip to content

Commit

Permalink
feat: namananand/ins 3605 add realease switch dropdown, share and del…
Browse files Browse the repository at this point in the history
…ete button to view pipeline page (#942)

Because

- add realease switch dropdown, share and delete button to view pipeline
page

This commit

- add realease switch dropdown, share and delete button to view pipeline
page

---------

Co-authored-by: EiffelFly <57251712+EiffelFly@users.noreply.github.com>
  • Loading branch information
iamnamananand996 and EiffelFly committed Feb 15, 2024
1 parent 78d903b commit a96bf9f
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/toolkit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@instill-ai/toolkit",
"version": "0.80.4-rc.11",
"version": "0.80.4-rc.13",
"description": "Instill AI's frontend toolkit",
"repository": "https://github.com/instill-ai/design-system.git",
"bugs": "https://github.com/instill-ai/design-system/issues",
Expand Down
2 changes: 1 addition & 1 deletion packages/toolkit/src/components/card-pipeline/Head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const Head = ({
<div className="flex flex-row p-3">
<div className="mr-auto flex flex-row gap-x-2">
<EntityAvatar
src={pipeline.owner?.profile?.avatar ?? null}
src={pipeline.owner?.profile_avatar ?? null}
className="h-8 w-8"
entityName={ownerID}
fallbackImg={
Expand Down
1 change: 1 addition & 0 deletions packages/toolkit/src/lib/vdp-sdk/pipeline/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export type PipelineRelease = {
visibility: Visibility;
openapi_schema: OpenAPIV3.Document;
metadata: GeneralRecord;
alias?: string;
};

export type PipelineTrace = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export const TabShare = () => {
<div className="flex flex-row">
<div className="mr-auto flex flex-row gap-x-2">
<EntityAvatar
src={pipeline.data?.owner?.profile.avatar ?? null}
src={pipeline.data?.owner?.profile_avatar ?? null}
entityName={pipeline.data?.owner_name ?? ""}
className="h-[30px] w-[30px]"
fallbackImg={
Expand Down
185 changes: 172 additions & 13 deletions packages/toolkit/src/view/pipeline/view-pipeline/Head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ import {
Tag,
TabMenu,
Skeleton,
Popover,
ScrollArea,
toast,
} from "@instill-ai/design-system";
import {
InstillStore,
Nullable,
isPublicPipeline,
toastInstillError,
useDeleteUserPipeline,
useEntity,
useInstillStore,
useOrganization,
Expand All @@ -22,19 +27,31 @@ import {
} from "../../../lib";
import { ClonePipelineDialog, EntityAvatar } from "../../../components";
import { EditMetadataDialog } from "./EditMetadataDialog";
import cn from "clsx";
import { Menu } from "./Menu";

const selector = (store: InstillStore) => ({
accessToken: store.accessToken,
enabledQuery: store.enabledQuery,
});

export const Head = () => {
type HeadProps = {
handleVersion: (version: string) => void;
currentVersion: string;
};

export const Head = (props: HeadProps) => {
const { accessToken, enabledQuery } = useInstillStore(useShallow(selector));

const { currentVersion, handleVersion } = props;

const router = useRouter();
const { id, entity } = router.query;
const [selectedTab, setSelectedTab] =
React.useState<Nullable<string>>("overview");

const [isOpen, setIsOpen] = React.useState<boolean>(false);

const entityObject = useEntity();

const user = useUser({
Expand Down Expand Up @@ -75,6 +92,29 @@ export const Head = () => {
enabledQuery: enabledQuery && entityObject.isSuccess,
});

const deletePipeline = useDeleteUserPipeline();
async function handleDeletePipeline() {
try {
await deletePipeline.mutateAsync({
pipelineName: pipeline.data?.name || "",
accessToken: accessToken ? accessToken : null,
});

toast({
title: "Pipeline deleted",
variant: "alert-success",
size: "large",
});
router.push(`/${entityObject.entity}/pipelines`);
} catch (error) {
toastInstillError({
title: "Something went wrong when delete the pipeline",
error,
toast,
});
}
}

return (
<React.Fragment>
<style jsx>{`
Expand All @@ -96,7 +136,7 @@ export const Head = () => {
<EntityAvatar
src={organization.data?.profile?.avatar ?? null}
entityName={organization.data?.name ?? ""}
className="h-6 w-6"
className="my-auto h-6 w-6"
fallbackImg={
<div className="flex h-6 w-6 rounded-full bg-semantic-bg-secondary">
<Icons.User02 className="m-auto h-4 w-4 stroke-semantic-fg-disabled" />
Expand All @@ -107,7 +147,7 @@ export const Head = () => {
<EntityAvatar
src={user.data?.profile?.avatar ?? null}
entityName={user.data?.name ?? ""}
className="h-6 w-6"
className="my-auto h-6 w-6"
fallbackImg={
<div className="flex h-6 w-6 rounded-full bg-semantic-bg-secondary">
<Icons.User02 className="m-auto h-4 w-4 stroke-semantic-fg-disabled" />
Expand All @@ -119,9 +159,9 @@ export const Head = () => {
<Skeleton className="h-6 w-6 rounded-full" />
)}

{pipeline.isSuccess ? (
{releases && pipeline.isSuccess ? (
<React.Fragment>
<div className="product-headings-heading-4">
<div className="my-auto product-headings-heading-4">
<span
onClick={() => {
router.push(`/${entity}`);
Expand All @@ -133,20 +173,97 @@ export const Head = () => {
<span className="text-semantic-fg-disabled">/</span>
<span className="text-semantic-fg-primary">{id}</span>
</div>

{releases.length && pipeline.isSuccess ? (
<Popover.Root
onOpenChange={() => setIsOpen(!isOpen)}
open={isOpen}
>
<Popover.Trigger asChild={true} className="my-auto">
<Button
className={cn(
"!h-8 !w-[145px] gap-x-1 !rounded-sm !border border-[#E1E6EF] !py-1 px-3 !transition-opacity !duration-300 !ease-in-out",
isOpen
? "border-opacity-100 !bg-semantic-accent-bg "
: "border-opacity-0"
)}
size="sm"
variant="tertiaryColour"
type="button"
onClick={() => setIsOpen(true)}
>
<Tag
size="sm"
variant="darkPurple"
className="h-6 gap-x-2"
>
Version{" "}
{currentVersion === "latest"
? releases[0]?.id
: currentVersion}
</Tag>
<Icons.ChevronDown className="h-4 w-4 stroke-semantic-fg-primary" />
</Button>
</Popover.Trigger>
<Popover.Content
side="top"
sideOffset={4}
align="start"
className="flex h-[180px] w-[145px] flex-col !rounded-sm !p-0"
>
<ScrollArea.Root>
<div className="flex flex-col gap-y-1 px-1.5 py-1">
{releases.length > 0 ? (
<React.Fragment>
{releases.map((release) => (
<VersionButton
key={release.id}
id={release.id}
currentVersion={
currentVersion === "latest"
? releases[0].id
: currentVersion
}
createTime={release.create_time}
onClick={() => {
handleVersion(release.id);
setIsOpen(false);
}}
/>
))}
</React.Fragment>
) : (
<div className="p-2 text-semantic-fg-disabled product-body-text-4-medium">
This pipeline has no released versions.
</div>
)}
</div>
</ScrollArea.Root>
</Popover.Content>
</Popover.Root>
) : null}
{pipeline.isSuccess ? (
<Tag className="!py-0" variant="darkBlue" size="sm">
{isPublicPipeline(pipeline.data) ? "Public" : "Private"}
<Tag
className="my-auto h-6 !border-0 !py-0"
variant="lightNeutral"
size="sm"
>
{isPublicPipeline(pipeline.data) ? (
<div className="flex flex-row gap-x-1">
<span className="my-auto">Public</span>
</div>
) : (
<div className="flex flex-row gap-x-1">
<span className="my-auto">Private</span>
<Icons.Lock03 className="my-auto h-3 w-3 stroke-semantic-fg-primary" />
</div>
)}
</Tag>
) : null}
</React.Fragment>
) : (
<PipelineNameSkeleton />
)}
{releases[0] ? (
<Tag className="!py-0" size="sm" variant="darkBlue">
{releases[0]?.id}
</Tag>
) : null}
</div>
</div>
{pipeline.isSuccess ? (
Expand All @@ -161,7 +278,7 @@ export const Head = () => {
/>
</div>
) : (
<div className="flex w-full flex-row items-center gap-x-2">
<div className="flex w-full flex-row items-center gap-x-2 p-1">
<p className="font-mono text-xs italic text-semantic-fg-disabled">
This is a placeholder brief of this pipeline
</p>
Expand Down Expand Up @@ -190,6 +307,13 @@ export const Head = () => {
</TabMenu.Root>
</div>
<div className="mt-auto flex flex-row gap-x-2 pb-1">
{pipeline.isSuccess ? (
<Menu
pipeline={pipeline.data}
handleDeletePipeline={handleDeletePipeline}
/>
) : null}

{pipeline.isSuccess ? (
<React.Fragment>
{me.isSuccess ? (
Expand Down Expand Up @@ -259,3 +383,38 @@ const HeaderControllerSkeleton = () => {
</React.Fragment>
);
};

const VersionButton = ({
id,
currentVersion,
onClick,
createTime,
}: {
id: string;
currentVersion: Nullable<string>;
createTime?: string;
onClick: () => void;
}) => {
return (
<Button
key={id}
className={cn(
"w-full !px-2 !py-1.5",
currentVersion === id ? "!bg-semantic-bg-secondary" : ""
)}
variant={"tertiaryColour"}
onClick={onClick}
>
<div className="flex w-full flex-row gap-x-2">
<div className="my-auto h-2 w-[9px] rounded-full bg-semantic-secondary-default"></div>
<p
className={cn(
"w-full text-left text-semantic-fg-secondary product-body-text-3-medium"
)}
>
Version {id}
</p>
</div>
</Button>
);
};
24 changes: 18 additions & 6 deletions packages/toolkit/src/view/pipeline/view-pipeline/InOutPut.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
Skeleton,
useToast,
} from "@instill-ai/design-system";
import { recursiveHelpers } from "../../pipeline-builder";
import { recursiveHelpers, useSortedReleases } from "../../pipeline-builder";
import { ComponentOutputs } from "../../pipeline-builder/components/ComponentOutputs";
import { getPipelineInputOutputSchema } from "../../pipeline-builder/lib/getPipelineInputOutputSchema";
import { LoadingSpin } from "../../../components";
Expand All @@ -34,7 +34,11 @@ const selector = (store: InstillStore) => ({
enabledQuery: store.enabledQuery,
});

export const InOutPut = () => {
type InOutPutProps = {
currentVersion: string;
};

export const InOutPut = ({ currentVersion }: InOutPutProps) => {
const { amplitudeIsInit } = useAmplitudeCtx();
const { accessToken, enabledQuery } = useInstillStore(useShallow(selector));
const router = useRouter();
Expand All @@ -53,13 +57,21 @@ export const InOutPut = () => {
accessToken,
});

const startComponent = React.useMemo(() => {
if (!pipeline.isSuccess) return null;
const releases = useSortedReleases({
pipelineName: entityObject.pipelineName,
accessToken,
enabledQuery: enabledQuery && entityObject.isSuccess,
});

const startComponent = React.useMemo(() => {
const pipelineVersion = releases.find(
(release) =>
release.id === currentVersion || release.alias === currentVersion
);
return (
pipeline.data.recipe.components.find((c) => c.id === "start") ?? null
pipelineVersion?.recipe.components.find((c) => c.id === "start") ?? null
);
}, [pipeline.isSuccess, pipeline.data]);
}, [releases, currentVersion]);

const { fields, form, Schema } = useStartOperatorTriggerPipelineForm({
mode: "demo",
Expand Down
Loading

0 comments on commit a96bf9f

Please sign in to comment.