Skip to content

Commit 0a11e8e

Browse files
committed
feat: add preset selector in TasksPage
1 parent bb83071 commit 0a11e8e

File tree

1 file changed

+92
-28
lines changed

1 file changed

+92
-28
lines changed

site/src/pages/TasksPage/TasksPage.tsx

Lines changed: 92 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import Skeleton from "@mui/material/Skeleton";
22
import { API } from "api/api";
33
import { getErrorDetail, getErrorMessage } from "api/errors";
44
import { disabledRefetchOptions } from "api/queries/util";
5-
import type { Template, TemplateVersionExternalAuth } from "api/typesGenerated";
5+
import type {
6+
Preset,
7+
Template,
8+
TemplateVersionExternalAuth,
9+
} from "api/typesGenerated";
610
import { ErrorAlert } from "components/Alert/ErrorAlert";
711
import { Avatar } from "components/Avatar/Avatar";
812
import { AvatarData } from "components/Avatar/AvatarData";
@@ -50,7 +54,7 @@ import { RedoIcon, RotateCcwIcon, SendIcon } from "lucide-react";
5054
import { AI_PROMPT_PARAMETER_NAME, type Task } from "modules/tasks/tasks";
5155
import { WorkspaceAppStatus } from "modules/workspaces/WorkspaceAppStatus/WorkspaceAppStatus";
5256
import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName";
53-
import { type FC, type ReactNode, useState } from "react";
57+
import { type FC, type ReactNode, useEffect, useState } from "react";
5458
import { Helmet } from "react-helmet-async";
5559
import { useMutation, useQuery, useQueryClient } from "react-query";
5660
import { Link as RouterLink, useNavigate } from "react-router-dom";
@@ -210,7 +214,11 @@ const TaskFormSection: FC<{
210214
);
211215
};
212216

213-
type CreateTaskMutationFnProps = { prompt: string; templateVersionId: string };
217+
type CreateTaskMutationFnProps = {
218+
prompt: string;
219+
templateVersionId: string;
220+
presetId: string | null;
221+
};
214222

215223
type TaskFormProps = {
216224
templates: Template[];
@@ -223,6 +231,8 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
223231
const [selectedTemplateId, setSelectedTemplateId] = useState<string>(
224232
templates[0].id,
225233
);
234+
const [presets, setPresets] = useState<Preset[] | null>(null);
235+
const [selectedPresetId, setSelectedPresetId] = useState<string | null>(null);
226236
const selectedTemplate = templates.find(
227237
(t) => t.id === selectedTemplateId,
228238
) as Template;
@@ -232,6 +242,28 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
232242
isPollingExternalAuth,
233243
isLoadingExternalAuth,
234244
} = useExternalAuth(selectedTemplate.active_version_id);
245+
246+
// Fetch presets when template changes
247+
const { data: presetsData } = useQuery<Preset[] | null, Error>({
248+
queryKey: ["template-version-presets", selectedTemplate.active_version_id],
249+
queryFn: () =>
250+
API.getTemplateVersionPresets(selectedTemplate.active_version_id),
251+
...disabledRefetchOptions,
252+
});
253+
254+
// Handle preset data changes
255+
useEffect(() => {
256+
if (presetsData) {
257+
setPresets(presetsData);
258+
// Set default preset if available
259+
const defaultPreset = presetsData.find((p: Preset) => p.Default);
260+
if (defaultPreset) {
261+
setSelectedPresetId(defaultPreset.ID);
262+
} else {
263+
setSelectedPresetId(null);
264+
}
265+
}
266+
}, [presetsData]);
235267
const missedExternalAuth = externalAuth?.filter(
236268
(auth) => !auth.optional && !auth.authenticated,
237269
);
@@ -243,8 +275,9 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
243275
mutationFn: async ({
244276
prompt,
245277
templateVersionId,
278+
presetId,
246279
}: CreateTaskMutationFnProps) =>
247-
data.createTask(prompt, user.id, templateVersionId),
280+
data.createTask(prompt, user.id, templateVersionId, presetId),
248281
onSuccess: async (task) => {
249282
await queryClient.invalidateQueries({
250283
queryKey: ["tasks"],
@@ -265,6 +298,7 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
265298
await createTaskMutation.mutateAsync({
266299
prompt,
267300
templateVersionId: selectedTemplate.active_version_id,
301+
presetId: selectedPresetId,
268302
});
269303
} catch (error) {
270304
const message = getErrorMessage(error, "Error creating task");
@@ -297,27 +331,50 @@ const TaskForm: FC<TaskFormProps> = ({ templates, onSuccess }) => {
297331
text-sm shadow-sm text-content-primary placeholder:text-content-secondary md:text-sm`}
298332
/>
299333
<div className="flex items-center justify-between pt-2">
300-
<Select
301-
name="templateID"
302-
onValueChange={(value) => setSelectedTemplateId(value)}
303-
defaultValue={templates[0].id}
304-
required
305-
>
306-
<SelectTrigger className="w-52 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3">
307-
<SelectValue placeholder="Select a template" />
308-
</SelectTrigger>
309-
<SelectContent>
310-
{templates.map((template) => {
311-
return (
312-
<SelectItem value={template.id} key={template.id}>
313-
<span className="overflow-hidden text-ellipsis block">
314-
{template.display_name || template.name}
315-
</span>
316-
</SelectItem>
317-
);
318-
})}
319-
</SelectContent>
320-
</Select>
334+
<div className="flex items-center gap-2">
335+
<Select
336+
name="templateID"
337+
onValueChange={(value) => setSelectedTemplateId(value)}
338+
defaultValue={templates[0].id}
339+
required
340+
>
341+
<SelectTrigger className="w-40 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3">
342+
<SelectValue placeholder="Select a template" />
343+
</SelectTrigger>
344+
<SelectContent>
345+
{templates.map((template) => {
346+
return (
347+
<SelectItem value={template.id} key={template.id}>
348+
<span className="overflow-hidden text-ellipsis block">
349+
{template.display_name || template.name}
350+
</span>
351+
</SelectItem>
352+
);
353+
})}
354+
</SelectContent>
355+
</Select>
356+
357+
{presets && presets.length > 0 && (
358+
<Select
359+
name="presetID"
360+
value={selectedPresetId === null ? undefined : selectedPresetId}
361+
onValueChange={(value) => setSelectedPresetId(value)}
362+
>
363+
<SelectTrigger className="w-40 text-xs [&_svg]:size-icon-xs border-0 bg-surface-secondary h-8 px-3">
364+
<SelectValue placeholder="Select a preset" />
365+
</SelectTrigger>
366+
<SelectContent>
367+
{presets.map((preset) => (
368+
<SelectItem value={preset.ID} key={preset.ID}>
369+
<span className="overflow-hidden text-ellipsis block">
370+
{preset.Name} {preset.Default && "(Default)"}
371+
</span>
372+
</SelectItem>
373+
))}
374+
</SelectContent>
375+
</Select>
376+
)}
377+
</div>
321378

322379
<div className="flex items-center gap-2">
323380
{missedExternalAuth && (
@@ -608,13 +665,20 @@ export const data = {
608665
prompt: string,
609666
userId: string,
610667
templateVersionId: string,
668+
presetId: string | null = null,
611669
): Promise<Task> {
612-
const presets = await API.getTemplateVersionPresets(templateVersionId);
613-
const defaultPreset = presets?.find((p) => p.Default);
670+
// If no preset is selected, get the default preset
671+
let preset_id: string | undefined = presetId || undefined;
672+
if (!preset_id) {
673+
const presets = await API.getTemplateVersionPresets(templateVersionId);
674+
const defaultPreset = presets?.find((p) => p.Default);
675+
preset_id = defaultPreset?.ID;
676+
}
677+
614678
const workspace = await API.createWorkspace(userId, {
615679
name: `task-${generateWorkspaceName()}`,
616680
template_version_id: templateVersionId,
617-
template_version_preset_id: defaultPreset?.ID,
681+
template_version_preset_id: preset_id || undefined,
618682
rich_parameter_values: [
619683
{ name: AI_PROMPT_PARAMETER_NAME, value: prompt },
620684
],

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy