rename and delete experiments
This commit is contained in:
@@ -39,7 +39,7 @@ export default function OutputCell({
|
|||||||
{ enabled: disabledReason === null }
|
{ enabled: disabledReason === null }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!vars) return;
|
if (!vars) return null;
|
||||||
|
|
||||||
if (disabledReason)
|
if (disabledReason)
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,16 +1,67 @@
|
|||||||
import { Box, Center } from "@chakra-ui/react";
|
import {
|
||||||
|
Box,
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
BreadcrumbLink,
|
||||||
|
Button,
|
||||||
|
Center,
|
||||||
|
Flex,
|
||||||
|
HStack,
|
||||||
|
Icon,
|
||||||
|
Input,
|
||||||
|
Tooltip,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
import { useState, useRef, useEffect } from "react";
|
||||||
|
import { BsTrash } from "react-icons/bs";
|
||||||
|
import { RiFlaskLine } from "react-icons/ri";
|
||||||
import OutputsTable from "~/components/OutputsTable";
|
import OutputsTable from "~/components/OutputsTable";
|
||||||
import AppShell from "~/components/nav/AppShell";
|
import AppShell from "~/components/nav/AppShell";
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
|
import { useExperiment, useHandledAsyncCallback } from "~/utils/hooks";
|
||||||
|
|
||||||
|
const DeleteButton = (props: { experimentId: string }) => {
|
||||||
|
const mutation = api.experiments.delete.useMutation();
|
||||||
|
const utils = api.useContext();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const [onClick] = useHandledAsyncCallback(async () => {
|
||||||
|
const nextExperiment = await mutation.mutateAsync({ id: props.experimentId });
|
||||||
|
await utils.experiments.list.invalidate();
|
||||||
|
|
||||||
|
if (nextExperiment) {
|
||||||
|
await router.push({ pathname: "/experiments/[id]", query: { id: nextExperiment } });
|
||||||
|
}
|
||||||
|
}, [mutation, props.experimentId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button size="sm" variant="ghost" colorScheme="gray" fontWeight="normal" onClick={onClick}>
|
||||||
|
<Icon as={BsTrash} boxSize={4} mr={2} />
|
||||||
|
Delete Experiment
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default function Experiment() {
|
export default function Experiment() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const experiment = useExperiment();
|
||||||
|
const utils = api.useContext();
|
||||||
|
|
||||||
const experiment = api.experiments.get.useQuery(
|
const [label, setLabel] = useState(experiment.data?.label || "");
|
||||||
{ id: router.query.id as string },
|
useEffect(() => {
|
||||||
{ enabled: !!router.query.id }
|
setLabel(experiment.data?.label || "");
|
||||||
);
|
}, [experiment.data?.label]);
|
||||||
|
|
||||||
|
const updateMutation = api.experiments.update.useMutation();
|
||||||
|
const [onSaveLabel] = useHandledAsyncCallback(async () => {
|
||||||
|
if (label && label !== experiment.data?.label && experiment.data?.id) {
|
||||||
|
await updateMutation.mutateAsync({
|
||||||
|
id: experiment.data.id,
|
||||||
|
updates: { label: label },
|
||||||
|
});
|
||||||
|
await Promise.all([utils.experiments.list.invalidate(), utils.experiments.get.invalidate()]);
|
||||||
|
}
|
||||||
|
}, [updateMutation, experiment.data?.id, experiment.data?.label, label]);
|
||||||
|
|
||||||
if (!experiment.isLoading && !experiment.data) {
|
if (!experiment.isLoading && !experiment.data) {
|
||||||
return (
|
return (
|
||||||
@@ -25,6 +76,34 @@ export default function Experiment() {
|
|||||||
return (
|
return (
|
||||||
<AppShell title={experiment.data?.label}>
|
<AppShell title={experiment.data?.label}>
|
||||||
<Box minH="100vh" mb={50}>
|
<Box minH="100vh" mb={50}>
|
||||||
|
<HStack px={4} py={2}>
|
||||||
|
<Breadcrumb flex={1}>
|
||||||
|
<BreadcrumbItem>
|
||||||
|
<BreadcrumbLink>
|
||||||
|
<Flex alignItems="center">
|
||||||
|
<Icon as={RiFlaskLine} boxSize={4} mr={2} /> Experiments
|
||||||
|
</Flex>
|
||||||
|
</BreadcrumbLink>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
<BreadcrumbItem isCurrentPage>
|
||||||
|
<Input
|
||||||
|
size="sm"
|
||||||
|
value={label}
|
||||||
|
onChange={(e) => setLabel(e.target.value)}
|
||||||
|
onBlur={onSaveLabel}
|
||||||
|
borderWidth={1}
|
||||||
|
borderColor="transparent"
|
||||||
|
fontSize={16}
|
||||||
|
px={0}
|
||||||
|
minW={400}
|
||||||
|
flex={1}
|
||||||
|
_hover={{ borderColor: "gray.300" }}
|
||||||
|
_focus={{ borderColor: "blue.500", outline: "none" }}
|
||||||
|
/>
|
||||||
|
</BreadcrumbItem>
|
||||||
|
</Breadcrumb>
|
||||||
|
<DeleteButton experimentId={router.query.id as string} />
|
||||||
|
</HStack>
|
||||||
<OutputsTable experimentId={router.query.id as string | undefined} />
|
<OutputsTable experimentId={router.query.id as string | undefined} />
|
||||||
</Box>
|
</Box>
|
||||||
</AppShell>
|
</AppShell>
|
||||||
|
|||||||
@@ -69,4 +69,34 @@ export const experimentsRouter = createTRPCRouter({
|
|||||||
|
|
||||||
return exp;
|
return exp;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
update: publicProcedure
|
||||||
|
.input(z.object({ id: z.string(), updates: z.object({ label: z.string() }) }))
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
return await prisma.experiment.update({
|
||||||
|
where: {
|
||||||
|
id: input.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
label: input.updates.label,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
delete: publicProcedure.input(z.object({ id: z.string() })).mutation(async ({ input }) => {
|
||||||
|
await prisma.experiment.delete({
|
||||||
|
where: {
|
||||||
|
id: input.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return the ID of the newest existing experiment so the client can redirect to it
|
||||||
|
const newestExperiment = await prisma.experiment.findFirst({
|
||||||
|
orderBy: {
|
||||||
|
sortIndex: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return newestExperiment?.id;
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user