Skip to content

Commit 25a505b

Browse files
committed
fix(webapp): minor webhook dashboard and deploy fixes
Paginate the Deliveries and Runs tabs on the webhook page independently (they shared one cursor, so paging one broke the other). Exclude webhook handler tasks from the generic test-task list, since they have their own console. Invalidate the engine endpoint cache when a redeploy changes an endpoint, so filter and routing changes take effect immediately on the deploying instance. Reset the console body editor when a sample or replay payload is loaded.
1 parent 8286abb commit 25a505b

5 files changed

Lines changed: 88 additions & 21 deletions

File tree

apps/webapp/app/components/ListPagination.tsx

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,31 @@ type List = {
1414
export const DirectionSchema = z.union([z.literal("forward"), z.literal("backward")]);
1515
export type Direction = z.infer<typeof DirectionSchema>;
1616

17-
export function ListPagination({ list, className }: { list: List; className?: string }) {
17+
export function ListPagination({
18+
list,
19+
className,
20+
cursorParam = "cursor",
21+
directionParam = "direction",
22+
}: {
23+
list: List;
24+
className?: string;
25+
cursorParam?: string;
26+
directionParam?: string;
27+
}) {
1828
const bothDisabled = !list.pagination.previous && !list.pagination.next;
1929

2030
return (
2131
<div className={cn("flex items-center", className)}>
22-
<PreviousButton cursor={list.pagination.previous} />
23-
<NextButton cursor={list.pagination.next} />
32+
<PreviousButton
33+
cursor={list.pagination.previous}
34+
cursorParam={cursorParam}
35+
directionParam={directionParam}
36+
/>
37+
<NextButton
38+
cursor={list.pagination.next}
39+
cursorParam={cursorParam}
40+
directionParam={directionParam}
41+
/>
2442
<div
2543
className={cn(
2644
"order-2 h-6 w-px bg-surface-control transition-colors peer-hover/next:bg-surface-control-hover peer-hover/prev:bg-surface-control-hover",
@@ -31,8 +49,16 @@ export function ListPagination({ list, className }: { list: List; className?: st
3149
);
3250
}
3351

34-
function PreviousButton({ cursor }: { cursor?: string }) {
35-
const path = useCursorPath(cursor, "backward");
52+
function PreviousButton({
53+
cursor,
54+
cursorParam,
55+
directionParam,
56+
}: {
57+
cursor?: string;
58+
cursorParam: string;
59+
directionParam: string;
60+
}) {
61+
const path = useCursorPath(cursor, "backward", cursorParam, directionParam);
3662

3763
return (
3864
<div className={cn("peer/prev order-1", !path && "pointer-events-none")}>
@@ -53,8 +79,16 @@ function PreviousButton({ cursor }: { cursor?: string }) {
5379
);
5480
}
5581

56-
function NextButton({ cursor }: { cursor?: string }) {
57-
const path = useCursorPath(cursor, "forward");
82+
function NextButton({
83+
cursor,
84+
cursorParam,
85+
directionParam,
86+
}: {
87+
cursor?: string;
88+
cursorParam: string;
89+
directionParam: string;
90+
}) {
91+
const path = useCursorPath(cursor, "forward", cursorParam, directionParam);
5892

5993
return (
6094
<div className={cn("peer/next order-3", !path && "pointer-events-none")}>
@@ -75,15 +109,20 @@ function NextButton({ cursor }: { cursor?: string }) {
75109
);
76110
}
77111

78-
function useCursorPath(cursor: string | undefined, direction: Direction) {
112+
function useCursorPath(
113+
cursor: string | undefined,
114+
direction: Direction,
115+
cursorParam: string,
116+
directionParam: string
117+
) {
79118
const location = useLocation();
80119

81120
if (!cursor) {
82121
return undefined;
83122
}
84123

85124
const search = new URLSearchParams(location.search);
86-
search.set("cursor", cursor);
87-
search.set("direction", direction);
125+
search.set(cursorParam, cursor);
126+
search.set(directionParam, direction);
88127
return location.pathname + "?" + search.toString();
89128
}

apps/webapp/app/components/webhookConsole/WebhookComposer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export function WebhookComposer({
7272
const [sourceTab, setSourceTab] = useState<SourceTab>("body");
7373
const [bodyDefault, setBodyDefault] = useState(defaultBody ?? DEFAULT_BODY);
7474
const bodyRef = useRef(bodyDefault);
75+
const [payloadReloadKey, setPayloadReloadKey] = useState(0);
7576
const [headerRows, setHeaderRows] = useState<HeaderRow[]>([]);
7677
const headerIdRef = useRef(0);
7778

@@ -89,6 +90,7 @@ export function WebhookComposer({
8990
(body: string, headers: Record<string, string>) => {
9091
setBodyDefault(body);
9192
bodyRef.current = body;
93+
setPayloadReloadKey((key) => key + 1);
9294
const entries = Object.entries(headers);
9395
if (entries.length > 0) {
9496
setHeaderRows(entries.map(([key, value]) => newHeaderRow(key, value)));
@@ -192,6 +194,7 @@ export function WebhookComposer({
192194
<div className="relative flex-1 overflow-hidden">
193195
<div className={cn("h-full", sourceTab !== "body" && "hidden")}>
194196
<JSONEditor
197+
key={payloadReloadKey}
195198
defaultValue={bodyDefault}
196199
readOnly={false}
197200
basicSetup

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ export class TestPresenter extends BasePresenter {
5252
SELECT bwt.id, version, slug, "filePath", bwt."friendlyId", bwt."triggerSource"
5353
FROM latest_workers
5454
JOIN ${sqlDatabaseSchema}."BackgroundWorkerTask" bwt ON bwt."workerId" = latest_workers.id
55-
WHERE bwt."triggerSource" NOT IN ('AGENT')
55+
WHERE bwt."triggerSource" NOT IN ('AGENT', 'WEBHOOK')
5656
ORDER BY slug ASC;`;
5757
} else {
5858
const currentDeployment = await findCurrentWorkerDeployment({ environmentId: envId });
59-
return (currentDeployment?.worker?.tasks ?? []).filter((t) => t.triggerSource !== "AGENT");
59+
return (currentDeployment?.worker?.tasks ?? []).filter(
60+
(t) => t.triggerSource !== "AGENT" && t.triggerSource !== "WEBHOOK"
61+
);
6062
}
6163
}
6264
}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.webhooks.$webhookParam/route.tsx

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,14 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
105105
const period = url.searchParams.get("period") ?? undefined;
106106
const from = parseFiniteInt(url.searchParams.get("from"));
107107
const to = parseFiniteInt(url.searchParams.get("to"));
108-
const cursor = url.searchParams.get("cursor") ?? undefined;
109-
const directionRaw = url.searchParams.get("direction") ?? undefined;
110-
const direction = directionRaw ? DirectionSchema.parse(directionRaw) : undefined;
108+
const deliveriesCursor = url.searchParams.get("deliveriesCursor") ?? undefined;
109+
const deliveriesDirectionRaw = url.searchParams.get("deliveriesDirection") ?? undefined;
110+
const deliveriesDirection = deliveriesDirectionRaw
111+
? DirectionSchema.parse(deliveriesDirectionRaw)
112+
: undefined;
113+
const runsCursor = url.searchParams.get("runsCursor") ?? undefined;
114+
const runsDirectionRaw = url.searchParams.get("runsDirection") ?? undefined;
115+
const runsDirection = runsDirectionRaw ? DirectionSchema.parse(runsDirectionRaw) : undefined;
111116

112117
const clickhouse = await clickhouseFactory.getClickhouseForOrganization(
113118
project.organizationId,
@@ -157,8 +162,8 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
157162
period,
158163
from,
159164
to,
160-
cursor,
161-
direction,
165+
cursor: runsCursor,
166+
direction: runsDirection,
162167
})
163168
.catch(() => null);
164169

@@ -171,8 +176,8 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
171176
period,
172177
from,
173178
to,
174-
cursor,
175-
direction,
179+
cursor: deliveriesCursor,
180+
direction: deliveriesDirection,
176181
})
177182
.catch(() => null);
178183

@@ -299,13 +304,29 @@ export default function Page() {
299304
{tab === "deliveries" ? (
300305
<Suspense fallback={null}>
301306
<TypedAwait resolve={deliveriesList} errorElement={null}>
302-
{(list) => (list ? <ListPagination list={list} /> : null)}
307+
{(list) =>
308+
list ? (
309+
<ListPagination
310+
list={list}
311+
cursorParam="deliveriesCursor"
312+
directionParam="deliveriesDirection"
313+
/>
314+
) : null
315+
}
303316
</TypedAwait>
304317
</Suspense>
305318
) : (
306319
<Suspense fallback={null}>
307320
<TypedAwait resolve={runList} errorElement={null}>
308-
{(list) => (list ? <ListPagination list={list} /> : null)}
321+
{(list) =>
322+
list ? (
323+
<ListPagination
324+
list={list}
325+
cursorParam="runsCursor"
326+
directionParam="runsDirection"
327+
/>
328+
) : null
329+
}
309330
</TypedAwait>
310331
</Suspense>
311332
)}

apps/webapp/app/v3/services/createBackgroundWorker.server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
import { taskMetadataCacheInstance } from "~/services/taskMetadataCacheInstance.server";
3232
import { generateFriendlyId } from "../friendlyIdentifiers";
3333
import { engine } from "../runEngine.server";
34+
import { webhookEngine } from "../webhookEngine.server";
3435
import {
3536
removeQueueConcurrencyLimits,
3637
updateEnvConcurrencyLimits,
@@ -756,6 +757,7 @@ export async function syncDeclarativeWebhooks(
756757
...filterData,
757758
},
758759
});
760+
webhookEngine.invalidateEndpoint(found.opaqueId);
759761
} else {
760762
const { id, friendlyId } = WebhookEndpointId.generate();
761763
await webhookPrisma.webhookEndpoint.create({

0 commit comments

Comments
 (0)