@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.
- package/.storybook/main.ts +1 -0
- package/.storybook/preview.css +4 -0
- package/.storybook/preview.tsx +56 -0
- package/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +207 -0
- package/LICENSE +21 -0
- package/dist/components/connection-picker.d.ts +7 -0
- package/dist/components/connection-picker.d.ts.map +1 -0
- package/dist/components/connection-picker.js +98 -0
- package/dist/components/connection-picker.js.map +1 -0
- package/dist/components/installed-integrations-section.d.ts +14 -0
- package/dist/components/installed-integrations-section.d.ts.map +1 -0
- package/dist/components/installed-integrations-section.js +203 -0
- package/dist/components/installed-integrations-section.js.map +1 -0
- package/dist/components/integration-delete-confirm-modal.d.ts +10 -0
- package/dist/components/integration-delete-confirm-modal.d.ts.map +1 -0
- package/dist/components/integration-delete-confirm-modal.js +61 -0
- package/dist/components/integration-delete-confirm-modal.js.map +1 -0
- package/dist/components/integration-gallery-for-workspace.d.ts +9 -0
- package/dist/components/integration-gallery-for-workspace.d.ts.map +1 -0
- package/dist/components/integration-gallery-for-workspace.js +169 -0
- package/dist/components/integration-gallery-for-workspace.js.map +1 -0
- package/dist/components/integration-gallery.d.ts +8 -0
- package/dist/components/integration-gallery.d.ts.map +1 -0
- package/dist/components/integration-gallery.js +26 -0
- package/dist/components/integration-gallery.js.map +1 -0
- package/dist/components/integration-gallery.stories.d.ts +26 -0
- package/dist/components/integration-gallery.stories.d.ts.map +1 -0
- package/dist/components/integration-gallery.stories.js +335 -0
- package/dist/components/integration-gallery.stories.js.map +1 -0
- package/dist/components/integration-usage-events.d.ts +4 -0
- package/dist/components/integration-usage-events.d.ts.map +1 -0
- package/dist/components/integration-usage-events.js +127 -0
- package/dist/components/integration-usage-events.js.map +1 -0
- package/dist/components/integration-usage-modal.d.ts +16 -0
- package/dist/components/integration-usage-modal.d.ts.map +1 -0
- package/dist/components/integration-usage-modal.js +184 -0
- package/dist/components/integration-usage-modal.js.map +1 -0
- package/dist/components/provider-grid.d.ts +14 -0
- package/dist/components/provider-grid.d.ts.map +1 -0
- package/dist/components/provider-grid.js +152 -0
- package/dist/components/provider-grid.js.map +1 -0
- package/dist/components/redirect-install-page.d.ts +19 -0
- package/dist/components/redirect-install-page.d.ts.map +1 -0
- package/dist/components/redirect-install-page.js +68 -0
- package/dist/components/redirect-install-page.js.map +1 -0
- package/dist/components/repository-picker.d.ts +15 -0
- package/dist/components/repository-picker.d.ts.map +1 -0
- package/dist/components/repository-picker.js +78 -0
- package/dist/components/repository-picker.js.map +1 -0
- package/dist/components/webhook/copyable-value.d.ts +10 -0
- package/dist/components/webhook/copyable-value.d.ts.map +1 -0
- package/dist/components/webhook/copyable-value.js +65 -0
- package/dist/components/webhook/copyable-value.js.map +1 -0
- package/dist/components/webhook/webhook-create-modal.d.ts +10 -0
- package/dist/components/webhook/webhook-create-modal.d.ts.map +1 -0
- package/dist/components/webhook/webhook-create-modal.js +233 -0
- package/dist/components/webhook/webhook-create-modal.js.map +1 -0
- package/dist/components/webhook/webhook-form-errors.d.ts +11 -0
- package/dist/components/webhook/webhook-form-errors.d.ts.map +1 -0
- package/dist/components/webhook/webhook-form-errors.js +27 -0
- package/dist/components/webhook/webhook-form-errors.js.map +1 -0
- package/dist/components/webhook/webhook-modals.stories.d.ts +25 -0
- package/dist/components/webhook/webhook-modals.stories.d.ts.map +1 -0
- package/dist/components/webhook/webhook-modals.stories.js +222 -0
- package/dist/components/webhook/webhook-modals.stories.js.map +1 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.d.ts +2 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.d.ts.map +1 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.js +20 -0
- package/dist/components/webhook/webhook-public-endpoint-alert.js.map +1 -0
- package/dist/components/webhook/webhook-usage-details.d.ts +7 -0
- package/dist/components/webhook/webhook-usage-details.d.ts.map +1 -0
- package/dist/components/webhook/webhook-usage-details.js +49 -0
- package/dist/components/webhook/webhook-usage-details.js.map +1 -0
- package/dist/connection-status-badge.d.ts +12 -0
- package/dist/connection-status-badge.d.ts.map +1 -0
- package/dist/connection-status-badge.js +34 -0
- package/dist/connection-status-badge.js.map +1 -0
- package/dist/feature.d.ts +37 -0
- package/dist/feature.d.ts.map +1 -0
- package/dist/feature.js +48 -0
- package/dist/feature.js.map +1 -0
- package/dist/hooks/api/integrations.d.ts +265 -0
- package/dist/hooks/api/integrations.d.ts.map +1 -0
- package/dist/hooks/api/integrations.js +229 -0
- package/dist/hooks/api/integrations.js.map +1 -0
- package/dist/hooks/api/webhook-connections.d.ts +91 -0
- package/dist/hooks/api/webhook-connections.d.ts.map +1 -0
- package/dist/hooks/api/webhook-connections.js +97 -0
- package/dist/hooks/api/webhook-connections.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/integration-icon.d.ts +17 -0
- package/dist/integration-icon.d.ts.map +1 -0
- package/dist/integration-icon.js +22 -0
- package/dist/integration-icon.js.map +1 -0
- package/dist/linear-callback.d.ts +17 -0
- package/dist/linear-callback.d.ts.map +1 -0
- package/dist/linear-callback.js +113 -0
- package/dist/linear-callback.js.map +1 -0
- package/dist/pages/gitea-form-errors.d.ts +11 -0
- package/dist/pages/gitea-form-errors.d.ts.map +1 -0
- package/dist/pages/gitea-form-errors.js +35 -0
- package/dist/pages/gitea-form-errors.js.map +1 -0
- package/dist/pages/gitea-install-page.d.ts +2 -0
- package/dist/pages/gitea-install-page.d.ts.map +1 -0
- package/dist/pages/gitea-install-page.js +139 -0
- package/dist/pages/gitea-install-page.js.map +1 -0
- package/dist/pages/github-install-page.d.ts +2 -0
- package/dist/pages/github-install-page.d.ts.map +1 -0
- package/dist/pages/github-install-page.js +11 -0
- package/dist/pages/github-install-page.js.map +1 -0
- package/dist/pages/linear-callback-page.d.ts +2 -0
- package/dist/pages/linear-callback-page.d.ts.map +1 -0
- package/dist/pages/linear-callback-page.js +192 -0
- package/dist/pages/linear-callback-page.js.map +1 -0
- package/dist/pages/linear-install-page.d.ts +2 -0
- package/dist/pages/linear-install-page.d.ts.map +1 -0
- package/dist/pages/linear-install-page.js +24 -0
- package/dist/pages/linear-install-page.js.map +1 -0
- package/dist/pages/sentry-callback-page.d.ts +2 -0
- package/dist/pages/sentry-callback-page.d.ts.map +1 -0
- package/dist/pages/sentry-callback-page.js +256 -0
- package/dist/pages/sentry-callback-page.js.map +1 -0
- package/dist/pages/sentry-install-page.d.ts +2 -0
- package/dist/pages/sentry-install-page.d.ts.map +1 -0
- package/dist/pages/sentry-install-page.js +17 -0
- package/dist/pages/sentry-install-page.js.map +1 -0
- package/dist/pages/source-control-onboarding-page.d.ts +2 -0
- package/dist/pages/source-control-onboarding-page.d.ts.map +1 -0
- package/dist/pages/source-control-onboarding-page.js +37 -0
- package/dist/pages/source-control-onboarding-page.js.map +1 -0
- package/dist/provider-catalog.d.ts +15 -0
- package/dist/provider-catalog.d.ts.map +1 -0
- package/dist/provider-catalog.js +28 -0
- package/dist/provider-catalog.js.map +1 -0
- package/dist/routes/gitea.d.ts +6 -0
- package/dist/routes/gitea.d.ts.map +1 -0
- package/dist/routes/gitea.js +7 -0
- package/dist/routes/gitea.js.map +1 -0
- package/dist/routes/github-callback.d.ts +6 -0
- package/dist/routes/github-callback.d.ts.map +1 -0
- package/dist/routes/github-callback.js +129 -0
- package/dist/routes/github-callback.js.map +1 -0
- package/dist/routes/github.d.ts +6 -0
- package/dist/routes/github.d.ts.map +1 -0
- package/dist/routes/github.js +7 -0
- package/dist/routes/github.js.map +1 -0
- package/dist/routes/integrations.d.ts +6 -0
- package/dist/routes/integrations.d.ts.map +1 -0
- package/dist/routes/integrations.js +7 -0
- package/dist/routes/integrations.js.map +1 -0
- package/dist/routes/linear-callback.d.ts +6 -0
- package/dist/routes/linear-callback.d.ts.map +1 -0
- package/dist/routes/linear-callback.js +7 -0
- package/dist/routes/linear-callback.js.map +1 -0
- package/dist/routes/linear.d.ts +6 -0
- package/dist/routes/linear.d.ts.map +1 -0
- package/dist/routes/linear.js +7 -0
- package/dist/routes/linear.js.map +1 -0
- package/dist/routes/sentry-callback.d.ts +6 -0
- package/dist/routes/sentry-callback.d.ts.map +1 -0
- package/dist/routes/sentry-callback.js +7 -0
- package/dist/routes/sentry-callback.js.map +1 -0
- package/dist/routes/sentry.d.ts +6 -0
- package/dist/routes/sentry.d.ts.map +1 -0
- package/dist/routes/sentry.js +7 -0
- package/dist/routes/sentry.js.map +1 -0
- package/dist/sentry-callback.d.ts +35 -0
- package/dist/sentry-callback.d.ts.map +1 -0
- package/dist/sentry-callback.js +132 -0
- package/dist/sentry-callback.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/package.json +120 -0
- package/src/components/connection-picker.tsx +89 -0
- package/src/components/installed-integrations-section.tsx +198 -0
- package/src/components/integration-delete-confirm-modal.tsx +62 -0
- package/src/components/integration-gallery-for-workspace.tsx +193 -0
- package/src/components/integration-gallery.stories.tsx +302 -0
- package/src/components/integration-gallery.test.tsx +692 -0
- package/src/components/integration-gallery.tsx +49 -0
- package/src/components/integration-usage-events.test.ts +80 -0
- package/src/components/integration-usage-events.ts +116 -0
- package/src/components/integration-usage-modal.tsx +178 -0
- package/src/components/provider-grid.tsx +163 -0
- package/src/components/redirect-install-page.test.tsx +98 -0
- package/src/components/redirect-install-page.tsx +68 -0
- package/src/components/repository-picker.tsx +102 -0
- package/src/components/webhook/copyable-value.test.tsx +41 -0
- package/src/components/webhook/copyable-value.tsx +72 -0
- package/src/components/webhook/webhook-create-modal.tsx +247 -0
- package/src/components/webhook/webhook-form-errors.test.ts +45 -0
- package/src/components/webhook/webhook-form-errors.ts +32 -0
- package/src/components/webhook/webhook-modals.stories.tsx +225 -0
- package/src/components/webhook/webhook-public-endpoint-alert.tsx +15 -0
- package/src/components/webhook/webhook-usage-details.tsx +44 -0
- package/src/connection-status-badge.tsx +38 -0
- package/src/feature.ts +47 -0
- package/src/hooks/api/integrations.test.ts +105 -0
- package/src/hooks/api/integrations.ts +287 -0
- package/src/hooks/api/webhook-connections.ts +115 -0
- package/src/index.ts +16 -0
- package/src/integration-icon.react.test.tsx +40 -0
- package/src/integration-icon.test.ts +19 -0
- package/src/integration-icon.tsx +26 -0
- package/src/linear-callback.test.ts +227 -0
- package/src/linear-callback.ts +136 -0
- package/src/pages/gitea-form-errors.test.ts +55 -0
- package/src/pages/gitea-form-errors.ts +36 -0
- package/src/pages/gitea-install-page.tsx +108 -0
- package/src/pages/github-install-page.tsx +11 -0
- package/src/pages/linear-callback-page.test.tsx +157 -0
- package/src/pages/linear-callback-page.tsx +175 -0
- package/src/pages/linear-install-page.tsx +26 -0
- package/src/pages/sentry-callback-page.test.tsx +205 -0
- package/src/pages/sentry-callback-page.tsx +238 -0
- package/src/pages/sentry-install-page.tsx +17 -0
- package/src/pages/source-control-onboarding-page.test.tsx +46 -0
- package/src/pages/source-control-onboarding-page.tsx +26 -0
- package/src/provider-catalog.test.ts +42 -0
- package/src/provider-catalog.ts +49 -0
- package/src/routes/gitea.tsx +4 -0
- package/src/routes/github-callback.tsx +114 -0
- package/src/routes/github.tsx +4 -0
- package/src/routes/integrations.tsx +4 -0
- package/src/routes/linear-callback.tsx +4 -0
- package/src/routes/linear.tsx +4 -0
- package/src/routes/sentry-callback.tsx +4 -0
- package/src/routes/sentry.tsx +4 -0
- package/src/sentry-callback.test.ts +239 -0
- package/src/sentry-callback.ts +142 -0
- package/test/render.tsx +111 -0
- package/test/setup.ts +3 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vercel.json +8 -0
- package/vitest.config.ts +75 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copyable-value.d.ts","sourceRoot":"","sources":["../../../src/components/webhook/copyable-value.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAGrC,UAAU,kBAAkB;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAC,EAAE,kBAAkB,+BAwDhF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
3
|
+
import { useCopyToClipboard } from '@shipfox/react-ui/hooks';
|
|
4
|
+
import { toast } from '@shipfox/react-ui/toast';
|
|
5
|
+
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
6
|
+
import { cn } from '@shipfox/react-ui/utils';
|
|
7
|
+
import { useEffect, useRef, useState } from 'react';
|
|
8
|
+
export function CopyableValue({ label, value, note, className }) {
|
|
9
|
+
const [copied, setCopied] = useState(false);
|
|
10
|
+
const timeoutRef = useRef(undefined);
|
|
11
|
+
const { copy } = useCopyToClipboard({
|
|
12
|
+
text: value,
|
|
13
|
+
onCopy: ()=>{
|
|
14
|
+
setCopied(true);
|
|
15
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
16
|
+
timeoutRef.current = setTimeout(()=>setCopied(false), 2000);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
useEffect(()=>{
|
|
20
|
+
return ()=>{
|
|
21
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
22
|
+
};
|
|
23
|
+
}, []);
|
|
24
|
+
async function handleCopy() {
|
|
25
|
+
try {
|
|
26
|
+
await copy();
|
|
27
|
+
} catch {
|
|
28
|
+
toast.error('Could not copy.');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
32
|
+
className: cn('flex w-full min-w-0 flex-col gap-8', className),
|
|
33
|
+
children: [
|
|
34
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
35
|
+
className: "flex min-w-0 items-center gap-8",
|
|
36
|
+
children: [
|
|
37
|
+
/*#__PURE__*/ _jsx(Code, {
|
|
38
|
+
as: "span",
|
|
39
|
+
variant: "paragraph",
|
|
40
|
+
className: "min-w-0 flex-1 break-all rounded-4 border border-border-neutral-base bg-background-components-base px-8 py-6 text-foreground-neutral-base",
|
|
41
|
+
children: value
|
|
42
|
+
}),
|
|
43
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
44
|
+
type: "button",
|
|
45
|
+
variant: "secondary",
|
|
46
|
+
size: "sm",
|
|
47
|
+
iconLeft: copied ? 'check' : 'copy',
|
|
48
|
+
"aria-label": `Copy ${label}`,
|
|
49
|
+
onClick: ()=>{
|
|
50
|
+
void handleCopy();
|
|
51
|
+
},
|
|
52
|
+
children: "Copy"
|
|
53
|
+
})
|
|
54
|
+
]
|
|
55
|
+
}),
|
|
56
|
+
note ? /*#__PURE__*/ _jsx(Text, {
|
|
57
|
+
size: "sm",
|
|
58
|
+
className: "text-foreground-neutral-muted",
|
|
59
|
+
children: note
|
|
60
|
+
}) : null
|
|
61
|
+
]
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=copyable-value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/webhook/copyable-value.tsx"],"sourcesContent":["import {Button} from '@shipfox/react-ui/button';\nimport {useCopyToClipboard} from '@shipfox/react-ui/hooks';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport type {ReactNode} from 'react';\nimport {useEffect, useRef, useState} from 'react';\n\ninterface CopyableValueProps {\n label: string;\n value: string;\n note?: ReactNode;\n className?: string;\n}\n\nexport function CopyableValue({label, value, note, className}: CopyableValueProps) {\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const {copy} = useCopyToClipboard({\n text: value,\n onCopy: () => {\n setCopied(true);\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => setCopied(false), 2000);\n },\n });\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n async function handleCopy() {\n try {\n await copy();\n } catch {\n toast.error('Could not copy.');\n }\n }\n\n return (\n <div className={cn('flex w-full min-w-0 flex-col gap-8', className)}>\n <div className=\"flex min-w-0 items-center gap-8\">\n <Code\n as=\"span\"\n variant=\"paragraph\"\n className=\"min-w-0 flex-1 break-all rounded-4 border border-border-neutral-base bg-background-components-base px-8 py-6 text-foreground-neutral-base\"\n >\n {value}\n </Code>\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"sm\"\n iconLeft={copied ? 'check' : 'copy'}\n aria-label={`Copy ${label}`}\n onClick={() => {\n void handleCopy();\n }}\n >\n Copy\n </Button>\n </div>\n {note ? (\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {note}\n </Text>\n ) : null}\n </div>\n );\n}\n"],"names":["Button","useCopyToClipboard","toast","Code","Text","cn","useEffect","useRef","useState","CopyableValue","label","value","note","className","copied","setCopied","timeoutRef","undefined","copy","text","onCopy","current","clearTimeout","setTimeout","handleCopy","error","div","as","variant","type","size","iconLeft","aria-label","onClick"],"mappings":";AAAA,SAAQA,MAAM,QAAO,2BAA2B;AAChD,SAAQC,kBAAkB,QAAO,0BAA0B;AAC3D,SAAQC,KAAK,QAAO,0BAA0B;AAC9C,SAAQC,IAAI,EAAEC,IAAI,QAAO,+BAA+B;AACxD,SAAQC,EAAE,QAAO,0BAA0B;AAE3C,SAAQC,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAO,QAAQ;AASlD,OAAO,SAASC,cAAc,EAACC,KAAK,EAAEC,KAAK,EAAEC,IAAI,EAAEC,SAAS,EAAqB;IAC/E,MAAM,CAACC,QAAQC,UAAU,GAAGP,SAAS;IACrC,MAAMQ,aAAaT,OAAkDU;IACrE,MAAM,EAACC,IAAI,EAAC,GAAGjB,mBAAmB;QAChCkB,MAAMR;QACNS,QAAQ;YACNL,UAAU;YACV,IAAIC,WAAWK,OAAO,EAAEC,aAAaN,WAAWK,OAAO;YACvDL,WAAWK,OAAO,GAAGE,WAAW,IAAMR,UAAU,QAAQ;QAC1D;IACF;IAEAT,UAAU;QACR,OAAO;YACL,IAAIU,WAAWK,OAAO,EAAEC,aAAaN,WAAWK,OAAO;QACzD;IACF,GAAG,EAAE;IAEL,eAAeG;QACb,IAAI;YACF,MAAMN;QACR,EAAE,OAAM;YACNhB,MAAMuB,KAAK,CAAC;QACd;IACF;IAEA,qBACE,MAACC;QAAIb,WAAWR,GAAG,sCAAsCQ;;0BACvD,MAACa;gBAAIb,WAAU;;kCACb,KAACV;wBACCwB,IAAG;wBACHC,SAAQ;wBACRf,WAAU;kCAETF;;kCAEH,KAACX;wBACC6B,MAAK;wBACLD,SAAQ;wBACRE,MAAK;wBACLC,UAAUjB,SAAS,UAAU;wBAC7BkB,cAAY,CAAC,KAAK,EAAEtB,OAAO;wBAC3BuB,SAAS;4BACP,KAAKT;wBACP;kCACD;;;;YAIFZ,qBACC,KAACR;gBAAK0B,MAAK;gBAAKjB,WAAU;0BACvBD;iBAED;;;AAGV"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IntegrationConnectionDto } from '@shipfox/api-integration-core-dto';
|
|
2
|
+
interface WebhookCreateModalProps {
|
|
3
|
+
workspaceId: string;
|
|
4
|
+
open: boolean;
|
|
5
|
+
onOpenChange: (open: boolean) => void;
|
|
6
|
+
onCreated: (connection: IntegrationConnectionDto) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function WebhookCreateModal({ workspaceId, open, onOpenChange, onCreated, }: WebhookCreateModalProps): import("react").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=webhook-create-modal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-create-modal.d.ts","sourceRoot":"","sources":["../../../src/components/webhook/webhook-create-modal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,mCAAmC,CAAC;AA0BhF,UAAU,uBAAuB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,UAAU,EAAE,wBAAwB,KAAK,IAAI,CAAC;CAC3D;AAED,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,SAAS,GACV,EAAE,uBAAuB,+BAmKzB"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createWebhookConnectionBodySchema, WEBHOOK_RESERVED_SLUGS, webhookSlugSchema } from '@shipfox/api-integration-webhook-dto';
|
|
3
|
+
import { displayNameFieldError } from '@shipfox/client-ui';
|
|
4
|
+
import { Button } from '@shipfox/react-ui/button';
|
|
5
|
+
import { Callout } from '@shipfox/react-ui/callout';
|
|
6
|
+
import { FormField, FormFieldInput, fieldError } from '@shipfox/react-ui/form-field';
|
|
7
|
+
import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, ModalTitle } from '@shipfox/react-ui/modal';
|
|
8
|
+
import { toast } from '@shipfox/react-ui/toast';
|
|
9
|
+
import { Code, Text } from '@shipfox/react-ui/typography';
|
|
10
|
+
import { useForm } from '@tanstack/react-form';
|
|
11
|
+
import { useEffect, useRef, useState } from 'react';
|
|
12
|
+
import { useCreateWebhookConnectionMutation } from '#hooks/api/webhook-connections.js';
|
|
13
|
+
import { webhookCreateErrorToFormError } from './webhook-form-errors.js';
|
|
14
|
+
export function WebhookCreateModal({ workspaceId, open, onOpenChange, onCreated }) {
|
|
15
|
+
const createWebhook = useCreateWebhookConnectionMutation();
|
|
16
|
+
const [formError, setFormError] = useState();
|
|
17
|
+
const [hasManualSlug, setHasManualSlug] = useState(false);
|
|
18
|
+
const nameInputRef = useRef(null);
|
|
19
|
+
const form = useForm({
|
|
20
|
+
defaultValues: {
|
|
21
|
+
name: '',
|
|
22
|
+
slug: ''
|
|
23
|
+
},
|
|
24
|
+
onSubmit: async ({ value })=>{
|
|
25
|
+
setFormError(undefined);
|
|
26
|
+
try {
|
|
27
|
+
const body = createWebhookConnectionBodySchema.parse({
|
|
28
|
+
workspace_id: workspaceId,
|
|
29
|
+
name: value.name.trim(),
|
|
30
|
+
slug: value.slug.trim()
|
|
31
|
+
});
|
|
32
|
+
const connection = await createWebhook.mutateAsync(body);
|
|
33
|
+
onCreated(toIntegrationConnection(connection));
|
|
34
|
+
toast.success('Webhook created.');
|
|
35
|
+
onOpenChange(false);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
const mapped = webhookCreateErrorToFormError(error);
|
|
38
|
+
if (mapped.kind === 'field') {
|
|
39
|
+
form.setFieldMeta(mapped.field, (prev)=>({
|
|
40
|
+
...prev,
|
|
41
|
+
errorMap: {
|
|
42
|
+
...prev.errorMap,
|
|
43
|
+
onServer: mapped.message
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
} else {
|
|
47
|
+
setFormError(mapped.message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
useEffect(()=>{
|
|
53
|
+
if (!open) {
|
|
54
|
+
setFormError(undefined);
|
|
55
|
+
setHasManualSlug(false);
|
|
56
|
+
form.reset();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
requestAnimationFrame(()=>nameInputRef.current?.focus());
|
|
60
|
+
}, [
|
|
61
|
+
form,
|
|
62
|
+
open
|
|
63
|
+
]);
|
|
64
|
+
const handleOpenChange = (nextOpen)=>{
|
|
65
|
+
if (createWebhook.isPending && !nextOpen) return;
|
|
66
|
+
onOpenChange(nextOpen);
|
|
67
|
+
};
|
|
68
|
+
return /*#__PURE__*/ _jsx(Modal, {
|
|
69
|
+
open: open,
|
|
70
|
+
onOpenChange: handleOpenChange,
|
|
71
|
+
children: /*#__PURE__*/ _jsxs(ModalContent, {
|
|
72
|
+
"aria-describedby": undefined,
|
|
73
|
+
children: [
|
|
74
|
+
/*#__PURE__*/ _jsx(ModalTitle, {
|
|
75
|
+
className: "sr-only",
|
|
76
|
+
children: "Add webhook"
|
|
77
|
+
}),
|
|
78
|
+
/*#__PURE__*/ _jsx(ModalHeader, {
|
|
79
|
+
title: "Add webhook",
|
|
80
|
+
showClose: !createWebhook.isPending
|
|
81
|
+
}),
|
|
82
|
+
/*#__PURE__*/ _jsxs("form", {
|
|
83
|
+
noValidate: true,
|
|
84
|
+
onSubmit: (event)=>{
|
|
85
|
+
event.preventDefault();
|
|
86
|
+
event.stopPropagation();
|
|
87
|
+
void form.handleSubmit();
|
|
88
|
+
},
|
|
89
|
+
children: [
|
|
90
|
+
/*#__PURE__*/ _jsxs(ModalBody, {
|
|
91
|
+
className: "gap-16",
|
|
92
|
+
children: [
|
|
93
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
94
|
+
size: "sm",
|
|
95
|
+
className: "text-foreground-neutral-muted",
|
|
96
|
+
children: "Create a named inbound webhook URL for this workspace."
|
|
97
|
+
}),
|
|
98
|
+
formError ? /*#__PURE__*/ _jsx(Callout, {
|
|
99
|
+
role: "alert",
|
|
100
|
+
type: "error",
|
|
101
|
+
children: formError
|
|
102
|
+
}) : null,
|
|
103
|
+
/*#__PURE__*/ _jsx(form.Field, {
|
|
104
|
+
name: "name",
|
|
105
|
+
validators: {
|
|
106
|
+
onBlur: ({ value })=>webhookNameFieldError(value),
|
|
107
|
+
onSubmit: ({ value })=>webhookNameFieldError(value)
|
|
108
|
+
},
|
|
109
|
+
children: (field)=>/*#__PURE__*/ _jsx(FormField, {
|
|
110
|
+
label: "Name",
|
|
111
|
+
id: "webhook-name",
|
|
112
|
+
error: fieldError(field),
|
|
113
|
+
className: "w-full",
|
|
114
|
+
children: /*#__PURE__*/ _jsx(FormFieldInput, {
|
|
115
|
+
ref: nameInputRef,
|
|
116
|
+
name: "name",
|
|
117
|
+
value: field.state.value,
|
|
118
|
+
onChange: (event)=>{
|
|
119
|
+
const nextName = event.target.value;
|
|
120
|
+
field.handleChange(nextName);
|
|
121
|
+
if (!hasManualSlug) {
|
|
122
|
+
form.setFieldValue('slug', nextName.trim() ? suggestWebhookSlug(nextName) : '');
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
onBlur: field.handleBlur,
|
|
126
|
+
placeholder: "Stripe production",
|
|
127
|
+
disabled: createWebhook.isPending
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
}),
|
|
131
|
+
/*#__PURE__*/ _jsx(form.Field, {
|
|
132
|
+
name: "slug",
|
|
133
|
+
validators: {
|
|
134
|
+
onBlur: ({ value })=>webhookSlugFieldError(value),
|
|
135
|
+
onSubmit: ({ value })=>webhookSlugFieldError(value)
|
|
136
|
+
},
|
|
137
|
+
children: (field)=>/*#__PURE__*/ _jsxs(FormField, {
|
|
138
|
+
label: "Slug",
|
|
139
|
+
id: "webhook-slug",
|
|
140
|
+
error: fieldError(field),
|
|
141
|
+
className: "w-full",
|
|
142
|
+
children: [
|
|
143
|
+
/*#__PURE__*/ _jsx(FormFieldInput, {
|
|
144
|
+
name: "slug",
|
|
145
|
+
value: field.state.value,
|
|
146
|
+
onChange: (event)=>{
|
|
147
|
+
const nextSlug = event.target.value;
|
|
148
|
+
setHasManualSlug(nextSlug.trim().length > 0);
|
|
149
|
+
field.handleChange(nextSlug);
|
|
150
|
+
if (nextSlug.trim().length === 0 && form.state.values.name.trim()) {
|
|
151
|
+
form.setFieldValue('slug', suggestWebhookSlug(form.state.values.name));
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
onBlur: field.handleBlur,
|
|
155
|
+
placeholder: "webhook-stripe-production",
|
|
156
|
+
disabled: createWebhook.isPending
|
|
157
|
+
}),
|
|
158
|
+
/*#__PURE__*/ _jsxs(Text, {
|
|
159
|
+
size: "sm",
|
|
160
|
+
className: "text-foreground-neutral-muted",
|
|
161
|
+
children: [
|
|
162
|
+
"Reference in workflows with",
|
|
163
|
+
' ',
|
|
164
|
+
/*#__PURE__*/ _jsxs(Code, {
|
|
165
|
+
as: "span",
|
|
166
|
+
children: [
|
|
167
|
+
"source: ",
|
|
168
|
+
field.state.value || 'webhook-stripe-production'
|
|
169
|
+
]
|
|
170
|
+
}),
|
|
171
|
+
"."
|
|
172
|
+
]
|
|
173
|
+
})
|
|
174
|
+
]
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
}),
|
|
179
|
+
/*#__PURE__*/ _jsxs(ModalFooter, {
|
|
180
|
+
children: [
|
|
181
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
182
|
+
type: "button",
|
|
183
|
+
variant: "secondary",
|
|
184
|
+
disabled: createWebhook.isPending,
|
|
185
|
+
onClick: ()=>onOpenChange(false),
|
|
186
|
+
children: "Cancel"
|
|
187
|
+
}),
|
|
188
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
189
|
+
type: "submit",
|
|
190
|
+
isLoading: createWebhook.isPending,
|
|
191
|
+
children: "Create"
|
|
192
|
+
})
|
|
193
|
+
]
|
|
194
|
+
})
|
|
195
|
+
]
|
|
196
|
+
})
|
|
197
|
+
]
|
|
198
|
+
})
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function webhookNameFieldError(value) {
|
|
202
|
+
return displayNameFieldError(value.trim(), 'Webhook name', createWebhookConnectionBodySchema.shape.name);
|
|
203
|
+
}
|
|
204
|
+
function webhookSlugFieldError(value) {
|
|
205
|
+
const trimmed = value.trim();
|
|
206
|
+
if (trimmed.length === 0) return 'Slug is required.';
|
|
207
|
+
if (WEBHOOK_RESERVED_SLUGS.includes(trimmed)) {
|
|
208
|
+
return 'That slug is reserved.';
|
|
209
|
+
}
|
|
210
|
+
if (webhookSlugSchema.safeParse(trimmed).success) return undefined;
|
|
211
|
+
return 'Use lowercase letters, numbers, hyphens, or underscores.';
|
|
212
|
+
}
|
|
213
|
+
function suggestWebhookSlug(name) {
|
|
214
|
+
const prefix = 'webhook';
|
|
215
|
+
const suffix = name.toLowerCase().replaceAll(/[^a-z0-9]+/g, '-').replaceAll(/^-+|-+$/g, '').slice(0, 100 - prefix.length - 1).replaceAll(/-+$/g, '');
|
|
216
|
+
return suffix ? `${prefix}-${suffix}` : prefix;
|
|
217
|
+
}
|
|
218
|
+
function toIntegrationConnection(connection) {
|
|
219
|
+
return {
|
|
220
|
+
id: connection.id,
|
|
221
|
+
workspace_id: connection.workspace_id,
|
|
222
|
+
provider: 'webhook',
|
|
223
|
+
external_account_id: connection.slug,
|
|
224
|
+
slug: connection.slug,
|
|
225
|
+
display_name: connection.name,
|
|
226
|
+
lifecycle_status: connection.lifecycle_status,
|
|
227
|
+
capabilities: [],
|
|
228
|
+
created_at: connection.created_at,
|
|
229
|
+
updated_at: connection.updated_at
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
//# sourceMappingURL=webhook-create-modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/webhook/webhook-create-modal.tsx"],"sourcesContent":["import type {IntegrationConnectionDto} from '@shipfox/api-integration-core-dto';\nimport {\n createWebhookConnectionBodySchema,\n WEBHOOK_RESERVED_SLUGS,\n type WebhookConnectionDto,\n webhookSlugSchema,\n} from '@shipfox/api-integration-webhook-dto';\nimport {displayNameFieldError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {FormField, FormFieldInput, fieldError} from '@shipfox/react-ui/form-field';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalTitle,\n} from '@shipfox/react-ui/modal';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Code, Text} from '@shipfox/react-ui/typography';\nimport {useForm} from '@tanstack/react-form';\nimport {useEffect, useRef, useState} from 'react';\nimport {useCreateWebhookConnectionMutation} from '#hooks/api/webhook-connections.js';\nimport {webhookCreateErrorToFormError} from './webhook-form-errors.js';\n\ninterface WebhookCreateModalProps {\n workspaceId: string;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onCreated: (connection: IntegrationConnectionDto) => void;\n}\n\nexport function WebhookCreateModal({\n workspaceId,\n open,\n onOpenChange,\n onCreated,\n}: WebhookCreateModalProps) {\n const createWebhook = useCreateWebhookConnectionMutation();\n const [formError, setFormError] = useState<string | undefined>();\n const [hasManualSlug, setHasManualSlug] = useState(false);\n const nameInputRef = useRef<HTMLInputElement | null>(null);\n\n const form = useForm({\n defaultValues: {name: '', slug: ''},\n onSubmit: async ({value}) => {\n setFormError(undefined);\n try {\n const body = createWebhookConnectionBodySchema.parse({\n workspace_id: workspaceId,\n name: value.name.trim(),\n slug: value.slug.trim(),\n });\n const connection = await createWebhook.mutateAsync(body);\n onCreated(toIntegrationConnection(connection));\n toast.success('Webhook created.');\n onOpenChange(false);\n } catch (error) {\n const mapped = webhookCreateErrorToFormError(error);\n if (mapped.kind === 'field') {\n form.setFieldMeta(mapped.field, (prev) => ({\n ...prev,\n errorMap: {...prev.errorMap, onServer: mapped.message},\n }));\n } else {\n setFormError(mapped.message);\n }\n }\n },\n });\n\n useEffect(() => {\n if (!open) {\n setFormError(undefined);\n setHasManualSlug(false);\n form.reset();\n return;\n }\n requestAnimationFrame(() => nameInputRef.current?.focus());\n }, [form, open]);\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (createWebhook.isPending && !nextOpen) return;\n onOpenChange(nextOpen);\n };\n\n return (\n <Modal open={open} onOpenChange={handleOpenChange}>\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">Add webhook</ModalTitle>\n <ModalHeader title=\"Add webhook\" showClose={!createWebhook.isPending} />\n <form\n noValidate\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n void form.handleSubmit();\n }}\n >\n <ModalBody className=\"gap-16\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Create a named inbound webhook URL for this workspace.\n </Text>\n {formError ? (\n <Callout role=\"alert\" type=\"error\">\n {formError}\n </Callout>\n ) : null}\n <form.Field\n name=\"name\"\n validators={{\n onBlur: ({value}) => webhookNameFieldError(value),\n onSubmit: ({value}) => webhookNameFieldError(value),\n }}\n >\n {(field) => (\n <FormField\n label=\"Name\"\n id=\"webhook-name\"\n error={fieldError(field)}\n className=\"w-full\"\n >\n <FormFieldInput\n ref={nameInputRef}\n name=\"name\"\n value={field.state.value}\n onChange={(event) => {\n const nextName = event.target.value;\n field.handleChange(nextName);\n if (!hasManualSlug) {\n form.setFieldValue(\n 'slug',\n nextName.trim() ? suggestWebhookSlug(nextName) : '',\n );\n }\n }}\n onBlur={field.handleBlur}\n placeholder=\"Stripe production\"\n disabled={createWebhook.isPending}\n />\n </FormField>\n )}\n </form.Field>\n <form.Field\n name=\"slug\"\n validators={{\n onBlur: ({value}) => webhookSlugFieldError(value),\n onSubmit: ({value}) => webhookSlugFieldError(value),\n }}\n >\n {(field) => (\n <FormField\n label=\"Slug\"\n id=\"webhook-slug\"\n error={fieldError(field)}\n className=\"w-full\"\n >\n <FormFieldInput\n name=\"slug\"\n value={field.state.value}\n onChange={(event) => {\n const nextSlug = event.target.value;\n setHasManualSlug(nextSlug.trim().length > 0);\n field.handleChange(nextSlug);\n if (nextSlug.trim().length === 0 && form.state.values.name.trim()) {\n form.setFieldValue('slug', suggestWebhookSlug(form.state.values.name));\n }\n }}\n onBlur={field.handleBlur}\n placeholder=\"webhook-stripe-production\"\n disabled={createWebhook.isPending}\n />\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Reference in workflows with{' '}\n <Code as=\"span\">\n source: {field.state.value || 'webhook-stripe-production'}\n </Code>\n .\n </Text>\n </FormField>\n )}\n </form.Field>\n </ModalBody>\n <ModalFooter>\n <Button\n type=\"button\"\n variant=\"secondary\"\n disabled={createWebhook.isPending}\n onClick={() => onOpenChange(false)}\n >\n Cancel\n </Button>\n <Button type=\"submit\" isLoading={createWebhook.isPending}>\n Create\n </Button>\n </ModalFooter>\n </form>\n </ModalContent>\n </Modal>\n );\n}\n\nfunction webhookNameFieldError(value: string): string | undefined {\n return displayNameFieldError(\n value.trim(),\n 'Webhook name',\n createWebhookConnectionBodySchema.shape.name,\n );\n}\n\nfunction webhookSlugFieldError(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length === 0) return 'Slug is required.';\n if (WEBHOOK_RESERVED_SLUGS.includes(trimmed as (typeof WEBHOOK_RESERVED_SLUGS)[number])) {\n return 'That slug is reserved.';\n }\n if (webhookSlugSchema.safeParse(trimmed).success) return undefined;\n return 'Use lowercase letters, numbers, hyphens, or underscores.';\n}\n\nfunction suggestWebhookSlug(name: string): string {\n const prefix = 'webhook';\n const suffix = name\n .toLowerCase()\n .replaceAll(/[^a-z0-9]+/g, '-')\n .replaceAll(/^-+|-+$/g, '')\n .slice(0, 100 - prefix.length - 1)\n .replaceAll(/-+$/g, '');\n\n return suffix ? `${prefix}-${suffix}` : prefix;\n}\n\nfunction toIntegrationConnection(connection: WebhookConnectionDto): IntegrationConnectionDto {\n return {\n id: connection.id,\n workspace_id: connection.workspace_id,\n provider: 'webhook',\n external_account_id: connection.slug,\n slug: connection.slug,\n display_name: connection.name,\n lifecycle_status: connection.lifecycle_status,\n capabilities: [],\n created_at: connection.created_at,\n updated_at: connection.updated_at,\n };\n}\n"],"names":["createWebhookConnectionBodySchema","WEBHOOK_RESERVED_SLUGS","webhookSlugSchema","displayNameFieldError","Button","Callout","FormField","FormFieldInput","fieldError","Modal","ModalBody","ModalContent","ModalFooter","ModalHeader","ModalTitle","toast","Code","Text","useForm","useEffect","useRef","useState","useCreateWebhookConnectionMutation","webhookCreateErrorToFormError","WebhookCreateModal","workspaceId","open","onOpenChange","onCreated","createWebhook","formError","setFormError","hasManualSlug","setHasManualSlug","nameInputRef","form","defaultValues","name","slug","onSubmit","value","undefined","body","parse","workspace_id","trim","connection","mutateAsync","toIntegrationConnection","success","error","mapped","kind","setFieldMeta","field","prev","errorMap","onServer","message","reset","requestAnimationFrame","current","focus","handleOpenChange","nextOpen","isPending","aria-describedby","className","title","showClose","noValidate","event","preventDefault","stopPropagation","handleSubmit","size","role","type","Field","validators","onBlur","webhookNameFieldError","label","id","ref","state","onChange","nextName","target","handleChange","setFieldValue","suggestWebhookSlug","handleBlur","placeholder","disabled","webhookSlugFieldError","nextSlug","length","values","as","variant","onClick","isLoading","shape","trimmed","includes","safeParse","prefix","suffix","toLowerCase","replaceAll","slice","provider","external_account_id","display_name","lifecycle_status","capabilities","created_at","updated_at"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type WebhookCreateField = 'slug';
|
|
2
|
+
export type WebhookCreateFormErrorMapping = {
|
|
3
|
+
kind: 'field';
|
|
4
|
+
field: WebhookCreateField;
|
|
5
|
+
message: string;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'form';
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function webhookCreateErrorToFormError(error: unknown): WebhookCreateFormErrorMapping;
|
|
11
|
+
//# sourceMappingURL=webhook-form-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-form-errors.d.ts","sourceRoot":"","sources":["../../../src/components/webhook/webhook-form-errors.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAExC,MAAM,MAAM,6BAA6B,GACrC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,GAC3D;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAEpC,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,6BAA6B,CAY3F"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ApiError } from '@shipfox/client-api';
|
|
2
|
+
export function webhookCreateErrorToFormError(error) {
|
|
3
|
+
const code = error instanceof ApiError ? error.code : undefined;
|
|
4
|
+
if (code === 'slug-already-exists') {
|
|
5
|
+
return {
|
|
6
|
+
kind: 'field',
|
|
7
|
+
field: 'slug',
|
|
8
|
+
message: 'A webhook with this slug already exists.'
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
kind: 'form',
|
|
13
|
+
message: webhookCreateErrorMessage(error)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function webhookCreateErrorMessage(error) {
|
|
17
|
+
if (error instanceof ApiError) {
|
|
18
|
+
if (error.code === 'network-error') {
|
|
19
|
+
return "We couldn't reach the server. Check your connection and try again.";
|
|
20
|
+
}
|
|
21
|
+
return error.message;
|
|
22
|
+
}
|
|
23
|
+
if (error instanceof Error) return error.message;
|
|
24
|
+
return 'Something went wrong. Try again.';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=webhook-form-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/webhook/webhook-form-errors.ts"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\n\nexport type WebhookCreateField = 'slug';\n\nexport type WebhookCreateFormErrorMapping =\n | {kind: 'field'; field: WebhookCreateField; message: string}\n | {kind: 'form'; message: string};\n\nexport function webhookCreateErrorToFormError(error: unknown): WebhookCreateFormErrorMapping {\n const code = error instanceof ApiError ? error.code : undefined;\n\n if (code === 'slug-already-exists') {\n return {\n kind: 'field',\n field: 'slug',\n message: 'A webhook with this slug already exists.',\n };\n }\n\n return {kind: 'form', message: webhookCreateErrorMessage(error)};\n}\n\nfunction webhookCreateErrorMessage(error: unknown): string {\n if (error instanceof ApiError) {\n if (error.code === 'network-error') {\n return \"We couldn't reach the server. Check your connection and try again.\";\n }\n return error.message;\n }\n if (error instanceof Error) return error.message;\n return 'Something went wrong. Try again.';\n}\n"],"names":["ApiError","webhookCreateErrorToFormError","error","code","undefined","kind","field","message","webhookCreateErrorMessage","Error"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAsB;AAQ7C,OAAO,SAASC,8BAA8BC,KAAc;IAC1D,MAAMC,OAAOD,iBAAiBF,WAAWE,MAAMC,IAAI,GAAGC;IAEtD,IAAID,SAAS,uBAAuB;QAClC,OAAO;YACLE,MAAM;YACNC,OAAO;YACPC,SAAS;QACX;IACF;IAEA,OAAO;QAACF,MAAM;QAAQE,SAASC,0BAA0BN;IAAM;AACjE;AAEA,SAASM,0BAA0BN,KAAc;IAC/C,IAAIA,iBAAiBF,UAAU;QAC7B,IAAIE,MAAMC,IAAI,KAAK,iBAAiB;YAClC,OAAO;QACT;QACA,OAAOD,MAAMK,OAAO;IACtB;IACA,IAAIL,iBAAiBO,OAAO,OAAOP,MAAMK,OAAO;IAChD,OAAO;AACT"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react';
|
|
2
|
+
type Scenario = 'create-form' | 'create-success' | 'usage-active' | 'usage-disabled' | 'delete-confirm' | 'copyable-value';
|
|
3
|
+
interface WebhookModalStoryProps {
|
|
4
|
+
scenario: Scenario;
|
|
5
|
+
}
|
|
6
|
+
declare function WebhookModalStory({ scenario }: WebhookModalStoryProps): import("react").JSX.Element;
|
|
7
|
+
declare const meta: {
|
|
8
|
+
title: string;
|
|
9
|
+
component: typeof WebhookModalStory;
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: string;
|
|
12
|
+
};
|
|
13
|
+
args: {
|
|
14
|
+
scenario: "create-form";
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export default meta;
|
|
18
|
+
type Story = StoryObj<typeof meta>;
|
|
19
|
+
export declare const Playground: Story;
|
|
20
|
+
export declare const CreateSuccess: Story;
|
|
21
|
+
export declare const UsageActive: Story;
|
|
22
|
+
export declare const UsageDisabled: Story;
|
|
23
|
+
export declare const DeleteConfirm: Story;
|
|
24
|
+
export declare const CopyableValueState: Story;
|
|
25
|
+
//# sourceMappingURL=webhook-modals.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-modals.stories.d.ts","sourceRoot":"","sources":["../../../src/components/webhook/webhook-modals.stories.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAqBrD,KAAK,QAAQ,GACT,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAoCD,iBAAS,iBAAiB,CAAC,EAAC,QAAQ,EAAC,EAAE,sBAAsB,+BAoB5D;AAED,QAAA,MAAM,IAAI;;;;;;;;;CAKgC,CAAC;AAE3C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAEhC,CAAC"}
|