@burdenoff/microfe-botmanor 2026.1027.2 → 2026.1027.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botlit/BotlitRoutes.js +142 -132
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/components/AgentApprovalPanel.js +144 -126
- package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
- package/dist/botlit/components/ModelRegistrationPanel.js +4 -4
- package/dist/botlit/components/VersionHistoryPanel.js +92 -83
- package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
- package/dist/botlit/pages/A2AAgentDetailPage.js +212 -203
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/A2ARegistryPage.js +129 -117
- package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
- package/dist/botlit/pages/AgentApprovalsPage.js +122 -110
- package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
- package/dist/botlit/pages/AgentBuilderPage.js +18 -18
- package/dist/botlit/pages/AgentDetailPage.js +298 -273
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentsListPage.js +145 -121
- package/dist/botlit/pages/AgentsListPage.js.map +1 -1
- package/dist/botlit/pages/BotChannelsTab.js +238 -226
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
- package/dist/botlit/pages/BotDetailPage.js +307 -288
- package/dist/botlit/pages/BotDetailPage.js.map +1 -1
- package/dist/botlit/pages/BotWorkflowTab.js +125 -116
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
- package/dist/botlit/pages/BotsListPage.js +159 -144
- package/dist/botlit/pages/BotsListPage.js.map +1 -1
- package/dist/botlit/pages/BucketsPage.js +279 -258
- package/dist/botlit/pages/BucketsPage.js.map +1 -1
- package/dist/botlit/pages/ChannelDetailPage.js +346 -328
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
- package/dist/botlit/pages/ChannelRoutesPage.js +10 -10
- package/dist/botlit/pages/ChannelsPage.js +163 -148
- package/dist/botlit/pages/ChannelsPage.js.map +1 -1
- package/dist/botlit/pages/DashboardPage.js +129 -114
- package/dist/botlit/pages/DashboardPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionDetailPage.js +145 -139
- package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionsPage.js +14 -14
- package/dist/botlit/pages/InstalledPackagesPage.js +245 -227
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +168 -156
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBasesPage.js +91 -79
- package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
- package/dist/botlit/pages/MCPServerDetailPage.js +200 -188
- package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
- package/dist/botlit/pages/MCPServersPage.js +170 -155
- package/dist/botlit/pages/MCPServersPage.js.map +1 -1
- package/dist/botlit/pages/PoliciesPage.js +113 -104
- package/dist/botlit/pages/PoliciesPage.js.map +1 -1
- package/dist/botlit/pages/PolicyDetailPage.js +145 -133
- package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptStudioPage.js +106 -97
- package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplateDetailPage.js +359 -347
- package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplatesPage.js +127 -112
- package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfileDetailPage.js +219 -210
- package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfilesPage.js +112 -103
- package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.js +264 -252
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/pages/SkillDetailPage.js +235 -226
- package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
- package/dist/botlit/pages/SkillsPage.js +115 -106
- package/dist/botlit/pages/SkillsPage.js.map +1 -1
- package/dist/botlit/pages/StorePackageDetailPage.js +194 -188
- package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
- package/dist/botlit/pages/StorePage.js +161 -155
- package/dist/botlit/pages/StorePage.js.map +1 -1
- package/dist/botlit/permissions/PermissionRequired.js +45 -0
- package/dist/botlit/permissions/PermissionRequired.js.map +1 -0
- package/dist/botlit/permissions/botmanorPermissions.js +72 -0
- package/dist/botlit/permissions/botmanorPermissions.js.map +1 -0
- package/dist/botlit/permissions/index.js +3 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js +19 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -0
- 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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
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
|
|
14
|
-
import { GlassCard as
|
|
15
|
-
import { Fragment as
|
|
16
|
-
import { Link as
|
|
17
|
-
import { ArrowRight as
|
|
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
|
|
22
|
+
var R = ({ type: e, className: t }) => {
|
|
20
23
|
switch (e) {
|
|
21
|
-
case "SLACK": return /* @__PURE__ */
|
|
22
|
-
case "DISCORD": return /* @__PURE__ */
|
|
23
|
-
case "TEAMS": return /* @__PURE__ */
|
|
24
|
-
case "WEB_WIDGET": return /* @__PURE__ */
|
|
25
|
-
case "WEBHOOK": return /* @__PURE__ */
|
|
26
|
-
default: return /* @__PURE__ */
|
|
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
|
-
},
|
|
29
|
-
let
|
|
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
|
|
34
|
+
for (let t of G) e.set(t.connectorId, (e.get(t.connectorId) ?? 0) + 1);
|
|
32
35
|
return e;
|
|
33
|
-
}, [
|
|
34
|
-
return /* @__PURE__ */
|
|
35
|
-
title:
|
|
36
|
-
description:
|
|
37
|
-
actions: /* @__PURE__ */
|
|
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__ */
|
|
42
|
+
children: [/* @__PURE__ */ T(o, {
|
|
40
43
|
variant: "outline",
|
|
41
|
-
children: /* @__PURE__ */
|
|
42
|
-
to:
|
|
43
|
-
children:
|
|
44
|
+
children: /* @__PURE__ */ T(D, {
|
|
45
|
+
to: j("channels/routes"),
|
|
46
|
+
children: A("botlit.channels.actions.viewRoutes", "View Routes")
|
|
44
47
|
})
|
|
45
|
-
}), /* @__PURE__ */
|
|
46
|
-
|
|
47
|
-
children: /* @__PURE__ */
|
|
48
|
-
|
|
49
|
-
children:
|
|
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__ */
|
|
59
|
+
children: /* @__PURE__ */ E("div", {
|
|
54
60
|
className: "space-y-6",
|
|
55
61
|
children: [
|
|
56
|
-
/* @__PURE__ */ C
|
|
57
|
-
icon: /* @__PURE__ */
|
|
58
|
-
children:
|
|
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__ */
|
|
66
|
+
/* @__PURE__ */ E("div", {
|
|
61
67
|
className: "flex gap-1 border-b border-border-subtle",
|
|
62
|
-
children: [/* @__PURE__ */
|
|
63
|
-
onClick: () =>
|
|
64
|
-
className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
|
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
|
-
|
|
72
|
+
A("botlit.channels.tabs.connectors", "Connectors"),
|
|
67
73
|
" (",
|
|
68
|
-
|
|
74
|
+
V.length,
|
|
69
75
|
")"
|
|
70
76
|
]
|
|
71
|
-
}), /* @__PURE__ */
|
|
72
|
-
onClick: () =>
|
|
73
|
-
className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
|
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
|
-
|
|
81
|
+
A("botlit.channels.tabs.routes", "Routes"),
|
|
76
82
|
" (",
|
|
77
|
-
|
|
83
|
+
G.length,
|
|
78
84
|
")"
|
|
79
85
|
]
|
|
80
86
|
})]
|
|
81
87
|
}),
|
|
82
|
-
/* @__PURE__ */
|
|
88
|
+
/* @__PURE__ */ E("div", {
|
|
83
89
|
className: "flex items-center gap-4",
|
|
84
|
-
children: [/* @__PURE__ */
|
|
90
|
+
children: [/* @__PURE__ */ E("div", {
|
|
85
91
|
className: "relative flex-1 max-w-md",
|
|
86
|
-
children: [/* @__PURE__ */
|
|
87
|
-
placeholder:
|
|
88
|
-
value:
|
|
89
|
-
onChange: (e) =>
|
|
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__ */
|
|
98
|
+
}), /* @__PURE__ */ T(o, {
|
|
93
99
|
variant: "outline",
|
|
94
|
-
leftIcon: /* @__PURE__ */
|
|
95
|
-
children:
|
|
100
|
+
leftIcon: /* @__PURE__ */ T(k, { size: 16 }),
|
|
101
|
+
children: A("botlit.channels.filters.filters", "Filters")
|
|
96
102
|
})]
|
|
97
103
|
}),
|
|
98
|
-
|
|
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__ */
|
|
105
|
-
}) :
|
|
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:
|
|
108
|
-
onRetry: () => void
|
|
109
|
-
}) :
|
|
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:
|
|
112
|
-
to:
|
|
113
|
-
children: /* @__PURE__ */
|
|
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__ */
|
|
121
|
+
children: [/* @__PURE__ */ T(u, { children: /* @__PURE__ */ E("div", {
|
|
116
122
|
className: "flex items-start justify-between",
|
|
117
|
-
children: [/* @__PURE__ */
|
|
123
|
+
children: [/* @__PURE__ */ E("div", {
|
|
118
124
|
className: "flex items-center gap-3",
|
|
119
|
-
children: [/* @__PURE__ */
|
|
125
|
+
children: [/* @__PURE__ */ T("div", {
|
|
120
126
|
className: "p-2 bg-action-primary-bg/10 rounded-lg",
|
|
121
|
-
children: /* @__PURE__ */
|
|
127
|
+
children: /* @__PURE__ */ T(R, {
|
|
122
128
|
type: e.type,
|
|
123
129
|
className: "h-5 w-5 text-primary"
|
|
124
130
|
})
|
|
125
|
-
}), /* @__PURE__ */
|
|
131
|
+
}), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T(d, {
|
|
126
132
|
className: "text-base",
|
|
127
133
|
children: e.name
|
|
128
|
-
}), /* @__PURE__ */
|
|
134
|
+
}), /* @__PURE__ */ T(l, {
|
|
129
135
|
className: "text-xs",
|
|
130
136
|
children: e.description
|
|
131
137
|
})] })]
|
|
132
|
-
}), /* @__PURE__ */
|
|
133
|
-
}) }), /* @__PURE__ */
|
|
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__ */
|
|
142
|
+
/* @__PURE__ */ E("div", {
|
|
137
143
|
className: "flex items-center justify-between",
|
|
138
|
-
children: [/* @__PURE__ */
|
|
144
|
+
children: [/* @__PURE__ */ T("span", {
|
|
139
145
|
className: "text-sm text-text-secondary",
|
|
140
|
-
children:
|
|
141
|
-
}), /* @__PURE__ */
|
|
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__ */
|
|
153
|
+
/* @__PURE__ */ E("div", {
|
|
148
154
|
className: "flex items-center justify-between",
|
|
149
|
-
children: [/* @__PURE__ */
|
|
155
|
+
children: [/* @__PURE__ */ T("span", {
|
|
150
156
|
className: "text-sm text-text-secondary",
|
|
151
|
-
children:
|
|
152
|
-
}), /* @__PURE__ */
|
|
157
|
+
children: A("botlit.channels.list.activeRoutes", "Active Routes")
|
|
158
|
+
}), /* @__PURE__ */ T(f, {
|
|
153
159
|
variant: "secondary",
|
|
154
|
-
children:
|
|
160
|
+
children: Y.get(e.id) ?? 0
|
|
155
161
|
})]
|
|
156
162
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ E("div", {
|
|
158
164
|
className: "pt-3 border-t border-border-subtle text-xs text-text-secondary",
|
|
159
165
|
children: [
|
|
160
|
-
|
|
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__ */
|
|
175
|
+
}) : /* @__PURE__ */ T(m, {
|
|
170
176
|
illustration: "empty-notifications",
|
|
171
|
-
title:
|
|
172
|
-
description:
|
|
173
|
-
action: /* @__PURE__ */
|
|
174
|
-
|
|
175
|
-
children: /* @__PURE__ */
|
|
176
|
-
|
|
177
|
-
children:
|
|
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
|
-
|
|
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__ */
|
|
188
|
-
}) :
|
|
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:
|
|
191
|
-
onRetry: () => void
|
|
192
|
-
}) :
|
|
199
|
+
error: q,
|
|
200
|
+
onRetry: () => void J()
|
|
201
|
+
}) : G.length > 0 ? /* @__PURE__ */ T("div", {
|
|
193
202
|
className: "space-y-4",
|
|
194
|
-
children:
|
|
203
|
+
children: G.map((e) => /* @__PURE__ */ T(s, { children: /* @__PURE__ */ T(c, {
|
|
195
204
|
className: "py-4",
|
|
196
|
-
children: /* @__PURE__ */
|
|
205
|
+
children: /* @__PURE__ */ E("div", {
|
|
197
206
|
className: "flex items-center justify-between",
|
|
198
|
-
children: [/* @__PURE__ */
|
|
207
|
+
children: [/* @__PURE__ */ T("div", {
|
|
199
208
|
className: "flex items-center gap-4",
|
|
200
|
-
children: /* @__PURE__ */
|
|
209
|
+
children: /* @__PURE__ */ E("div", {
|
|
201
210
|
className: "flex items-center gap-2 text-sm",
|
|
202
211
|
children: [
|
|
203
|
-
/* @__PURE__ */
|
|
212
|
+
/* @__PURE__ */ T(f, {
|
|
204
213
|
variant: "outline",
|
|
205
|
-
children:
|
|
214
|
+
children: _(e, "locationName") ?? e.locationId
|
|
206
215
|
}),
|
|
207
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ T(O, {
|
|
208
217
|
size: 16,
|
|
209
218
|
className: "text-text-secondary"
|
|
210
219
|
}),
|
|
211
|
-
/* @__PURE__ */
|
|
220
|
+
/* @__PURE__ */ T(f, {
|
|
212
221
|
variant: "secondary",
|
|
213
|
-
children:
|
|
222
|
+
children: _(e, "appName") ?? e.appId ?? "—"
|
|
214
223
|
})
|
|
215
224
|
]
|
|
216
225
|
})
|
|
217
|
-
}), /* @__PURE__ */
|
|
226
|
+
}), /* @__PURE__ */ E("div", {
|
|
218
227
|
className: "flex items-center gap-2",
|
|
219
|
-
children: [/* @__PURE__ */
|
|
228
|
+
children: [/* @__PURE__ */ T("span", {
|
|
220
229
|
className: "text-xs text-text-secondary",
|
|
221
230
|
children: n(e.createdAt)
|
|
222
|
-
}), /* @__PURE__ */
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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__ */
|
|
242
|
+
}) : /* @__PURE__ */ T(m, {
|
|
231
243
|
illustration: "empty-search",
|
|
232
|
-
title:
|
|
233
|
-
description:
|
|
234
|
-
action: /* @__PURE__ */
|
|
235
|
-
|
|
236
|
-
children:
|
|
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__ */
|
|
254
|
+
/* @__PURE__ */ E(S, {
|
|
240
255
|
treatment: "glass",
|
|
241
256
|
glow: !0,
|
|
242
257
|
className: "p-6",
|
|
243
|
-
children: [/* @__PURE__ */
|
|
258
|
+
children: [/* @__PURE__ */ E("div", {
|
|
244
259
|
className: "mb-4",
|
|
245
|
-
children: [/* @__PURE__ */
|
|
260
|
+
children: [/* @__PURE__ */ T("h2", {
|
|
246
261
|
className: "text-lg font-semibold tracking-tight text-text-primary",
|
|
247
|
-
children:
|
|
248
|
-
}), /* @__PURE__ */
|
|
262
|
+
children: A("botlit.channels.integrations.title", "Available Integrations")
|
|
263
|
+
}), /* @__PURE__ */ T("p", {
|
|
249
264
|
className: "text-sm text-text-secondary",
|
|
250
|
-
children:
|
|
265
|
+
children: A("botlit.channels.integrations.description", "Connect to popular messaging platforms")
|
|
251
266
|
})]
|
|
252
|
-
}), /* @__PURE__ */
|
|
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:
|
|
258
|
-
desc:
|
|
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:
|
|
263
|
-
desc:
|
|
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:
|
|
268
|
-
desc:
|
|
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:
|
|
273
|
-
desc:
|
|
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:
|
|
278
|
-
desc:
|
|
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:
|
|
283
|
-
desc:
|
|
297
|
+
name: A("botlit.channels.integrations.webhook", "Webhook"),
|
|
298
|
+
desc: A("botlit.channels.integrations.webhookDesc", "Custom integration")
|
|
284
299
|
}
|
|
285
|
-
].map((e) => /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
307
|
+
/* @__PURE__ */ T("p", {
|
|
293
308
|
className: "mt-2 font-medium text-sm",
|
|
294
309
|
children: e.name
|
|
295
310
|
}),
|
|
296
|
-
/* @__PURE__ */
|
|
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 {
|
|
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":";;;;;;;;;;;;;;;;;;;;;AAyCA,IAAM,KAAyD,EAAE,SAAM,mBAAgB;AACrF,SAAQ,GAAR;EACE,KAAK,QACH,QAAO,kBAAC,GAAD,EAAkB,cAAa,CAAA;EACxC,KAAK,UACH,QAAO,kBAAC,GAAD,EAAiB,cAAa,CAAA;EACvC,KAAK,QACH,QAAO,kBAAC,GAAD,EAA0B,cAAa,CAAA;EAChD,KAAK,aACH,QAAO,kBAAC,GAAD,EAAkB,cAAa,CAAA;EACxC,KAAK,UACH,QAAO,kBAAC,GAAD,EAAoB,cAAa,CAAA;EAC1C,QACE,QAAO,kBAAC,GAAD,EAA0B,cAAa,CAAA;;GAIvC,UAAyB;CACpC,IAAM,IAAI,GAAO,EACX,EAAE,eAAY,GAAW,EACzB,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,CAAC,GAAW,KAAgB,EAAkC,aAAa,EAE3E,EACJ,MAAM,GACN,SAAS,GACT,OAAO,GACP,SAAS,MACP,EANoB,SAAe,EAAE,WAAQ,GAAG,CAAC,EAAO,CAAC,CAMpB,EACnC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,GACP,SAAS,MACP,GAAkB,EAIhB,IAAwB,QAAc;EAC1C,IAAM,oBAAS,IAAI,KAAqB;AACxC,OAAK,IAAM,KAAS,EAClB,GAAO,IAAI,EAAM,cAAc,EAAO,IAAI,EAAM,YAAY,IAAI,KAAK,EAAE;AAEzE,SAAO;IACN,CAAC,EAAO,CAAC;AAEZ,QACE,kBAAC,GAAD;EACE,OAAO,EAAE,yBAAyB,WAAW;EAC7C,aAAa,EACX,+BACA,8DACD;EACD,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAQ,SAAQ;cACd,kBAAC,GAAD;KAAM,IAAI,EAAQ,kBAAkB;eACjC,EAAE,sCAAsC,cAAc;KAClD,CAAA;IACA,CAAA,EACT,kBAAC,GAAD;IAAwB,YAAY,EAAqB;cACvD,kBAAC,GAAD;KAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;eAClC,kBAAC,GAAD;MAAM,IAAI,EAAQ,eAAe;gBAC9B,EAAE,sCAAsC,cAAc;MAClD,CAAA;KACA,CAAA;IACc,CAAA,CACrB;;YAGR,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KAAa,MAAM,kBAAC,GAAD,EAAe,MAAM,IAAM,CAAA;eAC3C,EACC,2BACA,wUACD;KACW,CAAA;IAGd,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,eAAe,EAAa,aAAa;MACzC,WAAW,8DACT,MAAc,eACV,gCACA;gBALR;OAQG,EAAE,mCAAmC,aAAa;OAAC;OAAG,EAAW;OAAO;OAClE;SACT,kBAAC,UAAD;MACE,eAAe,EAAa,SAAS;MACrC,WAAW,8DACT,MAAc,WACV,gCACA;gBALR;OAQG,EAAE,+BAA+B,SAAS;OAAC;OAAG,EAAO;OAAO;OACtD;QACL;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAY,WAAU,wEAAyE,CAAA,EAC/F,kBAAC,GAAD;OACE,aAAa,EAAE,qCAAqC,qBAAqB,EACvE,KAAK,GACN,CAAC;OACF,OAAO;OACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;OAC1C,WAAU;OACV,CAAA,CACE;SACN,kBAAC,GAAD;MAAQ,SAAQ;MAAU,UAAU,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;gBACrD,EAAE,mCAAmC,UAAU;MACzC,CAAA,CACL;;IAGL,MAAc,gBACb,kBAAA,GAAA,EAAA,UACG,IACC,kBAAC,OAAD;KAAK,WAAU;eACZ;MAAC;MAAG;MAAG;MAAE,CAAC,KAAK,MACd,kBAAC,OAAD,EAEE,WAAU,+DACV,EAFK,EAEL,CACF;KACE,CAAA,GACJ,IACF,kBAAC,GAAD;KACE,UAAS;KACT,OAAO;KACP,eAAe,KAAK,GAAmB;KACvC,CAAA,GACA,EAAW,SAAS,IACtB,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAW,KAAK,MACf,kBAAC,GAAD;MAAyB,IAAI,EAAQ,YAAY,EAAU,KAAK;gBAC9D,kBAAC,GAAD;OAAM,WAAU;iBAAhB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBACb,kBAAC,GAAD;WAAa,MAAM,EAAU;WAAM,WAAU;WAAyB,CAAA;UAClE,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;UAAW,WAAU;oBAAa,EAAU;UAAiB,CAAA,EAC7D,kBAAC,GAAD;UAAiB,WAAU;oBACxB,EAAU;UACK,CAAA,CACd,EAAA,CAAA,CACF;YACN,kBAAC,GAAD,EAAa,QAAQ,EAAU,QAAU,CAAA,CACrC;WACK,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SAEE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAE,6BAA6B,OAAO;WAClC,CAAA,EACP,kBAAC,GAAD;WAAO,SAAQ;WAAU,WAAU;qBAChC,EAAU,KAAK,aAAa,CAAC,QAAQ,KAAK,IAAI;WACzC,CAAA,CACJ;;SAGN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAE,qCAAqC,gBAAgB;WACnD,CAAA,EACP,kBAAC,GAAD;WAAO,SAAQ;qBACZ,EAAsB,IAAI,EAAU,GAAG,IAAI;WACtC,CAAA,CACJ;;SAGN,kBAAC,OAAD;UAAK,WAAU;oBAAf;WACG,EAAE,gCAAgC,UAAU;WAAE;WAC9C,EAAmB,EAAU,UAAU;WACpC;;SACF;WACM,CAAA,CACT;;MACF,EAhDI,EAAU,GAgDd,CACP;KACE,CAAA,GAEN,kBAAC,GAAD;KACE,cAAa;KACb,OAAO,EAAE,0CAA0C,wBAAwB;KAC3E,aAAa,EACX,gDACA,yEACD;KACD,QACE,kBAAC,GAAD;MAAwB,YAAY,EAAqB;gBACvD,kBAAC,GAAD;OAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;iBAClC,kBAAC,GAAD;QAAM,IAAI,EAAQ,eAAe;kBAC9B,EAAE,sCAAsC,cAAc;QAClD,CAAA;OACA,CAAA;MACc,CAAA;KAE3B,CAAA,EAEH,CAAA;IAIJ,MAAc,YACb,kBAAA,GAAA,EAAA,UACG,IACC,kBAAC,OAAD;KAAK,WAAU;eACZ;MAAC;MAAG;MAAG;MAAE,CAAC,KAAK,MACd,kBAAC,OAAD,EAEE,WAAU,+DACV,EAFK,EAEL,CACF;KACE,CAAA,GACJ,IACF,kBAAC,GAAD;KACE,UAAS;KACT,OAAO;KACP,eAAe,KAAK,GAAe;KACnC,CAAA,GACA,EAAO,SAAS,IAClB,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAO,KAAK,MACX,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;MAAa,WAAU;gBACrB,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,GAAD;WAAO,SAAQ;qBACZ,EAAoB,GAAO,eAAe,IAAI,EAAM;WAC/C,CAAA;UACR,kBAAC,GAAD;WAAY,MAAM;WAAI,WAAU;WAAwB,CAAA;UACxD,kBAAC,GAAD;WAAO,SAAQ;qBACZ,EAAoB,GAAO,UAAU,IACpC,EAAM,SAAA;WAEF,CAAA;UACJ;;QACF,CAAA,EACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAmB,EAAM,UAAU;SAC/B,CAAA,EACP,kBAAC,GAAD;SAAwB,YAAY,EAAqB;mBACvD,kBAAC,GAAD;UAAQ,SAAQ;UAAQ,MAAK;oBAC3B,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;UACf,CAAA;SACc,CAAA,CACrB;UACF;;MACM,CAAA,EACT,EA5BI,EAAM,GA4BV,CACP;KACE,CAAA,GAEN,kBAAC,GAAD;KACE,cAAa;KACb,OAAO,EAAE,sCAAsC,uBAAuB;KACtE,aAAa,EACX,4CACA,+DACD;KACD,QACE,kBAAC,GAAD;MAAwB,YAAY,EAAqB;gBACvD,kBAAC,GAAD;OAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;iBACjC,EAAE,uCAAuC,eAAe;OAClD,CAAA;MACc,CAAA;KAE3B,CAAA,EAEH,CAAA;IAIL,kBAAC,GAAD;KAAW,WAAU;KAAQ,MAAA;KAAK,WAAU;eAA5C,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAE,sCAAsC,yBAAyB;OAC/D,CAAA,EACL,kBAAC,KAAD;OAAG,WAAU;iBACV,EACC,4CACA,yCACD;OACC,CAAA,CACA;SACN,kBAAC,OAAD;MAAK,WAAU;gBACZ;OACC;QACE,MAAM;QACN,MAAM,EAAE,0CAA0C,aAAa;QAC/D,MAAM,EAAE,8CAA8C,oBAAoB;QAC3E;OACD;QACE,MAAM;QACN,MAAM,EAAE,sCAAsC,QAAQ;QACtD,MAAM,EAAE,0CAA0C,wBAAwB;QAC3E;OACD;QACE,MAAM;QACN,MAAM,EAAE,sCAAsC,WAAW;QACzD,MAAM,EAAE,0CAA0C,YAAY;QAC/D;OACD;QACE,MAAM;QACN,MAAM,EAAE,wCAAwC,UAAU;QAC1D,MAAM,EAAE,4CAA4C,kBAAkB;QACvE;OACD;QACE,MAAM;QACN,MAAM,EAAE,yCAAyC,WAAW;QAC5D,MAAM,EAAE,6CAA6C,eAAe;QACrE;OACD;QACE,MAAM;QACN,MAAM,EAAE,wCAAwC,UAAU;QAC1D,MAAM,EAAE,4CAA4C,qBAAqB;QAC1E;OACF,CAAC,KAAK,MACL,kBAAC,UAAD;OAEE,WAAU;iBAFZ;QAIE,kBAAC,GAAD;SACE,MAAM,EAAY;SAClB,WAAU;SACV,CAAA;QACF,kBAAC,KAAD;SAAG,WAAU;mBAA4B,EAAY;SAAS,CAAA;QAC9D,kBAAC,KAAD;SAAG,WAAU;mBAA+B,EAAY;SAAS,CAAA;QAC1D;SATF,EAAY,KASV,CACT;MACE,CAAA,CACI;;IACR;;EACK,CAAA"}
|