@shipfox/client-integrations 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 (243) hide show
  1. package/.storybook/main.ts +1 -0
  2. package/.storybook/preview.css +4 -0
  3. package/.storybook/preview.tsx +56 -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 +207 -0
  8. package/LICENSE +21 -0
  9. package/dist/components/connection-picker.d.ts +7 -0
  10. package/dist/components/connection-picker.d.ts.map +1 -0
  11. package/dist/components/connection-picker.js +98 -0
  12. package/dist/components/connection-picker.js.map +1 -0
  13. package/dist/components/installed-integrations-section.d.ts +14 -0
  14. package/dist/components/installed-integrations-section.d.ts.map +1 -0
  15. package/dist/components/installed-integrations-section.js +203 -0
  16. package/dist/components/installed-integrations-section.js.map +1 -0
  17. package/dist/components/integration-delete-confirm-modal.d.ts +10 -0
  18. package/dist/components/integration-delete-confirm-modal.d.ts.map +1 -0
  19. package/dist/components/integration-delete-confirm-modal.js +61 -0
  20. package/dist/components/integration-delete-confirm-modal.js.map +1 -0
  21. package/dist/components/integration-gallery-for-workspace.d.ts +9 -0
  22. package/dist/components/integration-gallery-for-workspace.d.ts.map +1 -0
  23. package/dist/components/integration-gallery-for-workspace.js +169 -0
  24. package/dist/components/integration-gallery-for-workspace.js.map +1 -0
  25. package/dist/components/integration-gallery.d.ts +8 -0
  26. package/dist/components/integration-gallery.d.ts.map +1 -0
  27. package/dist/components/integration-gallery.js +26 -0
  28. package/dist/components/integration-gallery.js.map +1 -0
  29. package/dist/components/integration-gallery.stories.d.ts +26 -0
  30. package/dist/components/integration-gallery.stories.d.ts.map +1 -0
  31. package/dist/components/integration-gallery.stories.js +335 -0
  32. package/dist/components/integration-gallery.stories.js.map +1 -0
  33. package/dist/components/integration-usage-events.d.ts +4 -0
  34. package/dist/components/integration-usage-events.d.ts.map +1 -0
  35. package/dist/components/integration-usage-events.js +127 -0
  36. package/dist/components/integration-usage-events.js.map +1 -0
  37. package/dist/components/integration-usage-modal.d.ts +16 -0
  38. package/dist/components/integration-usage-modal.d.ts.map +1 -0
  39. package/dist/components/integration-usage-modal.js +184 -0
  40. package/dist/components/integration-usage-modal.js.map +1 -0
  41. package/dist/components/provider-grid.d.ts +14 -0
  42. package/dist/components/provider-grid.d.ts.map +1 -0
  43. package/dist/components/provider-grid.js +152 -0
  44. package/dist/components/provider-grid.js.map +1 -0
  45. package/dist/components/redirect-install-page.d.ts +19 -0
  46. package/dist/components/redirect-install-page.d.ts.map +1 -0
  47. package/dist/components/redirect-install-page.js +68 -0
  48. package/dist/components/redirect-install-page.js.map +1 -0
  49. package/dist/components/repository-picker.d.ts +15 -0
  50. package/dist/components/repository-picker.d.ts.map +1 -0
  51. package/dist/components/repository-picker.js +78 -0
  52. package/dist/components/repository-picker.js.map +1 -0
  53. package/dist/components/webhook/copyable-value.d.ts +10 -0
  54. package/dist/components/webhook/copyable-value.d.ts.map +1 -0
  55. package/dist/components/webhook/copyable-value.js +65 -0
  56. package/dist/components/webhook/copyable-value.js.map +1 -0
  57. package/dist/components/webhook/webhook-create-modal.d.ts +10 -0
  58. package/dist/components/webhook/webhook-create-modal.d.ts.map +1 -0
  59. package/dist/components/webhook/webhook-create-modal.js +233 -0
  60. package/dist/components/webhook/webhook-create-modal.js.map +1 -0
  61. package/dist/components/webhook/webhook-form-errors.d.ts +11 -0
  62. package/dist/components/webhook/webhook-form-errors.d.ts.map +1 -0
  63. package/dist/components/webhook/webhook-form-errors.js +27 -0
  64. package/dist/components/webhook/webhook-form-errors.js.map +1 -0
  65. package/dist/components/webhook/webhook-modals.stories.d.ts +25 -0
  66. package/dist/components/webhook/webhook-modals.stories.d.ts.map +1 -0
  67. package/dist/components/webhook/webhook-modals.stories.js +222 -0
  68. package/dist/components/webhook/webhook-modals.stories.js.map +1 -0
  69. package/dist/components/webhook/webhook-public-endpoint-alert.d.ts +2 -0
  70. package/dist/components/webhook/webhook-public-endpoint-alert.d.ts.map +1 -0
  71. package/dist/components/webhook/webhook-public-endpoint-alert.js +20 -0
  72. package/dist/components/webhook/webhook-public-endpoint-alert.js.map +1 -0
  73. package/dist/components/webhook/webhook-usage-details.d.ts +7 -0
  74. package/dist/components/webhook/webhook-usage-details.d.ts.map +1 -0
  75. package/dist/components/webhook/webhook-usage-details.js +49 -0
  76. package/dist/components/webhook/webhook-usage-details.js.map +1 -0
  77. package/dist/connection-status-badge.d.ts +12 -0
  78. package/dist/connection-status-badge.d.ts.map +1 -0
  79. package/dist/connection-status-badge.js +34 -0
  80. package/dist/connection-status-badge.js.map +1 -0
  81. package/dist/feature.d.ts +37 -0
  82. package/dist/feature.d.ts.map +1 -0
  83. package/dist/feature.js +48 -0
  84. package/dist/feature.js.map +1 -0
  85. package/dist/hooks/api/integrations.d.ts +265 -0
  86. package/dist/hooks/api/integrations.d.ts.map +1 -0
  87. package/dist/hooks/api/integrations.js +229 -0
  88. package/dist/hooks/api/integrations.js.map +1 -0
  89. package/dist/hooks/api/webhook-connections.d.ts +91 -0
  90. package/dist/hooks/api/webhook-connections.d.ts.map +1 -0
  91. package/dist/hooks/api/webhook-connections.js +97 -0
  92. package/dist/hooks/api/webhook-connections.js.map +1 -0
  93. package/dist/index.d.ts +17 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +18 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/integration-icon.d.ts +17 -0
  98. package/dist/integration-icon.d.ts.map +1 -0
  99. package/dist/integration-icon.js +22 -0
  100. package/dist/integration-icon.js.map +1 -0
  101. package/dist/linear-callback.d.ts +17 -0
  102. package/dist/linear-callback.d.ts.map +1 -0
  103. package/dist/linear-callback.js +113 -0
  104. package/dist/linear-callback.js.map +1 -0
  105. package/dist/pages/gitea-form-errors.d.ts +11 -0
  106. package/dist/pages/gitea-form-errors.d.ts.map +1 -0
  107. package/dist/pages/gitea-form-errors.js +35 -0
  108. package/dist/pages/gitea-form-errors.js.map +1 -0
  109. package/dist/pages/gitea-install-page.d.ts +2 -0
  110. package/dist/pages/gitea-install-page.d.ts.map +1 -0
  111. package/dist/pages/gitea-install-page.js +139 -0
  112. package/dist/pages/gitea-install-page.js.map +1 -0
  113. package/dist/pages/github-install-page.d.ts +2 -0
  114. package/dist/pages/github-install-page.d.ts.map +1 -0
  115. package/dist/pages/github-install-page.js +11 -0
  116. package/dist/pages/github-install-page.js.map +1 -0
  117. package/dist/pages/linear-callback-page.d.ts +2 -0
  118. package/dist/pages/linear-callback-page.d.ts.map +1 -0
  119. package/dist/pages/linear-callback-page.js +192 -0
  120. package/dist/pages/linear-callback-page.js.map +1 -0
  121. package/dist/pages/linear-install-page.d.ts +2 -0
  122. package/dist/pages/linear-install-page.d.ts.map +1 -0
  123. package/dist/pages/linear-install-page.js +24 -0
  124. package/dist/pages/linear-install-page.js.map +1 -0
  125. package/dist/pages/sentry-callback-page.d.ts +2 -0
  126. package/dist/pages/sentry-callback-page.d.ts.map +1 -0
  127. package/dist/pages/sentry-callback-page.js +256 -0
  128. package/dist/pages/sentry-callback-page.js.map +1 -0
  129. package/dist/pages/sentry-install-page.d.ts +2 -0
  130. package/dist/pages/sentry-install-page.d.ts.map +1 -0
  131. package/dist/pages/sentry-install-page.js +17 -0
  132. package/dist/pages/sentry-install-page.js.map +1 -0
  133. package/dist/pages/source-control-onboarding-page.d.ts +2 -0
  134. package/dist/pages/source-control-onboarding-page.d.ts.map +1 -0
  135. package/dist/pages/source-control-onboarding-page.js +37 -0
  136. package/dist/pages/source-control-onboarding-page.js.map +1 -0
  137. package/dist/provider-catalog.d.ts +15 -0
  138. package/dist/provider-catalog.d.ts.map +1 -0
  139. package/dist/provider-catalog.js +28 -0
  140. package/dist/provider-catalog.js.map +1 -0
  141. package/dist/routes/gitea.d.ts +6 -0
  142. package/dist/routes/gitea.d.ts.map +1 -0
  143. package/dist/routes/gitea.js +7 -0
  144. package/dist/routes/gitea.js.map +1 -0
  145. package/dist/routes/github-callback.d.ts +6 -0
  146. package/dist/routes/github-callback.d.ts.map +1 -0
  147. package/dist/routes/github-callback.js +129 -0
  148. package/dist/routes/github-callback.js.map +1 -0
  149. package/dist/routes/github.d.ts +6 -0
  150. package/dist/routes/github.d.ts.map +1 -0
  151. package/dist/routes/github.js +7 -0
  152. package/dist/routes/github.js.map +1 -0
  153. package/dist/routes/integrations.d.ts +6 -0
  154. package/dist/routes/integrations.d.ts.map +1 -0
  155. package/dist/routes/integrations.js +7 -0
  156. package/dist/routes/integrations.js.map +1 -0
  157. package/dist/routes/linear-callback.d.ts +6 -0
  158. package/dist/routes/linear-callback.d.ts.map +1 -0
  159. package/dist/routes/linear-callback.js +7 -0
  160. package/dist/routes/linear-callback.js.map +1 -0
  161. package/dist/routes/linear.d.ts +6 -0
  162. package/dist/routes/linear.d.ts.map +1 -0
  163. package/dist/routes/linear.js +7 -0
  164. package/dist/routes/linear.js.map +1 -0
  165. package/dist/routes/sentry-callback.d.ts +6 -0
  166. package/dist/routes/sentry-callback.d.ts.map +1 -0
  167. package/dist/routes/sentry-callback.js +7 -0
  168. package/dist/routes/sentry-callback.js.map +1 -0
  169. package/dist/routes/sentry.d.ts +6 -0
  170. package/dist/routes/sentry.d.ts.map +1 -0
  171. package/dist/routes/sentry.js +7 -0
  172. package/dist/routes/sentry.js.map +1 -0
  173. package/dist/sentry-callback.d.ts +35 -0
  174. package/dist/sentry-callback.d.ts.map +1 -0
  175. package/dist/sentry-callback.js +132 -0
  176. package/dist/sentry-callback.js.map +1 -0
  177. package/dist/tsconfig.test.tsbuildinfo +1 -0
  178. package/package.json +120 -0
  179. package/src/components/connection-picker.tsx +89 -0
  180. package/src/components/installed-integrations-section.tsx +198 -0
  181. package/src/components/integration-delete-confirm-modal.tsx +62 -0
  182. package/src/components/integration-gallery-for-workspace.tsx +193 -0
  183. package/src/components/integration-gallery.stories.tsx +302 -0
  184. package/src/components/integration-gallery.test.tsx +692 -0
  185. package/src/components/integration-gallery.tsx +49 -0
  186. package/src/components/integration-usage-events.test.ts +80 -0
  187. package/src/components/integration-usage-events.ts +116 -0
  188. package/src/components/integration-usage-modal.tsx +178 -0
  189. package/src/components/provider-grid.tsx +163 -0
  190. package/src/components/redirect-install-page.test.tsx +98 -0
  191. package/src/components/redirect-install-page.tsx +68 -0
  192. package/src/components/repository-picker.tsx +102 -0
  193. package/src/components/webhook/copyable-value.test.tsx +41 -0
  194. package/src/components/webhook/copyable-value.tsx +72 -0
  195. package/src/components/webhook/webhook-create-modal.tsx +247 -0
  196. package/src/components/webhook/webhook-form-errors.test.ts +45 -0
  197. package/src/components/webhook/webhook-form-errors.ts +32 -0
  198. package/src/components/webhook/webhook-modals.stories.tsx +225 -0
  199. package/src/components/webhook/webhook-public-endpoint-alert.tsx +15 -0
  200. package/src/components/webhook/webhook-usage-details.tsx +44 -0
  201. package/src/connection-status-badge.tsx +38 -0
  202. package/src/feature.ts +47 -0
  203. package/src/hooks/api/integrations.test.ts +105 -0
  204. package/src/hooks/api/integrations.ts +287 -0
  205. package/src/hooks/api/webhook-connections.ts +115 -0
  206. package/src/index.ts +16 -0
  207. package/src/integration-icon.react.test.tsx +40 -0
  208. package/src/integration-icon.test.ts +19 -0
  209. package/src/integration-icon.tsx +26 -0
  210. package/src/linear-callback.test.ts +227 -0
  211. package/src/linear-callback.ts +136 -0
  212. package/src/pages/gitea-form-errors.test.ts +55 -0
  213. package/src/pages/gitea-form-errors.ts +36 -0
  214. package/src/pages/gitea-install-page.tsx +108 -0
  215. package/src/pages/github-install-page.tsx +11 -0
  216. package/src/pages/linear-callback-page.test.tsx +157 -0
  217. package/src/pages/linear-callback-page.tsx +175 -0
  218. package/src/pages/linear-install-page.tsx +26 -0
  219. package/src/pages/sentry-callback-page.test.tsx +205 -0
  220. package/src/pages/sentry-callback-page.tsx +238 -0
  221. package/src/pages/sentry-install-page.tsx +17 -0
  222. package/src/pages/source-control-onboarding-page.test.tsx +46 -0
  223. package/src/pages/source-control-onboarding-page.tsx +26 -0
  224. package/src/provider-catalog.test.ts +42 -0
  225. package/src/provider-catalog.ts +49 -0
  226. package/src/routes/gitea.tsx +4 -0
  227. package/src/routes/github-callback.tsx +114 -0
  228. package/src/routes/github.tsx +4 -0
  229. package/src/routes/integrations.tsx +4 -0
  230. package/src/routes/linear-callback.tsx +4 -0
  231. package/src/routes/linear.tsx +4 -0
  232. package/src/routes/sentry-callback.tsx +4 -0
  233. package/src/routes/sentry.tsx +4 -0
  234. package/src/sentry-callback.test.ts +239 -0
  235. package/src/sentry-callback.ts +142 -0
  236. package/test/render.tsx +111 -0
  237. package/test/setup.ts +3 -0
  238. package/tsconfig.build.json +9 -0
  239. package/tsconfig.build.tsbuildinfo +1 -0
  240. package/tsconfig.json +3 -0
  241. package/tsconfig.test.json +8 -0
  242. package/vercel.json +8 -0
  243. package/vitest.config.ts +75 -0
@@ -0,0 +1,335 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { configureApiClient } from '@shipfox/client-api';
3
+ import { authStateAtom } from '@shipfox/client-auth';
4
+ import { Toaster } from '@shipfox/react-ui/toast';
5
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
+ import { createMemoryHistory, createRootRoute, createRoute, createRouter, Outlet, RouterProvider } from '@tanstack/react-router';
7
+ import { createStore, Provider as JotaiProvider } from 'jotai';
8
+ import { useMemo } from 'react';
9
+ import { IntegrationGallery } from './integration-gallery.js';
10
+ const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';
11
+ const WORKSPACE_PATH = `/workspaces/${WORKSPACE_ID}/settings/integrations`;
12
+ const SETUP_PATHS = [
13
+ '/workspaces/$wid/integrations/github',
14
+ '/workspaces/$wid/integrations/sentry',
15
+ '/workspaces/$wid/integrations/linear',
16
+ '/workspaces/$wid/integrations/gitea',
17
+ '/workspaces/$wid/settings/events'
18
+ ];
19
+ const PROVIDERS = [
20
+ {
21
+ provider: 'github',
22
+ display_name: 'GitHub',
23
+ capabilities: [
24
+ 'source_control'
25
+ ]
26
+ },
27
+ {
28
+ provider: 'sentry',
29
+ display_name: 'Sentry',
30
+ capabilities: []
31
+ },
32
+ {
33
+ provider: 'linear',
34
+ display_name: 'Linear',
35
+ capabilities: [
36
+ 'agent_tools'
37
+ ]
38
+ },
39
+ {
40
+ provider: 'gitea',
41
+ display_name: 'Gitea',
42
+ capabilities: [
43
+ 'source_control'
44
+ ]
45
+ },
46
+ {
47
+ provider: 'webhook',
48
+ display_name: 'Webhook',
49
+ capabilities: []
50
+ }
51
+ ];
52
+ function IntegrationGalleryStory({ scenario }) {
53
+ configureApiClient({
54
+ baseUrl: 'https://api.example.test',
55
+ fetchImpl: fetchForScenario(scenario)
56
+ });
57
+ const queryClient = useMemo(()=>new QueryClient({
58
+ defaultOptions: {
59
+ queries: {
60
+ retry: false
61
+ }
62
+ }
63
+ }), []);
64
+ const store = useMemo(()=>{
65
+ const nextStore = createStore();
66
+ nextStore.set(authStateAtom, {
67
+ status: 'authenticated',
68
+ workspaces: [
69
+ {
70
+ id: WORKSPACE_ID,
71
+ name: 'Acme',
72
+ membershipId: 'membership-1'
73
+ }
74
+ ]
75
+ });
76
+ return nextStore;
77
+ }, []);
78
+ const router = useMemo(()=>{
79
+ const rootRoute = createRootRoute({
80
+ component: Outlet
81
+ });
82
+ const workspaceRoute = createRoute({
83
+ getParentRoute: ()=>rootRoute,
84
+ path: '/workspaces/$wid',
85
+ component: Outlet
86
+ });
87
+ const galleryRoute = createRoute({
88
+ getParentRoute: ()=>workspaceRoute,
89
+ path: 'settings/integrations',
90
+ component: ()=>/*#__PURE__*/ _jsx("div", {
91
+ className: "mx-auto w-full max-w-[760px] bg-background-neutral-background p-24",
92
+ children: /*#__PURE__*/ _jsx(IntegrationGallery, {
93
+ workspaceId: WORKSPACE_ID
94
+ })
95
+ })
96
+ });
97
+ const setupRoutes = SETUP_PATHS.map((path)=>createRoute({
98
+ getParentRoute: ()=>workspaceRoute,
99
+ path: path.replace('/workspaces/$wid/', ''),
100
+ component: ()=>/*#__PURE__*/ _jsx("div", {})
101
+ }));
102
+ return createRouter({
103
+ history: createMemoryHistory({
104
+ initialEntries: [
105
+ WORKSPACE_PATH
106
+ ]
107
+ }),
108
+ routeTree: rootRoute.addChildren([
109
+ workspaceRoute.addChildren([
110
+ galleryRoute,
111
+ ...setupRoutes
112
+ ])
113
+ ])
114
+ });
115
+ }, []);
116
+ return /*#__PURE__*/ _jsx(QueryClientProvider, {
117
+ client: queryClient,
118
+ children: /*#__PURE__*/ _jsxs(JotaiProvider, {
119
+ store: store,
120
+ children: [
121
+ /*#__PURE__*/ _jsx(RouterProvider, {
122
+ router: router
123
+ }),
124
+ /*#__PURE__*/ _jsx(Toaster, {})
125
+ ]
126
+ })
127
+ });
128
+ }
129
+ const meta = {
130
+ title: 'Integrations/Gallery',
131
+ component: IntegrationGalleryStory,
132
+ parameters: {
133
+ layout: 'fullscreen'
134
+ },
135
+ args: {
136
+ scenario: 'mixed'
137
+ }
138
+ };
139
+ export default meta;
140
+ export const Playground = {};
141
+ export const EmptyConnections = {
142
+ args: {
143
+ scenario: 'empty-connections'
144
+ }
145
+ };
146
+ export const Loading = {
147
+ args: {
148
+ scenario: 'loading'
149
+ }
150
+ };
151
+ export const ConnectionsError = {
152
+ args: {
153
+ scenario: 'connections-error'
154
+ }
155
+ };
156
+ export const ProvidersError = {
157
+ args: {
158
+ scenario: 'providers-error'
159
+ }
160
+ };
161
+ export const NoProvidersAvailable = {
162
+ args: {
163
+ scenario: 'no-providers'
164
+ }
165
+ };
166
+ export const LongNames = {
167
+ args: {
168
+ scenario: 'long-names'
169
+ }
170
+ };
171
+ function fetchForScenario(scenario) {
172
+ return (input, init)=>{
173
+ const url = requestUrl(input);
174
+ const method = init?.method ?? 'GET';
175
+ if (scenario === 'loading') return new Promise(()=>undefined);
176
+ if (url.pathname === '/integration-providers') {
177
+ if (scenario === 'providers-error') return Promise.resolve(errorResponse());
178
+ return Promise.resolve(jsonResponse({
179
+ providers: scenario === 'no-providers' ? [] : PROVIDERS
180
+ }));
181
+ }
182
+ if (url.pathname.startsWith('/integration-connections/') && method === 'PATCH') {
183
+ return Promise.resolve(jsonResponse({
184
+ ...connection(),
185
+ id: url.pathname.split('/').at(-1),
186
+ lifecycle_status: 'disabled'
187
+ }));
188
+ }
189
+ if (url.pathname.startsWith('/integration-connections/') && method === 'DELETE') {
190
+ return Promise.resolve(jsonResponse(undefined, {
191
+ status: 204
192
+ }));
193
+ }
194
+ if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'PATCH') {
195
+ return Promise.resolve(jsonResponse({
196
+ id: url.pathname.split('/').at(-1),
197
+ workspace_id: WORKSPACE_ID,
198
+ name: 'Stripe production',
199
+ slug: 'stripe-prod',
200
+ lifecycle_status: 'disabled',
201
+ inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',
202
+ created_at: '2026-04-12T00:00:00.000Z',
203
+ updated_at: '2026-04-12T00:00:00.000Z'
204
+ }));
205
+ }
206
+ if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'DELETE') {
207
+ return Promise.resolve(jsonResponse(undefined, {
208
+ status: 204
209
+ }));
210
+ }
211
+ if (url.pathname === '/integration-connections') {
212
+ if (scenario === 'connections-error') return Promise.resolve(errorResponse());
213
+ return Promise.resolve(jsonResponse({
214
+ connections: connectionsForScenario(scenario)
215
+ }));
216
+ }
217
+ if (url.pathname === '/integrations/webhook/connections') {
218
+ return Promise.resolve(jsonResponse({
219
+ connections: [
220
+ {
221
+ id: '77777777-7777-4777-8777-777777777777',
222
+ workspace_id: WORKSPACE_ID,
223
+ name: 'Stripe production',
224
+ slug: 'stripe-prod',
225
+ lifecycle_status: 'active',
226
+ inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',
227
+ created_at: '2026-04-12T00:00:00.000Z',
228
+ updated_at: '2026-04-12T00:00:00.000Z'
229
+ }
230
+ ]
231
+ }));
232
+ }
233
+ return Promise.resolve(jsonResponse({}, {
234
+ status: 404
235
+ }));
236
+ };
237
+ }
238
+ function connectionsForScenario(scenario) {
239
+ if (scenario === 'empty-connections' || scenario === 'no-providers') return [];
240
+ if (scenario === 'long-names') {
241
+ return [
242
+ connection({
243
+ display_name: 'acme-production-observability-and-source-control-organization',
244
+ lifecycle_status: 'active'
245
+ }),
246
+ connection({
247
+ id: '55555555-5555-4555-8555-555555555555',
248
+ provider: 'sentry',
249
+ display_name: 'sentry-team-with-a-very-long-connected-account-name',
250
+ lifecycle_status: 'error'
251
+ })
252
+ ];
253
+ }
254
+ return [
255
+ connection({
256
+ display_name: 'acme-corp',
257
+ lifecycle_status: 'active'
258
+ }),
259
+ connection({
260
+ id: '88888888-8888-4888-8888-888888888888',
261
+ provider: 'linear',
262
+ display_name: 'linear-acme',
263
+ lifecycle_status: 'active',
264
+ external_url: 'https://linear.app/acme/settings'
265
+ }),
266
+ connection({
267
+ id: '55555555-5555-4555-8555-555555555555',
268
+ provider: 'linear',
269
+ display_name: 'linear-disabled',
270
+ lifecycle_status: 'disabled',
271
+ external_url: undefined
272
+ }),
273
+ connection({
274
+ id: '66666666-6666-4666-8666-666666666666',
275
+ provider: 'linear',
276
+ display_name: 'linear-error',
277
+ lifecycle_status: 'error',
278
+ external_url: undefined
279
+ }),
280
+ connection({
281
+ id: '77777777-7777-4777-8777-777777777777',
282
+ provider: 'webhook',
283
+ external_account_id: 'stripe-prod',
284
+ slug: 'stripe-prod',
285
+ display_name: 'Stripe production',
286
+ capabilities: [],
287
+ lifecycle_status: 'active',
288
+ external_url: undefined,
289
+ created_at: '2026-04-12T00:00:00.000Z',
290
+ updated_at: '2026-04-12T00:00:00.000Z'
291
+ })
292
+ ];
293
+ }
294
+ function connection(overrides = {}) {
295
+ return {
296
+ id: '44444444-4444-4444-8444-444444444444',
297
+ workspace_id: WORKSPACE_ID,
298
+ provider: 'github',
299
+ external_account_id: 'installation-1',
300
+ slug: 'github_acme_corp',
301
+ display_name: 'acme-corp',
302
+ lifecycle_status: 'active',
303
+ capabilities: [
304
+ 'source_control'
305
+ ],
306
+ external_url: 'https://github.com/organizations/acme-corp/settings/installations/1',
307
+ created_at: '2026-03-12T00:00:00.000Z',
308
+ updated_at: '2026-03-12T00:00:00.000Z',
309
+ ...overrides
310
+ };
311
+ }
312
+ function requestUrl(input) {
313
+ if (typeof input === 'string') return new URL(input);
314
+ if (input instanceof URL) return input;
315
+ return new URL(input.url);
316
+ }
317
+ function jsonResponse(body, init = {}) {
318
+ return new Response(JSON.stringify(body), {
319
+ status: 200,
320
+ headers: {
321
+ 'content-type': 'application/json'
322
+ },
323
+ ...init
324
+ });
325
+ }
326
+ function errorResponse() {
327
+ return jsonResponse({
328
+ code: 'server-error'
329
+ }, {
330
+ status: 500,
331
+ statusText: 'Server error'
332
+ });
333
+ }
334
+
335
+ //# sourceMappingURL=integration-gallery.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/integration-gallery.stories.tsx"],"sourcesContent":["import type {\n IntegrationConnectionDto,\n IntegrationProviderDto,\n} from '@shipfox/api-integration-core-dto';\nimport {configureApiClient} from '@shipfox/client-api';\nimport {authStateAtom} from '@shipfox/client-auth';\nimport {Toaster} from '@shipfox/react-ui/toast';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {\n createMemoryHistory,\n createRootRoute,\n createRoute,\n createRouter,\n Outlet,\n RouterProvider,\n} from '@tanstack/react-router';\nimport {createStore, Provider as JotaiProvider} from 'jotai';\nimport {useMemo} from 'react';\nimport {IntegrationGallery} from './integration-gallery.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\nconst WORKSPACE_PATH = `/workspaces/${WORKSPACE_ID}/settings/integrations`;\nconst SETUP_PATHS = [\n '/workspaces/$wid/integrations/github',\n '/workspaces/$wid/integrations/sentry',\n '/workspaces/$wid/integrations/linear',\n '/workspaces/$wid/integrations/gitea',\n '/workspaces/$wid/settings/events',\n] as const;\n\ntype Scenario =\n | 'mixed'\n | 'empty-connections'\n | 'loading'\n | 'connections-error'\n | 'providers-error'\n | 'no-providers'\n | 'long-names';\n\ninterface IntegrationGalleryStoryProps {\n scenario: Scenario;\n}\n\nconst PROVIDERS: IntegrationProviderDto[] = [\n {provider: 'github', display_name: 'GitHub', capabilities: ['source_control']},\n {provider: 'sentry', display_name: 'Sentry', capabilities: []},\n {provider: 'linear', display_name: 'Linear', capabilities: ['agent_tools']},\n {provider: 'gitea', display_name: 'Gitea', capabilities: ['source_control']},\n {provider: 'webhook', display_name: 'Webhook', capabilities: []},\n];\n\nfunction IntegrationGalleryStory({scenario}: IntegrationGalleryStoryProps) {\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: fetchForScenario(scenario),\n });\n\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n const store = useMemo(() => {\n const nextStore = createStore();\n nextStore.set(authStateAtom, {\n status: 'authenticated',\n workspaces: [{id: WORKSPACE_ID, name: 'Acme', membershipId: 'membership-1'}],\n });\n return nextStore;\n }, []);\n const router = useMemo(() => {\n const rootRoute = createRootRoute({component: Outlet});\n const workspaceRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/workspaces/$wid',\n component: Outlet,\n });\n const galleryRoute = createRoute({\n getParentRoute: () => workspaceRoute,\n path: 'settings/integrations',\n component: () => (\n <div className=\"mx-auto w-full max-w-[760px] bg-background-neutral-background p-24\">\n <IntegrationGallery workspaceId={WORKSPACE_ID} />\n </div>\n ),\n });\n const setupRoutes = SETUP_PATHS.map((path) =>\n createRoute({\n getParentRoute: () => workspaceRoute,\n path: path.replace('/workspaces/$wid/', ''),\n component: () => <div />,\n }),\n );\n\n return createRouter({\n history: createMemoryHistory({initialEntries: [WORKSPACE_PATH]}),\n routeTree: rootRoute.addChildren([\n workspaceRoute.addChildren([galleryRoute, ...setupRoutes]),\n ]),\n });\n }, []);\n\n return (\n <QueryClientProvider client={queryClient}>\n <JotaiProvider store={store}>\n <RouterProvider router={router} />\n <Toaster />\n </JotaiProvider>\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Integrations/Gallery',\n component: IntegrationGalleryStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'mixed'},\n} satisfies Meta<typeof IntegrationGalleryStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const EmptyConnections: Story = {\n args: {scenario: 'empty-connections'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ConnectionsError: Story = {\n args: {scenario: 'connections-error'},\n};\n\nexport const ProvidersError: Story = {\n args: {scenario: 'providers-error'},\n};\n\nexport const NoProvidersAvailable: Story = {\n args: {scenario: 'no-providers'},\n};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input, init) => {\n const url = requestUrl(input);\n const method = init?.method ?? 'GET';\n if (scenario === 'loading') return new Promise<Response>(() => undefined);\n if (url.pathname === '/integration-providers') {\n if (scenario === 'providers-error') return Promise.resolve(errorResponse());\n return Promise.resolve(\n jsonResponse({providers: scenario === 'no-providers' ? [] : PROVIDERS}),\n );\n }\n if (url.pathname.startsWith('/integration-connections/') && method === 'PATCH') {\n return Promise.resolve(\n jsonResponse({\n ...connection(),\n id: url.pathname.split('/').at(-1),\n lifecycle_status: 'disabled',\n }),\n );\n }\n if (url.pathname.startsWith('/integration-connections/') && method === 'DELETE') {\n return Promise.resolve(jsonResponse(undefined, {status: 204}));\n }\n if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'PATCH') {\n return Promise.resolve(\n jsonResponse({\n id: url.pathname.split('/').at(-1),\n workspace_id: WORKSPACE_ID,\n name: 'Stripe production',\n slug: 'stripe-prod',\n lifecycle_status: 'disabled',\n inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n }),\n );\n }\n if (url.pathname.startsWith('/integrations/webhook/connections/') && method === 'DELETE') {\n return Promise.resolve(jsonResponse(undefined, {status: 204}));\n }\n if (url.pathname === '/integration-connections') {\n if (scenario === 'connections-error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse({connections: connectionsForScenario(scenario)}));\n }\n if (url.pathname === '/integrations/webhook/connections') {\n return Promise.resolve(\n jsonResponse({\n connections: [\n {\n id: '77777777-7777-4777-8777-777777777777',\n workspace_id: WORKSPACE_ID,\n name: 'Stripe production',\n slug: 'stripe-prod',\n lifecycle_status: 'active',\n inbound_url: 'https://api.example.test/webhook/77777777-7777-4777-8777-777777777777',\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n },\n ],\n }),\n );\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction connectionsForScenario(scenario: Scenario): IntegrationConnectionDto[] {\n if (scenario === 'empty-connections' || scenario === 'no-providers') return [];\n if (scenario === 'long-names') {\n return [\n connection({\n display_name: 'acme-production-observability-and-source-control-organization',\n lifecycle_status: 'active',\n }),\n connection({\n id: '55555555-5555-4555-8555-555555555555',\n provider: 'sentry',\n display_name: 'sentry-team-with-a-very-long-connected-account-name',\n lifecycle_status: 'error',\n }),\n ];\n }\n return [\n connection({display_name: 'acme-corp', lifecycle_status: 'active'}),\n connection({\n id: '88888888-8888-4888-8888-888888888888',\n provider: 'linear',\n display_name: 'linear-acme',\n lifecycle_status: 'active',\n external_url: 'https://linear.app/acme/settings',\n }),\n connection({\n id: '55555555-5555-4555-8555-555555555555',\n provider: 'linear',\n display_name: 'linear-disabled',\n lifecycle_status: 'disabled',\n external_url: undefined,\n }),\n connection({\n id: '66666666-6666-4666-8666-666666666666',\n provider: 'linear',\n display_name: 'linear-error',\n lifecycle_status: 'error',\n external_url: undefined,\n }),\n connection({\n id: '77777777-7777-4777-8777-777777777777',\n provider: 'webhook',\n external_account_id: 'stripe-prod',\n slug: 'stripe-prod',\n display_name: 'Stripe production',\n capabilities: [],\n lifecycle_status: 'active',\n external_url: undefined,\n created_at: '2026-04-12T00:00:00.000Z',\n updated_at: '2026-04-12T00:00:00.000Z',\n }),\n ];\n}\n\nfunction connection(overrides: Partial<IntegrationConnectionDto> = {}): IntegrationConnectionDto {\n return {\n id: '44444444-4444-4444-8444-444444444444',\n workspace_id: WORKSPACE_ID,\n provider: 'github',\n external_account_id: 'installation-1',\n slug: 'github_acme_corp',\n display_name: 'acme-corp',\n lifecycle_status: 'active',\n capabilities: ['source_control'],\n external_url: 'https://github.com/organizations/acme-corp/settings/installations/1',\n created_at: '2026-03-12T00:00:00.000Z',\n updated_at: '2026-03-12T00:00:00.000Z',\n ...overrides,\n };\n}\n\nfunction requestUrl(input: RequestInfo | URL): URL {\n if (typeof input === 'string') return new URL(input);\n if (input instanceof URL) return input;\n return new URL(input.url);\n}\n\nfunction jsonResponse(body: unknown, init: ResponseInit = {}) {\n return new Response(JSON.stringify(body), {\n status: 200,\n headers: {'content-type': 'application/json'},\n ...init,\n });\n}\n\nfunction errorResponse() {\n return jsonResponse({code: 'server-error'}, {status: 500, statusText: 'Server error'});\n}\n"],"names":["configureApiClient","authStateAtom","Toaster","QueryClient","QueryClientProvider","createMemoryHistory","createRootRoute","createRoute","createRouter","Outlet","RouterProvider","createStore","Provider","JotaiProvider","useMemo","IntegrationGallery","WORKSPACE_ID","WORKSPACE_PATH","SETUP_PATHS","PROVIDERS","provider","display_name","capabilities","IntegrationGalleryStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","store","nextStore","set","status","workspaces","id","name","membershipId","router","rootRoute","component","workspaceRoute","getParentRoute","path","galleryRoute","div","className","workspaceId","setupRoutes","map","replace","history","initialEntries","routeTree","addChildren","client","meta","title","parameters","layout","args","Playground","EmptyConnections","Loading","ConnectionsError","ProvidersError","NoProvidersAvailable","LongNames","input","init","url","requestUrl","method","Promise","undefined","pathname","resolve","errorResponse","jsonResponse","providers","startsWith","connection","split","at","lifecycle_status","workspace_id","slug","inbound_url","created_at","updated_at","connections","connectionsForScenario","external_url","external_account_id","overrides","URL","body","Response","JSON","stringify","headers","code","statusText"],"mappings":";AAIA,SAAQA,kBAAkB,QAAO,sBAAsB;AACvD,SAAQC,aAAa,QAAO,uBAAuB;AACnD,SAAQC,OAAO,QAAO,0BAA0B;AAEhD,SAAQC,WAAW,EAAEC,mBAAmB,QAAO,wBAAwB;AACvE,SACEC,mBAAmB,EACnBC,eAAe,EACfC,WAAW,EACXC,YAAY,EACZC,MAAM,EACNC,cAAc,QACT,yBAAyB;AAChC,SAAQC,WAAW,EAAEC,YAAYC,aAAa,QAAO,QAAQ;AAC7D,SAAQC,OAAO,QAAO,QAAQ;AAC9B,SAAQC,kBAAkB,QAAO,2BAA2B;AAE5D,MAAMC,eAAe;AACrB,MAAMC,iBAAiB,CAAC,YAAY,EAAED,aAAa,sBAAsB,CAAC;AAC1E,MAAME,cAAc;IAClB;IACA;IACA;IACA;IACA;CACD;AAeD,MAAMC,YAAsC;IAC1C;QAACC,UAAU;QAAUC,cAAc;QAAUC,cAAc;YAAC;SAAiB;IAAA;IAC7E;QAACF,UAAU;QAAUC,cAAc;QAAUC,cAAc,EAAE;IAAA;IAC7D;QAACF,UAAU;QAAUC,cAAc;QAAUC,cAAc;YAAC;SAAc;IAAA;IAC1E;QAACF,UAAU;QAASC,cAAc;QAASC,cAAc;YAAC;SAAiB;IAAA;IAC3E;QAACF,UAAU;QAAWC,cAAc;QAAWC,cAAc,EAAE;IAAA;CAChE;AAED,SAASC,wBAAwB,EAACC,QAAQ,EAA+B;IACvExB,mBAAmB;QACjByB,SAAS;QACTC,WAAWC,iBAAiBH;IAC9B;IAEA,MAAMI,cAAcd,QAClB,IAAM,IAAIX,YAAY;YAAC0B,gBAAgB;gBAACC,SAAS;oBAACC,OAAO;gBAAK;YAAC;QAAC,IAChE,EAAE;IAEJ,MAAMC,QAAQlB,QAAQ;QACpB,MAAMmB,YAAYtB;QAClBsB,UAAUC,GAAG,CAACjC,eAAe;YAC3BkC,QAAQ;YACRC,YAAY;gBAAC;oBAACC,IAAIrB;oBAAcsB,MAAM;oBAAQC,cAAc;gBAAc;aAAE;QAC9E;QACA,OAAON;IACT,GAAG,EAAE;IACL,MAAMO,SAAS1B,QAAQ;QACrB,MAAM2B,YAAYnC,gBAAgB;YAACoC,WAAWjC;QAAM;QACpD,MAAMkC,iBAAiBpC,YAAY;YACjCqC,gBAAgB,IAAMH;YACtBI,MAAM;YACNH,WAAWjC;QACb;QACA,MAAMqC,eAAevC,YAAY;YAC/BqC,gBAAgB,IAAMD;YACtBE,MAAM;YACNH,WAAW,kBACT,KAACK;oBAAIC,WAAU;8BACb,cAAA,KAACjC;wBAAmBkC,aAAajC;;;QAGvC;QACA,MAAMkC,cAAchC,YAAYiC,GAAG,CAAC,CAACN,OACnCtC,YAAY;gBACVqC,gBAAgB,IAAMD;gBACtBE,MAAMA,KAAKO,OAAO,CAAC,qBAAqB;gBACxCV,WAAW,kBAAM,KAACK;YACpB;QAGF,OAAOvC,aAAa;YAClB6C,SAAShD,oBAAoB;gBAACiD,gBAAgB;oBAACrC;iBAAe;YAAA;YAC9DsC,WAAWd,UAAUe,WAAW,CAAC;gBAC/Bb,eAAea,WAAW,CAAC;oBAACV;uBAAiBI;iBAAY;aAC1D;QACH;IACF,GAAG,EAAE;IAEL,qBACE,KAAC9C;QAAoBqD,QAAQ7B;kBAC3B,cAAA,MAACf;YAAcmB,OAAOA;;8BACpB,KAACtB;oBAAe8B,QAAQA;;8BACxB,KAACtC;;;;AAIT;AAEA,MAAMwD,OAAO;IACXC,OAAO;IACPjB,WAAWnB;IACXqC,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAACtC,UAAU;IAAO;AAC1B;AAEA,eAAekC,KAAK;AAGpB,OAAO,MAAMK,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,mBAA0B;IACrCF,MAAM;QAACtC,UAAU;IAAmB;AACtC,EAAE;AAEF,OAAO,MAAMyC,UAAiB;IAC5BH,MAAM;QAACtC,UAAU;IAAS;AAC5B,EAAE;AAEF,OAAO,MAAM0C,mBAA0B;IACrCJ,MAAM;QAACtC,UAAU;IAAmB;AACtC,EAAE;AAEF,OAAO,MAAM2C,iBAAwB;IACnCL,MAAM;QAACtC,UAAU;IAAiB;AACpC,EAAE;AAEF,OAAO,MAAM4C,uBAA8B;IACzCN,MAAM;QAACtC,UAAU;IAAc;AACjC,EAAE;AAEF,OAAO,MAAM6C,YAAmB;IAC9BP,MAAM;QAACtC,UAAU;IAAY;AAC/B,EAAE;AAEF,SAASG,iBAAiBH,QAAkB;IAC1C,OAAO,CAAC8C,OAAOC;QACb,MAAMC,MAAMC,WAAWH;QACvB,MAAMI,SAASH,MAAMG,UAAU;QAC/B,IAAIlD,aAAa,WAAW,OAAO,IAAImD,QAAkB,IAAMC;QAC/D,IAAIJ,IAAIK,QAAQ,KAAK,0BAA0B;YAC7C,IAAIrD,aAAa,mBAAmB,OAAOmD,QAAQG,OAAO,CAACC;YAC3D,OAAOJ,QAAQG,OAAO,CACpBE,aAAa;gBAACC,WAAWzD,aAAa,iBAAiB,EAAE,GAAGL;YAAS;QAEzE;QACA,IAAIqD,IAAIK,QAAQ,CAACK,UAAU,CAAC,gCAAgCR,WAAW,SAAS;YAC9E,OAAOC,QAAQG,OAAO,CACpBE,aAAa;gBACX,GAAGG,YAAY;gBACf9C,IAAImC,IAAIK,QAAQ,CAACO,KAAK,CAAC,KAAKC,EAAE,CAAC,CAAC;gBAChCC,kBAAkB;YACpB;QAEJ;QACA,IAAId,IAAIK,QAAQ,CAACK,UAAU,CAAC,gCAAgCR,WAAW,UAAU;YAC/E,OAAOC,QAAQG,OAAO,CAACE,aAAaJ,WAAW;gBAACzC,QAAQ;YAAG;QAC7D;QACA,IAAIqC,IAAIK,QAAQ,CAACK,UAAU,CAAC,yCAAyCR,WAAW,SAAS;YACvF,OAAOC,QAAQG,OAAO,CACpBE,aAAa;gBACX3C,IAAImC,IAAIK,QAAQ,CAACO,KAAK,CAAC,KAAKC,EAAE,CAAC,CAAC;gBAChCE,cAAcvE;gBACdsB,MAAM;gBACNkD,MAAM;gBACNF,kBAAkB;gBAClBG,aAAa;gBACbC,YAAY;gBACZC,YAAY;YACd;QAEJ;QACA,IAAInB,IAAIK,QAAQ,CAACK,UAAU,CAAC,yCAAyCR,WAAW,UAAU;YACxF,OAAOC,QAAQG,OAAO,CAACE,aAAaJ,WAAW;gBAACzC,QAAQ;YAAG;QAC7D;QACA,IAAIqC,IAAIK,QAAQ,KAAK,4BAA4B;YAC/C,IAAIrD,aAAa,qBAAqB,OAAOmD,QAAQG,OAAO,CAACC;YAC7D,OAAOJ,QAAQG,OAAO,CAACE,aAAa;gBAACY,aAAaC,uBAAuBrE;YAAS;QACpF;QACA,IAAIgD,IAAIK,QAAQ,KAAK,qCAAqC;YACxD,OAAOF,QAAQG,OAAO,CACpBE,aAAa;gBACXY,aAAa;oBACX;wBACEvD,IAAI;wBACJkD,cAAcvE;wBACdsB,MAAM;wBACNkD,MAAM;wBACNF,kBAAkB;wBAClBG,aAAa;wBACbC,YAAY;wBACZC,YAAY;oBACd;iBACD;YACH;QAEJ;QACA,OAAOhB,QAAQG,OAAO,CAACE,aAAa,CAAC,GAAG;YAAC7C,QAAQ;QAAG;IACtD;AACF;AAEA,SAAS0D,uBAAuBrE,QAAkB;IAChD,IAAIA,aAAa,uBAAuBA,aAAa,gBAAgB,OAAO,EAAE;IAC9E,IAAIA,aAAa,cAAc;QAC7B,OAAO;YACL2D,WAAW;gBACT9D,cAAc;gBACdiE,kBAAkB;YACpB;YACAH,WAAW;gBACT9C,IAAI;gBACJjB,UAAU;gBACVC,cAAc;gBACdiE,kBAAkB;YACpB;SACD;IACH;IACA,OAAO;QACLH,WAAW;YAAC9D,cAAc;YAAaiE,kBAAkB;QAAQ;QACjEH,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACVC,cAAc;YACdiE,kBAAkB;YAClBQ,cAAc;QAChB;QACAX,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACVC,cAAc;YACdiE,kBAAkB;YAClBQ,cAAclB;QAChB;QACAO,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACVC,cAAc;YACdiE,kBAAkB;YAClBQ,cAAclB;QAChB;QACAO,WAAW;YACT9C,IAAI;YACJjB,UAAU;YACV2E,qBAAqB;YACrBP,MAAM;YACNnE,cAAc;YACdC,cAAc,EAAE;YAChBgE,kBAAkB;YAClBQ,cAAclB;YACdc,YAAY;YACZC,YAAY;QACd;KACD;AACH;AAEA,SAASR,WAAWa,YAA+C,CAAC,CAAC;IACnE,OAAO;QACL3D,IAAI;QACJkD,cAAcvE;QACdI,UAAU;QACV2E,qBAAqB;QACrBP,MAAM;QACNnE,cAAc;QACdiE,kBAAkB;QAClBhE,cAAc;YAAC;SAAiB;QAChCwE,cAAc;QACdJ,YAAY;QACZC,YAAY;QACZ,GAAGK,SAAS;IACd;AACF;AAEA,SAASvB,WAAWH,KAAwB;IAC1C,IAAI,OAAOA,UAAU,UAAU,OAAO,IAAI2B,IAAI3B;IAC9C,IAAIA,iBAAiB2B,KAAK,OAAO3B;IACjC,OAAO,IAAI2B,IAAI3B,MAAME,GAAG;AAC1B;AAEA,SAASQ,aAAakB,IAAa,EAAE3B,OAAqB,CAAC,CAAC;IAC1D,OAAO,IAAI4B,SAASC,KAAKC,SAAS,CAACH,OAAO;QACxC/D,QAAQ;QACRmE,SAAS;YAAC,gBAAgB;QAAkB;QAC5C,GAAG/B,IAAI;IACT;AACF;AAEA,SAASQ;IACP,OAAOC,aAAa;QAACuB,MAAM;IAAc,GAAG;QAACpE,QAAQ;QAAKqE,YAAY;IAAc;AACtF"}
@@ -0,0 +1,4 @@
1
+ import type { IntegrationConnectionDto } from '@shipfox/api-integration-core-dto';
2
+ import type { IntegrationUsageEvent } from './integration-usage-modal.js';
3
+ export declare function usageEventsForConnection(connection: IntegrationConnectionDto): IntegrationUsageEvent[];
4
+ //# sourceMappingURL=integration-usage-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-usage-events.d.ts","sourceRoot":"","sources":["../../src/components/integration-usage-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,wBAAwB,EAAoB,MAAM,mCAAmC,CAAC;AAInG,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,8BAA8B,CAAC;AAgFxE,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,wBAAwB,GACnC,qBAAqB,EAAE,CAyBzB"}
@@ -0,0 +1,127 @@
1
+ import { SENTRY_ISSUE_ACTIONS } from '@shipfox/api-integration-core-dto';
2
+ import { linearWebhookEventNames } from '@shipfox/api-integration-linear-dto';
3
+ import { WEBHOOK_RECEIVED_EVENT } from '@shipfox/api-integration-webhook-dto';
4
+ const GITHUB_EVENTS = [
5
+ 'push',
6
+ 'branch_protection_configuration',
7
+ 'branch_protection_rule',
8
+ 'check_run',
9
+ 'check_suite',
10
+ 'code_scanning_alert',
11
+ 'commit_comment',
12
+ 'create',
13
+ 'custom_property',
14
+ 'custom_property_values',
15
+ 'delete',
16
+ 'dependabot_alert',
17
+ 'deploy_key',
18
+ 'deployment',
19
+ 'deployment_protection_rule',
20
+ 'deployment_review',
21
+ 'deployment_status',
22
+ 'discussion',
23
+ 'discussion_comment',
24
+ 'fork',
25
+ 'github_app_authorization',
26
+ 'gollum',
27
+ 'installation',
28
+ 'installation_repositories',
29
+ 'installation_target',
30
+ 'issue_comment',
31
+ 'issue_dependencies',
32
+ 'issues',
33
+ 'label',
34
+ 'marketplace_purchase',
35
+ 'member',
36
+ 'membership',
37
+ 'merge_group',
38
+ 'meta',
39
+ 'milestone',
40
+ 'org_block',
41
+ 'organization',
42
+ 'package',
43
+ 'page_build',
44
+ 'personal_access_token_request',
45
+ 'ping',
46
+ 'project',
47
+ 'project_card',
48
+ 'project_column',
49
+ 'projects_v2',
50
+ 'projects_v2_item',
51
+ 'projects_v2_status_update',
52
+ 'public',
53
+ 'pull_request',
54
+ 'pull_request_review',
55
+ 'pull_request_review_comment',
56
+ 'pull_request_review_thread',
57
+ 'registry_package',
58
+ 'release',
59
+ 'repository',
60
+ 'repository_advisory',
61
+ 'repository_dispatch',
62
+ 'repository_import',
63
+ 'repository_ruleset',
64
+ 'repository_vulnerability_alert',
65
+ 'secret_scanning_alert',
66
+ 'secret_scanning_alert_location',
67
+ 'secret_scanning_scan',
68
+ 'security_advisory',
69
+ 'security_and_analysis',
70
+ 'sponsorship',
71
+ 'star',
72
+ 'status',
73
+ 'sub_issues',
74
+ 'team',
75
+ 'team_add',
76
+ 'watch',
77
+ 'workflow_dispatch',
78
+ 'workflow_job',
79
+ 'workflow_run'
80
+ ];
81
+ export function usageEventsForConnection(connection) {
82
+ if (connection.provider === 'webhook') {
83
+ return [
84
+ {
85
+ value: WEBHOOK_RECEIVED_EVENT,
86
+ label: WEBHOOK_RECEIVED_EVENT
87
+ }
88
+ ];
89
+ }
90
+ if (connection.provider === 'github') {
91
+ return GITHUB_EVENTS.map((event)=>({
92
+ value: event,
93
+ label: event
94
+ }));
95
+ }
96
+ if (connection.provider === 'sentry') {
97
+ return SENTRY_ISSUE_ACTIONS.map((action)=>({
98
+ value: `issue.${action}`,
99
+ label: sentryIssueEventLabel(action)
100
+ }));
101
+ }
102
+ if (connection.provider === 'linear') {
103
+ return linearWebhookEventNames.map((event)=>({
104
+ value: event,
105
+ label: event
106
+ }));
107
+ }
108
+ if (connection.capabilities.includes('source_control')) {
109
+ return [
110
+ {
111
+ value: 'push',
112
+ label: 'push'
113
+ }
114
+ ];
115
+ }
116
+ return [
117
+ {
118
+ value: 'received',
119
+ label: 'received'
120
+ }
121
+ ];
122
+ }
123
+ function sentryIssueEventLabel(action) {
124
+ return `issue.${action}`;
125
+ }
126
+
127
+ //# sourceMappingURL=integration-usage-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/integration-usage-events.ts"],"sourcesContent":["import type {IntegrationConnectionDto, SentryIssueAction} from '@shipfox/api-integration-core-dto';\nimport {SENTRY_ISSUE_ACTIONS} from '@shipfox/api-integration-core-dto';\nimport {linearWebhookEventNames} from '@shipfox/api-integration-linear-dto';\nimport {WEBHOOK_RECEIVED_EVENT} from '@shipfox/api-integration-webhook-dto';\nimport type {IntegrationUsageEvent} from './integration-usage-modal.js';\n\nconst GITHUB_EVENTS = [\n 'push',\n 'branch_protection_configuration',\n 'branch_protection_rule',\n 'check_run',\n 'check_suite',\n 'code_scanning_alert',\n 'commit_comment',\n 'create',\n 'custom_property',\n 'custom_property_values',\n 'delete',\n 'dependabot_alert',\n 'deploy_key',\n 'deployment',\n 'deployment_protection_rule',\n 'deployment_review',\n 'deployment_status',\n 'discussion',\n 'discussion_comment',\n 'fork',\n 'github_app_authorization',\n 'gollum',\n 'installation',\n 'installation_repositories',\n 'installation_target',\n 'issue_comment',\n 'issue_dependencies',\n 'issues',\n 'label',\n 'marketplace_purchase',\n 'member',\n 'membership',\n 'merge_group',\n 'meta',\n 'milestone',\n 'org_block',\n 'organization',\n 'package',\n 'page_build',\n 'personal_access_token_request',\n 'ping',\n 'project',\n 'project_card',\n 'project_column',\n 'projects_v2',\n 'projects_v2_item',\n 'projects_v2_status_update',\n 'public',\n 'pull_request',\n 'pull_request_review',\n 'pull_request_review_comment',\n 'pull_request_review_thread',\n 'registry_package',\n 'release',\n 'repository',\n 'repository_advisory',\n 'repository_dispatch',\n 'repository_import',\n 'repository_ruleset',\n 'repository_vulnerability_alert',\n 'secret_scanning_alert',\n 'secret_scanning_alert_location',\n 'secret_scanning_scan',\n 'security_advisory',\n 'security_and_analysis',\n 'sponsorship',\n 'star',\n 'status',\n 'sub_issues',\n 'team',\n 'team_add',\n 'watch',\n 'workflow_dispatch',\n 'workflow_job',\n 'workflow_run',\n] as const;\n\nexport function usageEventsForConnection(\n connection: IntegrationConnectionDto,\n): IntegrationUsageEvent[] {\n if (connection.provider === 'webhook') {\n return [{value: WEBHOOK_RECEIVED_EVENT, label: WEBHOOK_RECEIVED_EVENT}];\n }\n\n if (connection.provider === 'github') {\n return GITHUB_EVENTS.map((event) => ({value: event, label: event}));\n }\n\n if (connection.provider === 'sentry') {\n return SENTRY_ISSUE_ACTIONS.map((action) => ({\n value: `issue.${action}`,\n label: sentryIssueEventLabel(action),\n }));\n }\n\n if (connection.provider === 'linear') {\n return linearWebhookEventNames.map((event) => ({value: event, label: event}));\n }\n\n if (connection.capabilities.includes('source_control')) {\n return [{value: 'push', label: 'push'}];\n }\n\n return [{value: 'received', label: 'received'}];\n}\n\nfunction sentryIssueEventLabel(action: SentryIssueAction): string {\n return `issue.${action}`;\n}\n"],"names":["SENTRY_ISSUE_ACTIONS","linearWebhookEventNames","WEBHOOK_RECEIVED_EVENT","GITHUB_EVENTS","usageEventsForConnection","connection","provider","value","label","map","event","action","sentryIssueEventLabel","capabilities","includes"],"mappings":"AACA,SAAQA,oBAAoB,QAAO,oCAAoC;AACvE,SAAQC,uBAAuB,QAAO,sCAAsC;AAC5E,SAAQC,sBAAsB,QAAO,uCAAuC;AAG5E,MAAMC,gBAAgB;IACpB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAED,OAAO,SAASC,yBACdC,UAAoC;IAEpC,IAAIA,WAAWC,QAAQ,KAAK,WAAW;QACrC,OAAO;YAAC;gBAACC,OAAOL;gBAAwBM,OAAON;YAAsB;SAAE;IACzE;IAEA,IAAIG,WAAWC,QAAQ,KAAK,UAAU;QACpC,OAAOH,cAAcM,GAAG,CAAC,CAACC,QAAW,CAAA;gBAACH,OAAOG;gBAAOF,OAAOE;YAAK,CAAA;IAClE;IAEA,IAAIL,WAAWC,QAAQ,KAAK,UAAU;QACpC,OAAON,qBAAqBS,GAAG,CAAC,CAACE,SAAY,CAAA;gBAC3CJ,OAAO,CAAC,MAAM,EAAEI,QAAQ;gBACxBH,OAAOI,sBAAsBD;YAC/B,CAAA;IACF;IAEA,IAAIN,WAAWC,QAAQ,KAAK,UAAU;QACpC,OAAOL,wBAAwBQ,GAAG,CAAC,CAACC,QAAW,CAAA;gBAACH,OAAOG;gBAAOF,OAAOE;YAAK,CAAA;IAC5E;IAEA,IAAIL,WAAWQ,YAAY,CAACC,QAAQ,CAAC,mBAAmB;QACtD,OAAO;YAAC;gBAACP,OAAO;gBAAQC,OAAO;YAAM;SAAE;IACzC;IAEA,OAAO;QAAC;YAACD,OAAO;YAAYC,OAAO;QAAU;KAAE;AACjD;AAEA,SAASI,sBAAsBD,MAAyB;IACtD,OAAO,CAAC,MAAM,EAAEA,QAAQ;AAC1B"}
@@ -0,0 +1,16 @@
1
+ import type { IntegrationConnectionDto } from '@shipfox/api-integration-core-dto';
2
+ import type { ReactNode } from 'react';
3
+ export interface IntegrationUsageEvent {
4
+ value: string;
5
+ label: string;
6
+ }
7
+ interface IntegrationUsageModalProps {
8
+ connection: IntegrationConnectionDto | null;
9
+ events: IntegrationUsageEvent[];
10
+ open: boolean;
11
+ onOpenChange: (open: boolean) => void;
12
+ children?: ReactNode;
13
+ }
14
+ export declare function IntegrationUsageModal({ connection, events, open, onOpenChange, children, }: IntegrationUsageModalProps): import("react").JSX.Element;
15
+ export {};
16
+ //# sourceMappingURL=integration-usage-modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-usage-modal.d.ts","sourceRoot":"","sources":["../../src/components/integration-usage-modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,mCAAmC,CAAC;AA4BhF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAIrC,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,0BAA0B;IAClC,UAAU,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC5C,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAID,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,QAAQ,GACT,EAAE,0BAA0B,+BA+G5B"}