Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(persistence): clear traces UI #2988

Merged
merged 2 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 89 additions & 10 deletions app/src/pages/projects/ProjectActionMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,64 @@ import {
} from "@arizeai/components";
import { ActionMenu, Flex, Item, Text } from "@arizeai/components";

import { ProjectActionMenuMutation } from "./__generated__/ProjectActionMenuMutation.graphql";
import { ProjectActionMenuClearMutation } from "./__generated__/ProjectActionMenuClearMutation.graphql";
import { ProjectActionMenuDeleteMutation } from "./__generated__/ProjectActionMenuDeleteMutation.graphql";

enum ProjectAction {
DELETE = "deleteProject",
CLEAR = "clearProject",
}

export function ProjectActionMenu({
projectId,
projectName,
onProjectDelete,
onProjectClear,
}: {
projectId: string;
projectName: string;
onProjectClear: () => void;
onProjectDelete: () => void;
}) {
const [confirmDialog, setConfirmDialog] = useState<ReactNode>(null);
const [commit] = useMutation<ProjectActionMenuMutation>(graphql`
mutation ProjectActionMenuMutation($projectId: GlobalID!) {
const canDelete = projectName !== "default";
const [commitDelete] = useMutation<ProjectActionMenuDeleteMutation>(graphql`
mutation ProjectActionMenuDeleteMutation($projectId: GlobalID!) {
deleteProject(id: $projectId) {
__typename
}
}
`);
const [commitClear] = useMutation<ProjectActionMenuClearMutation>(graphql`
mutation ProjectActionMenuClearMutation($projectId: GlobalID!) {
clearProject(id: $projectId) {
__typename
}
}
`);
const handleDelete = useCallback(() => {
startTransition(() => {
commit({
commitDelete({
variables: {
projectId: projectId,
},
});

onProjectDelete();
});
}, [commit, projectId, onProjectDelete]);
}, [commitDelete, projectId, onProjectDelete]);

const handleClear = useCallback(() => {
startTransition(() => {
commitClear({
variables: {
projectId: projectId,
},
});

onProjectClear();
});
}, [commitClear, projectId, onProjectClear]);

const onDelete = useCallback(() => {
setConfirmDialog(
Expand All @@ -72,6 +100,37 @@ export function ProjectActionMenu({
);
}, [handleDelete, projectName]);

const onClear = useCallback(() => {
setConfirmDialog(
<Dialog size="S" title="Clear Project">
<View padding="size-200">
<Text color="danger">
{`Are you sure you want to clear project ${projectName}? All traces and evaluations for this project will be deleted. This cannot be undone.`}
</Text>
</View>
<View
paddingEnd="size-200"
paddingTop="size-100"
paddingBottom="size-100"
borderTopColor="light"
borderTopWidth="thin"
>
<Flex direction="row" justifyContent="end">
<Button
variant="danger"
onClick={() => {
handleClear();
setConfirmDialog(null);
}}
>
Clear
</Button>
</Flex>
</View>
</Dialog>
);
}, [handleClear, projectName]);

return (
<div
// TODO: add this logic to the ActionMenu component
Expand All @@ -85,24 +144,44 @@ export function ProjectActionMenu({
buttonVariant="quiet"
align="end"
onAction={(action) => {
switch (action) {
case "deleteProject": {
switch (action as ProjectAction) {
case ProjectAction.DELETE: {
return onDelete();
}
case ProjectAction.CLEAR: {
return onClear();
}
}
}}
disabledKeys={canDelete ? [] : [ProjectAction.DELETE]}
>
<Item key={"deleteProject"}>
<Item key={ProjectAction.CLEAR}>
<Flex
direction={"row"}
gap="size-75"
justifyContent={"start"}
alignItems={"center"}
>
<Icon svg={<Icons.TrashOutline />} />
<Text>Delete</Text>
<Icon svg={<Icons.Refresh />} />
<Text>Clear Data</Text>
</Flex>
</Item>
{canDelete ? (
<Item key={ProjectAction.DELETE}>
<Flex
direction={"row"}
gap="size-75"
justifyContent={"start"}
alignItems={"center"}
>
<Icon svg={<Icons.TrashOutline />} />
<Text>Delete</Text>
</Flex>
</Item>
) : (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(null as any)
)}
</ActionMenu>
<DialogContainer
type="modal"
Expand Down
33 changes: 23 additions & 10 deletions app/src/pages/projects/ProjectsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ export function ProjectsPageContent({ timeRange }: { timeRange: TimeRange }) {
[notify, refetch]
);

const onClear = useCallback(
(projectName: string) => {
startTransition(() => {
refetch({}, { fetchPolicy: "store-and-network" });
notify({
variant: "success",
title: "Project Cleared",
message: `Project ${projectName} has been cleared of traces.`,
});
});
},
[notify, refetch]
);

return (
<Flex direction="column" flex="1 1 auto">
<View
Expand Down Expand Up @@ -144,8 +158,8 @@ export function ProjectsPageContent({ timeRange }: { timeRange: TimeRange }) {
>
<ProjectItem
project={project}
canDelete={project.name !== "default"} // the default project cannot be deleted
onProjectDelete={() => onDelete(project.name)}
onProjectClear={() => onClear(project.name)}
/>
</Link>
</li>
Expand Down Expand Up @@ -182,13 +196,13 @@ function ProjectIcon({
}
type ProjectItemProps = {
project: ProjectsPageProjectsFragment$data["projects"]["edges"][number]["project"];
canDelete: boolean;
onProjectDelete: () => void;
onProjectClear: () => void;
};
function ProjectItem({
project,
canDelete,
onProjectDelete,
onProjectClear,
}: ProjectItemProps) {
const {
endTime,
Expand Down Expand Up @@ -244,13 +258,12 @@ function ProjectItem({
</Text>
</Flex>
</Flex>
{canDelete && (
<ProjectActionMenu
projectId={project.id}
projectName={project.name}
onProjectDelete={onProjectDelete}
/>
)}
<ProjectActionMenu
projectId={project.id}
projectName={project.name}
onProjectDelete={onProjectDelete}
onProjectClear={onProjectClear}
/>
</Flex>

<Flex direction="row" justifyContent="space-between">
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading