@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.
Files changed (95) hide show
  1. package/.storybook/main.ts +1 -0
  2. package/.storybook/preview.css +8 -0
  3. package/.storybook/preview.tsx +89 -0
  4. package/.turbo/turbo-build.log +2 -0
  5. package/.turbo/turbo-type$colon$emit.log +1 -0
  6. package/.turbo/turbo-type.log +1 -0
  7. package/CHANGELOG.md +120 -0
  8. package/LICENSE +21 -0
  9. package/dist/components/events-filter-bar.d.ts +13 -0
  10. package/dist/components/events-filter-bar.d.ts.map +1 -0
  11. package/dist/components/events-filter-bar.js +198 -0
  12. package/dist/components/events-filter-bar.js.map +1 -0
  13. package/dist/components/events-list-states.d.ts +16 -0
  14. package/dist/components/events-list-states.d.ts.map +1 -0
  15. package/dist/components/events-list-states.js +105 -0
  16. package/dist/components/events-list-states.js.map +1 -0
  17. package/dist/components/events-list.d.ts +3 -0
  18. package/dist/components/events-list.d.ts.map +1 -0
  19. package/dist/components/events-list.js +97 -0
  20. package/dist/components/events-list.js.map +1 -0
  21. package/dist/components/events-list.stories.d.ts +53 -0
  22. package/dist/components/events-list.stories.d.ts.map +1 -0
  23. package/dist/components/events-list.stories.js +180 -0
  24. package/dist/components/events-list.stories.js.map +1 -0
  25. package/dist/components/trigger-event-detail.d.ts +13 -0
  26. package/dist/components/trigger-event-detail.d.ts.map +1 -0
  27. package/dist/components/trigger-event-detail.js +376 -0
  28. package/dist/components/trigger-event-detail.js.map +1 -0
  29. package/dist/components/trigger-event-detail.stories.d.ts +65 -0
  30. package/dist/components/trigger-event-detail.stories.d.ts.map +1 -0
  31. package/dist/components/trigger-event-detail.stories.js +181 -0
  32. package/dist/components/trigger-event-detail.stories.js.map +1 -0
  33. package/dist/components/trigger-event-result.d.ts +15 -0
  34. package/dist/components/trigger-event-result.d.ts.map +1 -0
  35. package/dist/components/trigger-event-result.js +48 -0
  36. package/dist/components/trigger-event-result.js.map +1 -0
  37. package/dist/components/trigger-event-row.d.ts +9 -0
  38. package/dist/components/trigger-event-row.d.ts.map +1 -0
  39. package/dist/components/trigger-event-row.js +91 -0
  40. package/dist/components/trigger-event-row.js.map +1 -0
  41. package/dist/components/trigger-source-icon.d.ts +20 -0
  42. package/dist/components/trigger-source-icon.d.ts.map +1 -0
  43. package/dist/components/trigger-source-icon.js +28 -0
  44. package/dist/components/trigger-source-icon.js.map +1 -0
  45. package/dist/components/types.d.ts +20 -0
  46. package/dist/components/types.d.ts.map +1 -0
  47. package/dist/components/types.js +3 -0
  48. package/dist/components/types.js.map +1 -0
  49. package/dist/hooks/api/trigger-events.d.ts +164 -0
  50. package/dist/hooks/api/trigger-events.d.ts.map +1 -0
  51. package/dist/hooks/api/trigger-events.js +122 -0
  52. package/dist/hooks/api/trigger-events.js.map +1 -0
  53. package/dist/index.d.ts +5 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +6 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/pages/events-page.d.ts +12 -0
  58. package/dist/pages/events-page.d.ts.map +1 -0
  59. package/dist/pages/events-page.js +82 -0
  60. package/dist/pages/events-page.js.map +1 -0
  61. package/dist/search.d.ts +23 -0
  62. package/dist/search.d.ts.map +1 -0
  63. package/dist/search.js +28 -0
  64. package/dist/search.js.map +1 -0
  65. package/dist/tsconfig.test.tsbuildinfo +1 -0
  66. package/package.json +92 -0
  67. package/src/components/events-filter-bar.tsx +191 -0
  68. package/src/components/events-list-states.tsx +89 -0
  69. package/src/components/events-list.stories.tsx +141 -0
  70. package/src/components/events-list.test.tsx +173 -0
  71. package/src/components/events-list.tsx +107 -0
  72. package/src/components/trigger-event-detail.stories.tsx +169 -0
  73. package/src/components/trigger-event-detail.test.tsx +201 -0
  74. package/src/components/trigger-event-detail.tsx +317 -0
  75. package/src/components/trigger-event-result.test.ts +40 -0
  76. package/src/components/trigger-event-result.ts +40 -0
  77. package/src/components/trigger-event-row.tsx +86 -0
  78. package/src/components/trigger-source-icon.react.test.tsx +34 -0
  79. package/src/components/trigger-source-icon.test.ts +23 -0
  80. package/src/components/trigger-source-icon.tsx +36 -0
  81. package/src/components/types.ts +22 -0
  82. package/src/hooks/api/trigger-events.test.ts +252 -0
  83. package/src/hooks/api/trigger-events.ts +143 -0
  84. package/src/index.ts +4 -0
  85. package/src/pages/events-page.test.tsx +100 -0
  86. package/src/pages/events-page.tsx +79 -0
  87. package/src/search.test.ts +66 -0
  88. package/src/search.ts +38 -0
  89. package/test/setup.ts +35 -0
  90. package/tsconfig.build.json +9 -0
  91. package/tsconfig.build.tsbuildinfo +1 -0
  92. package/tsconfig.json +3 -0
  93. package/tsconfig.test.json +8 -0
  94. package/vercel.json +8 -0
  95. package/vitest.config.ts +68 -0
@@ -0,0 +1,97 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { QueryLoadError } from '@shipfox/client-ui';
3
+ import { Button } from '@shipfox/react-ui/button';
4
+ import { Table, TableBody, TableHead, TableHeader, TableRow } from '@shipfox/react-ui/table';
5
+ import { EventsFilterBar } from './events-filter-bar.js';
6
+ import { EventsListEmpty, EventsListNoMatches, EventsListSkeleton, EventsListStaleError } from './events-list-states.js';
7
+ import { TriggerEventRow } from './trigger-event-row.js';
8
+ function hasAnyFilter(filters) {
9
+ return Boolean(filters.source && filters.source.length > 0 || filters.event && filters.event.length > 0 || filters.from || filters.to || filters.outcome && filters.outcome.length > 0);
10
+ }
11
+ export function EventsList({ events, query, facets, filters, onFiltersChange, workspaceId, hasNextPage, isFetchingNextPage, onLoadMore, selectedEventId, onSelectEvent }) {
12
+ const activeFilters = hasAnyFilter(filters);
13
+ const refreshFailed = query.isError && query.data !== undefined;
14
+ const showEmptyState = !query.isPending && !query.isError && events.length === 0;
15
+ function clearFilters() {
16
+ onFiltersChange({
17
+ source: undefined,
18
+ event: undefined,
19
+ outcome: undefined,
20
+ from: undefined,
21
+ to: undefined
22
+ });
23
+ }
24
+ return /*#__PURE__*/ _jsxs("div", {
25
+ className: "flex min-h-0 flex-col overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base",
26
+ children: [
27
+ /*#__PURE__*/ _jsx(EventsFilterBar, {
28
+ filters: filters,
29
+ onFiltersChange: onFiltersChange,
30
+ sources: facets?.sources,
31
+ events: facets?.events,
32
+ hasActiveFilters: activeFilters,
33
+ onClear: clearFilters
34
+ }),
35
+ query.isPending ? /*#__PURE__*/ _jsx(EventsListSkeleton, {}) : null,
36
+ !query.isPending ? /*#__PURE__*/ _jsx(QueryLoadError, {
37
+ query: query,
38
+ subject: "events",
39
+ icon: "pulseLine"
40
+ }) : null,
41
+ !query.isPending && refreshFailed ? /*#__PURE__*/ _jsx(EventsListStaleError, {
42
+ query: query
43
+ }) : null,
44
+ showEmptyState && !activeFilters ? /*#__PURE__*/ _jsx(EventsListEmpty, {
45
+ workspaceId: workspaceId
46
+ }) : null,
47
+ showEmptyState && activeFilters ? /*#__PURE__*/ _jsx(EventsListNoMatches, {
48
+ onClear: clearFilters
49
+ }) : null,
50
+ events.length > 0 ? /*#__PURE__*/ _jsxs(_Fragment, {
51
+ children: [
52
+ /*#__PURE__*/ _jsxs(Table, {
53
+ children: [
54
+ /*#__PURE__*/ _jsx(TableHeader, {
55
+ className: "sticky top-0 z-10",
56
+ children: /*#__PURE__*/ _jsxs(TableRow, {
57
+ children: [
58
+ /*#__PURE__*/ _jsx(TableHead, {
59
+ children: "Event"
60
+ }),
61
+ /*#__PURE__*/ _jsx(TableHead, {
62
+ children: "Result"
63
+ }),
64
+ /*#__PURE__*/ _jsx(TableHead, {
65
+ className: "text-right",
66
+ children: "Received"
67
+ })
68
+ ]
69
+ })
70
+ }),
71
+ /*#__PURE__*/ _jsx(TableBody, {
72
+ children: events.map((event)=>/*#__PURE__*/ _jsx(TriggerEventRow, {
73
+ event: event,
74
+ selected: event.id === selectedEventId,
75
+ onSelect: onSelectEvent
76
+ }, event.id))
77
+ })
78
+ ]
79
+ }),
80
+ hasNextPage ? /*#__PURE__*/ _jsx("div", {
81
+ className: "flex justify-center p-16",
82
+ children: /*#__PURE__*/ _jsx(Button, {
83
+ type: "button",
84
+ variant: "secondary",
85
+ size: "sm",
86
+ isLoading: isFetchingNextPage,
87
+ onClick: onLoadMore,
88
+ children: "Load more"
89
+ })
90
+ }) : null
91
+ ]
92
+ }) : null
93
+ ]
94
+ });
95
+ }
96
+
97
+ //# sourceMappingURL=events-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/events-list.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Table, TableBody, TableHead, TableHeader, TableRow} from '@shipfox/react-ui/table';\nimport type {TriggerEventFilters} from '#hooks/api/trigger-events.js';\nimport {EventsFilterBar} from './events-filter-bar.js';\nimport {\n EventsListEmpty,\n EventsListNoMatches,\n EventsListSkeleton,\n EventsListStaleError,\n} from './events-list-states.js';\nimport {TriggerEventRow} from './trigger-event-row.js';\nimport type {EventsListProps} from './types.js';\n\nfunction hasAnyFilter(filters: TriggerEventFilters): boolean {\n return Boolean(\n (filters.source && filters.source.length > 0) ||\n (filters.event && filters.event.length > 0) ||\n filters.from ||\n filters.to ||\n (filters.outcome && filters.outcome.length > 0),\n );\n}\n\nexport function EventsList({\n events,\n query,\n facets,\n filters,\n onFiltersChange,\n workspaceId,\n hasNextPage,\n isFetchingNextPage,\n onLoadMore,\n selectedEventId,\n onSelectEvent,\n}: EventsListProps) {\n const activeFilters = hasAnyFilter(filters);\n const refreshFailed = query.isError && query.data !== undefined;\n const showEmptyState = !query.isPending && !query.isError && events.length === 0;\n\n function clearFilters() {\n onFiltersChange({\n source: undefined,\n event: undefined,\n outcome: undefined,\n from: undefined,\n to: undefined,\n });\n }\n\n return (\n <div className=\"flex min-h-0 flex-col overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base\">\n <EventsFilterBar\n filters={filters}\n onFiltersChange={onFiltersChange}\n sources={facets?.sources}\n events={facets?.events}\n hasActiveFilters={activeFilters}\n onClear={clearFilters}\n />\n\n {query.isPending ? <EventsListSkeleton /> : null}\n {!query.isPending ? <QueryLoadError query={query} subject=\"events\" icon=\"pulseLine\" /> : null}\n {!query.isPending && refreshFailed ? <EventsListStaleError query={query} /> : null}\n {showEmptyState && !activeFilters ? <EventsListEmpty workspaceId={workspaceId} /> : null}\n {showEmptyState && activeFilters ? <EventsListNoMatches onClear={clearFilters} /> : null}\n\n {events.length > 0 ? (\n <>\n <Table>\n <TableHeader className=\"sticky top-0 z-10\">\n <TableRow>\n <TableHead>Event</TableHead>\n <TableHead>Result</TableHead>\n <TableHead className=\"text-right\">Received</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {events.map((event) => (\n <TriggerEventRow\n key={event.id}\n event={event}\n selected={event.id === selectedEventId}\n onSelect={onSelectEvent}\n />\n ))}\n </TableBody>\n </Table>\n {hasNextPage ? (\n <div className=\"flex justify-center p-16\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n isLoading={isFetchingNextPage}\n onClick={onLoadMore}\n >\n Load more\n </Button>\n </div>\n ) : null}\n </>\n ) : null}\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Table","TableBody","TableHead","TableHeader","TableRow","EventsFilterBar","EventsListEmpty","EventsListNoMatches","EventsListSkeleton","EventsListStaleError","TriggerEventRow","hasAnyFilter","filters","Boolean","source","length","event","from","to","outcome","EventsList","events","query","facets","onFiltersChange","workspaceId","hasNextPage","isFetchingNextPage","onLoadMore","selectedEventId","onSelectEvent","activeFilters","refreshFailed","isError","data","undefined","showEmptyState","isPending","clearFilters","div","className","sources","hasActiveFilters","onClear","subject","icon","map","selected","id","onSelect","type","variant","size","isLoading","onClick"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,KAAK,EAAEC,SAAS,EAAEC,SAAS,EAAEC,WAAW,EAAEC,QAAQ,QAAO,0BAA0B;AAE3F,SAAQC,eAAe,QAAO,yBAAyB;AACvD,SACEC,eAAe,EACfC,mBAAmB,EACnBC,kBAAkB,EAClBC,oBAAoB,QACf,0BAA0B;AACjC,SAAQC,eAAe,QAAO,yBAAyB;AAGvD,SAASC,aAAaC,OAA4B;IAChD,OAAOC,QACL,AAACD,QAAQE,MAAM,IAAIF,QAAQE,MAAM,CAACC,MAAM,GAAG,KACxCH,QAAQI,KAAK,IAAIJ,QAAQI,KAAK,CAACD,MAAM,GAAG,KACzCH,QAAQK,IAAI,IACZL,QAAQM,EAAE,IACTN,QAAQO,OAAO,IAAIP,QAAQO,OAAO,CAACJ,MAAM,GAAG;AAEnD;AAEA,OAAO,SAASK,WAAW,EACzBC,MAAM,EACNC,KAAK,EACLC,MAAM,EACNX,OAAO,EACPY,eAAe,EACfC,WAAW,EACXC,WAAW,EACXC,kBAAkB,EAClBC,UAAU,EACVC,eAAe,EACfC,aAAa,EACG;IAChB,MAAMC,gBAAgBpB,aAAaC;IACnC,MAAMoB,gBAAgBV,MAAMW,OAAO,IAAIX,MAAMY,IAAI,KAAKC;IACtD,MAAMC,iBAAiB,CAACd,MAAMe,SAAS,IAAI,CAACf,MAAMW,OAAO,IAAIZ,OAAON,MAAM,KAAK;IAE/E,SAASuB;QACPd,gBAAgB;YACdV,QAAQqB;YACRnB,OAAOmB;YACPhB,SAASgB;YACTlB,MAAMkB;YACNjB,IAAIiB;QACN;IACF;IAEA,qBACE,MAACI;QAAIC,WAAU;;0BACb,KAACnC;gBACCO,SAASA;gBACTY,iBAAiBA;gBACjBiB,SAASlB,QAAQkB;gBACjBpB,QAAQE,QAAQF;gBAChBqB,kBAAkBX;gBAClBY,SAASL;;YAGVhB,MAAMe,SAAS,iBAAG,KAAC7B,0BAAwB;YAC3C,CAACc,MAAMe,SAAS,iBAAG,KAACvC;gBAAewB,OAAOA;gBAAOsB,SAAQ;gBAASC,MAAK;iBAAiB;YACxF,CAACvB,MAAMe,SAAS,IAAIL,8BAAgB,KAACvB;gBAAqBa,OAAOA;iBAAY;YAC7Ec,kBAAkB,CAACL,8BAAgB,KAACzB;gBAAgBmB,aAAaA;iBAAkB;YACnFW,kBAAkBL,8BAAgB,KAACxB;gBAAoBoC,SAASL;iBAAmB;YAEnFjB,OAAON,MAAM,GAAG,kBACf;;kCACE,MAACf;;0CACC,KAACG;gCAAYqC,WAAU;0CACrB,cAAA,MAACpC;;sDACC,KAACF;sDAAU;;sDACX,KAACA;sDAAU;;sDACX,KAACA;4CAAUsC,WAAU;sDAAa;;;;;0CAGtC,KAACvC;0CACEoB,OAAOyB,GAAG,CAAC,CAAC9B,sBACX,KAACN;wCAECM,OAAOA;wCACP+B,UAAU/B,MAAMgC,EAAE,KAAKnB;wCACvBoB,UAAUnB;uCAHLd,MAAMgC,EAAE;;;;oBAQpBtB,4BACC,KAACa;wBAAIC,WAAU;kCACb,cAAA,KAACzC;4BACCmD,MAAK;4BACLC,SAAQ;4BACRC,MAAK;4BACLC,WAAW1B;4BACX2B,SAAS1B;sCACV;;yBAID;;iBAEJ;;;AAGV"}
@@ -0,0 +1,53 @@
1
+ import type { Decorator, StoryObj } from '@storybook/react';
2
+ import { EventsList } from './events-list.js';
3
+ import type { TriggerEventsListQuery } from './types.js';
4
+ declare const meta: {
5
+ title: string;
6
+ component: typeof EventsList;
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ decorators: Decorator[];
11
+ args: {
12
+ events: {
13
+ id: string;
14
+ event_ref: string;
15
+ origin: "integration" | "manual" | "cron";
16
+ workspace_id: string;
17
+ provider: string | null;
18
+ source: string;
19
+ event: string;
20
+ delivery_id: string | null;
21
+ connection_id: string | null;
22
+ outcome: "received" | "routed" | "discarded" | "failed" | "errored";
23
+ matched_count: number;
24
+ received_at: string;
25
+ processed_at: string | null;
26
+ created_at: string;
27
+ }[];
28
+ query: TriggerEventsListQuery;
29
+ facets: {
30
+ sources: {
31
+ value: string;
32
+ count: number;
33
+ }[];
34
+ events: {
35
+ value: string;
36
+ count: number;
37
+ }[];
38
+ };
39
+ filters: {};
40
+ onFiltersChange: () => undefined;
41
+ workspaceId: string;
42
+ hasNextPage: false;
43
+ isFetchingNextPage: false;
44
+ onLoadMore: () => undefined;
45
+ selectedEventId: string;
46
+ onSelectEvent: () => undefined;
47
+ };
48
+ };
49
+ export default meta;
50
+ type Story = StoryObj<typeof meta>;
51
+ export declare const Playground: Story;
52
+ export declare const DataStates: Story;
53
+ //# sourceMappingURL=events-list.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-list.stories.d.ts","sourceRoot":"","sources":["../../src/components/events-list.stories.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAC,SAAS,EAAQ,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,YAAY,CAAC;AA2EvD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkByB,CAAC;AAEpC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,UAAU,EAAE,KAiBxB,CAAC"}
@@ -0,0 +1,180 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { RelativeTimeProvider } from '@shipfox/react-ui/relative-time';
3
+ import { Code } from '@shipfox/react-ui/typography';
4
+ import { EventsList } from './events-list.js';
5
+ const STORY_NOW = '2026-06-25T20:00:00.000Z';
6
+ const STORY_NOW_MS = Date.parse(STORY_NOW);
7
+ // Typed so meta's inferred type stays nameable (TS2883) under the package's tsconfig.
8
+ const withWidth = (Story)=>/*#__PURE__*/ _jsx(RelativeTimeProvider, {
9
+ now: STORY_NOW,
10
+ children: /*#__PURE__*/ _jsx("div", {
11
+ className: "w-[900px]",
12
+ children: /*#__PURE__*/ _jsx(Story, {})
13
+ })
14
+ });
15
+ function makeQuery(overrides = {}) {
16
+ return {
17
+ isPending: false,
18
+ isError: false,
19
+ isFetching: false,
20
+ data: {
21
+ pages: [],
22
+ pageParams: []
23
+ },
24
+ error: null,
25
+ refetch: ()=>undefined,
26
+ ...overrides
27
+ };
28
+ }
29
+ let seq = 0;
30
+ function makeEvent(outcome, provider, source, event, matchedCount, minutesAgo) {
31
+ seq += 1;
32
+ return {
33
+ id: `evt-${String(seq).padStart(8, '0')}`,
34
+ event_ref: `ref-${seq}`,
35
+ origin: 'integration',
36
+ workspace_id: 'ws-demo',
37
+ provider,
38
+ source,
39
+ event,
40
+ delivery_id: `delivery-${String(seq).padStart(6, '0')}`,
41
+ connection_id: 'conn-demo',
42
+ outcome,
43
+ matched_count: matchedCount,
44
+ received_at: new Date(STORY_NOW_MS - minutesAgo * 60_000).toISOString(),
45
+ processed_at: new Date(STORY_NOW_MS - minutesAgo * 60_000).toISOString(),
46
+ created_at: new Date(STORY_NOW_MS - minutesAgo * 60_000).toISOString()
47
+ };
48
+ }
49
+ const SAMPLE_EVENTS = [
50
+ makeEvent('received', 'github', 'github_acme', 'push', 0, 0),
51
+ makeEvent('routed', 'github', 'github_acme', 'push', 2, 3),
52
+ makeEvent('routed', 'gitea', 'gitea_acme', 'pull_request', 1, 12),
53
+ makeEvent('discarded', 'github', 'github_acme', 'issue_comment', 0, 38),
54
+ makeEvent('failed', 'gitlab', 'gitlab_acme', 'push', 1, 95)
55
+ ];
56
+ const SAMPLE_FACETS = {
57
+ sources: [
58
+ {
59
+ value: 'github_acme',
60
+ count: 3
61
+ },
62
+ {
63
+ value: 'gitea_acme',
64
+ count: 1
65
+ },
66
+ {
67
+ value: 'gitlab_acme',
68
+ count: 1
69
+ }
70
+ ],
71
+ events: [
72
+ {
73
+ value: 'push',
74
+ count: 3
75
+ },
76
+ {
77
+ value: 'pull_request',
78
+ count: 1
79
+ },
80
+ {
81
+ value: 'issue_comment',
82
+ count: 1
83
+ }
84
+ ]
85
+ };
86
+ const meta = {
87
+ title: 'Triggers/EventsList',
88
+ component: EventsList,
89
+ parameters: {
90
+ layout: 'padded'
91
+ },
92
+ decorators: [
93
+ withWidth
94
+ ],
95
+ args: {
96
+ events: SAMPLE_EVENTS,
97
+ query: makeQuery(),
98
+ facets: SAMPLE_FACETS,
99
+ filters: {},
100
+ onFiltersChange: ()=>undefined,
101
+ workspaceId: 'ws-demo',
102
+ hasNextPage: false,
103
+ isFetchingNextPage: false,
104
+ onLoadMore: ()=>undefined,
105
+ selectedEventId: 'evt-00000002',
106
+ onSelectEvent: ()=>undefined
107
+ }
108
+ };
109
+ export default meta;
110
+ export const Playground = {};
111
+ export const DataStates = {
112
+ render: (args)=>/*#__PURE__*/ _jsxs("div", {
113
+ className: "flex flex-col gap-32",
114
+ children: [
115
+ /*#__PURE__*/ _jsx(StateExample, {
116
+ label: "Loading",
117
+ children: /*#__PURE__*/ _jsx(EventsList, {
118
+ ...args,
119
+ events: [],
120
+ query: makeQuery({
121
+ isPending: true,
122
+ data: undefined
123
+ })
124
+ })
125
+ }),
126
+ /*#__PURE__*/ _jsx(StateExample, {
127
+ label: "Empty",
128
+ children: /*#__PURE__*/ _jsx(EventsList, {
129
+ ...args,
130
+ events: [],
131
+ facets: {
132
+ sources: [],
133
+ events: []
134
+ }
135
+ })
136
+ }),
137
+ /*#__PURE__*/ _jsx(StateExample, {
138
+ label: "No matches",
139
+ children: /*#__PURE__*/ _jsx(EventsList, {
140
+ ...args,
141
+ events: [],
142
+ filters: {
143
+ outcome: [
144
+ 'failed'
145
+ ]
146
+ }
147
+ })
148
+ }),
149
+ /*#__PURE__*/ _jsx(StateExample, {
150
+ label: "Load error",
151
+ children: /*#__PURE__*/ _jsx(EventsList, {
152
+ ...args,
153
+ events: [],
154
+ query: makeQuery({
155
+ isError: true,
156
+ data: undefined
157
+ })
158
+ })
159
+ })
160
+ ]
161
+ })
162
+ };
163
+ function StateExample({ label, children }) {
164
+ return /*#__PURE__*/ _jsxs("div", {
165
+ className: "flex flex-col gap-8",
166
+ children: [
167
+ /*#__PURE__*/ _jsx(Code, {
168
+ variant: "label",
169
+ className: "text-foreground-neutral-subtle",
170
+ children: label
171
+ }),
172
+ /*#__PURE__*/ _jsx("div", {
173
+ className: "min-h-280 rounded-8 border border-border-neutral-base bg-background-neutral-base p-12",
174
+ children: children
175
+ })
176
+ ]
177
+ });
178
+ }
179
+
180
+ //# sourceMappingURL=events-list.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/events-list.stories.tsx"],"sourcesContent":["import type {\n TriggerEventFacetsResponseDto,\n TriggerEventListItemDto,\n TriggerEventOutcomeDto,\n} from '@shipfox/api-triggers-dto';\nimport {RelativeTimeProvider} from '@shipfox/react-ui/relative-time';\nimport {Code} from '@shipfox/react-ui/typography';\nimport type {Decorator, Meta, StoryObj} from '@storybook/react';\nimport type {ReactNode} from 'react';\nimport {EventsList} from './events-list.js';\nimport type {TriggerEventsListQuery} from './types.js';\n\nconst STORY_NOW = '2026-06-25T20:00:00.000Z';\nconst STORY_NOW_MS = Date.parse(STORY_NOW);\n\n// Typed so meta's inferred type stays nameable (TS2883) under the package's tsconfig.\nconst withWidth: Decorator = (Story) => (\n <RelativeTimeProvider now={STORY_NOW}>\n <div className=\"w-[900px]\">\n <Story />\n </div>\n </RelativeTimeProvider>\n);\n\nfunction makeQuery(overrides: Partial<TriggerEventsListQuery> = {}): TriggerEventsListQuery {\n return {\n isPending: false,\n isError: false,\n isFetching: false,\n data: {pages: [], pageParams: []},\n error: null,\n refetch: () => undefined,\n ...overrides,\n };\n}\n\nlet seq = 0;\nfunction makeEvent(\n outcome: TriggerEventOutcomeDto,\n provider: string | null,\n source: string,\n event: string,\n matchedCount: number,\n minutesAgo: number,\n): TriggerEventListItemDto {\n seq += 1;\n return {\n id: `evt-${String(seq).padStart(8, '0')}`,\n event_ref: `ref-${seq}`,\n origin: 'integration',\n workspace_id: 'ws-demo',\n provider,\n source,\n event,\n delivery_id: `delivery-${String(seq).padStart(6, '0')}`,\n connection_id: 'conn-demo',\n outcome,\n matched_count: matchedCount,\n received_at: new Date(STORY_NOW_MS - minutesAgo * 60_000).toISOString(),\n processed_at: new Date(STORY_NOW_MS - minutesAgo * 60_000).toISOString(),\n created_at: new Date(STORY_NOW_MS - minutesAgo * 60_000).toISOString(),\n };\n}\n\nconst SAMPLE_EVENTS: TriggerEventListItemDto[] = [\n makeEvent('received', 'github', 'github_acme', 'push', 0, 0),\n makeEvent('routed', 'github', 'github_acme', 'push', 2, 3),\n makeEvent('routed', 'gitea', 'gitea_acme', 'pull_request', 1, 12),\n makeEvent('discarded', 'github', 'github_acme', 'issue_comment', 0, 38),\n makeEvent('failed', 'gitlab', 'gitlab_acme', 'push', 1, 95),\n];\n\nconst SAMPLE_FACETS: TriggerEventFacetsResponseDto = {\n sources: [\n {value: 'github_acme', count: 3},\n {value: 'gitea_acme', count: 1},\n {value: 'gitlab_acme', count: 1},\n ],\n events: [\n {value: 'push', count: 3},\n {value: 'pull_request', count: 1},\n {value: 'issue_comment', count: 1},\n ],\n};\n\nconst meta = {\n title: 'Triggers/EventsList',\n component: EventsList,\n parameters: {layout: 'padded'},\n decorators: [withWidth],\n args: {\n events: SAMPLE_EVENTS,\n query: makeQuery(),\n facets: SAMPLE_FACETS,\n filters: {},\n onFiltersChange: () => undefined,\n workspaceId: 'ws-demo',\n hasNextPage: false,\n isFetchingNextPage: false,\n onLoadMore: () => undefined,\n selectedEventId: 'evt-00000002',\n onSelectEvent: () => undefined,\n },\n} satisfies Meta<typeof EventsList>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const DataStates: Story = {\n render: (args) => (\n <div className=\"flex flex-col gap-32\">\n <StateExample label=\"Loading\">\n <EventsList {...args} events={[]} query={makeQuery({isPending: true, data: undefined})} />\n </StateExample>\n <StateExample label=\"Empty\">\n <EventsList {...args} events={[]} facets={{sources: [], events: []}} />\n </StateExample>\n <StateExample label=\"No matches\">\n <EventsList {...args} events={[]} filters={{outcome: ['failed']}} />\n </StateExample>\n <StateExample label=\"Load error\">\n <EventsList {...args} events={[]} query={makeQuery({isError: true, data: undefined})} />\n </StateExample>\n </div>\n ),\n};\n\nfunction StateExample({label, children}: {label: string; children: ReactNode}) {\n return (\n <div className=\"flex flex-col gap-8\">\n <Code variant=\"label\" className=\"text-foreground-neutral-subtle\">\n {label}\n </Code>\n <div className=\"min-h-280 rounded-8 border border-border-neutral-base bg-background-neutral-base p-12\">\n {children}\n </div>\n </div>\n );\n}\n"],"names":["RelativeTimeProvider","Code","EventsList","STORY_NOW","STORY_NOW_MS","Date","parse","withWidth","Story","now","div","className","makeQuery","overrides","isPending","isError","isFetching","data","pages","pageParams","error","refetch","undefined","seq","makeEvent","outcome","provider","source","event","matchedCount","minutesAgo","id","String","padStart","event_ref","origin","workspace_id","delivery_id","connection_id","matched_count","received_at","toISOString","processed_at","created_at","SAMPLE_EVENTS","SAMPLE_FACETS","sources","value","count","events","meta","title","component","parameters","layout","decorators","args","query","facets","filters","onFiltersChange","workspaceId","hasNextPage","isFetchingNextPage","onLoadMore","selectedEventId","onSelectEvent","Playground","DataStates","render","StateExample","label","children","variant"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { TriggerEventDetailResponseDto } from '@shipfox/api-triggers-dto';
2
+ export interface TriggerEventDetailProps {
3
+ workspaceId: string;
4
+ eventId?: string | undefined;
5
+ onBack: () => void;
6
+ }
7
+ export declare function TriggerEventDetail({ workspaceId, eventId, onBack }: TriggerEventDetailProps): import("react").JSX.Element;
8
+ export declare function TriggerEventDetailView({ workspaceId, event, onBack, }: {
9
+ workspaceId: string;
10
+ event: TriggerEventDetailResponseDto;
11
+ onBack: () => void;
12
+ }): import("react").JSX.Element;
13
+ //# sourceMappingURL=trigger-event-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-event-detail.d.ts","sourceRoot":"","sources":["../../src/components/trigger-event-detail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,6BAA6B,EAAC,MAAM,2BAA2B,CAAC;AA8BjG,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAC,EAAE,uBAAuB,+BAUzF;AAED,wBAAgB,sBAAsB,CAAC,EACrC,WAAW,EACX,KAAK,EACL,MAAM,GACP,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,6BAA6B,CAAC;IACrC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,+BAmEA"}