@nextclaw/ui 0.5.48 → 0.6.0
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/CHANGELOG.md +12 -0
- package/dist/assets/ChannelsList-BWQYaOuz.js +1 -0
- package/dist/assets/ChatPage-DsIuF-TC.js +32 -0
- package/dist/assets/DocBrowser-D4pXQDKt.js +1 -0
- package/dist/assets/MarketplacePage-Cj1HGbGe.js +49 -0
- package/dist/assets/ModelConfig-C2f3h7yq.js +1 -0
- package/dist/assets/{ProvidersList-BXHpjVtO.js → ProvidersList-DUdQEMNV.js} +1 -1
- package/dist/assets/RuntimeConfig-BnR60m9J.js +1 -0
- package/dist/assets/{SecretsConfig-KkgMzdt1.js → SecretsConfig-CXV017VN.js} +2 -2
- package/dist/assets/SessionsConfig-DsgHhuYe.js +2 -0
- package/dist/assets/{card-D7NY0Szf.js → card-B7d3Z9Y7.js} +1 -1
- package/dist/assets/index-Dp6x_DHf.js +2 -0
- package/dist/assets/index-DsQL2mtx.css +1 -0
- package/dist/assets/{label-Ojs7Al6B.js → label-Dlq0AZXx.js} +1 -1
- package/dist/assets/{logos-B1qBsCSi.js → logos-CSTJsbua.js} +1 -1
- package/dist/assets/{page-layout-CUMMO0nN.js → page-layout-DeBYaT_B.js} +1 -1
- package/dist/assets/provider-models-y4mUDcGF.js +1 -0
- package/dist/assets/{switch-BdhS_16-.js → switch-DwDE9PLr.js} +1 -1
- package/dist/assets/{tabs-custom-D261E5EA.js → tabs-custom-DqY_ht59.js} +1 -1
- package/dist/assets/useConfig-BiM-oO9i.js +6 -0
- package/dist/assets/{useConfirmDialog-BUKGHDL6.js → useConfirmDialog-BEFIWczY.js} +2 -2
- package/dist/assets/{vendor-Dh04PGww.js → vendor-Ylg6Wdt_.js} +84 -69
- package/dist/index.html +3 -3
- package/package.json +2 -1
- package/src/App.tsx +10 -6
- package/src/api/config.ts +42 -1
- package/src/api/types.ts +29 -0
- package/src/components/chat/ChatConversationPanel.tsx +75 -86
- package/src/components/chat/ChatInputBar.tsx +226 -0
- package/src/components/chat/ChatPage.tsx +359 -188
- package/src/components/chat/ChatSidebar.tsx +242 -0
- package/src/components/chat/ChatThread.tsx +92 -25
- package/src/components/chat/ChatWelcome.tsx +61 -0
- package/src/components/chat/SkillsPicker.tsx +137 -0
- package/src/components/chat/useChatStreamController.ts +287 -56
- package/src/components/config/ChannelForm.tsx +1 -1
- package/src/components/config/ChannelsList.tsx +3 -3
- package/src/components/config/ModelConfig.tsx +11 -89
- package/src/components/config/RuntimeConfig.tsx +29 -1
- package/src/components/layout/AppLayout.tsx +42 -6
- package/src/components/layout/Sidebar.tsx +68 -62
- package/src/components/marketplace/MarketplacePage.tsx +13 -3
- package/src/components/ui/popover.tsx +31 -0
- package/src/hooks/useConfig.ts +18 -0
- package/src/lib/i18n.ts +47 -0
- package/src/lib/provider-models.ts +129 -0
- package/dist/assets/ChannelsList-C8cguFLc.js +0 -1
- package/dist/assets/ChatPage-BkHWNUNR.js +0 -32
- package/dist/assets/CronConfig-D-ESQlvk.js +0 -1
- package/dist/assets/DocBrowser-B9ZD6pAk.js +0 -1
- package/dist/assets/MarketplacePage-Ds_l9KTF.js +0 -49
- package/dist/assets/ModelConfig-N1tbLv9b.js +0 -1
- package/dist/assets/RuntimeConfig-KsKfkjgv.js +0 -1
- package/dist/assets/SessionsConfig-CWBp8IPf.js +0 -2
- package/dist/assets/index-BRBYYgR_.js +0 -2
- package/dist/assets/index-C5cdRzpO.css +0 -1
- package/dist/assets/useConfig-txxbxXnT.js +0 -6
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { ConfigMetaView, ConfigView, ProviderConfigView } from '@/api/types';
|
|
2
|
+
|
|
3
|
+
export type ProviderModelCatalogItem = {
|
|
4
|
+
name: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
prefix: string;
|
|
7
|
+
aliases: string[];
|
|
8
|
+
models: string[];
|
|
9
|
+
configured: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function normalizeStringList(input: string[] | null | undefined): string[] {
|
|
13
|
+
if (!input || input.length === 0) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const deduped = new Set<string>();
|
|
17
|
+
for (const item of input) {
|
|
18
|
+
const trimmed = item.trim();
|
|
19
|
+
if (trimmed) {
|
|
20
|
+
deduped.add(trimmed);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return [...deduped];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function stripProviderPrefix(model: string, prefix: string): string {
|
|
27
|
+
const trimmed = model.trim();
|
|
28
|
+
const cleanPrefix = prefix.trim();
|
|
29
|
+
if (!trimmed || !cleanPrefix) {
|
|
30
|
+
return trimmed;
|
|
31
|
+
}
|
|
32
|
+
const withSlash = `${cleanPrefix}/`;
|
|
33
|
+
if (trimmed.startsWith(withSlash)) {
|
|
34
|
+
return trimmed.slice(withSlash.length);
|
|
35
|
+
}
|
|
36
|
+
return trimmed;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function toProviderLocalModel(model: string, aliases: string[]): string {
|
|
40
|
+
let normalized = model.trim();
|
|
41
|
+
if (!normalized) {
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
for (const alias of aliases) {
|
|
45
|
+
normalized = stripProviderPrefix(normalized, alias);
|
|
46
|
+
}
|
|
47
|
+
return normalized.trim();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function composeProviderModel(prefix: string, localModel: string): string {
|
|
51
|
+
const normalizedModel = localModel.trim();
|
|
52
|
+
const normalizedPrefix = prefix.trim();
|
|
53
|
+
if (!normalizedModel) {
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
if (!normalizedPrefix) {
|
|
57
|
+
return normalizedModel;
|
|
58
|
+
}
|
|
59
|
+
return `${normalizedPrefix}/${normalizedModel}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function findProviderByModel(
|
|
63
|
+
model: string,
|
|
64
|
+
providerCatalog: Array<{ name: string; aliases: string[] }>
|
|
65
|
+
): string | null {
|
|
66
|
+
const trimmed = model.trim();
|
|
67
|
+
if (!trimmed) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
let bestMatch: { name: string; score: number } | null = null;
|
|
71
|
+
for (const provider of providerCatalog) {
|
|
72
|
+
for (const alias of provider.aliases) {
|
|
73
|
+
const cleanAlias = alias.trim();
|
|
74
|
+
if (!cleanAlias) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (trimmed === cleanAlias || trimmed.startsWith(`${cleanAlias}/`)) {
|
|
78
|
+
if (!bestMatch || cleanAlias.length > bestMatch.score) {
|
|
79
|
+
bestMatch = { name: provider.name, score: cleanAlias.length };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return bestMatch?.name ?? null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function isProviderConfigured(provider: ProviderConfigView | undefined): boolean {
|
|
88
|
+
if (!provider) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
// Keep in sync with ProvidersList "已配置" tab: only apiKeySet counts as configured.
|
|
92
|
+
return provider.apiKeySet === true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function buildProviderModelCatalog(params: {
|
|
96
|
+
meta?: ConfigMetaView;
|
|
97
|
+
config?: ConfigView;
|
|
98
|
+
onlyConfigured?: boolean;
|
|
99
|
+
}): ProviderModelCatalogItem[] {
|
|
100
|
+
const { meta, config, onlyConfigured = false } = params;
|
|
101
|
+
|
|
102
|
+
const catalog = (meta?.providers ?? []).map((spec) => {
|
|
103
|
+
const providerConfig = config?.providers?.[spec.name];
|
|
104
|
+
const prefix = (spec.modelPrefix || spec.name || '').trim();
|
|
105
|
+
const aliases = normalizeStringList([spec.modelPrefix || '', spec.name || '']);
|
|
106
|
+
const defaultModels = normalizeStringList((spec.defaultModels ?? []).map((model) => toProviderLocalModel(model, aliases)));
|
|
107
|
+
const customModels = normalizeStringList(
|
|
108
|
+
(providerConfig?.models ?? []).map((model) => toProviderLocalModel(model, aliases))
|
|
109
|
+
);
|
|
110
|
+
const models = normalizeStringList([...defaultModels, ...customModels]);
|
|
111
|
+
const configDisplayName = providerConfig?.displayName?.trim();
|
|
112
|
+
const configured = isProviderConfigured(providerConfig);
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
name: spec.name,
|
|
116
|
+
displayName: configDisplayName || spec.displayName || spec.name,
|
|
117
|
+
prefix,
|
|
118
|
+
aliases,
|
|
119
|
+
models,
|
|
120
|
+
configured
|
|
121
|
+
} satisfies ProviderModelCatalogItem;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (!onlyConfigured) {
|
|
125
|
+
return catalog;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return catalog.filter((provider) => provider.configured && provider.models.length > 0);
|
|
129
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as j,j as a,ab as Z,s as ee,ae as F,K as ae,a3 as te,af as se,ag as ne,ah as le,ai as re,U as oe,aj as ce,n as ie}from"./vendor-Dh04PGww.js";import{u as $,a as q,b as K,k as me,l as pe,I as T}from"./useConfig-txxbxXnT.js";import{B as E,P as de,a as be}from"./page-layout-CUMMO0nN.js";import{L as ue}from"./label-Ojs7Al6B.js";import{S as xe}from"./switch-BdhS_16-.js";import{t as e,c as D,g as ye,S as ge,a as he,b as fe,d as we,e as je}from"./index-BRBYYgR_.js";import{C as ve,a as ke,L as H,d as J,S as z,b as Se,c as Ce}from"./logos-B1qBsCSi.js";import{h as U}from"./config-hints-CApS3K_7.js";import{T as Ne}from"./tabs-custom-D261E5EA.js";function Pe({value:t,onChange:p,className:i,placeholder:c=""}){const[r,u]=j.useState(""),d=x=>{x.key==="Enter"&&r.trim()?(x.preventDefault(),p([...t,r.trim()]),u("")):x.key==="Backspace"&&!r&&t.length>0&&p(t.slice(0,-1))},g=x=>{p(t.filter((v,h)=>h!==x))};return a.jsxs("div",{className:D("flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]",i),children:[t.map((x,v)=>a.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded text-sm",children:[x,a.jsx("button",{type:"button",onClick:()=>g(v),className:"hover:text-red-300 transition-colors",children:a.jsx(Z,{className:"h-3 w-3"})})]},v)),a.jsx("input",{type:"text",value:r,onChange:x=>u(x.target.value),onKeyDown:d,className:"flex-1 outline-none min-w-[100px] bg-transparent text-sm",placeholder:c||e("enterTag")})]})}function Y(t){var c,r;const p=ye();return((c=t.tutorialUrls)==null?void 0:c[p])||((r=t.tutorialUrls)==null?void 0:r.default)||t.tutorialUrl}const B=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],R=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Ie=[{value:"off",label:"off"},{value:"partial",label:"partial"},{value:"block",label:"block"},{value:"progress",label:"progress"}],Fe=t=>t.includes("token")||t.includes("secret")||t.includes("password")?a.jsx(ae,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("url")||t.includes("host")?a.jsx(te,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("email")||t.includes("mail")?a.jsx(se,{className:"h-3.5 w-3.5 text-gray-500"}):t.includes("id")||t.includes("from")?a.jsx(ne,{className:"h-3.5 w-3.5 text-gray-500"}):t==="enabled"||t==="consentGranted"?a.jsx(le,{className:"h-3.5 w-3.5 text-gray-500"}):a.jsx(re,{className:"h-3.5 w-3.5 text-gray-500"});function G(){return{telegram:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"proxy",type:"text",label:e("proxy")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:R},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],discord:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"gatewayUrl",type:"text",label:e("gatewayUrl")},{name:"intents",type:"number",label:e("intents")},{name:"proxy",type:"text",label:e("proxy")},{name:"mediaMaxMb",type:"number",label:e("attachmentMaxSizeMb")},{name:"streaming",type:"select",label:e("streamingMode"),options:Ie},{name:"draftChunk",type:"json",label:e("draftChunkingJson")},{name:"textChunkLimit",type:"number",label:e("textChunkLimit")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:B},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:R},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],whatsapp:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"bridgeUrl",type:"text",label:e("bridgeUrl")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],feishu:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"appSecret",type:"password",label:e("appSecret")},{name:"encryptKey",type:"password",label:e("encryptKey")},{name:"verificationToken",type:"password",label:e("verificationToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],dingtalk:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"clientId",type:"text",label:e("clientId")},{name:"clientSecret",type:"password",label:e("clientSecret")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],wecom:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"corpId",type:"text",label:e("corpId")},{name:"agentId",type:"text",label:e("agentId")},{name:"secret",type:"password",label:e("secret")},{name:"token",type:"password",label:e("token")},{name:"callbackPort",type:"number",label:e("callbackPort")},{name:"callbackPath",type:"text",label:e("callbackPath")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],slack:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"mode",type:"text",label:e("mode")},{name:"webhookPath",type:"text",label:e("webhookPath")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"botToken",type:"password",label:e("botToken")},{name:"appToken",type:"password",label:e("appToken")}],email:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"consentGranted",type:"boolean",label:e("consentGranted")},{name:"imapHost",type:"text",label:e("imapHost")},{name:"imapPort",type:"number",label:e("imapPort")},{name:"imapUsername",type:"text",label:e("imapUsername")},{name:"imapPassword",type:"password",label:e("imapPassword")},{name:"fromAddress",type:"email",label:e("fromAddress")}],mochat:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"baseUrl",type:"text",label:e("baseUrl")},{name:"clawToken",type:"password",label:e("clawToken")},{name:"agentUserId",type:"text",label:e("agentUserId")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],qq:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"secret",type:"password",label:e("appSecret")},{name:"markdownSupport",type:"boolean",label:e("markdownSupport")},{name:"allowFrom",type:"tags",label:e("allowFrom")}]}}function A(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function V(t,p){const i={...t};for(const[c,r]of Object.entries(p)){const u=i[c];if(A(u)&&A(r)){i[c]=V(u,r);continue}i[c]=r}return i}function Te(t,p){const i=t.split("."),c={};let r=c;for(let u=0;u<i.length-1;u+=1){const d=i[u];r[d]={},r=r[d]}return r[i[i.length-1]]=p,c}function De({channelName:t}){var _,O;const{data:p}=$(),{data:i}=q(),{data:c}=K(),r=me(),u=pe(),[d,g]=j.useState({}),[x,v]=j.useState({}),[h,f]=j.useState(null),k=t?p==null?void 0:p.channels[t]:null,w=t?G()[t]??[]:[],o=c==null?void 0:c.uiHints,m=t?`channels.${t}`:null,S=((_=c==null?void 0:c.actions)==null?void 0:_.filter(s=>s.scope===m))??[],C=t&&(((O=U(`channels.${t}`,o))==null?void 0:O.label)??t),P=i==null?void 0:i.channels.find(s=>s.name===t),I=P?Y(P):void 0;j.useEffect(()=>{if(k){g({...k});const s={};(t?G()[t]??[]:[]).filter(l=>l.type==="json").forEach(l=>{const y=k[l.name];s[l.name]=JSON.stringify(y??{},null,2)}),v(s)}else g({}),v({})},[k,t]);const N=(s,n)=>{g(l=>({...l,[s]:n}))},L=s=>{if(s.preventDefault(),!t)return;const n={...d};for(const l of w){if(l.type!=="password")continue;const y=n[l.name];(typeof y!="string"||y.length===0)&&delete n[l.name]}for(const l of w){if(l.type!=="json")continue;const y=x[l.name]??"";try{n[l.name]=y.trim()?JSON.parse(y):{}}catch{F.error(`${e("invalidJson")}: ${l.name}`);return}}r.mutate({channel:t,data:n})},Q=s=>{if(!s||!t)return;const n=s.channels;if(!A(n))return;const l=n[t];A(l)&&g(y=>V(y,l))},W=async s=>{if(!(!t||!m)){f(s.id);try{let n={...d};s.saveBeforeRun&&(n={...n,...s.savePatch??{}},g(n),await r.mutateAsync({channel:t,data:n}));const l=await u.mutateAsync({actionId:s.id,data:{scope:m,draftConfig:Te(m,n)}});Q(l.patch),l.ok?F.success(l.message||e("success")):F.error(l.message||e("error"))}catch(n){const l=n instanceof Error?n.message:String(n);F.error(`${e("error")}: ${l}`)}finally{f(null)}}};if(!t||!P||!k)return a.jsx("div",{className:ve,children:a.jsxs("div",{children:[a.jsx("h3",{className:"text-base font-semibold text-gray-900",children:e("channelsSelectTitle")}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsSelectDescription")})]})});const M=!!k.enabled;return a.jsxs("div",{className:ke,children:[a.jsx("div",{className:"border-b border-gray-100 px-6 py-5",children:a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0",children:[a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx(H,{name:t,src:J(t),className:D("h-9 w-9 rounded-lg border",M?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:t[0]})}),a.jsx("h3",{className:"truncate text-lg font-semibold text-gray-900 capitalize",children:C})]}),a.jsx("p",{className:"mt-2 text-sm text-gray-500",children:e("channelsFormDescription")}),I&&a.jsxs("a",{href:I,className:"mt-2 inline-flex items-center gap-1.5 text-xs text-primary transition-colors hover:text-primary-hover",children:[a.jsx(ee,{className:"h-3.5 w-3.5"}),e("channelsGuideTitle")]})]}),a.jsx(z,{status:M?"active":"inactive",label:M?e("statusActive"):e("statusInactive")})]})}),a.jsxs("form",{onSubmit:L,className:"flex min-h-0 flex-1 flex-col",children:[a.jsx("div",{className:"min-h-0 flex-1 space-y-6 overflow-y-auto px-6 py-5",children:w.map(s=>{const n=t?U(`channels.${t}.${s.name}`,o):void 0,l=(n==null?void 0:n.label)??s.label,y=n==null?void 0:n.placeholder;return a.jsxs("div",{className:"space-y-2.5",children:[a.jsxs(ue,{htmlFor:s.name,className:"flex items-center gap-2 text-sm font-medium text-gray-900",children:[Fe(s.name),l]}),s.type==="boolean"&&a.jsxs("div",{className:"flex items-center justify-between rounded-xl bg-gray-50 p-3",children:[a.jsx("span",{className:"text-sm text-gray-500",children:d[s.name]?e("enabled"):e("disabled")}),a.jsx(xe,{id:s.name,checked:d[s.name]||!1,onCheckedChange:b=>N(s.name,b),className:"data-[state=checked]:bg-emerald-500"})]}),(s.type==="text"||s.type==="email")&&a.jsx(T,{id:s.name,type:s.type,value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y,className:"rounded-xl"}),s.type==="password"&&a.jsx(T,{id:s.name,type:"password",value:d[s.name]||"",onChange:b=>N(s.name,b.target.value),placeholder:y??e("leaveBlankToKeepUnchanged"),className:"rounded-xl"}),s.type==="number"&&a.jsx(T,{id:s.name,type:"number",value:d[s.name]||0,onChange:b=>N(s.name,parseInt(b.target.value,10)||0),placeholder:y,className:"rounded-xl"}),s.type==="tags"&&a.jsx(Pe,{value:d[s.name]||[],onChange:b=>N(s.name,b)}),s.type==="select"&&a.jsxs(ge,{value:d[s.name]||"",onValueChange:b=>N(s.name,b),children:[a.jsx(he,{className:"rounded-xl",children:a.jsx(fe,{})}),a.jsx(we,{children:(s.options??[]).map(b=>a.jsx(je,{value:b.value,children:b.label},b.value))})]}),s.type==="json"&&a.jsx("textarea",{id:s.name,value:x[s.name]??"{}",onChange:b=>v(X=>({...X,[s.name]:b.target.value})),className:"min-h-[120px] w-full resize-none rounded-lg border border-gray-200 bg-white px-3 py-2 text-xs font-mono"})]},s.name)})}),a.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 border-t border-gray-100 px-6 py-4",children:[a.jsx("div",{className:"flex flex-wrap items-center gap-2",children:S.filter(s=>s.trigger==="manual").map(s=>a.jsx(E,{type:"button",onClick:()=>W(s),disabled:r.isPending||!!h,variant:"secondary",children:h===s.id?e("connecting"):s.title},s.id))}),a.jsx(E,{type:"submit",disabled:r.isPending||!!h,children:r.isPending?e("saving"):e("save")})]})]})]})}const Ae={telegram:"channelDescTelegram",slack:"channelDescSlack",email:"channelDescEmail",webhook:"channelDescWebhook",discord:"channelDescDiscord",feishu:"channelDescFeishu"};function $e(){const{data:t}=$(),{data:p}=q(),{data:i}=K(),[c,r]=j.useState("enabled"),[u,d]=j.useState(),[g,x]=j.useState(""),v=i==null?void 0:i.uiHints,h=p==null?void 0:p.channels,f=t==null?void 0:t.channels,k=[{id:"enabled",label:e("channelsTabEnabled"),count:(h??[]).filter(o=>{var m;return(m=f==null?void 0:f[o.name])==null?void 0:m.enabled}).length},{id:"all",label:e("channelsTabAll"),count:(h??[]).length}],w=j.useMemo(()=>{const o=g.trim().toLowerCase();return(h??[]).filter(m=>{var C;const S=((C=f==null?void 0:f[m.name])==null?void 0:C.enabled)||!1;return c==="enabled"?S:!0}).filter(m=>o?(m.displayName||m.name).toLowerCase().includes(o)||m.name.toLowerCase().includes(o):!0)},[c,f,h,g]);return j.useEffect(()=>{if(w.length===0){d(void 0);return}w.some(m=>m.name===u)||d(w[0].name)},[w,u]),!t||!p?a.jsx("div",{className:"p-8 text-gray-400",children:e("channelsLoading")}):a.jsxs(de,{children:[a.jsx(be,{title:e("channelsPageTitle"),description:e("channelsPageDescription")}),a.jsxs("div",{className:Se,children:[a.jsxs("section",{className:Ce,children:[a.jsx("div",{className:"border-b border-gray-100 px-4 pt-4",children:a.jsx(Ne,{tabs:k,activeTab:c,onChange:r,className:"mb-0"})}),a.jsx("div",{className:"border-b border-gray-100 px-4 py-3",children:a.jsxs("div",{className:"relative",children:[a.jsx(oe,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400"}),a.jsx(T,{value:g,onChange:o=>x(o.target.value),placeholder:e("channelsFilterPlaceholder"),className:"h-10 rounded-xl pl-9"})]})}),a.jsxs("div",{className:"min-h-0 flex-1 space-y-2 overflow-y-auto p-3",children:[w.map(o=>{const m=t.channels[o.name],S=(m==null?void 0:m.enabled)||!1,C=U(`channels.${o.name}`,v),P=Y(o),I=(C==null?void 0:C.help)||e(Ae[o.name]||"channelDescriptionDefault"),N=u===o.name;return a.jsx("button",{type:"button",onClick:()=>d(o.name),className:D("w-full rounded-xl border p-2.5 text-left transition-all",N?"border-primary/30 bg-primary-50/40 shadow-sm":"border-gray-200/70 bg-white hover:border-gray-300 hover:bg-gray-50/70"),children:a.jsxs("div",{className:"flex items-start justify-between gap-3",children:[a.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[a.jsx(H,{name:o.name,src:J(o.name),className:D("h-10 w-10 rounded-lg border",S?"border-primary/30 bg-white":"border-gray-200/70 bg-white"),imgClassName:"h-5 w-5 object-contain",fallback:a.jsx("span",{className:"text-sm font-semibold uppercase text-gray-500",children:o.name[0]})}),a.jsxs("div",{className:"min-w-0",children:[a.jsx("p",{className:"truncate text-sm font-semibold text-gray-900",children:o.displayName||o.name}),a.jsx("p",{className:"line-clamp-1 text-[11px] text-gray-500",children:I})]})]}),a.jsxs("div",{className:"flex items-center gap-2",children:[P&&a.jsx("a",{href:P,onClick:L=>L.stopPropagation(),className:"inline-flex h-7 w-7 items-center justify-center rounded-md text-gray-300 transition-colors hover:bg-gray-100/70 hover:text-gray-500",title:e("channelsGuideTitle"),children:a.jsx(ce,{className:"h-3.5 w-3.5"})}),a.jsx(z,{status:S?"active":"inactive",label:S?e("statusActive"):e("statusInactive"),className:"min-w-[56px] justify-center"})]})]})},o.name)}),w.length===0&&a.jsxs("div",{className:"flex h-full min-h-[220px] flex-col items-center justify-center rounded-xl border border-dashed border-gray-200 bg-gray-50/70 py-10 text-center",children:[a.jsx("div",{className:"mb-3 flex h-10 w-10 items-center justify-center rounded-lg bg-white",children:a.jsx(ie,{className:"h-5 w-5 text-gray-300"})}),a.jsx("p",{className:"text-sm font-medium text-gray-700",children:e("channelsNoMatch")})]})]})]}),a.jsx(De,{channelName:u})]})]})}export{$e as ChannelsList};
|