@burdenoff/microfe-botmanor 2026.1027.2 → 2026.1028.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 (91) hide show
  1. package/dist/botlit/BotlitRoutes.js +142 -132
  2. package/dist/botlit/BotlitRoutes.js.map +1 -1
  3. package/dist/botlit/components/AgentApprovalPanel.js +144 -126
  4. package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
  5. package/dist/botlit/components/ModelRegistrationPanel.js +4 -4
  6. package/dist/botlit/components/RetentionStatusPanel.js +95 -0
  7. package/dist/botlit/components/RetentionStatusPanel.js.map +1 -0
  8. package/dist/botlit/components/VersionHistoryPanel.js +92 -83
  9. package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
  10. package/dist/botlit/hooks/index.js +1 -0
  11. package/dist/botlit/hooks/useRetention.js +31 -0
  12. package/dist/botlit/hooks/useRetention.js.map +1 -0
  13. package/dist/botlit/pages/A2AAgentDetailPage.js +212 -203
  14. package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
  15. package/dist/botlit/pages/A2ARegistryPage.js +129 -117
  16. package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
  17. package/dist/botlit/pages/AgentApprovalsPage.js +122 -110
  18. package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
  19. package/dist/botlit/pages/AgentBuilderPage.js +18 -18
  20. package/dist/botlit/pages/AgentDetailPage.js +298 -273
  21. package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
  22. package/dist/botlit/pages/AgentsListPage.js +145 -121
  23. package/dist/botlit/pages/AgentsListPage.js.map +1 -1
  24. package/dist/botlit/pages/BotChannelsTab.js +238 -226
  25. package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
  26. package/dist/botlit/pages/BotDetailPage.js +307 -288
  27. package/dist/botlit/pages/BotDetailPage.js.map +1 -1
  28. package/dist/botlit/pages/BotWorkflowTab.js +125 -116
  29. package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
  30. package/dist/botlit/pages/BotsListPage.js +159 -144
  31. package/dist/botlit/pages/BotsListPage.js.map +1 -1
  32. package/dist/botlit/pages/BucketsPage.js +279 -258
  33. package/dist/botlit/pages/BucketsPage.js.map +1 -1
  34. package/dist/botlit/pages/ChannelDetailPage.js +346 -328
  35. package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
  36. package/dist/botlit/pages/ChannelRoutesPage.js +10 -10
  37. package/dist/botlit/pages/ChannelsPage.js +163 -148
  38. package/dist/botlit/pages/ChannelsPage.js.map +1 -1
  39. package/dist/botlit/pages/DashboardPage.js +129 -114
  40. package/dist/botlit/pages/DashboardPage.js.map +1 -1
  41. package/dist/botlit/pages/ExecutionDetailPage.js +145 -139
  42. package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
  43. package/dist/botlit/pages/ExecutionsPage.js +14 -14
  44. package/dist/botlit/pages/InstalledPackagesPage.js +245 -227
  45. package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
  46. package/dist/botlit/pages/KnowledgeBaseDetailPage.js +168 -156
  47. package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
  48. package/dist/botlit/pages/KnowledgeBasesPage.js +91 -79
  49. package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
  50. package/dist/botlit/pages/MCPServerDetailPage.js +200 -188
  51. package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
  52. package/dist/botlit/pages/MCPServersPage.js +170 -155
  53. package/dist/botlit/pages/MCPServersPage.js.map +1 -1
  54. package/dist/botlit/pages/PoliciesPage.js +115 -104
  55. package/dist/botlit/pages/PoliciesPage.js.map +1 -1
  56. package/dist/botlit/pages/PolicyDetailPage.js +368 -324
  57. package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
  58. package/dist/botlit/pages/PromptStudioPage.js +106 -97
  59. package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
  60. package/dist/botlit/pages/PromptTemplateDetailPage.js +359 -347
  61. package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
  62. package/dist/botlit/pages/PromptTemplatesPage.js +127 -112
  63. package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
  64. package/dist/botlit/pages/RetrievalProfileDetailPage.js +219 -210
  65. package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
  66. package/dist/botlit/pages/RetrievalProfilesPage.js +112 -103
  67. package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
  68. package/dist/botlit/pages/SettingsPage.js +264 -252
  69. package/dist/botlit/pages/SettingsPage.js.map +1 -1
  70. package/dist/botlit/pages/SkillDetailPage.js +235 -226
  71. package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
  72. package/dist/botlit/pages/SkillsPage.js +115 -106
  73. package/dist/botlit/pages/SkillsPage.js.map +1 -1
  74. package/dist/botlit/pages/StorePackageDetailPage.js +194 -188
  75. package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
  76. package/dist/botlit/pages/StorePage.js +161 -155
  77. package/dist/botlit/pages/StorePage.js.map +1 -1
  78. package/dist/botlit/permissions/PermissionRequired.js +45 -0
  79. package/dist/botlit/permissions/PermissionRequired.js.map +1 -0
  80. package/dist/botlit/permissions/botmanorPermissions.js +72 -0
  81. package/dist/botlit/permissions/botmanorPermissions.js.map +1 -0
  82. package/dist/botlit/permissions/index.js +3 -0
  83. package/dist/botlit/permissions/useBotmanorPermissions.js +19 -0
  84. package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -0
  85. package/dist/botlit/utils/policyConfig.js +67 -42
  86. package/dist/botlit/utils/policyConfig.js.map +1 -1
  87. package/dist/generated/global-types.js.map +1 -1
  88. package/dist/generated/wspace-operations.js +90 -54
  89. package/dist/generated/wspace-operations.js.map +1 -1
  90. package/dist/generated/wspace-types.js.map +1 -1
  91. package/package.json +1 -1
@@ -1,163 +1,169 @@
1
1
  import { useTr as e } from "../../shared/hooks/useTr.js";
2
2
  import { useBotlit as t } from "../providers/BotlitProvider.js";
3
3
  import { formatRelativeTime as n } from "../utils/formatters.js";
4
- import { PageLayout as r } from "../components/PageLayout.js";
5
- import { Card as i, CardContent as a, CardDescription as o, CardHeader as s, CardTitle as c } from "../components/Card.js";
6
- import { Button as l } from "../components/Button.js";
7
- import { Badge as u, StatusBadge as d } from "../components/Badge.js";
8
- import { EmptyState as f } from "../components/EmptyState.js";
9
- import { Input as p } from "../components/Input.js";
10
- import { ErrorState as m } from "../components/ErrorState.js";
11
- import { routeMetadataString as h, useChannelConnectors as g, useChannelRoutes as _ } from "../hooks/useChannels.js";
4
+ import { BOTMANOR_PERMISSIONS as r } from "../permissions/botmanorPermissions.js";
5
+ import { BotmanorPermissionGate as i } from "../permissions/useBotmanorPermissions.js";
6
+ import { PageLayout as a } from "../components/PageLayout.js";
7
+ import { Button as o } from "../components/Button.js";
8
+ import "../permissions/index.js";
9
+ import { Card as s, CardContent as c, CardDescription as l, CardHeader as u, CardTitle as d } from "../components/Card.js";
10
+ import { Badge as f, StatusBadge as p } from "../components/Badge.js";
11
+ import { EmptyState as m } from "../components/EmptyState.js";
12
+ import { Input as h } from "../components/Input.js";
13
+ import { ErrorState as g } from "../components/ErrorState.js";
14
+ import { routeMetadataString as _, useChannelConnectors as v, useChannelRoutes as y } from "../hooks/useChannels.js";
12
15
  import "../hooks/index.js";
13
- import { useMemo as v, useState as y } from "react";
14
- import { GlassCard as b, PagePurpose as x } from "@burdenoff/fe-libs/ui";
15
- import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
16
- import { Link as T } from "react-router";
17
- import { ArrowRight as E, Filter as D, Globe as O, Hash as k, MessageSquare as A, Plus as j, Search as M, Settings as N, Slack as P, Webhook as F } from "lucide-react";
16
+ import { useMemo as b, useState as x } from "react";
17
+ import { GlassCard as S, PagePurpose as C } from "@burdenoff/fe-libs/ui";
18
+ import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
19
+ import { Link as D } from "react-router";
20
+ import { ArrowRight as O, Filter as k, Globe as A, Hash as j, MessageSquare as M, Plus as N, Search as P, Settings as F, Slack as I, Webhook as L } from "lucide-react";
18
21
  //#region src/botlit/pages/ChannelsPage.tsx
19
- var I = ({ type: e, className: t }) => {
22
+ var R = ({ type: e, className: t }) => {
20
23
  switch (e) {
21
- case "SLACK": return /* @__PURE__ */ C(P, { className: t });
22
- case "DISCORD": return /* @__PURE__ */ C(k, { className: t });
23
- case "TEAMS": return /* @__PURE__ */ C(A, { className: t });
24
- case "WEB_WIDGET": return /* @__PURE__ */ C(O, { className: t });
25
- case "WEBHOOK": return /* @__PURE__ */ C(F, { className: t });
26
- default: return /* @__PURE__ */ C(A, { className: t });
24
+ case "SLACK": return /* @__PURE__ */ T(I, { className: t });
25
+ case "DISCORD": return /* @__PURE__ */ T(j, { className: t });
26
+ case "TEAMS": return /* @__PURE__ */ T(M, { className: t });
27
+ case "WEB_WIDGET": return /* @__PURE__ */ T(A, { className: t });
28
+ case "WEBHOOK": return /* @__PURE__ */ T(L, { className: t });
29
+ default: return /* @__PURE__ */ T(M, { className: t });
27
30
  }
28
- }, L = () => {
29
- let O = e(), { getPath: k } = t(), [P, F] = y(""), [L, R] = y("connectors"), { data: z, loading: B, error: V, refetch: H } = g(v(() => ({ search: P }), [P])), { data: U, loading: W, error: G, refetch: K } = _(), q = v(() => {
31
+ }, z = () => {
32
+ let A = e(), { getPath: j } = t(), [I, L] = x(""), [z, B] = x("connectors"), { data: V, loading: H, error: U, refetch: W } = v(b(() => ({ search: I }), [I])), { data: G, loading: K, error: q, refetch: J } = y(), Y = b(() => {
30
33
  let e = /* @__PURE__ */ new Map();
31
- for (let t of U) e.set(t.connectorId, (e.get(t.connectorId) ?? 0) + 1);
34
+ for (let t of G) e.set(t.connectorId, (e.get(t.connectorId) ?? 0) + 1);
32
35
  return e;
33
- }, [U]);
34
- return /* @__PURE__ */ C(r, {
35
- title: O("botlit.channels.title", "Channels"),
36
- description: O("botlit.channels.description", "Connect agents to messaging platforms and configure routing"),
37
- actions: /* @__PURE__ */ w("div", {
36
+ }, [G]);
37
+ return /* @__PURE__ */ T(a, {
38
+ title: A("botlit.channels.title", "Channels"),
39
+ description: A("botlit.channels.description", "Connect agents to messaging platforms and configure routing"),
40
+ actions: /* @__PURE__ */ E("div", {
38
41
  className: "flex gap-2",
39
- children: [/* @__PURE__ */ C(l, {
42
+ children: [/* @__PURE__ */ T(o, {
40
43
  variant: "outline",
41
- children: /* @__PURE__ */ C(T, {
42
- to: k("channels/routes"),
43
- children: O("botlit.channels.actions.viewRoutes", "View Routes")
44
+ children: /* @__PURE__ */ T(D, {
45
+ to: j("channels/routes"),
46
+ children: A("botlit.channels.actions.viewRoutes", "View Routes")
44
47
  })
45
- }), /* @__PURE__ */ C(l, {
46
- leftIcon: /* @__PURE__ */ C(j, { size: 16 }),
47
- children: /* @__PURE__ */ C(T, {
48
- to: k("channels/new"),
49
- children: O("botlit.channels.actions.addChannel", "Add Channel")
48
+ }), /* @__PURE__ */ T(i, {
49
+ permission: r.CHANNEL_CREATE,
50
+ children: /* @__PURE__ */ T(o, {
51
+ leftIcon: /* @__PURE__ */ T(N, { size: 16 }),
52
+ children: /* @__PURE__ */ T(D, {
53
+ to: j("channels/new"),
54
+ children: A("botlit.channels.actions.addChannel", "Add Channel")
55
+ })
50
56
  })
51
57
  })]
52
58
  }),
53
- children: /* @__PURE__ */ w("div", {
59
+ children: /* @__PURE__ */ E("div", {
54
60
  className: "space-y-6",
55
61
  children: [
56
- /* @__PURE__ */ C(x, {
57
- icon: /* @__PURE__ */ C(A, { size: 18 }),
58
- children: O("botlit.channels.purpose", "Channels are where your bots actually talk to people. Connect a messaging platform — a website chat widget, Slack, Microsoft Teams, Discord, WhatsApp or a custom webhook — then add a route that points an incoming location at the bot that should answer. Use this page to manage those connectors and routing rules in one place.")
62
+ /* @__PURE__ */ T(C, {
63
+ icon: /* @__PURE__ */ T(M, { size: 18 }),
64
+ children: A("botlit.channels.purpose", "Channels are where your bots actually talk to people. Connect a messaging platform — a website chat widget, Slack, Microsoft Teams, Discord, WhatsApp or a custom webhook — then add a route that points an incoming location at the bot that should answer. Use this page to manage those connectors and routing rules in one place.")
59
65
  }),
60
- /* @__PURE__ */ w("div", {
66
+ /* @__PURE__ */ E("div", {
61
67
  className: "flex gap-1 border-b border-border-subtle",
62
- children: [/* @__PURE__ */ w("button", {
63
- onClick: () => R("connectors"),
64
- className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${L === "connectors" ? "border-primary text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
68
+ children: [/* @__PURE__ */ E("button", {
69
+ onClick: () => B("connectors"),
70
+ className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${z === "connectors" ? "border-primary text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
65
71
  children: [
66
- O("botlit.channels.tabs.connectors", "Connectors"),
72
+ A("botlit.channels.tabs.connectors", "Connectors"),
67
73
  " (",
68
- z.length,
74
+ V.length,
69
75
  ")"
70
76
  ]
71
- }), /* @__PURE__ */ w("button", {
72
- onClick: () => R("routes"),
73
- className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${L === "routes" ? "border-primary text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
77
+ }), /* @__PURE__ */ E("button", {
78
+ onClick: () => B("routes"),
79
+ className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${z === "routes" ? "border-primary text-primary" : "border-transparent text-text-secondary hover:text-text-primary"}`,
74
80
  children: [
75
- O("botlit.channels.tabs.routes", "Routes"),
81
+ A("botlit.channels.tabs.routes", "Routes"),
76
82
  " (",
77
- U.length,
83
+ G.length,
78
84
  ")"
79
85
  ]
80
86
  })]
81
87
  }),
82
- /* @__PURE__ */ w("div", {
88
+ /* @__PURE__ */ E("div", {
83
89
  className: "flex items-center gap-4",
84
- children: [/* @__PURE__ */ w("div", {
90
+ children: [/* @__PURE__ */ E("div", {
85
91
  className: "relative flex-1 max-w-md",
86
- children: [/* @__PURE__ */ C(M, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ C(p, {
87
- placeholder: O("botlit.channels.searchPlaceholder", "Search {{tab}}...", { tab: L }),
88
- value: P,
89
- onChange: (e) => F(e.target.value),
92
+ children: [/* @__PURE__ */ T(P, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ T(h, {
93
+ placeholder: A("botlit.channels.searchPlaceholder", "Search {{tab}}...", { tab: z }),
94
+ value: I,
95
+ onChange: (e) => L(e.target.value),
90
96
  className: "pl-9"
91
97
  })]
92
- }), /* @__PURE__ */ C(l, {
98
+ }), /* @__PURE__ */ T(o, {
93
99
  variant: "outline",
94
- leftIcon: /* @__PURE__ */ C(D, { size: 16 }),
95
- children: O("botlit.channels.filters.filters", "Filters")
100
+ leftIcon: /* @__PURE__ */ T(k, { size: 16 }),
101
+ children: A("botlit.channels.filters.filters", "Filters")
96
102
  })]
97
103
  }),
98
- L === "connectors" && /* @__PURE__ */ C(S, { children: B ? /* @__PURE__ */ C("div", {
104
+ z === "connectors" && /* @__PURE__ */ T(w, { children: H ? /* @__PURE__ */ T("div", {
99
105
  className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
100
106
  children: [
101
107
  1,
102
108
  2,
103
109
  3
104
- ].map((e) => /* @__PURE__ */ C("div", { className: "h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
105
- }) : V ? /* @__PURE__ */ C(m, {
110
+ ].map((e) => /* @__PURE__ */ T("div", { className: "h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
111
+ }) : U ? /* @__PURE__ */ T(g, {
106
112
  resource: "channel connectors",
107
- error: V,
108
- onRetry: () => void H()
109
- }) : z.length > 0 ? /* @__PURE__ */ C("div", {
113
+ error: U,
114
+ onRetry: () => void W()
115
+ }) : V.length > 0 ? /* @__PURE__ */ T("div", {
110
116
  className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
111
- children: z.map((e) => /* @__PURE__ */ C(T, {
112
- to: k(`channels/${e.id}`),
113
- children: /* @__PURE__ */ w(i, {
117
+ children: V.map((e) => /* @__PURE__ */ T(D, {
118
+ to: j(`channels/${e.id}`),
119
+ children: /* @__PURE__ */ E(s, {
114
120
  className: "h-full hover:border-primary/50 transition-colors cursor-pointer",
115
- children: [/* @__PURE__ */ C(s, { children: /* @__PURE__ */ w("div", {
121
+ children: [/* @__PURE__ */ T(u, { children: /* @__PURE__ */ E("div", {
116
122
  className: "flex items-start justify-between",
117
- children: [/* @__PURE__ */ w("div", {
123
+ children: [/* @__PURE__ */ E("div", {
118
124
  className: "flex items-center gap-3",
119
- children: [/* @__PURE__ */ C("div", {
125
+ children: [/* @__PURE__ */ T("div", {
120
126
  className: "p-2 bg-action-primary-bg/10 rounded-lg",
121
- children: /* @__PURE__ */ C(I, {
127
+ children: /* @__PURE__ */ T(R, {
122
128
  type: e.type,
123
129
  className: "h-5 w-5 text-primary"
124
130
  })
125
- }), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C(c, {
131
+ }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T(d, {
126
132
  className: "text-base",
127
133
  children: e.name
128
- }), /* @__PURE__ */ C(o, {
134
+ }), /* @__PURE__ */ T(l, {
129
135
  className: "text-xs",
130
136
  children: e.description
131
137
  })] })]
132
- }), /* @__PURE__ */ C(d, { status: e.status })]
133
- }) }), /* @__PURE__ */ C(a, { children: /* @__PURE__ */ w("div", {
138
+ }), /* @__PURE__ */ T(p, { status: e.status })]
139
+ }) }), /* @__PURE__ */ T(c, { children: /* @__PURE__ */ E("div", {
134
140
  className: "space-y-3",
135
141
  children: [
136
- /* @__PURE__ */ w("div", {
142
+ /* @__PURE__ */ E("div", {
137
143
  className: "flex items-center justify-between",
138
- children: [/* @__PURE__ */ C("span", {
144
+ children: [/* @__PURE__ */ T("span", {
139
145
  className: "text-sm text-text-secondary",
140
- children: O("botlit.channels.list.type", "Type")
141
- }), /* @__PURE__ */ C(u, {
146
+ children: A("botlit.channels.list.type", "Type")
147
+ }), /* @__PURE__ */ T(f, {
142
148
  variant: "outline",
143
149
  className: "capitalize",
144
150
  children: e.type.toLowerCase().replace("_", " ")
145
151
  })]
146
152
  }),
147
- /* @__PURE__ */ w("div", {
153
+ /* @__PURE__ */ E("div", {
148
154
  className: "flex items-center justify-between",
149
- children: [/* @__PURE__ */ C("span", {
155
+ children: [/* @__PURE__ */ T("span", {
150
156
  className: "text-sm text-text-secondary",
151
- children: O("botlit.channels.list.activeRoutes", "Active Routes")
152
- }), /* @__PURE__ */ C(u, {
157
+ children: A("botlit.channels.list.activeRoutes", "Active Routes")
158
+ }), /* @__PURE__ */ T(f, {
153
159
  variant: "secondary",
154
- children: q.get(e.id) ?? 0
160
+ children: Y.get(e.id) ?? 0
155
161
  })]
156
162
  }),
157
- /* @__PURE__ */ w("div", {
163
+ /* @__PURE__ */ E("div", {
158
164
  className: "pt-3 border-t border-border-subtle text-xs text-text-secondary",
159
165
  children: [
160
- O("botlit.botsList.createdLabel", "Created"),
166
+ A("botlit.botsList.createdLabel", "Created"),
161
167
  " ",
162
168
  n(e.createdAt)
163
169
  ]
@@ -166,134 +172,143 @@ var I = ({ type: e, className: t }) => {
166
172
  }) })]
167
173
  })
168
174
  }, e.id))
169
- }) : /* @__PURE__ */ C(f, {
175
+ }) : /* @__PURE__ */ T(m, {
170
176
  illustration: "empty-notifications",
171
- title: O("botlit.channels.empty.connectors.title", "No channel connectors"),
172
- description: O("botlit.channels.empty.connectors.description", "Connect messaging platforms to deploy agents across multiple channels."),
173
- action: /* @__PURE__ */ C(l, {
174
- leftIcon: /* @__PURE__ */ C(j, { size: 16 }),
175
- children: /* @__PURE__ */ C(T, {
176
- to: k("channels/new"),
177
- children: O("botlit.channels.actions.addChannel", "Add Channel")
177
+ title: A("botlit.channels.empty.connectors.title", "No channel connectors"),
178
+ description: A("botlit.channels.empty.connectors.description", "Connect messaging platforms to deploy agents across multiple channels."),
179
+ action: /* @__PURE__ */ T(i, {
180
+ permission: r.CHANNEL_CREATE,
181
+ children: /* @__PURE__ */ T(o, {
182
+ leftIcon: /* @__PURE__ */ T(N, { size: 16 }),
183
+ children: /* @__PURE__ */ T(D, {
184
+ to: j("channels/new"),
185
+ children: A("botlit.channels.actions.addChannel", "Add Channel")
186
+ })
178
187
  })
179
188
  })
180
189
  }) }),
181
- L === "routes" && /* @__PURE__ */ C(S, { children: W ? /* @__PURE__ */ C("div", {
190
+ z === "routes" && /* @__PURE__ */ T(w, { children: K ? /* @__PURE__ */ T("div", {
182
191
  className: "space-y-4",
183
192
  children: [
184
193
  1,
185
194
  2,
186
195
  3
187
- ].map((e) => /* @__PURE__ */ C("div", { className: "h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
188
- }) : G ? /* @__PURE__ */ C(m, {
196
+ ].map((e) => /* @__PURE__ */ T("div", { className: "h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
197
+ }) : q ? /* @__PURE__ */ T(g, {
189
198
  resource: "channel routes",
190
- error: G,
191
- onRetry: () => void K()
192
- }) : U.length > 0 ? /* @__PURE__ */ C("div", {
199
+ error: q,
200
+ onRetry: () => void J()
201
+ }) : G.length > 0 ? /* @__PURE__ */ T("div", {
193
202
  className: "space-y-4",
194
- children: U.map((e) => /* @__PURE__ */ C(i, { children: /* @__PURE__ */ C(a, {
203
+ children: G.map((e) => /* @__PURE__ */ T(s, { children: /* @__PURE__ */ T(c, {
195
204
  className: "py-4",
196
- children: /* @__PURE__ */ w("div", {
205
+ children: /* @__PURE__ */ E("div", {
197
206
  className: "flex items-center justify-between",
198
- children: [/* @__PURE__ */ C("div", {
207
+ children: [/* @__PURE__ */ T("div", {
199
208
  className: "flex items-center gap-4",
200
- children: /* @__PURE__ */ w("div", {
209
+ children: /* @__PURE__ */ E("div", {
201
210
  className: "flex items-center gap-2 text-sm",
202
211
  children: [
203
- /* @__PURE__ */ C(u, {
212
+ /* @__PURE__ */ T(f, {
204
213
  variant: "outline",
205
- children: h(e, "locationName") ?? e.locationId
214
+ children: _(e, "locationName") ?? e.locationId
206
215
  }),
207
- /* @__PURE__ */ C(E, {
216
+ /* @__PURE__ */ T(O, {
208
217
  size: 16,
209
218
  className: "text-text-secondary"
210
219
  }),
211
- /* @__PURE__ */ C(u, {
220
+ /* @__PURE__ */ T(f, {
212
221
  variant: "secondary",
213
- children: h(e, "appName") ?? e.appId ?? "—"
222
+ children: _(e, "appName") ?? e.appId ?? "—"
214
223
  })
215
224
  ]
216
225
  })
217
- }), /* @__PURE__ */ w("div", {
226
+ }), /* @__PURE__ */ E("div", {
218
227
  className: "flex items-center gap-2",
219
- children: [/* @__PURE__ */ C("span", {
228
+ children: [/* @__PURE__ */ T("span", {
220
229
  className: "text-xs text-text-secondary",
221
230
  children: n(e.createdAt)
222
- }), /* @__PURE__ */ C(l, {
223
- variant: "ghost",
224
- size: "icon",
225
- children: /* @__PURE__ */ C(N, { size: 16 })
231
+ }), /* @__PURE__ */ T(i, {
232
+ permission: r.CHANNEL_UPDATE,
233
+ children: /* @__PURE__ */ T(o, {
234
+ variant: "ghost",
235
+ size: "icon",
236
+ children: /* @__PURE__ */ T(F, { size: 16 })
237
+ })
226
238
  })]
227
239
  })]
228
240
  })
229
241
  }) }, e.id))
230
- }) : /* @__PURE__ */ C(f, {
242
+ }) : /* @__PURE__ */ T(m, {
231
243
  illustration: "empty-search",
232
- title: O("botlit.channels.empty.routes.title", "No routes configured"),
233
- description: O("botlit.channels.empty.routes.description", "Create routes to connect channel locations to specific bots."),
234
- action: /* @__PURE__ */ C(l, {
235
- leftIcon: /* @__PURE__ */ C(j, { size: 16 }),
236
- children: O("botlit.channels.actions.createRoute", "Create Route")
244
+ title: A("botlit.channels.empty.routes.title", "No routes configured"),
245
+ description: A("botlit.channels.empty.routes.description", "Create routes to connect channel locations to specific bots."),
246
+ action: /* @__PURE__ */ T(i, {
247
+ permission: r.CHANNEL_CREATE,
248
+ children: /* @__PURE__ */ T(o, {
249
+ leftIcon: /* @__PURE__ */ T(N, { size: 16 }),
250
+ children: A("botlit.channels.actions.createRoute", "Create Route")
251
+ })
237
252
  })
238
253
  }) }),
239
- /* @__PURE__ */ w(b, {
254
+ /* @__PURE__ */ E(S, {
240
255
  treatment: "glass",
241
256
  glow: !0,
242
257
  className: "p-6",
243
- children: [/* @__PURE__ */ w("div", {
258
+ children: [/* @__PURE__ */ E("div", {
244
259
  className: "mb-4",
245
- children: [/* @__PURE__ */ C("h2", {
260
+ children: [/* @__PURE__ */ T("h2", {
246
261
  className: "text-lg font-semibold tracking-tight text-text-primary",
247
- children: O("botlit.channels.integrations.title", "Available Integrations")
248
- }), /* @__PURE__ */ C("p", {
262
+ children: A("botlit.channels.integrations.title", "Available Integrations")
263
+ }), /* @__PURE__ */ T("p", {
249
264
  className: "text-sm text-text-secondary",
250
- children: O("botlit.channels.integrations.description", "Connect to popular messaging platforms")
265
+ children: A("botlit.channels.integrations.description", "Connect to popular messaging platforms")
251
266
  })]
252
- }), /* @__PURE__ */ C("div", {
267
+ }), /* @__PURE__ */ T("div", {
253
268
  className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4",
254
269
  children: [
255
270
  {
256
271
  type: "WEB_WIDGET",
257
- name: O("botlit.channels.integrations.webWidget", "Web Widget"),
258
- desc: O("botlit.channels.integrations.webWidgetDesc", "Embed on websites")
272
+ name: A("botlit.channels.integrations.webWidget", "Web Widget"),
273
+ desc: A("botlit.channels.integrations.webWidgetDesc", "Embed on websites")
259
274
  },
260
275
  {
261
276
  type: "SLACK",
262
- name: O("botlit.channels.integrations.slack", "Slack"),
263
- desc: O("botlit.channels.integrations.slackDesc", "Workspace integration")
277
+ name: A("botlit.channels.integrations.slack", "Slack"),
278
+ desc: A("botlit.channels.integrations.slackDesc", "Workspace integration")
264
279
  },
265
280
  {
266
281
  type: "TEAMS",
267
- name: O("botlit.channels.integrations.teams", "MS Teams"),
268
- desc: O("botlit.channels.integrations.teamsDesc", "Teams app")
282
+ name: A("botlit.channels.integrations.teams", "MS Teams"),
283
+ desc: A("botlit.channels.integrations.teamsDesc", "Teams app")
269
284
  },
270
285
  {
271
286
  type: "DISCORD",
272
- name: O("botlit.channels.integrations.discord", "Discord"),
273
- desc: O("botlit.channels.integrations.discordDesc", "Bot integration")
287
+ name: A("botlit.channels.integrations.discord", "Discord"),
288
+ desc: A("botlit.channels.integrations.discordDesc", "Bot integration")
274
289
  },
275
290
  {
276
291
  type: "WHATSAPP",
277
- name: O("botlit.channels.integrations.whatsapp", "WhatsApp"),
278
- desc: O("botlit.channels.integrations.whatsappDesc", "Business API")
292
+ name: A("botlit.channels.integrations.whatsapp", "WhatsApp"),
293
+ desc: A("botlit.channels.integrations.whatsappDesc", "Business API")
279
294
  },
280
295
  {
281
296
  type: "WEBHOOK",
282
- name: O("botlit.channels.integrations.webhook", "Webhook"),
283
- desc: O("botlit.channels.integrations.webhookDesc", "Custom integration")
297
+ name: A("botlit.channels.integrations.webhook", "Webhook"),
298
+ desc: A("botlit.channels.integrations.webhookDesc", "Custom integration")
284
299
  }
285
- ].map((e) => /* @__PURE__ */ w("button", {
300
+ ].map((e) => /* @__PURE__ */ E("button", {
286
301
  className: "p-4 text-center border border-border-subtle rounded-lg hover:bg-accent transition-colors",
287
302
  children: [
288
- /* @__PURE__ */ C(I, {
303
+ /* @__PURE__ */ T(R, {
289
304
  type: e.type,
290
305
  className: "h-8 w-8 mx-auto text-text-secondary"
291
306
  }),
292
- /* @__PURE__ */ C("p", {
307
+ /* @__PURE__ */ T("p", {
293
308
  className: "mt-2 font-medium text-sm",
294
309
  children: e.name
295
310
  }),
296
- /* @__PURE__ */ C("p", {
311
+ /* @__PURE__ */ T("p", {
297
312
  className: "text-xs text-text-secondary",
298
313
  children: e.desc
299
314
  })
@@ -306,6 +321,6 @@ var I = ({ type: e, className: t }) => {
306
321
  });
307
322
  };
308
323
  //#endregion
309
- export { L as ChannelsPage };
324
+ export { z as ChannelsPage };
310
325
 
311
326
  //# sourceMappingURL=ChannelsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelsPage.js","names":[],"sources":["../../../src/botlit/pages/ChannelsPage.tsx"],"sourcesContent":["/**\n * Channels Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Plus,\n Search as SearchIcon,\n Filter,\n MessageSquare,\n Globe,\n Slack,\n Hash,\n Webhook,\n ArrowRight,\n Settings,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useChannelConnectors,\n useChannelRoutes,\n routeMetadataString,\n type ChannelConnectorRecord,\n type ChannelRouteRecord,\n} from '../hooks';\nimport { formatRelativeTime, MISSING_VALUE } from '../utils/formatters';\nimport type { ChannelType } from '../types';\n\nconst ChannelIcon: FC<{ type: string; className?: string }> = ({ type, className }) => {\n switch (type) {\n case 'SLACK':\n return <Slack className={className} />;\n case 'DISCORD':\n return <Hash className={className} />;\n case 'TEAMS':\n return <MessageSquare className={className} />;\n case 'WEB_WIDGET':\n return <Globe className={className} />;\n case 'WEBHOOK':\n return <Webhook className={className} />;\n default:\n return <MessageSquare className={className} />;\n }\n};\n\nexport const ChannelsPage: FC = () => {\n const t = useTr();\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const [activeTab, setActiveTab] = useState<'connectors' | 'routes'>('connectors');\n const connectorFilter = useMemo(() => ({ search }), [search]);\n const {\n data: connectors,\n loading: loadingConnectors,\n error: connectorsError,\n refetch: refetchConnectors,\n } = useChannelConnectors(connectorFilter);\n const {\n data: routes,\n loading: loadingRoutes,\n error: routesError,\n refetch: refetchRoutes,\n } = useChannelRoutes();\n\n // Routes are keyed by connector, so the per-connector count is derived here\n // rather than assuming a field the service does not return.\n const routeCountByConnector = useMemo(() => {\n const counts = new Map<string, number>();\n for (const route of routes) {\n counts.set(route.connectorId, (counts.get(route.connectorId) ?? 0) + 1);\n }\n return counts;\n }, [routes]);\n\n return (\n <PageLayout\n title={t('botlit.channels.title', 'Channels')}\n description={t(\n 'botlit.channels.description',\n 'Connect agents to messaging platforms and configure routing'\n )}\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\">\n <Link to={getPath('channels/routes')}>\n {t('botlit.channels.actions.viewRoutes', 'View Routes')}\n </Link>\n </Button>\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('channels/new')}>\n {t('botlit.channels.actions.addChannel', 'Add Channel')}\n </Link>\n </Button>\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<MessageSquare size={18} />}>\n {t(\n 'botlit.channels.purpose',\n 'Channels are where your bots actually talk to people. Connect a messaging platform — a website chat widget, Slack, Microsoft Teams, Discord, WhatsApp or a custom webhook — then add a route that points an incoming location at the bot that should answer. Use this page to manage those connectors and routing rules in one place.'\n )}\n </PagePurpose>\n\n {/* Tabs */}\n <div className=\"flex gap-1 border-b border-border-subtle\">\n <button\n onClick={() => setActiveTab('connectors')}\n className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${\n activeTab === 'connectors'\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n }`}\n >\n {t('botlit.channels.tabs.connectors', 'Connectors')} ({connectors.length})\n </button>\n <button\n onClick={() => setActiveTab('routes')}\n className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${\n activeTab === 'routes'\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n }`}\n >\n {t('botlit.channels.tabs.routes', 'Routes')} ({routes.length})\n </button>\n </div>\n\n {/* Search */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={t('botlit.channels.searchPlaceholder', 'Search {{tab}}...', {\n tab: activeTab,\n })}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Button variant=\"outline\" leftIcon={<Filter size={16} />}>\n {t('botlit.channels.filters.filters', 'Filters')}\n </Button>\n </div>\n\n {/* Connectors Tab */}\n {activeTab === 'connectors' && (\n <>\n {loadingConnectors ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : connectorsError ? (\n <ErrorState\n resource=\"channel connectors\"\n error={connectorsError}\n onRetry={() => void refetchConnectors()}\n />\n ) : connectors.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {connectors.map((connector: ChannelConnectorRecord) => (\n <Link key={connector.id} to={getPath(`channels/${connector.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <ChannelIcon type={connector.type} className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <CardTitle className=\"text-base\">{connector.name}</CardTitle>\n <CardDescription className=\"text-xs\">\n {connector.description}\n </CardDescription>\n </div>\n </div>\n <StatusBadge status={connector.status} />\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {/* Type */}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.channels.list.type', 'Type')}\n </span>\n <Badge variant=\"outline\" className=\"capitalize\">\n {connector.type.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n\n {/* Routes */}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.channels.list.activeRoutes', 'Active Routes')}\n </span>\n <Badge variant=\"secondary\">\n {routeCountByConnector.get(connector.id) ?? 0}\n </Badge>\n </div>\n\n {/* Footer */}\n <div className=\"pt-3 border-t border-border-subtle text-xs text-text-secondary\">\n {t('botlit.botsList.createdLabel', 'Created')}{' '}\n {formatRelativeTime(connector.createdAt)}\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-notifications\"\n title={t('botlit.channels.empty.connectors.title', 'No channel connectors')}\n description={t(\n 'botlit.channels.empty.connectors.description',\n 'Connect messaging platforms to deploy agents across multiple channels.'\n )}\n action={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('channels/new')}>\n {t('botlit.channels.actions.addChannel', 'Add Channel')}\n </Link>\n </Button>\n }\n />\n )}\n </>\n )}\n\n {/* Routes Tab */}\n {activeTab === 'routes' && (\n <>\n {loadingRoutes ? (\n <div className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : routesError ? (\n <ErrorState\n resource=\"channel routes\"\n error={routesError}\n onRetry={() => void refetchRoutes()}\n />\n ) : routes.length > 0 ? (\n <div className=\"space-y-4\">\n {routes.map((route: ChannelRouteRecord) => (\n <Card key={route.id}>\n <CardContent className=\"py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2 text-sm\">\n <Badge variant=\"outline\">\n {routeMetadataString(route, 'locationName') ?? route.locationId}\n </Badge>\n <ArrowRight size={16} className=\"text-text-secondary\" />\n <Badge variant=\"secondary\">\n {routeMetadataString(route, 'appName') ??\n route.appId ??\n MISSING_VALUE}\n </Badge>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(route.createdAt)}\n </span>\n <Button variant=\"ghost\" size=\"icon\">\n <Settings size={16} />\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n title={t('botlit.channels.empty.routes.title', 'No routes configured')}\n description={t(\n 'botlit.channels.empty.routes.description',\n 'Create routes to connect channel locations to specific bots.'\n )}\n action={\n <Button leftIcon={<Plus size={16} />}>\n {t('botlit.channels.actions.createRoute', 'Create Route')}\n </Button>\n }\n />\n )}\n </>\n )}\n\n {/* Available Integrations */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.channels.integrations.title', 'Available Integrations')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'botlit.channels.integrations.description',\n 'Connect to popular messaging platforms'\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4\">\n {[\n {\n type: 'WEB_WIDGET' as ChannelType,\n name: t('botlit.channels.integrations.webWidget', 'Web Widget'),\n desc: t('botlit.channels.integrations.webWidgetDesc', 'Embed on websites'),\n },\n {\n type: 'SLACK' as ChannelType,\n name: t('botlit.channels.integrations.slack', 'Slack'),\n desc: t('botlit.channels.integrations.slackDesc', 'Workspace integration'),\n },\n {\n type: 'TEAMS' as ChannelType,\n name: t('botlit.channels.integrations.teams', 'MS Teams'),\n desc: t('botlit.channels.integrations.teamsDesc', 'Teams app'),\n },\n {\n type: 'DISCORD' as ChannelType,\n name: t('botlit.channels.integrations.discord', 'Discord'),\n desc: t('botlit.channels.integrations.discordDesc', 'Bot integration'),\n },\n {\n type: 'WHATSAPP' as ChannelType,\n name: t('botlit.channels.integrations.whatsapp', 'WhatsApp'),\n desc: t('botlit.channels.integrations.whatsappDesc', 'Business API'),\n },\n {\n type: 'WEBHOOK' as ChannelType,\n name: t('botlit.channels.integrations.webhook', 'Webhook'),\n desc: t('botlit.channels.integrations.webhookDesc', 'Custom integration'),\n },\n ].map((integration) => (\n <button\n key={integration.type}\n className=\"p-4 text-center border border-border-subtle rounded-lg hover:bg-accent transition-colors\"\n >\n <ChannelIcon\n type={integration.type}\n className=\"h-8 w-8 mx-auto text-text-secondary\"\n />\n <p className=\"mt-2 font-medium text-sm\">{integration.name}</p>\n <p className=\"text-xs text-text-secondary\">{integration.desc}</p>\n </button>\n ))}\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ChannelsPage.js","names":[],"sources":["../../../src/botlit/pages/ChannelsPage.tsx"],"sourcesContent":["/**\n * Channels Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Plus,\n Search as SearchIcon,\n Filter,\n MessageSquare,\n Globe,\n Slack,\n Hash,\n Webhook,\n ArrowRight,\n Settings,\n} from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useChannelConnectors,\n useChannelRoutes,\n routeMetadataString,\n type ChannelConnectorRecord,\n type ChannelRouteRecord,\n} from '../hooks';\nimport { formatRelativeTime, MISSING_VALUE } from '../utils/formatters';\nimport type { ChannelType } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nconst ChannelIcon: FC<{ type: string; className?: string }> = ({ type, className }) => {\n switch (type) {\n case 'SLACK':\n return <Slack className={className} />;\n case 'DISCORD':\n return <Hash className={className} />;\n case 'TEAMS':\n return <MessageSquare className={className} />;\n case 'WEB_WIDGET':\n return <Globe className={className} />;\n case 'WEBHOOK':\n return <Webhook className={className} />;\n default:\n return <MessageSquare className={className} />;\n }\n};\n\nexport const ChannelsPage: FC = () => {\n const t = useTr();\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const [activeTab, setActiveTab] = useState<'connectors' | 'routes'>('connectors');\n const connectorFilter = useMemo(() => ({ search }), [search]);\n const {\n data: connectors,\n loading: loadingConnectors,\n error: connectorsError,\n refetch: refetchConnectors,\n } = useChannelConnectors(connectorFilter);\n const {\n data: routes,\n loading: loadingRoutes,\n error: routesError,\n refetch: refetchRoutes,\n } = useChannelRoutes();\n\n // Routes are keyed by connector, so the per-connector count is derived here\n // rather than assuming a field the service does not return.\n const routeCountByConnector = useMemo(() => {\n const counts = new Map<string, number>();\n for (const route of routes) {\n counts.set(route.connectorId, (counts.get(route.connectorId) ?? 0) + 1);\n }\n return counts;\n }, [routes]);\n\n return (\n <PageLayout\n title={t('botlit.channels.title', 'Channels')}\n description={t(\n 'botlit.channels.description',\n 'Connect agents to messaging platforms and configure routing'\n )}\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\">\n <Link to={getPath('channels/routes')}>\n {t('botlit.channels.actions.viewRoutes', 'View Routes')}\n </Link>\n </Button>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('channels/new')}>\n {t('botlit.channels.actions.addChannel', 'Add Channel')}\n </Link>\n </Button>\n </BotmanorPermissionGate>\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<MessageSquare size={18} />}>\n {t(\n 'botlit.channels.purpose',\n 'Channels are where your bots actually talk to people. Connect a messaging platform — a website chat widget, Slack, Microsoft Teams, Discord, WhatsApp or a custom webhook — then add a route that points an incoming location at the bot that should answer. Use this page to manage those connectors and routing rules in one place.'\n )}\n </PagePurpose>\n\n {/* Tabs */}\n <div className=\"flex gap-1 border-b border-border-subtle\">\n <button\n onClick={() => setActiveTab('connectors')}\n className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${\n activeTab === 'connectors'\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n }`}\n >\n {t('botlit.channels.tabs.connectors', 'Connectors')} ({connectors.length})\n </button>\n <button\n onClick={() => setActiveTab('routes')}\n className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${\n activeTab === 'routes'\n ? 'border-primary text-primary'\n : 'border-transparent text-text-secondary hover:text-text-primary'\n }`}\n >\n {t('botlit.channels.tabs.routes', 'Routes')} ({routes.length})\n </button>\n </div>\n\n {/* Search */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder={t('botlit.channels.searchPlaceholder', 'Search {{tab}}...', {\n tab: activeTab,\n })}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Button variant=\"outline\" leftIcon={<Filter size={16} />}>\n {t('botlit.channels.filters.filters', 'Filters')}\n </Button>\n </div>\n\n {/* Connectors Tab */}\n {activeTab === 'connectors' && (\n <>\n {loadingConnectors ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : connectorsError ? (\n <ErrorState\n resource=\"channel connectors\"\n error={connectorsError}\n onRetry={() => void refetchConnectors()}\n />\n ) : connectors.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {connectors.map((connector: ChannelConnectorRecord) => (\n <Link key={connector.id} to={getPath(`channels/${connector.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer\">\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <ChannelIcon type={connector.type} className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <CardTitle className=\"text-base\">{connector.name}</CardTitle>\n <CardDescription className=\"text-xs\">\n {connector.description}\n </CardDescription>\n </div>\n </div>\n <StatusBadge status={connector.status} />\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {/* Type */}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.channels.list.type', 'Type')}\n </span>\n <Badge variant=\"outline\" className=\"capitalize\">\n {connector.type.toLowerCase().replace('_', ' ')}\n </Badge>\n </div>\n\n {/* Routes */}\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {t('botlit.channels.list.activeRoutes', 'Active Routes')}\n </span>\n <Badge variant=\"secondary\">\n {routeCountByConnector.get(connector.id) ?? 0}\n </Badge>\n </div>\n\n {/* Footer */}\n <div className=\"pt-3 border-t border-border-subtle text-xs text-text-secondary\">\n {t('botlit.botsList.createdLabel', 'Created')}{' '}\n {formatRelativeTime(connector.createdAt)}\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-notifications\"\n title={t('botlit.channels.empty.connectors.title', 'No channel connectors')}\n description={t(\n 'botlit.channels.empty.connectors.description',\n 'Connect messaging platforms to deploy agents across multiple channels.'\n )}\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('channels/new')}>\n {t('botlit.channels.actions.addChannel', 'Add Channel')}\n </Link>\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </>\n )}\n\n {/* Routes Tab */}\n {activeTab === 'routes' && (\n <>\n {loadingRoutes ? (\n <div className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-20 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : routesError ? (\n <ErrorState\n resource=\"channel routes\"\n error={routesError}\n onRetry={() => void refetchRoutes()}\n />\n ) : routes.length > 0 ? (\n <div className=\"space-y-4\">\n {routes.map((route: ChannelRouteRecord) => (\n <Card key={route.id}>\n <CardContent className=\"py-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-2 text-sm\">\n <Badge variant=\"outline\">\n {routeMetadataString(route, 'locationName') ?? route.locationId}\n </Badge>\n <ArrowRight size={16} className=\"text-text-secondary\" />\n <Badge variant=\"secondary\">\n {routeMetadataString(route, 'appName') ??\n route.appId ??\n MISSING_VALUE}\n </Badge>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(route.createdAt)}\n </span>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_UPDATE}>\n <Button variant=\"ghost\" size=\"icon\">\n <Settings size={16} />\n </Button>\n </BotmanorPermissionGate>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n title={t('botlit.channels.empty.routes.title', 'No routes configured')}\n description={t(\n 'botlit.channels.empty.routes.description',\n 'Create routes to connect channel locations to specific bots.'\n )}\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.CHANNEL_CREATE}>\n <Button leftIcon={<Plus size={16} />}>\n {t('botlit.channels.actions.createRoute', 'Create Route')}\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n </>\n )}\n\n {/* Available Integrations */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.channels.integrations.title', 'Available Integrations')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t(\n 'botlit.channels.integrations.description',\n 'Connect to popular messaging platforms'\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4\">\n {[\n {\n type: 'WEB_WIDGET' as ChannelType,\n name: t('botlit.channels.integrations.webWidget', 'Web Widget'),\n desc: t('botlit.channels.integrations.webWidgetDesc', 'Embed on websites'),\n },\n {\n type: 'SLACK' as ChannelType,\n name: t('botlit.channels.integrations.slack', 'Slack'),\n desc: t('botlit.channels.integrations.slackDesc', 'Workspace integration'),\n },\n {\n type: 'TEAMS' as ChannelType,\n name: t('botlit.channels.integrations.teams', 'MS Teams'),\n desc: t('botlit.channels.integrations.teamsDesc', 'Teams app'),\n },\n {\n type: 'DISCORD' as ChannelType,\n name: t('botlit.channels.integrations.discord', 'Discord'),\n desc: t('botlit.channels.integrations.discordDesc', 'Bot integration'),\n },\n {\n type: 'WHATSAPP' as ChannelType,\n name: t('botlit.channels.integrations.whatsapp', 'WhatsApp'),\n desc: t('botlit.channels.integrations.whatsappDesc', 'Business API'),\n },\n {\n type: 'WEBHOOK' as ChannelType,\n name: t('botlit.channels.integrations.webhook', 'Webhook'),\n desc: t('botlit.channels.integrations.webhookDesc', 'Custom integration'),\n },\n ].map((integration) => (\n <button\n key={integration.type}\n className=\"p-4 text-center border border-border-subtle rounded-lg hover:bg-accent transition-colors\"\n >\n <ChannelIcon\n type={integration.type}\n className=\"h-8 w-8 mx-auto text-text-secondary\"\n />\n <p className=\"mt-2 font-medium text-sm\">{integration.name}</p>\n <p className=\"text-xs text-text-secondary\">{integration.desc}</p>\n </button>\n ))}\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}