@shipfox/client-triggers 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/main.ts +1 -0
- package/.storybook/preview.css +8 -0
- package/.storybook/preview.tsx +89 -0
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +120 -0
- package/LICENSE +21 -0
- package/dist/components/events-filter-bar.d.ts +13 -0
- package/dist/components/events-filter-bar.d.ts.map +1 -0
- package/dist/components/events-filter-bar.js +198 -0
- package/dist/components/events-filter-bar.js.map +1 -0
- package/dist/components/events-list-states.d.ts +16 -0
- package/dist/components/events-list-states.d.ts.map +1 -0
- package/dist/components/events-list-states.js +105 -0
- package/dist/components/events-list-states.js.map +1 -0
- package/dist/components/events-list.d.ts +3 -0
- package/dist/components/events-list.d.ts.map +1 -0
- package/dist/components/events-list.js +97 -0
- package/dist/components/events-list.js.map +1 -0
- package/dist/components/events-list.stories.d.ts +53 -0
- package/dist/components/events-list.stories.d.ts.map +1 -0
- package/dist/components/events-list.stories.js +180 -0
- package/dist/components/events-list.stories.js.map +1 -0
- package/dist/components/trigger-event-detail.d.ts +13 -0
- package/dist/components/trigger-event-detail.d.ts.map +1 -0
- package/dist/components/trigger-event-detail.js +376 -0
- package/dist/components/trigger-event-detail.js.map +1 -0
- package/dist/components/trigger-event-detail.stories.d.ts +65 -0
- package/dist/components/trigger-event-detail.stories.d.ts.map +1 -0
- package/dist/components/trigger-event-detail.stories.js +181 -0
- package/dist/components/trigger-event-detail.stories.js.map +1 -0
- package/dist/components/trigger-event-result.d.ts +15 -0
- package/dist/components/trigger-event-result.d.ts.map +1 -0
- package/dist/components/trigger-event-result.js +48 -0
- package/dist/components/trigger-event-result.js.map +1 -0
- package/dist/components/trigger-event-row.d.ts +9 -0
- package/dist/components/trigger-event-row.d.ts.map +1 -0
- package/dist/components/trigger-event-row.js +91 -0
- package/dist/components/trigger-event-row.js.map +1 -0
- package/dist/components/trigger-source-icon.d.ts +20 -0
- package/dist/components/trigger-source-icon.d.ts.map +1 -0
- package/dist/components/trigger-source-icon.js +28 -0
- package/dist/components/trigger-source-icon.js.map +1 -0
- package/dist/components/types.d.ts +20 -0
- package/dist/components/types.d.ts.map +1 -0
- package/dist/components/types.js +3 -0
- package/dist/components/types.js.map +1 -0
- package/dist/hooks/api/trigger-events.d.ts +164 -0
- package/dist/hooks/api/trigger-events.d.ts.map +1 -0
- package/dist/hooks/api/trigger-events.js +122 -0
- package/dist/hooks/api/trigger-events.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/pages/events-page.d.ts +12 -0
- package/dist/pages/events-page.d.ts.map +1 -0
- package/dist/pages/events-page.js +82 -0
- package/dist/pages/events-page.js.map +1 -0
- package/dist/search.d.ts +23 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +28 -0
- package/dist/search.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/package.json +92 -0
- package/src/components/events-filter-bar.tsx +191 -0
- package/src/components/events-list-states.tsx +89 -0
- package/src/components/events-list.stories.tsx +141 -0
- package/src/components/events-list.test.tsx +173 -0
- package/src/components/events-list.tsx +107 -0
- package/src/components/trigger-event-detail.stories.tsx +169 -0
- package/src/components/trigger-event-detail.test.tsx +201 -0
- package/src/components/trigger-event-detail.tsx +317 -0
- package/src/components/trigger-event-result.test.ts +40 -0
- package/src/components/trigger-event-result.ts +40 -0
- package/src/components/trigger-event-row.tsx +86 -0
- package/src/components/trigger-source-icon.react.test.tsx +34 -0
- package/src/components/trigger-source-icon.test.ts +23 -0
- package/src/components/trigger-source-icon.tsx +36 -0
- package/src/components/types.ts +22 -0
- package/src/hooks/api/trigger-events.test.ts +252 -0
- package/src/hooks/api/trigger-events.ts +143 -0
- package/src/index.ts +4 -0
- package/src/pages/events-page.test.tsx +100 -0
- package/src/pages/events-page.tsx +79 -0
- package/src/search.test.ts +66 -0
- package/src/search.ts +38 -0
- package/test/setup.ts +35 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vercel.json +8 -0
- package/vitest.config.ts +68 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Badge } from '@shipfox/react-ui/badge';
|
|
3
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
4
|
+
import { Callout } from '@shipfox/react-ui/callout';
|
|
5
|
+
import { CodeBlock, CodeBlockBody, CodeBlockContent, CodeBlockCopyButton, CodeBlockFilename, CodeBlockFiles, CodeBlockHeader, CodeBlockItem } from '@shipfox/react-ui/code-block';
|
|
6
|
+
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
7
|
+
import { Icon } from '@shipfox/react-ui/icon';
|
|
8
|
+
import { RelativeTime } from '@shipfox/react-ui/relative-time';
|
|
9
|
+
import { Skeleton } from '@shipfox/react-ui/skeleton';
|
|
10
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
|
|
11
|
+
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
12
|
+
import { cn } from '@shipfox/react-ui/utils';
|
|
13
|
+
import { Link } from '@tanstack/react-router';
|
|
14
|
+
import { useMemo } from 'react';
|
|
15
|
+
import { useTriggerEventQuery } from '#hooks/api/trigger-events.js';
|
|
16
|
+
import { triggerEventResult } from './trigger-event-result.js';
|
|
17
|
+
import { TriggerSourceIcon } from './trigger-source-icon.js';
|
|
18
|
+
const PANEL_CLASS = 'min-h-0 rounded-8 border border-border-neutral-base bg-background-neutral-base';
|
|
19
|
+
export function TriggerEventDetail({ workspaceId, eventId, onBack }) {
|
|
20
|
+
const query = useTriggerEventQuery(eventId);
|
|
21
|
+
if (!eventId) return /*#__PURE__*/ _jsx(TriggerEventDetailPlaceholder, {});
|
|
22
|
+
if (query.data) {
|
|
23
|
+
return /*#__PURE__*/ _jsx(TriggerEventDetailView, {
|
|
24
|
+
workspaceId: workspaceId,
|
|
25
|
+
event: query.data,
|
|
26
|
+
onBack: onBack
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (query.isError) return /*#__PURE__*/ _jsx(TriggerEventDetailError, {
|
|
30
|
+
onBack: onBack,
|
|
31
|
+
onRetry: ()=>query.refetch()
|
|
32
|
+
});
|
|
33
|
+
return /*#__PURE__*/ _jsx(TriggerEventDetailLoading, {
|
|
34
|
+
onBack: onBack
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export function TriggerEventDetailView({ workspaceId, event, onBack }) {
|
|
38
|
+
const result = triggerEventResult(event);
|
|
39
|
+
const eventLabel = triggerEventDisplayLabel(event);
|
|
40
|
+
const fullEventLabel = triggerEventFullLabel(event);
|
|
41
|
+
const formattedPayload = useMemo(()=>JSON.stringify(event.payload ?? null, null, 2) ?? 'null', [
|
|
42
|
+
event.payload
|
|
43
|
+
]);
|
|
44
|
+
return /*#__PURE__*/ _jsxs("aside", {
|
|
45
|
+
"aria-label": "Event details",
|
|
46
|
+
className: cn(PANEL_CLASS, 'flex min-h-0 flex-col overflow-hidden'),
|
|
47
|
+
children: [
|
|
48
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
49
|
+
className: "flex shrink-0 flex-col gap-12 border-b border-border-neutral-base p-16",
|
|
50
|
+
children: [
|
|
51
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
52
|
+
type: "button",
|
|
53
|
+
variant: "transparentMuted",
|
|
54
|
+
size: "sm",
|
|
55
|
+
iconLeft: "arrowLeftLine",
|
|
56
|
+
className: "self-start min-[900px]:hidden",
|
|
57
|
+
onClick: onBack,
|
|
58
|
+
children: "Back to events"
|
|
59
|
+
}),
|
|
60
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
61
|
+
className: "flex min-w-0 items-start justify-between gap-12",
|
|
62
|
+
children: [
|
|
63
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
64
|
+
className: "flex min-w-0 flex-col gap-4",
|
|
65
|
+
children: [
|
|
66
|
+
/*#__PURE__*/ _jsxs(Tooltip, {
|
|
67
|
+
children: [
|
|
68
|
+
/*#__PURE__*/ _jsx(TooltipTrigger, {
|
|
69
|
+
asChild: true,
|
|
70
|
+
children: /*#__PURE__*/ _jsxs("button", {
|
|
71
|
+
type: "button",
|
|
72
|
+
"aria-label": fullEventLabel,
|
|
73
|
+
className: "flex min-w-0 items-center gap-6 rounded-6 border-0 bg-transparent p-0 text-left outline-none focus-visible:shadow-button-neutral-focus",
|
|
74
|
+
children: [
|
|
75
|
+
/*#__PURE__*/ _jsx(TriggerSourceIcon, {
|
|
76
|
+
provider: event.provider,
|
|
77
|
+
source: event.source,
|
|
78
|
+
"aria-hidden": "true",
|
|
79
|
+
className: "size-16 shrink-0 text-foreground-neutral-muted"
|
|
80
|
+
}),
|
|
81
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
82
|
+
as: "span",
|
|
83
|
+
variant: "label",
|
|
84
|
+
className: "truncate text-foreground-neutral-base",
|
|
85
|
+
children: eventLabel
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
})
|
|
89
|
+
}),
|
|
90
|
+
/*#__PURE__*/ _jsx(TooltipContent, {
|
|
91
|
+
children: /*#__PURE__*/ _jsx(Code, {
|
|
92
|
+
as: "span",
|
|
93
|
+
variant: "label",
|
|
94
|
+
className: "block max-w-[360px] break-words",
|
|
95
|
+
children: fullEventLabel
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
}),
|
|
100
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
101
|
+
size: "xs",
|
|
102
|
+
className: "truncate text-foreground-neutral-muted",
|
|
103
|
+
children: /*#__PURE__*/ _jsx(RelativeTime, {
|
|
104
|
+
value: event.received_at
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
]
|
|
108
|
+
}),
|
|
109
|
+
/*#__PURE__*/ _jsx(Badge, {
|
|
110
|
+
variant: result.badge,
|
|
111
|
+
size: "xs",
|
|
112
|
+
children: result.label
|
|
113
|
+
})
|
|
114
|
+
]
|
|
115
|
+
})
|
|
116
|
+
]
|
|
117
|
+
}),
|
|
118
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
119
|
+
className: "flex min-h-0 flex-1 flex-col gap-20 overflow-y-auto p-16 scrollbar",
|
|
120
|
+
children: [
|
|
121
|
+
/*#__PURE__*/ _jsx(EventRuns, {
|
|
122
|
+
workspaceId: workspaceId,
|
|
123
|
+
event: event
|
|
124
|
+
}),
|
|
125
|
+
/*#__PURE__*/ _jsx(EventPayload, {
|
|
126
|
+
payload: formattedPayload
|
|
127
|
+
})
|
|
128
|
+
]
|
|
129
|
+
})
|
|
130
|
+
]
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function triggerEventDisplayLabel(event) {
|
|
134
|
+
return event.event || event.source;
|
|
135
|
+
}
|
|
136
|
+
function triggerEventFullLabel(event) {
|
|
137
|
+
return [
|
|
138
|
+
event.source,
|
|
139
|
+
event.event
|
|
140
|
+
].filter(Boolean).join(' · ');
|
|
141
|
+
}
|
|
142
|
+
function TriggerEventDetailPlaceholder() {
|
|
143
|
+
return /*#__PURE__*/ _jsx("aside", {
|
|
144
|
+
"aria-label": "Event details",
|
|
145
|
+
className: cn(PANEL_CLASS, 'hidden min-h-[240px] items-center justify-center p-24 min-[900px]:flex'),
|
|
146
|
+
children: /*#__PURE__*/ _jsx(EmptyState, {
|
|
147
|
+
icon: "pulseLine",
|
|
148
|
+
variant: "compact",
|
|
149
|
+
title: "No event selected"
|
|
150
|
+
})
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
function TriggerEventDetailLoading({ onBack }) {
|
|
154
|
+
return /*#__PURE__*/ _jsxs("aside", {
|
|
155
|
+
"aria-label": "Event details",
|
|
156
|
+
className: cn(PANEL_CLASS, 'flex min-h-[320px] flex-col gap-16 p-16'),
|
|
157
|
+
children: [
|
|
158
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
159
|
+
type: "button",
|
|
160
|
+
variant: "transparentMuted",
|
|
161
|
+
size: "sm",
|
|
162
|
+
iconLeft: "arrowLeftLine",
|
|
163
|
+
className: "self-start min-[900px]:hidden",
|
|
164
|
+
onClick: onBack,
|
|
165
|
+
children: "Back to events"
|
|
166
|
+
}),
|
|
167
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
168
|
+
className: "flex flex-col gap-8",
|
|
169
|
+
children: [
|
|
170
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
171
|
+
className: "h-16 w-160"
|
|
172
|
+
}),
|
|
173
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
174
|
+
className: "h-12 w-120"
|
|
175
|
+
})
|
|
176
|
+
]
|
|
177
|
+
}),
|
|
178
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
179
|
+
className: "h-96"
|
|
180
|
+
}),
|
|
181
|
+
/*#__PURE__*/ _jsx(Skeleton, {
|
|
182
|
+
className: "h-160"
|
|
183
|
+
})
|
|
184
|
+
]
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function TriggerEventDetailError({ onBack, onRetry }) {
|
|
188
|
+
return /*#__PURE__*/ _jsxs("aside", {
|
|
189
|
+
"aria-label": "Event details",
|
|
190
|
+
className: cn(PANEL_CLASS, 'flex flex-col gap-16 p-16'),
|
|
191
|
+
children: [
|
|
192
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
193
|
+
type: "button",
|
|
194
|
+
variant: "transparentMuted",
|
|
195
|
+
size: "sm",
|
|
196
|
+
iconLeft: "arrowLeftLine",
|
|
197
|
+
className: "self-start min-[900px]:hidden",
|
|
198
|
+
onClick: onBack,
|
|
199
|
+
children: "Back to events"
|
|
200
|
+
}),
|
|
201
|
+
/*#__PURE__*/ _jsx(Callout, {
|
|
202
|
+
role: "alert",
|
|
203
|
+
type: "error",
|
|
204
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
205
|
+
className: "flex items-center justify-between gap-12",
|
|
206
|
+
children: [
|
|
207
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
208
|
+
size: "sm",
|
|
209
|
+
children: "Event detail could not be loaded."
|
|
210
|
+
}),
|
|
211
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
212
|
+
type: "button",
|
|
213
|
+
variant: "secondary",
|
|
214
|
+
size: "xs",
|
|
215
|
+
onClick: onRetry,
|
|
216
|
+
children: "Retry"
|
|
217
|
+
})
|
|
218
|
+
]
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
]
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
function EventRuns({ workspaceId, event }) {
|
|
225
|
+
if (event.decisions.length === 0) {
|
|
226
|
+
if (event.outcome === 'discarded') {
|
|
227
|
+
return /*#__PURE__*/ _jsx(Text, {
|
|
228
|
+
size: "sm",
|
|
229
|
+
className: "text-foreground-neutral-muted",
|
|
230
|
+
children: "No workflows are subscribed to this event."
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
return /*#__PURE__*/ _jsxs("section", {
|
|
236
|
+
"aria-labelledby": "trigger-event-runs-heading",
|
|
237
|
+
className: "flex flex-col gap-6",
|
|
238
|
+
children: [
|
|
239
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
240
|
+
id: "trigger-event-runs-heading",
|
|
241
|
+
size: "sm",
|
|
242
|
+
bold: true,
|
|
243
|
+
children: "Matched workflows"
|
|
244
|
+
}),
|
|
245
|
+
/*#__PURE__*/ _jsx("ul", {
|
|
246
|
+
className: "-mx-8 flex flex-col gap-1",
|
|
247
|
+
children: event.decisions.map((decision)=>/*#__PURE__*/ _jsx(DecisionRow, {
|
|
248
|
+
workspaceId: workspaceId,
|
|
249
|
+
decision: decision
|
|
250
|
+
}, decision.id))
|
|
251
|
+
})
|
|
252
|
+
]
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
function DecisionRow({ workspaceId, decision }) {
|
|
256
|
+
if (decision.decision !== 'triggered' || !decision.run_id || !decision.run_name) {
|
|
257
|
+
return /*#__PURE__*/ _jsxs("li", {
|
|
258
|
+
className: "flex min-w-0 items-start gap-8 rounded-6 px-8 py-6",
|
|
259
|
+
children: [
|
|
260
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
261
|
+
name: "cornerDownRightLine",
|
|
262
|
+
className: "mt-2 size-14 shrink-0 text-foreground-neutral-disabled",
|
|
263
|
+
"aria-hidden": "true"
|
|
264
|
+
}),
|
|
265
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
266
|
+
className: "flex min-w-0 flex-col gap-1",
|
|
267
|
+
children: [
|
|
268
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
269
|
+
size: "sm",
|
|
270
|
+
className: "min-w-0 truncate text-foreground-neutral-base",
|
|
271
|
+
children: decision.subscription_name
|
|
272
|
+
}),
|
|
273
|
+
decision.reason ? /*#__PURE__*/ _jsx(Text, {
|
|
274
|
+
size: "xs",
|
|
275
|
+
className: "text-foreground-highlight-error",
|
|
276
|
+
children: decision.reason
|
|
277
|
+
}) : /*#__PURE__*/ _jsx(Text, {
|
|
278
|
+
size: "xs",
|
|
279
|
+
className: "text-foreground-neutral-disabled",
|
|
280
|
+
children: "No run created"
|
|
281
|
+
})
|
|
282
|
+
]
|
|
283
|
+
})
|
|
284
|
+
]
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
return /*#__PURE__*/ _jsx("li", {
|
|
288
|
+
children: /*#__PURE__*/ _jsxs(Link, {
|
|
289
|
+
to: "/workspaces/$wid/projects/$pid/runs/$workflowRunId",
|
|
290
|
+
params: {
|
|
291
|
+
wid: workspaceId,
|
|
292
|
+
pid: decision.project_id,
|
|
293
|
+
workflowRunId: decision.run_id
|
|
294
|
+
},
|
|
295
|
+
className: "flex min-w-0 items-start gap-8 rounded-6 px-8 py-6 transition-colors hover:bg-background-components-hover focus-visible:shadow-border-interactive-with-active focus-visible:outline-none",
|
|
296
|
+
children: [
|
|
297
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
298
|
+
name: "cornerDownRightLine",
|
|
299
|
+
className: "mt-3 size-14 shrink-0 text-foreground-neutral-muted",
|
|
300
|
+
"aria-hidden": "true"
|
|
301
|
+
}),
|
|
302
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
303
|
+
className: "flex min-w-0 flex-col gap-1",
|
|
304
|
+
children: [
|
|
305
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
306
|
+
as: "span",
|
|
307
|
+
size: "sm",
|
|
308
|
+
className: "min-w-0 truncate text-foreground-neutral-base",
|
|
309
|
+
children: decision.subscription_name
|
|
310
|
+
}),
|
|
311
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
312
|
+
as: "span",
|
|
313
|
+
variant: "label",
|
|
314
|
+
className: "truncate text-foreground-neutral-muted",
|
|
315
|
+
children: decision.run_name
|
|
316
|
+
})
|
|
317
|
+
]
|
|
318
|
+
})
|
|
319
|
+
]
|
|
320
|
+
})
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
function EventPayload({ payload }) {
|
|
324
|
+
const data = [
|
|
325
|
+
{
|
|
326
|
+
language: 'json',
|
|
327
|
+
filename: 'payload.json',
|
|
328
|
+
code: payload
|
|
329
|
+
}
|
|
330
|
+
];
|
|
331
|
+
return /*#__PURE__*/ _jsxs("section", {
|
|
332
|
+
"aria-labelledby": "trigger-event-payload-heading",
|
|
333
|
+
className: "flex flex-col gap-6",
|
|
334
|
+
children: [
|
|
335
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
336
|
+
id: "trigger-event-payload-heading",
|
|
337
|
+
size: "sm",
|
|
338
|
+
bold: true,
|
|
339
|
+
children: "Payload"
|
|
340
|
+
}),
|
|
341
|
+
/*#__PURE__*/ _jsxs(CodeBlock, {
|
|
342
|
+
data: data,
|
|
343
|
+
className: "flex h-auto max-h-[min(360px,45vh)] flex-col rounded-8 bg-background-contrast-base shadow-none",
|
|
344
|
+
children: [
|
|
345
|
+
/*#__PURE__*/ _jsxs(CodeBlockHeader, {
|
|
346
|
+
className: "shrink-0 border-b border-border-contrast-base bg-background-contrast-base px-10 py-6",
|
|
347
|
+
children: [
|
|
348
|
+
/*#__PURE__*/ _jsx(CodeBlockFiles, {
|
|
349
|
+
children: (item)=>/*#__PURE__*/ _jsx(CodeBlockFilename, {
|
|
350
|
+
value: item.filename,
|
|
351
|
+
children: item.filename
|
|
352
|
+
})
|
|
353
|
+
}),
|
|
354
|
+
/*#__PURE__*/ _jsx(CodeBlockCopyButton, {})
|
|
355
|
+
]
|
|
356
|
+
}),
|
|
357
|
+
/*#__PURE__*/ _jsx(CodeBlockBody, {
|
|
358
|
+
className: "min-h-0 overflow-auto scrollbar",
|
|
359
|
+
children: (item)=>/*#__PURE__*/ _jsx(CodeBlockItem, {
|
|
360
|
+
value: item.filename,
|
|
361
|
+
lineNumbers: false,
|
|
362
|
+
className: "px-0 pb-0 [&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base [&>div]:dark:bg-background-contrast-base [&_code]:!text-foreground-neutral-on-color",
|
|
363
|
+
children: /*#__PURE__*/ _jsx(CodeBlockContent, {
|
|
364
|
+
language: "json",
|
|
365
|
+
syntaxHighlighting: false,
|
|
366
|
+
children: item.code
|
|
367
|
+
})
|
|
368
|
+
})
|
|
369
|
+
})
|
|
370
|
+
]
|
|
371
|
+
})
|
|
372
|
+
]
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
//# sourceMappingURL=trigger-event-detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/trigger-event-detail.tsx"],"sourcesContent":["import type {TriggerDecisionDto, TriggerEventDetailResponseDto} from '@shipfox/api-triggers-dto';\nimport {Badge} from '@shipfox/react-ui/badge';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {\n CodeBlock,\n CodeBlockBody,\n CodeBlockContent,\n CodeBlockCopyButton,\n CodeBlockFilename,\n CodeBlockFiles,\n CodeBlockHeader,\n CodeBlockItem,\n} from '@shipfox/react-ui/code-block';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {RelativeTime} from '@shipfox/react-ui/relative-time';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {Link} from '@tanstack/react-router';\nimport {useMemo} from 'react';\nimport {useTriggerEventQuery} from '#hooks/api/trigger-events.js';\nimport {triggerEventResult} from './trigger-event-result.js';\nimport {TriggerSourceIcon} from './trigger-source-icon.js';\n\nconst PANEL_CLASS =\n 'min-h-0 rounded-8 border border-border-neutral-base bg-background-neutral-base';\n\nexport interface TriggerEventDetailProps {\n workspaceId: string;\n eventId?: string | undefined;\n onBack: () => void;\n}\n\nexport function TriggerEventDetail({workspaceId, eventId, onBack}: TriggerEventDetailProps) {\n const query = useTriggerEventQuery(eventId);\n\n if (!eventId) return <TriggerEventDetailPlaceholder />;\n if (query.data) {\n return <TriggerEventDetailView workspaceId={workspaceId} event={query.data} onBack={onBack} />;\n }\n if (query.isError)\n return <TriggerEventDetailError onBack={onBack} onRetry={() => query.refetch()} />;\n return <TriggerEventDetailLoading onBack={onBack} />;\n}\n\nexport function TriggerEventDetailView({\n workspaceId,\n event,\n onBack,\n}: {\n workspaceId: string;\n event: TriggerEventDetailResponseDto;\n onBack: () => void;\n}) {\n const result = triggerEventResult(event);\n const eventLabel = triggerEventDisplayLabel(event);\n const fullEventLabel = triggerEventFullLabel(event);\n const formattedPayload = useMemo(\n () => JSON.stringify(event.payload ?? null, null, 2) ?? 'null',\n [event.payload],\n );\n\n return (\n <aside\n aria-label=\"Event details\"\n className={cn(PANEL_CLASS, 'flex min-h-0 flex-col overflow-hidden')}\n >\n <div className=\"flex shrink-0 flex-col gap-12 border-b border-border-neutral-base p-16\">\n <Button\n type=\"button\"\n variant=\"transparentMuted\"\n size=\"sm\"\n iconLeft=\"arrowLeftLine\"\n className=\"self-start min-[900px]:hidden\"\n onClick={onBack}\n >\n Back to events\n </Button>\n <div className=\"flex min-w-0 items-start justify-between gap-12\">\n <div className=\"flex min-w-0 flex-col gap-4\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={fullEventLabel}\n className=\"flex min-w-0 items-center gap-6 rounded-6 border-0 bg-transparent p-0 text-left outline-none focus-visible:shadow-button-neutral-focus\"\n >\n <TriggerSourceIcon\n provider={event.provider}\n source={event.source}\n aria-hidden=\"true\"\n className=\"size-16 shrink-0 text-foreground-neutral-muted\"\n />\n <Code as=\"span\" variant=\"label\" className=\"truncate text-foreground-neutral-base\">\n {eventLabel}\n </Code>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Code as=\"span\" variant=\"label\" className=\"block max-w-[360px] break-words\">\n {fullEventLabel}\n </Code>\n </TooltipContent>\n </Tooltip>\n <Text size=\"xs\" className=\"truncate text-foreground-neutral-muted\">\n <RelativeTime value={event.received_at} />\n </Text>\n </div>\n <Badge variant={result.badge} size=\"xs\">\n {result.label}\n </Badge>\n </div>\n </div>\n\n <div className=\"flex min-h-0 flex-1 flex-col gap-20 overflow-y-auto p-16 scrollbar\">\n <EventRuns workspaceId={workspaceId} event={event} />\n <EventPayload payload={formattedPayload} />\n </div>\n </aside>\n );\n}\n\nfunction triggerEventDisplayLabel(event: Pick<TriggerEventDetailResponseDto, 'event' | 'source'>) {\n return event.event || event.source;\n}\n\nfunction triggerEventFullLabel(event: Pick<TriggerEventDetailResponseDto, 'event' | 'source'>) {\n return [event.source, event.event].filter(Boolean).join(' · ');\n}\n\nfunction TriggerEventDetailPlaceholder() {\n return (\n <aside\n aria-label=\"Event details\"\n className={cn(\n PANEL_CLASS,\n 'hidden min-h-[240px] items-center justify-center p-24 min-[900px]:flex',\n )}\n >\n <EmptyState icon=\"pulseLine\" variant=\"compact\" title=\"No event selected\" />\n </aside>\n );\n}\n\nfunction TriggerEventDetailLoading({onBack}: {onBack: () => void}) {\n return (\n <aside\n aria-label=\"Event details\"\n className={cn(PANEL_CLASS, 'flex min-h-[320px] flex-col gap-16 p-16')}\n >\n <Button\n type=\"button\"\n variant=\"transparentMuted\"\n size=\"sm\"\n iconLeft=\"arrowLeftLine\"\n className=\"self-start min-[900px]:hidden\"\n onClick={onBack}\n >\n Back to events\n </Button>\n <div className=\"flex flex-col gap-8\">\n <Skeleton className=\"h-16 w-160\" />\n <Skeleton className=\"h-12 w-120\" />\n </div>\n <Skeleton className=\"h-96\" />\n <Skeleton className=\"h-160\" />\n </aside>\n );\n}\n\nfunction TriggerEventDetailError({onBack, onRetry}: {onBack: () => void; onRetry: () => void}) {\n return (\n <aside aria-label=\"Event details\" className={cn(PANEL_CLASS, 'flex flex-col gap-16 p-16')}>\n <Button\n type=\"button\"\n variant=\"transparentMuted\"\n size=\"sm\"\n iconLeft=\"arrowLeftLine\"\n className=\"self-start min-[900px]:hidden\"\n onClick={onBack}\n >\n Back to events\n </Button>\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex items-center justify-between gap-12\">\n <Text size=\"sm\">Event detail could not be loaded.</Text>\n <Button type=\"button\" variant=\"secondary\" size=\"xs\" onClick={onRetry}>\n Retry\n </Button>\n </div>\n </Callout>\n </aside>\n );\n}\n\nfunction EventRuns({\n workspaceId,\n event,\n}: {\n workspaceId: string;\n event: TriggerEventDetailResponseDto;\n}) {\n if (event.decisions.length === 0) {\n if (event.outcome === 'discarded') {\n return (\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n No workflows are subscribed to this event.\n </Text>\n );\n }\n return null;\n }\n\n return (\n <section aria-labelledby=\"trigger-event-runs-heading\" className=\"flex flex-col gap-6\">\n <Text id=\"trigger-event-runs-heading\" size=\"sm\" bold>\n Matched workflows\n </Text>\n <ul className=\"-mx-8 flex flex-col gap-1\">\n {event.decisions.map((decision) => (\n <DecisionRow key={decision.id} workspaceId={workspaceId} decision={decision} />\n ))}\n </ul>\n </section>\n );\n}\n\nfunction DecisionRow({workspaceId, decision}: {workspaceId: string; decision: TriggerDecisionDto}) {\n if (decision.decision !== 'triggered' || !decision.run_id || !decision.run_name) {\n return (\n <li className=\"flex min-w-0 items-start gap-8 rounded-6 px-8 py-6\">\n <Icon\n name=\"cornerDownRightLine\"\n className=\"mt-2 size-14 shrink-0 text-foreground-neutral-disabled\"\n aria-hidden=\"true\"\n />\n <div className=\"flex min-w-0 flex-col gap-1\">\n <Text size=\"sm\" className=\"min-w-0 truncate text-foreground-neutral-base\">\n {decision.subscription_name}\n </Text>\n {decision.reason ? (\n <Text size=\"xs\" className=\"text-foreground-highlight-error\">\n {decision.reason}\n </Text>\n ) : (\n <Text size=\"xs\" className=\"text-foreground-neutral-disabled\">\n No run created\n </Text>\n )}\n </div>\n </li>\n );\n }\n\n return (\n <li>\n <Link\n to=\"/workspaces/$wid/projects/$pid/runs/$workflowRunId\"\n params={{wid: workspaceId, pid: decision.project_id, workflowRunId: decision.run_id}}\n className=\"flex min-w-0 items-start gap-8 rounded-6 px-8 py-6 transition-colors hover:bg-background-components-hover focus-visible:shadow-border-interactive-with-active focus-visible:outline-none\"\n >\n <Icon\n name=\"cornerDownRightLine\"\n className=\"mt-3 size-14 shrink-0 text-foreground-neutral-muted\"\n aria-hidden=\"true\"\n />\n <span className=\"flex min-w-0 flex-col gap-1\">\n <Text as=\"span\" size=\"sm\" className=\"min-w-0 truncate text-foreground-neutral-base\">\n {decision.subscription_name}\n </Text>\n <Code as=\"span\" variant=\"label\" className=\"truncate text-foreground-neutral-muted\">\n {decision.run_name}\n </Code>\n </span>\n </Link>\n </li>\n );\n}\n\nfunction EventPayload({payload}: {payload: string}) {\n const data = [{language: 'json', filename: 'payload.json', code: payload}];\n\n return (\n <section aria-labelledby=\"trigger-event-payload-heading\" className=\"flex flex-col gap-6\">\n <Text id=\"trigger-event-payload-heading\" size=\"sm\" bold>\n Payload\n </Text>\n <CodeBlock\n data={data}\n className=\"flex h-auto max-h-[min(360px,45vh)] flex-col rounded-8 bg-background-contrast-base shadow-none\"\n >\n <CodeBlockHeader className=\"shrink-0 border-b border-border-contrast-base bg-background-contrast-base px-10 py-6\">\n <CodeBlockFiles>\n {(item) => <CodeBlockFilename value={item.filename}>{item.filename}</CodeBlockFilename>}\n </CodeBlockFiles>\n <CodeBlockCopyButton />\n </CodeBlockHeader>\n <CodeBlockBody className=\"min-h-0 overflow-auto scrollbar\">\n {(item) => (\n <CodeBlockItem\n value={item.filename}\n lineNumbers={false}\n className=\"px-0 pb-0 [&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base [&>div]:dark:bg-background-contrast-base [&_code]:!text-foreground-neutral-on-color\"\n >\n <CodeBlockContent language=\"json\" syntaxHighlighting={false}>\n {item.code}\n </CodeBlockContent>\n </CodeBlockItem>\n )}\n </CodeBlockBody>\n </CodeBlock>\n </section>\n );\n}\n"],"names":["Badge","Button","Callout","CodeBlock","CodeBlockBody","CodeBlockContent","CodeBlockCopyButton","CodeBlockFilename","CodeBlockFiles","CodeBlockHeader","CodeBlockItem","EmptyState","Icon","RelativeTime","Skeleton","Tooltip","TooltipContent","TooltipTrigger","Code","Text","cn","Link","useMemo","useTriggerEventQuery","triggerEventResult","TriggerSourceIcon","PANEL_CLASS","TriggerEventDetail","workspaceId","eventId","onBack","query","TriggerEventDetailPlaceholder","data","TriggerEventDetailView","event","isError","TriggerEventDetailError","onRetry","refetch","TriggerEventDetailLoading","result","eventLabel","triggerEventDisplayLabel","fullEventLabel","triggerEventFullLabel","formattedPayload","JSON","stringify","payload","aside","aria-label","className","div","type","variant","size","iconLeft","onClick","asChild","button","provider","source","aria-hidden","as","value","received_at","badge","label","EventRuns","EventPayload","filter","Boolean","join","icon","title","role","decisions","length","outcome","section","aria-labelledby","id","bold","ul","map","decision","DecisionRow","run_id","run_name","li","name","subscription_name","reason","to","params","wid","pid","project_id","workflowRunId","span","language","filename","code","item","lineNumbers","syntaxHighlighting"],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Decorator, StoryObj } from '@storybook/react';
|
|
2
|
+
import { TriggerEventDetailView } from './trigger-event-detail.js';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof TriggerEventDetailView;
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: string;
|
|
8
|
+
argos: {
|
|
9
|
+
modes: {
|
|
10
|
+
light: {
|
|
11
|
+
theme: string;
|
|
12
|
+
};
|
|
13
|
+
dark: {
|
|
14
|
+
theme: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
decorators: Decorator[];
|
|
20
|
+
args: {
|
|
21
|
+
workspaceId: string;
|
|
22
|
+
event: {
|
|
23
|
+
id: string;
|
|
24
|
+
event_ref: string;
|
|
25
|
+
origin: "integration" | "manual" | "cron";
|
|
26
|
+
workspace_id: string;
|
|
27
|
+
provider: string | null;
|
|
28
|
+
source: string;
|
|
29
|
+
event: string;
|
|
30
|
+
delivery_id: string | null;
|
|
31
|
+
connection_id: string | null;
|
|
32
|
+
outcome: "received" | "routed" | "discarded" | "failed" | "errored";
|
|
33
|
+
matched_count: number;
|
|
34
|
+
received_at: string;
|
|
35
|
+
processed_at: string | null;
|
|
36
|
+
created_at: string;
|
|
37
|
+
connection_name: string | null;
|
|
38
|
+
payload: Record<string, unknown> | null;
|
|
39
|
+
decisions: {
|
|
40
|
+
id: string;
|
|
41
|
+
received_event_id: string;
|
|
42
|
+
subscription_kind: "trigger" | "listener";
|
|
43
|
+
subscription_id: string;
|
|
44
|
+
subscription_name: string;
|
|
45
|
+
workflow_definition_id: string | null;
|
|
46
|
+
project_id: string | null;
|
|
47
|
+
workflow_run_id: string | null;
|
|
48
|
+
job_id: string | null;
|
|
49
|
+
matcher_kind: "on" | "until" | null;
|
|
50
|
+
matcher_ordinal: number | null;
|
|
51
|
+
decision: "triggered" | "filter-error" | "dispatch-error";
|
|
52
|
+
run_id: string | null;
|
|
53
|
+
run_name: string | null;
|
|
54
|
+
reason: string | null;
|
|
55
|
+
created_at: string;
|
|
56
|
+
}[];
|
|
57
|
+
};
|
|
58
|
+
onBack: () => undefined;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
export default meta;
|
|
62
|
+
type Story = StoryObj<typeof meta>;
|
|
63
|
+
export declare const Playground: Story;
|
|
64
|
+
export declare const Discarded: Story;
|
|
65
|
+
//# sourceMappingURL=trigger-event-detail.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trigger-event-detail.stories.d.ts","sourceRoot":"","sources":["../../src/components/trigger-event-detail.stories.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,SAAS,EAAQ,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAUhE,OAAO,EAAC,sBAAsB,EAAC,MAAM,2BAA2B,CAAC;AAoHjE,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBqC,CAAC;AAEhD,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAOnC,eAAO,MAAM,UAAU,EAAE,KAIxB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAKvB,CAAC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { argosScreenshot } from '@argos-ci/storybook/vitest';
|
|
3
|
+
import { RelativeTimeProvider } from '@shipfox/react-ui/relative-time';
|
|
4
|
+
import { createMemoryHistory, createRootRoute, createRoute, createRouter, Outlet, RouterProvider } from '@tanstack/react-router';
|
|
5
|
+
import { screen } from 'storybook/test';
|
|
6
|
+
import { TriggerEventDetailView } from './trigger-event-detail.js';
|
|
7
|
+
const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';
|
|
8
|
+
const PROJECT_ID = '22222222-2222-4222-8222-222222222222';
|
|
9
|
+
const RUN_ID = '33333333-3333-4333-8333-333333333333';
|
|
10
|
+
function minutesAgo(minutes) {
|
|
11
|
+
return new Date(Date.now() - minutes * 60_000).toISOString();
|
|
12
|
+
}
|
|
13
|
+
const withRouter = (Story)=>{
|
|
14
|
+
function StoryRoute() {
|
|
15
|
+
return /*#__PURE__*/ _jsx(RelativeTimeProvider, {
|
|
16
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
17
|
+
className: "min-h-screen bg-background-subtle-base p-24",
|
|
18
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
19
|
+
className: "ml-auto w-[400px]",
|
|
20
|
+
children: /*#__PURE__*/ _jsx(Story, {})
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const rootRoute = createRootRoute({
|
|
26
|
+
component: Outlet
|
|
27
|
+
});
|
|
28
|
+
const storyRoute = createRoute({
|
|
29
|
+
getParentRoute: ()=>rootRoute,
|
|
30
|
+
path: '/',
|
|
31
|
+
component: StoryRoute
|
|
32
|
+
});
|
|
33
|
+
const runRoute = createRoute({
|
|
34
|
+
getParentRoute: ()=>rootRoute,
|
|
35
|
+
path: '/workspaces/$wid/projects/$pid/runs/$workflowRunId',
|
|
36
|
+
component: StoryRoute
|
|
37
|
+
});
|
|
38
|
+
const router = createRouter({
|
|
39
|
+
history: createMemoryHistory({
|
|
40
|
+
initialEntries: [
|
|
41
|
+
'/'
|
|
42
|
+
]
|
|
43
|
+
}),
|
|
44
|
+
routeTree: rootRoute.addChildren([
|
|
45
|
+
storyRoute,
|
|
46
|
+
runRoute
|
|
47
|
+
])
|
|
48
|
+
});
|
|
49
|
+
return /*#__PURE__*/ _jsx(RouterProvider, {
|
|
50
|
+
router: router
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const routedEvent = {
|
|
54
|
+
id: '44444444-4444-4444-8444-444444444444',
|
|
55
|
+
event_ref: 'github:delivery-179:push',
|
|
56
|
+
origin: 'integration',
|
|
57
|
+
workspace_id: WORKSPACE_ID,
|
|
58
|
+
provider: 'github',
|
|
59
|
+
source: 'github_acme',
|
|
60
|
+
event: 'push',
|
|
61
|
+
delivery_id: 'delivery-179',
|
|
62
|
+
connection_id: '55555555-5555-4555-8555-555555555555',
|
|
63
|
+
connection_name: 'ShipfoxHQ Production',
|
|
64
|
+
outcome: 'routed',
|
|
65
|
+
matched_count: 2,
|
|
66
|
+
payload: {
|
|
67
|
+
ref: 'refs/heads/main',
|
|
68
|
+
repository: {
|
|
69
|
+
full_name: 'ShipfoxHQ/platform'
|
|
70
|
+
},
|
|
71
|
+
head_commit: {
|
|
72
|
+
id: '9f1a0f2c7a1b',
|
|
73
|
+
message: 'Deploy event detail'
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
received_at: minutesAgo(15),
|
|
77
|
+
processed_at: '2026-06-25T19:30:02.000Z',
|
|
78
|
+
created_at: '2026-06-25T19:30:00.000Z',
|
|
79
|
+
decisions: [
|
|
80
|
+
{
|
|
81
|
+
id: '66666666-6666-4666-8666-666666666666',
|
|
82
|
+
received_event_id: '44444444-4444-4444-8444-444444444444',
|
|
83
|
+
subscription_kind: 'trigger',
|
|
84
|
+
subscription_id: '77777777-7777-4777-8777-777777777777',
|
|
85
|
+
subscription_name: 'Deploy production',
|
|
86
|
+
workflow_definition_id: '88888888-8888-4888-8888-888888888888',
|
|
87
|
+
project_id: PROJECT_ID,
|
|
88
|
+
workflow_run_id: null,
|
|
89
|
+
job_id: null,
|
|
90
|
+
matcher_kind: null,
|
|
91
|
+
matcher_ordinal: null,
|
|
92
|
+
decision: 'triggered',
|
|
93
|
+
run_id: RUN_ID,
|
|
94
|
+
run_name: 'deploy-web #184',
|
|
95
|
+
reason: null,
|
|
96
|
+
created_at: '2026-06-25T19:30:02.000Z'
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: '99999999-9999-4999-8999-999999999999',
|
|
100
|
+
received_event_id: '44444444-4444-4444-8444-444444444444',
|
|
101
|
+
subscription_kind: 'trigger',
|
|
102
|
+
subscription_id: 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',
|
|
103
|
+
subscription_name: 'Mirror staging',
|
|
104
|
+
workflow_definition_id: 'bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb',
|
|
105
|
+
project_id: PROJECT_ID,
|
|
106
|
+
workflow_run_id: null,
|
|
107
|
+
job_id: null,
|
|
108
|
+
matcher_kind: null,
|
|
109
|
+
matcher_ordinal: null,
|
|
110
|
+
decision: 'triggered',
|
|
111
|
+
run_id: 'cccccccc-cccc-4ccc-8ccc-cccccccccccc',
|
|
112
|
+
run_name: 'mirror-staging #51',
|
|
113
|
+
reason: null,
|
|
114
|
+
created_at: '2026-06-25T19:30:02.000Z'
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
};
|
|
118
|
+
const discardedEvent = {
|
|
119
|
+
...routedEvent,
|
|
120
|
+
id: 'dddddddd-dddd-4ddd-8ddd-dddddddddddd',
|
|
121
|
+
event_ref: 'github:delivery-180:issue_comment',
|
|
122
|
+
event: 'issue_comment',
|
|
123
|
+
delivery_id: 'delivery-180',
|
|
124
|
+
outcome: 'discarded',
|
|
125
|
+
matched_count: 0,
|
|
126
|
+
payload: {
|
|
127
|
+
action: 'created',
|
|
128
|
+
comment: {
|
|
129
|
+
body: '/preview'
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
processed_at: '2026-06-25T19:33:01.000Z',
|
|
133
|
+
decisions: []
|
|
134
|
+
};
|
|
135
|
+
const meta = {
|
|
136
|
+
title: 'Triggers/EventDetail',
|
|
137
|
+
component: TriggerEventDetailView,
|
|
138
|
+
parameters: {
|
|
139
|
+
layout: 'fullscreen',
|
|
140
|
+
argos: {
|
|
141
|
+
modes: {
|
|
142
|
+
light: {
|
|
143
|
+
theme: 'light'
|
|
144
|
+
},
|
|
145
|
+
dark: {
|
|
146
|
+
theme: 'dark'
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
decorators: [
|
|
152
|
+
withRouter
|
|
153
|
+
],
|
|
154
|
+
args: {
|
|
155
|
+
workspaceId: WORKSPACE_ID,
|
|
156
|
+
event: routedEvent,
|
|
157
|
+
onBack: ()=>undefined
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
export default meta;
|
|
161
|
+
async function captureDetail(ctx, name) {
|
|
162
|
+
await screen.findByRole('complementary', {
|
|
163
|
+
name: 'Event details'
|
|
164
|
+
});
|
|
165
|
+
await argosScreenshot(ctx, name);
|
|
166
|
+
}
|
|
167
|
+
export const Playground = {
|
|
168
|
+
play: async (ctx)=>{
|
|
169
|
+
await captureDetail(ctx, 'Trigger Event Detail Playground');
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
export const Discarded = {
|
|
173
|
+
args: {
|
|
174
|
+
event: discardedEvent
|
|
175
|
+
},
|
|
176
|
+
play: async (ctx)=>{
|
|
177
|
+
await captureDetail(ctx, 'Trigger Event Detail Discarded');
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
//# sourceMappingURL=trigger-event-detail.stories.js.map
|