@shipfox/client-triggers 12.0.2 → 13.0.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 (49) hide show
  1. package/.storybook/preview.tsx +3 -3
  2. package/.turbo/turbo-build.log +1 -1
  3. package/CHANGELOG.md +23 -0
  4. package/dist/components/events-list-states.d.ts +2 -2
  5. package/dist/components/events-list-states.d.ts.map +1 -1
  6. package/dist/components/events-list-states.js +5 -5
  7. package/dist/components/events-list-states.js.map +1 -1
  8. package/dist/components/events-list.d.ts +1 -1
  9. package/dist/components/events-list.d.ts.map +1 -1
  10. package/dist/components/events-list.js +2 -2
  11. package/dist/components/events-list.js.map +1 -1
  12. package/dist/components/events-list.stories.d.ts +1 -1
  13. package/dist/components/events-list.stories.js +1 -1
  14. package/dist/components/events-list.stories.js.map +1 -1
  15. package/dist/components/trigger-event-detail.d.ts +6 -4
  16. package/dist/components/trigger-event-detail.d.ts.map +1 -1
  17. package/dist/components/trigger-event-detail.js +80 -35
  18. package/dist/components/trigger-event-detail.js.map +1 -1
  19. package/dist/components/trigger-event-detail.stories.d.ts +1 -0
  20. package/dist/components/trigger-event-detail.stories.d.ts.map +1 -1
  21. package/dist/components/trigger-event-detail.stories.js +40 -6
  22. package/dist/components/trigger-event-detail.stories.js.map +1 -1
  23. package/dist/components/types.d.ts +1 -1
  24. package/dist/components/types.d.ts.map +1 -1
  25. package/dist/components/types.js.map +1 -1
  26. package/dist/feature.d.ts +1 -1
  27. package/dist/feature.js +1 -1
  28. package/dist/feature.js.map +1 -1
  29. package/dist/pages/events-page.d.ts +2 -1
  30. package/dist/pages/events-page.d.ts.map +1 -1
  31. package/dist/pages/events-page.js +3 -2
  32. package/dist/pages/events-page.js.map +1 -1
  33. package/dist/routes/events-settings.d.ts.map +1 -1
  34. package/dist/routes/events-settings.js +2 -1
  35. package/dist/routes/events-settings.js.map +1 -1
  36. package/dist/tsconfig.test.tsbuildinfo +1 -1
  37. package/package.json +6 -5
  38. package/src/components/events-list-states.tsx +8 -6
  39. package/src/components/events-list.stories.tsx +1 -1
  40. package/src/components/events-list.test.tsx +0 -1
  41. package/src/components/events-list.tsx +2 -2
  42. package/src/components/trigger-event-detail.stories.tsx +25 -7
  43. package/src/components/trigger-event-detail.test.tsx +42 -10
  44. package/src/components/trigger-event-detail.tsx +137 -28
  45. package/src/components/types.ts +1 -1
  46. package/src/feature.ts +1 -1
  47. package/src/pages/events-page.tsx +9 -2
  48. package/src/routes/events-settings.tsx +7 -2
  49. package/tsconfig.build.tsbuildinfo +1 -1
@@ -34,20 +34,20 @@ const withRelativeTime: Decorator = (Story) => (
34
34
  </RelativeTimeProvider>
35
35
  );
36
36
 
37
- // The empty state renders `<Link to="/workspaces/$wid/settings/integrations">`, which needs a
37
+ // The empty state renders `<Link to="/w/$workspaceSlug/settings/integrations">`, which needs a
38
38
  // router in context to resolve its href. A memory router seeded at a matching path lets the
39
39
  // story render the link without the real app shell.
40
40
  const withRouter: Decorator = (Story) => {
41
41
  const rootRoute = createRootRoute();
42
42
  const integrationsRoute = createRoute({
43
43
  getParentRoute: () => rootRoute,
44
- path: '/workspaces/$wid/settings/integrations',
44
+ path: '/w/$workspaceSlug/settings/integrations',
45
45
  component: () => <Story />,
46
46
  });
47
47
  const router = createRouter({
48
48
  routeTree: rootRoute.addChildren([integrationsRoute]),
49
49
  history: createMemoryHistory({
50
- initialEntries: ['/workspaces/ws-demo/settings/integrations'],
50
+ initialEntries: ['/w/ws-demo/settings/integrations'],
51
51
  }),
52
52
  });
53
53
  return <RouterProvider router={router} />;
@@ -1,2 +1,2 @@
1
1
  $ shipfox-swc
2
- Successfully compiled: 18 files with swc (359.84ms)
2
+ Successfully compiled: 18 files with swc (242.57ms)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @shipfox/client-triggers
2
2
 
3
+ ## 13.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - e405e92: Move client routes to slug-based `/w/$workspaceSlug` and `/p/$projectSlug` URLs, enforce the new composition contract, and support bounded project-slug resolution.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [e405e92]
12
+ - Updated dependencies [f78740d]
13
+ - Updated dependencies [9969937]
14
+ - Updated dependencies [9fdd5e4]
15
+ - Updated dependencies [3c73365]
16
+ - Updated dependencies [4eb18b8]
17
+ - Updated dependencies [54c820e]
18
+ - Updated dependencies [6adc228]
19
+ - Updated dependencies [e1efaee]
20
+ - @shipfox/client-projects@13.0.0
21
+ - @shipfox/client-shell@13.0.0
22
+ - @shipfox/client-ui@13.0.0
23
+ - @shipfox/react-ui@0.4.0
24
+ - @shipfox/integration-icons@0.2.3
25
+
3
26
  ## 12.0.2
4
27
 
5
28
  ### Patch Changes
@@ -1,7 +1,7 @@
1
1
  import type { QueryLoadErrorQuery } from '@shipfox/client-ui';
2
2
  export declare function EventsListSkeleton(): import("react").JSX.Element;
3
- export declare function EventsListEmpty({ workspaceId }: {
4
- workspaceId: string;
3
+ export declare function EventsListEmpty({ workspaceSlug }: {
4
+ workspaceSlug?: string | undefined;
5
5
  }): import("react").JSX.Element;
6
6
  export declare function EventsListNoMatches({ onClear }: {
7
7
  onClear: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"events-list-states.d.ts","sourceRoot":"","sources":["../../src/components/events-list-states.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAQ5D,wBAAgB,kBAAkB,gCAiBjC;AAED,wBAAgB,eAAe,CAAC,EAAC,WAAW,EAAC,EAAE;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,+BAiBnE;AAED,wBAAgB,mBAAmB,CAAC,EAAC,OAAO,EAAC,EAAE;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAC,+BAenE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAC,KAAK,EAAC,EAAE;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAC,+BAqBzE"}
1
+ {"version":3,"file":"events-list-states.d.ts","sourceRoot":"","sources":["../../src/components/events-list-states.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAQ5D,wBAAgB,kBAAkB,gCAiBjC;AAED,wBAAgB,eAAe,CAAC,EAAC,aAAa,EAAC,EAAE;IAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAC,+BAmBpF;AAED,wBAAgB,mBAAmB,CAAC,EAAC,OAAO,EAAC,EAAE;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAC,+BAenE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAC,KAAK,EAAC,EAAE;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAC,+BAqBzE"}
@@ -31,25 +31,25 @@ export function EventsListSkeleton() {
31
31
  }, index))
32
32
  });
33
33
  }
34
- export function EventsListEmpty({ workspaceId }) {
34
+ export function EventsListEmpty({ workspaceSlug }) {
35
35
  return /*#__PURE__*/ _jsx("div", {
36
36
  className: "p-16",
37
37
  children: /*#__PURE__*/ _jsx(EmptyState, {
38
38
  icon: "pulseLine",
39
39
  title: "No events yet",
40
40
  description: "Events appear here once a connected integration delivers one or you fire a trigger.",
41
- action: /*#__PURE__*/ _jsx(Button, {
41
+ action: workspaceSlug ? /*#__PURE__*/ _jsx(Button, {
42
42
  asChild: true,
43
43
  size: "sm",
44
44
  variant: "secondary",
45
45
  children: /*#__PURE__*/ _jsx(Link, {
46
- to: "/workspaces/$wid/settings/integrations",
46
+ to: "/w/$workspaceSlug/settings/integrations",
47
47
  params: {
48
- wid: workspaceId
48
+ workspaceSlug
49
49
  },
50
50
  children: "Configure integrations"
51
51
  })
52
- })
52
+ }) : undefined
53
53
  })
54
54
  });
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/events-list-states.tsx"],"sourcesContent":["import type {QueryLoadErrorQuery} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\n\nexport function EventsListSkeleton() {\n return (\n <div className=\"flex flex-col gap-8 p-8\" role=\"status\" aria-label=\"Loading events\">\n {Array.from({length: 8}).map((_, index) => (\n <div\n // biome-ignore lint/suspicious/noArrayIndexKey: skeleton row, stable position\n key={index}\n className=\"flex h-20 items-center gap-12\"\n >\n <Skeleton className=\"size-6 shrink-0 rounded-full\" />\n <Skeleton className=\"h-12 w-1/4\" />\n <Skeleton className=\"h-12 w-20\" />\n <Skeleton className=\"ml-auto h-12 w-40\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport function EventsListEmpty({workspaceId}: {workspaceId: string}) {\n return (\n <div className=\"p-16\">\n <EmptyState\n icon=\"pulseLine\"\n title=\"No events yet\"\n description=\"Events appear here once a connected integration delivers one or you fire a trigger.\"\n action={\n <Button asChild size=\"sm\" variant=\"secondary\">\n <Link to=\"/workspaces/$wid/settings/integrations\" params={{wid: workspaceId}}>\n Configure integrations\n </Link>\n </Button>\n }\n />\n </div>\n );\n}\n\nexport function EventsListNoMatches({onClear}: {onClear: () => void}) {\n return (\n <div className=\"p-16\">\n <EmptyState\n icon=\"filterOffLine\"\n title=\"No matching events\"\n description=\"No events match your current filters.\"\n action={\n <Button type=\"button\" size=\"sm\" variant=\"secondary\" onClick={onClear}>\n Clear filters\n </Button>\n }\n />\n </div>\n );\n}\n\n/**\n * Slim banner shown when a background refetch fails after a prior success, so the loaded\n * rows stay on screen with the retry inline rather than being wiped by a full placeholder.\n */\nexport function EventsListStaleError({query}: {query: QueryLoadErrorQuery}) {\n return (\n <div className=\"p-8\">\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex items-center justify-between gap-8\">\n <Text size=\"xs\">Could not refresh events.</Text>\n <Button\n type=\"button\"\n size=\"2xs\"\n variant=\"secondary\"\n isLoading={query.isFetching}\n onClick={() => {\n void query.refetch();\n }}\n >\n Retry\n </Button>\n </div>\n </Callout>\n </div>\n );\n}\n"],"names":["Button","Callout","EmptyState","Skeleton","Text","Link","EventsListSkeleton","div","className","role","aria-label","Array","from","length","map","_","index","EventsListEmpty","workspaceId","icon","title","description","action","asChild","size","variant","to","params","wid","EventsListNoMatches","onClear","type","onClick","EventsListStaleError","query","isLoading","isFetching","refetch"],"mappings":";AACA,SAAQA,MAAM,QAAO,2BAA2B;AAChD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,UAAU,QAAO,gCAAgC;AACzD,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,IAAI,QAAO,yBAAyB;AAE5C,OAAO,SAASC;IACd,qBACE,KAACC;QAAIC,WAAU;QAA0BC,MAAK;QAASC,cAAW;kBAC/DC,MAAMC,IAAI,CAAC;YAACC,QAAQ;QAAC,GAAGC,GAAG,CAAC,CAACC,GAAGC,sBAC/B,MAACT;gBAGCC,WAAU;;kCAEV,KAACL;wBAASK,WAAU;;kCACpB,KAACL;wBAASK,WAAU;;kCACpB,KAACL;wBAASK,WAAU;;kCACpB,KAACL;wBAASK,WAAU;;;eANfQ;;AAWf;AAEA,OAAO,SAASC,gBAAgB,EAACC,WAAW,EAAwB;IAClE,qBACE,KAACX;QAAIC,WAAU;kBACb,cAAA,KAACN;YACCiB,MAAK;YACLC,OAAM;YACNC,aAAY;YACZC,sBACE,KAACtB;gBAAOuB,OAAO;gBAACC,MAAK;gBAAKC,SAAQ;0BAChC,cAAA,KAACpB;oBAAKqB,IAAG;oBAAyCC,QAAQ;wBAACC,KAAKV;oBAAW;8BAAG;;;;;AAQ1F;AAEA,OAAO,SAASW,oBAAoB,EAACC,OAAO,EAAwB;IAClE,qBACE,KAACvB;QAAIC,WAAU;kBACb,cAAA,KAACN;YACCiB,MAAK;YACLC,OAAM;YACNC,aAAY;YACZC,sBACE,KAACtB;gBAAO+B,MAAK;gBAASP,MAAK;gBAAKC,SAAQ;gBAAYO,SAASF;0BAAS;;;;AAOhF;AAEA;;;CAGC,GACD,OAAO,SAASG,qBAAqB,EAACC,KAAK,EAA+B;IACxE,qBACE,KAAC3B;QAAIC,WAAU;kBACb,cAAA,KAACP;YAAQQ,MAAK;YAAQsB,MAAK;sBACzB,cAAA,MAACxB;gBAAIC,WAAU;;kCACb,KAACJ;wBAAKoB,MAAK;kCAAK;;kCAChB,KAACxB;wBACC+B,MAAK;wBACLP,MAAK;wBACLC,SAAQ;wBACRU,WAAWD,MAAME,UAAU;wBAC3BJ,SAAS;4BACP,KAAKE,MAAMG,OAAO;wBACpB;kCACD;;;;;;AAOX"}
1
+ {"version":3,"sources":["../../src/components/events-list-states.tsx"],"sourcesContent":["import type {QueryLoadErrorQuery} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {Link} from '@tanstack/react-router';\n\nexport function EventsListSkeleton() {\n return (\n <div className=\"flex flex-col gap-8 p-8\" role=\"status\" aria-label=\"Loading events\">\n {Array.from({length: 8}).map((_, index) => (\n <div\n // biome-ignore lint/suspicious/noArrayIndexKey: skeleton row, stable position\n key={index}\n className=\"flex h-20 items-center gap-12\"\n >\n <Skeleton className=\"size-6 shrink-0 rounded-full\" />\n <Skeleton className=\"h-12 w-1/4\" />\n <Skeleton className=\"h-12 w-20\" />\n <Skeleton className=\"ml-auto h-12 w-40\" />\n </div>\n ))}\n </div>\n );\n}\n\nexport function EventsListEmpty({workspaceSlug}: {workspaceSlug?: string | undefined}) {\n return (\n <div className=\"p-16\">\n <EmptyState\n icon=\"pulseLine\"\n title=\"No events yet\"\n description=\"Events appear here once a connected integration delivers one or you fire a trigger.\"\n action={\n workspaceSlug ? (\n <Button asChild size=\"sm\" variant=\"secondary\">\n <Link to=\"/w/$workspaceSlug/settings/integrations\" params={{workspaceSlug}}>\n Configure integrations\n </Link>\n </Button>\n ) : undefined\n }\n />\n </div>\n );\n}\n\nexport function EventsListNoMatches({onClear}: {onClear: () => void}) {\n return (\n <div className=\"p-16\">\n <EmptyState\n icon=\"filterOffLine\"\n title=\"No matching events\"\n description=\"No events match your current filters.\"\n action={\n <Button type=\"button\" size=\"sm\" variant=\"secondary\" onClick={onClear}>\n Clear filters\n </Button>\n }\n />\n </div>\n );\n}\n\n/**\n * Slim banner shown when a background refetch fails after a prior success, so the loaded\n * rows stay on screen with the retry inline rather than being wiped by a full placeholder.\n */\nexport function EventsListStaleError({query}: {query: QueryLoadErrorQuery}) {\n return (\n <div className=\"p-8\">\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex items-center justify-between gap-8\">\n <Text size=\"xs\">Could not refresh events.</Text>\n <Button\n type=\"button\"\n size=\"2xs\"\n variant=\"secondary\"\n isLoading={query.isFetching}\n onClick={() => {\n void query.refetch();\n }}\n >\n Retry\n </Button>\n </div>\n </Callout>\n </div>\n );\n}\n"],"names":["Button","Callout","EmptyState","Skeleton","Text","Link","EventsListSkeleton","div","className","role","aria-label","Array","from","length","map","_","index","EventsListEmpty","workspaceSlug","icon","title","description","action","asChild","size","variant","to","params","undefined","EventsListNoMatches","onClear","type","onClick","EventsListStaleError","query","isLoading","isFetching","refetch"],"mappings":";AACA,SAAQA,MAAM,QAAO,2BAA2B;AAChD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,UAAU,QAAO,gCAAgC;AACzD,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,IAAI,QAAO,yBAAyB;AAE5C,OAAO,SAASC;IACd,qBACE,KAACC;QAAIC,WAAU;QAA0BC,MAAK;QAASC,cAAW;kBAC/DC,MAAMC,IAAI,CAAC;YAACC,QAAQ;QAAC,GAAGC,GAAG,CAAC,CAACC,GAAGC,sBAC/B,MAACT;gBAGCC,WAAU;;kCAEV,KAACL;wBAASK,WAAU;;kCACpB,KAACL;wBAASK,WAAU;;kCACpB,KAACL;wBAASK,WAAU;;kCACpB,KAACL;wBAASK,WAAU;;;eANfQ;;AAWf;AAEA,OAAO,SAASC,gBAAgB,EAACC,aAAa,EAAuC;IACnF,qBACE,KAACX;QAAIC,WAAU;kBACb,cAAA,KAACN;YACCiB,MAAK;YACLC,OAAM;YACNC,aAAY;YACZC,QACEJ,8BACE,KAAClB;gBAAOuB,OAAO;gBAACC,MAAK;gBAAKC,SAAQ;0BAChC,cAAA,KAACpB;oBAAKqB,IAAG;oBAA0CC,QAAQ;wBAACT;oBAAa;8BAAG;;iBAI5EU;;;AAKd;AAEA,OAAO,SAASC,oBAAoB,EAACC,OAAO,EAAwB;IAClE,qBACE,KAACvB;QAAIC,WAAU;kBACb,cAAA,KAACN;YACCiB,MAAK;YACLC,OAAM;YACNC,aAAY;YACZC,sBACE,KAACtB;gBAAO+B,MAAK;gBAASP,MAAK;gBAAKC,SAAQ;gBAAYO,SAASF;0BAAS;;;;AAOhF;AAEA;;;CAGC,GACD,OAAO,SAASG,qBAAqB,EAACC,KAAK,EAA+B;IACxE,qBACE,KAAC3B;QAAIC,WAAU;kBACb,cAAA,KAACP;YAAQQ,MAAK;YAAQsB,MAAK;sBACzB,cAAA,MAACxB;gBAAIC,WAAU;;kCACb,KAACJ;wBAAKoB,MAAK;kCAAK;;kCAChB,KAACxB;wBACC+B,MAAK;wBACLP,MAAK;wBACLC,SAAQ;wBACRU,WAAWD,MAAME,UAAU;wBAC3BJ,SAAS;4BACP,KAAKE,MAAMG,OAAO;wBACpB;kCACD;;;;;;AAOX"}
@@ -1,3 +1,3 @@
1
1
  import type { EventsListProps } from './types.js';
2
- export declare function EventsList({ events, query, facets, filters, onFiltersChange, workspaceId, hasNextPage, isFetchingNextPage, onLoadMore, selectedEventId, onSelectEvent, }: EventsListProps): import("react").JSX.Element;
2
+ export declare function EventsList({ events, query, facets, filters, onFiltersChange, workspaceSlug, hasNextPage, isFetchingNextPage, onLoadMore, selectedEventId, onSelectEvent, }: EventsListProps): import("react").JSX.Element;
3
3
  //# sourceMappingURL=events-list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"events-list.d.ts","sourceRoot":"","sources":["../../src/components/events-list.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,YAAY,CAAC;AAEhD,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,eAAe,EACf,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,aAAa,GACd,EAAE,eAAe,+BAsEjB"}
1
+ {"version":3,"file":"events-list.d.ts","sourceRoot":"","sources":["../../src/components/events-list.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,YAAY,CAAC;AAEhD,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,eAAe,EACf,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,eAAe,EACf,aAAa,GACd,EAAE,eAAe,+BAsEjB"}
@@ -6,7 +6,7 @@ import { hasTriggerEventFilters } from '#core/trigger-event.js';
6
6
  import { EventsFilterBar } from './events-filter-bar.js';
7
7
  import { EventsListEmpty, EventsListNoMatches, EventsListSkeleton, EventsListStaleError } from './events-list-states.js';
8
8
  import { TriggerEventRow } from './trigger-event-row.js';
9
- export function EventsList({ events, query, facets, filters, onFiltersChange, workspaceId, hasNextPage, isFetchingNextPage, onLoadMore, selectedEventId, onSelectEvent }) {
9
+ export function EventsList({ events, query, facets, filters, onFiltersChange, workspaceSlug, hasNextPage, isFetchingNextPage, onLoadMore, selectedEventId, onSelectEvent }) {
10
10
  const activeFilters = hasTriggerEventFilters(filters);
11
11
  const refreshFailed = query.isError && query.data !== undefined;
12
12
  const showEmptyState = !query.isPending && !query.isError && events.length === 0;
@@ -40,7 +40,7 @@ export function EventsList({ events, query, facets, filters, onFiltersChange, wo
40
40
  query: query
41
41
  }) : null,
42
42
  showEmptyState && !activeFilters ? /*#__PURE__*/ _jsx(EventsListEmpty, {
43
- workspaceId: workspaceId
43
+ workspaceSlug: workspaceSlug
44
44
  }) : null,
45
45
  showEmptyState && activeFilters ? /*#__PURE__*/ _jsx(EventsListNoMatches, {
46
46
  onClear: clearFilters
@@ -1 +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 {hasTriggerEventFilters} from '#core/trigger-event.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\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 = hasTriggerEventFilters(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","hasTriggerEventFilters","EventsFilterBar","EventsListEmpty","EventsListNoMatches","EventsListSkeleton","EventsListStaleError","TriggerEventRow","EventsList","events","query","facets","filters","onFiltersChange","workspaceId","hasNextPage","isFetchingNextPage","onLoadMore","selectedEventId","onSelectEvent","activeFilters","refreshFailed","isError","data","undefined","showEmptyState","isPending","length","clearFilters","source","event","outcome","from","to","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;AAC3F,SAAQC,sBAAsB,QAAO,yBAAyB;AAC9D,SAAQC,eAAe,QAAO,yBAAyB;AACvD,SACEC,eAAe,EACfC,mBAAmB,EACnBC,kBAAkB,EAClBC,oBAAoB,QACf,0BAA0B;AACjC,SAAQC,eAAe,QAAO,yBAAyB;AAGvD,OAAO,SAASC,WAAW,EACzBC,MAAM,EACNC,KAAK,EACLC,MAAM,EACNC,OAAO,EACPC,eAAe,EACfC,WAAW,EACXC,WAAW,EACXC,kBAAkB,EAClBC,UAAU,EACVC,eAAe,EACfC,aAAa,EACG;IAChB,MAAMC,gBAAgBnB,uBAAuBW;IAC7C,MAAMS,gBAAgBX,MAAMY,OAAO,IAAIZ,MAAMa,IAAI,KAAKC;IACtD,MAAMC,iBAAiB,CAACf,MAAMgB,SAAS,IAAI,CAAChB,MAAMY,OAAO,IAAIb,OAAOkB,MAAM,KAAK;IAE/E,SAASC;QACPf,gBAAgB;YACdgB,QAAQL;YACRM,OAAON;YACPO,SAASP;YACTQ,MAAMR;YACNS,IAAIT;QACN;IACF;IAEA,qBACE,MAACU;QAAIC,WAAU;;0BACb,KAACjC;gBACCU,SAASA;gBACTC,iBAAiBA;gBACjBuB,SAASzB,QAAQyB;gBACjB3B,QAAQE,QAAQF;gBAChB4B,kBAAkBjB;gBAClBkB,SAASV;;YAGVlB,MAAMgB,SAAS,iBAAG,KAACrB,0BAAwB;YAC3C,CAACK,MAAMgB,SAAS,iBAAG,KAAChC;gBAAegB,OAAOA;gBAAO6B,SAAQ;gBAASC,MAAK;iBAAiB;YACxF,CAAC9B,MAAMgB,SAAS,IAAIL,8BAAgB,KAACf;gBAAqBI,OAAOA;iBAAY;YAC7Ee,kBAAkB,CAACL,8BAAgB,KAACjB;gBAAgBW,aAAaA;iBAAkB;YACnFW,kBAAkBL,8BAAgB,KAAChB;gBAAoBkC,SAASV;iBAAmB;YAEnFnB,OAAOkB,MAAM,GAAG,kBACf;;kCACE,MAAC/B;;0CACC,KAACG;gCAAYoC,WAAU;0CACrB,cAAA,MAACnC;;sDACC,KAACF;sDAAU;;sDACX,KAACA;sDAAU;;sDACX,KAACA;4CAAUqC,WAAU;sDAAa;;;;;0CAGtC,KAACtC;0CACEY,OAAOgC,GAAG,CAAC,CAACX,sBACX,KAACvB;wCAECuB,OAAOA;wCACPY,UAAUZ,MAAMa,EAAE,KAAKzB;wCACvB0B,UAAUzB;uCAHLW,MAAMa,EAAE;;;;oBAQpB5B,4BACC,KAACmB;wBAAIC,WAAU;kCACb,cAAA,KAACxC;4BACCkD,MAAK;4BACLC,SAAQ;4BACRC,MAAK;4BACLC,WAAWhC;4BACXiC,SAAShC;sCACV;;yBAID;;iBAEJ;;;AAGV"}
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 {hasTriggerEventFilters} from '#core/trigger-event.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\nexport function EventsList({\n events,\n query,\n facets,\n filters,\n onFiltersChange,\n workspaceSlug,\n hasNextPage,\n isFetchingNextPage,\n onLoadMore,\n selectedEventId,\n onSelectEvent,\n}: EventsListProps) {\n const activeFilters = hasTriggerEventFilters(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 workspaceSlug={workspaceSlug} /> : 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","hasTriggerEventFilters","EventsFilterBar","EventsListEmpty","EventsListNoMatches","EventsListSkeleton","EventsListStaleError","TriggerEventRow","EventsList","events","query","facets","filters","onFiltersChange","workspaceSlug","hasNextPage","isFetchingNextPage","onLoadMore","selectedEventId","onSelectEvent","activeFilters","refreshFailed","isError","data","undefined","showEmptyState","isPending","length","clearFilters","source","event","outcome","from","to","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;AAC3F,SAAQC,sBAAsB,QAAO,yBAAyB;AAC9D,SAAQC,eAAe,QAAO,yBAAyB;AACvD,SACEC,eAAe,EACfC,mBAAmB,EACnBC,kBAAkB,EAClBC,oBAAoB,QACf,0BAA0B;AACjC,SAAQC,eAAe,QAAO,yBAAyB;AAGvD,OAAO,SAASC,WAAW,EACzBC,MAAM,EACNC,KAAK,EACLC,MAAM,EACNC,OAAO,EACPC,eAAe,EACfC,aAAa,EACbC,WAAW,EACXC,kBAAkB,EAClBC,UAAU,EACVC,eAAe,EACfC,aAAa,EACG;IAChB,MAAMC,gBAAgBnB,uBAAuBW;IAC7C,MAAMS,gBAAgBX,MAAMY,OAAO,IAAIZ,MAAMa,IAAI,KAAKC;IACtD,MAAMC,iBAAiB,CAACf,MAAMgB,SAAS,IAAI,CAAChB,MAAMY,OAAO,IAAIb,OAAOkB,MAAM,KAAK;IAE/E,SAASC;QACPf,gBAAgB;YACdgB,QAAQL;YACRM,OAAON;YACPO,SAASP;YACTQ,MAAMR;YACNS,IAAIT;QACN;IACF;IAEA,qBACE,MAACU;QAAIC,WAAU;;0BACb,KAACjC;gBACCU,SAASA;gBACTC,iBAAiBA;gBACjBuB,SAASzB,QAAQyB;gBACjB3B,QAAQE,QAAQF;gBAChB4B,kBAAkBjB;gBAClBkB,SAASV;;YAGVlB,MAAMgB,SAAS,iBAAG,KAACrB,0BAAwB;YAC3C,CAACK,MAAMgB,SAAS,iBAAG,KAAChC;gBAAegB,OAAOA;gBAAO6B,SAAQ;gBAASC,MAAK;iBAAiB;YACxF,CAAC9B,MAAMgB,SAAS,IAAIL,8BAAgB,KAACf;gBAAqBI,OAAOA;iBAAY;YAC7Ee,kBAAkB,CAACL,8BAAgB,KAACjB;gBAAgBW,eAAeA;iBAAoB;YACvFW,kBAAkBL,8BAAgB,KAAChB;gBAAoBkC,SAASV;iBAAmB;YAEnFnB,OAAOkB,MAAM,GAAG,kBACf;;kCACE,MAAC/B;;0CACC,KAACG;gCAAYoC,WAAU;0CACrB,cAAA,MAACnC;;sDACC,KAACF;sDAAU;;sDACX,KAACA;sDAAU;;sDACX,KAACA;4CAAUqC,WAAU;sDAAa;;;;;0CAGtC,KAACtC;0CACEY,OAAOgC,GAAG,CAAC,CAACX,sBACX,KAACvB;wCAECuB,OAAOA;wCACPY,UAAUZ,MAAMa,EAAE,KAAKzB;wCACvB0B,UAAUzB;uCAHLW,MAAMa,EAAE;;;;oBAQpB5B,4BACC,KAACmB;wBAAIC,WAAU;kCACb,cAAA,KAACxC;4BACCkD,MAAK;4BACLC,SAAQ;4BACRC,MAAK;4BACLC,WAAWhC;4BACXiC,SAAShC;sCACV;;yBAID;;iBAEJ;;;AAGV"}
@@ -9,6 +9,7 @@ declare const meta: {
9
9
  };
10
10
  decorators: Decorator[];
11
11
  args: {
12
+ workspaceSlug: string;
12
13
  events: import("../index.js").TriggerEventSummary[];
13
14
  query: TriggerEventsListQuery;
14
15
  facets: {
@@ -23,7 +24,6 @@ declare const meta: {
23
24
  };
24
25
  filters: {};
25
26
  onFiltersChange: () => undefined;
26
- workspaceId: string;
27
27
  hasNextPage: false;
28
28
  isFetchingNextPage: false;
29
29
  onLoadMore: () => undefined;
@@ -94,12 +94,12 @@ const meta = {
94
94
  withWidth
95
95
  ],
96
96
  args: {
97
+ workspaceSlug: 'acme',
97
98
  events: SAMPLE_EVENTS,
98
99
  query: makeQuery(),
99
100
  facets: SAMPLE_FACETS,
100
101
  filters: {},
101
102
  onFiltersChange: ()=>undefined,
102
- workspaceId: 'ws-demo',
103
103
  hasNextPage: false,
104
104
  isFetchingNextPage: false,
105
105
  onLoadMore: ()=>undefined,
@@ -1 +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 {toTriggerEventSummary} from '#hooks/api/trigger-event-mapper.js';\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 = [\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].map(toTriggerEventSummary);\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","toTriggerEventSummary","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","map","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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"}
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 {toTriggerEventSummary} from '#hooks/api/trigger-event-mapper.js';\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 = [\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].map(toTriggerEventSummary);\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 workspaceSlug: 'acme',\n events: SAMPLE_EVENTS,\n query: makeQuery(),\n facets: SAMPLE_FACETS,\n filters: {},\n onFiltersChange: () => undefined,\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","toTriggerEventSummary","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","map","SAMPLE_FACETS","sources","value","count","events","meta","title","component","parameters","layout","decorators","args","workspaceSlug","query","facets","filters","onFiltersChange","hasNextPage","isFetchingNextPage","onLoadMore","selectedEventId","onSelectEvent","Playground","DataStates","render","StateExample","label","children","variant"],"mappings":"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"}
@@ -1,12 +1,14 @@
1
1
  import type { TriggerEventDetail as TriggerEventDetailModel } from '#core/trigger-event.js';
2
2
  export interface TriggerEventDetailProps {
3
- workspaceId: string;
3
+ workspaceId?: string | undefined;
4
+ workspaceSlug?: string | undefined;
4
5
  eventId?: string | undefined;
5
6
  onBack: () => void;
6
7
  }
7
- export declare function TriggerEventDetail({ workspaceId, eventId, onBack }: TriggerEventDetailProps): import("react").JSX.Element;
8
- export declare function TriggerEventDetailView({ workspaceId, event, onBack, }: {
9
- workspaceId: string;
8
+ export declare function TriggerEventDetail({ workspaceId, workspaceSlug, eventId, onBack, }: TriggerEventDetailProps): import("react").JSX.Element;
9
+ export declare function TriggerEventDetailView({ workspaceId, workspaceSlug, event, onBack, }: {
10
+ workspaceId?: string | undefined;
11
+ workspaceSlug?: string | undefined;
10
12
  event: TriggerEventDetailModel;
11
13
  onBack: () => void;
12
14
  }): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"trigger-event-detail.d.ts","sourceRoot":"","sources":["../../src/components/trigger-event-detail.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,kBAAkB,IAAI,uBAAuB,EAE9C,MAAM,wBAAwB,CAAC;AAUhC,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,uBAAuB,CAAC;IAC/B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,+BAsEA"}
1
+ {"version":3,"file":"trigger-event-detail.d.ts","sourceRoot":"","sources":["../../src/components/trigger-event-detail.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,kBAAkB,IAAI,uBAAuB,EAE9C,MAAM,wBAAwB,CAAC;AAUhC,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,aAAa,EACb,OAAO,EACP,MAAM,GACP,EAAE,uBAAuB,+BAiBzB;AAED,wBAAgB,sBAAsB,CAAC,EACrC,WAAW,EACX,aAAa,EACb,KAAK,EACL,MAAM,GACP,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,KAAK,EAAE,uBAAuB,CAAC;IAC/B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,+BAsEA"}
@@ -1,4 +1,5 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useProjectQuery, useProjectsInfiniteQuery } from '@shipfox/client-projects';
2
3
  import { Badge } from '@shipfox/react-ui/badge';
3
4
  import { Button } from '@shipfox/react-ui/button';
4
5
  import { Callout } from '@shipfox/react-ui/callout';
@@ -17,12 +18,13 @@ import { triggerEventResult } from './trigger-event-result.js';
17
18
  import { TriggerSourceIcon } from './trigger-source-icon.js';
18
19
  const PANEL_CLASS = 'min-h-0 rounded-8 border border-border-neutral-base bg-background-neutral-base';
19
20
  const DETAIL_RAIL_CLASS = '@min-[820px]:sticky @min-[820px]:top-16 @min-[820px]:max-h-[calc(var(--app-content-h,100dvh_-_96px)_-_32px)] @min-[820px]:min-h-[min(320px,calc(var(--app-content-h,100dvh_-_96px)_-_32px))]';
20
- export function TriggerEventDetail({ workspaceId, eventId, onBack }) {
21
+ export function TriggerEventDetail({ workspaceId, workspaceSlug, eventId, onBack }) {
21
22
  const query = useTriggerEventQuery(eventId);
22
23
  if (!eventId) return /*#__PURE__*/ _jsx(TriggerEventDetailPlaceholder, {});
23
24
  if (query.data) {
24
25
  return /*#__PURE__*/ _jsx(TriggerEventDetailView, {
25
26
  workspaceId: workspaceId,
27
+ workspaceSlug: workspaceSlug,
26
28
  event: query.data,
27
29
  onBack: onBack
28
30
  });
@@ -35,7 +37,7 @@ export function TriggerEventDetail({ workspaceId, eventId, onBack }) {
35
37
  onBack: onBack
36
38
  });
37
39
  }
38
- export function TriggerEventDetailView({ workspaceId, event, onBack }) {
40
+ export function TriggerEventDetailView({ workspaceId, workspaceSlug, event, onBack }) {
39
41
  const result = triggerEventResult(event);
40
42
  const eventLabel = triggerEventDisplayLabel(event);
41
43
  const fullEventLabel = triggerEventFullLabel(event);
@@ -121,6 +123,7 @@ export function TriggerEventDetailView({ workspaceId, event, onBack }) {
121
123
  children: [
122
124
  /*#__PURE__*/ _jsx(EventRuns, {
123
125
  workspaceId: workspaceId,
126
+ workspaceSlug: workspaceSlug,
124
127
  event: event
125
128
  }),
126
129
  /*#__PURE__*/ _jsx(EventPayload, {
@@ -222,7 +225,7 @@ function TriggerEventDetailError({ onBack, onRetry }) {
222
225
  ]
223
226
  });
224
227
  }
225
- function EventRuns({ workspaceId, event }) {
228
+ function EventRuns({ workspaceId, workspaceSlug, event }) {
226
229
  if (event.decisions.length === 0) {
227
230
  if (event.outcome === 'discarded') {
228
231
  return /*#__PURE__*/ _jsx(Text, {
@@ -233,6 +236,35 @@ function EventRuns({ workspaceId, event }) {
233
236
  }
234
237
  return null;
235
238
  }
239
+ if (!workspaceId) {
240
+ return /*#__PURE__*/ _jsx(EventRunsList, {
241
+ workspaceSlug: workspaceSlug,
242
+ projectSlugs: new Map(),
243
+ event: event
244
+ });
245
+ }
246
+ return /*#__PURE__*/ _jsx(EventRunsWithProjects, {
247
+ workspaceId: workspaceId,
248
+ workspaceSlug: workspaceSlug,
249
+ event: event
250
+ });
251
+ }
252
+ function EventRunsWithProjects({ workspaceId, workspaceSlug, event }) {
253
+ const projectsQuery = useProjectsInfiniteQuery(workspaceId);
254
+ const projectSlugs = useMemo(()=>new Map(projectsQuery.data?.pages.flatMap((page)=>page.projects).map((project)=>[
255
+ project.id,
256
+ project.slug
257
+ ])), [
258
+ projectsQuery.data
259
+ ]);
260
+ return /*#__PURE__*/ _jsx(EventRunsList, {
261
+ workspaceSlug: workspaceSlug,
262
+ projectSlugs: projectSlugs,
263
+ projectDetailLookupEnabled: !projectsQuery.isPending,
264
+ event: event
265
+ });
266
+ }
267
+ function EventRunsList({ workspaceSlug, projectSlugs, projectDetailLookupEnabled = false, event }) {
236
268
  return /*#__PURE__*/ _jsxs("section", {
237
269
  "aria-labelledby": "trigger-event-runs-heading",
238
270
  className: "flex flex-col gap-6",
@@ -246,14 +278,20 @@ function EventRuns({ workspaceId, event }) {
246
278
  /*#__PURE__*/ _jsx("ul", {
247
279
  className: "-mx-8 flex flex-col gap-1",
248
280
  children: event.decisions.map((decision)=>/*#__PURE__*/ _jsx(DecisionRow, {
249
- workspaceId: workspaceId,
281
+ workspaceSlug: workspaceSlug,
282
+ projectId: decision.projectId ?? undefined,
283
+ projectSlug: decision.projectId ? projectSlugs.get(decision.projectId) : undefined,
284
+ projectDetailLookupEnabled: projectDetailLookupEnabled,
250
285
  decision: decision
251
286
  }, decision.id))
252
287
  })
253
288
  ]
254
289
  });
255
290
  }
256
- function DecisionRow({ workspaceId, decision }) {
291
+ function DecisionRow({ projectId, projectSlug, workspaceSlug, projectDetailLookupEnabled, decision }) {
292
+ const canRenderRunLink = decision.decision === 'triggered' && Boolean(decision.runId && decision.runName);
293
+ const projectQuery = useProjectQuery(canRenderRunLink && projectDetailLookupEnabled && !projectSlug ? projectId : undefined);
294
+ const resolvedProjectSlug = projectSlug ?? projectQuery.data?.slug;
257
295
  if (decision.decision !== 'triggered' || !decision.runId || !decision.runName) {
258
296
  return /*#__PURE__*/ _jsxs("li", {
259
297
  className: "flex min-w-0 items-start gap-8 rounded-6 px-8 py-6",
@@ -285,39 +323,46 @@ function DecisionRow({ workspaceId, decision }) {
285
323
  ]
286
324
  });
287
325
  }
326
+ const row = /*#__PURE__*/ _jsxs(_Fragment, {
327
+ children: [
328
+ /*#__PURE__*/ _jsx(Icon, {
329
+ name: "cornerDownRightLine",
330
+ className: "mt-3 size-14 shrink-0 text-foreground-neutral-muted",
331
+ "aria-hidden": "true"
332
+ }),
333
+ /*#__PURE__*/ _jsxs("span", {
334
+ className: "flex min-w-0 flex-col gap-1",
335
+ children: [
336
+ /*#__PURE__*/ _jsx(Text, {
337
+ as: "span",
338
+ size: "sm",
339
+ className: "min-w-0 truncate text-foreground-neutral-base",
340
+ children: decision.subscriptionName
341
+ }),
342
+ /*#__PURE__*/ _jsx(Code, {
343
+ as: "span",
344
+ variant: "label",
345
+ className: "truncate text-foreground-neutral-muted",
346
+ children: decision.runName
347
+ })
348
+ ]
349
+ })
350
+ ]
351
+ });
352
+ const rowClassName = 'flex min-w-0 items-start gap-8 rounded-6 px-8 py-6 hover:bg-background-components-hover focus-visible:outline-none focus-visible:shadow-button-neutral-focus';
288
353
  return /*#__PURE__*/ _jsx("li", {
289
- children: /*#__PURE__*/ _jsxs(Link, {
290
- to: "/workspaces/$wid/projects/$pid/runs/$workflowRunId",
354
+ children: workspaceSlug && resolvedProjectSlug ? /*#__PURE__*/ _jsx(Link, {
355
+ to: "/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId",
291
356
  params: {
292
- wid: workspaceId,
293
- pid: decision.projectId ?? '',
357
+ workspaceSlug,
358
+ projectSlug: resolvedProjectSlug,
294
359
  workflowRunId: decision.runId
295
360
  },
296
- 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",
297
- children: [
298
- /*#__PURE__*/ _jsx(Icon, {
299
- name: "cornerDownRightLine",
300
- className: "mt-3 size-14 shrink-0 text-foreground-neutral-muted",
301
- "aria-hidden": "true"
302
- }),
303
- /*#__PURE__*/ _jsxs("span", {
304
- className: "flex min-w-0 flex-col gap-1",
305
- children: [
306
- /*#__PURE__*/ _jsx(Text, {
307
- as: "span",
308
- size: "sm",
309
- className: "min-w-0 truncate text-foreground-neutral-base",
310
- children: decision.subscriptionName
311
- }),
312
- /*#__PURE__*/ _jsx(Code, {
313
- as: "span",
314
- variant: "label",
315
- className: "truncate text-foreground-neutral-muted",
316
- children: decision.runName
317
- })
318
- ]
319
- })
320
- ]
361
+ className: rowClassName,
362
+ children: row
363
+ }) : /*#__PURE__*/ _jsx("div", {
364
+ className: rowClassName,
365
+ children: row
321
366
  })
322
367
  });
323
368
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/trigger-event-detail.tsx"],"sourcesContent":["import {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 type {\n TriggerEventDetail as TriggerEventDetailModel,\n TriggerEventMatchedWorkflowResult,\n} from '#core/trigger-event.js';\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';\nconst DETAIL_RAIL_CLASS =\n '@min-[820px]:sticky @min-[820px]:top-16 @min-[820px]:max-h-[calc(var(--app-content-h,100dvh_-_96px)_-_32px)] @min-[820px]:min-h-[min(320px,calc(var(--app-content-h,100dvh_-_96px)_-_32px))]';\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: TriggerEventDetailModel;\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, DETAIL_RAIL_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-[820px]: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.receivedAt} />\n </Text>\n </div>\n <Badge variant={result.badge} size=\"xs\">\n {result.label}\n </Badge>\n </div>\n </div>\n\n <div\n key={event.id}\n className=\"flex min-h-0 flex-1 flex-col gap-20 overflow-y-auto p-16 scrollbar\"\n >\n <EventRuns workspaceId={workspaceId} event={event} />\n <EventPayload payload={formattedPayload} />\n </div>\n </aside>\n );\n}\n\nfunction triggerEventDisplayLabel(event: Pick<TriggerEventDetailModel, 'event' | 'source'>) {\n return event.event || event.source;\n}\n\nfunction triggerEventFullLabel(event: Pick<TriggerEventDetailModel, '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-[820px]: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, DETAIL_RAIL_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-[820px]: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\n aria-label=\"Event details\"\n className={cn(PANEL_CLASS, DETAIL_RAIL_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-[820px]: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({workspaceId, event}: {workspaceId: string; event: TriggerEventDetailModel}) {\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({\n workspaceId,\n decision,\n}: {\n workspaceId: string;\n decision: TriggerEventMatchedWorkflowResult;\n}) {\n if (decision.decision !== 'triggered' || !decision.runId || !decision.runName) {\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.subscriptionName}\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.projectId ?? '', workflowRunId: decision.runId}}\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.subscriptionName}\n </Text>\n <Code as=\"span\" variant=\"label\" className=\"truncate text-foreground-neutral-muted\">\n {decision.runName}\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 flex-col overflow-visible rounded-8 bg-background-contrast-base shadow-none\"\n >\n <CodeBlockHeader className=\"sticky top-0 z-10 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 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","DETAIL_RAIL_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","receivedAt","badge","label","EventRuns","EventPayload","id","filter","Boolean","join","icon","title","role","decisions","length","outcome","section","aria-labelledby","bold","ul","map","decision","DecisionRow","runId","runName","li","name","subscriptionName","reason","to","params","wid","pid","projectId","workflowRunId","span","language","filename","code","item","lineNumbers","syntaxHighlighting"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/components/trigger-event-detail.tsx"],"sourcesContent":["import {useProjectQuery, useProjectsInfiniteQuery} from '@shipfox/client-projects';\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 type {\n TriggerEventDetail as TriggerEventDetailModel,\n TriggerEventMatchedWorkflowResult,\n} from '#core/trigger-event.js';\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';\nconst DETAIL_RAIL_CLASS =\n '@min-[820px]:sticky @min-[820px]:top-16 @min-[820px]:max-h-[calc(var(--app-content-h,100dvh_-_96px)_-_32px)] @min-[820px]:min-h-[min(320px,calc(var(--app-content-h,100dvh_-_96px)_-_32px))]';\n\nexport interface TriggerEventDetailProps {\n workspaceId?: string | undefined;\n workspaceSlug?: string | undefined;\n eventId?: string | undefined;\n onBack: () => void;\n}\n\nexport function TriggerEventDetail({\n workspaceId,\n workspaceSlug,\n eventId,\n onBack,\n}: TriggerEventDetailProps) {\n const query = useTriggerEventQuery(eventId);\n\n if (!eventId) return <TriggerEventDetailPlaceholder />;\n if (query.data) {\n return (\n <TriggerEventDetailView\n workspaceId={workspaceId}\n workspaceSlug={workspaceSlug}\n event={query.data}\n onBack={onBack}\n />\n );\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 workspaceSlug,\n event,\n onBack,\n}: {\n workspaceId?: string | undefined;\n workspaceSlug?: string | undefined;\n event: TriggerEventDetailModel;\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, DETAIL_RAIL_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-[820px]: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.receivedAt} />\n </Text>\n </div>\n <Badge variant={result.badge} size=\"xs\">\n {result.label}\n </Badge>\n </div>\n </div>\n\n <div\n key={event.id}\n className=\"flex min-h-0 flex-1 flex-col gap-20 overflow-y-auto p-16 scrollbar\"\n >\n <EventRuns workspaceId={workspaceId} workspaceSlug={workspaceSlug} event={event} />\n <EventPayload payload={formattedPayload} />\n </div>\n </aside>\n );\n}\n\nfunction triggerEventDisplayLabel(event: Pick<TriggerEventDetailModel, 'event' | 'source'>) {\n return event.event || event.source;\n}\n\nfunction triggerEventFullLabel(event: Pick<TriggerEventDetailModel, '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-[820px]: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, DETAIL_RAIL_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-[820px]: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\n aria-label=\"Event details\"\n className={cn(PANEL_CLASS, DETAIL_RAIL_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-[820px]: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 workspaceSlug,\n event,\n}: {\n workspaceId?: string | undefined;\n workspaceSlug?: string | undefined;\n event: TriggerEventDetailModel;\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 if (!workspaceId) {\n return <EventRunsList workspaceSlug={workspaceSlug} projectSlugs={new Map()} event={event} />;\n }\n\n return (\n <EventRunsWithProjects workspaceId={workspaceId} workspaceSlug={workspaceSlug} event={event} />\n );\n}\n\nfunction EventRunsWithProjects({\n workspaceId,\n workspaceSlug,\n event,\n}: {\n workspaceId: string;\n workspaceSlug?: string | undefined;\n event: TriggerEventDetailModel;\n}) {\n const projectsQuery = useProjectsInfiniteQuery(workspaceId);\n const projectSlugs = useMemo(\n () =>\n new Map(\n projectsQuery.data?.pages\n .flatMap((page) => page.projects)\n .map((project) => [project.id, project.slug] as const),\n ),\n [projectsQuery.data],\n );\n return (\n <EventRunsList\n workspaceSlug={workspaceSlug}\n projectSlugs={projectSlugs}\n projectDetailLookupEnabled={!projectsQuery.isPending}\n event={event}\n />\n );\n}\n\nfunction EventRunsList({\n workspaceSlug,\n projectSlugs,\n projectDetailLookupEnabled = false,\n event,\n}: {\n workspaceSlug?: string | undefined;\n projectSlugs: ReadonlyMap<string, string>;\n projectDetailLookupEnabled?: boolean;\n event: TriggerEventDetailModel;\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\n key={decision.id}\n workspaceSlug={workspaceSlug}\n projectId={decision.projectId ?? undefined}\n projectSlug={decision.projectId ? projectSlugs.get(decision.projectId) : undefined}\n projectDetailLookupEnabled={projectDetailLookupEnabled}\n decision={decision}\n />\n ))}\n </ul>\n </section>\n );\n}\n\nfunction DecisionRow({\n projectId,\n projectSlug,\n workspaceSlug,\n projectDetailLookupEnabled,\n decision,\n}: {\n projectId?: string | undefined;\n projectSlug?: string | undefined;\n workspaceSlug?: string | undefined;\n projectDetailLookupEnabled: boolean;\n decision: TriggerEventMatchedWorkflowResult;\n}) {\n const canRenderRunLink =\n decision.decision === 'triggered' && Boolean(decision.runId && decision.runName);\n const projectQuery = useProjectQuery(\n canRenderRunLink && projectDetailLookupEnabled && !projectSlug ? projectId : undefined,\n );\n const resolvedProjectSlug = projectSlug ?? projectQuery.data?.slug;\n\n if (decision.decision !== 'triggered' || !decision.runId || !decision.runName) {\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.subscriptionName}\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 const row = (\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.subscriptionName}\n </Text>\n <Code as=\"span\" variant=\"label\" className=\"truncate text-foreground-neutral-muted\">\n {decision.runName}\n </Code>\n </span>\n </>\n );\n const rowClassName =\n 'flex min-w-0 items-start gap-8 rounded-6 px-8 py-6 hover:bg-background-components-hover focus-visible:outline-none focus-visible:shadow-button-neutral-focus';\n\n return (\n <li>\n {workspaceSlug && resolvedProjectSlug ? (\n <Link\n to=\"/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId\"\n params={{\n workspaceSlug,\n projectSlug: resolvedProjectSlug,\n workflowRunId: decision.runId,\n }}\n className={rowClassName}\n >\n {row}\n </Link>\n ) : (\n <div className={rowClassName}>{row}</div>\n )}\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 flex-col overflow-visible rounded-8 bg-background-contrast-base shadow-none\"\n >\n <CodeBlockHeader className=\"sticky top-0 z-10 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 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":["useProjectQuery","useProjectsInfiniteQuery","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","DETAIL_RAIL_CLASS","TriggerEventDetail","workspaceId","workspaceSlug","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","receivedAt","badge","label","EventRuns","EventPayload","id","filter","Boolean","join","icon","title","role","decisions","length","outcome","EventRunsList","projectSlugs","Map","EventRunsWithProjects","projectsQuery","pages","flatMap","page","projects","map","project","slug","projectDetailLookupEnabled","isPending","section","aria-labelledby","bold","ul","decision","DecisionRow","projectId","undefined","projectSlug","get","canRenderRunLink","runId","runName","projectQuery","resolvedProjectSlug","li","name","subscriptionName","reason","row","span","rowClassName","to","params","workflowRunId","language","filename","code","item","lineNumbers","syntaxHighlighting"],"mappings":"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"}
@@ -19,6 +19,7 @@ declare const meta: {
19
19
  decorators: Decorator[];
20
20
  args: {
21
21
  workspaceId: string;
22
+ workspaceSlug: string;
22
23
  event: import("../index.js").TriggerEventDetail;
23
24
  onBack: () => undefined;
24
25
  };