@burdenoff/microfe-channel 2026.513.1 → 2026.514.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/channel/ChannelRoot.js +1 -1
  2. package/dist/channel/ChannelRoot.js.map +1 -1
  3. package/dist/channel/hooks/useChannelSubscription.d.ts +4 -4
  4. package/dist/channel/hooks/useChannelSubscription.d.ts.map +1 -1
  5. package/dist/channel/hooks/useChannelSubscription.js +2 -2
  6. package/dist/channel/hooks/useChannelSubscription.js.map +1 -1
  7. package/dist/channel/hooks/useChannels.d.ts.map +1 -1
  8. package/dist/channel/hooks/useChannels.js +130 -124
  9. package/dist/channel/hooks/useChannels.js.map +1 -1
  10. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +5 -5
  11. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -1
  12. package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts.map +1 -1
  13. package/dist/channel/modules/channels/pages/ChannelUsersPage.js +25 -7
  14. package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -1
  15. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +7 -7
  16. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -1
  17. package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts.map +1 -1
  18. package/dist/channel/modules/channels/pages/ConnectionsListPage.js +137 -133
  19. package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -1
  20. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts.map +1 -1
  21. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +162 -158
  22. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -1
  23. package/dist/channel/modules/channels/pages/EditChannelPage.js +5 -5
  24. package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -1
  25. package/dist/channel/modules/channels/pages/SendMessagePage.js +2 -2
  26. package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -1
  27. package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts.map +1 -1
  28. package/dist/channel/modules/channels/pages/WebhookEventsPage.js +11 -3
  29. package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -1
  30. package/dist/generated/wspace-types.d.ts +681 -145
  31. package/dist/generated/wspace-types.d.ts.map +1 -1
  32. package/dist/translations/en.d.ts +260 -0
  33. package/dist/translations/en.d.ts.map +1 -0
  34. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionDetailsPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/ConnectionDetailsPage.tsx"],"sourcesContent":["/**\n * Connection Details Page\n *\n * View and manage a specific connection within a channel.\n */\n\nimport { useEffect, useState } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\nimport { reportShellError } from '../../../utils/shellBridge';\nimport { nativeImpact, nativeNotify } from '../../../../utils/nativeBridge';\nimport {\n ArrowLeft,\n Loader2,\n AlertCircle,\n CheckCircle2,\n XCircle,\n RefreshCw,\n Trash2,\n Edit,\n Shield,\n Clock,\n} from 'lucide-react';\nimport { useChannel } from '../../../hooks/useChannels';\nimport { useChannel as useChannelContext } from '../../../providers/ChannelProvider';\nimport { getGlobalChannelClient } from '../../../graphql/global-client';\nimport {\n GetConnectionDocument,\n type GetConnectionQuery,\n} from '../../../../generated/global-operations';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\n\nconst HEALTH_CONFIG: Record<\n string,\n { icon: typeof CheckCircle2; color: string; bgColor: string; label: string }\n> = {\n true: {\n icon: CheckCircle2,\n color: 'text-green-500',\n bgColor: 'bg-green-500/10',\n label: 'Healthy',\n },\n false: { icon: XCircle, color: 'text-red-500', bgColor: 'bg-red-500/10', label: 'Unhealthy' },\n};\n\nexport function ConnectionDetailsPage() {\n const navigate = useNavigate();\n const params = useParams<{ channelId?: string; connectionId: string }>();\n const { connectionId } = params;\n const { authToken, apiGatewayUrl, organizationId } = useChannelContext();\n\n // Route may be /channels/connections/:connectionId (no channelId in URL).\n // Resolve channelId from getConnection when absent so downstream channel hooks work.\n const [resolvedChannelId, setResolvedChannelId] = useState<string | undefined>(params.channelId);\n const [resolveError, setResolveError] = useState<string | null>(null);\n\n useEffect(() => {\n if (resolvedChannelId || !connectionId) return;\n let cancelled = false;\n void (async () => {\n try {\n const client = getGlobalChannelClient(apiGatewayUrl, authToken, organizationId);\n const result = await client.query<GetConnectionQuery>({\n query: GetConnectionDocument,\n variables: { id: connectionId },\n fetchPolicy: 'network-only',\n });\n if (cancelled) return;\n const conn = result.data?.getConnection;\n if (conn?.channelId) setResolvedChannelId(conn.channelId);\n else setResolveError('Connection not found');\n } catch (err) {\n if (!cancelled)\n setResolveError(err instanceof Error ? err.message : 'Failed to resolve connection');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [connectionId, resolvedChannelId, apiGatewayUrl, authToken, organizationId]);\n\n const channelId = resolvedChannelId;\n const { channel, isLoading, error, runHealthCheck, deleteConnection } = useChannel(channelId);\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const [isDeleting, setIsDeleting] = useState(false);\n const [isRunningHealth, setIsRunningHealth] = useState(false);\n const [deleteConfirm, setDeleteConfirm] = useState(false);\n\n const connection = channel?.connection;\n\n // Run health check\n const handleRunHealthCheck = async () => {\n setIsRunningHealth(true);\n try {\n await runHealthCheck();\n } finally {\n setIsRunningHealth(false);\n }\n };\n\n // Delete connection\n const handleDelete = async () => {\n if (!connectionId) return;\n void nativeImpact('medium');\n setIsDeleting(true);\n try {\n // deleteConnection throws on failure; success is guaranteed if it returns.\n await deleteConnection(connectionId);\n void nativeNotify('success');\n navigate(`/channels/${channelId}`);\n } catch (err) {\n void nativeNotify('error');\n reportShellError(\n err,\n { module: 'channel', context: { action: 'Failed to delete connection' } },\n '[channel] Failed to delete connection'\n );\n } finally {\n setIsDeleting(false);\n }\n };\n\n if (isLoading || (!resolvedChannelId && !resolveError)) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 className=\"w-8 h-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (resolveError || error || !channel) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"w-12 h-12 text-destructive\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.channelNotFound', 'Channel not found')}\n </h1>\n <button onClick={() => navigate('../../list')} className=\"text-primary hover:underline\">\n {tr('channel.backToChannels', 'Back to channels')}\n </button>\n </div>\n );\n }\n\n if (!connection) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"w-12 h-12 text-muted-foreground\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.noConnectionFound', 'No connection found')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'channel.noConnectionConfigured',\n 'This channel does not have a connection configured.'\n )}\n </p>\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"text-primary hover:underline\"\n >\n {tr('channel.backToChannel', 'Back to channel')}\n </button>\n </div>\n );\n }\n\n const health = HEALTH_CONFIG[String(connection.isHealthy)] || HEALTH_CONFIG.false;\n const HealthIcon = health.icon;\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_CONNECTION_READ}>\n <div className=\"min-h-screen bg-background\">\n {/* Header */}\n <div className=\"border-b bg-card\">\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <ArrowLeft className=\"w-5 h-5\" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold\">\n {tr('channel.connectionDetails', 'Connection Details')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {channel.name} • {channel.platform}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_EXECUTE}>\n <button\n onClick={handleRunHealthCheck}\n disabled={isRunningHealth}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted transition-colors flex items-center gap-2\"\n >\n {isRunningHealth ? (\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"w-4 h-4\" />\n )}\n {tr('channel.runHealthCheck', 'Run Health Check')}\n </button>\n </PermissionGuard>\n <button\n onClick={() => navigate(`/channels/${channelId}/edit`)}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted transition-colors flex items-center gap-2\"\n >\n <Edit className=\"w-4 h-4\" />\n {tr('channel.editChannel', 'Edit Channel')}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"container mx-auto px-6 py-8 max-w-3xl space-y-6\">\n {/* Health Status */}\n <div className={`p-6 rounded-lg border ${health.bgColor}`}>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className={health.color}>\n <HealthIcon className=\"w-10 h-10\" />\n </div>\n <div>\n <h2 className=\"text-xl font-semibold\">{health.label}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {connection.isHealthy\n ? tr('channel.connectionWorking', 'Connection is working properly')\n : tr('channel.connectionNotWorking', 'Connection is not working properly')}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Connection Info */}\n <div className=\"border rounded-lg p-6 space-y-4\">\n <h3 className=\"font-semibold\">\n {tr('channel.connectionInformation', 'Connection Information')}\n </h3>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-muted-foreground\">Connection ID</p>\n <p className=\"font-mono text-sm\">{connection.id}</p>\n </div>\n\n <div>\n <p className=\"text-sm text-muted-foreground\">Auth Type</p>\n <p className=\"flex items-center gap-2\">\n <Shield className=\"w-4 h-4 text-muted-foreground\" />\n {connection.authType}\n </p>\n </div>\n\n <div>\n <p className=\"text-sm text-muted-foreground\">Status</p>\n <p className={connection.isActive ? 'text-green-500' : 'text-muted-foreground'}>\n {connection.isActive\n ? tr('channel.activeStatus', 'Active')\n : tr('channel.inactiveStatus', 'Inactive')}\n </p>\n </div>\n\n <div>\n <p className=\"text-sm text-muted-foreground\">Token Refresh</p>\n <p\n className={\n connection.needsTokenRefresh ? 'text-yellow-500' : 'text-muted-foreground'\n }\n >\n {connection.needsTokenRefresh\n ? tr('channel.tokenRefreshRequired', 'Required soon')\n : tr('channel.tokenRefreshNotNeeded', 'Not needed')}\n </p>\n </div>\n\n {connection.lastTestedAt && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Last Tested</p>\n <p className=\"flex items-center gap-2\">\n <Clock className=\"w-4 h-4 text-muted-foreground\" />\n {new Date(connection.lastTestedAt).toLocaleString()}\n </p>\n </div>\n )}\n\n {connection.daysUntilExpiry !== null && connection.daysUntilExpiry !== undefined && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Days Until Token Expiry</p>\n <p\n className={\n connection.daysUntilExpiry < 30 ? 'text-yellow-500' : 'text-muted-foreground'\n }\n >\n {connection.daysUntilExpiry} days\n </p>\n </div>\n )}\n </div>\n\n {connection.testStatus && (\n <div className=\"pt-4 border-t\">\n <p className=\"text-sm text-muted-foreground mb-2\">Last Test Status</p>\n <div className=\"p-3 rounded-lg bg-muted\">\n <p className=\"font-mono text-sm\">{connection.testStatus}</p>\n </div>\n </div>\n )}\n\n {connection.tagAssignments && connection.tagAssignments.length > 0 && (\n <div className=\"pt-4 border-t\">\n <p className=\"text-sm text-muted-foreground mb-2\">{tr('channel.tags', 'Tags')}</p>\n <div className=\"flex flex-wrap gap-1.5\" aria-label=\"Connection tags\">\n {connection.tagAssignments.map((a) => (\n <TagBadge key={a.id} id={a.tagId} label={a.tagId} size=\"md\" />\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"border rounded-lg p-6 space-y-4\">\n <h3 className=\"font-semibold\">{tr('channel.actions', 'Actions')}</h3>\n\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"font-medium\">{tr('channel.deleteConnection', 'Delete Connection')}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'channel.deleteConnectionWarning',\n 'Permanently remove this connection. The channel will become inactive.'\n )}\n </p>\n </div>\n\n {!deleteConfirm ? (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_CONNECTION_DELETE}>\n <button\n onClick={() => setDeleteConfirm(true)}\n className=\"px-4 py-2 rounded-lg text-destructive border border-destructive hover:bg-destructive/10 transition-colors flex items-center gap-2\"\n >\n <Trash2 className=\"w-4 h-4\" />\n {tr('channel.delete', 'Delete')}\n </button>\n </PermissionGuard>\n ) : (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">\n {tr('channel.confirmDelete', 'Confirm delete?')}\n </span>\n <button\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors flex items-center gap-2\"\n >\n {isDeleting ? (\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n ) : (\n <Trash2 className=\"w-4 h-4\" />\n )}\n {tr('channel.delete', 'Delete')}\n </button>\n <button\n onClick={() => setDeleteConfirm(false)}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted transition-colors\"\n >\n {tr('channel.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ConnectionDetailsPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/ConnectionDetailsPage.tsx"],"sourcesContent":["/**\n * Connection Details Page\n *\n * View and manage a specific connection within a channel.\n */\n\nimport { useEffect, useState } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { TagBadge } from '@burdenoff/fe-libs/tag';\nimport { reportShellError } from '../../../utils/shellBridge';\nimport { nativeImpact, nativeNotify } from '../../../../utils/nativeBridge';\nimport {\n ArrowLeft,\n Loader2,\n AlertCircle,\n CheckCircle2,\n XCircle,\n RefreshCw,\n Trash2,\n Edit,\n Shield,\n Clock,\n} from 'lucide-react';\nimport { useChannel } from '../../../hooks/useChannels';\nimport { useChannel as useChannelContext } from '../../../providers/ChannelProvider';\nimport { getGlobalChannelClient } from '../../../graphql/global-client';\nimport {\n GetConnectionDocument,\n type GetConnectionQuery,\n} from '../../../../generated/global-operations';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\n\nconst HEALTH_CONFIG: Record<\n string,\n { icon: typeof CheckCircle2; color: string; bgColor: string; label: string }\n> = {\n true: {\n icon: CheckCircle2,\n color: 'text-success-500',\n bgColor: 'bg-success-500/10',\n label: 'Healthy',\n },\n false: { icon: XCircle, color: 'text-error-500', bgColor: 'bg-error-500/10', label: 'Unhealthy' },\n};\n\nexport function ConnectionDetailsPage() {\n const navigate = useNavigate();\n const params = useParams<{ channelId?: string; connectionId: string }>();\n const { connectionId } = params;\n const { authToken, apiGatewayUrl, organizationId } = useChannelContext();\n\n // Route may be /channels/connections/:connectionId (no channelId in URL).\n // Resolve channelId from getConnection when absent so downstream channel hooks work.\n const [resolvedChannelId, setResolvedChannelId] = useState<string | undefined>(params.channelId);\n const [resolveError, setResolveError] = useState<string | null>(null);\n\n useEffect(() => {\n if (resolvedChannelId || !connectionId) return;\n let cancelled = false;\n void (async () => {\n try {\n const client = getGlobalChannelClient(apiGatewayUrl, authToken, organizationId);\n const result = await client.query<GetConnectionQuery>({\n query: GetConnectionDocument,\n variables: { id: connectionId },\n fetchPolicy: 'network-only',\n });\n if (cancelled) return;\n const conn = result.data?.getConnection;\n if (conn?.channelId) setResolvedChannelId(conn.channelId);\n else setResolveError('Connection not found');\n } catch (err) {\n if (!cancelled)\n setResolveError(err instanceof Error ? err.message : 'Failed to resolve connection');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [connectionId, resolvedChannelId, apiGatewayUrl, authToken, organizationId]);\n\n const channelId = resolvedChannelId;\n const { channel, isLoading, error, runHealthCheck, deleteConnection } = useChannel(channelId);\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const [isDeleting, setIsDeleting] = useState(false);\n const [isRunningHealth, setIsRunningHealth] = useState(false);\n const [deleteConfirm, setDeleteConfirm] = useState(false);\n\n const connection = channel?.connection;\n\n // Run health check\n const handleRunHealthCheck = async () => {\n setIsRunningHealth(true);\n try {\n await runHealthCheck();\n } finally {\n setIsRunningHealth(false);\n }\n };\n\n // Delete connection\n const handleDelete = async () => {\n if (!connectionId) return;\n void nativeImpact('medium');\n setIsDeleting(true);\n try {\n // deleteConnection throws on failure; success is guaranteed if it returns.\n await deleteConnection(connectionId);\n void nativeNotify('success');\n navigate(`/channels/${channelId}`);\n } catch (err) {\n void nativeNotify('error');\n reportShellError(\n err,\n { module: 'channel', context: { action: 'Failed to delete connection' } },\n '[channel] Failed to delete connection'\n );\n } finally {\n setIsDeleting(false);\n }\n };\n\n if (isLoading || (!resolvedChannelId && !resolveError)) {\n return (\n <div className=\"flex items-center justify-center min-h-screen\">\n <Loader2 className=\"w-8 h-8 animate-spin text-muted-foreground\" />\n </div>\n );\n }\n\n if (resolveError || error || !channel) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"w-12 h-12 text-destructive\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.channelNotFound', 'Channel not found')}\n </h1>\n <button onClick={() => navigate('../../list')} className=\"text-primary hover:underline\">\n {tr('channel.backToChannels', 'Back to channels')}\n </button>\n </div>\n );\n }\n\n if (!connection) {\n return (\n <div className=\"flex flex-col items-center justify-center min-h-screen gap-4\">\n <AlertCircle className=\"w-12 h-12 text-muted-foreground\" />\n <h1 className=\"text-xl font-semibold\">\n {tr('channel.noConnectionFound', 'No connection found')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'channel.noConnectionConfigured',\n 'This channel does not have a connection configured.'\n )}\n </p>\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"text-primary hover:underline\"\n >\n {tr('channel.backToChannel', 'Back to channel')}\n </button>\n </div>\n );\n }\n\n const health = HEALTH_CONFIG[String(connection.isHealthy)] || HEALTH_CONFIG.false;\n const HealthIcon = health.icon;\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_CONNECTION_READ}>\n <div className=\"min-h-screen bg-background\">\n {/* Header */}\n <div className=\"border-b bg-card\">\n <div className=\"container mx-auto px-6 py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <button\n onClick={() => navigate(`/channels/${channelId}`)}\n className=\"p-2 hover:bg-muted rounded-lg transition-colors\"\n >\n <ArrowLeft className=\"w-5 h-5\" />\n </button>\n <div>\n <h1 className=\"text-2xl font-bold\">\n {tr('channel.connectionDetails', 'Connection Details')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {channel.name} • {channel.platform}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_EXECUTE}>\n <button\n onClick={handleRunHealthCheck}\n disabled={isRunningHealth}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted transition-colors flex items-center gap-2\"\n >\n {isRunningHealth ? (\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n ) : (\n <RefreshCw className=\"w-4 h-4\" />\n )}\n {tr('channel.runHealthCheck', 'Run Health Check')}\n </button>\n </PermissionGuard>\n <button\n onClick={() => navigate(`/channels/${channelId}/edit`)}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted transition-colors flex items-center gap-2\"\n >\n <Edit className=\"w-4 h-4\" />\n {tr('channel.editChannel', 'Edit Channel')}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n {/* Content */}\n <div className=\"container mx-auto px-6 py-8 max-w-3xl space-y-6\">\n {/* Health Status */}\n <div className={`p-6 rounded-lg border ${health.bgColor}`}>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className={health.color}>\n <HealthIcon className=\"w-10 h-10\" />\n </div>\n <div>\n <h2 className=\"text-xl font-semibold\">{health.label}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {connection.isHealthy\n ? tr('channel.connectionWorking', 'Connection is working properly')\n : tr('channel.connectionNotWorking', 'Connection is not working properly')}\n </p>\n </div>\n </div>\n </div>\n </div>\n\n {/* Connection Info */}\n <div className=\"border rounded-lg p-6 space-y-4\">\n <h3 className=\"font-semibold\">\n {tr('channel.connectionInformation', 'Connection Information')}\n </h3>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-muted-foreground\">Connection ID</p>\n <p className=\"font-mono text-sm\">{connection.id}</p>\n </div>\n\n <div>\n <p className=\"text-sm text-muted-foreground\">Auth Type</p>\n <p className=\"flex items-center gap-2\">\n <Shield className=\"w-4 h-4 text-muted-foreground\" />\n {connection.authType}\n </p>\n </div>\n\n <div>\n <p className=\"text-sm text-muted-foreground\">Status</p>\n <p className={connection.isActive ? 'text-success-500' : 'text-muted-foreground'}>\n {connection.isActive\n ? tr('channel.activeStatus', 'Active')\n : tr('channel.inactiveStatus', 'Inactive')}\n </p>\n </div>\n\n <div>\n <p className=\"text-sm text-muted-foreground\">Token Refresh</p>\n <p\n className={\n connection.needsTokenRefresh ? 'text-warning-500' : 'text-muted-foreground'\n }\n >\n {connection.needsTokenRefresh\n ? tr('channel.tokenRefreshRequired', 'Required soon')\n : tr('channel.tokenRefreshNotNeeded', 'Not needed')}\n </p>\n </div>\n\n {connection.lastTestedAt && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Last Tested</p>\n <p className=\"flex items-center gap-2\">\n <Clock className=\"w-4 h-4 text-muted-foreground\" />\n {new Date(connection.lastTestedAt).toLocaleString()}\n </p>\n </div>\n )}\n\n {connection.daysUntilExpiry !== null && connection.daysUntilExpiry !== undefined && (\n <div>\n <p className=\"text-sm text-muted-foreground\">Days Until Token Expiry</p>\n <p\n className={\n connection.daysUntilExpiry < 30 ? 'text-warning-500' : 'text-muted-foreground'\n }\n >\n {connection.daysUntilExpiry} days\n </p>\n </div>\n )}\n </div>\n\n {connection.testStatus && (\n <div className=\"pt-4 border-t\">\n <p className=\"text-sm text-muted-foreground mb-2\">Last Test Status</p>\n <div className=\"p-3 rounded-lg bg-muted\">\n <p className=\"font-mono text-sm\">{connection.testStatus}</p>\n </div>\n </div>\n )}\n\n {connection.tagAssignments && connection.tagAssignments.length > 0 && (\n <div className=\"pt-4 border-t\">\n <p className=\"text-sm text-muted-foreground mb-2\">{tr('channel.tags', 'Tags')}</p>\n <div className=\"flex flex-wrap gap-1.5\" aria-label=\"Connection tags\">\n {connection.tagAssignments.map((a) => (\n <TagBadge key={a.id} id={a.tagId} label={a.tagId} size=\"md\" />\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"border rounded-lg p-6 space-y-4\">\n <h3 className=\"font-semibold\">{tr('channel.actions', 'Actions')}</h3>\n\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"font-medium\">{tr('channel.deleteConnection', 'Delete Connection')}</p>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\n 'channel.deleteConnectionWarning',\n 'Permanently remove this connection. The channel will become inactive.'\n )}\n </p>\n </div>\n\n {!deleteConfirm ? (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_CONNECTION_DELETE}>\n <button\n onClick={() => setDeleteConfirm(true)}\n className=\"px-4 py-2 rounded-lg text-destructive border border-destructive hover:bg-destructive/10 transition-colors flex items-center gap-2\"\n >\n <Trash2 className=\"w-4 h-4\" />\n {tr('channel.delete', 'Delete')}\n </button>\n </PermissionGuard>\n ) : (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">\n {tr('channel.confirmDelete', 'Confirm delete?')}\n </span>\n <button\n onClick={handleDelete}\n disabled={isDeleting}\n className=\"px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors flex items-center gap-2\"\n >\n {isDeleting ? (\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n ) : (\n <Trash2 className=\"w-4 h-4\" />\n )}\n {tr('channel.delete', 'Delete')}\n </button>\n <button\n onClick={() => setDeleteConfirm(false)}\n className=\"px-4 py-2 rounded-lg border hover:bg-muted transition-colors\"\n >\n {tr('channel.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n </div>\n </div>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ConnectionsListPage.d.ts","sourceRoot":"","sources":["../../../../../src/channel/modules/channels/pages/ConnectionsListPage.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AA+BH,wBAAgB,mBAAmB,4CA2RlC"}
1
+ {"version":3,"file":"ConnectionsListPage.d.ts","sourceRoot":"","sources":["../../../../../src/channel/modules/channels/pages/ConnectionsListPage.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,wBAAgB,mBAAmB,4CAyRlC"}
@@ -1,42 +1,37 @@
1
- import { useChannel as e } from "../../../providers/ChannelProvider.js";
2
- import { CONNECTION_STATUS_CHANGED_SUBSCRIPTION as t, useChannelSubscription as n } from "../../../hooks/useChannelSubscription.js";
3
- import { useChannels as r } from "../../../hooks/useChannels.js";
4
- import { PermissionGuard as i } from "../../../components/PermissionGuard.js";
5
- import { CHANNEL_PERMISSIONS as a } from "../../../constants/permissions.js";
6
- import { useState as o } from "react";
7
- import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
8
- import { AlertCircle as c, ArrowLeft as l, CheckCircle2 as u, Link as d, Loader2 as f, Plus as p, RefreshCw as m, Settings as h, XCircle as g } from "lucide-react";
9
- import { useNavigate as _ } from "react-router-dom";
10
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
11
- import { TagBadge as b } from "@burdenoff/fe-libs/tag";
1
+ import { useChannels as e } from "../../../hooks/useChannels.js";
2
+ import { PermissionGuard as t } from "../../../components/PermissionGuard.js";
3
+ import { CHANNEL_PERMISSIONS as n } from "../../../constants/permissions.js";
4
+ import { useEffect as r, useState as i } from "react";
5
+ import { useI18n as a } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
+ import { AlertCircle as o, ArrowLeft as s, CheckCircle2 as c, Link as l, Loader2 as u, Plus as d, RefreshCw as f, Settings as p, XCircle as m } from "lucide-react";
7
+ import { useNavigate as h } from "react-router-dom";
8
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
9
+ import { TagBadge as v } from "@burdenoff/fe-libs/tag";
12
10
  //#region src/channel/modules/channels/pages/ConnectionsListPage.tsx
13
- var x = {
11
+ var y = {
14
12
  true: {
15
- icon: u,
16
- color: "text-green-500",
13
+ icon: c,
14
+ color: "text-success-500",
17
15
  label: "Healthy"
18
16
  },
19
17
  false: {
20
- icon: g,
21
- color: "text-red-500",
18
+ icon: m,
19
+ color: "text-error-500",
22
20
  label: "Unhealthy"
23
21
  }
24
22
  };
25
- function S() {
26
- let u = _(), { channels: g, isLoading: S, error: C, refetch: w } = r(), { organizationId: T } = e();
27
- n({
28
- query: t,
29
- variables: { organizationId: T },
30
- operationName: "ConnectionStatusChanged",
31
- enabled: !!T,
32
- onData: () => void w(),
33
- pollFn: w,
34
- pollIntervalMs: 6e4
35
- });
36
- let { t: E } = s(), D = (e, t) => {
37
- let n = E(e);
23
+ function b() {
24
+ let c = h(), { channels: m, isLoading: b, error: x, refetch: S } = e();
25
+ r(() => {
26
+ let e = setInterval(() => {
27
+ S();
28
+ }, 6e4);
29
+ return () => clearInterval(e);
30
+ }, [S]);
31
+ let { t: C } = a(), w = (e, t) => {
32
+ let n = C(e);
38
33
  return n === e ? t : n;
39
- }, [O, k] = o("all"), [A, j] = o("all"), M = g.filter((e) => e.connection).map((e) => ({
34
+ }, [T, E] = i("all"), [D, O] = i("all"), k = m.filter((e) => e.connection).map((e) => ({
40
35
  channelId: e.id,
41
36
  channelName: e.name,
42
37
  platform: e.platform,
@@ -49,153 +44,161 @@ function S() {
49
44
  lastTestedAt: e.connection.lastTestedAt,
50
45
  authType: e.connection.authType,
51
46
  tagAssignments: e.connection.tagAssignments ?? []
52
- })), N = [...new Set(M.map((e) => e.platform))], P = M.filter((e) => !(O === "healthy" && !e.isHealthy || O === "unhealthy" && e.isHealthy || A !== "all" && e.platform !== A));
53
- return S ? /* @__PURE__ */ v("div", {
47
+ })), A = [...new Set(k.map((e) => e.platform))], j = k.filter((e) => !(T === "healthy" && !e.isHealthy || T === "unhealthy" && e.isHealthy || D !== "all" && e.platform !== D));
48
+ return b ? /* @__PURE__ */ g("div", {
54
49
  className: "flex items-center justify-center min-h-screen",
55
- children: /* @__PURE__ */ v(f, { className: "w-8 h-8 animate-spin text-muted-foreground" })
56
- }) : C ? /* @__PURE__ */ y("div", {
50
+ children: /* @__PURE__ */ g(u, { className: "w-8 h-8 animate-spin text-muted-foreground" })
51
+ }) : x ? /* @__PURE__ */ _("div", {
57
52
  className: "flex flex-col items-center justify-center min-h-screen gap-4",
58
53
  children: [
59
- /* @__PURE__ */ v(c, { className: "w-12 h-12 text-destructive" }),
60
- /* @__PURE__ */ v("h1", {
54
+ /* @__PURE__ */ g(o, { className: "w-12 h-12 text-destructive" }),
55
+ /* @__PURE__ */ g("h1", {
61
56
  className: "text-xl font-semibold",
62
- children: D("channel.loadConnectionsFailed", "Failed to load connections")
57
+ children: w("channel.loadConnectionsFailed", "Failed to load connections")
63
58
  }),
64
- /* @__PURE__ */ v("p", {
59
+ /* @__PURE__ */ g("p", {
65
60
  className: "text-sm text-muted-foreground",
66
- children: C
61
+ children: x
67
62
  }),
68
- /* @__PURE__ */ v("button", {
69
- onClick: () => w(),
63
+ /* @__PURE__ */ g("button", {
64
+ onClick: () => S(),
70
65
  className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90",
71
- children: D("channel.retry", "Retry")
66
+ children: w("channel.retry", "Retry")
72
67
  })
73
68
  ]
74
- }) : /* @__PURE__ */ v(i, {
75
- permission: a.CHANNEL_CONNECTION_READ,
76
- children: /* @__PURE__ */ y("div", {
69
+ }) : /* @__PURE__ */ g(t, {
70
+ permission: n.CHANNEL_CONNECTION_READ,
71
+ children: /* @__PURE__ */ _("div", {
77
72
  className: "min-h-screen bg-background",
78
73
  children: [
79
- /* @__PURE__ */ v("div", {
74
+ /* @__PURE__ */ g("div", {
80
75
  className: "border-b bg-card",
81
- children: /* @__PURE__ */ v("div", {
76
+ children: /* @__PURE__ */ g("div", {
82
77
  className: "container mx-auto px-6 py-4",
83
- children: /* @__PURE__ */ y("div", {
78
+ children: /* @__PURE__ */ _("div", {
84
79
  className: "flex items-center justify-between",
85
- children: [/* @__PURE__ */ y("div", {
80
+ children: [/* @__PURE__ */ _("div", {
86
81
  className: "flex items-center gap-4",
87
- children: [/* @__PURE__ */ v("button", {
88
- onClick: () => u("./list"),
82
+ children: [/* @__PURE__ */ g("button", {
83
+ onClick: () => c("./list"),
84
+ "aria-label": w("channel.backToChannels", "Back to channels"),
89
85
  className: "p-2 hover:bg-muted rounded-lg transition-colors",
90
- children: /* @__PURE__ */ v(l, { className: "w-5 h-5" })
91
- }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h1", {
86
+ children: /* @__PURE__ */ g(s, { className: "w-5 h-5" })
87
+ }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("h1", {
92
88
  className: "text-2xl font-bold",
93
- children: D("channel.connections", "Connections")
94
- }), /* @__PURE__ */ y("p", {
89
+ children: w("channel.connections", "Connections")
90
+ }), /* @__PURE__ */ _("p", {
95
91
  className: "text-sm text-muted-foreground",
96
92
  children: [
97
- P.length,
93
+ j.length,
98
94
  " connection",
99
- P.length === 1 ? "" : "s"
95
+ j.length === 1 ? "" : "s"
100
96
  ]
101
97
  })] })]
102
- }), /* @__PURE__ */ y("button", {
103
- onClick: () => u("./create"),
98
+ }), /* @__PURE__ */ _("button", {
99
+ onClick: () => c("./create"),
104
100
  className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors flex items-center gap-2",
105
- children: [/* @__PURE__ */ v(p, { className: "w-4 h-4" }), D("channel.newChannel", "New Channel")]
101
+ children: [/* @__PURE__ */ g(d, { className: "w-4 h-4" }), w("channel.newChannel", "New Channel")]
106
102
  })]
107
103
  })
108
104
  })
109
105
  }),
110
- /* @__PURE__ */ v("div", {
106
+ /* @__PURE__ */ g("div", {
111
107
  className: "container mx-auto px-6 py-4",
112
- children: /* @__PURE__ */ y("div", {
108
+ children: /* @__PURE__ */ _("div", {
113
109
  className: "flex items-center gap-4",
114
110
  children: [
115
- /* @__PURE__ */ y("select", {
116
- value: A,
117
- onChange: (e) => j(e.target.value),
111
+ /* @__PURE__ */ _("select", {
112
+ value: D,
113
+ onChange: (e) => O(e.target.value),
118
114
  className: "px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary",
119
- children: [/* @__PURE__ */ v("option", {
115
+ children: [/* @__PURE__ */ g("option", {
120
116
  value: "all",
121
- children: D("channel.allPlatforms", "All Platforms")
122
- }), N.map((e) => /* @__PURE__ */ v("option", {
117
+ children: w("channel.allPlatforms", "All Platforms")
118
+ }), A.map((e) => /* @__PURE__ */ g("option", {
123
119
  value: e,
124
120
  children: e
125
121
  }, e))]
126
122
  }),
127
- /* @__PURE__ */ y("select", {
128
- value: O,
129
- onChange: (e) => k(e.target.value),
123
+ /* @__PURE__ */ _("select", {
124
+ value: T,
125
+ onChange: (e) => E(e.target.value),
130
126
  className: "px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary",
131
127
  children: [
132
- /* @__PURE__ */ v("option", {
128
+ /* @__PURE__ */ g("option", {
133
129
  value: "all",
134
- children: D("channel.allStatus", "All Status")
130
+ children: w("channel.allStatus", "All Status")
135
131
  }),
136
- /* @__PURE__ */ v("option", {
132
+ /* @__PURE__ */ g("option", {
137
133
  value: "healthy",
138
- children: D("channel.healthy", "Healthy")
134
+ children: w("channel.healthy", "Healthy")
139
135
  }),
140
- /* @__PURE__ */ v("option", {
136
+ /* @__PURE__ */ g("option", {
141
137
  value: "unhealthy",
142
- children: D("channel.unhealthy", "Unhealthy")
138
+ children: w("channel.unhealthy", "Unhealthy")
143
139
  })
144
140
  ]
145
141
  }),
146
- /* @__PURE__ */ v("button", {
147
- onClick: () => w(),
142
+ /* @__PURE__ */ g("button", {
143
+ onClick: () => S(),
144
+ "aria-label": w("channel.refresh", "Refresh"),
148
145
  className: "p-2 hover:bg-muted rounded-lg transition-colors",
149
- title: D("channel.refresh", "Refresh"),
150
- children: /* @__PURE__ */ v(m, { className: "w-5 h-5" })
146
+ children: /* @__PURE__ */ g(f, {
147
+ className: "w-5 h-5",
148
+ "aria-hidden": "true"
149
+ })
151
150
  })
152
151
  ]
153
152
  })
154
153
  }),
155
- /* @__PURE__ */ v("div", {
154
+ /* @__PURE__ */ g("div", {
156
155
  className: "container mx-auto px-6 pb-8",
157
- children: P.length === 0 ? /* @__PURE__ */ y("div", {
156
+ children: j.length === 0 ? /* @__PURE__ */ _("div", {
158
157
  className: "text-center py-12",
159
158
  children: [
160
- /* @__PURE__ */ v(d, { className: "w-12 h-12 mx-auto text-muted-foreground mb-4" }),
161
- /* @__PURE__ */ v("h2", {
159
+ /* @__PURE__ */ g(l, { className: "w-12 h-12 mx-auto text-muted-foreground mb-4" }),
160
+ /* @__PURE__ */ g("h2", {
162
161
  className: "text-lg font-semibold mb-2",
163
- children: D("channel.noConnectionsFound", "No connections found")
162
+ children: w("channel.noConnectionsFound", "No connections found")
164
163
  }),
165
- /* @__PURE__ */ v("p", {
164
+ /* @__PURE__ */ g("p", {
166
165
  className: "text-sm text-muted-foreground mb-4",
167
- children: g.length === 0 ? D("channel.createChannelFirst", "Create a channel first to add connections") : D("channel.noConnectionsMatchFilter", "No connections match your filters")
166
+ children: m.length === 0 ? w("channel.createChannelFirst", "Create a channel first to add connections") : w("channel.noConnectionsMatchFilter", "No connections match your filters")
168
167
  }),
169
- g.length === 0 ? /* @__PURE__ */ v("button", {
170
- onClick: () => u("./create"),
168
+ m.length === 0 ? /* @__PURE__ */ g("button", {
169
+ onClick: () => c("./create"),
171
170
  className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90",
172
- children: D("channel.createChannel", "Create Channel")
173
- }) : /* @__PURE__ */ v("button", {
171
+ children: w("channel.createChannel", "Create Channel")
172
+ }) : /* @__PURE__ */ g("button", {
174
173
  onClick: () => {
175
- k("all"), j("all");
174
+ E("all"), O("all");
176
175
  },
177
176
  className: "px-4 py-2 rounded-lg border hover:bg-muted",
178
- children: D("channel.clearFilters", "Clear Filters")
177
+ children: w("channel.clearFilters", "Clear Filters")
179
178
  })
180
179
  ]
181
- }) : /* @__PURE__ */ v("div", {
180
+ }) : /* @__PURE__ */ g("div", {
182
181
  className: "border rounded-lg divide-y",
183
- children: P.map((e) => {
184
- let t = x[String(e.isHealthy)] || x.false, n = t.icon;
185
- return /* @__PURE__ */ v("div", {
182
+ children: j.map((e) => {
183
+ let t = y[String(e.isHealthy)] || y.false, n = t.icon;
184
+ return /* @__PURE__ */ g("div", {
186
185
  className: "p-4 hover:bg-muted/50 transition-colors cursor-pointer",
187
- onClick: () => u(`./${e.channelId}`),
188
- children: /* @__PURE__ */ y("div", {
186
+ onClick: () => c(`./${e.channelId}`),
187
+ children: /* @__PURE__ */ _("div", {
189
188
  className: "flex items-center justify-between",
190
- children: [/* @__PURE__ */ y("div", {
189
+ children: [/* @__PURE__ */ _("div", {
191
190
  className: "flex items-center gap-4",
192
- children: [/* @__PURE__ */ v("div", {
191
+ children: [/* @__PURE__ */ g("div", {
193
192
  className: t.color,
194
- children: /* @__PURE__ */ v(n, { className: "w-5 h-5" })
195
- }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
193
+ "aria-label": t.label,
194
+ children: /* @__PURE__ */ g(n, {
195
+ className: "w-5 h-5",
196
+ "aria-hidden": "true"
197
+ })
198
+ }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("p", {
196
199
  className: "font-medium",
197
200
  children: e.channelName
198
- }), /* @__PURE__ */ y("p", {
201
+ }), /* @__PURE__ */ _("p", {
199
202
  className: "text-sm text-muted-foreground",
200
203
  children: [
201
204
  e.platform,
@@ -205,59 +208,60 @@ function S() {
205
208
  e.authType
206
209
  ]
207
210
  })] })]
208
- }), /* @__PURE__ */ y("div", {
211
+ }), /* @__PURE__ */ _("div", {
209
212
  className: "flex items-center gap-4",
210
213
  children: [
211
- /* @__PURE__ */ y("div", {
214
+ /* @__PURE__ */ _("div", {
212
215
  className: "text-right",
213
- children: [/* @__PURE__ */ v("p", {
216
+ children: [/* @__PURE__ */ g("p", {
214
217
  className: "text-sm",
215
- children: e.channelStatus === "ACTIVE" ? /* @__PURE__ */ v("span", {
216
- className: "text-green-500",
217
- children: D("channel.activeStatus", "Active")
218
- }) : e.channelStatus === "INACTIVE" ? /* @__PURE__ */ v("span", {
218
+ children: e.channelStatus === "ACTIVE" ? /* @__PURE__ */ g("span", {
219
+ className: "text-success-500",
220
+ children: w("channel.activeStatus", "Active")
221
+ }) : e.channelStatus === "INACTIVE" ? /* @__PURE__ */ g("span", {
219
222
  className: "text-muted-foreground",
220
- children: D("channel.inactiveStatus", "Inactive")
221
- }) : e.channelStatus === "ERROR" ? /* @__PURE__ */ v("span", {
222
- className: "text-red-500",
223
- children: D("channel.errorStatus", "Error")
224
- }) : e.channelStatus === "SUSPENDED" ? /* @__PURE__ */ v("span", {
225
- className: "text-yellow-500",
226
- children: D("channel.suspendedStatus", "Suspended")
227
- }) : e.channelStatus === "ARCHIVED" ? /* @__PURE__ */ v("span", {
223
+ children: w("channel.inactiveStatus", "Inactive")
224
+ }) : e.channelStatus === "ERROR" ? /* @__PURE__ */ g("span", {
225
+ className: "text-error-500",
226
+ children: w("channel.errorStatus", "Error")
227
+ }) : e.channelStatus === "SUSPENDED" ? /* @__PURE__ */ g("span", {
228
+ className: "text-warning-500",
229
+ children: w("channel.suspendedStatus", "Suspended")
230
+ }) : e.channelStatus === "ARCHIVED" ? /* @__PURE__ */ g("span", {
228
231
  className: "text-muted-foreground",
229
- children: D("channel.archivedStatus", "Archived")
230
- }) : /* @__PURE__ */ v("span", {
232
+ children: w("channel.archivedStatus", "Archived")
233
+ }) : /* @__PURE__ */ g("span", {
231
234
  className: "text-muted-foreground",
232
- children: D("channel.inactiveStatus", "Inactive")
235
+ children: w("channel.inactiveStatus", "Inactive")
233
236
  })
234
- }), e.lastTestedAt && /* @__PURE__ */ y("p", {
237
+ }), e.lastTestedAt && /* @__PURE__ */ _("p", {
235
238
  className: "text-xs text-muted-foreground",
236
239
  children: ["Last tested: ", new Date(e.lastTestedAt).toLocaleDateString()]
237
240
  })]
238
241
  }),
239
- e.needsTokenRefresh && /* @__PURE__ */ v("span", {
240
- className: "px-2 py-1 text-xs bg-yellow-500/10 text-yellow-500 rounded",
242
+ e.needsTokenRefresh && /* @__PURE__ */ g("span", {
243
+ className: "px-2 py-1 text-xs bg-warning-500/10 text-warning-500 rounded",
241
244
  children: "Token Expires"
242
245
  }),
243
- e.tagAssignments.length > 0 && /* @__PURE__ */ y("div", {
246
+ e.tagAssignments.length > 0 && /* @__PURE__ */ _("div", {
244
247
  className: "flex flex-wrap gap-1",
245
248
  "aria-label": "Connection tags",
246
- children: [e.tagAssignments.slice(0, 3).map((e) => /* @__PURE__ */ v(b, {
249
+ children: [e.tagAssignments.slice(0, 3).map((e) => /* @__PURE__ */ g(v, {
247
250
  id: e.tagId,
248
251
  label: e.tagId,
249
252
  size: "sm"
250
- }, e.id)), e.tagAssignments.length > 3 && /* @__PURE__ */ y("span", {
253
+ }, e.id)), e.tagAssignments.length > 3 && /* @__PURE__ */ _("span", {
251
254
  className: "text-xs text-muted-foreground",
252
255
  children: ["+", e.tagAssignments.length - 3]
253
256
  })]
254
257
  }),
255
- /* @__PURE__ */ v("button", {
258
+ /* @__PURE__ */ g("button", {
256
259
  onClick: (t) => {
257
- t.stopPropagation(), u(`/channels/${e.channelId}`);
260
+ t.stopPropagation(), c(`/channels/${e.channelId}`);
258
261
  },
262
+ "aria-label": w("channel.viewChannelSettings", "View channel settings"),
259
263
  className: "p-2 hover:bg-muted rounded-lg transition-colors",
260
- children: /* @__PURE__ */ v(h, { className: "w-4 h-4" })
264
+ children: /* @__PURE__ */ g(p, { className: "w-4 h-4" })
261
265
  })
262
266
  ]
263
267
  })]
@@ -271,6 +275,6 @@ function S() {
271
275
  });
272
276
  }
273
277
  //#endregion
274
- export { S as ConnectionsListPage };
278
+ export { b as ConnectionsListPage };
275
279
 
276
280
  //# sourceMappingURL=ConnectionsListPage.js.map