Skip to content

Commit c03b773

Browse files
committed
Show templates list and apply values when selected
1 parent 7cf0643 commit c03b773

2 files changed

Lines changed: 136 additions & 7 deletions

File tree

apps/webapp/app/presenters/v3/TestTaskPresenter.server.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
import { ScheduledTaskPayload, parsePacket, prettyPrintPacket } from "@trigger.dev/core/v3";
2-
import { type RuntimeEnvironmentType, type TaskRunStatus } from "@trigger.dev/database";
2+
import {
3+
type TaskRunTemplate,
4+
type RuntimeEnvironmentType,
5+
type TaskRunStatus,
6+
} from "@trigger.dev/database";
37
import { type PrismaClient, prisma, sqlDatabaseSchema } from "~/db.server";
48
import { getTimezones } from "~/utils/timezones.server";
59
import { findCurrentWorkerDeployment } from "~/v3/models/workerDeployment.server";
610
import { queueTypeFromType } from "./QueueRetrievePresenter.server";
711
import parse from "parse-duration";
812

13+
export type RunTemplate = TaskRunTemplate & {
14+
scheduledTaskPayload?: ScheduledRun["payload"];
15+
};
16+
917
type TestTaskOptions = {
1018
userId: string;
1119
projectId: string;
@@ -40,6 +48,7 @@ export type TestTaskResult =
4048
latestVersions: string[];
4149
disableVersionSelection: boolean;
4250
allowArbitraryQueues: boolean;
51+
taskRunTemplates: TaskRunTemplate[];
4352
}
4453
| {
4554
foundTask: true;
@@ -51,6 +60,7 @@ export type TestTaskResult =
5160
latestVersions: string[];
5261
disableVersionSelection: boolean;
5362
allowArbitraryQueues: boolean;
63+
taskRunTemplates: TaskRunTemplate[];
5464
}
5565
| {
5666
foundTask: false;
@@ -163,6 +173,17 @@ export class TestTaskPresenter {
163173
take: 20, // last 20 versions should suffice
164174
});
165175

176+
const taskRunTemplates = await this.#prismaClient.taskRunTemplate.findMany({
177+
where: {
178+
projectId,
179+
taskSlug: task.slug,
180+
},
181+
orderBy: {
182+
createdAt: "desc",
183+
},
184+
take: 50,
185+
});
186+
166187
const latestVersions = backgroundWorkers.map((v) => v.version);
167188

168189
const disableVersionSelection = environment.type === "DEVELOPMENT";
@@ -247,6 +268,7 @@ export class TestTaskPresenter {
247268
latestVersions,
248269
disableVersionSelection,
249270
allowArbitraryQueues,
271+
taskRunTemplates,
250272
};
251273
case "SCHEDULED": {
252274
const possibleTimezones = getTimezones();
@@ -266,7 +288,7 @@ export class TestTaskPresenter {
266288
runs: (
267289
await Promise.all(
268290
latestRuns.map(async (r) => {
269-
const payload = await getScheduleTaskRunPayload(r);
291+
const payload = await getScheduleTaskRunPayload(r.payload, r.payloadType);
270292

271293
if (payload.success) {
272294
return {
@@ -281,6 +303,21 @@ export class TestTaskPresenter {
281303
latestVersions,
282304
disableVersionSelection,
283305
allowArbitraryQueues,
306+
taskRunTemplates: await Promise.all(
307+
taskRunTemplates.map(async (t) => {
308+
const scheduledTaskPayload = t.payload
309+
? await getScheduleTaskRunPayload(t.payload, t.payloadType)
310+
: undefined;
311+
312+
return {
313+
...t,
314+
scheduledTaskPayload:
315+
scheduledTaskPayload && scheduledTaskPayload.success
316+
? scheduledTaskPayload.data
317+
: undefined,
318+
};
319+
})
320+
),
284321
};
285322
}
286323
default: {
@@ -290,11 +327,11 @@ export class TestTaskPresenter {
290327
}
291328
}
292329

293-
async function getScheduleTaskRunPayload(run: RawRun) {
294-
const payload = await parsePacket({ data: run.payload, dataType: run.payloadType });
295-
if (!payload.timezone) {
296-
payload.timezone = "UTC";
330+
async function getScheduleTaskRunPayload(payload: string, payloadType: string) {
331+
const packet = await parsePacket({ data: payload, dataType: payloadType });
332+
if (!packet.timezone) {
333+
packet.timezone = "UTC";
297334
}
298-
const parsed = ScheduledTaskPayload.safeParse(payload);
335+
const parsed = ScheduledTaskPayload.safeParse(packet);
299336
return parsed;
300337
}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.test.tasks.$taskParam/route.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
type StandardRun,
4444
type StandardTaskResult,
4545
type ScheduledTaskResult,
46+
type RunTemplate,
4647
TestTaskPresenter,
4748
} from "~/presenters/v3/TestTaskPresenter.server";
4849
import { logger } from "~/services/logger.server";
@@ -235,6 +236,7 @@ export default function Page() {
235236
queues={queues}
236237
runs={result.runs}
237238
versions={result.latestVersions}
239+
templates={result.taskRunTemplates}
238240
disableVersionSelection={result.disableVersionSelection}
239241
allowArbitraryQueues={result.allowArbitraryQueues}
240242
/>
@@ -247,6 +249,7 @@ export default function Page() {
247249
queues={queues}
248250
runs={result.runs}
249251
versions={result.latestVersions}
252+
templates={result.taskRunTemplates}
250253
possibleTimezones={result.possibleTimezones}
251254
disableVersionSelection={result.disableVersionSelection}
252255
allowArbitraryQueues={result.allowArbitraryQueues}
@@ -267,13 +270,15 @@ function StandardTaskForm({
267270
queues,
268271
runs,
269272
versions,
273+
templates,
270274
disableVersionSelection,
271275
allowArbitraryQueues,
272276
}: {
273277
task: StandardTaskResult["task"];
274278
queues: Required<StandardTaskResult>["queue"][];
275279
runs: StandardRun[];
276280
versions: string[];
281+
templates: RunTemplate[];
277282
disableVersionSelection: boolean;
278283
allowArbitraryQueues: boolean;
279284
}) {
@@ -374,6 +379,20 @@ function StandardTaskForm({
374379
</Paragraph>
375380
</div>
376381
<div className="flex items-center gap-1.5">
382+
<RunTemplatesPopover
383+
templates={templates}
384+
onTemplateSelected={(template) => {
385+
setPayload(template.payload ?? "");
386+
setMetadata(template.metadata ?? "");
387+
// setTtlValue(template.ttlSeconds ?? "");
388+
// setConcurrencyKeyValue(template.concurrencyKey ?? "");
389+
setMaxAttemptsValue(template.maxAttempts ?? undefined);
390+
setMaxDurationValue(template.maxDurationSeconds ?? undefined);
391+
setMachineValue(template.machinePreset ?? undefined);
392+
setTagsValue(template.tags ?? []);
393+
setQueueValue(template.queue);
394+
}}
395+
/>
377396
<RecentRunsPopover
378397
runs={runs}
379398
onRunSelected={(run) => {
@@ -709,6 +728,7 @@ function ScheduledTaskForm({
709728
possibleTimezones,
710729
queues,
711730
versions,
731+
templates,
712732
disableVersionSelection,
713733
allowArbitraryQueues,
714734
}: {
@@ -717,6 +737,7 @@ function ScheduledTaskForm({
717737
possibleTimezones: string[];
718738
queues: Required<ScheduledTaskResult>["queue"][];
719739
versions: string[];
740+
templates: RunTemplate[];
720741
disableVersionSelection: boolean;
721742
allowArbitraryQueues: boolean;
722743
}) {
@@ -811,6 +832,22 @@ function ScheduledTaskForm({
811832
</Paragraph>
812833
</div>
813834
<div className="flex items-center gap-1.5">
835+
<RunTemplatesPopover
836+
templates={templates}
837+
onTemplateSelected={(template) => {
838+
// setTtlValue(template.ttlSeconds ?? "");
839+
// setConcurrencyKeyValue(template.concurrencyKey ?? "");
840+
setMaxAttemptsValue(template.maxAttempts ?? undefined);
841+
setMaxDurationValue(template.maxDurationSeconds ?? undefined);
842+
setMachineValue(template.machinePreset ?? undefined);
843+
setTagsValue(template.tags ?? []);
844+
setQueueValue(template.queue);
845+
setTimestampValue(template.scheduledTaskPayload?.timestamp);
846+
setLastTimestampValue(template.scheduledTaskPayload?.lastTimestamp);
847+
setExternalIdValue(template.scheduledTaskPayload?.externalId);
848+
setTimezoneValue(template.scheduledTaskPayload?.timezone ?? "UTC");
849+
}}
850+
/>
814851
<RecentRunsPopover
815852
runs={runs}
816853
onRunSelected={(run) => {
@@ -1234,6 +1271,61 @@ function RecentRunsPopover<T extends StandardRun | ScheduledRun>({
12341271
);
12351272
}
12361273

1274+
function RunTemplatesPopover({
1275+
templates,
1276+
onTemplateSelected,
1277+
}: {
1278+
templates: RunTemplate[];
1279+
onTemplateSelected: (run: RunTemplate) => void;
1280+
}) {
1281+
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
1282+
1283+
return (
1284+
<Popover open={isPopoverOpen} onOpenChange={setIsPopoverOpen}>
1285+
<PopoverTrigger asChild>
1286+
{templates.length === 0 ? (
1287+
<SimpleTooltip
1288+
button={
1289+
<Button type="button" variant="tertiary/small" LeadingIcon={StarIcon} disabled={true}>
1290+
Templates
1291+
</Button>
1292+
}
1293+
content="No templates yet"
1294+
/>
1295+
) : (
1296+
<Button type="button" variant="tertiary/small" LeadingIcon={StarIcon}>
1297+
Templates
1298+
</Button>
1299+
)}
1300+
</PopoverTrigger>
1301+
<PopoverContent className="min-w-[279px] p-0" align="end" sideOffset={6}>
1302+
<div className="max-h-80 overflow-y-auto">
1303+
<div className="p-1">
1304+
{templates.map((template) => (
1305+
<button
1306+
key={template.id}
1307+
type="button"
1308+
onClick={() => {
1309+
onTemplateSelected(template);
1310+
setIsPopoverOpen(false);
1311+
}}
1312+
className="flex w-full items-center gap-2 rounded-sm px-2 py-2 outline-none transition-colors focus-custom hover:bg-charcoal-900 "
1313+
>
1314+
<div className="flex flex-col items-start">
1315+
<Paragraph variant="small">{template.label}</Paragraph>
1316+
<div className="flex items-center gap-2 text-xs text-text-dimmed">
1317+
<DateTime date={template.createdAt} showTooltip={false} />
1318+
</div>
1319+
</div>
1320+
</button>
1321+
))}
1322+
</div>
1323+
</div>
1324+
</PopoverContent>
1325+
</Popover>
1326+
);
1327+
}
1328+
12371329
function CreateTemplateModal({
12381330
rawTestTaskFormData,
12391331
getCurrentPayload,

0 commit comments

Comments
 (0)