Skip to content

Commit

Permalink
Merge pull request #43 from classmodel/experiment-split-create-run
Browse files Browse the repository at this point in the history
Experiment split create and run
  • Loading branch information
sverhoeven authored Sep 24, 2024
2 parents fb215d7 + d05d1b4 commit fa4a9c5
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 100 deletions.
97 changes: 80 additions & 17 deletions apps/class-solid/src/components/Experiment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Button, buttonVariants } from "~/components/ui/button";
import { createArchive, toConfigBlob } from "~/lib/download";
import {
type Experiment,
addExperiment,
deleteExperiment,
duplicateExperiment,
modifyExperiment,
Expand Down Expand Up @@ -40,10 +41,61 @@ import {
DropdownMenuTrigger,
} from "./ui/dropdown-menu";

export function ExperimentSettingsDialog(experiment: Experiment) {
const [open, setOpen] = createSignal(
experiment.reference.output === undefined,
export function AddExperimentDialog(props: {
nextIndex: number;
onClose: () => void;
open: boolean;
}) {
const initialExperiment = () => {
return {
name: `My experiment ${props.nextIndex}`,
description: "",
reference: { config: {} },
permutations: [],
running: false,
};
};

function setOpen(value: boolean) {
if (!value) {
props.onClose();
}
}

return (
<Dialog open={props.open} onOpenChange={setOpen}>
<DialogContent class="min-w-[33%]">
<DialogHeader>
<DialogTitle class="mr-10">Experiment</DialogTitle>
</DialogHeader>
<ExperimentConfigForm
id="experiment-form"
experiment={initialExperiment()}
onSubmit={(newConfig) => {
props.onClose();
const { title, description, ...strippedConfig } = newConfig;
addExperiment(
strippedConfig,
title ?? initialExperiment().name,
description ?? initialExperiment().description,
);
}}
/>
<DialogFooter>
<Button type="submit" form="experiment-form">
Run
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

export function ExperimentSettingsDialog(props: {
experiment: Experiment;
experimentIndex: number;
}) {
const [open, setOpen] = createSignal(false);

return (
<Dialog open={open()} onOpenChange={setOpen}>
Expand All @@ -56,15 +108,15 @@ export function ExperimentSettingsDialog(experiment: Experiment) {
</DialogHeader>
<ExperimentConfigForm
id="experiment-form"
experiment={experiment}
experiment={props.experiment}
onSubmit={(newConfig) => {
setOpen(false);
const { title, description, ...strippedConfig } = newConfig;
modifyExperiment(
experiment.id,
props.experimentIndex,
strippedConfig,
title ?? experiment.name,
description ?? experiment.description,
title ?? props.experiment.name,
description ?? props.experiment.description,
);
}}
/>
Expand Down Expand Up @@ -133,7 +185,7 @@ function DownloadExperimentArchive(props: { experiment: Experiment }) {
onCleanup(() => URL.revokeObjectURL(objectUrl));
});

const filename = `class-${props.experiment.id}.zip`;
const filename = `class-${props.experiment.name}.zip`;
return (
<a href={url()} download={filename} type="application/json">
Config + output
Expand Down Expand Up @@ -162,31 +214,42 @@ function DownloadExperiment(props: { experiment: Experiment }) {
);
}

export function ExperimentCard(experiment: Experiment) {
export function ExperimentCard(props: {
experiment: Experiment;
experimentIndex: number;
}) {
const experiment = () => props.experiment;
const experimentIndex = () => props.experimentIndex;
return (
<Card class="w-[380px]">
<CardHeader>
<CardTitle>{experiment.name}</CardTitle>
<CardDescription>{experiment.description}</CardDescription>
<CardTitle>{experiment().name}</CardTitle>
<CardDescription>{experiment().description}</CardDescription>
</CardHeader>
<CardContent>
<PermutationsList experiment={experiment} />
<PermutationsList
experiment={experiment()}
experimentIndex={experimentIndex()}
/>
</CardContent>
<CardFooter>
<Show when={!experiment.running} fallback={<RunningIndicator />}>
<DownloadExperiment experiment={experiment} />
<ExperimentSettingsDialog {...experiment} />
<Show when={!experiment().running} fallback={<RunningIndicator />}>
<DownloadExperiment experiment={experiment()} />
<ExperimentSettingsDialog
experiment={experiment()}
experimentIndex={experimentIndex()}
/>
<Button
variant="outline"
title="Duplicate experiment"
onClick={() => duplicateExperiment(experiment.id)}
onClick={() => duplicateExperiment(experimentIndex())}
>
<MdiContentCopy />
</Button>
<Button
variant="outline"
title="Delete experiment"
onClick={() => deleteExperiment(experiment.id)}
onClick={() => deleteExperiment(experimentIndex())}
>
<MdiDelete />
</Button>
Expand Down
40 changes: 28 additions & 12 deletions apps/class-solid/src/components/PermutationsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function PermutationConfigForm(props: {
},
});

const handleSubmit: SubmitHandler<ClassConfig> = (values, event) => {
const handleSubmit: SubmitHandler<ClassConfig> = (values: ClassConfig) => {
// Parse only for validation
const data = classConfig.parse(values);
// TODO if parse fails, show error
Expand All @@ -80,7 +80,10 @@ function PermutationConfigForm(props: {
);
}

function AddPermutationButton(props: { experiment: Experiment }) {
function AddPermutationButton(props: {
experiment: Experiment;
experimentIndex: number;
}) {
const [open, setOpen] = createSignal(false);
const permutationName = `${props.experiment.permutations.length + 1}`;
return (
Expand All @@ -97,7 +100,7 @@ function AddPermutationButton(props: { experiment: Experiment }) {
<DialogHeader>
<DialogTitle class="mr-10">
Permutation on reference configuration of experiment{" "}
{props.experiment.id}
{props.experiment.name}
</DialogTitle>
</DialogHeader>
<PermutationConfigForm
Expand All @@ -107,7 +110,7 @@ function AddPermutationButton(props: { experiment: Experiment }) {
onSubmit={(config) => {
const { title, description, ...strippedConfig } = config;
setPermutationConfigInExperiment(
props.experiment.id,
props.experimentIndex,
-1,
strippedConfig,
title ?? permutationName,
Expand All @@ -127,6 +130,7 @@ function AddPermutationButton(props: { experiment: Experiment }) {

function EditPermutationButton(props: {
experiment: Experiment;
experimentIndex: number;
permutationIndex: number;
}) {
const [open, setOpen] = createSignal(false);
Expand All @@ -145,7 +149,7 @@ function EditPermutationButton(props: {
<DialogHeader>
<DialogTitle>
Permutation on reference configuration of experiment{" "}
{props.experiment.id}
{props.experiment.name}
</DialogTitle>
</DialogHeader>
<PermutationConfigForm
Expand All @@ -155,7 +159,7 @@ function EditPermutationButton(props: {
onSubmit={(config) => {
const { title, description, ...strippedConfig } = config;
setPermutationConfigInExperiment(
props.experiment.id,
props.experimentIndex,
props.permutationIndex,
strippedConfig,
title ?? permutationName,
Expand Down Expand Up @@ -208,6 +212,7 @@ function PermutationDifferenceButton(props: {

function PermutationInfo(props: {
experiment: Experiment;
experimentIndex: number;
permutationIndex: number;
perm: Permutation;
}) {
Expand All @@ -220,6 +225,7 @@ function PermutationInfo(props: {
/>
<EditPermutationButton
experiment={props.experiment}
experimentIndex={props.experimentIndex}
permutationIndex={props.permutationIndex}
/>
<DropdownMenu>
Expand All @@ -234,7 +240,7 @@ function PermutationInfo(props: {
<DropdownMenuItem
onClick={() =>
deletePermutationFromExperiment(
props.experiment.id,
props.experimentIndex,
props.permutationIndex,
)
}
Expand All @@ -243,15 +249,18 @@ function PermutationInfo(props: {
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
duplicatePermutation(props.experiment.id, props.permutationIndex);
duplicatePermutation(
props.experimentIndex,
props.permutationIndex,
);
}}
>
<MdiContentCopy /> Duplicate permutation
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
promotePermutationToExperiment(
props.experiment.id,
props.experimentIndex,
props.permutationIndex,
);
}}
Expand All @@ -261,7 +270,7 @@ function PermutationInfo(props: {
<DropdownMenuItem
onClick={() => {
swapPermutationAndReferenceConfiguration(
props.experiment.id,
props.experimentIndex,
props.permutationIndex,
);
}}
Expand All @@ -274,18 +283,25 @@ function PermutationInfo(props: {
);
}

export function PermutationsList(props: { experiment: Experiment }) {
export function PermutationsList(props: {
experimentIndex: number;
experiment: Experiment;
}) {
return (
<fieldset class="border">
<legend class="flex flex-row items-center gap-2">
Permutations
<AddPermutationButton experiment={props.experiment} />
<AddPermutationButton
experiment={props.experiment}
experimentIndex={props.experimentIndex}
/>
</legend>
<ul>
<For each={props.experiment.permutations}>
{(perm, permutationIndex) => (
<li>
<PermutationInfo
experimentIndex={props.experimentIndex}
experiment={props.experiment}
permutationIndex={permutationIndex()}
perm={perm}
Expand Down
Loading

0 comments on commit fa4a9c5

Please sign in to comment.