@burdenoff/microfe-channel 2026.513.2 → 2026.514.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/channel/ChannelRoot.js +1 -1
- package/dist/channel/ChannelRoot.js.map +1 -1
- package/dist/channel/hooks/useChannelSubscription.d.ts +4 -4
- package/dist/channel/hooks/useChannelSubscription.d.ts.map +1 -1
- package/dist/channel/hooks/useChannelSubscription.js +2 -2
- package/dist/channel/hooks/useChannelSubscription.js.map +1 -1
- package/dist/channel/hooks/useChannels.d.ts.map +1 -1
- package/dist/channel/hooks/useChannels.js +130 -124
- package/dist/channel/hooks/useChannels.js.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +5 -5
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ChannelUsersPage.js +25 -7
- package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +7 -7
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/ConnectionsListPage.js +137 -133
- package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +162 -158
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/EditChannelPage.js +5 -5
- package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -1
- package/dist/channel/modules/channels/pages/SendMessagePage.js +2 -2
- package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -1
- package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts.map +1 -1
- package/dist/channel/modules/channels/pages/WebhookEventsPage.js +11 -3
- package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -1
- package/dist/translations/en.d.ts +260 -0
- package/dist/translations/en.d.ts.map +1 -0
- 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;
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
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
|
|
11
|
+
var y = {
|
|
14
12
|
true: {
|
|
15
|
-
icon:
|
|
16
|
-
color: "text-
|
|
13
|
+
icon: c,
|
|
14
|
+
color: "text-success-500",
|
|
17
15
|
label: "Healthy"
|
|
18
16
|
},
|
|
19
17
|
false: {
|
|
20
|
-
icon:
|
|
21
|
-
color: "text-
|
|
18
|
+
icon: m,
|
|
19
|
+
color: "text-error-500",
|
|
22
20
|
label: "Unhealthy"
|
|
23
21
|
}
|
|
24
22
|
};
|
|
25
|
-
function
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
}, [
|
|
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
|
-
})),
|
|
53
|
-
return
|
|
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__ */
|
|
56
|
-
}) :
|
|
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__ */
|
|
60
|
-
/* @__PURE__ */
|
|
54
|
+
/* @__PURE__ */ g(o, { className: "w-12 h-12 text-destructive" }),
|
|
55
|
+
/* @__PURE__ */ g("h1", {
|
|
61
56
|
className: "text-xl font-semibold",
|
|
62
|
-
children:
|
|
57
|
+
children: w("channel.loadConnectionsFailed", "Failed to load connections")
|
|
63
58
|
}),
|
|
64
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ g("p", {
|
|
65
60
|
className: "text-sm text-muted-foreground",
|
|
66
|
-
children:
|
|
61
|
+
children: x
|
|
67
62
|
}),
|
|
68
|
-
/* @__PURE__ */
|
|
69
|
-
onClick: () =>
|
|
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:
|
|
66
|
+
children: w("channel.retry", "Retry")
|
|
72
67
|
})
|
|
73
68
|
]
|
|
74
|
-
}) : /* @__PURE__ */
|
|
75
|
-
permission:
|
|
76
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
74
|
+
/* @__PURE__ */ g("div", {
|
|
80
75
|
className: "border-b bg-card",
|
|
81
|
-
children: /* @__PURE__ */
|
|
76
|
+
children: /* @__PURE__ */ g("div", {
|
|
82
77
|
className: "container mx-auto px-6 py-4",
|
|
83
|
-
children: /* @__PURE__ */
|
|
78
|
+
children: /* @__PURE__ */ _("div", {
|
|
84
79
|
className: "flex items-center justify-between",
|
|
85
|
-
children: [/* @__PURE__ */
|
|
80
|
+
children: [/* @__PURE__ */ _("div", {
|
|
86
81
|
className: "flex items-center gap-4",
|
|
87
|
-
children: [/* @__PURE__ */
|
|
88
|
-
onClick: () =>
|
|
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__ */
|
|
91
|
-
}), /* @__PURE__ */
|
|
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:
|
|
94
|
-
}), /* @__PURE__ */
|
|
89
|
+
children: w("channel.connections", "Connections")
|
|
90
|
+
}), /* @__PURE__ */ _("p", {
|
|
95
91
|
className: "text-sm text-muted-foreground",
|
|
96
92
|
children: [
|
|
97
|
-
|
|
93
|
+
j.length,
|
|
98
94
|
" connection",
|
|
99
|
-
|
|
95
|
+
j.length === 1 ? "" : "s"
|
|
100
96
|
]
|
|
101
97
|
})] })]
|
|
102
|
-
}), /* @__PURE__ */
|
|
103
|
-
onClick: () =>
|
|
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__ */
|
|
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__ */
|
|
106
|
+
/* @__PURE__ */ g("div", {
|
|
111
107
|
className: "container mx-auto px-6 py-4",
|
|
112
|
-
children: /* @__PURE__ */
|
|
108
|
+
children: /* @__PURE__ */ _("div", {
|
|
113
109
|
className: "flex items-center gap-4",
|
|
114
110
|
children: [
|
|
115
|
-
/* @__PURE__ */
|
|
116
|
-
value:
|
|
117
|
-
onChange: (e) =>
|
|
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__ */
|
|
115
|
+
children: [/* @__PURE__ */ g("option", {
|
|
120
116
|
value: "all",
|
|
121
|
-
children:
|
|
122
|
-
}),
|
|
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__ */
|
|
128
|
-
value:
|
|
129
|
-
onChange: (e) =>
|
|
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__ */
|
|
128
|
+
/* @__PURE__ */ g("option", {
|
|
133
129
|
value: "all",
|
|
134
|
-
children:
|
|
130
|
+
children: w("channel.allStatus", "All Status")
|
|
135
131
|
}),
|
|
136
|
-
/* @__PURE__ */
|
|
132
|
+
/* @__PURE__ */ g("option", {
|
|
137
133
|
value: "healthy",
|
|
138
|
-
children:
|
|
134
|
+
children: w("channel.healthy", "Healthy")
|
|
139
135
|
}),
|
|
140
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ g("option", {
|
|
141
137
|
value: "unhealthy",
|
|
142
|
-
children:
|
|
138
|
+
children: w("channel.unhealthy", "Unhealthy")
|
|
143
139
|
})
|
|
144
140
|
]
|
|
145
141
|
}),
|
|
146
|
-
/* @__PURE__ */
|
|
147
|
-
onClick: () =>
|
|
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
|
-
|
|
150
|
-
|
|
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__ */
|
|
154
|
+
/* @__PURE__ */ g("div", {
|
|
156
155
|
className: "container mx-auto px-6 pb-8",
|
|
157
|
-
children:
|
|
156
|
+
children: j.length === 0 ? /* @__PURE__ */ _("div", {
|
|
158
157
|
className: "text-center py-12",
|
|
159
158
|
children: [
|
|
160
|
-
/* @__PURE__ */
|
|
161
|
-
/* @__PURE__ */
|
|
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:
|
|
162
|
+
children: w("channel.noConnectionsFound", "No connections found")
|
|
164
163
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
164
|
+
/* @__PURE__ */ g("p", {
|
|
166
165
|
className: "text-sm text-muted-foreground mb-4",
|
|
167
|
-
children:
|
|
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
|
-
|
|
170
|
-
onClick: () =>
|
|
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:
|
|
173
|
-
}) : /* @__PURE__ */
|
|
171
|
+
children: w("channel.createChannel", "Create Channel")
|
|
172
|
+
}) : /* @__PURE__ */ g("button", {
|
|
174
173
|
onClick: () => {
|
|
175
|
-
|
|
174
|
+
E("all"), O("all");
|
|
176
175
|
},
|
|
177
176
|
className: "px-4 py-2 rounded-lg border hover:bg-muted",
|
|
178
|
-
children:
|
|
177
|
+
children: w("channel.clearFilters", "Clear Filters")
|
|
179
178
|
})
|
|
180
179
|
]
|
|
181
|
-
}) : /* @__PURE__ */
|
|
180
|
+
}) : /* @__PURE__ */ g("div", {
|
|
182
181
|
className: "border rounded-lg divide-y",
|
|
183
|
-
children:
|
|
184
|
-
let t =
|
|
185
|
-
return /* @__PURE__ */
|
|
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: () =>
|
|
188
|
-
children: /* @__PURE__ */
|
|
186
|
+
onClick: () => c(`./${e.channelId}`),
|
|
187
|
+
children: /* @__PURE__ */ _("div", {
|
|
189
188
|
className: "flex items-center justify-between",
|
|
190
|
-
children: [/* @__PURE__ */
|
|
189
|
+
children: [/* @__PURE__ */ _("div", {
|
|
191
190
|
className: "flex items-center gap-4",
|
|
192
|
-
children: [/* @__PURE__ */
|
|
191
|
+
children: [/* @__PURE__ */ g("div", {
|
|
193
192
|
className: t.color,
|
|
194
|
-
|
|
195
|
-
|
|
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__ */
|
|
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__ */
|
|
211
|
+
}), /* @__PURE__ */ _("div", {
|
|
209
212
|
className: "flex items-center gap-4",
|
|
210
213
|
children: [
|
|
211
|
-
/* @__PURE__ */
|
|
214
|
+
/* @__PURE__ */ _("div", {
|
|
212
215
|
className: "text-right",
|
|
213
|
-
children: [/* @__PURE__ */
|
|
216
|
+
children: [/* @__PURE__ */ g("p", {
|
|
214
217
|
className: "text-sm",
|
|
215
|
-
children: e.channelStatus === "ACTIVE" ? /* @__PURE__ */
|
|
216
|
-
className: "text-
|
|
217
|
-
children:
|
|
218
|
-
}) : e.channelStatus === "INACTIVE" ? /* @__PURE__ */
|
|
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:
|
|
221
|
-
}) : e.channelStatus === "ERROR" ? /* @__PURE__ */
|
|
222
|
-
className: "text-
|
|
223
|
-
children:
|
|
224
|
-
}) : e.channelStatus === "SUSPENDED" ? /* @__PURE__ */
|
|
225
|
-
className: "text-
|
|
226
|
-
children:
|
|
227
|
-
}) : e.channelStatus === "ARCHIVED" ? /* @__PURE__ */
|
|
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:
|
|
230
|
-
}) : /* @__PURE__ */
|
|
232
|
+
children: w("channel.archivedStatus", "Archived")
|
|
233
|
+
}) : /* @__PURE__ */ g("span", {
|
|
231
234
|
className: "text-muted-foreground",
|
|
232
|
-
children:
|
|
235
|
+
children: w("channel.inactiveStatus", "Inactive")
|
|
233
236
|
})
|
|
234
|
-
}), e.lastTestedAt && /* @__PURE__ */
|
|
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__ */
|
|
240
|
-
className: "px-2 py-1 text-xs bg-
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
258
|
+
/* @__PURE__ */ g("button", {
|
|
256
259
|
onClick: (t) => {
|
|
257
|
-
t.stopPropagation(),
|
|
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__ */
|
|
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 {
|
|
278
|
+
export { b as ConnectionsListPage };
|
|
275
279
|
|
|
276
280
|
//# sourceMappingURL=ConnectionsListPage.js.map
|