@burdenoff/microfe-channel 2026.510.112

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 (156) hide show
  1. package/README.md +147 -0
  2. package/dist/channel/ChannelRoot.d.ts +32 -0
  3. package/dist/channel/ChannelRoot.d.ts.map +1 -0
  4. package/dist/channel/ChannelRoot.js +81 -0
  5. package/dist/channel/ChannelRoot.js.map +1 -0
  6. package/dist/channel/ChannelRoutes.d.ts +10 -0
  7. package/dist/channel/ChannelRoutes.d.ts.map +1 -0
  8. package/dist/channel/ChannelRoutes.js +104 -0
  9. package/dist/channel/ChannelRoutes.js.map +1 -0
  10. package/dist/channel/components/AdapterCredentialsForm.d.ts +20 -0
  11. package/dist/channel/components/AdapterCredentialsForm.d.ts.map +1 -0
  12. package/dist/channel/components/AdapterCredentialsForm.js +230 -0
  13. package/dist/channel/components/AdapterCredentialsForm.js.map +1 -0
  14. package/dist/channel/components/FeatureNotEnabled.d.ts +10 -0
  15. package/dist/channel/components/FeatureNotEnabled.d.ts.map +1 -0
  16. package/dist/channel/components/FeatureNotEnabled.js +32 -0
  17. package/dist/channel/components/FeatureNotEnabled.js.map +1 -0
  18. package/dist/channel/components/PermissionGuard.d.ts +15 -0
  19. package/dist/channel/components/PermissionGuard.d.ts.map +1 -0
  20. package/dist/channel/components/PermissionGuard.js +23 -0
  21. package/dist/channel/components/PermissionGuard.js.map +1 -0
  22. package/dist/channel/config/adapterCredentials.d.ts +44 -0
  23. package/dist/channel/config/adapterCredentials.d.ts.map +1 -0
  24. package/dist/channel/config/adapterCredentials.js +946 -0
  25. package/dist/channel/config/adapterCredentials.js.map +1 -0
  26. package/dist/channel/constants/permissions.d.ts +32 -0
  27. package/dist/channel/constants/permissions.d.ts.map +1 -0
  28. package/dist/channel/constants/permissions.js +30 -0
  29. package/dist/channel/constants/permissions.js.map +1 -0
  30. package/dist/channel/graphql/global-client.d.ts +11 -0
  31. package/dist/channel/graphql/global-client.d.ts.map +1 -0
  32. package/dist/channel/graphql/global-client.js +56 -0
  33. package/dist/channel/graphql/global-client.js.map +1 -0
  34. package/dist/channel/hooks/useChannelOrgSettings.d.ts +22 -0
  35. package/dist/channel/hooks/useChannelOrgSettings.d.ts.map +1 -0
  36. package/dist/channel/hooks/useChannelOrgSettings.js +61 -0
  37. package/dist/channel/hooks/useChannelOrgSettings.js.map +1 -0
  38. package/dist/channel/hooks/useChannelSubscription.d.ts +36 -0
  39. package/dist/channel/hooks/useChannelSubscription.d.ts.map +1 -0
  40. package/dist/channel/hooks/useChannelSubscription.js +111 -0
  41. package/dist/channel/hooks/useChannelSubscription.js.map +1 -0
  42. package/dist/channel/hooks/useChannels.d.ts +214 -0
  43. package/dist/channel/hooks/useChannels.d.ts.map +1 -0
  44. package/dist/channel/hooks/useChannels.js +416 -0
  45. package/dist/channel/hooks/useChannels.js.map +1 -0
  46. package/dist/channel/index.d.ts +12 -0
  47. package/dist/channel/index.d.ts.map +1 -0
  48. package/dist/channel/index.js +2 -0
  49. package/dist/channel/modules/channels/hooks/useExport.d.ts +45 -0
  50. package/dist/channel/modules/channels/hooks/useExport.d.ts.map +1 -0
  51. package/dist/channel/modules/channels/hooks/useExport.js +195 -0
  52. package/dist/channel/modules/channels/hooks/useExport.js.map +1 -0
  53. package/dist/channel/modules/channels/i18n.d.ts +14 -0
  54. package/dist/channel/modules/channels/i18n.d.ts.map +1 -0
  55. package/dist/channel/modules/channels/i18n.js +110 -0
  56. package/dist/channel/modules/channels/i18n.js.map +1 -0
  57. package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts +14 -0
  58. package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts.map +1 -0
  59. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js +680 -0
  60. package/dist/channel/modules/channels/pages/ChannelDashboardPage.js.map +1 -0
  61. package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts +7 -0
  62. package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts.map +1 -0
  63. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js +949 -0
  64. package/dist/channel/modules/channels/pages/ChannelDetailsPage.js.map +1 -0
  65. package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts +7 -0
  66. package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts.map +1 -0
  67. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +404 -0
  68. package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -0
  69. package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts +7 -0
  70. package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts.map +1 -0
  71. package/dist/channel/modules/channels/pages/ChannelUsersPage.js +315 -0
  72. package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -0
  73. package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts +7 -0
  74. package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts.map +1 -0
  75. package/dist/channel/modules/channels/pages/ChannelsListPage.js +604 -0
  76. package/dist/channel/modules/channels/pages/ChannelsListPage.js.map +1 -0
  77. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts +7 -0
  78. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts.map +1 -0
  79. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +323 -0
  80. package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -0
  81. package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts +7 -0
  82. package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts.map +1 -0
  83. package/dist/channel/modules/channels/pages/ConnectionsListPage.js +276 -0
  84. package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -0
  85. package/dist/channel/modules/channels/pages/CreateChannelPage.d.ts +12 -0
  86. package/dist/channel/modules/channels/pages/CreateChannelPage.d.ts.map +1 -0
  87. package/dist/channel/modules/channels/pages/CreateChannelPage.js +456 -0
  88. package/dist/channel/modules/channels/pages/CreateChannelPage.js.map +1 -0
  89. package/dist/channel/modules/channels/pages/CreateConnectionPage.d.ts +11 -0
  90. package/dist/channel/modules/channels/pages/CreateConnectionPage.d.ts.map +1 -0
  91. package/dist/channel/modules/channels/pages/CreateConnectionPage.js +219 -0
  92. package/dist/channel/modules/channels/pages/CreateConnectionPage.js.map +1 -0
  93. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts +7 -0
  94. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts.map +1 -0
  95. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +375 -0
  96. package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -0
  97. package/dist/channel/modules/channels/pages/EditChannelPage.d.ts +8 -0
  98. package/dist/channel/modules/channels/pages/EditChannelPage.d.ts.map +1 -0
  99. package/dist/channel/modules/channels/pages/EditChannelPage.js +459 -0
  100. package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -0
  101. package/dist/channel/modules/channels/pages/EditConnectionPage.d.ts +10 -0
  102. package/dist/channel/modules/channels/pages/EditConnectionPage.d.ts.map +1 -0
  103. package/dist/channel/modules/channels/pages/EditConnectionPage.js +199 -0
  104. package/dist/channel/modules/channels/pages/EditConnectionPage.js.map +1 -0
  105. package/dist/channel/modules/channels/pages/SendMessagePage.d.ts +8 -0
  106. package/dist/channel/modules/channels/pages/SendMessagePage.d.ts.map +1 -0
  107. package/dist/channel/modules/channels/pages/SendMessagePage.js +403 -0
  108. package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -0
  109. package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts +7 -0
  110. package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts.map +1 -0
  111. package/dist/channel/modules/channels/pages/WebhookEventsPage.js +303 -0
  112. package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -0
  113. package/dist/channel/modules/channels/pages/index.d.ts +18 -0
  114. package/dist/channel/modules/channels/pages/index.d.ts.map +1 -0
  115. package/dist/channel/modules/channels/pages/index.js +14 -0
  116. package/dist/channel/pages/ChannelLandingPage.d.ts +9 -0
  117. package/dist/channel/pages/ChannelLandingPage.d.ts.map +1 -0
  118. package/dist/channel/pages/ChannelLandingPage.js +72 -0
  119. package/dist/channel/pages/ChannelLandingPage.js.map +1 -0
  120. package/dist/channel/providers/ChannelProvider.d.ts +16 -0
  121. package/dist/channel/providers/ChannelProvider.d.ts.map +1 -0
  122. package/dist/channel/providers/ChannelProvider.js +35 -0
  123. package/dist/channel/providers/ChannelProvider.js.map +1 -0
  124. package/dist/channel/types/index.d.ts +89 -0
  125. package/dist/channel/types/index.d.ts.map +1 -0
  126. package/dist/channel/utils/shellBridge.d.ts +59 -0
  127. package/dist/channel/utils/shellBridge.d.ts.map +1 -0
  128. package/dist/channel/utils/shellBridge.js +36 -0
  129. package/dist/channel/utils/shellBridge.js.map +1 -0
  130. package/dist/dev/App.d.ts +6 -0
  131. package/dist/dev/App.d.ts.map +1 -0
  132. package/dist/dev/main.d.ts +2 -0
  133. package/dist/dev/main.d.ts.map +1 -0
  134. package/dist/generated/global-operations.d.ts +1547 -0
  135. package/dist/generated/global-operations.d.ts.map +1 -0
  136. package/dist/generated/global-operations.js +466 -0
  137. package/dist/generated/global-operations.js.map +1 -0
  138. package/dist/generated/global-types.d.ts +21289 -0
  139. package/dist/generated/global-types.d.ts.map +1 -0
  140. package/dist/generated/global-types.js +14 -0
  141. package/dist/generated/global-types.js.map +1 -0
  142. package/dist/generated/wspace-operations.d.ts +2 -0
  143. package/dist/generated/wspace-operations.d.ts.map +1 -0
  144. package/dist/generated/wspace-types.d.ts +55214 -0
  145. package/dist/generated/wspace-types.d.ts.map +1 -0
  146. package/dist/index.d.ts +5 -0
  147. package/dist/index.d.ts.map +1 -0
  148. package/dist/index.js +4 -0
  149. package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js +24 -0
  150. package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
  151. package/dist/node_modules/@apollo/client/errors/utils.js +16 -0
  152. package/dist/node_modules/@apollo/client/errors/utils.js.map +1 -0
  153. package/dist/utils/nativeBridge.d.ts +3 -0
  154. package/dist/utils/nativeBridge.d.ts.map +1 -0
  155. package/dist/utils/nativeBridge.js +2 -0
  156. package/package.json +116 -0
package/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # @burdenoff/microfe-channel
2
+
3
+ Channel microfrontend for multi-channel communication management.
4
+
5
+ ## Features
6
+
7
+ - **Channel Management (CRUDL)**: Create, Read, Update, Delete, and List communication channels
8
+ - **Connection Management (CRUDL)**: Manage channel connections with encrypted credential storage
9
+ - **Message Delivery**: Send messages through configured channels
10
+ - **Multi-Platform Support**: Email, SMS, Push, Slack, Teams, Discord, WhatsApp, and more
11
+ - **Health Monitoring**: Real-time channel health checks and status monitoring
12
+ - **Failover Support**: Priority-based failover chains for reliability
13
+
14
+ ## Supported Platforms
15
+
16
+ ### Communication Channels
17
+ - **Email**: AWS SES, Azure ACS, SendGrid, Mailgun, SMTP, and more
18
+ - **SMS**: Twilio, AWS SNS, Vonage, Plivo, and more
19
+ - **Push Notifications**: FCM, APNS, OneSignal, Expo, and more
20
+ - **Messaging Platforms**: Slack, Microsoft Teams, Discord, WhatsApp
21
+ - **In-App**: Native in-app notifications
22
+ - **Webhooks**: Custom HTTP webhooks
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ bun add @burdenoff/microfe-channel
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ### Integration with Host Application
33
+
34
+ ```tsx
35
+ import { ChannelRoot, type ChannelRootProps } from '@burdenoff/microfe-channel';
36
+
37
+ function App() {
38
+ const props: ChannelRootProps = {
39
+ basePath: '/channels',
40
+ navigate: (path) => router.push(path),
41
+ currentUser: { id: '1', email: 'user@example.com', firstName: 'John', lastName: 'Doe' },
42
+ workspaceId: 'ws-123',
43
+ organizationId: 'org-123',
44
+ apiGatewayUrl: 'https://api.example.com/graphql',
45
+ authToken: 'your-auth-token',
46
+ registerNavItems: (items) => { /* register nav items */ return () => {}; },
47
+ };
48
+
49
+ return <ChannelRoot {...props} />;
50
+ }
51
+ ```
52
+
53
+ ### Standalone Development
54
+
55
+ ```bash
56
+ # Install dependencies
57
+ bun install
58
+
59
+ # Start development server
60
+ bun dev
61
+
62
+ # Build for production
63
+ bun run build
64
+
65
+ # Run linter
66
+ bun run lint
67
+
68
+ # Format code
69
+ bun run format
70
+
71
+ # Type check
72
+ bun run type:check
73
+
74
+ # Run all checks
75
+ bun run sanity
76
+ ```
77
+
78
+ ## Routes
79
+
80
+ - `/dashboard` - Channel overview dashboard
81
+ - `/channels` - List all channels
82
+ - `/channels/create` - Create new channel
83
+ - `/channels/:id` - Channel details
84
+ - `/channels/:id/edit` - Edit channel
85
+ - `/connections` - List all connections
86
+ - `/connections/create` - Create new connection
87
+ - `/connections/:id` - Connection details
88
+ - `/connections/:id/edit` - Edit connection
89
+ - `/send` - Send message interface
90
+ - `/settings` - Channel settings
91
+
92
+ ## GraphQL Operations
93
+
94
+ The microfe uses GraphQL for all API communication. After adding or modifying operations:
95
+
96
+ ```bash
97
+ # Generate TypeScript types from GraphQL operations
98
+ bun run codegen
99
+ ```
100
+
101
+ ## Architecture
102
+
103
+ ### Directory Structure
104
+
105
+ ```
106
+ src/
107
+ ├── channel/
108
+ │ ├── modules/ # Feature modules
109
+ │ │ ├── channels/ # Channel CRUDL
110
+ │ │ ├── connections/ # Connection CRUDL
111
+ │ │ ├── dashboard/ # Overview dashboard
112
+ │ │ └── triggers/ # Message sending
113
+ │ ├── shared/ # Shared components
114
+ │ │ ├── components/
115
+ │ │ ├── types/
116
+ │ │ └── utils/
117
+ │ ├── hooks/ # Custom React hooks
118
+ │ ├── providers/ # Context providers
119
+ │ ├── ChannelRoot.tsx # Root component
120
+ │ ├── ChannelRoutes.tsx # Routing configuration
121
+ │ └── index.ts # Public exports
122
+ ├── dev/ # Development setup
123
+ └── index.ts # Package entry point
124
+ ```
125
+
126
+ ### State Management
127
+
128
+ - **Apollo Client**: Server state and GraphQL operations
129
+ - **Zustand**: Local UI state (optional, for complex UI state)
130
+ - **React Context**: Dependency injection and configuration
131
+
132
+ ## Environment Variables (Development)
133
+
134
+ Create a `.env.local` file for local development:
135
+
136
+ ```env
137
+ VITE_API_GATEWAY_URL=http://localhost:4000/graphql
138
+ VITE_AUTH_TOKEN=your-dev-token
139
+ ```
140
+
141
+ ## License
142
+
143
+ MIT
144
+
145
+ ## Author
146
+
147
+ Burdenoff
@@ -0,0 +1,32 @@
1
+ import { FC } from 'react';
2
+ import { ChannelRootProps } from './types';
3
+
4
+ /**
5
+ * Root component for the Channel microfrontend.
6
+ *
7
+ * This is the main entry point that host applications import and render.
8
+ * It sets up the necessary providers and renders the internal routing.
9
+ * Automatically registers navigation items with the shell if registration functions are provided.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { ChannelRoot, type ChannelRootProps } from '@burdenoff/microfe-channel';
14
+ *
15
+ * function App() {
16
+ * const props: ChannelRootProps = {
17
+ * basePath: '/channels',
18
+ * navigate: (path) => router.push(path),
19
+ * currentUser: { id: '1', email: 'user@example.com', firstName: 'John', lastName: 'Doe' },
20
+ * workspaceId: 'ws-123',
21
+ * organizationId: 'org-123',
22
+ * apiGatewayUrl: 'https://api.example.com/workspaces/graphql',
23
+ * authToken: 'token',
24
+ * registerNavItems: (items) => { return () => {}; },
25
+ * };
26
+ *
27
+ * return <ChannelRoot {...props} />;
28
+ * }
29
+ * ```
30
+ */
31
+ export declare const ChannelRoot: FC<ChannelRootProps>;
32
+ //# sourceMappingURL=ChannelRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelRoot.d.ts","sourceRoot":"","sources":["../../src/channel/ChannelRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAOhC,OAAO,KAAK,EAAW,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGzD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAiG5C,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { ChannelProvider as e } from "./providers/ChannelProvider.js";
2
+ import { ChannelRoutes as t } from "./ChannelRoutes.js";
3
+ import { useCallback as n, useEffect as r } from "react";
4
+ import { ErrorBoundary as i } from "@burdenoff/fe-libs/shared/components";
5
+ import { useI18n as a } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
+ import { Cable as o, Radio as s, Send as c, Settings as l } from "lucide-react";
7
+ import { jsx as u } from "react/jsx-runtime";
8
+ import { FeatureFlagProvider as d } from "@burdenoff/fe-libs/shared/feature-flags";
9
+ //#region src/channel/ChannelRoot.tsx
10
+ var f = (f) => {
11
+ let { registerNavItems: p, registerFooterItems: m, basePath: h = "/" } = f, { t: g } = a(), _ = n((e, t) => {
12
+ let n = g(e);
13
+ return n === e ? t : n;
14
+ }, [g]), v = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
15
+ return r(() => {
16
+ if (p) return p([
17
+ {
18
+ id: "channel-channels",
19
+ label: _("channel.channels", "Channels"),
20
+ path: h === "/" ? "/" : v(h, "list"),
21
+ icon: /* @__PURE__ */ u(s, { size: 20 }),
22
+ order: 100,
23
+ group: "channel"
24
+ },
25
+ {
26
+ id: "channel-connections",
27
+ label: _("channel.connections", "Connections"),
28
+ path: v(h, "connections"),
29
+ icon: /* @__PURE__ */ u(o, { size: 20 }),
30
+ order: 110,
31
+ group: "channel"
32
+ },
33
+ {
34
+ id: "channel-send",
35
+ label: _("channel.sendMessage", "Send Message"),
36
+ path: v(h, "send"),
37
+ icon: /* @__PURE__ */ u(c, { size: 20 }),
38
+ order: 120,
39
+ group: "channel"
40
+ },
41
+ {
42
+ id: "channel-settings",
43
+ label: _("channel.settings", "Settings"),
44
+ path: v(h, "settings"),
45
+ icon: /* @__PURE__ */ u(l, { size: 20 }),
46
+ order: 130,
47
+ group: "channel"
48
+ }
49
+ ]);
50
+ }, [
51
+ p,
52
+ h,
53
+ _
54
+ ]), r(() => {
55
+ if (m) return m([{
56
+ id: "channel-status",
57
+ label: _("channel.channelsReady", "Channels Ready"),
58
+ type: "status",
59
+ order: 10,
60
+ section: "left"
61
+ }]);
62
+ }, [m, _]), /* @__PURE__ */ u(i, {
63
+ fallback: /* @__PURE__ */ u("div", {
64
+ className: "p-6 text-center text-text-secondary",
65
+ children: "Something went wrong loading this module. Please refresh the page."
66
+ }),
67
+ children: /* @__PURE__ */ u(d, {
68
+ workspaceId: null,
69
+ gateway: "global",
70
+ defaultEnabled: !0,
71
+ children: /* @__PURE__ */ u(e, {
72
+ ...f,
73
+ children: /* @__PURE__ */ u(t, {})
74
+ })
75
+ })
76
+ });
77
+ };
78
+ //#endregion
79
+ export { f as ChannelRoot };
80
+
81
+ //# sourceMappingURL=ChannelRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelRoot.js","names":[],"sources":["../../src/channel/ChannelRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect, useCallback } from 'react';\nimport { ErrorBoundary } from '@burdenoff/fe-libs/shared/components';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Radio, Cable, Send, Settings } from 'lucide-react';\nimport { ChannelProvider } from './providers/ChannelProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport type { NavItem, ChannelRootProps } from './types';\nimport { ChannelRoutes } from './ChannelRoutes';\n\n/**\n * Root component for the Channel microfrontend.\n *\n * This is the main entry point that host applications import and render.\n * It sets up the necessary providers and renders the internal routing.\n * Automatically registers navigation items with the shell if registration functions are provided.\n *\n * @example\n * ```tsx\n * import { ChannelRoot, type ChannelRootProps } from '@burdenoff/microfe-channel';\n *\n * function App() {\n * const props: ChannelRootProps = {\n * basePath: '/channels',\n * navigate: (path) => router.push(path),\n * currentUser: { id: '1', email: 'user@example.com', firstName: 'John', lastName: 'Doe' },\n * workspaceId: 'ws-123',\n * organizationId: 'org-123',\n * apiGatewayUrl: 'https://api.example.com/workspaces/graphql',\n * authToken: 'token',\n * registerNavItems: (items) => { return () => {}; },\n * };\n *\n * return <ChannelRoot {...props} />;\n * }\n * ```\n */\nexport const ChannelRoot: FC<ChannelRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n\n // Helper to join paths correctly, avoiding double slashes\n const joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n };\n\n // Register navigation items with the shell\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'channel-channels',\n label: tr('channel.channels', 'Channels'),\n path: basePath === '/' ? '/' : joinPath(basePath, 'list'),\n icon: <Radio size={20} />,\n order: 100,\n group: 'channel',\n },\n {\n id: 'channel-connections',\n label: tr('channel.connections', 'Connections'),\n path: joinPath(basePath, 'connections'),\n icon: <Cable size={20} />,\n order: 110,\n group: 'channel',\n },\n {\n id: 'channel-send',\n label: tr('channel.sendMessage', 'Send Message'),\n path: joinPath(basePath, 'send'),\n icon: <Send size={20} />,\n order: 120,\n group: 'channel',\n },\n {\n id: 'channel-settings',\n label: tr('channel.settings', 'Settings'),\n path: joinPath(basePath, 'settings'),\n icon: <Settings size={20} />,\n order: 130,\n group: 'channel',\n },\n ];\n\n // Register and get cleanup function\n const cleanup = registerNavItems(navItems);\n\n // Return cleanup function to unregister on unmount\n return cleanup;\n }, [registerNavItems, basePath, tr]);\n\n // Register footer items (example: Channel status indicator in left section)\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'channel-status',\n label: tr('channel.channelsReady', 'Channels Ready'),\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems, tr]);\n\n return (\n <ErrorBoundary\n fallback={\n <div className=\"p-6 text-center text-text-secondary\">\n Something went wrong loading this module. Please refresh the page.\n </div>\n }\n >\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <ChannelProvider {...props}>\n <ChannelRoutes />\n </ChannelProvider>\n </FeatureFlagProvider>\n </ErrorBoundary>\n );\n};\n"],"mappings":";;;;;;;;;AAqCA,IAAa,KAAqC,MAAU;CAC1D,IAAM,EAAE,qBAAkB,wBAAqB,cAAW,QAAQ,GAC5D,EAAE,SAAM,GAAS,EACjB,IAAK,GACR,GAAa,MAA6B;EACzC,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAEpC,CAAC,EAAE,CACJ,EAGK,KAAY,GAAc,OACZ,EAAK,SAAS,IAAI,GAAG,EAAK,MAAM,GAAG,GAAG,GAAG,MACzC,EAAK,WAAW,IAAI,GAAG,IAAO,IAAI;AAoEtD,QA/DA,QAAgB;AACT,QAyCL,QAHgB,EApCY;GAC1B;IACE,IAAI;IACJ,OAAO,EAAG,oBAAoB,WAAW;IACzC,MAAM,MAAa,MAAM,MAAM,EAAS,GAAU,OAAO;IACzD,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;IACzB,OAAO;IACP,OAAO;IACR;GACD;IACE,IAAI;IACJ,OAAO,EAAG,uBAAuB,cAAc;IAC/C,MAAM,EAAS,GAAU,cAAc;IACvC,MAAM,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;IACzB,OAAO;IACP,OAAO;IACR;GACD;IACE,IAAI;IACJ,OAAO,EAAG,uBAAuB,eAAe;IAChD,MAAM,EAAS,GAAU,OAAO;IAChC,MAAM,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;IACxB,OAAO;IACP,OAAO;IACR;GACD;IACE,IAAI;IACJ,OAAO,EAAG,oBAAoB,WAAW;IACzC,MAAM,EAAS,GAAU,WAAW;IACpC,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;IAC5B,OAAO;IACP,OAAO;IACR;GACF,CAGyC;IAIzC;EAAC;EAAkB;EAAU;EAAG,CAAC,EAGpC,QAAgB;AACT,QAaL,QADgB,EAVI,CAClB;GACE,IAAI;GACJ,OAAO,EAAG,yBAAyB,iBAAiB;GACpD,MAAM;GACN,OAAO;GACP,SAAS;GACV,CACF,CAE+C;IAE/C,CAAC,GAAqB,EAAG,CAAC,EAG3B,kBAAC,GAAD;EACE,UACE,kBAAC,OAAD;GAAK,WAAU;aAAsC;GAE/C,CAAA;YAGR,kBAAC,GAAD;GAAqB,aAAa;GAAM,SAAQ;GAAS,gBAAgB;aACvE,kBAAC,GAAD;IAAiB,GAAI;cACnB,kBAAC,GAAD,EAAiB,CAAA;IACD,CAAA;GACE,CAAA;EACR,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Internal router for the Channel microfrontend.
3
+ *
4
+ * The shell mounts this at /channels/* so all paths here are relative to /channels/.
5
+ * Every concrete route is wrapped with a FeatureGate so individual surfaces can
6
+ * be rolled out or kill-switched independently. Flag names follow
7
+ * `channels.<route-name>` (see vibecontrols-channel-stability tracker).
8
+ */
9
+ export declare function ChannelRoutes(): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=ChannelRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelRoutes.d.ts","sourceRoot":"","sources":["../../src/channel/ChannelRoutes.tsx"],"names":[],"mappings":"AAmCA;;;;;;;GAOG;AACH,wBAAgB,aAAa,4CAoD5B"}
@@ -0,0 +1,104 @@
1
+ import { ChannelDashboardPage as e } from "./modules/channels/pages/ChannelDashboardPage.js";
2
+ import { ChannelsListPage as t } from "./modules/channels/pages/ChannelsListPage.js";
3
+ import { ChannelDetailsPage as n } from "./modules/channels/pages/ChannelDetailsPage.js";
4
+ import { CreateChannelPage as r } from "./modules/channels/pages/CreateChannelPage.js";
5
+ import { EditChannelPage as i } from "./modules/channels/pages/EditChannelPage.js";
6
+ import { SendMessagePage as a } from "./modules/channels/pages/SendMessagePage.js";
7
+ import { ConnectionsListPage as o } from "./modules/channels/pages/ConnectionsListPage.js";
8
+ import { ConnectionDetailsPage as s } from "./modules/channels/pages/ConnectionDetailsPage.js";
9
+ import { CreateConnectionPage as c } from "./modules/channels/pages/CreateConnectionPage.js";
10
+ import { EditConnectionPage as l } from "./modules/channels/pages/EditConnectionPage.js";
11
+ import { ChannelSettingsPage as u } from "./modules/channels/pages/ChannelSettingsPage.js";
12
+ import { DeliveryHistoryPage as d } from "./modules/channels/pages/DeliveryHistoryPage.js";
13
+ import { WebhookEventsPage as f } from "./modules/channels/pages/WebhookEventsPage.js";
14
+ import { ChannelUsersPage as p } from "./modules/channels/pages/ChannelUsersPage.js";
15
+ import "./modules/channels/pages/index.js";
16
+ import { ChannelLandingPage as m } from "./pages/ChannelLandingPage.js";
17
+ import { FeatureNotEnabled as h } from "./components/FeatureNotEnabled.js";
18
+ import { Navigate as g, Route as _, Routes as v } from "react-router-dom";
19
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
20
+ import { FeatureGate as x } from "@burdenoff/fe-libs/shared/feature-flags";
21
+ //#region src/channel/ChannelRoutes.tsx
22
+ function S(e, t) {
23
+ return /* @__PURE__ */ y(x, {
24
+ flag: e,
25
+ defaultValue: !1,
26
+ fallback: /* @__PURE__ */ y(h, { flag: e }),
27
+ children: t
28
+ });
29
+ }
30
+ function C() {
31
+ return /* @__PURE__ */ b(v, { children: [
32
+ /* @__PURE__ */ y(_, {
33
+ index: !0,
34
+ element: S("channels.dashboard", /* @__PURE__ */ y(m, {}))
35
+ }),
36
+ /* @__PURE__ */ y(_, {
37
+ path: "dashboard",
38
+ element: S("channels.dashboard", /* @__PURE__ */ y(e, {}))
39
+ }),
40
+ /* @__PURE__ */ y(_, {
41
+ path: "list",
42
+ element: S("channels.list", /* @__PURE__ */ y(t, {}))
43
+ }),
44
+ /* @__PURE__ */ y(_, {
45
+ path: "create",
46
+ element: S("channels.create", /* @__PURE__ */ y(r, {}))
47
+ }),
48
+ /* @__PURE__ */ y(_, {
49
+ path: ":channelId",
50
+ element: S("channels.detail", /* @__PURE__ */ y(n, {}))
51
+ }),
52
+ /* @__PURE__ */ y(_, {
53
+ path: ":channelId/edit",
54
+ element: S("channels.edit", /* @__PURE__ */ y(i, {}))
55
+ }),
56
+ /* @__PURE__ */ y(_, {
57
+ path: ":channelId/deliveries",
58
+ element: S("channels.deliveries", /* @__PURE__ */ y(d, {}))
59
+ }),
60
+ /* @__PURE__ */ y(_, {
61
+ path: ":channelId/webhooks",
62
+ element: S("channels.webhooks", /* @__PURE__ */ y(f, {}))
63
+ }),
64
+ /* @__PURE__ */ y(_, {
65
+ path: ":channelId/users",
66
+ element: S("channels.users", /* @__PURE__ */ y(p, {}))
67
+ }),
68
+ /* @__PURE__ */ y(_, {
69
+ path: "connections",
70
+ element: S("channels.connections.list", /* @__PURE__ */ y(o, {}))
71
+ }),
72
+ /* @__PURE__ */ y(_, {
73
+ path: "connections/create",
74
+ element: S("channels.connections.create", /* @__PURE__ */ y(c, {}))
75
+ }),
76
+ /* @__PURE__ */ y(_, {
77
+ path: "connections/:connectionId",
78
+ element: S("channels.connections.detail", /* @__PURE__ */ y(s, {}))
79
+ }),
80
+ /* @__PURE__ */ y(_, {
81
+ path: "connections/:connectionId/edit",
82
+ element: S("channels.connections.edit", /* @__PURE__ */ y(l, {}))
83
+ }),
84
+ /* @__PURE__ */ y(_, {
85
+ path: "send",
86
+ element: S("channels.send", /* @__PURE__ */ y(a, {}))
87
+ }),
88
+ /* @__PURE__ */ y(_, {
89
+ path: "settings",
90
+ element: S("channels.settings", /* @__PURE__ */ y(u, {}))
91
+ }),
92
+ /* @__PURE__ */ y(_, {
93
+ path: "*",
94
+ element: /* @__PURE__ */ y(g, {
95
+ to: "dashboard",
96
+ replace: !0
97
+ })
98
+ })
99
+ ] });
100
+ }
101
+ //#endregion
102
+ export { C as ChannelRoutes };
103
+
104
+ //# sourceMappingURL=ChannelRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelRoutes.js","names":[],"sources":["../../src/channel/ChannelRoutes.tsx"],"sourcesContent":["import { Navigate, Route, Routes } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport {\n ChannelDashboardPage,\n ChannelsListPage,\n ChannelDetailsPage,\n CreateChannelPage,\n EditChannelPage,\n SendMessagePage,\n ConnectionsListPage,\n ConnectionDetailsPage,\n CreateConnectionPage,\n EditConnectionPage,\n ChannelSettingsPage,\n DeliveryHistoryPage,\n WebhookEventsPage,\n ChannelUsersPage,\n} from './modules/channels/pages';\nimport { ChannelLandingPage } from './pages/ChannelLandingPage';\nimport { FeatureNotEnabled } from './components/FeatureNotEnabled';\nimport type { ReactNode } from 'react';\n\n/**\n * Wraps a route element in a FeatureGate. Unknown / absent flags default to\n * disabled (defaultValue=false) so a not-yet-rolled-out flag is treated as\n * off — the user sees a soft \"Feature not enabled\" panel, not a 500.\n */\nfunction gated(flag: string, element: ReactNode): ReactNode {\n return (\n <FeatureGate flag={flag} defaultValue={false} fallback={<FeatureNotEnabled flag={flag} />}>\n {element}\n </FeatureGate>\n );\n}\n\n/**\n * Internal router for the Channel microfrontend.\n *\n * The shell mounts this at /channels/* so all paths here are relative to /channels/.\n * Every concrete route is wrapped with a FeatureGate so individual surfaces can\n * be rolled out or kill-switched independently. Flag names follow\n * `channels.<route-name>` (see vibecontrols-channel-stability tracker).\n */\nexport function ChannelRoutes() {\n return (\n <Routes>\n {/* Tabbed landing — gated under the dashboard flag */}\n <Route index element={gated('channels.dashboard', <ChannelLandingPage />)} />\n\n {/* Dashboard */}\n <Route path=\"dashboard\" element={gated('channels.dashboard', <ChannelDashboardPage />)} />\n\n {/* Channel CRUD — flat under /channels/ */}\n <Route path=\"list\" element={gated('channels.list', <ChannelsListPage />)} />\n <Route path=\"create\" element={gated('channels.create', <CreateChannelPage />)} />\n <Route path=\":channelId\" element={gated('channels.detail', <ChannelDetailsPage />)} />\n <Route path=\":channelId/edit\" element={gated('channels.edit', <EditChannelPage />)} />\n <Route\n path=\":channelId/deliveries\"\n element={gated('channels.deliveries', <DeliveryHistoryPage />)}\n />\n <Route\n path=\":channelId/webhooks\"\n element={gated('channels.webhooks', <WebhookEventsPage />)}\n />\n <Route path=\":channelId/users\" element={gated('channels.users', <ChannelUsersPage />)} />\n\n {/* Connections */}\n <Route\n path=\"connections\"\n element={gated('channels.connections.list', <ConnectionsListPage />)}\n />\n <Route\n path=\"connections/create\"\n element={gated('channels.connections.create', <CreateConnectionPage />)}\n />\n <Route\n path=\"connections/:connectionId\"\n element={gated('channels.connections.detail', <ConnectionDetailsPage />)}\n />\n <Route\n path=\"connections/:connectionId/edit\"\n element={gated('channels.connections.edit', <EditConnectionPage />)}\n />\n\n {/* Send Message */}\n <Route path=\"send\" element={gated('channels.send', <SendMessagePage />)} />\n\n {/* Settings */}\n <Route path=\"settings\" element={gated('channels.settings', <ChannelSettingsPage />)} />\n\n {/* Catch-all → dashboard */}\n <Route path=\"*\" element={<Navigate to=\"dashboard\" replace />} />\n </Routes>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2BA,SAAS,EAAM,GAAc,GAA+B;AAC1D,QACE,kBAAC,GAAD;EAAmB;EAAM,cAAc;EAAO,UAAU,kBAAC,GAAD,EAAyB,SAAQ,CAAA;YACtF;EACW,CAAA;;AAYlB,SAAgB,IAAgB;AAC9B,QACE,kBAAC,GAAD,EAAA,UAAA;EAEE,kBAAC,GAAD;GAAO,OAAA;GAAM,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAsB,CAAA,CAAC;GAAI,CAAA;EAG7E,kBAAC,GAAD;GAAO,MAAK;GAAY,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAwB,CAAA,CAAC;GAAI,CAAA;EAG1F,kBAAC,GAAD;GAAO,MAAK;GAAO,SAAS,EAAM,iBAAiB,kBAAC,GAAD,EAAoB,CAAA,CAAC;GAAI,CAAA;EAC5E,kBAAC,GAAD;GAAO,MAAK;GAAS,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAqB,CAAA,CAAC;GAAI,CAAA;EACjF,kBAAC,GAAD;GAAO,MAAK;GAAa,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAsB,CAAA,CAAC;GAAI,CAAA;EACtF,kBAAC,GAAD;GAAO,MAAK;GAAkB,SAAS,EAAM,iBAAiB,kBAAC,GAAD,EAAmB,CAAA,CAAC;GAAI,CAAA;EACtF,kBAAC,GAAD;GACE,MAAK;GACL,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAuB,CAAA,CAAC;GAC9D,CAAA;EACF,kBAAC,GAAD;GACE,MAAK;GACL,SAAS,EAAM,qBAAqB,kBAAC,GAAD,EAAqB,CAAA,CAAC;GAC1D,CAAA;EACF,kBAAC,GAAD;GAAO,MAAK;GAAmB,SAAS,EAAM,kBAAkB,kBAAC,GAAD,EAAoB,CAAA,CAAC;GAAI,CAAA;EAGzF,kBAAC,GAAD;GACE,MAAK;GACL,SAAS,EAAM,6BAA6B,kBAAC,GAAD,EAAuB,CAAA,CAAC;GACpE,CAAA;EACF,kBAAC,GAAD;GACE,MAAK;GACL,SAAS,EAAM,+BAA+B,kBAAC,GAAD,EAAwB,CAAA,CAAC;GACvE,CAAA;EACF,kBAAC,GAAD;GACE,MAAK;GACL,SAAS,EAAM,+BAA+B,kBAAC,GAAD,EAAyB,CAAA,CAAC;GACxE,CAAA;EACF,kBAAC,GAAD;GACE,MAAK;GACL,SAAS,EAAM,6BAA6B,kBAAC,GAAD,EAAsB,CAAA,CAAC;GACnE,CAAA;EAGF,kBAAC,GAAD;GAAO,MAAK;GAAO,SAAS,EAAM,iBAAiB,kBAAC,GAAD,EAAmB,CAAA,CAAC;GAAI,CAAA;EAG3E,kBAAC,GAAD;GAAO,MAAK;GAAW,SAAS,EAAM,qBAAqB,kBAAC,GAAD,EAAuB,CAAA,CAAC;GAAI,CAAA;EAGvF,kBAAC,GAAD;GAAO,MAAK;GAAI,SAAS,kBAAC,GAAD;IAAU,IAAG;IAAY,SAAA;IAAU,CAAA;GAAI,CAAA;EACzD,EAAA,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { AdapterType } from '../hooks/useChannels';
2
+
3
+ interface AdapterCredentialsFormProps {
4
+ adapterType: AdapterType | undefined;
5
+ credentials: Record<string, unknown>;
6
+ onChange: (credentials: Record<string, unknown>) => void;
7
+ onValidationChange?: (isValid: boolean, errors: string[]) => void;
8
+ disabled?: boolean;
9
+ showPlatformMetadata?: boolean;
10
+ }
11
+ export declare function AdapterCredentialsForm({ adapterType, credentials, onChange, onValidationChange, disabled, showPlatformMetadata, }: AdapterCredentialsFormProps): import("react/jsx-runtime").JSX.Element;
12
+ /**
13
+ * Compact validation status indicator
14
+ */
15
+ export declare function CredentialValidationStatus({ adapterType, credentials, }: {
16
+ adapterType: AdapterType | undefined;
17
+ credentials: Record<string, unknown>;
18
+ }): import("react/jsx-runtime").JSX.Element | null;
19
+ export {};
20
+ //# sourceMappingURL=AdapterCredentialsForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdapterCredentialsForm.d.ts","sourceRoot":"","sources":["../../../src/channel/components/AdapterCredentialsForm.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAQxD,UAAU,2BAA2B;IACnC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACzD,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,sBAAsB,CAAC,EACrC,WAAW,EACX,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,QAAgB,EAChB,oBAA2B,GAC5B,EAAE,2BAA2B,2CA0O7B;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,WAAW,EACX,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC,kDA8BA"}
@@ -0,0 +1,230 @@
1
+ import { getAdapterCredentialSchema as e, getDefaultCredentials as t, validateCredentials as n } from "../config/adapterCredentials.js";
2
+ import { useEffect as r, useState as i } from "react";
3
+ import { useI18n as a } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
4
+ import { AlertCircle as o, CheckCircle2 as s, ExternalLink as c, Eye as l, EyeOff as u } from "lucide-react";
5
+ import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
6
+ //#region src/channel/components/AdapterCredentialsForm.tsx
7
+ function m({ adapterType: s, credentials: m, onChange: h, onValidationChange: g, disabled: _ = !1, showPlatformMetadata: v = !0 }) {
8
+ let { t: y } = a(), b = (e, t) => {
9
+ let n = y(e);
10
+ return n === e ? t : n;
11
+ }, [x, S] = i({}), [C, w] = i({}), T = e(s);
12
+ if (r(() => {
13
+ if (s) {
14
+ let e = {
15
+ ...t(s),
16
+ ...m
17
+ };
18
+ JSON.stringify(e) !== JSON.stringify(m) && h(e);
19
+ }
20
+ }, [s]), r(() => {
21
+ if (g && s) {
22
+ let { valid: e, errors: t } = n(s, m);
23
+ g(e, t);
24
+ }
25
+ }, [
26
+ m,
27
+ s,
28
+ g
29
+ ]), !s) return /* @__PURE__ */ f("div", {
30
+ className: "text-center py-6 text-muted-foreground",
31
+ children: /* @__PURE__ */ f("p", {
32
+ className: "text-sm",
33
+ children: b("channel.selectAdapterType", "Select an adapter type to configure credentials")
34
+ })
35
+ });
36
+ if (!T) return /* @__PURE__ */ f("div", {
37
+ className: "p-4 bg-warning-100 border border-warning-300 rounded-lg",
38
+ children: /* @__PURE__ */ p("div", {
39
+ className: "flex items-start gap-2",
40
+ children: [/* @__PURE__ */ f(o, {
41
+ size: 16,
42
+ className: "text-warning-500 mt-0.5"
43
+ }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("p", {
44
+ className: "text-sm font-medium text-warning-700",
45
+ children: [
46
+ b("channel.noCredentialSchema", "No credential schema defined for"),
47
+ " ",
48
+ s
49
+ ]
50
+ }), /* @__PURE__ */ f("p", {
51
+ className: "text-xs text-warning-600 mt-1",
52
+ children: b("channel.enterCredentialsAsJson", "You can still enter credentials as JSON in the raw format below.")
53
+ })] })]
54
+ })
55
+ });
56
+ let E = (e, t) => {
57
+ h({
58
+ ...m,
59
+ [e]: t
60
+ });
61
+ }, D = (e) => {
62
+ w((t) => ({
63
+ ...t,
64
+ [e]: !0
65
+ }));
66
+ }, O = (e) => {
67
+ S((t) => ({
68
+ ...t,
69
+ [e]: !t[e]
70
+ }));
71
+ }, k = (e) => {
72
+ let t = m[e.key], n = C[e.key] && e.required && !t, r = `w-full px-3 py-2 text-sm bg-surface border rounded-lg focus:outline-none focus:ring-2 focus:ring-accent-primary disabled:opacity-50 disabled:cursor-not-allowed ${n ? "border-error-500" : "border-border"}`;
73
+ return /* @__PURE__ */ p("div", { children: [
74
+ /* @__PURE__ */ p("label", {
75
+ className: "block text-sm font-medium text-foreground mb-1.5",
76
+ children: [e.displayName, e.required && /* @__PURE__ */ f("span", {
77
+ className: "text-error-500 ml-1",
78
+ children: "*"
79
+ })]
80
+ }),
81
+ e.type === "text" && /* @__PURE__ */ f("input", {
82
+ type: "text",
83
+ value: t || "",
84
+ onChange: (t) => E(e.key, t.target.value),
85
+ onBlur: () => D(e.key),
86
+ disabled: _,
87
+ placeholder: e.placeholder,
88
+ className: r
89
+ }),
90
+ e.type === "password" && /* @__PURE__ */ p("div", {
91
+ className: "relative",
92
+ children: [/* @__PURE__ */ f("input", {
93
+ type: x[e.key] ? "text" : "password",
94
+ value: t || "",
95
+ onChange: (t) => E(e.key, t.target.value),
96
+ onBlur: () => D(e.key),
97
+ disabled: _,
98
+ placeholder: e.placeholder,
99
+ className: `${r} pr-10`
100
+ }), /* @__PURE__ */ f("button", {
101
+ type: "button",
102
+ onClick: () => O(e.key),
103
+ className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 text-muted-foreground hover:text-foreground",
104
+ tabIndex: -1,
105
+ children: x[e.key] ? /* @__PURE__ */ f(u, { size: 16 }) : /* @__PURE__ */ f(l, { size: 16 })
106
+ })]
107
+ }),
108
+ e.type === "textarea" && /* @__PURE__ */ f("textarea", {
109
+ value: t || "",
110
+ onChange: (t) => E(e.key, t.target.value),
111
+ onBlur: () => D(e.key),
112
+ disabled: _,
113
+ placeholder: e.placeholder,
114
+ rows: 4,
115
+ className: `${r} resize-none font-mono text-xs`
116
+ }),
117
+ e.type === "number" && /* @__PURE__ */ f("input", {
118
+ type: "number",
119
+ value: t ?? e.defaultValue ?? "",
120
+ onChange: (t) => E(e.key, t.target.value ? Number(t.target.value) : void 0),
121
+ onBlur: () => D(e.key),
122
+ disabled: _,
123
+ placeholder: e.placeholder,
124
+ className: r
125
+ }),
126
+ e.type === "boolean" && /* @__PURE__ */ p("label", {
127
+ className: "flex items-center gap-2 cursor-pointer",
128
+ children: [/* @__PURE__ */ f("input", {
129
+ type: "checkbox",
130
+ checked: t ?? e.defaultValue ?? !1,
131
+ onChange: (t) => E(e.key, t.target.checked),
132
+ disabled: _,
133
+ className: "w-4 h-4 rounded border-border text-accent-primary focus:ring-accent-primary"
134
+ }), /* @__PURE__ */ f("span", {
135
+ className: "text-sm text-muted-foreground",
136
+ children: e.description
137
+ })]
138
+ }),
139
+ e.type === "select" && e.options && /* @__PURE__ */ p("select", {
140
+ value: t ?? e.defaultValue ?? "",
141
+ onChange: (t) => E(e.key, t.target.value),
142
+ onBlur: () => D(e.key),
143
+ disabled: _,
144
+ className: `${r} bg-bg-surface`,
145
+ children: [/* @__PURE__ */ p("option", {
146
+ value: "",
147
+ children: [
148
+ b("channel.select", "Select"),
149
+ " ",
150
+ e.displayName.toLowerCase()
151
+ ]
152
+ }), e.options.map((e) => /* @__PURE__ */ f("option", {
153
+ value: e.value,
154
+ children: e.label
155
+ }, e.value))]
156
+ }),
157
+ e.type !== "boolean" && /* @__PURE__ */ f("p", {
158
+ className: "mt-1 text-xs text-muted-foreground",
159
+ children: e.description
160
+ }),
161
+ n && /* @__PURE__ */ f("p", {
162
+ className: "mt-1 text-xs text-error-500",
163
+ children: b("channel.fieldRequired", "This field is required")
164
+ })
165
+ ] }, e.key);
166
+ };
167
+ return /* @__PURE__ */ p("div", {
168
+ className: "space-y-5",
169
+ children: [/* @__PURE__ */ p("div", {
170
+ className: "flex items-start justify-between",
171
+ children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h3", {
172
+ className: "text-sm font-semibold text-foreground",
173
+ children: T.displayName
174
+ }), /* @__PURE__ */ f("p", {
175
+ className: "text-xs text-muted-foreground mt-0.5",
176
+ children: T.description
177
+ })] }), T.docUrl && /* @__PURE__ */ p("a", {
178
+ href: T.docUrl,
179
+ target: "_blank",
180
+ rel: "noopener noreferrer",
181
+ className: "flex items-center gap-1 text-xs text-accent-primary hover:text-accent-primary-hover",
182
+ children: [/* @__PURE__ */ f("span", { children: b("channel.docs", "Docs") }), /* @__PURE__ */ f(c, { size: 12 })]
183
+ })]
184
+ }), /* @__PURE__ */ p("div", {
185
+ className: "space-y-4",
186
+ children: [T.credentials.length > 0 && /* @__PURE__ */ f("div", {
187
+ className: "space-y-4",
188
+ children: T.credentials.map(k)
189
+ }), v && T.platformMetadata && T.platformMetadata.length > 0 && /* @__PURE__ */ f(d, { children: /* @__PURE__ */ p("div", {
190
+ className: "border-t border-border pt-4 mt-4",
191
+ children: [/* @__PURE__ */ f("p", {
192
+ className: "text-xs font-medium text-muted-foreground mb-3",
193
+ children: b("channel.optionalSettings", "Optional Settings")
194
+ }), /* @__PURE__ */ f("div", {
195
+ className: "space-y-4",
196
+ children: T.platformMetadata.map(k)
197
+ })]
198
+ }) })]
199
+ })]
200
+ });
201
+ }
202
+ function h({ adapterType: e, credentials: t }) {
203
+ let { t: r } = a(), i = (e, t) => {
204
+ let n = r(e);
205
+ return n === e ? t : n;
206
+ };
207
+ if (!e) return null;
208
+ let { valid: c, errors: l } = n(e, t);
209
+ return c ? /* @__PURE__ */ p("div", {
210
+ className: "flex items-center gap-1.5 text-success-500",
211
+ children: [/* @__PURE__ */ f(s, { size: 14 }), /* @__PURE__ */ f("span", {
212
+ className: "text-xs",
213
+ children: i("channel.allRequiredFieldsFilled", "All required fields filled")
214
+ })]
215
+ }) : /* @__PURE__ */ p("div", {
216
+ className: "flex items-center gap-1.5 text-warning-500",
217
+ children: [/* @__PURE__ */ f(o, { size: 14 }), /* @__PURE__ */ p("span", {
218
+ className: "text-xs",
219
+ children: [
220
+ l.length,
221
+ " ",
222
+ i("channel.fieldsNeedAttention", "field(s) need attention")
223
+ ]
224
+ })]
225
+ });
226
+ }
227
+ //#endregion
228
+ export { m as AdapterCredentialsForm, h as CredentialValidationStatus };
229
+
230
+ //# sourceMappingURL=AdapterCredentialsForm.js.map