@burdenoff/microfe-botmanor 2026.821.1 → 2026.925.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.
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/BotmanorRoot.js.map +1 -1
- package/dist/botlit/BotmanorRootInner.js +4 -4
- package/dist/botlit/BotmanorRootInner.js.map +1 -1
- package/dist/botlit/components/ErrorState.js +33 -29
- package/dist/botlit/components/ErrorState.js.map +1 -1
- package/dist/botlit/components/RouteLoader.js +52 -48
- package/dist/botlit/components/RouteLoader.js.map +1 -1
- package/dist/botlit/components/VersionHistoryPanel.js +74 -77
- package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
- package/dist/botlit/components/WorkspaceRequired.js +31 -30
- package/dist/botlit/components/WorkspaceRequired.js.map +1 -1
- package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -1
- package/dist/botlit/hooks/useConversations.js.map +1 -1
- package/dist/botlit/hooks/useLLMProviders.js.map +1 -1
- package/dist/botlit/pages/A2AAgentDetailPage.js +1 -1
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/A2ARegistryPage.js +116 -124
- package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
- package/dist/botlit/pages/AgentDetailPage.js +169 -172
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentsListPage.js +96 -90
- package/dist/botlit/pages/AgentsListPage.js.map +1 -1
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
- package/dist/botlit/pages/BotDetailPage.js +228 -231
- package/dist/botlit/pages/BotDetailPage.js.map +1 -1
- package/dist/botlit/pages/BotWorkflowTab.js +84 -87
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
- package/dist/botlit/pages/BotsListPage.js +144 -147
- package/dist/botlit/pages/BotsListPage.js.map +1 -1
- package/dist/botlit/pages/BucketsPage.js +3 -3
- package/dist/botlit/pages/BucketsPage.js.map +1 -1
- package/dist/botlit/pages/ChannelDetailPage.js +1 -1
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
- package/dist/botlit/pages/ChannelsPage.js +156 -149
- package/dist/botlit/pages/ChannelsPage.js.map +1 -1
- package/dist/botlit/pages/ChatPage.js +126 -129
- package/dist/botlit/pages/ChatPage.js.map +1 -1
- package/dist/botlit/pages/DashboardPage.js +111 -114
- package/dist/botlit/pages/DashboardPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionsPage.js +163 -159
- package/dist/botlit/pages/ExecutionsPage.js.map +1 -1
- package/dist/botlit/pages/InstalledPackagesPage.js +3 -3
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBasesPage.js +84 -78
- package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
- package/dist/botlit/pages/MCPServersPage.js +159 -154
- package/dist/botlit/pages/MCPServersPage.js.map +1 -1
- package/dist/botlit/pages/PoliciesPage.js +119 -114
- package/dist/botlit/pages/PoliciesPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfilesPage.js +102 -109
- package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.js +144 -159
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/pages/SkillsPage.js +122 -105
- package/dist/botlit/pages/SkillsPage.js.map +1 -1
- package/dist/botlit/pages/StorePage.js +176 -175
- package/dist/botlit/pages/StorePage.js.map +1 -1
- package/dist/botlit/providers/BotlitProvider.js.map +1 -1
- package/dist/botlit/store/botlitStore.js +1 -1
- package/dist/botlit/store/botlitStore.js.map +1 -1
- package/dist/botlit/utils/navigation.js.map +1 -1
- package/dist/shared/hooks/useTr.js +14 -0
- package/dist/shared/hooks/useTr.js.map +1 -0
- package/package.json +33 -9
|
@@ -1,292 +1,299 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
1
|
+
import { useTr as e } from "../../shared/hooks/useTr.js";
|
|
2
|
+
import { useBotlit as t } from "../providers/BotlitProvider.js";
|
|
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";
|
|
11
12
|
import "../hooks/index.js";
|
|
12
|
-
import { useMemo as
|
|
13
|
-
import { GlassCard as
|
|
14
|
-
import { Fragment as
|
|
15
|
-
import { Link as
|
|
16
|
-
import { ArrowRight as
|
|
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";
|
|
17
18
|
//#region src/botlit/pages/ChannelsPage.tsx
|
|
18
|
-
var
|
|
19
|
+
var I = ({ type: e, className: t }) => {
|
|
19
20
|
switch (e) {
|
|
20
|
-
case "SLACK": return /* @__PURE__ */
|
|
21
|
-
case "DISCORD": return /* @__PURE__ */
|
|
22
|
-
case "TEAMS": return /* @__PURE__ */
|
|
23
|
-
case "WEB_WIDGET": return /* @__PURE__ */
|
|
24
|
-
case "WEBHOOK": return /* @__PURE__ */
|
|
25
|
-
default: return /* @__PURE__ */
|
|
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 });
|
|
26
27
|
}
|
|
27
|
-
},
|
|
28
|
-
let { getPath:
|
|
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(() => {
|
|
29
30
|
let e = /* @__PURE__ */ new Map();
|
|
30
|
-
for (let t of
|
|
31
|
+
for (let t of U) e.set(t.connectorId, (e.get(t.connectorId) ?? 0) + 1);
|
|
31
32
|
return e;
|
|
32
|
-
}, [
|
|
33
|
-
return /* @__PURE__ */
|
|
34
|
-
title: "Channels",
|
|
35
|
-
description: "Connect agents to messaging platforms and configure routing",
|
|
36
|
-
actions: /* @__PURE__ */
|
|
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", {
|
|
37
38
|
className: "flex gap-2",
|
|
38
|
-
children: [/* @__PURE__ */
|
|
39
|
+
children: [/* @__PURE__ */ C(l, {
|
|
39
40
|
variant: "outline",
|
|
40
|
-
children: /* @__PURE__ */
|
|
41
|
-
to:
|
|
42
|
-
children: "View Routes"
|
|
41
|
+
children: /* @__PURE__ */ C(T, {
|
|
42
|
+
to: k("channels/routes"),
|
|
43
|
+
children: O("botlit.channels.actions.viewRoutes", "View Routes")
|
|
43
44
|
})
|
|
44
|
-
}), /* @__PURE__ */
|
|
45
|
-
leftIcon: /* @__PURE__ */
|
|
46
|
-
children: /* @__PURE__ */
|
|
47
|
-
to:
|
|
48
|
-
children: "Add Channel"
|
|
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")
|
|
49
50
|
})
|
|
50
51
|
})]
|
|
51
52
|
}),
|
|
52
|
-
children: /* @__PURE__ */
|
|
53
|
+
children: /* @__PURE__ */ w("div", {
|
|
53
54
|
className: "space-y-6",
|
|
54
55
|
children: [
|
|
55
|
-
/* @__PURE__ */
|
|
56
|
-
icon: /* @__PURE__ */
|
|
57
|
-
children: "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."
|
|
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.")
|
|
58
59
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
60
|
+
/* @__PURE__ */ w("div", {
|
|
60
61
|
className: "flex gap-1 border-b border-border-subtle",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
62
|
-
onClick: () =>
|
|
63
|
-
className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
|
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"}`,
|
|
64
65
|
children: [
|
|
65
|
-
"
|
|
66
|
-
|
|
66
|
+
O("botlit.channels.tabs.connectors", "Connectors"),
|
|
67
|
+
" (",
|
|
68
|
+
z.length,
|
|
67
69
|
")"
|
|
68
70
|
]
|
|
69
|
-
}), /* @__PURE__ */
|
|
70
|
-
onClick: () =>
|
|
71
|
-
className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${
|
|
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"}`,
|
|
72
74
|
children: [
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
+
O("botlit.channels.tabs.routes", "Routes"),
|
|
76
|
+
" (",
|
|
77
|
+
U.length,
|
|
75
78
|
")"
|
|
76
79
|
]
|
|
77
80
|
})]
|
|
78
81
|
}),
|
|
79
|
-
/* @__PURE__ */
|
|
82
|
+
/* @__PURE__ */ w("div", {
|
|
80
83
|
className: "flex items-center gap-4",
|
|
81
|
-
children: [/* @__PURE__ */
|
|
84
|
+
children: [/* @__PURE__ */ w("div", {
|
|
82
85
|
className: "relative flex-1 max-w-md",
|
|
83
|
-
children: [/* @__PURE__ */
|
|
84
|
-
placeholder:
|
|
85
|
-
value:
|
|
86
|
-
onChange: (e) =>
|
|
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),
|
|
87
90
|
className: "pl-9"
|
|
88
91
|
})]
|
|
89
|
-
}), /* @__PURE__ */
|
|
92
|
+
}), /* @__PURE__ */ C(l, {
|
|
90
93
|
variant: "outline",
|
|
91
|
-
leftIcon: /* @__PURE__ */
|
|
92
|
-
children: "Filters"
|
|
94
|
+
leftIcon: /* @__PURE__ */ C(D, { size: 16 }),
|
|
95
|
+
children: O("botlit.channels.filters.filters", "Filters")
|
|
93
96
|
})]
|
|
94
97
|
}),
|
|
95
|
-
|
|
98
|
+
L === "connectors" && /* @__PURE__ */ C(S, { children: B ? /* @__PURE__ */ C("div", {
|
|
96
99
|
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
97
100
|
children: [
|
|
98
101
|
1,
|
|
99
102
|
2,
|
|
100
103
|
3
|
|
101
|
-
].map((e) => /* @__PURE__ */
|
|
102
|
-
}) :
|
|
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, {
|
|
103
106
|
resource: "channel connectors",
|
|
104
|
-
error:
|
|
105
|
-
onRetry: () => void
|
|
106
|
-
}) :
|
|
107
|
+
error: V,
|
|
108
|
+
onRetry: () => void H()
|
|
109
|
+
}) : z.length > 0 ? /* @__PURE__ */ C("div", {
|
|
107
110
|
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
108
|
-
children:
|
|
109
|
-
to:
|
|
110
|
-
children: /* @__PURE__ */
|
|
111
|
+
children: z.map((e) => /* @__PURE__ */ C(T, {
|
|
112
|
+
to: k(`channels/${e.id}`),
|
|
113
|
+
children: /* @__PURE__ */ w(i, {
|
|
111
114
|
className: "h-full hover:border-primary/50 transition-colors cursor-pointer",
|
|
112
|
-
children: [/* @__PURE__ */
|
|
115
|
+
children: [/* @__PURE__ */ C(s, { children: /* @__PURE__ */ w("div", {
|
|
113
116
|
className: "flex items-start justify-between",
|
|
114
|
-
children: [/* @__PURE__ */
|
|
117
|
+
children: [/* @__PURE__ */ w("div", {
|
|
115
118
|
className: "flex items-center gap-3",
|
|
116
|
-
children: [/* @__PURE__ */
|
|
119
|
+
children: [/* @__PURE__ */ C("div", {
|
|
117
120
|
className: "p-2 bg-action-primary-bg/10 rounded-lg",
|
|
118
|
-
children: /* @__PURE__ */
|
|
121
|
+
children: /* @__PURE__ */ C(I, {
|
|
119
122
|
type: e.type,
|
|
120
123
|
className: "h-5 w-5 text-primary"
|
|
121
124
|
})
|
|
122
|
-
}), /* @__PURE__ */
|
|
125
|
+
}), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C(c, {
|
|
123
126
|
className: "text-base",
|
|
124
127
|
children: e.name
|
|
125
|
-
}), /* @__PURE__ */
|
|
128
|
+
}), /* @__PURE__ */ C(o, {
|
|
126
129
|
className: "text-xs",
|
|
127
130
|
children: e.description
|
|
128
131
|
})] })]
|
|
129
|
-
}), /* @__PURE__ */
|
|
130
|
-
}) }), /* @__PURE__ */
|
|
132
|
+
}), /* @__PURE__ */ C(d, { status: e.status })]
|
|
133
|
+
}) }), /* @__PURE__ */ C(a, { children: /* @__PURE__ */ w("div", {
|
|
131
134
|
className: "space-y-3",
|
|
132
135
|
children: [
|
|
133
|
-
/* @__PURE__ */
|
|
136
|
+
/* @__PURE__ */ w("div", {
|
|
134
137
|
className: "flex items-center justify-between",
|
|
135
|
-
children: [/* @__PURE__ */
|
|
138
|
+
children: [/* @__PURE__ */ C("span", {
|
|
136
139
|
className: "text-sm text-text-secondary",
|
|
137
|
-
children: "Type"
|
|
138
|
-
}), /* @__PURE__ */
|
|
140
|
+
children: O("botlit.channels.list.type", "Type")
|
|
141
|
+
}), /* @__PURE__ */ C(u, {
|
|
139
142
|
variant: "outline",
|
|
140
143
|
className: "capitalize",
|
|
141
144
|
children: e.type.toLowerCase().replace("_", " ")
|
|
142
145
|
})]
|
|
143
146
|
}),
|
|
144
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ w("div", {
|
|
145
148
|
className: "flex items-center justify-between",
|
|
146
|
-
children: [/* @__PURE__ */
|
|
149
|
+
children: [/* @__PURE__ */ C("span", {
|
|
147
150
|
className: "text-sm text-text-secondary",
|
|
148
|
-
children: "Active Routes"
|
|
149
|
-
}), /* @__PURE__ */
|
|
151
|
+
children: O("botlit.channels.list.activeRoutes", "Active Routes")
|
|
152
|
+
}), /* @__PURE__ */ C(u, {
|
|
150
153
|
variant: "secondary",
|
|
151
|
-
children:
|
|
154
|
+
children: q.get(e.id) ?? 0
|
|
152
155
|
})]
|
|
153
156
|
}),
|
|
154
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ w("div", {
|
|
155
158
|
className: "pt-3 border-t border-border-subtle text-xs text-text-secondary",
|
|
156
|
-
children: [
|
|
159
|
+
children: [
|
|
160
|
+
O("botlit.botsList.createdLabel", "Created"),
|
|
161
|
+
" ",
|
|
162
|
+
n(e.createdAt)
|
|
163
|
+
]
|
|
157
164
|
})
|
|
158
165
|
]
|
|
159
166
|
}) })]
|
|
160
167
|
})
|
|
161
168
|
}, e.id))
|
|
162
|
-
}) : /* @__PURE__ */
|
|
169
|
+
}) : /* @__PURE__ */ C(f, {
|
|
163
170
|
illustration: "empty-notifications",
|
|
164
|
-
title: "No channel connectors",
|
|
165
|
-
description: "Connect messaging platforms to deploy agents across multiple channels.",
|
|
166
|
-
action: /* @__PURE__ */
|
|
167
|
-
leftIcon: /* @__PURE__ */
|
|
168
|
-
children: /* @__PURE__ */
|
|
169
|
-
to:
|
|
170
|
-
children: "Add Channel"
|
|
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")
|
|
171
178
|
})
|
|
172
179
|
})
|
|
173
180
|
}) }),
|
|
174
|
-
|
|
181
|
+
L === "routes" && /* @__PURE__ */ C(S, { children: W ? /* @__PURE__ */ C("div", {
|
|
175
182
|
className: "space-y-4",
|
|
176
183
|
children: [
|
|
177
184
|
1,
|
|
178
185
|
2,
|
|
179
186
|
3
|
|
180
|
-
].map((e) => /* @__PURE__ */
|
|
181
|
-
}) :
|
|
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, {
|
|
182
189
|
resource: "channel routes",
|
|
183
|
-
error:
|
|
184
|
-
onRetry: () => void
|
|
185
|
-
}) :
|
|
190
|
+
error: G,
|
|
191
|
+
onRetry: () => void K()
|
|
192
|
+
}) : U.length > 0 ? /* @__PURE__ */ C("div", {
|
|
186
193
|
className: "space-y-4",
|
|
187
|
-
children:
|
|
194
|
+
children: U.map((e) => /* @__PURE__ */ C(i, { children: /* @__PURE__ */ C(a, {
|
|
188
195
|
className: "py-4",
|
|
189
|
-
children: /* @__PURE__ */
|
|
196
|
+
children: /* @__PURE__ */ w("div", {
|
|
190
197
|
className: "flex items-center justify-between",
|
|
191
|
-
children: [/* @__PURE__ */
|
|
198
|
+
children: [/* @__PURE__ */ C("div", {
|
|
192
199
|
className: "flex items-center gap-4",
|
|
193
|
-
children: /* @__PURE__ */
|
|
200
|
+
children: /* @__PURE__ */ w("div", {
|
|
194
201
|
className: "flex items-center gap-2 text-sm",
|
|
195
202
|
children: [
|
|
196
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ C(u, {
|
|
197
204
|
variant: "outline",
|
|
198
|
-
children:
|
|
205
|
+
children: h(e, "locationName") ?? e.locationId
|
|
199
206
|
}),
|
|
200
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ C(E, {
|
|
201
208
|
size: 16,
|
|
202
209
|
className: "text-text-secondary"
|
|
203
210
|
}),
|
|
204
|
-
/* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ C(u, {
|
|
205
212
|
variant: "secondary",
|
|
206
|
-
children:
|
|
213
|
+
children: h(e, "appName") ?? e.appId ?? "—"
|
|
207
214
|
})
|
|
208
215
|
]
|
|
209
216
|
})
|
|
210
|
-
}), /* @__PURE__ */
|
|
217
|
+
}), /* @__PURE__ */ w("div", {
|
|
211
218
|
className: "flex items-center gap-2",
|
|
212
|
-
children: [/* @__PURE__ */
|
|
219
|
+
children: [/* @__PURE__ */ C("span", {
|
|
213
220
|
className: "text-xs text-text-secondary",
|
|
214
|
-
children:
|
|
215
|
-
}), /* @__PURE__ */
|
|
221
|
+
children: n(e.createdAt)
|
|
222
|
+
}), /* @__PURE__ */ C(l, {
|
|
216
223
|
variant: "ghost",
|
|
217
224
|
size: "icon",
|
|
218
|
-
children: /* @__PURE__ */
|
|
225
|
+
children: /* @__PURE__ */ C(N, { size: 16 })
|
|
219
226
|
})]
|
|
220
227
|
})]
|
|
221
228
|
})
|
|
222
229
|
}) }, e.id))
|
|
223
|
-
}) : /* @__PURE__ */
|
|
230
|
+
}) : /* @__PURE__ */ C(f, {
|
|
224
231
|
illustration: "empty-search",
|
|
225
|
-
title: "No routes configured",
|
|
226
|
-
description: "Create routes to connect channel locations to specific bots.",
|
|
227
|
-
action: /* @__PURE__ */
|
|
228
|
-
leftIcon: /* @__PURE__ */
|
|
229
|
-
children: "Create Route"
|
|
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")
|
|
230
237
|
})
|
|
231
238
|
}) }),
|
|
232
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ w(b, {
|
|
233
240
|
treatment: "glass",
|
|
234
241
|
glow: !0,
|
|
235
242
|
className: "p-6",
|
|
236
|
-
children: [/* @__PURE__ */
|
|
243
|
+
children: [/* @__PURE__ */ w("div", {
|
|
237
244
|
className: "mb-4",
|
|
238
|
-
children: [/* @__PURE__ */
|
|
245
|
+
children: [/* @__PURE__ */ C("h2", {
|
|
239
246
|
className: "text-lg font-semibold tracking-tight text-text-primary",
|
|
240
|
-
children: "Available Integrations"
|
|
241
|
-
}), /* @__PURE__ */
|
|
247
|
+
children: O("botlit.channels.integrations.title", "Available Integrations")
|
|
248
|
+
}), /* @__PURE__ */ C("p", {
|
|
242
249
|
className: "text-sm text-text-secondary",
|
|
243
|
-
children: "Connect to popular messaging platforms"
|
|
250
|
+
children: O("botlit.channels.integrations.description", "Connect to popular messaging platforms")
|
|
244
251
|
})]
|
|
245
|
-
}), /* @__PURE__ */
|
|
252
|
+
}), /* @__PURE__ */ C("div", {
|
|
246
253
|
className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4",
|
|
247
254
|
children: [
|
|
248
255
|
{
|
|
249
256
|
type: "WEB_WIDGET",
|
|
250
|
-
name: "Web Widget",
|
|
251
|
-
desc: "Embed on websites"
|
|
257
|
+
name: O("botlit.channels.integrations.webWidget", "Web Widget"),
|
|
258
|
+
desc: O("botlit.channels.integrations.webWidgetDesc", "Embed on websites")
|
|
252
259
|
},
|
|
253
260
|
{
|
|
254
261
|
type: "SLACK",
|
|
255
|
-
name: "Slack",
|
|
256
|
-
desc: "Workspace integration"
|
|
262
|
+
name: O("botlit.channels.integrations.slack", "Slack"),
|
|
263
|
+
desc: O("botlit.channels.integrations.slackDesc", "Workspace integration")
|
|
257
264
|
},
|
|
258
265
|
{
|
|
259
266
|
type: "TEAMS",
|
|
260
|
-
name: "MS Teams",
|
|
261
|
-
desc: "Teams app"
|
|
267
|
+
name: O("botlit.channels.integrations.teams", "MS Teams"),
|
|
268
|
+
desc: O("botlit.channels.integrations.teamsDesc", "Teams app")
|
|
262
269
|
},
|
|
263
270
|
{
|
|
264
271
|
type: "DISCORD",
|
|
265
|
-
name: "Discord",
|
|
266
|
-
desc: "Bot integration"
|
|
272
|
+
name: O("botlit.channels.integrations.discord", "Discord"),
|
|
273
|
+
desc: O("botlit.channels.integrations.discordDesc", "Bot integration")
|
|
267
274
|
},
|
|
268
275
|
{
|
|
269
276
|
type: "WHATSAPP",
|
|
270
|
-
name: "WhatsApp",
|
|
271
|
-
desc: "Business API"
|
|
277
|
+
name: O("botlit.channels.integrations.whatsapp", "WhatsApp"),
|
|
278
|
+
desc: O("botlit.channels.integrations.whatsappDesc", "Business API")
|
|
272
279
|
},
|
|
273
280
|
{
|
|
274
281
|
type: "WEBHOOK",
|
|
275
|
-
name: "Webhook",
|
|
276
|
-
desc: "Custom integration"
|
|
282
|
+
name: O("botlit.channels.integrations.webhook", "Webhook"),
|
|
283
|
+
desc: O("botlit.channels.integrations.webhookDesc", "Custom integration")
|
|
277
284
|
}
|
|
278
|
-
].map((e) => /* @__PURE__ */
|
|
285
|
+
].map((e) => /* @__PURE__ */ w("button", {
|
|
279
286
|
className: "p-4 text-center border border-border-subtle rounded-lg hover:bg-accent transition-colors",
|
|
280
287
|
children: [
|
|
281
|
-
/* @__PURE__ */
|
|
288
|
+
/* @__PURE__ */ C(I, {
|
|
282
289
|
type: e.type,
|
|
283
290
|
className: "h-8 w-8 mx-auto text-text-secondary"
|
|
284
291
|
}),
|
|
285
|
-
/* @__PURE__ */
|
|
292
|
+
/* @__PURE__ */ C("p", {
|
|
286
293
|
className: "mt-2 font-medium text-sm",
|
|
287
294
|
children: e.name
|
|
288
295
|
}),
|
|
289
|
-
/* @__PURE__ */
|
|
296
|
+
/* @__PURE__ */ C("p", {
|
|
290
297
|
className: "text-xs text-text-secondary",
|
|
291
298
|
children: e.desc
|
|
292
299
|
})
|
|
@@ -299,6 +306,6 @@ var F = ({ type: e, className: t }) => {
|
|
|
299
306
|
});
|
|
300
307
|
};
|
|
301
308
|
//#endregion
|
|
302
|
-
export {
|
|
309
|
+
export { L as ChannelsPage };
|
|
303
310
|
|
|
304
311
|
//# 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 { 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 { 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=\"Channels\"\n description=\"Connect agents to messaging platforms and configure routing\"\n actions={\n <div className=\"flex gap-2\">\n <Button variant=\"outline\">\n <Link to={getPath('channels/routes')}>View Routes</Link>\n </Button>\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('channels/new')}>Add Channel</Link>\n </Button>\n </div>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<MessageSquare size={18} />}>\n Channels are where your bots actually talk to people. Connect a messaging platform — a\n website chat widget, Slack, Microsoft Teams, Discord, WhatsApp or a custom webhook — then\n add a route that points an incoming location at the bot that should answer. Use this page\n to manage those connectors and routing rules in one place.\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 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 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={`Search ${activeTab}...`}\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 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\">Type</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\">Active Routes</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 Created {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=\"No channel connectors\"\n description=\"Connect messaging platforms to deploy agents across multiple channels.\"\n action={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('channels/new')}>Add Channel</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=\"No routes configured\"\n description=\"Create routes to connect channel locations to specific bots.\"\n action={<Button leftIcon={<Plus size={16} />}>Create Route</Button>}\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 Available Integrations\n </h2>\n <p className=\"text-sm text-text-secondary\">Connect to popular messaging platforms</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: 'Web Widget',\n desc: 'Embed on websites',\n },\n { type: 'SLACK' as ChannelType, name: 'Slack', desc: 'Workspace integration' },\n { type: 'TEAMS' as ChannelType, name: 'MS Teams', desc: 'Teams app' },\n { type: 'DISCORD' as ChannelType, name: 'Discord', desc: 'Bot integration' },\n { type: 'WHATSAPP' as ChannelType, name: 'WhatsApp', desc: 'Business API' },\n { type: 'WEBHOOK' as ChannelType, name: 'Webhook', desc: 'Custom integration' },\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';\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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"}
|