Skip to content

Commit

Permalink
[UI v2] Edit variables (PrefectHQ#16035)
Browse files Browse the repository at this point in the history
  • Loading branch information
desertaxle authored Nov 24, 2024
1 parent d64c0d7 commit db1288a
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 72 deletions.
21 changes: 19 additions & 2 deletions ui-v2/src/components/ui/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,39 @@ import * as React from "react";

import { cn } from "@/lib/utils";
import { buttonVariants } from "./styles";
import { Loader2 } from "lucide-react";

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
loading?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
(
{
className,
variant,
size,
asChild = false,
loading = false,
children,
...props
},
ref,
) => {
const Comp = asChild ? Slot : "button";

return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
disabled={loading}
{...props}
/>
>
{loading ? <Loader2 className="w-4 h-4 animate-spin" /> : children}
</Comp>
);
},
);
Expand Down
14 changes: 11 additions & 3 deletions ui-v2/src/components/variables/data-table/cells.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ import type { CellContext } from "@tanstack/react-table";
import type { components } from "@/api/prefect";
import { useToast } from "@/hooks/use-toast";

export const ActionsCell = ({
row,
}: CellContext<components["schemas"]["Variable"], unknown>) => {
type ActionsCellProps = CellContext<
components["schemas"]["Variable"],
unknown
> & {
onVariableEdit: (variable: components["schemas"]["Variable"]) => void;
};

export const ActionsCell = ({ row, onVariableEdit }: ActionsCellProps) => {
const id = row.original.id;
const queryClient = useQueryClient();
const { mutate: deleteVariable } = useMutation({
Expand Down Expand Up @@ -81,6 +86,9 @@ export const ActionsCell = ({
>
Copy Value
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onVariableEdit(row.original)}>
Edit
</DropdownMenuItem>
<DropdownMenuItem onClick={onVariableDelete}>Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
Expand Down
15 changes: 12 additions & 3 deletions ui-v2/src/components/variables/data-table/data-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
import { DataTable } from "@/components/ui/data-table";
import { Badge } from "@/components/ui/badge";
import { ActionsCell } from "./cells";
import { useCallback } from "react";
import { useCallback, useMemo } from "react";
import { SearchInput } from "@/components/ui/input";
import { TagsInput } from "@/components/ui/tags-input";
import {
Expand All @@ -24,7 +24,9 @@ import type React from "react";

const columnHelper = createColumnHelper<components["schemas"]["Variable"]>();

const columns = [
const createColumns = (
onVariableEdit: (variable: components["schemas"]["Variable"]) => void,
) => [
columnHelper.accessor("name", {
header: "Name",
}),
Expand Down Expand Up @@ -74,7 +76,7 @@ const columns = [
}),
columnHelper.display({
id: "actions",
cell: ActionsCell,
cell: (props) => <ActionsCell {...props} onVariableEdit={onVariableEdit} />,
}),
];

Expand All @@ -87,6 +89,7 @@ type VariablesDataTableProps = {
onColumnFiltersChange: OnChangeFn<ColumnFiltersState>;
sorting: components["schemas"]["VariableSort"];
onSortingChange: (sortKey: components["schemas"]["VariableSort"]) => void;
onVariableEdit: (variable: components["schemas"]["Variable"]) => void;
};

export const VariablesDataTable = ({
Expand All @@ -98,7 +101,13 @@ export const VariablesDataTable = ({
onColumnFiltersChange,
sorting,
onSortingChange,
onVariableEdit,
}: VariablesDataTableProps) => {
const columns = useMemo(
() => createColumns(onVariableEdit),
[onVariableEdit],
);

const nameSearchValue = columnFilters.find((filter) => filter.id === "name")
?.value as string;
const tagsSearchValue = columnFilters.find((filter) => filter.id === "tags")
Expand Down
86 changes: 86 additions & 0 deletions ui-v2/src/components/variables/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type { components } from "@/api/prefect";
import { getQueryService } from "@/api/service";
import { useToast } from "@/hooks/use-toast";
import { useMutation, useQueryClient } from "@tanstack/react-query";

type UseCreateVariableProps = {
onSuccess: () => void;
onError: (error: Error) => void;
};

export const useCreateVariable = ({
onSuccess,
onError,
}: UseCreateVariableProps) => {
const queryClient = useQueryClient();
const { toast } = useToast();

return useMutation({
mutationFn: (variable: components["schemas"]["VariableCreate"]) => {
return getQueryService().POST("/variables/", {
body: variable,
});
},
onSettled: async () => {
return await Promise.all([
queryClient.invalidateQueries({
predicate: (query) => query.queryKey[0] === "variables",
}),
queryClient.invalidateQueries({
predicate: (query) => query.queryKey[0] === "total-variable-count",
}),
]);
},
onSuccess: () => {
toast({
title: "Variable created",
});
onSuccess();
},
onError,
});
};

type UseUpdateVariableProps = {
onSuccess: () => void;
onError: (error: Error) => void;
};

type VariableUpdateWithId = components["schemas"]["VariableUpdate"] & {
id: string;
};

export const useUpdateVariable = ({
onSuccess,
onError,
}: UseUpdateVariableProps) => {
const queryClient = useQueryClient();
const { toast } = useToast();

return useMutation({
mutationFn: (variable: VariableUpdateWithId) => {
const { id, ...body } = variable;
return getQueryService().PATCH("/variables/{id}", {
params: { path: { id } },
body,
});
},
onSettled: async () => {
return await Promise.all([
queryClient.invalidateQueries({
predicate: (query) => query.queryKey[0] === "variables",
}),
queryClient.invalidateQueries({
predicate: (query) => query.queryKey[0] === "total-variable-count",
}),
]);
},
onSuccess: () => {
toast({
title: "Variable updated",
});
onSuccess();
},
onError,
});
};
34 changes: 28 additions & 6 deletions ui-v2/src/components/variables/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import {
BreadcrumbList,
} from "@/components/ui/breadcrumb";
import { Button } from "@/components/ui/button";
import { AddVariableDialog } from "@/components/variables/add-variable-dialog";
import {
VariableDialog,
type VariableDialogProps,
} from "@/components/variables/variable-dialog";
import { VariablesEmptyState } from "@/components/variables/empty-state";
import { PlusIcon } from "lucide-react";
import { useState } from "react";
import { useCallback, useState } from "react";
import { VariablesDataTable } from "./data-table";
import type {
ColumnFiltersState,
Expand Down Expand Up @@ -40,15 +43,33 @@ export const VariablesPage = ({
onSortingChange,
}: VariablesPageProps) => {
const [addVariableDialogOpen, setAddVariableDialogOpen] = useState(false);
const onAddVariableClick = () => {
const [variableToEdit, setVariableToEdit] = useState<
VariableDialogProps["existingVariable"] | undefined
>(undefined);

const onAddVariableClick = useCallback(() => {
setVariableToEdit(undefined);
setAddVariableDialogOpen(true);
};
}, []);

const handleVariableEdit = useCallback(
(variable: components["schemas"]["Variable"]) => {
setVariableToEdit(variable);
setAddVariableDialogOpen(true);
},
[],
);

const handleVariableDialogOpenChange = useCallback((open: boolean) => {
setAddVariableDialogOpen(open);
}, []);

return (
<>
<AddVariableDialog
<VariableDialog
open={addVariableDialogOpen}
onOpenChange={setAddVariableDialogOpen}
onOpenChange={handleVariableDialogOpenChange}
existingVariable={variableToEdit}
/>
<div className="flex flex-col gap-4 p-4">
<div className="flex items-center gap-2">
Expand Down Expand Up @@ -80,6 +101,7 @@ export const VariablesPage = ({
onColumnFiltersChange={onColumnFiltersChange}
sorting={sorting}
onSortingChange={onSortingChange}
onVariableEdit={handleVariableEdit}
/>
)}
</div>
Expand Down
Loading

0 comments on commit db1288a

Please sign in to comment.