@open-mercato/webhooks 0.6.5-develop.4534.1.b459babe6d → 0.6.5-develop.4544.1.71c003c861

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/webhooks/backend/webhooks/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useParams, usePathname, useRouter } from 'next/navigation'\nimport { RotateCw } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { LoadingMessage, ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport {\n buildWebhookFormContentHeader,\n buildWebhookFormFields,\n buildWebhookFormGroups,\n createWebhookInitialValues,\n normalizeWebhookFormPayload,\n type WebhookFormValues,\n} from '../../../components/webhook-form-config'\nimport { useWebhookFeatureAccess } from '../useWebhookFeatureAccess'\nimport { WebhookSecretPanel } from '../../../components/WebhookSecretPanel'\n\ntype Webhook = {\n id: string\n name: string\n description: string | null\n url: string\n subscribedEvents: string[]\n httpMethod: 'POST' | 'PUT' | 'PATCH'\n isActive: boolean\n maxRetries: number\n timeoutMs: number\n rateLimitPerMinute: number\n autoDisableThreshold: number\n consecutiveFailures: number\n lastSuccessAt: string | null\n lastFailureAt: string | null\n customHeaders: Record<string, string> | null\n createdAt: string\n updatedAt: string\n maskedSecret: string\n previousSecretSetAt: string | null\n}\n\ntype DeliveryRow = {\n id: string\n webhookId: string\n eventType: string\n messageId: string\n status: string\n responseStatus: number | null\n errorMessage: string | null\n attemptNumber: number\n maxAttempts: number\n durationMs: number | null\n targetUrl: string\n enqueuedAt: string\n lastAttemptAt: string | null\n deliveredAt: string | null\n createdAt: string\n}\n\ntype DeliveryResponse = {\n items: DeliveryRow[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n}\n\ntype DeliveryDetail = DeliveryRow & {\n payload: Record<string, unknown>\n responseBody: string | null\n responseHeaders: Record<string, string> | null\n nextRetryAt: string | null\n updatedAt: string\n}\n\nconst statusVariantMap: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n delivered: 'default',\n pending: 'secondary',\n sending: 'outline',\n failed: 'destructive',\n expired: 'destructive',\n}\nconst DELIVERY_AUTO_REFRESH_INTERVAL_MS = 30000\n\nexport default function WebhookDetailPage() {\n const params = useParams()\n const pathname = usePathname()\n const router = useRouter()\n const t = useT()\n const webhookId = React.useMemo(() => resolveWebhookId(params?.id, pathname), [params?.id, pathname])\n\n const [webhook, setWebhook] = React.useState<Webhook | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [isEditing, setIsEditing] = React.useState(false)\n\n const [deliveries, setDeliveries] = React.useState<DeliveryRow[]>([])\n const [deliveryPage, setDeliveryPage] = React.useState(1)\n const [deliveryTotal, setDeliveryTotal] = React.useState(0)\n const [deliveryTotalPages, setDeliveryTotalPages] = React.useState(1)\n const [deliveriesLoading, setDeliveriesLoading] = React.useState(false)\n const [isRefreshingDeliveries, setIsRefreshingDeliveries] = React.useState(false)\n const [testDelivery, setTestDelivery] = React.useState<DeliveryDetail | null>(null)\n const [selectedDelivery, setSelectedDelivery] = React.useState<DeliveryDetail | null>(null)\n const [selectedDeliveryLoading, setSelectedDeliveryLoading] = React.useState(false)\n const [revealedSecret, setRevealedSecret] = React.useState<string | null>(null)\n const refreshInFlightRef = React.useRef(false)\n const access = useWebhookFeatureAccess()\n\n const fetchWebhook = React.useCallback(async (options?: { silent?: boolean }) => {\n if (!webhookId) {\n setIsNotFound(true)\n setIsLoading(false)\n return\n }\n\n const silent = options?.silent === true\n if (!silent) {\n setIsLoading(true)\n }\n\n setError(null)\n setIsNotFound(false)\n\n try {\n const call = await apiCall<Webhook>(\n `/api/webhooks/${encodeURIComponent(webhookId)}`,\n undefined,\n { fallback: null },\n )\n\n if (call.ok && call.result) {\n setWebhook(call.result)\n return\n }\n\n if (call.status === 404) {\n setIsNotFound(true)\n } else {\n setError(t('webhooks.detail.loadError'))\n }\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError.message : t('webhooks.detail.loadError'))\n } finally {\n if (!silent) {\n setIsLoading(false)\n }\n }\n }, [t, webhookId])\n\n const fetchDeliveries = React.useCallback(async (options?: { silent?: boolean }) => {\n if (!webhookId) return\n\n const silent = options?.silent === true\n if (!silent) {\n setDeliveriesLoading(true)\n }\n\n try {\n const params = new URLSearchParams()\n params.set('webhookId', webhookId)\n params.set('page', String(deliveryPage))\n params.set('pageSize', '20')\n\n const fallback: DeliveryResponse = { items: [], total: 0, page: deliveryPage, pageSize: 20, totalPages: 1 }\n const call = await apiCall<DeliveryResponse>(\n `/api/webhooks/deliveries?${params.toString()}`,\n undefined,\n { fallback },\n )\n\n if (call.ok && call.result) {\n setDeliveries(call.result.items)\n setDeliveryTotal(call.result.total)\n setDeliveryTotalPages(call.result.totalPages)\n }\n } finally {\n if (!silent) {\n setDeliveriesLoading(false)\n }\n }\n }, [deliveryPage, webhookId])\n\n const fetchDeliveryDetail = React.useCallback(async (deliveryId: string): Promise<DeliveryDetail | null> => {\n const call = await apiCall<DeliveryDetail>(\n `/api/webhooks/deliveries/${encodeURIComponent(deliveryId)}`,\n undefined,\n { fallback: null },\n )\n\n if (!call.ok || !call.result) {\n return null\n }\n\n return call.result\n }, [])\n\n const refreshDeliveryState = React.useCallback(async () => {\n if (!webhookId || refreshInFlightRef.current) return\n\n refreshInFlightRef.current = true\n setIsRefreshingDeliveries(true)\n\n try {\n await Promise.all([\n fetchWebhook({ silent: true }),\n fetchDeliveries({ silent: true }),\n ])\n\n const detailIds = [selectedDelivery?.id, testDelivery?.id].filter(\n (value): value is string => typeof value === 'string' && value.length > 0,\n )\n\n if (detailIds.length > 0) {\n const details = await Promise.all(detailIds.map((deliveryId) => fetchDeliveryDetail(deliveryId)))\n const detailMap = new Map<string, DeliveryDetail>()\n\n for (const detail of details) {\n if (detail) {\n detailMap.set(detail.id, detail)\n }\n }\n\n if (selectedDelivery?.id) {\n setSelectedDelivery((current) => current?.id ? (detailMap.get(current.id) ?? current) : current)\n }\n\n if (testDelivery?.id) {\n setTestDelivery((current) => current?.id ? (detailMap.get(current.id) ?? current) : current)\n }\n }\n } finally {\n refreshInFlightRef.current = false\n setIsRefreshingDeliveries(false)\n }\n }, [fetchDeliveries, fetchDeliveryDetail, fetchWebhook, selectedDelivery?.id, testDelivery?.id, webhookId])\n\n React.useEffect(() => {\n void fetchWebhook()\n }, [fetchWebhook])\n\n React.useEffect(() => {\n if (!webhookId) return\n void fetchDeliveries()\n }, [fetchDeliveries, webhookId])\n\n useAppEvent('webhooks.delivery.*', (event) => {\n const eventWebhookId = typeof event.payload?.webhookId === 'string' ? event.payload.webhookId : null\n if (eventWebhookId !== webhookId) return\n void refreshDeliveryState()\n }, [refreshDeliveryState, webhookId])\n\n React.useEffect(() => {\n if (!webhookId || isEditing) return\n\n const intervalId = window.setInterval(() => {\n if (document.visibilityState !== 'visible') return\n void refreshDeliveryState()\n }, DELIVERY_AUTO_REFRESH_INTERVAL_MS)\n\n return () => {\n window.clearInterval(intervalId)\n }\n }, [isEditing, refreshDeliveryState, webhookId])\n\n const handleToggleActive = React.useCallback(async () => {\n if (!webhook) return\n try {\n const call = await apiCall<Webhook>(\n `/api/webhooks/${encodeURIComponent(webhook.id)}`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ isActive: !webhook.isActive }),\n },\n { fallback: null },\n )\n if (call.ok) {\n setWebhook((prev) => prev ? { ...prev, isActive: !prev.isActive } : prev)\n flash(t('webhooks.form.updateSuccess'), 'success')\n void refreshDeliveryState()\n }\n } catch {\n flash(t('webhooks.form.updateError'), 'error')\n }\n }, [refreshDeliveryState, webhook, t])\n\n const handleRotateSecret = React.useCallback(async () => {\n if (!webhook) return\n try {\n const call = await apiCall<{ secret: string }>(\n `/api/webhooks/${encodeURIComponent(webhook.id)}/rotate-secret`,\n { method: 'POST' },\n { fallback: null },\n )\n if (!call.ok || !call.result) {\n flash(t('webhooks.detail.rotateError'), 'error')\n return\n }\n setRevealedSecret(call.result.secret)\n flash(t('webhooks.detail.rotateSuccess'), 'success')\n void refreshDeliveryState()\n } catch {\n flash(t('webhooks.detail.rotateError'), 'error')\n }\n }, [refreshDeliveryState, t, webhook])\n\n const handleTest = React.useCallback(async () => {\n if (!webhook) return\n try {\n const call = await apiCall<{ delivery: DeliveryDetail }>(\n `/api/webhooks/${encodeURIComponent(webhook.id)}/test`,\n { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({}) },\n { fallback: null },\n )\n if (!call.ok || !call.result) {\n flash(t('webhooks.detail.testError'), 'error')\n return\n }\n const deliveryStatus = call.result.delivery.status\n setTestDelivery(call.result.delivery)\n flash(\n deliveryStatus === 'delivered' ? t('webhooks.detail.testSuccess') : t('webhooks.detail.testQueued'),\n deliveryStatus === 'delivered' ? 'success' : 'error',\n )\n void refreshDeliveryState()\n } catch {\n flash(t('webhooks.detail.testError'), 'error')\n }\n }, [refreshDeliveryState, t, webhook])\n\n const handleRetryDelivery = React.useCallback(async (deliveryId: string) => {\n try {\n const call = await apiCall(\n `/api/webhooks/deliveries/${encodeURIComponent(deliveryId)}/retry`,\n { method: 'POST' },\n { fallback: null },\n )\n if (!call.ok) {\n flash(t('webhooks.deliveries.retryError'), 'error')\n return\n }\n flash(t('webhooks.deliveries.retrySuccess'), 'success')\n void refreshDeliveryState()\n } catch {\n flash(t('webhooks.deliveries.retryError'), 'error')\n }\n }, [refreshDeliveryState, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!webhook) return\n try {\n await deleteCrud(`webhooks/${encodeURIComponent(webhook.id)}`, { fallbackResult: null })\n flash(t('webhooks.list.deleteSuccess'), 'success')\n router.push('/backend/webhooks')\n } catch {\n flash(t('webhooks.list.deleteError'), 'error')\n }\n }, [router, t, webhook])\n\n const handleDeliveryOpen = React.useCallback(async (deliveryId: string) => {\n setSelectedDeliveryLoading(true)\n try {\n const detail = await fetchDeliveryDetail(deliveryId)\n if (!detail) {\n flash(t('webhooks.deliveries.loadError'), 'error')\n return\n }\n setSelectedDelivery(detail)\n } catch {\n flash(t('webhooks.deliveries.loadError'), 'error')\n } finally {\n setSelectedDeliveryLoading(false)\n }\n }, [fetchDeliveryDetail, t])\n\n const deliveryColumns = React.useMemo<ColumnDef<DeliveryRow>[]>(() => [\n { accessorKey: 'eventType', header: t('webhooks.deliveries.columns.event') },\n {\n accessorKey: 'status',\n header: t('webhooks.deliveries.columns.status'),\n cell: ({ row }) => (\n <Badge variant={statusVariantMap[row.original.status] ?? 'secondary'}>\n {t(`webhooks.deliveries.status.${row.original.status}` as Parameters<typeof t>[0])}\n </Badge>\n ),\n },\n {\n accessorKey: 'responseStatus',\n header: t('webhooks.deliveries.columns.responseStatus'),\n cell: ({ row }) => row.original.responseStatus ?? '\u2014',\n },\n {\n accessorKey: 'attemptNumber',\n header: t('webhooks.deliveries.columns.attempts'),\n cell: ({ row }) => `${row.original.attemptNumber}/${row.original.maxAttempts}`,\n },\n {\n accessorKey: 'durationMs',\n header: t('webhooks.deliveries.columns.duration'),\n cell: ({ row }) => row.original.durationMs != null ? `${row.original.durationMs}ms` : '\u2014',\n },\n {\n accessorKey: 'createdAt',\n header: t('webhooks.deliveries.columns.enqueuedAt'),\n cell: ({ row }) => {\n try { return new Date(row.original.enqueuedAt).toLocaleString() }\n catch { return '\u2014' }\n },\n },\n ], [t])\n\n const fields = React.useMemo(() => buildWebhookFormFields(t), [t])\n const groups = React.useMemo(() => buildWebhookFormGroups(t), [t])\n const contentHeader = React.useMemo(() => buildWebhookFormContentHeader(t), [t])\n const menuActions = React.useMemo(() => {\n const items: Array<{ id: string; label: string; onSelect: () => void }> = []\n const isActive = webhook?.isActive ?? false\n\n if (access.canManage) {\n items.push(\n {\n id: 'edit',\n label: t('webhooks.list.actions.edit'),\n onSelect: () => setIsEditing(true),\n },\n {\n id: 'toggle-active',\n label: isActive ? t('webhooks.detail.actions.deactivate') : t('webhooks.detail.actions.activate'),\n onSelect: () => { void handleToggleActive() },\n },\n )\n }\n\n if (access.canSecrets) {\n items.push({\n id: 'rotate-secret',\n label: t('webhooks.detail.actions.rotateSecret'),\n onSelect: () => { void handleRotateSecret() },\n })\n }\n\n if (access.canTest) {\n items.push({\n id: 'test',\n label: t('webhooks.detail.actions.test'),\n onSelect: () => { void handleTest() },\n })\n }\n\n if (access.canManage) {\n items.push({\n id: 'delete',\n label: t('webhooks.list.actions.delete'),\n onSelect: () => { void handleDelete() },\n })\n }\n\n return items\n }, [access.canManage, access.canSecrets, access.canTest, handleDelete, handleRotateSecret, handleTest, handleToggleActive, t, webhook?.isActive])\n\n if (isLoading) return <Page><PageBody><LoadingMessage label={t('webhooks.detail.loading')} /></PageBody></Page>\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('webhooks.errors.notFound')}\n backHref=\"/backend/webhooks\"\n backLabel={t('webhooks.detail.backToList', 'Back to webhooks')}\n />\n </PageBody>\n </Page>\n )\n }\n if (error || !webhook) return <Page><PageBody><ErrorMessage label={error ?? t('webhooks.detail.loadError')} /></PageBody></Page>\n\n if (isEditing) {\n return (\n <Page>\n <PageBody>\n <CrudForm\n title={t('webhooks.form.title.edit')}\n backHref={`/backend/webhooks/${webhook.id}`}\n fields={fields}\n groups={groups}\n initialValues={createWebhookInitialValues(webhook)}\n submitLabel={t('common.save')}\n cancelHref={`/backend/webhooks/${webhook.id}`}\n contentHeader={contentHeader}\n onDelete={access.canManage ? handleDelete : undefined}\n onSubmit={async (values) => {\n const payload = normalizeWebhookFormPayload(values as WebhookFormValues, t)\n await updateCrud(`webhooks/${encodeURIComponent(webhook.id)}`, payload)\n flash(t('webhooks.form.updateSuccess'), 'success')\n setIsEditing(false)\n await refreshDeliveryState()\n }}\n />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {revealedSecret ? (\n <WebhookSecretPanel secret={revealedSecret} onClose={() => setRevealedSecret(null)} />\n ) : null}\n <FormHeader\n mode=\"detail\"\n title={webhook.name}\n entityTypeLabel={t('webhooks.nav.title')}\n statusBadge={\n <Badge\n className={webhook.isActive\n ? 'border-transparent bg-status-success-bg text-status-success-text'\n : 'border-transparent bg-status-neutral-bg text-status-neutral-text'}\n >\n {webhook.isActive ? t('webhooks.list.status.active') : t('webhooks.list.status.inactive')}\n </Badge>\n }\n backHref=\"/backend/webhooks\"\n menuActions={menuActions}\n />\n\n <div className=\"mt-6 space-y-4\">\n {!access.isLoading && !access.canManage && !access.canSecrets && !access.canTest ? (\n <Alert variant=\"info\">\n <AlertDescription>{t('webhooks.detail.readOnlyTip')}</AlertDescription>\n </Alert>\n ) : null}\n <div className=\"grid gap-3 lg:grid-cols-2\">\n <Alert variant=\"info\">\n <AlertDescription>{t('webhooks.detail.deliveryTip')}</AlertDescription>\n </Alert>\n <Alert variant=\"info\">\n <AlertDescription>{t('webhooks.detail.signatureTip')}</AlertDescription>\n </Alert>\n </div>\n <div className=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.url')}:</span>\n <code className=\"ml-2 text-xs break-all\">{webhook.url}</code>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.httpMethod')}:</span>\n <span className=\"ml-2\">{webhook.httpMethod}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.subscribedEvents')}:</span>\n <span className=\"ml-2 text-xs\">{webhook.subscribedEvents.join(', ')}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.maxRetries')}:</span>\n <span className=\"ml-2\">{webhook.maxRetries}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.rateLimitPerMinute')}:</span>\n <span className=\"ml-2\">{webhook.rateLimitPerMinute}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.autoDisableThreshold')}:</span>\n <span className=\"ml-2\">{webhook.autoDisableThreshold}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.detail.consecutiveFailures')}:</span>\n <span className=\"ml-2\">{webhook.consecutiveFailures}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.secret')}:</span>\n <span className=\"ml-2 inline-flex items-center gap-2\">\n <span className=\"font-mono text-xs\">{webhook.maskedSecret}</span>\n {access.canSecrets ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs\"\n onClick={() => { void handleRotateSecret() }}\n >\n <RotateCw className=\"mr-1.5 size-3.5\" />\n {t('webhooks.detail.actions.rotateSecret')}\n </Button>\n ) : null}\n </span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.list.columns.lastDelivery')}:</span>\n <span className=\"ml-2\">{webhook.lastSuccessAt ?? webhook.lastFailureAt ?? '\u2014'}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.detail.previousSecretSetAt')}:</span>\n <span className=\"ml-2\">{webhook.previousSecretSetAt ?? '\u2014'}</span>\n </div>\n <div className=\"col-span-2\">\n <span className=\"text-muted-foreground\">{t('webhooks.form.customHeaders')}:</span>\n <pre className=\"mt-2 rounded border bg-muted/50 p-3 text-xs\">\n {webhook.customHeaders ? JSON.stringify(webhook.customHeaders, null, 2) : '\u2014'}\n </pre>\n </div>\n </div>\n </div>\n\n {testDelivery ? (\n <div className=\"mt-8 rounded-lg border bg-card p-4\">\n <h2 className=\"text-sm font-semibold\">{t('webhooks.detail.testResult')}</h2>\n <div className=\"mt-3 grid gap-2 text-sm\">\n <div>{t('webhooks.deliveries.columns.status')}: {testDelivery.status}</div>\n <div>{t('webhooks.deliveries.columns.responseStatus')}: {testDelivery.responseStatus ?? '\u2014'}</div>\n <div>{t('webhooks.deliveries.columns.duration')}: {testDelivery.durationMs != null ? `${testDelivery.durationMs}ms` : '\u2014'}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {JSON.stringify(testDelivery.payload, null, 2)}\n </pre>\n </div>\n </div>\n ) : null}\n\n <div className=\"mt-8\">\n <DataTable\n title={t('webhooks.deliveries.title')}\n actions={(\n <div className=\"flex items-center gap-2\">\n <span className=\"hidden text-xs text-muted-foreground md:inline\">\n {t('webhooks.deliveries.autoRefreshHint')}\n </span>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => { void refreshDeliveryState() }}\n disabled={isRefreshingDeliveries}\n >\n {isRefreshingDeliveries\n ? t('webhooks.deliveries.refreshing')\n : t('webhooks.deliveries.refresh')}\n </Button>\n </div>\n )}\n columns={deliveryColumns}\n data={deliveries}\n onRowClick={(row) => { void handleDeliveryOpen(row.id) }}\n rowActions={(row) => {\n const items: Array<{ id: string; label: string; onSelect: () => void }> = [\n {\n id: 'view-details',\n label: t('webhooks.deliveries.actions.viewDetails'),\n onSelect: () => { void handleDeliveryOpen(row.id) },\n },\n ]\n\n if (access.canManage && (row.status === 'failed' || row.status === 'expired')) {\n items.push({\n id: 'retry',\n label: t('webhooks.deliveries.actions.retry'),\n onSelect: () => { void handleRetryDelivery(row.id) },\n })\n }\n\n return <RowActions items={items} />\n }}\n perspective={{ tableId: 'webhooks.deliveries' }}\n pagination={{\n page: deliveryPage,\n pageSize: 20,\n total: deliveryTotal,\n totalPages: deliveryTotalPages,\n onPageChange: setDeliveryPage,\n }}\n isLoading={deliveriesLoading || isRefreshingDeliveries}\n />\n </div>\n\n {selectedDelivery || selectedDeliveryLoading ? (\n <div className=\"mt-6 rounded-lg border bg-card p-4\">\n <h2 className=\"text-sm font-semibold\">{t('webhooks.deliveries.detailTitle')}</h2>\n {selectedDeliveryLoading || !selectedDelivery ? (\n <div className=\"mt-3 text-sm text-muted-foreground\">{t('common.loading')}</div>\n ) : (\n <div className=\"mt-3 space-y-4 text-sm\">\n <div>{t('webhooks.deliveries.columns.status')}: {selectedDelivery.status}</div>\n <div>{t('webhooks.deliveries.columns.responseStatus')}: {selectedDelivery.responseStatus ?? '\u2014'}</div>\n <div>{t('webhooks.deliveries.columns.duration')}: {selectedDelivery.durationMs != null ? `${selectedDelivery.durationMs}ms` : '\u2014'}</div>\n <div>\n <div className=\"mb-2 font-medium\">{t('webhooks.deliveries.requestBody')}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {JSON.stringify(selectedDelivery.payload, null, 2)}\n </pre>\n </div>\n <div>\n <div className=\"mb-2 font-medium\">{t('webhooks.deliveries.responseBody')}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {selectedDelivery.responseBody ?? '\u2014'}\n </pre>\n </div>\n <div>\n <div className=\"mb-2 font-medium\">{t('webhooks.deliveries.responseHeaders')}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {selectedDelivery.responseHeaders ? JSON.stringify(selectedDelivery.responseHeaders, null, 2) : '\u2014'}\n </pre>\n </div>\n </div>\n )}\n </div>\n ) : null}\n </PageBody>\n </Page>\n )\n}\n\nfunction resolveWebhookId(paramValue: string | string[] | undefined, pathname: string | null): string | null {\n if (typeof paramValue === 'string' && paramValue.trim().length > 0) {\n return paramValue\n }\n\n if (Array.isArray(paramValue)) {\n const first = paramValue.find((value) => typeof value === 'string' && value.trim().length > 0)\n if (first) return first\n }\n\n if (typeof pathname === 'string') {\n const match = pathname.match(/\\/backend\\/webhooks\\/([^/?#]+)/)\n if (match?.[1]) {\n return decodeURIComponent(match[1])\n }\n }\n\n return null\n}\n"],
5
- "mappings": "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",
6
- "names": ["params"]
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useParams, usePathname, useRouter } from 'next/navigation'\nimport { RotateCw } from 'lucide-react'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { LoadingMessage, ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport { useAppEvent } from '@open-mercato/ui/backend/injection/useAppEvent'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { deleteCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport {\n buildWebhookFormContentHeader,\n buildWebhookFormFields,\n buildWebhookFormGroups,\n createWebhookInitialValues,\n normalizeWebhookFormPayload,\n type WebhookFormValues,\n} from '../../../components/webhook-form-config'\nimport { useWebhookFeatureAccess } from '../useWebhookFeatureAccess'\nimport { WebhookSecretPanel } from '../../../components/WebhookSecretPanel'\n\ntype Webhook = {\n id: string\n name: string\n description: string | null\n url: string\n subscribedEvents: string[]\n httpMethod: 'POST' | 'PUT' | 'PATCH'\n isActive: boolean\n maxRetries: number\n timeoutMs: number\n rateLimitPerMinute: number\n autoDisableThreshold: number\n consecutiveFailures: number\n lastSuccessAt: string | null\n lastFailureAt: string | null\n customHeaders: Record<string, string> | null\n createdAt: string\n updatedAt: string\n maskedSecret: string\n previousSecretSetAt: string | null\n}\n\ntype DeliveryRow = {\n id: string\n webhookId: string\n eventType: string\n messageId: string\n status: string\n responseStatus: number | null\n errorMessage: string | null\n attemptNumber: number\n maxAttempts: number\n durationMs: number | null\n targetUrl: string\n enqueuedAt: string\n lastAttemptAt: string | null\n deliveredAt: string | null\n createdAt: string\n}\n\ntype DeliveryResponse = {\n items: DeliveryRow[]\n total: number\n page: number\n pageSize: number\n totalPages: number\n}\n\ntype DeliveryDetail = DeliveryRow & {\n payload: Record<string, unknown>\n responseBody: string | null\n responseHeaders: Record<string, string> | null\n nextRetryAt: string | null\n updatedAt: string\n}\n\nconst statusVariantMap: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {\n delivered: 'default',\n pending: 'secondary',\n sending: 'outline',\n failed: 'destructive',\n expired: 'destructive',\n}\nconst DELIVERY_AUTO_REFRESH_INTERVAL_MS = 30000\n\nexport default function WebhookDetailPage() {\n const params = useParams()\n const pathname = usePathname()\n const router = useRouter()\n const t = useT()\n const webhookId = React.useMemo(() => resolveWebhookId(params?.id, pathname), [params?.id, pathname])\n\n const [webhook, setWebhook] = React.useState<Webhook | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [isNotFound, setIsNotFound] = React.useState(false)\n const [isEditing, setIsEditing] = React.useState(false)\n\n const [deliveries, setDeliveries] = React.useState<DeliveryRow[]>([])\n const [deliveryPage, setDeliveryPage] = React.useState(1)\n const [deliveryTotal, setDeliveryTotal] = React.useState(0)\n const [deliveryTotalPages, setDeliveryTotalPages] = React.useState(1)\n const [deliveriesLoading, setDeliveriesLoading] = React.useState(false)\n const [isRefreshingDeliveries, setIsRefreshingDeliveries] = React.useState(false)\n const [testDelivery, setTestDelivery] = React.useState<DeliveryDetail | null>(null)\n const [selectedDelivery, setSelectedDelivery] = React.useState<DeliveryDetail | null>(null)\n const [selectedDeliveryLoading, setSelectedDeliveryLoading] = React.useState(false)\n const [revealedSecret, setRevealedSecret] = React.useState<string | null>(null)\n const refreshInFlightRef = React.useRef(false)\n const access = useWebhookFeatureAccess()\n\n const fetchWebhook = React.useCallback(async (options?: { silent?: boolean }) => {\n if (!webhookId) {\n setIsNotFound(true)\n setIsLoading(false)\n return\n }\n\n const silent = options?.silent === true\n if (!silent) {\n setIsLoading(true)\n }\n\n setError(null)\n setIsNotFound(false)\n\n try {\n const call = await apiCall<Webhook>(\n `/api/webhooks/${encodeURIComponent(webhookId)}`,\n undefined,\n { fallback: null },\n )\n\n if (call.ok && call.result) {\n setWebhook(call.result)\n return\n }\n\n if (call.status === 404) {\n setIsNotFound(true)\n } else {\n setError(t('webhooks.detail.loadError'))\n }\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError.message : t('webhooks.detail.loadError'))\n } finally {\n if (!silent) {\n setIsLoading(false)\n }\n }\n }, [t, webhookId])\n\n const fetchDeliveries = React.useCallback(async (options?: { silent?: boolean }) => {\n if (!webhookId) return\n\n const silent = options?.silent === true\n if (!silent) {\n setDeliveriesLoading(true)\n }\n\n try {\n const params = new URLSearchParams()\n params.set('webhookId', webhookId)\n params.set('page', String(deliveryPage))\n params.set('pageSize', '20')\n\n const fallback: DeliveryResponse = { items: [], total: 0, page: deliveryPage, pageSize: 20, totalPages: 1 }\n const call = await apiCall<DeliveryResponse>(\n `/api/webhooks/deliveries?${params.toString()}`,\n undefined,\n { fallback },\n )\n\n if (call.ok && call.result) {\n setDeliveries(call.result.items)\n setDeliveryTotal(call.result.total)\n setDeliveryTotalPages(call.result.totalPages)\n }\n } finally {\n if (!silent) {\n setDeliveriesLoading(false)\n }\n }\n }, [deliveryPage, webhookId])\n\n const fetchDeliveryDetail = React.useCallback(async (deliveryId: string): Promise<DeliveryDetail | null> => {\n const call = await apiCall<DeliveryDetail>(\n `/api/webhooks/deliveries/${encodeURIComponent(deliveryId)}`,\n undefined,\n { fallback: null },\n )\n\n if (!call.ok || !call.result) {\n return null\n }\n\n return call.result\n }, [])\n\n const refreshDeliveryState = React.useCallback(async () => {\n if (!webhookId || refreshInFlightRef.current) return\n\n refreshInFlightRef.current = true\n setIsRefreshingDeliveries(true)\n\n try {\n await Promise.all([\n fetchWebhook({ silent: true }),\n fetchDeliveries({ silent: true }),\n ])\n\n const detailIds = [selectedDelivery?.id, testDelivery?.id].filter(\n (value): value is string => typeof value === 'string' && value.length > 0,\n )\n\n if (detailIds.length > 0) {\n const details = await Promise.all(detailIds.map((deliveryId) => fetchDeliveryDetail(deliveryId)))\n const detailMap = new Map<string, DeliveryDetail>()\n\n for (const detail of details) {\n if (detail) {\n detailMap.set(detail.id, detail)\n }\n }\n\n if (selectedDelivery?.id) {\n setSelectedDelivery((current) => current?.id ? (detailMap.get(current.id) ?? current) : current)\n }\n\n if (testDelivery?.id) {\n setTestDelivery((current) => current?.id ? (detailMap.get(current.id) ?? current) : current)\n }\n }\n } finally {\n refreshInFlightRef.current = false\n setIsRefreshingDeliveries(false)\n }\n }, [fetchDeliveries, fetchDeliveryDetail, fetchWebhook, selectedDelivery?.id, testDelivery?.id, webhookId])\n\n React.useEffect(() => {\n void fetchWebhook()\n }, [fetchWebhook])\n\n React.useEffect(() => {\n if (!webhookId) return\n void fetchDeliveries()\n }, [fetchDeliveries, webhookId])\n\n useAppEvent('webhooks.delivery.*', (event) => {\n const eventWebhookId = typeof event.payload?.webhookId === 'string' ? event.payload.webhookId : null\n if (eventWebhookId !== webhookId) return\n void refreshDeliveryState()\n }, [refreshDeliveryState, webhookId])\n\n React.useEffect(() => {\n if (!webhookId || isEditing) return\n\n const intervalId = window.setInterval(() => {\n if (document.visibilityState !== 'visible') return\n void refreshDeliveryState()\n }, DELIVERY_AUTO_REFRESH_INTERVAL_MS)\n\n return () => {\n window.clearInterval(intervalId)\n }\n }, [isEditing, refreshDeliveryState, webhookId])\n\n const handleToggleActive = React.useCallback(async () => {\n if (!webhook) return\n try {\n const call = await apiCall<Webhook>(\n `/api/webhooks/${encodeURIComponent(webhook.id)}`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ isActive: !webhook.isActive }),\n },\n { fallback: null },\n )\n if (call.ok) {\n setWebhook((prev) => prev ? { ...prev, isActive: !prev.isActive } : prev)\n flash(t('webhooks.form.updateSuccess'), 'success')\n void refreshDeliveryState()\n }\n } catch {\n flash(t('webhooks.form.updateError'), 'error')\n }\n }, [refreshDeliveryState, webhook, t])\n\n const handleRotateSecret = React.useCallback(async () => {\n if (!webhook) return\n try {\n const call = await apiCall<{ secret: string }>(\n `/api/webhooks/${encodeURIComponent(webhook.id)}/rotate-secret`,\n { method: 'POST' },\n { fallback: null },\n )\n if (!call.ok || !call.result) {\n flash(t('webhooks.detail.rotateError'), 'error')\n return\n }\n setRevealedSecret(call.result.secret)\n flash(t('webhooks.detail.rotateSuccess'), 'success')\n void refreshDeliveryState()\n } catch {\n flash(t('webhooks.detail.rotateError'), 'error')\n }\n }, [refreshDeliveryState, t, webhook])\n\n const handleTest = React.useCallback(async () => {\n if (!webhook) return\n try {\n const call = await apiCall<{ delivery: DeliveryDetail }>(\n `/api/webhooks/${encodeURIComponent(webhook.id)}/test`,\n { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({}) },\n { fallback: null },\n )\n if (!call.ok || !call.result) {\n flash(t('webhooks.detail.testError'), 'error')\n return\n }\n const deliveryStatus = call.result.delivery.status\n setTestDelivery(call.result.delivery)\n flash(\n deliveryStatus === 'delivered' ? t('webhooks.detail.testSuccess') : t('webhooks.detail.testQueued'),\n deliveryStatus === 'delivered' ? 'success' : 'error',\n )\n void refreshDeliveryState()\n } catch {\n flash(t('webhooks.detail.testError'), 'error')\n }\n }, [refreshDeliveryState, t, webhook])\n\n const handleRetryDelivery = React.useCallback(async (deliveryId: string) => {\n try {\n const call = await apiCall(\n `/api/webhooks/deliveries/${encodeURIComponent(deliveryId)}/retry`,\n { method: 'POST' },\n { fallback: null },\n )\n if (!call.ok) {\n flash(t('webhooks.deliveries.retryError'), 'error')\n return\n }\n flash(t('webhooks.deliveries.retrySuccess'), 'success')\n void refreshDeliveryState()\n } catch {\n flash(t('webhooks.deliveries.retryError'), 'error')\n }\n }, [refreshDeliveryState, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!webhook) return\n try {\n await deleteCrud(`webhooks/${encodeURIComponent(webhook.id)}`, {\n fallbackResult: null,\n headers: buildOptimisticLockHeader(webhook.updatedAt),\n })\n flash(t('webhooks.list.deleteSuccess'), 'success')\n router.push('/backend/webhooks')\n } catch (error) {\n if (surfaceRecordConflict(error, t)) return\n flash(t('webhooks.list.deleteError'), 'error')\n }\n }, [router, t, webhook])\n\n const handleDeliveryOpen = React.useCallback(async (deliveryId: string) => {\n setSelectedDeliveryLoading(true)\n try {\n const detail = await fetchDeliveryDetail(deliveryId)\n if (!detail) {\n flash(t('webhooks.deliveries.loadError'), 'error')\n return\n }\n setSelectedDelivery(detail)\n } catch {\n flash(t('webhooks.deliveries.loadError'), 'error')\n } finally {\n setSelectedDeliveryLoading(false)\n }\n }, [fetchDeliveryDetail, t])\n\n const deliveryColumns = React.useMemo<ColumnDef<DeliveryRow>[]>(() => [\n { accessorKey: 'eventType', header: t('webhooks.deliveries.columns.event') },\n {\n accessorKey: 'status',\n header: t('webhooks.deliveries.columns.status'),\n cell: ({ row }) => (\n <Badge variant={statusVariantMap[row.original.status] ?? 'secondary'}>\n {t(`webhooks.deliveries.status.${row.original.status}` as Parameters<typeof t>[0])}\n </Badge>\n ),\n },\n {\n accessorKey: 'responseStatus',\n header: t('webhooks.deliveries.columns.responseStatus'),\n cell: ({ row }) => row.original.responseStatus ?? '\u2014',\n },\n {\n accessorKey: 'attemptNumber',\n header: t('webhooks.deliveries.columns.attempts'),\n cell: ({ row }) => `${row.original.attemptNumber}/${row.original.maxAttempts}`,\n },\n {\n accessorKey: 'durationMs',\n header: t('webhooks.deliveries.columns.duration'),\n cell: ({ row }) => row.original.durationMs != null ? `${row.original.durationMs}ms` : '\u2014',\n },\n {\n accessorKey: 'createdAt',\n header: t('webhooks.deliveries.columns.enqueuedAt'),\n cell: ({ row }) => {\n try { return new Date(row.original.enqueuedAt).toLocaleString() }\n catch { return '\u2014' }\n },\n },\n ], [t])\n\n const fields = React.useMemo(() => buildWebhookFormFields(t), [t])\n const groups = React.useMemo(() => buildWebhookFormGroups(t), [t])\n const contentHeader = React.useMemo(() => buildWebhookFormContentHeader(t), [t])\n const menuActions = React.useMemo(() => {\n const items: Array<{ id: string; label: string; onSelect: () => void }> = []\n const isActive = webhook?.isActive ?? false\n\n if (access.canManage) {\n items.push(\n {\n id: 'edit',\n label: t('webhooks.list.actions.edit'),\n onSelect: () => setIsEditing(true),\n },\n {\n id: 'toggle-active',\n label: isActive ? t('webhooks.detail.actions.deactivate') : t('webhooks.detail.actions.activate'),\n onSelect: () => { void handleToggleActive() },\n },\n )\n }\n\n if (access.canSecrets) {\n items.push({\n id: 'rotate-secret',\n label: t('webhooks.detail.actions.rotateSecret'),\n onSelect: () => { void handleRotateSecret() },\n })\n }\n\n if (access.canTest) {\n items.push({\n id: 'test',\n label: t('webhooks.detail.actions.test'),\n onSelect: () => { void handleTest() },\n })\n }\n\n if (access.canManage) {\n items.push({\n id: 'delete',\n label: t('webhooks.list.actions.delete'),\n onSelect: () => { void handleDelete() },\n })\n }\n\n return items\n }, [access.canManage, access.canSecrets, access.canTest, handleDelete, handleRotateSecret, handleTest, handleToggleActive, t, webhook?.isActive])\n\n if (isLoading) return <Page><PageBody><LoadingMessage label={t('webhooks.detail.loading')} /></PageBody></Page>\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('webhooks.errors.notFound')}\n backHref=\"/backend/webhooks\"\n backLabel={t('webhooks.detail.backToList', 'Back to webhooks')}\n />\n </PageBody>\n </Page>\n )\n }\n if (error || !webhook) return <Page><PageBody><ErrorMessage label={error ?? t('webhooks.detail.loadError')} /></PageBody></Page>\n\n if (isEditing) {\n return (\n <Page>\n <PageBody>\n <CrudForm\n title={t('webhooks.form.title.edit')}\n backHref={`/backend/webhooks/${webhook.id}`}\n fields={fields}\n groups={groups}\n initialValues={createWebhookInitialValues(webhook)}\n optimisticLockUpdatedAt={webhook.updatedAt}\n submitLabel={t('common.save')}\n cancelHref={`/backend/webhooks/${webhook.id}`}\n contentHeader={contentHeader}\n onDelete={access.canManage ? handleDelete : undefined}\n onSubmit={async (values) => {\n const payload = normalizeWebhookFormPayload(values as WebhookFormValues, t)\n await updateCrud(`webhooks/${encodeURIComponent(webhook.id)}`, payload)\n flash(t('webhooks.form.updateSuccess'), 'success')\n setIsEditing(false)\n await refreshDeliveryState()\n }}\n />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {revealedSecret ? (\n <WebhookSecretPanel secret={revealedSecret} onClose={() => setRevealedSecret(null)} />\n ) : null}\n <FormHeader\n mode=\"detail\"\n title={webhook.name}\n entityTypeLabel={t('webhooks.nav.title')}\n statusBadge={\n <Badge\n className={webhook.isActive\n ? 'border-transparent bg-status-success-bg text-status-success-text'\n : 'border-transparent bg-status-neutral-bg text-status-neutral-text'}\n >\n {webhook.isActive ? t('webhooks.list.status.active') : t('webhooks.list.status.inactive')}\n </Badge>\n }\n backHref=\"/backend/webhooks\"\n menuActions={menuActions}\n />\n\n <div className=\"mt-6 space-y-4\">\n {!access.isLoading && !access.canManage && !access.canSecrets && !access.canTest ? (\n <Alert variant=\"info\">\n <AlertDescription>{t('webhooks.detail.readOnlyTip')}</AlertDescription>\n </Alert>\n ) : null}\n <div className=\"grid gap-3 lg:grid-cols-2\">\n <Alert variant=\"info\">\n <AlertDescription>{t('webhooks.detail.deliveryTip')}</AlertDescription>\n </Alert>\n <Alert variant=\"info\">\n <AlertDescription>{t('webhooks.detail.signatureTip')}</AlertDescription>\n </Alert>\n </div>\n <div className=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.url')}:</span>\n <code className=\"ml-2 text-xs break-all\">{webhook.url}</code>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.httpMethod')}:</span>\n <span className=\"ml-2\">{webhook.httpMethod}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.subscribedEvents')}:</span>\n <span className=\"ml-2 text-xs\">{webhook.subscribedEvents.join(', ')}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.maxRetries')}:</span>\n <span className=\"ml-2\">{webhook.maxRetries}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.rateLimitPerMinute')}:</span>\n <span className=\"ml-2\">{webhook.rateLimitPerMinute}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.autoDisableThreshold')}:</span>\n <span className=\"ml-2\">{webhook.autoDisableThreshold}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.detail.consecutiveFailures')}:</span>\n <span className=\"ml-2\">{webhook.consecutiveFailures}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.form.secret')}:</span>\n <span className=\"ml-2 inline-flex items-center gap-2\">\n <span className=\"font-mono text-xs\">{webhook.maskedSecret}</span>\n {access.canSecrets ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 px-2 text-xs\"\n onClick={() => { void handleRotateSecret() }}\n >\n <RotateCw className=\"mr-1.5 size-3.5\" />\n {t('webhooks.detail.actions.rotateSecret')}\n </Button>\n ) : null}\n </span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.list.columns.lastDelivery')}:</span>\n <span className=\"ml-2\">{webhook.lastSuccessAt ?? webhook.lastFailureAt ?? '\u2014'}</span>\n </div>\n <div>\n <span className=\"text-muted-foreground\">{t('webhooks.detail.previousSecretSetAt')}:</span>\n <span className=\"ml-2\">{webhook.previousSecretSetAt ?? '\u2014'}</span>\n </div>\n <div className=\"col-span-2\">\n <span className=\"text-muted-foreground\">{t('webhooks.form.customHeaders')}:</span>\n <pre className=\"mt-2 rounded border bg-muted/50 p-3 text-xs\">\n {webhook.customHeaders ? JSON.stringify(webhook.customHeaders, null, 2) : '\u2014'}\n </pre>\n </div>\n </div>\n </div>\n\n {testDelivery ? (\n <div className=\"mt-8 rounded-lg border bg-card p-4\">\n <h2 className=\"text-sm font-semibold\">{t('webhooks.detail.testResult')}</h2>\n <div className=\"mt-3 grid gap-2 text-sm\">\n <div>{t('webhooks.deliveries.columns.status')}: {testDelivery.status}</div>\n <div>{t('webhooks.deliveries.columns.responseStatus')}: {testDelivery.responseStatus ?? '\u2014'}</div>\n <div>{t('webhooks.deliveries.columns.duration')}: {testDelivery.durationMs != null ? `${testDelivery.durationMs}ms` : '\u2014'}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {JSON.stringify(testDelivery.payload, null, 2)}\n </pre>\n </div>\n </div>\n ) : null}\n\n <div className=\"mt-8\">\n <DataTable\n title={t('webhooks.deliveries.title')}\n actions={(\n <div className=\"flex items-center gap-2\">\n <span className=\"hidden text-xs text-muted-foreground md:inline\">\n {t('webhooks.deliveries.autoRefreshHint')}\n </span>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => { void refreshDeliveryState() }}\n disabled={isRefreshingDeliveries}\n >\n {isRefreshingDeliveries\n ? t('webhooks.deliveries.refreshing')\n : t('webhooks.deliveries.refresh')}\n </Button>\n </div>\n )}\n columns={deliveryColumns}\n data={deliveries}\n onRowClick={(row) => { void handleDeliveryOpen(row.id) }}\n rowActions={(row) => {\n const items: Array<{ id: string; label: string; onSelect: () => void }> = [\n {\n id: 'view-details',\n label: t('webhooks.deliveries.actions.viewDetails'),\n onSelect: () => { void handleDeliveryOpen(row.id) },\n },\n ]\n\n if (access.canManage && (row.status === 'failed' || row.status === 'expired')) {\n items.push({\n id: 'retry',\n label: t('webhooks.deliveries.actions.retry'),\n onSelect: () => { void handleRetryDelivery(row.id) },\n })\n }\n\n return <RowActions items={items} />\n }}\n perspective={{ tableId: 'webhooks.deliveries' }}\n pagination={{\n page: deliveryPage,\n pageSize: 20,\n total: deliveryTotal,\n totalPages: deliveryTotalPages,\n onPageChange: setDeliveryPage,\n }}\n isLoading={deliveriesLoading || isRefreshingDeliveries}\n />\n </div>\n\n {selectedDelivery || selectedDeliveryLoading ? (\n <div className=\"mt-6 rounded-lg border bg-card p-4\">\n <h2 className=\"text-sm font-semibold\">{t('webhooks.deliveries.detailTitle')}</h2>\n {selectedDeliveryLoading || !selectedDelivery ? (\n <div className=\"mt-3 text-sm text-muted-foreground\">{t('common.loading')}</div>\n ) : (\n <div className=\"mt-3 space-y-4 text-sm\">\n <div>{t('webhooks.deliveries.columns.status')}: {selectedDelivery.status}</div>\n <div>{t('webhooks.deliveries.columns.responseStatus')}: {selectedDelivery.responseStatus ?? '\u2014'}</div>\n <div>{t('webhooks.deliveries.columns.duration')}: {selectedDelivery.durationMs != null ? `${selectedDelivery.durationMs}ms` : '\u2014'}</div>\n <div>\n <div className=\"mb-2 font-medium\">{t('webhooks.deliveries.requestBody')}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {JSON.stringify(selectedDelivery.payload, null, 2)}\n </pre>\n </div>\n <div>\n <div className=\"mb-2 font-medium\">{t('webhooks.deliveries.responseBody')}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {selectedDelivery.responseBody ?? '\u2014'}\n </pre>\n </div>\n <div>\n <div className=\"mb-2 font-medium\">{t('webhooks.deliveries.responseHeaders')}</div>\n <pre className=\"overflow-auto rounded border bg-muted/50 p-3 text-xs\">\n {selectedDelivery.responseHeaders ? JSON.stringify(selectedDelivery.responseHeaders, null, 2) : '\u2014'}\n </pre>\n </div>\n </div>\n )}\n </div>\n ) : null}\n </PageBody>\n </Page>\n )\n}\n\nfunction resolveWebhookId(paramValue: string | string[] | undefined, pathname: string | null): string | null {\n if (typeof paramValue === 'string' && paramValue.trim().length > 0) {\n return paramValue\n }\n\n if (Array.isArray(paramValue)) {\n const first = paramValue.find((value) => typeof value === 'string' && value.trim().length > 0)\n if (first) return first\n }\n\n if (typeof pathname === 'string') {\n const match = pathname.match(/\\/backend\\/webhooks\\/([^/?#]+)/)\n if (match?.[1]) {\n return decodeURIComponent(match[1])\n }\n }\n\n return null\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["params", "error"]
7
7
  }
@@ -8,6 +8,8 @@ import { DataTable } from "@open-mercato/ui/backend/DataTable";
8
8
  import { Button } from "@open-mercato/ui/primitives/button";
9
9
  import { RowActions } from "@open-mercato/ui/backend/RowActions";
10
10
  import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
11
+ import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
12
+ import { surfaceRecordConflict } from "@open-mercato/ui/backend/conflicts";
11
13
  import { flash } from "@open-mercato/ui/backend/FlashMessages";
12
14
  import { useOrganizationScopeVersion } from "@open-mercato/shared/lib/frontend/useOrganizationScope";
13
15
  import { useT } from "@open-mercato/shared/lib/i18n/context";
@@ -81,10 +83,11 @@ function WebhooksListPage() {
81
83
  try {
82
84
  const call = await apiCall(
83
85
  `/api/webhooks/${encodeURIComponent(row.id)}`,
84
- { method: "DELETE" },
86
+ { method: "DELETE", headers: buildOptimisticLockHeader(row.updatedAt) },
85
87
  { fallback: null }
86
88
  );
87
89
  if (!call.ok) {
90
+ if (surfaceRecordConflict({ status: call.status, body: call.result }, t)) return;
88
91
  const errorPayload = call.result;
89
92
  const message = typeof errorPayload?.error === "string" ? errorPayload.error : t("webhooks.list.deleteError");
90
93
  flash(message, "error");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/webhooks/backend/webhooks/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { useWebhookFeatureAccess } from './useWebhookFeatureAccess'\n\ntype Row = {\n id: string\n name: string\n description: string | null\n url: string\n subscribedEvents: string[]\n httpMethod: string\n isActive: boolean\n deliveryStrategy: string\n maxRetries: number\n consecutiveFailures: number\n lastSuccessAt: string | null\n lastFailureAt: string | null\n createdAt: string\n updatedAt: string\n}\n\ntype ResponsePayload = {\n items: Row[]\n total: number\n page: number\n totalPages: number\n}\n\nexport default function WebhooksListPage() {\n const [rows, setRows] = React.useState<Row[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const scopeVersion = useOrganizationScopeVersion()\n const t = useT()\n const router = useRouter()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const access = useWebhookFeatureAccess()\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n try {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', '20')\n if (search) params.set('search', search)\n if (typeof filterValues.status === 'string' && filterValues.status.length > 0) {\n params.set('isActive', filterValues.status)\n }\n const fallback: ResponsePayload = { items: [], total: 0, page, totalPages: 1 }\n const call = await apiCall<ResponsePayload>(\n `/api/webhooks?${params.toString()}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('webhooks.list.loadError')\n flash(message, 'error')\n return\n }\n const payload = call.result ?? fallback\n if (!cancelled) {\n setRows(Array.isArray(payload.items) ? payload.items : [])\n setTotal(payload.total || 0)\n setTotalPages(payload.totalPages || 1)\n }\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error ? error.message : t('webhooks.list.loadError')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [filterValues.status, page, search, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: Row) => {\n const confirmed = await confirm({\n title: t('webhooks.list.confirmDelete'),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const call = await apiCall<{ error?: string }>(\n `/api/webhooks/${encodeURIComponent(row.id)}`,\n { method: 'DELETE' },\n { fallback: null },\n )\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('webhooks.list.deleteError')\n flash(message, 'error')\n return\n }\n flash(t('webhooks.list.deleteSuccess'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message = error instanceof Error ? error.message : t('webhooks.list.deleteError')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n const handleToggleActive = React.useCallback(async (row: Row) => {\n try {\n const call = await apiCall<Row>(\n `/api/webhooks/${encodeURIComponent(row.id)}`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ isActive: !row.isActive }),\n },\n { fallback: null },\n )\n if (!call.ok) {\n flash(t('webhooks.form.updateError'), 'error')\n return\n }\n flash(t('webhooks.form.updateSuccess'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n flash(error instanceof Error ? error.message : t('webhooks.form.updateError'), 'error')\n }\n }, [t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'status',\n label: t('webhooks.list.filters.status'),\n type: 'select',\n options: [\n { value: 'true', label: t('webhooks.list.status.active') },\n { value: 'false', label: t('webhooks.list.status.inactive') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<Row>[]>(() => [\n {\n accessorKey: 'name',\n header: t('webhooks.list.columns.name'),\n cell: ({ row }) => (\n <Link href={`/backend/webhooks/${row.original.id}`} className=\"font-medium text-primary hover:underline\">\n {row.original.name}\n </Link>\n ),\n },\n {\n accessorKey: 'url',\n header: t('webhooks.list.columns.url'),\n cell: ({ row }) => (\n <code className=\"text-xs truncate max-w-[200px] block\" title={row.original.url}>{row.original.url}</code>\n ),\n meta: { truncate: true, maxWidth: 250 },\n },\n {\n accessorKey: 'subscribedEvents',\n header: t('webhooks.list.columns.events'),\n cell: ({ row }) => {\n const events = row.original.subscribedEvents\n if (events.length === 0) return <span className=\"text-muted-foreground text-xs\">\u2014</span>\n if (events.length <= 2) return <span className=\"text-xs\">{events.join(', ')}</span>\n return <span className=\"text-xs\">{events.slice(0, 2).join(', ')} +{events.length - 2}</span>\n },\n },\n {\n accessorKey: 'isActive',\n header: t('webhooks.list.columns.status'),\n cell: ({ row }) => (\n <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${row.original.isActive ? 'bg-status-success-bg text-status-success-text' : 'bg-status-neutral-bg text-status-neutral-text'}`}>\n {row.original.isActive ? t('webhooks.list.status.active') : t('webhooks.list.status.inactive')}\n </span>\n ),\n },\n {\n accessorKey: 'lastSuccessAt',\n header: t('webhooks.list.columns.lastDelivery'),\n cell: ({ row }) => {\n const lastSuccessAt = row.original.lastSuccessAt ? new Date(row.original.lastSuccessAt).getTime() : null\n const lastFailureAt = row.original.lastFailureAt ? new Date(row.original.lastFailureAt).getTime() : null\n const lastTimestamp = Math.max(lastSuccessAt ?? 0, lastFailureAt ?? 0)\n if (!lastTimestamp) return <span className=\"text-muted-foreground\">\u2014</span>\n const isFailure = lastFailureAt !== null && lastFailureAt >= (lastSuccessAt ?? 0)\n return (\n <span className={isFailure ? 'text-destructive' : 'text-muted-foreground'}>\n {new Date(lastTimestamp).toLocaleString()}\n </span>\n )\n },\n },\n {\n accessorKey: 'createdAt',\n header: t('webhooks.list.columns.createdAt'),\n cell: ({ row }) => {\n try {\n return new Date(row.original.createdAt).toLocaleDateString()\n } catch {\n return '\u2014'\n }\n },\n },\n ], [t])\n\n return (\n <Page>\n <PageBody className=\"space-y-4\">\n <Alert variant=\"info\">\n <AlertTitle>{t('webhooks.list.description')}</AlertTitle>\n <AlertDescription>{t('webhooks.list.operatorTip')}</AlertDescription>\n </Alert>\n <DataTable\n title={t('webhooks.list.title')}\n actions={access.canManage ? (\n <Button asChild>\n <Link href=\"/backend/webhooks/create\">{t('webhooks.nav.create')}</Link>\n </Button>\n ) : undefined}\n columns={columns}\n data={rows}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(next) => {\n setFilterValues(next)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: 'webhooks.list' }}\n rowActions={(row) => {\n const items = [\n {\n id: 'view-deliveries',\n label: t('webhooks.list.actions.viewDeliveries'),\n onSelect: () => { router.push(`/backend/webhooks/${row.id}`) },\n },\n ]\n\n if (access.canManage) {\n items.unshift(\n { id: 'edit', label: t('webhooks.list.actions.edit'), onSelect: () => { router.push(`/backend/webhooks/${row.id}`) } },\n {\n id: 'toggle-active',\n label: row.isActive ? t('webhooks.detail.actions.deactivate') : t('webhooks.detail.actions.activate'),\n onSelect: () => { void handleToggleActive(row) },\n },\n )\n items.push({ id: 'delete', label: t('webhooks.list.actions.delete'), onSelect: () => { void handleDelete(row) } })\n }\n\n return <RowActions items={items} />\n }}\n pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}\n isLoading={isLoading}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable } from '@open-mercato/ui/backend/DataTable'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { FilterDef, FilterValues } from '@open-mercato/ui/backend/FilterBar'\nimport { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { useWebhookFeatureAccess } from './useWebhookFeatureAccess'\n\ntype Row = {\n id: string\n name: string\n description: string | null\n url: string\n subscribedEvents: string[]\n httpMethod: string\n isActive: boolean\n deliveryStrategy: string\n maxRetries: number\n consecutiveFailures: number\n lastSuccessAt: string | null\n lastFailureAt: string | null\n createdAt: string\n updatedAt: string\n}\n\ntype ResponsePayload = {\n items: Row[]\n total: number\n page: number\n totalPages: number\n}\n\nexport default function WebhooksListPage() {\n const [rows, setRows] = React.useState<Row[]>([])\n const [page, setPage] = React.useState(1)\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [search, setSearch] = React.useState('')\n const [filterValues, setFilterValues] = React.useState<FilterValues>({})\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const scopeVersion = useOrganizationScopeVersion()\n const t = useT()\n const router = useRouter()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const access = useWebhookFeatureAccess()\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n try {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', '20')\n if (search) params.set('search', search)\n if (typeof filterValues.status === 'string' && filterValues.status.length > 0) {\n params.set('isActive', filterValues.status)\n }\n const fallback: ResponsePayload = { items: [], total: 0, page, totalPages: 1 }\n const call = await apiCall<ResponsePayload>(\n `/api/webhooks?${params.toString()}`,\n undefined,\n { fallback },\n )\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('webhooks.list.loadError')\n flash(message, 'error')\n return\n }\n const payload = call.result ?? fallback\n if (!cancelled) {\n setRows(Array.isArray(payload.items) ? payload.items : [])\n setTotal(payload.total || 0)\n setTotalPages(payload.totalPages || 1)\n }\n } catch (error) {\n if (!cancelled) {\n const message = error instanceof Error ? error.message : t('webhooks.list.loadError')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [filterValues.status, page, search, reloadToken, scopeVersion, t])\n\n const handleDelete = React.useCallback(async (row: Row) => {\n const confirmed = await confirm({\n title: t('webhooks.list.confirmDelete'),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n const call = await apiCall<{ error?: string }>(\n `/api/webhooks/${encodeURIComponent(row.id)}`,\n { method: 'DELETE', headers: buildOptimisticLockHeader(row.updatedAt) },\n { fallback: null },\n )\n if (!call.ok) {\n if (surfaceRecordConflict({ status: call.status, body: call.result }, t)) return\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('webhooks.list.deleteError')\n flash(message, 'error')\n return\n }\n flash(t('webhooks.list.deleteSuccess'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n const message = error instanceof Error ? error.message : t('webhooks.list.deleteError')\n flash(message, 'error')\n }\n }, [confirm, t])\n\n const handleToggleActive = React.useCallback(async (row: Row) => {\n try {\n const call = await apiCall<Row>(\n `/api/webhooks/${encodeURIComponent(row.id)}`,\n {\n method: 'PUT',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ isActive: !row.isActive }),\n },\n { fallback: null },\n )\n if (!call.ok) {\n flash(t('webhooks.form.updateError'), 'error')\n return\n }\n flash(t('webhooks.form.updateSuccess'), 'success')\n setReloadToken((token) => token + 1)\n } catch (error) {\n flash(error instanceof Error ? error.message : t('webhooks.form.updateError'), 'error')\n }\n }, [t])\n\n const filters = React.useMemo<FilterDef[]>(() => [\n {\n id: 'status',\n label: t('webhooks.list.filters.status'),\n type: 'select',\n options: [\n { value: 'true', label: t('webhooks.list.status.active') },\n { value: 'false', label: t('webhooks.list.status.inactive') },\n ],\n },\n ], [t])\n\n const columns = React.useMemo<ColumnDef<Row>[]>(() => [\n {\n accessorKey: 'name',\n header: t('webhooks.list.columns.name'),\n cell: ({ row }) => (\n <Link href={`/backend/webhooks/${row.original.id}`} className=\"font-medium text-primary hover:underline\">\n {row.original.name}\n </Link>\n ),\n },\n {\n accessorKey: 'url',\n header: t('webhooks.list.columns.url'),\n cell: ({ row }) => (\n <code className=\"text-xs truncate max-w-[200px] block\" title={row.original.url}>{row.original.url}</code>\n ),\n meta: { truncate: true, maxWidth: 250 },\n },\n {\n accessorKey: 'subscribedEvents',\n header: t('webhooks.list.columns.events'),\n cell: ({ row }) => {\n const events = row.original.subscribedEvents\n if (events.length === 0) return <span className=\"text-muted-foreground text-xs\">\u2014</span>\n if (events.length <= 2) return <span className=\"text-xs\">{events.join(', ')}</span>\n return <span className=\"text-xs\">{events.slice(0, 2).join(', ')} +{events.length - 2}</span>\n },\n },\n {\n accessorKey: 'isActive',\n header: t('webhooks.list.columns.status'),\n cell: ({ row }) => (\n <span className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${row.original.isActive ? 'bg-status-success-bg text-status-success-text' : 'bg-status-neutral-bg text-status-neutral-text'}`}>\n {row.original.isActive ? t('webhooks.list.status.active') : t('webhooks.list.status.inactive')}\n </span>\n ),\n },\n {\n accessorKey: 'lastSuccessAt',\n header: t('webhooks.list.columns.lastDelivery'),\n cell: ({ row }) => {\n const lastSuccessAt = row.original.lastSuccessAt ? new Date(row.original.lastSuccessAt).getTime() : null\n const lastFailureAt = row.original.lastFailureAt ? new Date(row.original.lastFailureAt).getTime() : null\n const lastTimestamp = Math.max(lastSuccessAt ?? 0, lastFailureAt ?? 0)\n if (!lastTimestamp) return <span className=\"text-muted-foreground\">\u2014</span>\n const isFailure = lastFailureAt !== null && lastFailureAt >= (lastSuccessAt ?? 0)\n return (\n <span className={isFailure ? 'text-destructive' : 'text-muted-foreground'}>\n {new Date(lastTimestamp).toLocaleString()}\n </span>\n )\n },\n },\n {\n accessorKey: 'createdAt',\n header: t('webhooks.list.columns.createdAt'),\n cell: ({ row }) => {\n try {\n return new Date(row.original.createdAt).toLocaleDateString()\n } catch {\n return '\u2014'\n }\n },\n },\n ], [t])\n\n return (\n <Page>\n <PageBody className=\"space-y-4\">\n <Alert variant=\"info\">\n <AlertTitle>{t('webhooks.list.description')}</AlertTitle>\n <AlertDescription>{t('webhooks.list.operatorTip')}</AlertDescription>\n </Alert>\n <DataTable\n title={t('webhooks.list.title')}\n actions={access.canManage ? (\n <Button asChild>\n <Link href=\"/backend/webhooks/create\">{t('webhooks.nav.create')}</Link>\n </Button>\n ) : undefined}\n columns={columns}\n data={rows}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n filters={filters}\n filterValues={filterValues}\n onFiltersApply={(next) => {\n setFilterValues(next)\n setPage(1)\n }}\n onFiltersClear={() => {\n setFilterValues({})\n setPage(1)\n }}\n perspective={{ tableId: 'webhooks.list' }}\n rowActions={(row) => {\n const items = [\n {\n id: 'view-deliveries',\n label: t('webhooks.list.actions.viewDeliveries'),\n onSelect: () => { router.push(`/backend/webhooks/${row.id}`) },\n },\n ]\n\n if (access.canManage) {\n items.unshift(\n { id: 'edit', label: t('webhooks.list.actions.edit'), onSelect: () => { router.push(`/backend/webhooks/${row.id}`) } },\n {\n id: 'toggle-active',\n label: row.isActive ? t('webhooks.detail.actions.deactivate') : t('webhooks.detail.actions.activate'),\n onSelect: () => { void handleToggleActive(row) },\n },\n )\n items.push({ id: 'delete', label: t('webhooks.list.actions.delete'), onSelect: () => { void handleDelete(row) } })\n }\n\n return <RowActions items={items} />\n }}\n pagination={{ page, pageSize: 20, total, totalPages, onPageChange: setPage }}\n isLoading={isLoading}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/webhooks",
3
- "version": "0.6.5-develop.4534.1.b459babe6d",
3
+ "version": "0.6.5-develop.4544.1.71c003c861",
4
4
  "description": "Webhooks module for Open Mercato — Standard Webhooks compliant outbound/inbound delivery",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -69,19 +69,19 @@
69
69
  }
70
70
  },
71
71
  "dependencies": {
72
- "@open-mercato/core": "0.6.5-develop.4534.1.b459babe6d",
73
- "@open-mercato/queue": "0.6.5-develop.4534.1.b459babe6d",
74
- "@open-mercato/ui": "0.6.5-develop.4534.1.b459babe6d",
72
+ "@open-mercato/core": "0.6.5-develop.4544.1.71c003c861",
73
+ "@open-mercato/queue": "0.6.5-develop.4544.1.71c003c861",
74
+ "@open-mercato/ui": "0.6.5-develop.4544.1.71c003c861",
75
75
  "svix": "^1.95.1"
76
76
  },
77
77
  "peerDependencies": {
78
78
  "@mikro-orm/postgresql": "^7.0.14",
79
- "@open-mercato/shared": "0.6.5-develop.4534.1.b459babe6d",
79
+ "@open-mercato/shared": "0.6.5-develop.4544.1.71c003c861",
80
80
  "react": "^19.0.0",
81
81
  "react-dom": "^19.0.0"
82
82
  },
83
83
  "devDependencies": {
84
- "@open-mercato/shared": "0.6.5-develop.4534.1.b459babe6d",
84
+ "@open-mercato/shared": "0.6.5-develop.4544.1.71c003c861",
85
85
  "@types/jest": "^30.0.0",
86
86
  "@types/react": "^19.2.16",
87
87
  "@types/react-dom": "^19.2.3",