@samanhappy/mcphub 0.12.17 → 1.0.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.
Files changed (97) hide show
  1. package/README.fr.md +1 -1
  2. package/dist/services/mcpService.js +42 -10
  3. package/dist/services/mcpService.js.map +1 -1
  4. package/dist/services/sseService.js +5 -3
  5. package/dist/services/sseService.js.map +1 -1
  6. package/frontend/dist/assets/ActivityPage-VwilVMvp.js +2 -0
  7. package/frontend/dist/assets/ActivityPage-VwilVMvp.js.map +1 -0
  8. package/frontend/dist/assets/ConfirmDialog-CxlizGia.js +2 -0
  9. package/frontend/dist/assets/ConfirmDialog-CxlizGia.js.map +1 -0
  10. package/frontend/dist/assets/Dashboard-DuBJTbbA.js +2 -0
  11. package/frontend/dist/assets/Dashboard-DuBJTbbA.js.map +1 -0
  12. package/frontend/dist/assets/DeleteDialog-DRbWonMu.js +2 -0
  13. package/frontend/dist/assets/DeleteDialog-DRbWonMu.js.map +1 -0
  14. package/frontend/dist/assets/EndpointCopy-C59moJ3Y.js +2 -0
  15. package/frontend/dist/assets/EndpointCopy-C59moJ3Y.js.map +1 -0
  16. package/frontend/dist/assets/GroupsPage-Bhg51kbu.js +33 -0
  17. package/frontend/dist/assets/GroupsPage-Bhg51kbu.js.map +1 -0
  18. package/frontend/dist/assets/LoginPage-C8RkMoJN.js +2 -0
  19. package/frontend/dist/assets/LoginPage-C8RkMoJN.js.map +1 -0
  20. package/frontend/dist/assets/LogsPage-HBGNLtyN.js +2 -0
  21. package/frontend/dist/assets/LogsPage-HBGNLtyN.js.map +1 -0
  22. package/frontend/dist/assets/MarketPage-C5ATZ4WS.js +3 -0
  23. package/frontend/dist/assets/MarketPage-C5ATZ4WS.js.map +1 -0
  24. package/frontend/dist/assets/{Pagination-y-gVO8ms.js → Pagination-BFi-X7qY.js} +2 -2
  25. package/frontend/dist/assets/{Pagination-y-gVO8ms.js.map → Pagination-BFi-X7qY.js.map} +1 -1
  26. package/frontend/dist/assets/PromptsPage-DUge8OO4.js +2 -0
  27. package/frontend/dist/assets/PromptsPage-DUge8OO4.js.map +1 -0
  28. package/frontend/dist/assets/ResourcesPage-5J3JYGVC.js +2 -0
  29. package/frontend/dist/assets/ResourcesPage-5J3JYGVC.js.map +1 -0
  30. package/frontend/dist/assets/ServersPage-DtnlfwJF.js +37 -0
  31. package/frontend/dist/assets/ServersPage-DtnlfwJF.js.map +1 -0
  32. package/frontend/dist/assets/SettingsPage-BeLZKC1d.js +12 -0
  33. package/frontend/dist/assets/SettingsPage-BeLZKC1d.js.map +1 -0
  34. package/frontend/dist/assets/StatusDot-DR803YdX.js +2 -0
  35. package/frontend/dist/assets/StatusDot-DR803YdX.js.map +1 -0
  36. package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js → ToggleGroup-DE8t8Ni4.js} +2 -2
  37. package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js.map → ToggleGroup-DE8t8Ni4.js.map} +1 -1
  38. package/frontend/dist/assets/UsersPage-CMscqAmn.js +2 -0
  39. package/frontend/dist/assets/UsersPage-CMscqAmn.js.map +1 -0
  40. package/frontend/dist/assets/{framework-vendor-_OBebcuv.js → framework-vendor-BUhDPOUZ.js} +2 -2
  41. package/frontend/dist/assets/{framework-vendor-_OBebcuv.js.map → framework-vendor-BUhDPOUZ.js.map} +1 -1
  42. package/frontend/dist/assets/{i18n-vendor-MQ921plD.js → i18n-vendor-Kbr87Ofu.js} +2 -2
  43. package/frontend/dist/assets/{i18n-vendor-MQ921plD.js.map → i18n-vendor-Kbr87Ofu.js.map} +1 -1
  44. package/frontend/dist/assets/icons-vendor-CKgJB3SC.js +292 -0
  45. package/frontend/dist/assets/icons-vendor-CKgJB3SC.js.map +1 -0
  46. package/frontend/dist/assets/index-B9cW2F0H.js +3 -0
  47. package/frontend/dist/assets/index-B9cW2F0H.js.map +1 -0
  48. package/frontend/dist/assets/index-Crcbkt8x.css +1 -0
  49. package/frontend/dist/assets/{resourceService-BfCTSBsr.js → resourceService-BFMkDDIh.js} +2 -2
  50. package/frontend/dist/assets/{resourceService-BfCTSBsr.js.map → resourceService-BFMkDDIh.js.map} +1 -1
  51. package/frontend/dist/assets/useServerData-BnLmpLAC.js +2 -0
  52. package/frontend/dist/assets/{useServerData-QZqQTYcv.js.map → useServerData-BnLmpLAC.js.map} +1 -1
  53. package/frontend/dist/assets/useSettingsData-Cqi9d7Ug.js +2 -0
  54. package/frontend/dist/assets/{useSettingsData-D3VROqS7.js.map → useSettingsData-Cqi9d7Ug.js.map} +1 -1
  55. package/frontend/dist/assets/variableDetection-BigiltQM.js +16 -0
  56. package/frontend/dist/assets/variableDetection-BigiltQM.js.map +1 -0
  57. package/frontend/dist/index.html +5 -5
  58. package/package.json +1 -1
  59. package/frontend/dist/assets/ActivityPage-ClgKeihP.js +0 -2
  60. package/frontend/dist/assets/ActivityPage-ClgKeihP.js.map +0 -1
  61. package/frontend/dist/assets/Badge-Ck2fhRdl.js +0 -2
  62. package/frontend/dist/assets/Badge-Ck2fhRdl.js.map +0 -1
  63. package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js +0 -2
  64. package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js.map +0 -1
  65. package/frontend/dist/assets/Dashboard-BIXrLobn.js +0 -2
  66. package/frontend/dist/assets/Dashboard-BIXrLobn.js.map +0 -1
  67. package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js +0 -2
  68. package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js.map +0 -1
  69. package/frontend/dist/assets/GroupsPage-BjrvyHwu.js +0 -33
  70. package/frontend/dist/assets/GroupsPage-BjrvyHwu.js.map +0 -1
  71. package/frontend/dist/assets/LoginPage-BBHt_TfF.js +0 -2
  72. package/frontend/dist/assets/LoginPage-BBHt_TfF.js.map +0 -1
  73. package/frontend/dist/assets/LogsPage-D8Znq5NB.js +0 -2
  74. package/frontend/dist/assets/LogsPage-D8Znq5NB.js.map +0 -1
  75. package/frontend/dist/assets/MarketPage-haRuzjCw.js +0 -3
  76. package/frontend/dist/assets/MarketPage-haRuzjCw.js.map +0 -1
  77. package/frontend/dist/assets/PromptsPage-ByHWPyGe.js +0 -2
  78. package/frontend/dist/assets/PromptsPage-ByHWPyGe.js.map +0 -1
  79. package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js +0 -2
  80. package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js.map +0 -1
  81. package/frontend/dist/assets/ServersPage-CtS1I4yS.js +0 -37
  82. package/frontend/dist/assets/ServersPage-CtS1I4yS.js.map +0 -1
  83. package/frontend/dist/assets/SettingsPage-DxVigf7p.js +0 -12
  84. package/frontend/dist/assets/SettingsPage-DxVigf7p.js.map +0 -1
  85. package/frontend/dist/assets/UsersPage-Bipw33cS.js +0 -2
  86. package/frontend/dist/assets/UsersPage-Bipw33cS.js.map +0 -1
  87. package/frontend/dist/assets/icons-vendor-B67NtVuR.js +0 -172
  88. package/frontend/dist/assets/icons-vendor-B67NtVuR.js.map +0 -1
  89. package/frontend/dist/assets/index-CmnA4an8.js +0 -5
  90. package/frontend/dist/assets/index-CmnA4an8.js.map +0 -1
  91. package/frontend/dist/assets/index-DfFHVARX.css +0 -1
  92. package/frontend/dist/assets/useGroupData-DLhbP6zd.js +0 -2
  93. package/frontend/dist/assets/useGroupData-DLhbP6zd.js.map +0 -1
  94. package/frontend/dist/assets/useServerData-QZqQTYcv.js +0 -2
  95. package/frontend/dist/assets/useSettingsData-D3VROqS7.js +0 -2
  96. package/frontend/dist/assets/variableDetection-C3Xi21av.js +0 -16
  97. package/frontend/dist/assets/variableDetection-C3Xi21av.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{r as l,j as e}from"./framework-vendor-BUhDPOUZ.js";import{r as Y,s as Z,t as ee,v as te,w as ae}from"./index-B9cW2F0H.js";import{P as se}from"./Pagination-BFi-X7qY.js";import{u as le}from"./i18n-vendor-Kbr87Ofu.js";import"./icons-vendor-CKgJB3SC.js";const T=["success","error"],re=a=>T.includes(a),xe=()=>{const{t:a}=le(),[m,B]=l.useState([]),[n,V]=l.useState(null),[r,$]=l.useState(null),[i,I]=l.useState(null),[o,d]=l.useState(1),[b,J]=l.useState(10),[j,M]=l.useState(!0),[z,f]=l.useState(null),[c,G]=l.useState(null),[H,A]=l.useState(!1),[F,R]=l.useState({}),[v,N]=l.useState(""),[p,w]=l.useState(""),[x,k]=l.useState(""),[g,S]=l.useState(""),[y,C]=l.useState(""),L=l.useCallback(async()=>{M(!0),f(null);try{const t={...F},[s,u,h]=await Promise.all([Y(o,b,t),Z(t),ee()]);s!=null&&s.success&&Array.isArray(s.data)&&(B(s.data),s.pagination&&I(s.pagination)),u!=null&&u.success&&u.data&&V(u.data),h!=null&&h.success&&h.data&&$(h.data)}catch(t){console.error("Error fetching activity data:",t),f(a("activity.fetchError"))}finally{M(!1)}},[o,b,F,a]);l.useEffect(()=>{L()},[L]),l.useEffect(()=>{if(!i)return;const t=Math.max(1,i.totalPages||1);o>t&&d(t)},[i,o]);const K=async t=>{try{const s=await ae(t.id);s!=null&&s.success&&s.data&&(G(s.data),A(!0))}catch(s){console.error("Error fetching activity details:",s)}},W=async()=>{var t;if(window.confirm(a("activity.confirmCleanup")))try{const s=await te(30);s!=null&&s.success&&(alert(a("activity.cleanupSuccess",{count:((t=s.data)==null?void 0:t.deletedCount)||0})),L())}catch(s){console.error("Error cleaning up activities:",s),alert(a("activity.cleanupError"))}},O=()=>{const t={};v&&(t.server=v),p&&(t.tool=p),x&&re(x)&&(t.status=x),g&&(t.group=g),y&&(t.keyName=y),R(t),d(1)},U=()=>{N(""),w(""),k(""),S(""),C(""),R({}),d(1)},P=t=>t<1e3?`${t}ms`:t<6e4?`${(t/1e3).toFixed(2)}s`:`${(t/6e4).toFixed(2)}m`,D=t=>new Date(t).toLocaleString(),E=t=>{if(!t)return null;try{return JSON.parse(t)}catch{return t}},_=()=>n?e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-3 mb-4",children:[{label:a("activity.totalCalls"),value:n.totalCalls,tone:"default"},{label:a("activity.successCount"),value:n.successCount,tone:"ok"},{label:a("activity.errorCount"),value:n.errorCount,tone:"err"},{label:a("activity.avgDuration"),value:P(n.avgDuration),tone:"default"}].map(t=>e.jsxs("div",{className:"hub-card",style:{padding:"12px 14px"},children:[e.jsx("div",{className:"text-[12px]",style:{color:"var(--hub-ink-3)"},children:t.label}),e.jsx("div",{className:"hub-num",style:{fontSize:22,fontWeight:500,lineHeight:1.1,marginTop:6,letterSpacing:"-0.02em",color:t.tone==="ok"?"oklch(0.4 0.13 145)":t.tone==="err"?"oklch(0.45 0.18 25)":"var(--hub-ink)"},children:t.value})]},t.label))}):null,q=()=>e.jsx("div",{className:"hub-card px-4 py-3 mb-4",children:e.jsxs("div",{className:"flex flex-wrap gap-3 items-end",children:[e.jsxs("div",{className:"flex-1 min-w-[140px]",children:[e.jsx("label",{className:"sr-only",htmlFor:"activity-server",children:a("activity.server")}),e.jsxs("div",{className:"relative",children:[e.jsx("input",{id:"activity-server",type:"text",value:v,onChange:t=>N(t.target.value),placeholder:a("activity.searchServer"),className:"hub-input pr-9",list:"server-options"}),v&&e.jsx("button",{onClick:()=>N(""),className:"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300","aria-label":a("common.clear"),type:"button",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]}),(r==null?void 0:r.servers)&&e.jsx("datalist",{id:"server-options",children:r.servers.map(t=>e.jsx("option",{value:t},t))})]}),e.jsxs("div",{className:"flex-1 min-w-[140px]",children:[e.jsx("label",{className:"sr-only",htmlFor:"activity-tool",children:a("activity.tool")}),e.jsxs("div",{className:"relative",children:[e.jsx("input",{id:"activity-tool",type:"text",value:p,onChange:t=>w(t.target.value),placeholder:a("activity.searchTool"),className:"hub-input pr-9",list:"tool-options"}),p&&e.jsx("button",{onClick:()=>w(""),className:"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300","aria-label":a("common.clear"),type:"button",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]}),(r==null?void 0:r.tools)&&e.jsx("datalist",{id:"tool-options",children:r.tools.map(t=>e.jsx("option",{value:t},t))})]}),e.jsxs("div",{className:"flex-1 min-w-[140px]",children:[e.jsx("label",{className:"sr-only",htmlFor:"activity-status",children:a("activity.status")}),e.jsxs("div",{className:"relative",children:[e.jsx("input",{id:"activity-status",type:"text",value:x,onChange:t=>k(t.target.value.toLowerCase()),placeholder:a("activity.searchStatus"),className:"hub-input pr-9",list:"activity-status-options"}),x&&e.jsx("button",{onClick:()=>k(""),className:"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300","aria-label":a("common.clear"),type:"button",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]}),e.jsx("datalist",{id:"activity-status-options",children:T.map(t=>e.jsx("option",{value:t},t))})]}),e.jsxs("div",{className:"flex-1 min-w-[140px]",children:[e.jsx("label",{className:"sr-only",htmlFor:"activity-group",children:a("activity.group")}),e.jsxs("div",{className:"relative",children:[e.jsx("input",{id:"activity-group",type:"text",value:g,onChange:t=>S(t.target.value),placeholder:a("activity.searchGroup"),className:"hub-input pr-9",list:"group-options"}),g&&e.jsx("button",{onClick:()=>S(""),className:"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300","aria-label":a("common.clear"),type:"button",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]}),(r==null?void 0:r.groups)&&e.jsx("datalist",{id:"group-options",children:r.groups.map(t=>e.jsx("option",{value:t},t))})]}),e.jsxs("div",{className:"flex-1 min-w-[140px]",children:[e.jsx("label",{className:"sr-only",htmlFor:"activity-keyname",children:a("activity.keyName")}),e.jsxs("div",{className:"relative",children:[e.jsx("input",{id:"activity-keyname",type:"text",value:y,onChange:t=>C(t.target.value),placeholder:a("activity.searchKeyName"),className:"hub-input pr-9",list:"keyname-options"}),y&&e.jsx("button",{onClick:()=>C(""),className:"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300","aria-label":a("common.clear"),type:"button",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]}),(r==null?void 0:r.keyNames)&&e.jsx("datalist",{id:"keyname-options",children:r.keyNames.map(t=>e.jsx("option",{value:t},t))})]}),e.jsxs("div",{className:"flex-shrink-0 flex items-center gap-2",children:[e.jsxs("button",{onClick:O,className:"hub-btn primary whitespace-nowrap",children:[e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-3.5 w-3.5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z",clipRule:"evenodd"})}),a("common.search")]}),e.jsx("button",{onClick:U,className:"hub-btn whitespace-nowrap",children:a("common.clear")})]})]})}),Q=()=>m.length===0?e.jsx("div",{className:"hub-card p-10 text-center",style:{color:"var(--hub-ink-3)"},children:a("activity.noData")}):e.jsx("div",{className:"hub-card overflow-hidden",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"min-w-full",children:[e.jsx("thead",{style:{background:"var(--hub-bg-2)"},children:e.jsx("tr",{children:[a("activity.timestamp"),a("activity.server"),a("activity.tool"),a("activity.duration"),a("activity.status"),a("activity.group"),a("activity.key"),a("common.actions")].map(t=>e.jsx("th",{className:"hub-mono",style:{padding:"9px 14px",textAlign:"left",fontSize:11,color:"var(--hub-ink-3)",textTransform:"uppercase",letterSpacing:"0.08em",fontWeight:500},children:t},t))})}),e.jsx("tbody",{children:m.map(t=>e.jsxs("tr",{className:"transition-colors hover:bg-[var(--hub-surface-hover)]",style:{borderTop:"1px solid var(--hub-line-2)"},children:[e.jsx("td",{className:"hub-mono whitespace-nowrap",style:{padding:"10px 14px",fontSize:12,color:"var(--hub-ink-2)"},children:D(t.timestamp)}),e.jsx("td",{style:{padding:"10px 14px"},children:e.jsx("span",{className:"hub-tag",children:t.server})}),e.jsx("td",{style:{padding:"10px 14px"},children:e.jsx("span",{className:"hub-tag accent",children:t.tool})}),e.jsx("td",{className:"hub-mono hub-num whitespace-nowrap",style:{padding:"10px 14px",fontSize:12,color:"var(--hub-ink-2)"},children:P(t.duration)}),e.jsx("td",{style:{padding:"10px 14px"},className:"whitespace-nowrap",children:e.jsxs("span",{className:`hub-status ${t.status==="success"?"ok":"err"}`,children:[e.jsx("span",{className:"hub-dot"}),t.status==="success"?a("activity.statusSuccess"):a("activity.statusError")]})}),e.jsx("td",{style:{padding:"10px 14px",fontSize:12,color:"var(--hub-ink-3)"},children:t.group||"—"}),e.jsx("td",{style:{padding:"10px 14px",fontSize:12,color:"var(--hub-ink-3)"},children:t.keyName||"—"}),e.jsx("td",{style:{padding:"10px 14px"},children:e.jsx("button",{onClick:()=>K(t),className:"hub-btn ghost sm",style:{color:"var(--hub-accent)"},children:a("common.view")})})]},t.id))})]})})}),X=()=>{if(!H||!c)return null;const t=E(c.input),s=E(c.output);return e.jsx("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:e.jsxs("div",{className:"hub-card max-w-4xl w-full mx-4 max-h-[90vh] overflow-hidden",style:{boxShadow:"0 8px 24px rgba(0,0,0,0.12)"},children:[e.jsxs("div",{className:"flex items-center justify-between px-5 py-3",style:{borderBottom:"1px solid var(--hub-line-2)"},children:[e.jsx("h3",{className:"hub-card-title",children:a("activity.details")}),e.jsx("button",{onClick:()=>A(!1),className:"hub-icon-btn sm","aria-label":"close",children:e.jsx("svg",{className:"h-3.5 w-3.5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),e.jsxs("div",{className:"px-6 py-4 overflow-y-auto max-h-[calc(90vh-120px)]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 mb-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400",children:a("activity.timestamp")}),e.jsx("p",{className:"text-gray-900 dark:text-white",children:D(c.timestamp)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400",children:a("activity.duration")}),e.jsx("p",{className:"text-gray-900 dark:text-white",children:P(c.duration)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400",children:a("activity.server")}),e.jsx("p",{className:"text-gray-900 dark:text-white font-mono",children:c.server})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400",children:a("activity.tool")}),e.jsx("p",{className:"text-gray-900 dark:text-white font-mono",children:c.tool})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400",children:a("activity.status")}),e.jsx("span",{className:`px-2 py-1 rounded text-xs font-medium ${c.status==="success"?"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200":"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"}`,children:c.status==="success"?a("activity.statusSuccess"):a("activity.statusError")})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400",children:a("activity.group")}),e.jsx("p",{className:"text-gray-900 dark:text-white",children:c.group||"-"})]}),c.keyName&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400",children:a("activity.key")}),e.jsx("p",{className:"text-gray-900 dark:text-white",children:c.keyName})]})]}),c.errorMessage&&e.jsxs("div",{className:"mb-4",children:[e.jsx("label",{className:"block text-sm font-medium text-red-500 mb-1",children:a("activity.errorMessage")}),e.jsx("div",{className:"bg-red-50 dark:bg-red-900/20 rounded p-3 text-sm text-red-800 dark:text-red-200",children:c.errorMessage})]}),t&&e.jsxs("div",{className:"mb-4",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400 mb-1",children:a("activity.input")}),e.jsx("pre",{className:"bg-gray-100 dark:bg-gray-700 rounded p-3 text-sm overflow-x-auto max-h-64",children:typeof t=="string"?t:JSON.stringify(t,null,2)})]}),s&&e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-500 dark:text-gray-400 mb-1",children:a("activity.output")}),e.jsx("pre",{className:"bg-gray-100 dark:bg-gray-700 rounded p-3 text-sm overflow-x-auto max-h-64",children:typeof s=="string"?s:JSON.stringify(s,null,2)})]})]})]})})};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-end justify-between gap-4 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"hub-h1",children:a("activity.title")}),e.jsxs("p",{className:"hub-sub",children:[e.jsx("span",{className:"hub-num",children:(i==null?void 0:i.total)??m.length})," entries"]})]}),e.jsxs("button",{onClick:W,className:"hub-btn danger",children:[e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-3.5 w-3.5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z",clipRule:"evenodd"})}),a("activity.cleanup")]})]}),z&&e.jsxs("div",{className:"hub-card flex items-center justify-between gap-3 mb-4",style:{padding:"10px 14px",borderColor:"oklch(0.85 0.1 25)",background:"oklch(0.97 0.03 25)",color:"oklch(0.4 0.18 25)"},children:[e.jsx("span",{className:"truncate text-[13px]",children:z}),e.jsx("button",{className:"hub-icon-btn sm",onClick:()=>f(null),"aria-label":"close",children:e.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-3 w-3",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]}),j&&m.length===0?e.jsx("div",{className:"hub-card p-10 text-center",style:{color:"var(--hub-ink-3)"},children:a("app.loading")}):e.jsxs(e.Fragment,{children:[_(),q(),Q(),e.jsxs("div",{className:"flex items-center mt-6",children:[e.jsx("div",{className:"flex-[2] text-sm text-gray-500 dark:text-gray-400",children:i&&a("common.showing",{start:(i.page-1)*i.limit+1,end:Math.min(i.page*i.limit,i.total),total:i.total})}),e.jsx("div",{className:"flex-[4] flex justify-center",children:i&&i.totalPages>1&&e.jsx(se,{currentPage:o,totalPages:i.totalPages,onPageChange:d,disabled:j})}),e.jsxs("div",{className:"flex-[2] flex items-center justify-end space-x-2",children:[e.jsxs("label",{htmlFor:"perPage",className:"text-sm text-gray-500 dark:text-gray-400",children:[a("common.itemsPerPage"),":"]}),e.jsxs("select",{id:"perPage",value:b,onChange:t=>{J(Number(t.target.value)),d(1)},disabled:j,className:"border border-gray-300 dark:border-gray-600 rounded p-1 text-sm dark:bg-gray-700 dark:text-white outline-none disabled:opacity-50 disabled:cursor-not-allowed",children:[e.jsx("option",{value:10,children:"10"}),e.jsx("option",{value:20,children:"20"}),e.jsx("option",{value:50,children:"50"}),e.jsx("option",{value:100,children:"100"})]})]})]})]}),X()]})};export{xe as default};
2
+ //# sourceMappingURL=ActivityPage-VwilVMvp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActivityPage-VwilVMvp.js","sources":["../../src/pages/ActivityPage.tsx"],"sourcesContent":["import React, { useState, useEffect, useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport {\n Activity,\n ActivityStats,\n ActivityFilter,\n ActivityFilterOptions,\n ActivityStatus,\n} from '@/types';\nimport {\n getActivities,\n getActivityById,\n getActivityStats,\n getActivityFilterOptions,\n deleteOldActivities,\n} from '@/services/activityService';\nimport Pagination from '@/components/ui/Pagination';\n\n// Pagination info type\ninterface PaginationInfo {\n page: number;\n limit: number;\n total: number;\n totalPages: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n}\n\nconst STATUS_OPTIONS: ActivityStatus[] = ['success', 'error'];\n\nconst isValidStatus = (value: string): value is ActivityStatus =>\n STATUS_OPTIONS.includes(value as ActivityStatus);\n\nconst ActivityPage: React.FC = () => {\n const { t } = useTranslation();\n\n // State\n const [activities, setActivities] = useState<Activity[]>([]);\n const [stats, setStats] = useState<ActivityStats | null>(null);\n const [filterOptions, setFilterOptions] = useState<ActivityFilterOptions | null>(null);\n const [pagination, setPagination] = useState<PaginationInfo | null>(null);\n const [currentPage, setCurrentPage] = useState(1);\n const [itemsPerPage, setItemsPerPage] = useState(10);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [selectedActivity, setSelectedActivity] = useState<Activity | null>(null);\n const [showDetailModal, setShowDetailModal] = useState(false);\n\n // Filter state\n const [appliedFilters, setAppliedFilters] = useState<ActivityFilter>({});\n const [searchServer, setSearchServer] = useState('');\n const [searchTool, setSearchTool] = useState('');\n const [searchStatus, setSearchStatus] = useState<string>('');\n const [searchGroup, setSearchGroup] = useState('');\n const [searchKeyName, setSearchKeyName] = useState('');\n\n // Fetch data\n const fetchData = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n // Use appliedFilters directly for fetching\n const currentFilter = { ...appliedFilters };\n\n // Fetch activities, stats, and filter options in parallel\n const [activitiesRes, statsRes, optionsRes] = await Promise.all([\n getActivities(currentPage, itemsPerPage, currentFilter),\n getActivityStats(currentFilter),\n getActivityFilterOptions(),\n ]);\n\n if (activitiesRes?.success && Array.isArray(activitiesRes.data)) {\n setActivities(activitiesRes.data);\n if (activitiesRes.pagination) {\n setPagination(activitiesRes.pagination);\n }\n }\n\n if (statsRes?.success && statsRes.data) {\n setStats(statsRes.data);\n }\n\n if (optionsRes?.success && optionsRes.data) {\n setFilterOptions(optionsRes.data);\n }\n } catch (err) {\n console.error('Error fetching activity data:', err);\n setError(t('activity.fetchError'));\n } finally {\n setIsLoading(false);\n }\n }, [currentPage, itemsPerPage, appliedFilters, t]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n useEffect(() => {\n if (!pagination) {\n return;\n }\n\n const totalPages = Math.max(1, pagination.totalPages || 1);\n if (currentPage > totalPages) {\n setCurrentPage(totalPages);\n }\n }, [pagination, currentPage]);\n\n // Handle view activity details\n const handleViewDetails = async (activity: Activity) => {\n try {\n const response = await getActivityById(activity.id);\n if (response?.success && response.data) {\n setSelectedActivity(response.data);\n setShowDetailModal(true);\n }\n } catch (err) {\n console.error('Error fetching activity details:', err);\n }\n };\n\n // Handle cleanup old activities\n const handleCleanup = async () => {\n if (!window.confirm(t('activity.confirmCleanup'))) {\n return;\n }\n\n try {\n const response = await deleteOldActivities(30);\n if (response?.success) {\n alert(t('activity.cleanupSuccess', { count: response.data?.deletedCount || 0 }));\n fetchData();\n }\n } catch (err) {\n console.error('Error cleaning up activities:', err);\n alert(t('activity.cleanupError'));\n }\n };\n\n // Handle search\n const handleSearch = () => {\n const filters: ActivityFilter = {};\n if (searchServer) filters.server = searchServer;\n if (searchTool) filters.tool = searchTool;\n if (searchStatus && isValidStatus(searchStatus)) {\n filters.status = searchStatus;\n }\n if (searchGroup) filters.group = searchGroup;\n if (searchKeyName) filters.keyName = searchKeyName;\n\n setAppliedFilters(filters);\n setCurrentPage(1);\n };\n\n // Handle clear filters\n const handleClearFilters = () => {\n setSearchServer('');\n setSearchTool('');\n setSearchStatus('');\n setSearchGroup('');\n setSearchKeyName('');\n setAppliedFilters({});\n setCurrentPage(1);\n };\n\n // Format duration\n const formatDuration = (ms: number): string => {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\n return `${(ms / 60000).toFixed(2)}m`;\n };\n\n // Format timestamp\n const formatTimestamp = (timestamp: string): string => {\n return new Date(timestamp).toLocaleString();\n };\n\n // Parse JSON safely\n const safeParseJSON = (str: string | undefined): any => {\n if (!str) return null;\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n };\n\n // Render stats cards\n const renderStats = () => {\n if (!stats) return null;\n\n return (\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-3 mb-4\">\n {[\n { label: t('activity.totalCalls'), value: stats.totalCalls, tone: 'default' as const },\n { label: t('activity.successCount'), value: stats.successCount, tone: 'ok' as const },\n { label: t('activity.errorCount'), value: stats.errorCount, tone: 'err' as const },\n {\n label: t('activity.avgDuration'),\n value: formatDuration(stats.avgDuration),\n tone: 'default' as const,\n },\n ].map((s) => (\n <div key={s.label} className=\"hub-card\" style={{ padding: '12px 14px' }}>\n <div className=\"text-[12px]\" style={{ color: 'var(--hub-ink-3)' }}>\n {s.label}\n </div>\n <div\n className=\"hub-num\"\n style={{\n fontSize: 22,\n fontWeight: 500,\n lineHeight: 1.1,\n marginTop: 6,\n letterSpacing: '-0.02em',\n color:\n s.tone === 'ok'\n ? 'oklch(0.4 0.13 145)'\n : s.tone === 'err'\n ? 'oklch(0.45 0.18 25)'\n : 'var(--hub-ink)',\n }}\n >\n {s.value}\n </div>\n </div>\n ))}\n </div>\n );\n };\n\n // Render filters\n const renderFilters = () => {\n return (\n <div className=\"hub-card px-4 py-3 mb-4\">\n <div className=\"flex flex-wrap gap-3 items-end\">\n <div className=\"flex-1 min-w-[140px]\">\n <label className=\"sr-only\" htmlFor=\"activity-server\">\n {t('activity.server')}\n </label>\n <div className=\"relative\">\n <input\n id=\"activity-server\"\n type=\"text\"\n value={searchServer}\n onChange={(e) => setSearchServer(e.target.value)}\n placeholder={t('activity.searchServer')}\n className=\"hub-input pr-9\"\n list=\"server-options\"\n />\n {searchServer && (\n <button\n onClick={() => setSearchServer('')}\n className=\"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300\"\n aria-label={t('common.clear')}\n type=\"button\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </div>\n {filterOptions?.servers && (\n <datalist id=\"server-options\">\n {filterOptions.servers.map((s) => (\n <option key={s} value={s} />\n ))}\n </datalist>\n )}\n </div>\n <div className=\"flex-1 min-w-[140px]\">\n <label className=\"sr-only\" htmlFor=\"activity-tool\">\n {t('activity.tool')}\n </label>\n <div className=\"relative\">\n <input\n id=\"activity-tool\"\n type=\"text\"\n value={searchTool}\n onChange={(e) => setSearchTool(e.target.value)}\n placeholder={t('activity.searchTool')}\n className=\"hub-input pr-9\"\n list=\"tool-options\"\n />\n {searchTool && (\n <button\n onClick={() => setSearchTool('')}\n className=\"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300\"\n aria-label={t('common.clear')}\n type=\"button\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </div>\n {filterOptions?.tools && (\n <datalist id=\"tool-options\">\n {filterOptions.tools.map((t) => (\n <option key={t} value={t} />\n ))}\n </datalist>\n )}\n </div>\n <div className=\"flex-1 min-w-[140px]\">\n <label className=\"sr-only\" htmlFor=\"activity-status\">\n {t('activity.status')}\n </label>\n <div className=\"relative\">\n <input\n id=\"activity-status\"\n type=\"text\"\n value={searchStatus}\n onChange={(e) => setSearchStatus(e.target.value.toLowerCase())}\n placeholder={t('activity.searchStatus')}\n className=\"hub-input pr-9\"\n list=\"activity-status-options\"\n />\n {searchStatus && (\n <button\n onClick={() => setSearchStatus('')}\n className=\"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300\"\n aria-label={t('common.clear')}\n type=\"button\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </div>\n <datalist id=\"activity-status-options\">\n {STATUS_OPTIONS.map((status) => (\n <option key={status} value={status} />\n ))}\n </datalist>\n </div>\n <div className=\"flex-1 min-w-[140px]\">\n <label className=\"sr-only\" htmlFor=\"activity-group\">\n {t('activity.group')}\n </label>\n <div className=\"relative\">\n <input\n id=\"activity-group\"\n type=\"text\"\n value={searchGroup}\n onChange={(e) => setSearchGroup(e.target.value)}\n placeholder={t('activity.searchGroup')}\n className=\"hub-input pr-9\"\n list=\"group-options\"\n />\n {searchGroup && (\n <button\n onClick={() => setSearchGroup('')}\n className=\"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300\"\n aria-label={t('common.clear')}\n type=\"button\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </div>\n {filterOptions?.groups && (\n <datalist id=\"group-options\">\n {filterOptions.groups.map((g) => (\n <option key={g} value={g} />\n ))}\n </datalist>\n )}\n </div>\n <div className=\"flex-1 min-w-[140px]\">\n <label className=\"sr-only\" htmlFor=\"activity-keyname\">\n {t('activity.keyName')}\n </label>\n <div className=\"relative\">\n <input\n id=\"activity-keyname\"\n type=\"text\"\n value={searchKeyName}\n onChange={(e) => setSearchKeyName(e.target.value)}\n placeholder={t('activity.searchKeyName')}\n className=\"hub-input pr-9\"\n list=\"keyname-options\"\n />\n {searchKeyName && (\n <button\n onClick={() => setSearchKeyName('')}\n className=\"absolute inset-y-0 right-2 flex items-center text-gray-400 hover:text-gray-600 dark:hover:text-gray-300\"\n aria-label={t('common.clear')}\n type=\"button\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </div>\n {filterOptions?.keyNames && (\n <datalist id=\"keyname-options\">\n {filterOptions.keyNames.map((k) => (\n <option key={k} value={k} />\n ))}\n </datalist>\n )}\n </div>\n <div className=\"flex-shrink-0 flex items-center gap-2\">\n <button onClick={handleSearch} className=\"hub-btn primary whitespace-nowrap\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-3.5 w-3.5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {t('common.search')}\n </button>\n <button onClick={handleClearFilters} className=\"hub-btn whitespace-nowrap\">\n {t('common.clear')}\n </button>\n </div>\n </div>\n </div>\n );\n };\n\n // Render activity table\n const renderActivityTable = () => {\n if (activities.length === 0) {\n return (\n <div className=\"hub-card p-10 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n {t('activity.noData')}\n </div>\n );\n }\n\n return (\n <div className=\"hub-card overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full\">\n <thead style={{ background: 'var(--hub-bg-2)' }}>\n <tr>\n {[\n t('activity.timestamp'),\n t('activity.server'),\n t('activity.tool'),\n t('activity.duration'),\n t('activity.status'),\n t('activity.group'),\n t('activity.key'),\n t('common.actions'),\n ].map((label) => (\n <th\n key={label}\n className=\"hub-mono\"\n style={{\n padding: '9px 14px',\n textAlign: 'left',\n fontSize: 11,\n color: 'var(--hub-ink-3)',\n textTransform: 'uppercase',\n letterSpacing: '0.08em',\n fontWeight: 500,\n }}\n >\n {label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {activities.map((activity) => (\n <tr\n key={activity.id}\n className=\"transition-colors hover:bg-[var(--hub-surface-hover)]\"\n style={{ borderTop: '1px solid var(--hub-line-2)' }}\n >\n <td\n className=\"hub-mono whitespace-nowrap\"\n style={{ padding: '10px 14px', fontSize: 12, color: 'var(--hub-ink-2)' }}\n >\n {formatTimestamp(activity.timestamp)}\n </td>\n <td style={{ padding: '10px 14px' }}>\n <span className=\"hub-tag\">{activity.server}</span>\n </td>\n <td style={{ padding: '10px 14px' }}>\n <span className=\"hub-tag accent\">{activity.tool}</span>\n </td>\n <td\n className=\"hub-mono hub-num whitespace-nowrap\"\n style={{ padding: '10px 14px', fontSize: 12, color: 'var(--hub-ink-2)' }}\n >\n {formatDuration(activity.duration)}\n </td>\n <td style={{ padding: '10px 14px' }} className=\"whitespace-nowrap\">\n <span\n className={`hub-status ${activity.status === 'success' ? 'ok' : 'err'}`}\n >\n <span className=\"hub-dot\" />\n {activity.status === 'success'\n ? t('activity.statusSuccess')\n : t('activity.statusError')}\n </span>\n </td>\n <td\n style={{ padding: '10px 14px', fontSize: 12, color: 'var(--hub-ink-3)' }}\n >\n {activity.group || '—'}\n </td>\n <td\n style={{ padding: '10px 14px', fontSize: 12, color: 'var(--hub-ink-3)' }}\n >\n {activity.keyName || '—'}\n </td>\n <td style={{ padding: '10px 14px' }}>\n <button\n onClick={() => handleViewDetails(activity)}\n className=\"hub-btn ghost sm\"\n style={{ color: 'var(--hub-accent)' }}\n >\n {t('common.view')}\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n );\n };\n\n // Render detail modal\n const renderDetailModal = () => {\n if (!showDetailModal || !selectedActivity) return null;\n\n const inputData = safeParseJSON(selectedActivity.input);\n const outputData = safeParseJSON(selectedActivity.output);\n\n return (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div\n className=\"hub-card max-w-4xl w-full mx-4 max-h-[90vh] overflow-hidden\"\n style={{ boxShadow: '0 8px 24px rgba(0,0,0,0.12)' }}\n >\n <div\n className=\"flex items-center justify-between px-5 py-3\"\n style={{ borderBottom: '1px solid var(--hub-line-2)' }}\n >\n <h3 className=\"hub-card-title\">{t('activity.details')}</h3>\n <button\n onClick={() => setShowDetailModal(false)}\n className=\"hub-icon-btn sm\"\n aria-label=\"close\"\n >\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n <div className=\"px-6 py-4 overflow-y-auto max-h-[calc(90vh-120px)]\">\n <div className=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400\">\n {t('activity.timestamp')}\n </label>\n <p className=\"text-gray-900 dark:text-white\">\n {formatTimestamp(selectedActivity.timestamp)}\n </p>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400\">\n {t('activity.duration')}\n </label>\n <p className=\"text-gray-900 dark:text-white\">\n {formatDuration(selectedActivity.duration)}\n </p>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400\">\n {t('activity.server')}\n </label>\n <p className=\"text-gray-900 dark:text-white font-mono\">{selectedActivity.server}</p>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400\">\n {t('activity.tool')}\n </label>\n <p className=\"text-gray-900 dark:text-white font-mono\">{selectedActivity.tool}</p>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400\">\n {t('activity.status')}\n </label>\n <span\n className={`px-2 py-1 rounded text-xs font-medium ${\n selectedActivity.status === 'success'\n ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'\n : 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'\n }`}\n >\n {selectedActivity.status === 'success'\n ? t('activity.statusSuccess')\n : t('activity.statusError')}\n </span>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400\">\n {t('activity.group')}\n </label>\n <p className=\"text-gray-900 dark:text-white\">{selectedActivity.group || '-'}</p>\n </div>\n {selectedActivity.keyName && (\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400\">\n {t('activity.key')}\n </label>\n <p className=\"text-gray-900 dark:text-white\">{selectedActivity.keyName}</p>\n </div>\n )}\n </div>\n\n {selectedActivity.errorMessage && (\n <div className=\"mb-4\">\n <label className=\"block text-sm font-medium text-red-500 mb-1\">\n {t('activity.errorMessage')}\n </label>\n <div className=\"bg-red-50 dark:bg-red-900/20 rounded p-3 text-sm text-red-800 dark:text-red-200\">\n {selectedActivity.errorMessage}\n </div>\n </div>\n )}\n\n {inputData && (\n <div className=\"mb-4\">\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400 mb-1\">\n {t('activity.input')}\n </label>\n <pre className=\"bg-gray-100 dark:bg-gray-700 rounded p-3 text-sm overflow-x-auto max-h-64\">\n {typeof inputData === 'string' ? inputData : JSON.stringify(inputData, null, 2)}\n </pre>\n </div>\n )}\n\n {outputData && (\n <div>\n <label className=\"block text-sm font-medium text-gray-500 dark:text-gray-400 mb-1\">\n {t('activity.output')}\n </label>\n <pre className=\"bg-gray-100 dark:bg-gray-700 rounded p-3 text-sm overflow-x-auto max-h-64\">\n {typeof outputData === 'string'\n ? outputData\n : JSON.stringify(outputData, null, 2)}\n </pre>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n };\n\n return (\n <div>\n <div className=\"flex items-end justify-between gap-4 mb-6\">\n <div>\n <h1 className=\"hub-h1\">{t('activity.title')}</h1>\n <p className=\"hub-sub\">\n <span className=\"hub-num\">{pagination?.total ?? activities.length}</span> entries\n </p>\n </div>\n <button onClick={handleCleanup} className=\"hub-btn danger\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-3.5 w-3.5\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {t('activity.cleanup')}\n </button>\n </div>\n\n {error && (\n <div\n className=\"hub-card flex items-center justify-between gap-3 mb-4\"\n style={{\n padding: '10px 14px',\n borderColor: 'oklch(0.85 0.1 25)',\n background: 'oklch(0.97 0.03 25)',\n color: 'oklch(0.4 0.18 25)',\n }}\n >\n <span className=\"truncate text-[13px]\">{error}</span>\n <button className=\"hub-icon-btn sm\" onClick={() => setError(null)} aria-label=\"close\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-3 w-3\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n </div>\n )}\n\n {isLoading && activities.length === 0 ? (\n <div className=\"hub-card p-10 text-center\" style={{ color: 'var(--hub-ink-3)' }}>\n {t('app.loading')}\n </div>\n ) : (\n <>\n {renderStats()}\n {renderFilters()}\n {renderActivityTable()}\n\n {/* Pagination */}\n <div className=\"flex items-center mt-6\">\n <div className=\"flex-[2] text-sm text-gray-500 dark:text-gray-400\">\n {pagination &&\n t('common.showing', {\n start: (pagination.page - 1) * pagination.limit + 1,\n end: Math.min(pagination.page * pagination.limit, pagination.total),\n total: pagination.total,\n })}\n </div>\n <div className=\"flex-[4] flex justify-center\">\n {pagination && pagination.totalPages > 1 && (\n <Pagination\n currentPage={currentPage}\n totalPages={pagination.totalPages}\n onPageChange={setCurrentPage}\n disabled={isLoading}\n />\n )}\n </div>\n <div className=\"flex-[2] flex items-center justify-end space-x-2\">\n <label htmlFor=\"perPage\" className=\"text-sm text-gray-500 dark:text-gray-400\">\n {t('common.itemsPerPage')}:\n </label>\n <select\n id=\"perPage\"\n value={itemsPerPage}\n onChange={(e) => {\n setItemsPerPage(Number(e.target.value));\n setCurrentPage(1);\n }}\n disabled={isLoading}\n className=\"border border-gray-300 dark:border-gray-600 rounded p-1 text-sm dark:bg-gray-700 dark:text-white outline-none disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <option value={10}>10</option>\n <option value={20}>20</option>\n <option value={50}>50</option>\n <option value={100}>100</option>\n </select>\n </div>\n </div>\n </>\n )}\n\n {renderDetailModal()}\n </div>\n );\n};\n\nexport default ActivityPage;\n"],"names":["STATUS_OPTIONS","isValidStatus","value","ActivityPage","t","useTranslation","activities","setActivities","useState","stats","setStats","filterOptions","setFilterOptions","pagination","setPagination","currentPage","setCurrentPage","itemsPerPage","setItemsPerPage","isLoading","setIsLoading","error","setError","selectedActivity","setSelectedActivity","showDetailModal","setShowDetailModal","appliedFilters","setAppliedFilters","searchServer","setSearchServer","searchTool","setSearchTool","searchStatus","setSearchStatus","searchGroup","setSearchGroup","searchKeyName","setSearchKeyName","fetchData","useCallback","currentFilter","activitiesRes","statsRes","optionsRes","getActivities","getActivityStats","getActivityFilterOptions","err","useEffect","totalPages","handleViewDetails","activity","response","getActivityById","handleCleanup","deleteOldActivities","_a","handleSearch","filters","handleClearFilters","formatDuration","ms","formatTimestamp","timestamp","safeParseJSON","str","renderStats","jsx","s","jsxs","renderFilters","e","status","g","k","renderActivityTable","label","renderDetailModal","inputData","outputData","Fragment","Pagination"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{j as e}from"./framework-vendor-BUhDPOUZ.js";import{u as j}from"./i18n-vendor-Kbr87Ofu.js";const k=({isOpen:o,onClose:s,onConfirm:r,title:i,message:c,confirmText:l,cancelText:d,variant:m="warning"})=>{const{t:a}=j();if(!o)return null;const h=()=>{switch(m){case"danger":return{icon:e.jsx("svg",{className:"w-6 h-6 text-red-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"})}),confirmBtnClass:"hub-btn danger"};case"warning":return{icon:e.jsx("svg",{className:"w-6 h-6 text-yellow-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"})}),confirmBtnClass:"hub-btn primary"};case"info":return{icon:e.jsx("svg",{className:"w-6 h-6 text-blue-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})}),confirmBtnClass:"hub-btn primary"};default:return{icon:null,confirmBtnClass:"hub-btn primary"}}},{icon:t,confirmBtnClass:u}=h(),x=n=>{n.target===n.currentTarget&&s()},f=n=>{n.key==="Escape"?s():n.key==="Enter"&&r()};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-[100] flex items-center justify-center p-4",onClick:x,onKeyDown:f,tabIndex:-1,children:e.jsx("div",{className:"hub-card max-w-md w-full transform transition-all duration-200 ease-out",role:"dialog","aria-modal":"true","aria-labelledby":"confirm-dialog-title","aria-describedby":"confirm-dialog-message",children:e.jsxs("div",{className:"p-6",children:[e.jsxs("div",{className:"flex items-start space-x-3",children:[t&&e.jsx("div",{className:"flex-shrink-0",children:t}),e.jsxs("div",{className:"flex-1",children:[i&&e.jsx("h3",{id:"confirm-dialog-title",className:"text-lg font-medium text-gray-900 mb-2",children:i}),e.jsx("p",{id:"confirm-dialog-message",className:"text-gray-600 leading-relaxed",children:c})]})]}),e.jsxs("div",{className:"flex justify-end space-x-3 mt-6",children:[e.jsx("button",{onClick:s,className:"hub-btn",autoFocus:!0,children:d||a("common.cancel")}),e.jsx("button",{onClick:r,className:u,children:l||a("common.confirm")})]})]})})})};export{k as C};
2
+ //# sourceMappingURL=ConfirmDialog-CxlizGia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog-CxlizGia.js","sources":["../../src/components/ui/ConfirmDialog.tsx"],"sourcesContent":["import React from 'react';\nimport { useTranslation } from 'react-i18next';\n\ninterface ConfirmDialogProps {\n isOpen: boolean;\n onClose: () => void;\n onConfirm: () => void;\n title?: string;\n message: string;\n confirmText?: string;\n cancelText?: string;\n variant?: 'danger' | 'warning' | 'info';\n}\n\nconst ConfirmDialog: React.FC<ConfirmDialogProps> = ({\n isOpen,\n onClose,\n onConfirm,\n title,\n message,\n confirmText,\n cancelText,\n variant = 'warning'\n}) => {\n const { t } = useTranslation();\n\n if (!isOpen) return null;\n\n const getVariantStyles = () => {\n switch (variant) {\n case 'danger':\n return {\n icon: (\n <svg className=\"w-6 h-6 text-red-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n ),\n confirmBtnClass: 'hub-btn danger',\n };\n case 'warning':\n return {\n icon: (\n <svg className=\"w-6 h-6 text-yellow-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z\" />\n </svg>\n ),\n confirmBtnClass: 'hub-btn primary',\n };\n case 'info':\n return {\n icon: (\n <svg className=\"w-6 h-6 text-blue-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n ),\n confirmBtnClass: 'hub-btn primary',\n };\n default:\n return {\n icon: null,\n confirmBtnClass: 'hub-btn primary',\n };\n }\n };\n\n const { icon, confirmBtnClass } = getVariantStyles();\n\n const handleBackdropClick = (e: React.MouseEvent) => {\n if (e.target === e.currentTarget) {\n onClose();\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose();\n } else if (e.key === 'Enter') {\n onConfirm();\n }\n };\n\n return (\n <div\n className=\"fixed inset-0 bg-black/50 z-[100] flex items-center justify-center p-4\"\n onClick={handleBackdropClick}\n onKeyDown={handleKeyDown}\n tabIndex={-1}\n >\n <div\n className=\"hub-card max-w-md w-full transform transition-all duration-200 ease-out\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"confirm-dialog-title\"\n aria-describedby=\"confirm-dialog-message\"\n >\n <div className=\"p-6\">\n <div className=\"flex items-start space-x-3\">\n {icon && (\n <div className=\"flex-shrink-0\">\n {icon}\n </div>\n )}\n <div className=\"flex-1\">\n {title && (\n <h3\n id=\"confirm-dialog-title\"\n className=\"text-lg font-medium text-gray-900 mb-2\"\n >\n {title}\n </h3>\n )}\n <p\n id=\"confirm-dialog-message\"\n className=\"text-gray-600 leading-relaxed\"\n >\n {message}\n </p>\n </div>\n </div>\n\n <div className=\"flex justify-end space-x-3 mt-6\">\n <button\n onClick={onClose}\n className=\"hub-btn\"\n autoFocus\n >\n {cancelText || t('common.cancel')}\n </button>\n <button\n onClick={onConfirm}\n className={confirmBtnClass}\n >\n {confirmText || t('common.confirm')}\n </button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default ConfirmDialog;\n"],"names":["ConfirmDialog","isOpen","onClose","onConfirm","title","message","confirmText","cancelText","variant","t","useTranslation","getVariantStyles","jsx","icon","confirmBtnClass","handleBackdropClick","e","handleKeyDown","jsxs"],"mappings":"iGAcA,MAAMA,EAA8C,CAAC,CACnD,OAAAC,EACA,QAAAC,EACA,UAAAC,EACA,MAAAC,EACA,QAAAC,EACA,YAAAC,EACA,WAAAC,EACA,QAAAC,EAAU,SACZ,IAAM,CACJ,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAA,EAEd,GAAI,CAACT,EAAQ,OAAO,KAEpB,MAAMU,EAAmB,IAAM,CAC7B,OAAQH,EAAA,CACN,IAAK,SACH,MAAO,CACL,WACG,MAAA,CAAI,UAAU,uBAAuB,KAAK,OAAO,QAAQ,YAAY,OAAO,eAC3E,SAAAI,EAAAA,IAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,2IAAA,CAA4I,CAAA,CACnN,EAEF,gBAAiB,gBAAA,EAErB,IAAK,UACH,MAAO,CACL,WACG,MAAA,CAAI,UAAU,0BAA0B,KAAK,OAAO,QAAQ,YAAY,OAAO,eAC9E,SAAAA,EAAAA,IAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,2IAAA,CAA4I,CAAA,CACnN,EAEF,gBAAiB,iBAAA,EAErB,IAAK,OACH,MAAO,CACL,WACG,MAAA,CAAI,UAAU,wBAAwB,KAAK,OAAO,QAAQ,YAAY,OAAO,eAC5E,SAAAA,EAAAA,IAAC,OAAA,CAAK,cAAc,QAAQ,eAAe,QAAQ,YAAa,EAAG,EAAE,2DAAA,CAA4D,CAAA,CACnI,EAEF,gBAAiB,iBAAA,EAErB,QACE,MAAO,CACL,KAAM,KACN,gBAAiB,iBAAA,CACnB,CAEN,EAEM,CAAE,KAAAC,EAAM,gBAAAC,CAAA,EAAoBH,EAAA,EAE5BI,EAAuBC,GAAwB,CAC/CA,EAAE,SAAWA,EAAE,eACjBd,EAAA,CAEJ,EAEMe,EAAiBD,GAA2B,CAC5CA,EAAE,MAAQ,SACZd,EAAA,EACSc,EAAE,MAAQ,SACnBb,EAAA,CAEJ,EAEA,OACES,EAAAA,IAAC,MAAA,CACC,UAAU,yEACV,QAASG,EACT,UAAWE,EACX,SAAU,GAEV,SAAAL,EAAAA,IAAC,MAAA,CACC,UAAU,0EACV,KAAK,SACL,aAAW,OACX,kBAAgB,uBAChB,mBAAiB,yBAEjB,SAAAM,EAAAA,KAAC,MAAA,CAAI,UAAU,MACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,6BACZ,SAAA,CAAAL,GACCD,EAAAA,IAAC,MAAA,CAAI,UAAU,gBACZ,SAAAC,EACH,EAEFK,EAAAA,KAAC,MAAA,CAAI,UAAU,SACZ,SAAA,CAAAd,GACCQ,EAAAA,IAAC,KAAA,CACC,GAAG,uBACH,UAAU,yCAET,SAAAR,CAAA,CAAA,EAGLQ,EAAAA,IAAC,IAAA,CACC,GAAG,yBACH,UAAU,gCAET,SAAAP,CAAA,CAAA,CACH,CAAA,CACF,CAAA,EACF,EAEAa,EAAAA,KAAC,MAAA,CAAI,UAAU,kCACb,SAAA,CAAAN,EAAAA,IAAC,SAAA,CACC,QAASV,EACT,UAAU,UACV,UAAS,GAER,SAAAK,GAAcE,EAAE,eAAe,CAAA,CAAA,EAElCG,EAAAA,IAAC,SAAA,CACC,QAAST,EACT,UAAWW,EAEV,SAAAR,GAAeG,EAAE,gBAAgB,CAAA,CAAA,CACpC,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAGN"}
@@ -0,0 +1,2 @@
1
+ import{b as z,R as m,r as k,j as e}from"./framework-vendor-BUhDPOUZ.js";import{u as E}from"./useServerData-BnLmpLAC.js";import{d as $}from"./index-B9cW2F0H.js";import{u as D}from"./useSettingsData-Cqi9d7Ug.js";import{E as h}from"./EndpointCopy-C59moJ3Y.js";import{S as L}from"./StatusDot-DR803YdX.js";import{u as T}from"./i18n-vendor-Kbr87Ofu.js";import{R as M,P,j as S,k as A}from"./icons-vendor-CKgJB3SC.js";const c=({label:s,value:l,tone:a="default"})=>{const t=a==="ok"?"oklch(0.4 0.13 145)":a==="warn"?"oklch(0.45 0.13 80)":a==="err"?"oklch(0.45 0.18 25)":a==="muted"?"var(--hub-ink-3)":"var(--hub-ink)";return e.jsxs("div",{className:"hub-card",style:{padding:"14px 16px"},children:[e.jsx("div",{className:"text-[12px]",style:{color:"var(--hub-ink-3)"},children:s}),e.jsx("div",{className:"hub-num",style:{fontSize:26,fontWeight:500,letterSpacing:"-0.02em",lineHeight:1.1,marginTop:8,color:t},children:l})]})},U=(s,l)=>l?l==="stdio"?s("server.typeStdio")||"stdio":l==="sse"?s("server.typeSse")||"sse":l==="streamable-http"?s("server.typeStreamableHttp")||"http":l==="openapi"?s("server.typeOpenapi")||"openapi":l:null,F=()=>{var j;const{t:s}=T(),l=z(),{allServers:a,error:t,setError:y,isLoading:p,triggerRefresh:C}=E({refreshOnMount:!0}),{groups:b}=$(),{installConfig:u}=D(),[w,x]=m.useState(!1),v=m.useRef(!1);m.useEffect(()=>{if(p){v.current=!0;return}if(v.current){x(!0);return}(a.length>0||t)&&x(!0)},[p,a.length,t]);const n=k.useMemo(()=>({total:a.length,online:a.filter(r=>r.status==="connected").length,disabled:a.filter(r=>r.enabled===!1).length,offline:a.filter(r=>r.status==="disconnected"&&r.enabled!==!1).length,connecting:a.filter(r=>(r.status==="connecting"||r.status==="oauth_required")&&r.enabled!==!1).length,tools:a.reduce((r,i)=>{var o;return r+(((o=i.tools)==null?void 0:o.length)||0)},0)}),[a]),R=k.useMemo(()=>a.slice(0,6),[a]),d=((j=u==null?void 0:u.baseUrl)==null?void 0:j.replace(/\/+$/,""))||"",g=!w;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-end justify-between gap-4 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"hub-h1",children:s("pages.dashboard.title")}),e.jsxs("p",{className:"hub-sub",children:[s("pages.dashboard.totalServers")," · ",e.jsx("span",{className:"hub-num",children:n.total})," · ",s("pages.dashboard.onlineServers")," · ",e.jsx("span",{className:"hub-num",children:n.online})]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{className:"hub-btn",onClick:()=>C(),children:[e.jsx(M,{size:13})," ",s("common.refresh")]}),e.jsxs("button",{className:"hub-btn primary",onClick:()=>l("/servers"),children:[e.jsx(P,{size:13})," ",s("server.add")]})]})]}),t&&e.jsxs("div",{className:"hub-card flex items-center justify-between gap-3 mb-5",style:{padding:"10px 14px",borderColor:"oklch(0.85 0.1 25)",background:"oklch(0.97 0.03 25)",color:"oklch(0.4 0.18 25)"},children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(S,{size:14,className:"flex-shrink-0"}),e.jsx("span",{className:"truncate text-[13px]",children:t})]}),e.jsx("button",{className:"hub-icon-btn sm",onClick:()=>y(null),"aria-label":s("app.closeButton"),children:"✕"})]}),g?e.jsx("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-3 mb-6",children:Array.from({length:5}).map((r,i)=>e.jsx("div",{className:"hub-card animate-pulse",style:{padding:"14px 16px",height:78}},i))}):e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-3 mb-6",children:[e.jsx(c,{label:s("pages.dashboard.totalServers"),value:n.total}),e.jsx(c,{label:s("pages.dashboard.onlineServers"),value:n.online,tone:"ok"}),e.jsx(c,{label:s("pages.dashboard.connectingServers"),value:n.connecting,tone:"warn"}),e.jsx(c,{label:s("pages.dashboard.offlineServers"),value:n.offline,tone:"err"}),e.jsx(c,{label:s("pages.dashboard.disabledServers"),value:n.disabled,tone:"muted"})]}),a.length>0&&!g&&e.jsxs("div",{className:"hub-card overflow-hidden mb-6",children:[e.jsxs("div",{className:"flex items-center justify-between px-4 py-3",style:{borderBottom:"1px solid var(--hub-line-2)"},children:[e.jsx("h3",{className:"hub-card-title",children:s("pages.dashboard.recentServers")}),e.jsxs("button",{className:"hub-btn ghost sm",style:{color:"var(--hub-ink-3)"},onClick:()=>l("/servers"),children:[s("common.viewAll")||"View all",e.jsx(A,{size:12})]})]}),e.jsxs("div",{className:"hub-row head hub-mono",style:{gridTemplateColumns:"1.3fr 110px 70px 90px 80px 80px 80px"},children:[e.jsx("div",{children:s("server.name")}),e.jsx("div",{children:s("server.status")}),e.jsx("div",{children:s("common.type")||"Transport"}),e.jsx("div",{children:s("server.tools")}),e.jsx("div",{children:s("server.prompts")}),e.jsx("div",{children:s("nav.resources")}),e.jsx("div",{children:s("server.enabled")})]}),R.map(r=>{var i,o,f,N;return e.jsxs("div",{className:"hub-row hover cursor-pointer",style:{gridTemplateColumns:"1.3fr 110px 70px 90px 80px 80px 80px"},onClick:()=>l("/servers"),children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx("span",{className:"hub-mono truncate",style:{fontSize:13,color:r.enabled===!1?"var(--hub-ink-3)":"var(--hub-ink)"},children:r.name}),r.error&&e.jsx(S,{size:13,className:"text-[var(--hub-err)] flex-shrink-0"})]}),e.jsx("div",{children:e.jsx(L,{status:r.status,enabled:r.enabled})}),e.jsx("div",{children:(i=r.config)!=null&&i.type?e.jsx("span",{className:"hub-tag",children:U(s,r.config.type)}):e.jsx("span",{style:{color:"var(--hub-ink-3)",fontSize:12},children:"—"})}),e.jsx("div",{className:"hub-num hub-mono",style:{fontSize:12.5},children:((o=r.tools)==null?void 0:o.length)||0}),e.jsx("div",{className:"hub-num hub-mono",style:{fontSize:12.5,color:"var(--hub-ink-2)"},children:((f=r.prompts)==null?void 0:f.length)||0}),e.jsx("div",{className:"hub-num hub-mono",style:{fontSize:12.5,color:"var(--hub-ink-2)"},children:((N=r.resources)==null?void 0:N.length)||0}),e.jsx("div",{className:"text-[12px]",style:{color:r.enabled!==!1?"var(--hub-ok)":"var(--hub-ink-3)"},children:r.enabled!==!1?"✓":"—"})]},r.name)})]}),e.jsxs("div",{className:"hub-card mb-5",style:{padding:16},children:[e.jsxs("div",{className:"flex justify-between items-start gap-3 mb-3",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"hub-card-title",children:s("pages.dashboard.endpoints")||"MCP Endpoints"}),e.jsx("p",{className:"hub-sub",style:{marginTop:2},children:s("pages.dashboard.endpointsHint")||"Use these URLs in Claude Desktop, Cursor, or any MCP client"})]}),e.jsxs("a",{className:"hub-btn ghost",href:"https://docs.mcphub.app",target:"_blank",rel:"noopener noreferrer",style:{color:"var(--hub-ink-3)"},children:[s("common.docs")||"Docs"," →"]})]}),e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-2.5",children:[e.jsx(h,{label:"ALL",url:`${d}/mcp`}),e.jsx(h,{label:"SMART",url:`${d}/mcp/$smart`}),b.slice(0,2).map(r=>e.jsx(h,{label:"GROUP",url:`${d}/mcp/${r.name}`},r.id)),b.length<2&&a[0]&&e.jsx(h,{label:"SERVER",url:`${d}/mcp/${a[0].name}`})]})]})]})};export{F as default};
2
+ //# sourceMappingURL=Dashboard-DuBJTbbA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dashboard-DuBJTbbA.js","sources":["../../src/pages/Dashboard.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router-dom';\nimport { RefreshCw, Plus, ChevronRight, AlertCircle } from 'lucide-react';\nimport { useServerData } from '@/hooks/useServerData';\nimport { useGroupData } from '@/hooks/useGroupData';\nimport { useSettingsData } from '@/hooks/useSettingsData';\nimport { Server } from '@/types';\nimport { EndpointCopy } from '@/components/ui/EndpointCopy';\nimport { ServerStatusDot } from '@/components/ui/StatusDot';\n\nconst Stat: React.FC<{ label: string; value: React.ReactNode; tone?: 'ok' | 'warn' | 'err' | 'muted' | 'default' }> = ({\n label,\n value,\n tone = 'default',\n}) => {\n const toneColor =\n tone === 'ok'\n ? 'oklch(0.4 0.13 145)'\n : tone === 'warn'\n ? 'oklch(0.45 0.13 80)'\n : tone === 'err'\n ? 'oklch(0.45 0.18 25)'\n : tone === 'muted'\n ? 'var(--hub-ink-3)'\n : 'var(--hub-ink)';\n return (\n <div className=\"hub-card\" style={{ padding: '14px 16px' }}>\n <div className=\"text-[12px]\" style={{ color: 'var(--hub-ink-3)' }}>\n {label}\n </div>\n <div\n className=\"hub-num\"\n style={{\n fontSize: 26,\n fontWeight: 500,\n letterSpacing: '-0.02em',\n lineHeight: 1.1,\n marginTop: 8,\n color: toneColor,\n }}\n >\n {value}\n </div>\n </div>\n );\n};\n\nconst transportLabel = (t: any, type?: string) => {\n if (!type) return null;\n if (type === 'stdio') return t('server.typeStdio') || 'stdio';\n if (type === 'sse') return t('server.typeSse') || 'sse';\n if (type === 'streamable-http') return t('server.typeStreamableHttp') || 'http';\n if (type === 'openapi') return t('server.typeOpenapi') || 'openapi';\n return type;\n};\n\nconst DashboardPage: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { allServers, error, setError, isLoading, triggerRefresh } = useServerData({\n refreshOnMount: true,\n });\n const { groups } = useGroupData();\n const { installConfig } = useSettingsData();\n\n const [hasLoaded, setHasLoaded] = React.useState(false);\n const loadingStartedRef = React.useRef(false);\n React.useEffect(() => {\n if (isLoading) {\n loadingStartedRef.current = true;\n return;\n }\n if (loadingStartedRef.current) {\n setHasLoaded(true);\n return;\n }\n if (allServers.length > 0 || error) setHasLoaded(true);\n }, [isLoading, allServers.length, error]);\n\n const stats = useMemo(\n () => ({\n total: allServers.length,\n online: allServers.filter((s: Server) => s.status === 'connected').length,\n disabled: allServers.filter((s: Server) => s.enabled === false).length,\n offline: allServers.filter(\n (s: Server) => s.status === 'disconnected' && s.enabled !== false,\n ).length,\n connecting: allServers.filter(\n (s: Server) =>\n (s.status === 'connecting' || s.status === 'oauth_required') && s.enabled !== false,\n ).length,\n tools: allServers.reduce((acc, s) => acc + (s.tools?.length || 0), 0),\n }),\n [allServers],\n );\n\n const recentServers = useMemo(() => allServers.slice(0, 6), [allServers]);\n const baseUrl = installConfig?.baseUrl?.replace(/\\/+$/, '') || '';\n\n const showSkeleton = !hasLoaded;\n\n return (\n <div>\n {/* Header */}\n <div className=\"flex items-end justify-between gap-4 mb-6\">\n <div>\n <h1 className=\"hub-h1\">{t('pages.dashboard.title')}</h1>\n <p className=\"hub-sub\">\n {t('pages.dashboard.totalServers')} · <span className=\"hub-num\">{stats.total}</span>\n {' · '}\n {t('pages.dashboard.onlineServers')} · <span className=\"hub-num\">{stats.online}</span>\n </p>\n </div>\n <div className=\"flex gap-2\">\n <button className=\"hub-btn\" onClick={() => triggerRefresh()}>\n <RefreshCw size={13} /> {t('common.refresh')}\n </button>\n <button className=\"hub-btn primary\" onClick={() => navigate('/servers')}>\n <Plus size={13} /> {t('server.add')}\n </button>\n </div>\n </div>\n\n {error && (\n <div\n className=\"hub-card flex items-center justify-between gap-3 mb-5\"\n style={{\n padding: '10px 14px',\n borderColor: 'oklch(0.85 0.1 25)',\n background: 'oklch(0.97 0.03 25)',\n color: 'oklch(0.4 0.18 25)',\n }}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <AlertCircle size={14} className=\"flex-shrink-0\" />\n <span className=\"truncate text-[13px]\">{error}</span>\n </div>\n <button\n className=\"hub-icon-btn sm\"\n onClick={() => setError(null)}\n aria-label={t('app.closeButton')}\n >\n ✕\n </button>\n </div>\n )}\n\n {/* Stat row */}\n {showSkeleton ? (\n <div className=\"grid grid-cols-2 md:grid-cols-5 gap-3 mb-6\">\n {Array.from({ length: 5 }).map((_, i) => (\n <div\n key={i}\n className=\"hub-card animate-pulse\"\n style={{ padding: '14px 16px', height: 78 }}\n />\n ))}\n </div>\n ) : (\n <div className=\"grid grid-cols-2 md:grid-cols-5 gap-3 mb-6\">\n <Stat label={t('pages.dashboard.totalServers')} value={stats.total} />\n <Stat label={t('pages.dashboard.onlineServers')} value={stats.online} tone=\"ok\" />\n <Stat label={t('pages.dashboard.connectingServers')} value={stats.connecting} tone=\"warn\" />\n <Stat label={t('pages.dashboard.offlineServers')} value={stats.offline} tone=\"err\" />\n <Stat label={t('pages.dashboard.disabledServers')} value={stats.disabled} tone=\"muted\" />\n </div>\n )}\n\n {/* Recent servers */}\n {allServers.length > 0 && !showSkeleton && (\n <div className=\"hub-card overflow-hidden mb-6\">\n <div\n className=\"flex items-center justify-between px-4 py-3\"\n style={{ borderBottom: '1px solid var(--hub-line-2)' }}\n >\n <h3 className=\"hub-card-title\">{t('pages.dashboard.recentServers')}</h3>\n <button\n className=\"hub-btn ghost sm\"\n style={{ color: 'var(--hub-ink-3)' }}\n onClick={() => navigate('/servers')}\n >\n {t('common.viewAll') || 'View all'}\n <ChevronRight size={12} />\n </button>\n </div>\n <div\n className=\"hub-row head hub-mono\"\n style={{ gridTemplateColumns: '1.3fr 110px 70px 90px 80px 80px 80px' }}\n >\n <div>{t('server.name')}</div>\n <div>{t('server.status')}</div>\n <div>{t('common.type') || 'Transport'}</div>\n <div>{t('server.tools')}</div>\n <div>{t('server.prompts')}</div>\n <div>{t('nav.resources')}</div>\n <div>{t('server.enabled')}</div>\n </div>\n {recentServers.map((s) => (\n <div\n key={s.name}\n className=\"hub-row hover cursor-pointer\"\n style={{ gridTemplateColumns: '1.3fr 110px 70px 90px 80px 80px 80px' }}\n onClick={() => navigate('/servers')}\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <span\n className=\"hub-mono truncate\"\n style={{ fontSize: 13, color: s.enabled === false ? 'var(--hub-ink-3)' : 'var(--hub-ink)' }}\n >\n {s.name}\n </span>\n {s.error && <AlertCircle size={13} className=\"text-[var(--hub-err)] flex-shrink-0\" />}\n </div>\n <div>\n <ServerStatusDot status={s.status} enabled={s.enabled} />\n </div>\n <div>\n {s.config?.type ? (\n <span className=\"hub-tag\">{transportLabel(t, s.config.type)}</span>\n ) : (\n <span style={{ color: 'var(--hub-ink-3)', fontSize: 12 }}>—</span>\n )}\n </div>\n <div className=\"hub-num hub-mono\" style={{ fontSize: 12.5 }}>\n {s.tools?.length || 0}\n </div>\n <div className=\"hub-num hub-mono\" style={{ fontSize: 12.5, color: 'var(--hub-ink-2)' }}>\n {s.prompts?.length || 0}\n </div>\n <div className=\"hub-num hub-mono\" style={{ fontSize: 12.5, color: 'var(--hub-ink-2)' }}>\n {s.resources?.length || 0}\n </div>\n <div className=\"text-[12px]\" style={{ color: s.enabled !== false ? 'var(--hub-ok)' : 'var(--hub-ink-3)' }}>\n {s.enabled !== false ? '✓' : '—'}\n </div>\n </div>\n ))}\n </div>\n )}\n\n {/* Endpoint quick-access */}\n <div className=\"hub-card mb-5\" style={{ padding: 16 }}>\n <div className=\"flex justify-between items-start gap-3 mb-3\">\n <div>\n <h3 className=\"hub-card-title\">{t('pages.dashboard.endpoints') || 'MCP Endpoints'}</h3>\n <p className=\"hub-sub\" style={{ marginTop: 2 }}>\n {t('pages.dashboard.endpointsHint') ||\n 'Use these URLs in Claude Desktop, Cursor, or any MCP client'}\n </p>\n </div>\n <a\n className=\"hub-btn ghost\"\n href=\"https://docs.mcphub.app\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: 'var(--hub-ink-3)' }}\n >\n {t('common.docs') || 'Docs'} →\n </a>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-2.5\">\n <EndpointCopy label=\"ALL\" url={`${baseUrl}/mcp`} />\n <EndpointCopy label=\"SMART\" url={`${baseUrl}/mcp/$smart`} />\n {groups.slice(0, 2).map((g) => (\n <EndpointCopy key={g.id} label=\"GROUP\" url={`${baseUrl}/mcp/${g.name}`} />\n ))}\n {/* Pad with first server endpoint if there's space */}\n {groups.length < 2 && allServers[0] && (\n <EndpointCopy label=\"SERVER\" url={`${baseUrl}/mcp/${allServers[0].name}`} />\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default DashboardPage;\n"],"names":["Stat","label","value","tone","toneColor","jsxs","jsx","transportLabel","t","type","DashboardPage","useTranslation","navigate","useNavigate","allServers","error","setError","isLoading","triggerRefresh","useServerData","groups","useGroupData","installConfig","useSettingsData","hasLoaded","setHasLoaded","React","loadingStartedRef","stats","useMemo","s","acc","_a","recentServers","baseUrl","showSkeleton","RefreshCw","Plus","AlertCircle","_","ChevronRight","ServerStatusDot","_b","_c","_d","EndpointCopy","g"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{j as s}from"./framework-vendor-BUhDPOUZ.js";import{u as i}from"./i18n-vendor-Kbr87Ofu.js";const d=({isOpen:a,onClose:r,onConfirm:c,serverName:n,isGroup:l=!1,isUser:t=!1})=>{const{t:e}=i();return a?s.jsx("div",{className:"fixed inset-0 bg-black/50 bg-opacity-30 z-50 flex items-center justify-center p-4",children:s.jsx("div",{className:"hub-card max-w-md w-full",children:s.jsxs("div",{className:"p-6",children:[s.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-3",children:e(t?"users.confirmDelete":l?"groups.confirmDelete":"server.confirmDelete")}),s.jsx("p",{className:"text-gray-500 mb-6",children:t?e("users.deleteWarning",{username:n}):l?e("groups.deleteWarning",{name:n}):e("server.deleteWarning",{name:n})}),s.jsxs("div",{className:"flex justify-end space-x-3",children:[s.jsx("button",{onClick:r,className:"hub-btn",children:e("common.cancel")}),s.jsx("button",{onClick:c,className:"hub-btn danger",children:e("common.delete")})]})]})})}):null};export{d as D};
2
+ //# sourceMappingURL=DeleteDialog-DRbWonMu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeleteDialog-DRbWonMu.js","sources":["../../src/components/ui/DeleteDialog.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next'\n\ninterface DeleteDialogProps {\n isOpen: boolean\n onClose: () => void\n onConfirm: () => void\n serverName: string\n isGroup?: boolean\n isUser?: boolean\n}\n\nconst DeleteDialog = ({ isOpen, onClose, onConfirm, serverName, isGroup = false, isUser = false }: DeleteDialogProps) => {\n const { t } = useTranslation()\n\n if (!isOpen) return null\n\n return (\n <div className=\"fixed inset-0 bg-black/50 bg-opacity-30 z-50 flex items-center justify-center p-4\">\n <div className=\"hub-card max-w-md w-full\">\n <div className=\"p-6\">\n <h3 className=\"text-lg font-medium text-gray-900 mb-3\">\n {isUser\n ? t('users.confirmDelete')\n : isGroup\n ? t('groups.confirmDelete')\n : t('server.confirmDelete')}\n </h3>\n <p className=\"text-gray-500 mb-6\">\n {isUser\n ? t('users.deleteWarning', { username: serverName })\n : isGroup\n ? t('groups.deleteWarning', { name: serverName })\n : t('server.deleteWarning', { name: serverName })}\n </p>\n <div className=\"flex justify-end space-x-3\">\n <button\n onClick={onClose}\n className=\"hub-btn\"\n >\n {t('common.cancel')}\n </button>\n <button\n onClick={onConfirm}\n className=\"hub-btn danger\"\n >\n {t('common.delete')}\n </button>\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nexport default DeleteDialog"],"names":["DeleteDialog","isOpen","onClose","onConfirm","serverName","isGroup","isUser","t","useTranslation","jsx","jsxs"],"mappings":"iGAWA,MAAMA,EAAe,CAAC,CAAE,OAAAC,EAAQ,QAAAC,EAAS,UAAAC,EAAW,WAAAC,EAAY,QAAAC,EAAU,GAAO,OAAAC,EAAS,MAA+B,CACvH,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAA,EAEd,OAAKP,EAGHQ,EAAAA,IAAC,MAAA,CAAI,UAAU,oFACb,SAAAA,EAAAA,IAAC,MAAA,CAAI,UAAU,2BACb,SAAAC,EAAAA,KAAC,MAAA,CAAI,UAAU,MACb,SAAA,CAAAD,EAAAA,IAAC,KAAA,CAAG,UAAU,yCACX,SACGF,EADHD,EACK,sBACFD,EACI,uBACA,sBAHmB,EAI7B,EACAI,EAAAA,IAAC,IAAA,CAAE,UAAU,qBACV,SAAAH,EACGC,EAAE,sBAAuB,CAAE,SAAUH,CAAA,CAAY,EACjDC,EACEE,EAAE,uBAAwB,CAAE,KAAMH,CAAA,CAAY,EAC9CG,EAAE,uBAAwB,CAAE,KAAMH,CAAA,CAAY,CAAA,CACtD,EACAM,EAAAA,KAAC,MAAA,CAAI,UAAU,6BACb,SAAA,CAAAD,EAAAA,IAAC,SAAA,CACC,QAASP,EACT,UAAU,UAET,WAAE,eAAe,CAAA,CAAA,EAEpBO,EAAAA,IAAC,SAAA,CACC,QAASN,EACT,UAAU,iBAET,WAAE,eAAe,CAAA,CAAA,CACpB,CAAA,CACF,CAAA,CAAA,CACF,EACF,EACF,EApCkB,IAsCtB"}
@@ -0,0 +1,2 @@
1
+ import{r as y,j as t}from"./framework-vendor-BUhDPOUZ.js";import{i as x,m as r}from"./index-B9cW2F0H.js";import{u as h}from"./i18n-vendor-Kbr87Ofu.js";import{C,o as b}from"./icons-vendor-CKgJB3SC.js";const f=async e=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(e),!0}catch{}try{const o=document.createElement("textarea");o.value=e,o.style.position="fixed",o.style.left="-9999px",document.body.appendChild(o),o.focus(),o.select();const s=document.execCommand("copy");return document.body.removeChild(o),s}catch{return!1}},E=({url:e,label:o,prefix:s,className:p,copyValue:d,ariaLabel:l})=>{const{t:c}=h(),{showToast:n}=x(),[a,i]=y.useState(!1),m=async u=>{if(u.stopPropagation(),!await f(d??e)){n(c("common.copyFailed")||"Copy failed","error");return}i(!0),n(c("common.copySuccess")||"Copied to clipboard","success"),setTimeout(()=>i(!1),1200)};return t.jsxs("div",{className:r("hub-endpoint",p),role:"group","aria-label":l||e,children:[o&&t.jsx("div",{className:"hub-endpoint-label",children:o}),t.jsxs("div",{className:"hub-endpoint-url",title:e,children:[s&&t.jsx("span",{style:{color:"var(--hub-ink-3)"},children:s}),e]}),t.jsx("button",{type:"button",onClick:m,className:r("hub-endpoint-copy",a?"copied":""),title:c("common.copy")||"Copy","aria-label":c("common.copy")||"Copy",children:a?t.jsx(C,{size:13}):t.jsx(b,{size:13})})]})};export{E};
2
+ //# sourceMappingURL=EndpointCopy-C59moJ3Y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EndpointCopy-C59moJ3Y.js","sources":["../../src/components/ui/EndpointCopy.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Copy, Check } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useToast } from '@/contexts/ToastContext';\nimport { cn } from '@/utils/cn';\n\nconst copyText = async (value: string): Promise<boolean> => {\n try {\n if (navigator.clipboard && window.isSecureContext) {\n await navigator.clipboard.writeText(value);\n return true;\n }\n } catch {\n // fall through to fallback\n }\n try {\n const el = document.createElement('textarea');\n el.value = value;\n el.style.position = 'fixed';\n el.style.left = '-9999px';\n document.body.appendChild(el);\n el.focus();\n el.select();\n const ok = document.execCommand('copy');\n document.body.removeChild(el);\n return ok;\n } catch {\n return false;\n }\n};\n\ninterface EndpointCopyProps {\n url: string;\n label?: string;\n prefix?: string;\n className?: string;\n /** Optionally override the value placed on the clipboard. */\n copyValue?: string;\n ariaLabel?: string;\n}\n\nexport const EndpointCopy: React.FC<EndpointCopyProps> = ({\n url,\n label,\n prefix,\n className,\n copyValue,\n ariaLabel,\n}) => {\n const { t } = useTranslation();\n const { showToast } = useToast();\n const [copied, setCopied] = useState(false);\n\n const onCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n const ok = await copyText(copyValue ?? url);\n if (!ok) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n return;\n }\n setCopied(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopied(false), 1200);\n };\n\n return (\n <div className={cn('hub-endpoint', className)} role=\"group\" aria-label={ariaLabel || url}>\n {label && <div className=\"hub-endpoint-label\">{label}</div>}\n <div className=\"hub-endpoint-url\" title={url}>\n {prefix && <span style={{ color: 'var(--hub-ink-3)' }}>{prefix}</span>}\n {url}\n </div>\n <button\n type=\"button\"\n onClick={onCopy}\n className={cn('hub-endpoint-copy', copied ? 'copied' : '')}\n title={t('common.copy') || 'Copy'}\n aria-label={t('common.copy') || 'Copy'}\n >\n {copied ? <Check size={13} /> : <Copy size={13} />}\n </button>\n </div>\n );\n};\n\ninterface MonoCopyProps {\n text: string;\n className?: string;\n copyValue?: string;\n title?: string;\n}\n\n/** Inline monospace value with hover-to-copy icon. */\nexport const MonoCopy: React.FC<MonoCopyProps> = ({ text, className, copyValue, title }) => {\n const { t } = useTranslation();\n const { showToast } = useToast();\n const [copied, setCopied] = useState(false);\n\n const onCopy = async (e: React.MouseEvent) => {\n e.stopPropagation();\n const ok = await copyText(copyValue ?? text);\n if (!ok) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n return;\n }\n setCopied(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopied(false), 1200);\n };\n\n return (\n <span\n className={cn(\n 'hub-mono inline-flex items-center gap-1.5 group cursor-pointer text-[12.5px]',\n className,\n )}\n onClick={onCopy}\n title={title || text}\n role=\"button\"\n >\n <span className=\"truncate\">{text}</span>\n {copied ? (\n <Check size={12} className=\"text-[var(--hub-ok)] flex-shrink-0\" />\n ) : (\n <Copy\n size={12}\n className=\"text-[var(--hub-ink-3)] opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\"\n />\n )}\n </span>\n );\n};\n"],"names":["copyText","value","el","ok","EndpointCopy","url","label","prefix","className","copyValue","ariaLabel","t","useTranslation","showToast","useToast","copied","setCopied","useState","onCopy","e","jsxs","cn","jsx","Check","Copy"],"mappings":"wMAMA,MAAMA,EAAW,MAAOC,GAAoC,CAC1D,GAAI,CACF,GAAI,UAAU,WAAa,OAAO,gBAChC,aAAM,UAAU,UAAU,UAAUA,CAAK,EAClC,EAEX,MAAQ,CAER,CACA,GAAI,CACF,MAAMC,EAAK,SAAS,cAAc,UAAU,EAC5CA,EAAG,MAAQD,EACXC,EAAG,MAAM,SAAW,QACpBA,EAAG,MAAM,KAAO,UAChB,SAAS,KAAK,YAAYA,CAAE,EAC5BA,EAAG,MAAA,EACHA,EAAG,OAAA,EACH,MAAMC,EAAK,SAAS,YAAY,MAAM,EACtC,gBAAS,KAAK,YAAYD,CAAE,EACrBC,CACT,MAAQ,CACN,MAAO,EACT,CACF,EAYaC,EAA4C,CAAC,CACxD,IAAAC,EACA,MAAAC,EACA,OAAAC,EACA,UAAAC,EACA,UAAAC,EACA,UAAAC,CACF,IAAM,CACJ,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAA,EACR,CAAE,UAAAC,CAAA,EAAcC,EAAA,EAChB,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAS,EAAK,EAEpCC,EAAS,MAAOC,GAAwB,CAG5C,GAFAA,EAAE,gBAAA,EAEE,CADO,MAAMnB,EAASS,GAAaJ,CAAG,EACjC,CACPQ,EAAUF,EAAE,mBAAmB,GAAK,cAAe,OAAO,EAC1D,MACF,CACAK,EAAU,EAAI,EACdH,EAAUF,EAAE,oBAAoB,GAAK,sBAAuB,SAAS,EACrE,WAAW,IAAMK,EAAU,EAAK,EAAG,IAAI,CACzC,EAEA,OACEI,EAAAA,KAAC,MAAA,CAAI,UAAWC,EAAG,eAAgBb,CAAS,EAAG,KAAK,QAAQ,aAAYE,GAAaL,EAClF,SAAA,CAAAC,GAASgB,EAAAA,IAAC,MAAA,CAAI,UAAU,qBAAsB,SAAAhB,EAAM,EACrDc,EAAAA,KAAC,MAAA,CAAI,UAAU,mBAAmB,MAAOf,EACtC,SAAA,CAAAE,SAAW,OAAA,CAAK,MAAO,CAAE,MAAO,kBAAA,EAAuB,SAAAA,EAAO,EAC9DF,CAAA,EACH,EACAiB,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,QAASJ,EACT,UAAWG,EAAG,oBAAqBN,EAAS,SAAW,EAAE,EACzD,MAAOJ,EAAE,aAAa,GAAK,OAC3B,aAAYA,EAAE,aAAa,GAAK,OAE/B,SAAAI,QAAUQ,EAAA,CAAM,KAAM,GAAI,EAAKD,EAAAA,IAACE,EAAA,CAAK,KAAM,EAAA,CAAI,CAAA,CAAA,CAClD,EACF,CAEJ"}
@@ -0,0 +1,33 @@
1
+ import{r as b,R as W,j as e}from"./framework-vendor-BUhDPOUZ.js";import{m as U,d as q,i as Q,e as M}from"./index-B9cW2F0H.js";import{u as J}from"./useServerData-BnLmpLAC.js";import{u as X}from"./useSettingsData-Cqi9d7Ug.js";import{u as P}from"./i18n-vendor-Kbr87Ofu.js";import{W as ee,f as se,F as te,C as re,o as B,x as ae,u as le,t as ne,T as oe,s as ie,v as V,D as ce,P as _,j as de,X as me}from"./icons-vendor-CKgJB3SC.js";import{D as ue}from"./DeleteDialog-DRbWonMu.js";const pe={tools:[],prompts:[],resources:[]},H={tools:"all",prompts:"all",resources:"all"},Y=({servers:i,value:m,onChange:t,className:d})=>{const{t:u}=P(),{nameSeparator:A}=X(),[g,k]=b.useState(new Set),x=W.useMemo(()=>m.map(s=>typeof s=="string"?{name:s,...H}:{...s,tools:s.tools||"all",prompts:s.prompts||"all",resources:s.resources||"all"}),[m]),p=W.useMemo(()=>i.filter(s=>s.enabled!==!1),[i]);W.useEffect(()=>{const s=new Set(x.map(r=>r.name)),l=new Set(p.map(r=>r.name));k(r=>{const S=new Set;return r.forEach(N=>{(s.has(N)||l.has(N))&&S.add(N)}),S})},[x,p]);const v=s=>{if(x.findIndex(r=>r.name===s)>=0){const r=x.filter(S=>S.name!==s);t(r)}else{const r=[...x,{name:s,...H}];t(r)}},y=s=>{k(l=>{const r=new Set(l);return r.has(s)?r.delete(s):r.add(s),r})},w=s=>["tools","prompts","resources"].some(l=>{const r=s[l];return r==="all"||Array.isArray(r)&&r.length>0}),C=(s,l,r,S=!1)=>{const N=x.find(h=>h.name===s),z={...N?{...N}:{name:s,...pe},[l]:r};if(!w(z)){const h=x.filter(F=>F.name!==s);t(h),S||k(F=>{const I=new Set(F);return I.delete(s),I});return}if(N){t(x.map(h=>h.name===s?z:h));return}t([...x,z])},E=(s,l)=>{const r=`${s}${A}`;return l.startsWith(r)?l.slice(r.length):l},o=(s,l)=>l==="tools"?(s.tools||[]).filter(r=>r.enabled!==!1).map(r=>({key:r.name,value:E(s.name,r.name),description:r.description})):l==="prompts"?(s.prompts||[]).filter(r=>r.enabled!==!1).map(r=>({key:r.name,value:E(s.name,r.name),description:r.description})):(s.resources||[]).filter(r=>r.enabled!==!1).map(r=>({key:r.uri,value:r.uri,description:r.description})),c=(s,l,r)=>{const S=p.find(h=>h.name===s);if(!S)return;const N=o(S,l).map(h=>h.value),D=x.find(h=>h.name===s);if(!D){C(s,l,[r]);return}const z=D[l];if(z==="all"){const h=N.filter(F=>F!==r);C(s,l,h);return}if(Array.isArray(z)){if(z.includes(r)){C(s,l,z.filter(F=>F!==r));return}const h=[...z,r];C(s,l,h.length===N.length?"all":h);return}C(s,l,[r])},f=s=>{const l=x.find(r=>r.name===s);return!!(l&&w(l))},a=s=>{const l=x.find(r=>r.name===s);return l?["tools","prompts","resources"].some(r=>{const S=l[r];return Array.isArray(S)&&S.length>0}):!1},n=(s,l,r)=>{const S=x.find(D=>D.name===s);if(!S)return!1;const N=S[l];return N==="all"?!0:Array.isArray(N)?N.includes(r):!1},j=(s,l)=>{const r=x.find(D=>D.name===s.name);if(!r)return 0;const S=o(s,l),N=r[l];if(N==="all")return S.length;if(Array.isArray(N)){const D=new Set(S.map(z=>z.value));return N.filter(z=>D.has(z)).length}return 0},T=[{key:"tools",titleKey:"groups.toolSelection",countKey:"groups.toolsSelected",allKey:"groups.allTools"},{key:"prompts",titleKey:"groups.promptSelection",countKey:"groups.promptsSelected",allKey:"groups.allPrompts"},{key:"resources",titleKey:"groups.resourceSelection",countKey:"groups.resourcesSelected",allKey:"groups.allResources"}],R=s=>T.map(({key:l})=>({key:l,count:j(s,l)})).filter(l=>l.count>0);return e.jsxs("div",{className:U("space-y-4",d),children:[e.jsx("div",{className:"space-y-3",children:p.map(s=>{const l=f(s.name),r=a(s.name),S=g.has(s.name),N=x.find(h=>h.name===s.name),D=R(s),z=T.filter(({key:h})=>o(s,h).length>0);return e.jsxs("div",{className:"border border-gray-200 dark:border-gray-700 rounded-lg hover:border-gray-300 hover:bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700 transition-colors",children:[e.jsxs("div",{className:"flex items-center justify-between p-3 cursor-pointer rounded-lg transition-colors",onClick:()=>y(s.name),children:[e.jsxs("div",{className:"flex items-center space-x-3",onClick:h=>{h.stopPropagation(),v(s.name)},children:[e.jsx("input",{type:"checkbox",checked:l||r,onChange:()=>v(s.name),className:"w-4 h-4 text-blue-600 bg-gray-100 dark:bg-gray-800 border-gray-300 rounded focus:ring-blue-500"}),e.jsx("span",{className:"font-medium text-gray-900 cursor-pointer select-none",children:s.name})]}),e.jsxs("div",{className:"flex items-center space-x-3",children:[D.map(({key:h,count:F})=>e.jsxs("span",{className:"text-sm text-green-600 flex items-center gap-1",children:[h==="tools"?e.jsx(ee,{size:14}):h==="prompts"?e.jsx(se,{size:14}):e.jsx(te,{size:14})," ",F]},h)),z.length>0&&e.jsx("button",{type:"button",className:"p-1 text-gray-400 hover:text-gray-600 transition-colors",children:e.jsx("svg",{className:U("w-5 h-5 transition-transform",S&&"rotate-180"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})})]})]}),S&&z.length>0&&e.jsx("div",{className:"border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800 p-3",children:e.jsx("div",{className:"space-y-4",children:z.map(({key:h,titleKey:F,countKey:I,allKey:L})=>{const $=o(s,h),K=j(s,h),O=(N==null?void 0:N[h])==="all"||K===$.length;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("span",{className:"text-sm font-medium text-gray-700",children:u(F)}),e.jsxs("div",{className:"flex items-center gap-3",children:[N&&e.jsx("span",{className:"text-xs text-green-600",children:O?`(${u(L)} ${$.length}/${$.length})`:`(${u(I)} ${K}/${$.length})`}),e.jsx("button",{type:"button",onClick:()=>{C(s.name,h,O?[]:"all",!0)},className:"text-sm text-blue-600 hover:text-blue-800 transition-colors",children:u(O?"groups.selectNone":"groups.selectAll")})]})]}),e.jsx("div",{className:"grid grid-cols-1 gap-2 max-h-32 overflow-y-auto",children:$.map(G=>{const Z=n(s.name,h,G.value);return e.jsxs("label",{className:"flex items-center space-x-2 text-sm",children:[e.jsx("input",{type:"checkbox",checked:Z,onChange:()=>c(s.name,h,G.value),className:"w-3 h-3 text-blue-600 bg-gray-100 dark:bg-gray-800 border-gray-300 rounded focus:ring-blue-500"}),e.jsx("span",{className:"text-gray-700 break-all whitespace-nowrap",children:G.value}),G.description&&e.jsx("span",{className:"text-gray-400 text-xs truncate",children:G.description})]},G.key)})})]},h)})})})]},s.name)})}),p.length===0&&e.jsx("p",{className:"text-gray-500 text-sm",children:u("groups.noServerOptions")})]})},xe=({onAdd:i,onCancel:m})=>{const{t}=P(),{createGroup:d}=q(),{allServers:u}=J(),[A,g]=b.useState([]),[k,x]=b.useState(null),[p,v]=b.useState(!1),[y,w]=b.useState({name:"",description:"",servers:[]});b.useEffect(()=>{g(u.filter(o=>o.enabled!==!1))},[u]);const C=o=>{const{name:c,value:f}=o.target;w(a=>({...a,[c]:f}))},E=async o=>{o.preventDefault(),v(!0),x(null);try{if(!y.name.trim()){x(t("groups.nameRequired")),v(!1);return}const c=await d(y.name,y.description,y.servers);if(!c||!c.success){x((c==null?void 0:c.message)||t("groups.createError")),v(!1);return}i()}catch(c){x(c instanceof Error?c.message:String(c)),v(!1)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg max-w-3xl w-full max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"p-6 flex-shrink-0",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-800 mb-4",children:t("groups.addNew")}),k&&e.jsx("div",{className:"mb-4 p-3 bg-red-100 text-red-700 rounded-md border border-gray-200 dark:border-gray-700",children:k})]}),e.jsxs("form",{onSubmit:E,className:"flex flex-col flex-1 min-h-0",children:[e.jsx("div",{className:"flex-1 overflow-y-auto px-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("label",{className:"block text-gray-700 text-sm font-bold mb-2",htmlFor:"name",children:[t("groups.name")," *"]}),e.jsx("input",{type:"text",id:"name",name:"name",value:y.name,onChange:C,className:"w-full border border-gray-300 rounded-md px-3 py-2 text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",placeholder:t("groups.namePlaceholder"),required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-gray-700 text-sm font-bold mb-2",children:t("groups.configureCapabilities")}),e.jsx(Y,{servers:A,value:y.servers,onChange:o=>w(c=>({...c,servers:o})),className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4 bg-gray-50 dark:bg-gray-800"})]})]})}),e.jsxs("div",{className:"flex justify-end space-x-2 p-5 pt-3 border-t border-[var(--hub-line-2)] flex-shrink-0",children:[e.jsx("button",{type:"button",onClick:m,className:"hub-btn",disabled:p,children:t("common.cancel")}),e.jsx("button",{type:"submit",className:"hub-btn primary",disabled:p,children:t(p?"common.submitting":"common.create")})]})]})]})})},he=({group:i,onEdit:m,onCancel:t})=>{const{t:d}=P(),{updateGroup:u}=q(),{allServers:A}=J(),[g,k]=b.useState([]),[x,p]=b.useState(null),[v,y]=b.useState(!1),[w,C]=b.useState({name:i.name,description:i.description||"",servers:i.servers||[]});b.useEffect(()=>{k(A.filter(c=>c.enabled!==!1))},[A]);const E=c=>{const{name:f,value:a}=c.target;C(n=>({...n,[f]:a}))},o=async c=>{c.preventDefault(),y(!0),p(null);try{if(!w.name.trim()){p(d("groups.nameRequired")),y(!1);return}const f=await u(i.id,{name:w.name,description:w.description,servers:w.servers});if(!f||!f.success){p((f==null?void 0:f.message)||d("groups.updateError")),y(!1);return}m()}catch(f){p(f instanceof Error?f.message:String(f)),y(!1)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 rounded-lg shadow-lg max-w-3xl w-full max-h-[90vh] flex flex-col",children:[e.jsxs("div",{className:"p-6 flex-shrink-0",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-800 mb-4",children:d("groups.edit")}),x&&e.jsx("div",{className:"mb-4 p-3 bg-red-100 text-red-700 rounded-md border border-gray-200 dark:border-gray-700",children:x})]}),e.jsxs("form",{onSubmit:o,className:"flex flex-col flex-1 min-h-0",children:[e.jsx("div",{className:"flex-1 overflow-y-auto px-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("label",{className:"block text-gray-700 text-sm font-bold mb-2",htmlFor:"name",children:[d("groups.name")," *"]}),e.jsx("input",{type:"text",id:"name",name:"name",value:w.name,onChange:E,className:"w-full border border-gray-300 rounded-md px-3 py-2 text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",placeholder:d("groups.namePlaceholder"),required:!0})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-gray-700 text-sm font-bold mb-2",children:d("groups.configureCapabilities")}),e.jsx(Y,{servers:g,value:w.servers,onChange:c=>C(f=>({...f,servers:c})),className:"border border-gray-200 dark:border-gray-700 rounded-lg p-4 bg-gray-50 dark:bg-gray-800"})]})]})}),e.jsxs("div",{className:"flex justify-end space-x-2 p-5 pt-3 border-t border-[var(--hub-line-2)] flex-shrink-0",children:[e.jsx("button",{type:"button",onClick:t,className:"hub-btn",disabled:v,children:d("common.cancel")}),e.jsx("button",{type:"submit",className:"hub-btn primary",disabled:v,children:d(v?"common.submitting":"common.save")})]})]})]})})},be=i=>i.map(m=>typeof m=="string"?m:m.name),ge=(i,m)=>{const t=i.servers.find(d=>typeof d=="string"?d===m:d.name===m);return t?typeof t=="string"?{name:t,tools:"all",prompts:"all",resources:"all"}:t:{name:m,tools:"all",prompts:"all",resources:"all"}},fe=async i=>{try{if(navigator.clipboard&&window.isSecureContext)return await navigator.clipboard.writeText(i),!0}catch{}try{const m=document.createElement("textarea");m.value=i,m.style.position="fixed",m.style.left="-9999px",document.body.appendChild(m),m.focus(),m.select();const t=document.execCommand("copy");return document.body.removeChild(m),t}catch{return!1}},ye=({group:i,servers:m,onEdit:t,onDelete:d})=>{var R;const{t:u}=P(),{showToast:A}=Q(),{installConfig:g,nameSeparator:k}=X(),x=((R=g==null?void 0:g.baseUrl)==null?void 0:R.replace(/\/+$/,""))||"",[p,v]=b.useState(!1),[y,w]=b.useState(!1),[C,E]=b.useState(!1),o=b.useRef(null);b.useEffect(()=>{const s=l=>{o.current&&!o.current.contains(l.target)&&E(!1)};return document.addEventListener("mousedown",s),()=>document.removeEventListener("mousedown",s)},[]);const c=async s=>{await fe(s)?(w(!0),E(!1),A(u("common.copySuccess")||"Copied","success"),setTimeout(()=>w(!1),1500)):A(u("common.copyFailed")||"Copy failed","error")},f=`${x}/mcp/${i.name}`,a=be(i.servers),n=m.filter(s=>a.includes(s.name)),j=s=>{const l=ge(i,s.name),r=`${s.name}${k}`,S=s.tools||[],N=s.prompts||[],D=s.resources||[],z=Array.isArray(l.tools)?S.filter(I=>{if(I.enabled===!1)return!1;const L=I.name.startsWith(r)?I.name.slice(r.length):I.name;return l.tools.includes(L)}).length:S.filter(I=>I.enabled!==!1).length,h=Array.isArray(l.prompts)?N.filter(I=>{if(I.enabled===!1)return!1;const L=I.name.startsWith(r)?I.name.slice(r.length):I.name;return l.prompts.includes(L)}).length:N.filter(I=>I.enabled!==!1).length,F=Array.isArray(l.resources)?D.filter(I=>I.enabled!==!1&&l.resources.includes(I.uri)).length:D.filter(I=>I.enabled!==!1).length;return{visibleTools:z,totalTools:S.length,visiblePrompts:h,totalPrompts:N.length,visibleResources:F,totalResources:D.length}},T=n.reduce((s,l)=>s+j(l).visibleTools,0);return e.jsxs("div",{className:"hub-card overflow-visible",children:[e.jsxs("div",{className:"flex items-start gap-3 px-4 py-3",style:{borderBottom:"1px solid var(--hub-line-2)"},children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{style:{fontSize:15,fontWeight:600,letterSpacing:"-0.015em"},children:i.name}),e.jsx("span",{className:"hub-mono",style:{fontSize:11,color:"var(--hub-ink-3)",padding:"0 6px",border:"1px solid var(--hub-line)",borderRadius:4,height:18,display:"inline-flex",alignItems:"center"},title:i.id,children:i.id})]}),i.description&&e.jsx("div",{style:{fontSize:12.5,color:"var(--hub-ink-3)",marginTop:2},children:i.description})]}),e.jsxs("div",{className:"flex items-center gap-1",ref:o,children:[e.jsxs("div",{className:"relative",children:[e.jsx("button",{onClick:()=>E(s=>!s),className:"hub-icon-btn sm",title:u("common.copy"),children:y?e.jsx(re,{size:13,className:"text-[var(--hub-ok)]"}):e.jsx(B,{size:13})}),C&&e.jsxs("div",{className:"absolute top-full right-0 mt-1 z-20 hub-card",style:{minWidth:160,padding:4},children:[e.jsxs("button",{onClick:()=>c(i.id),className:"flex items-center gap-2 w-full px-2.5 py-1.5 text-[13px] rounded-md hover:bg-[var(--hub-surface-hover)] text-left",children:[e.jsx(B,{size:12})," ",u("common.copyId")]}),e.jsxs("button",{onClick:()=>c(f),className:"flex items-center gap-2 w-full px-2.5 py-1.5 text-[13px] rounded-md hover:bg-[var(--hub-surface-hover)] text-left",children:[e.jsx(ae,{size:12})," ",u("common.copyUrl")]}),e.jsxs("button",{onClick:()=>c(JSON.stringify({mcpServers:{mcphub:{url:f,headers:{Authorization:"Bearer <your-access-token>"}}}},null,2)),className:"flex items-center gap-2 w-full px-2.5 py-1.5 text-[13px] rounded-md hover:bg-[var(--hub-surface-hover)] text-left",children:[e.jsx(le,{size:12})," ",u("common.copyJson")]})]})]}),e.jsx("button",{onClick:()=>t(i),className:"hub-icon-btn sm",title:u("groups.edit"),children:e.jsx(ne,{size:13})}),e.jsx("button",{onClick:()=>v(!0),className:"hub-icon-btn sm",title:u("groups.delete"),style:{color:"var(--hub-ink-3)"},children:e.jsx(oe,{size:13})})]})]}),e.jsxs("div",{className:"grid items-center gap-3 px-4 py-3",style:{gridTemplateColumns:"1fr 80px 1fr"},children:[e.jsx("div",{className:"flex flex-col gap-1.5",children:n.length===0?e.jsx("div",{style:{fontSize:12,color:"var(--hub-ink-3)"},children:u("groups.noServers")}):n.map(s=>{const l=j(s);return e.jsxs("div",{className:"flex items-center gap-2.5 px-2.5 py-1.5 rounded-md",style:{background:"var(--hub-bg-2)",border:"1px solid var(--hub-line-2)"},children:[e.jsx("span",{className:"inline-block flex-shrink-0",style:{width:6,height:6,borderRadius:50,background:s.status==="connected"?"var(--hub-ok)":s.status==="connecting"?"var(--hub-warn)":"var(--hub-err)"}}),e.jsx("span",{className:"hub-mono truncate flex-1",style:{fontSize:12.5},children:s.name}),e.jsxs("span",{className:"hub-mono hub-num flex-shrink-0",style:{fontSize:11,color:"var(--hub-ink-3)"},children:[l.visibleTools,"/",l.totalTools," tools"]})]},s.name)})}),e.jsxs("svg",{width:"80",height:"80",viewBox:"0 0 80 80",className:"self-center",children:[n.length===0?e.jsx("path",{d:"M0,40 C30,40 50,40 80,40",stroke:"var(--hub-line)",strokeWidth:"1",fill:"none",strokeDasharray:"3 3"}):n.map((s,l)=>{const r=12+60/Math.max(n.length,1)*(l+.5);return e.jsx("path",{d:`M0,${r} C 30,${r} 50,40 80,40`,stroke:"var(--hub-line)",strokeWidth:"1",fill:"none",strokeDasharray:"3 3"},l)}),e.jsx("circle",{cx:"80",cy:"40",r:"4",fill:"var(--hub-ink)"})]}),e.jsxs("div",{className:"px-3 py-2.5 rounded-md",style:{border:"1px solid var(--hub-line)",background:"var(--hub-bg-2)"},children:[e.jsx("div",{className:"hub-sect",style:{marginBottom:4},children:"endpoint"}),e.jsxs("div",{className:"hub-mono break-all",style:{fontSize:12,color:"var(--hub-ink-2)",lineHeight:1.4},children:[e.jsx("span",{style:{color:"var(--hub-ink-3)"},children:"/mcp/"}),e.jsx("b",{style:{color:"var(--hub-ink)",fontWeight:600},children:i.name})]}),e.jsx("div",{className:"flex gap-1.5 mt-2",children:e.jsxs("button",{className:"hub-btn sm flex-1 justify-center",onClick:()=>c(f),children:[e.jsx(B,{size:11})," ",u("common.copy")]})})]})]}),e.jsxs("div",{className:"flex justify-between items-center px-4 py-2",style:{borderTop:"1px solid var(--hub-line-2)",background:"var(--hub-bg-2)",fontSize:12,color:"var(--hub-ink-3)"},children:[e.jsxs("div",{className:"hub-mono",children:[e.jsx("span",{style:{color:"var(--hub-ink-2)"},children:n.length})," ",u("nav.servers").toLowerCase()," ·"," ",e.jsx("span",{style:{color:"var(--hub-ink-2)"},children:T})," ",u("server.tools").toLowerCase()]}),e.jsxs("button",{className:"hub-btn ghost sm",style:{color:"var(--hub-ink-3)"},onClick:()=>t(i),children:[u("groups.configureTools")||u("groups.edit"),e.jsx(ie,{size:11,style:{transform:"rotate(-90deg)"}})]})]}),e.jsx(ue,{isOpen:p,onClose:()=>v(!1),onConfirm:()=>{d(i.id),v(!1)},serverName:i.name,isGroup:!0})]})},je=({onSuccess:i,onCancel:m})=>{const{t}=P(),[d,u]=b.useState(""),[A,g]=b.useState(null),[k,x]=b.useState(!1),[p,v]=b.useState(null),y=`{
2
+ "groups": [
3
+ {
4
+ "name": "AI Assistants",
5
+ "servers": ["openai-server", "anthropic-server"]
6
+ },
7
+ {
8
+ "name": "Development Tools",
9
+ "servers": [
10
+ {
11
+ "name": "github-server",
12
+ "tools": ["create_issue", "list_repos"],
13
+ "prompts": ["triage_prompt"],
14
+ "resources": ["resource://docs/repo-guide"]
15
+ },
16
+ {
17
+ "name": "gitlab-server",
18
+ "tools": "all",
19
+ "prompts": "all",
20
+ "resources": "all"
21
+ }
22
+ ]
23
+ }
24
+ ]
25
+ }
26
+
27
+ Supports:
28
+ - Simple server list: ["server1", "server2"]
29
+ - Advanced server config: [{"name": "server1", "tools": ["tool1"], "prompts": ["prompt1"], "resources": ["resource://docs/guide"]}]
30
+ - All groups will be imported in a single efficient batch operation.`,w=a=>{try{const n=JSON.parse(a.trim());if(!n.groups||!Array.isArray(n.groups))return g(t("groupImport.invalidFormat")),null;for(const j of n.groups)if(!j.name||typeof j.name!="string")return g(t("groupImport.missingName")),null;return n}catch{return g(t("groupImport.parseError")),null}},C=()=>{g(null);const a=w(d);a&&v(a.groups)},E=async()=>{if(p){x(!0),g(null);try{const a=await M("/groups/batch",{groups:p});if(a.success){const{successCount:n,failureCount:j,results:T}=a;if(j>0){const R=T.filter(s=>!s.success).map(s=>`${s.name}: ${s.message||t("groupImport.addFailed")}`);g(t("groupImport.partialSuccess",{count:n,total:p.length})+`
31
+ `+R.join(`
32
+ `))}n>0&&i()}else g(a.message||t("groupImport.importFailed"))}catch(a){console.error("Import error:",a),g(t("groupImport.importFailed"))}finally{x(!1)}}},o=a=>e.jsx("span",{className:"text-gray-500 ml-2",children:t(`groups.${a}`)}),c=(a,n)=>{if(!n||n==="all")return null;const j=Array.isArray(n)?n.join(", "):n;return e.jsx("span",{className:"text-gray-500 ml-2",children:t(`groups.${a}`,{items:j})})},f=a=>!a||a.length===0?e.jsx("span",{className:"text-gray-500",children:t("groups.noServers")}):e.jsx("div",{className:"space-y-1",children:a.map((n,j)=>typeof n=="string"?e.jsxs("div",{className:"text-sm",children:["• ",n]},j):e.jsxs("div",{className:"text-sm",children:["• ",n.name,n.tools&&n.tools!=="all"&&e.jsxs("span",{className:"text-gray-500 ml-2",children:["(",Array.isArray(n.tools)?n.tools.join(", "):n.tools,")"]}),n.tools==="all"&&o("previewAllTools"),c("previewPrompts",n.prompts),n.prompts==="all"&&o("previewAllPrompts"),c("previewResources",n.resources),n.resources==="all"&&o("previewAllResources")]},j))});return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6 w-full max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsxs("div",{className:"flex justify-between items-center mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:t("groupImport.title")}),e.jsx("button",{onClick:m,className:"text-gray-500 hover:text-gray-700",children:"✕"})]}),A&&e.jsx("div",{className:"mb-4 bg-red-50 border-l-4 border-red-500 p-4 rounded",children:e.jsx("p",{className:"text-red-700 whitespace-pre-wrap",children:A})}),p?e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("h3",{className:"text-lg font-medium text-gray-900 mb-3",children:t("groupImport.previewTitle")}),e.jsx("div",{className:"space-y-3",children:p.map((a,n)=>e.jsx("div",{className:"bg-gray-50 dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700",children:e.jsx("div",{className:"flex items-start justify-between",children:e.jsxs("div",{className:"flex-1",children:[e.jsx("h4",{className:"font-medium text-gray-900",children:a.name}),a.description&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:a.description}),e.jsxs("div",{className:"mt-2 text-sm text-gray-600",children:[e.jsxs("strong",{children:[t("groups.servers"),":"]}),e.jsx("div",{className:"mt-1",children:f(a.servers)})]})]})})},n))})]}),e.jsxs("div",{className:"flex justify-end space-x-4",children:[e.jsx("button",{onClick:()=>v(null),disabled:k,className:"hub-btn",children:t("common.back")}),e.jsx("button",{onClick:E,disabled:k,className:"hub-btn primary",children:k?e.jsxs(e.Fragment,{children:[e.jsxs("svg",{className:"animate-spin h-4 w-4 mr-2",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",children:[e.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),e.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"})]}),t("groupImport.importing")]}):t("groupImport.import")})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:t("groupImport.inputLabel")}),e.jsx("textarea",{value:d,onChange:a=>u(a.target.value),className:"w-full h-96 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm",placeholder:y}),e.jsx("p",{className:"text-xs text-gray-500 mt-2",children:t("groupImport.inputHelp")})]}),e.jsxs("div",{className:"flex justify-end space-x-4",children:[e.jsx("button",{onClick:m,className:"hub-btn",children:t("common.cancel")}),e.jsx("button",{onClick:C,disabled:!d.trim(),className:"hub-btn primary",children:t("groupImport.preview")})]})]})]})})},ve=({groups:i,onCancel:m})=>{const{t}=P(),[d,u]=b.useState(""),[A,g]=b.useState(""),[k,x]=b.useState([]),[p,v]=b.useState(!1),[y,w]=b.useState(!1),[C,E]=b.useState(null),o=a=>{x(n=>n.includes(a)?n.filter(j=>j!==a):[...n,a])},c=()=>{k.length===i.length?x([]):x(i.map(a=>a.id))},f=async()=>{if(!d.trim()){E(t("template.nameRequired"));return}w(!0),E(null);try{const a=await M("/templates/export",{name:d.trim(),description:A.trim()||void 0,groupIds:k.length>0?k:void 0,includeDisabledServers:p});if(a.success&&a.data){const n=a.data,j=new Blob([JSON.stringify(n,null,2)],{type:"application/json"}),T=URL.createObjectURL(j),R=document.createElement("a");R.href=T,R.download=`${n.name.replace(/[^a-zA-Z0-9-_]/g,"_")}.mcphub-template.json`,document.body.appendChild(R),R.click(),document.body.removeChild(R),URL.revokeObjectURL(T),m()}else E(a.message||t("template.exportFailed"))}catch(a){console.error("Export error:",a),E(t("template.exportFailed"))}finally{w(!1)}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6 w-full max-w-3xl max-h-[90vh] overflow-y-auto",children:[e.jsxs("div",{className:"flex justify-between items-center mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:t("template.exportTitle")}),e.jsx("button",{onClick:m,className:"text-gray-500 hover:text-gray-700",children:"✕"})]}),C&&e.jsx("div",{className:"mb-4 bg-red-50 border-l-4 border-red-500 p-4 rounded",children:e.jsx("p",{className:"text-red-700",children:C})}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsxs("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:[t("template.name")," *"]}),e.jsx("input",{type:"text",value:d,onChange:a=>u(a.target.value),className:"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:t("template.namePlaceholder")})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-1",children:t("template.description")}),e.jsx("input",{type:"text",value:A,onChange:a=>g(a.target.value),className:"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:t("template.descriptionPlaceholder")})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex justify-between items-center mb-2",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700",children:t("template.selectGroups")}),e.jsx("button",{onClick:c,className:"text-sm text-blue-600 hover:text-blue-800",children:k.length===i.length?t("template.deselectAll"):t("template.selectAll")})]}),e.jsx("p",{className:"text-xs text-gray-500 mb-2",children:t("template.selectGroupsHelp")}),e.jsx("div",{className:"border border-gray-200 dark:border-gray-700 rounded-md max-h-48 overflow-y-auto",children:i.map(a=>e.jsxs("label",{className:"flex items-center px-3 py-2 hover:bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:k.includes(a.id),onChange:()=>o(a.id),className:"mr-3 h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"}),e.jsxs("div",{children:[e.jsx("span",{className:"text-sm font-medium text-gray-900",children:a.name}),a.description&&e.jsx("span",{className:"text-xs text-gray-500 ml-2",children:a.description})]})]},a.id))})]}),e.jsxs("label",{className:"flex items-center space-x-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:p,onChange:a=>v(a.target.checked),className:"h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"}),e.jsx("span",{className:"text-sm text-gray-700",children:t("template.includeDisabled")})]})]}),e.jsx("div",{className:"mt-4 p-3 bg-blue-50 border border-blue-200 rounded-md",children:e.jsx("p",{className:"text-sm text-blue-700",children:t("template.exportNote")})}),e.jsxs("div",{className:"flex justify-end space-x-4 mt-6",children:[e.jsx("button",{onClick:m,className:"hub-btn",children:t("common.cancel")}),e.jsx("button",{onClick:f,disabled:y||!d.trim(),className:"hub-btn primary",children:t(y?"template.exporting":"template.export")})]})]})})},Ne=({onSuccess:i,onCancel:m})=>{const{t}=P(),[d,u]=b.useState(null),[A,g]=b.useState(null),[k,x]=b.useState(!1),[p,v]=b.useState(null),y=b.useRef(null),w=o=>{var a;g(null),u(null),v(null);const c=(a=o.target.files)==null?void 0:a[0];if(!c)return;const f=new FileReader;f.onload=n=>{var j;try{const T=JSON.parse((j=n.target)==null?void 0:j.result);if(!T.version||!T.name||!T.servers||!T.groups){g(t("template.invalidFormat"));return}u(T)}catch{g(t("template.parseError"))}},f.readAsText(c)},C=o=>{if(g(null),u(null),v(null),!!o.trim())try{const c=JSON.parse(o.trim());if(!c.version||!c.name||!c.servers||!c.groups){g(t("template.invalidFormat"));return}u(c)}catch{g(t("template.parseError"))}},E=async()=>{if(d){x(!0),g(null);try{const o=await M("/templates/import",d);o.data?(v(o.data),o.data.success&&i()):g(o.message||t("template.importFailed"))}catch(o){console.error("Import error:",o),g(t("template.importFailed"))}finally{x(!1)}}};return e.jsx("div",{className:"fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4",children:e.jsxs("div",{className:"bg-white dark:bg-gray-800 shadow rounded-lg p-6 w-full max-w-4xl max-h-[90vh] overflow-y-auto",children:[e.jsxs("div",{className:"flex justify-between items-center mb-6",children:[e.jsx("h2",{className:"text-xl font-semibold text-gray-900",children:t("template.importTitle")}),e.jsx("button",{onClick:m,className:"text-gray-500 hover:text-gray-700",children:"✕"})]}),A&&e.jsx("div",{className:"mb-4 bg-red-50 border-l-4 border-red-500 p-4 rounded",children:e.jsx("p",{className:"text-red-700",children:A})}),p&&e.jsxs("div",{className:`mb-4 p-4 rounded border-l-4 ${p.success?"bg-green-50 border-green-500":"bg-yellow-50 border-yellow-500"}`,children:[e.jsx("p",{className:p.success?"text-green-700":"text-yellow-700",children:t("template.importResult",{serversCreated:p.serversCreated,serversSkipped:p.serversSkipped,groupsCreated:p.groupsCreated,groupsSkipped:p.groupsSkipped})}),p.requiredEnvVars.length>0&&e.jsxs("div",{className:"mt-2 p-2 bg-orange-50 border border-orange-200 rounded",children:[e.jsx("p",{className:"text-sm font-medium text-orange-800",children:t("template.envVarsNeeded")}),e.jsx("ul",{className:"mt-1 text-sm text-orange-700",children:p.requiredEnvVars.map(o=>e.jsx("li",{className:"font-mono",children:o},o))})]})]}),d?e.jsxs("div",{children:[e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"p-3 bg-gray-50 dark:bg-gray-800 rounded-md",children:[e.jsx("h3",{className:"font-medium text-gray-900",children:d.name}),d.description&&e.jsx("p",{className:"text-sm text-gray-600 mt-1",children:d.description}),e.jsxs("p",{className:"text-xs text-gray-500 mt-1",children:[t("template.version"),": ",d.version," | ",t("template.createdAt"),":"," ",new Date(d.createdAt).toLocaleDateString()]})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:[t("template.servers")," (",Object.keys(d.servers).length,")"]}),e.jsx("div",{className:"border border-gray-200 dark:border-gray-700 rounded-md divide-y divide-gray-200 dark:divide-gray-700 max-h-40 overflow-y-auto",children:Object.entries(d.servers).map(([o,c])=>e.jsxs("div",{className:"px-3 py-2",children:[e.jsx("span",{className:"text-sm font-medium text-gray-900",children:o}),e.jsx("span",{className:"text-xs text-gray-500 ml-2",children:c.type||"stdio"})]},o))})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-sm font-medium text-gray-700 mb-2",children:[t("template.groups")," (",d.groups.length,")"]}),e.jsx("div",{className:"border border-gray-200 dark:border-gray-700 rounded-md divide-y divide-gray-200 dark:divide-gray-700 max-h-40 overflow-y-auto",children:d.groups.map((o,c)=>e.jsxs("div",{className:"px-3 py-2",children:[e.jsx("span",{className:"text-sm font-medium text-gray-900",children:o.name}),o.description&&e.jsx("span",{className:"text-xs text-gray-500 ml-2",children:o.description}),e.jsxs("div",{className:"text-xs text-gray-500 mt-1",children:[o.servers.length," ",t("template.serversInGroup")]})]},c))})]}),d.requiredEnvVars.length>0&&e.jsxs("div",{className:"p-3 bg-orange-50 border border-orange-200 rounded-md",children:[e.jsx("h4",{className:"text-sm font-medium text-orange-800",children:t("template.envVarsNeeded")}),e.jsx("ul",{className:"mt-1 text-sm text-orange-700 font-mono",children:d.requiredEnvVars.map(o=>e.jsx("li",{children:o},o))})]})]}),e.jsxs("div",{className:"flex justify-end space-x-4 mt-6",children:[e.jsx("button",{onClick:()=>{u(null),v(null),y.current&&(y.current.value="")},className:"hub-btn",children:t("common.back")}),e.jsx("button",{onClick:E,disabled:k,className:"hub-btn primary",children:t(k?"template.importing":"template.import")})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"mb-4",children:[e.jsx("div",{className:"flex items-center justify-between mb-2",children:e.jsx("label",{className:"block text-sm font-medium text-gray-700",children:t("template.uploadFile")})}),e.jsx("div",{className:"flex items-center space-x-4",children:e.jsx("input",{ref:y,type:"file",accept:".json",onChange:w,className:"block text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"})})]}),e.jsxs("div",{className:"relative my-4",children:[e.jsx("div",{className:"absolute inset-0 flex items-center",children:e.jsx("div",{className:"w-full border-t border-gray-300"})}),e.jsx("div",{className:"relative flex justify-center text-sm",children:e.jsx("span",{className:"bg-white dark:bg-gray-800 px-2 text-gray-500",children:t("template.or")})})]}),e.jsxs("div",{className:"mb-4",children:[e.jsx("label",{className:"block text-sm font-medium text-gray-700 mb-2",children:t("template.pasteJson")}),e.jsx("textarea",{className:"w-full h-64 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm",placeholder:t("template.pastePlaceholder"),onChange:o=>C(o.target.value)})]}),e.jsx("div",{className:"flex justify-end space-x-4",children:e.jsx("button",{onClick:m,className:"hub-btn",children:t("common.cancel")})})]})]})})},ze=()=>{const{t:i}=P(),{groups:m,loading:t,error:d,setError:u,deleteGroup:A,triggerRefresh:g}=q(),{allServers:k}=J({refreshOnMount:!0}),[x,p]=b.useState(null),[v,y]=b.useState(!1),[w,C]=b.useState(!1),[E,o]=b.useState(!1),[c,f]=b.useState(!1),a=async n=>{const j=await A(n);(!j||!j.success)&&u((j==null?void 0:j.message)||i("groups.deleteError"))};return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-end justify-between gap-4 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"hub-h1",children:i("pages.groups.title")}),e.jsxs("p",{className:"hub-sub",children:[e.jsx("span",{className:"hub-num",children:m.length})," ",i("nav.groups").toLowerCase()]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsxs("button",{className:"hub-btn",onClick:()=>C(!0),children:[e.jsx(V,{size:13})," ",i("groupImport.button")]}),e.jsxs("button",{className:"hub-btn",onClick:()=>o(!0),children:[e.jsx(ce,{size:13})," ",i("template.exportButton")]}),e.jsxs("button",{className:"hub-btn",onClick:()=>f(!0),children:[e.jsx(V,{size:13})," ",i("template.importButton")]}),e.jsxs("button",{className:"hub-btn primary",onClick:()=>y(!0),children:[e.jsx(_,{size:13})," ",i("groups.add")]})]})]}),d&&e.jsxs("div",{className:"hub-card flex items-center justify-between gap-3 mb-4",style:{padding:"10px 14px",borderColor:"oklch(0.85 0.1 25)",background:"oklch(0.97 0.03 25)",color:"oklch(0.4 0.18 25)"},children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(de,{size:14,className:"flex-shrink-0"}),e.jsx("span",{className:"truncate text-[13px]",children:d})]}),e.jsx("button",{className:"hub-icon-btn sm",onClick:()=>u(null),children:e.jsx(me,{size:13})})]}),t?e.jsx("div",{className:"hub-card p-6 text-center",style:{color:"var(--hub-ink-3)"},children:i("app.loading")}):m.length===0?e.jsx("div",{className:"hub-card p-10 text-center",style:{color:"var(--hub-ink-3)"},children:i("groups.noGroups")}):e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-3.5",children:[m.map(n=>e.jsx(ye,{group:n,servers:k,onEdit:p,onDelete:a},n.id)),e.jsx("button",{onClick:()=>y(!0),className:"flex items-center justify-center text-[var(--hub-ink-3)] hover:text-[var(--hub-ink-2)] transition-colors",style:{border:"1px dashed var(--hub-line)",borderRadius:10,minHeight:200,background:"transparent",cursor:"pointer"},children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"grid place-items-center mx-auto mb-2",style:{width:36,height:36,borderRadius:10,border:"1px solid var(--hub-line)"},children:e.jsx(_,{size:16})}),e.jsx("div",{style:{fontSize:13,fontWeight:500,color:"var(--hub-ink-2)"},children:i("groups.add")}),e.jsx("div",{style:{fontSize:12,marginTop:2},children:i("groups.addNew")})]})})]}),v&&e.jsx(xe,{onAdd:()=>{y(!1),g()},onCancel:()=>y(!1)}),w&&e.jsx(je,{onSuccess:()=>{C(!1),g()},onCancel:()=>C(!1)}),x&&e.jsx(he,{group:x,onEdit:()=>{p(null),g()},onCancel:()=>p(null)}),E&&e.jsx(ve,{groups:m,onCancel:()=>o(!1)}),c&&e.jsx(Ne,{onSuccess:()=>{f(!1),g()},onCancel:()=>f(!1)})]})};export{ze as default};
33
+ //# sourceMappingURL=GroupsPage-Bhg51kbu.js.map