Files
mai-bot/dashboard/dist/assets/key-value-editor-D1uUqXIn.js

4 lines
9.7 KiB
JavaScript

import{r as o,j as e}from"./router-zNjPR4CY.js";import{B as b,I as T,T as M,O as D,P as J,R as O,g as E}from"./index-CuOHsLf7.js";import{T as K}from"./textarea-8PIujbf-.js";import{S as P}from"./switch-Kc2EZ0Ga.js";import{S as $,a as B,b as F,c as L,d as v}from"./select-DGqIoF9r.js";import{w as V,a as U,y as W,v as q,W as G,b as H}from"./icons-DTcdLw9j.js";function N(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`${Date.now().toString(36)}-${Math.random().toString(36).substring(2,11)}`}function S(t){return t===null?"null":Array.isArray(t)?"array":typeof t=="object"?"object":typeof t=="boolean"?"boolean":typeof t=="number"?"number":"string"}function k(t){return Object.entries(t).map(([n,r])=>{const a=S(r),x={id:N(),key:n,value:r,type:a,expanded:!0};return a==="object"&&r&&typeof r=="object"?x.children=k(r):a==="array"&&Array.isArray(r)&&(x.children=r.map((h,l)=>{const f=S(h),i={id:N(),key:String(l),value:h,type:f,expanded:!0};return f==="object"&&h&&typeof h=="object"?i.children=k(h):f==="array"&&Array.isArray(h)&&(i.children=h.map((y,j)=>({id:N(),key:String(j),value:y,type:S(y),expanded:!0}))),i})),x})}function C(t){const n={};for(const r of t)r.key.trim()&&(r.type==="object"&&r.children?n[r.key]=C(r.children):r.type==="array"&&r.children?n[r.key]=r.children.map(a=>a.type==="object"&&a.children?C(a.children):a.type==="array"&&a.children?a.children.map(x=>x.value):a.value):r.type==="null"?n[r.key]=null:n[r.key]=r.value);return n}function R(t,n){switch(n){case"boolean":return t==="true";case"number":{const r=parseFloat(t);return isNaN(r)?0:r}case"null":return null;default:return t}}function z({node:t,level:n,onUpdate:r,onRemove:a,onAddChild:x,onToggleExpand:h}){const l=t.type==="object"||t.type==="array",f=t.children&&t.children.length>0;return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"grid gap-2 items-center",style:{gridTemplateColumns:l?"32px 1fr 90px 64px":"32px 1fr 1fr 90px 32px",paddingLeft:`${n*20}px`},children:[e.jsx(b,{type:"button",variant:"ghost",size:"icon",className:"h-7 w-7",onClick:()=>h(t.id),disabled:!l||!f,children:l&&f?t.expanded?e.jsx(U,{className:"h-4 w-4"}):e.jsx(W,{className:"h-4 w-4"}):e.jsx("span",{className:"w-4"})}),e.jsx(T,{value:t.key,onChange:i=>r(t.id,"key",i.target.value),placeholder:"key",className:"h-8 text-sm"}),!l&&e.jsx(e.Fragment,{children:t.type==="boolean"?e.jsxs("div",{className:"flex items-center h-8 px-3 border rounded-md bg-background",children:[e.jsx(P,{checked:t.value===!0,onCheckedChange:i=>r(t.id,"value",i)}),e.jsx("span",{className:"ml-2 text-sm text-muted-foreground",children:t.value?"true":"false"})]}):t.type==="null"?e.jsx("div",{className:"flex items-center h-8 px-3 border rounded-md bg-muted text-sm text-muted-foreground",children:"null"}):e.jsx(T,{type:t.type==="number"?"number":"text",value:t.value,onChange:i=>r(t.id,"value",i.target.value),placeholder:"value",className:"h-8 text-sm",step:t.type==="number"?"any":void 0})}),e.jsxs($,{value:t.type,onValueChange:i=>r(t.id,"type",i),children:[e.jsx(B,{className:"h-8 text-xs",children:e.jsx(F,{})}),e.jsxs(L,{children:[e.jsx(v,{value:"string",children:"字符串"}),e.jsx(v,{value:"number",children:"数字"}),e.jsx(v,{value:"boolean",children:"布尔"}),e.jsx(v,{value:"null",children:"Null"}),e.jsx(v,{value:"object",children:"对象"}),e.jsx(v,{value:"array",children:"数组"})]})]}),e.jsxs("div",{className:"flex gap-1 justify-end",children:[l&&e.jsx(b,{type:"button",variant:"ghost",size:"icon",className:"h-8 w-8 text-muted-foreground hover:text-primary",onClick:()=>x(t.id),title:"添加子项",children:e.jsx(V,{className:"h-4 w-4"})}),e.jsx(b,{type:"button",variant:"ghost",size:"icon",className:"h-8 w-8 text-muted-foreground hover:text-destructive",onClick:()=>a(t.id),title:"删除",children:e.jsx(q,{className:"h-4 w-4"})})]})]}),l&&t.expanded&&t.children&&t.children.length>0&&e.jsx("div",{className:"space-y-1",children:t.children.map(i=>e.jsx(z,{node:i,level:n+1,onUpdate:r,onRemove:a,onAddChild:x,onToggleExpand:h},i.id))})]})}function Q({value:t,onChange:n,placeholder:r="添加参数..."}){const[a,x]=o.useState(()=>k(t||{})),h=o.useRef(null);o.useEffect(()=>{const d=JSON.stringify(t||{});h.current!==d&&x(k(t||{}))},[t]);const l=o.useCallback(d=>{const u=C(d);h.current=JSON.stringify(u),x(d),n(u)},[n]),f=o.useCallback(()=>{const d={id:N(),key:"",value:"",type:"string",expanded:!1};l([...a,d])},[a,l]),i=o.useCallback((d,u,c)=>{const s=w=>w.map(m=>{if(m.id===d)if(u==="type"){const p=c;if(p==="object")return{...m,type:p,value:{},children:[]};if(p==="array")return{...m,type:p,value:[],children:[]};if(p==="null")return{...m,type:p,value:null};{const I=R(String(m.value),p);return{...m,type:p,value:I,children:void 0}}}else if(u==="value"){const p=R(String(c),m.type);return{...m,value:p}}else return{...m,[u]:String(c)};return m.children?{...m,children:s(m.children)}:m});l(s(a))},[a,l]),y=o.useCallback(d=>{const u=c=>c.filter(s=>s.id!==d).map(s=>s.children?{...s,children:u(s.children)}:s);l(u(a))},[a,l]),j=o.useCallback(d=>{const u=c=>c.map(s=>{if(s.id===d){const w={id:N(),key:s.type==="array"?String(s.children?.length||0):"",value:"",type:"string",expanded:!0};return{...s,children:[...s.children||[],w]}}return s.children?{...s,children:u(s.children)}:s});l(u(a))},[a,l]),g=o.useCallback(d=>{const u=c=>c.map(s=>s.id===d?{...s,expanded:!s.expanded}:s.children?{...s,children:u(s.children)}:s);x(u(a))},[a]);return e.jsxs("div",{className:"h-full flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("span",{className:"text-xs text-muted-foreground",children:[a.length," 个参数"]}),e.jsxs(b,{type:"button",size:"sm",variant:"outline",onClick:f,className:"h-7 text-xs",children:[e.jsx(V,{className:"h-3 w-3 mr-1"}),"添加参数"]})]}),e.jsx("div",{className:"flex-1 overflow-y-auto space-y-1",children:a.length===0?e.jsx("div",{className:"text-sm text-muted-foreground text-center py-4 border border-dashed rounded-md",children:r}):e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"grid gap-2 text-xs text-muted-foreground px-1 sticky top-0 bg-background z-10",style:{gridTemplateColumns:"32px 1fr 1fr 90px 32px"},children:[e.jsx("span",{}),e.jsx("span",{children:"键名"}),e.jsx("span",{children:"值"}),e.jsx("span",{children:"类型"}),e.jsx("span",{})]}),a.map(d=>e.jsx(z,{node:d,level:0,onUpdate:i,onRemove:y,onAddChild:j,onToggleExpand:g},d.id))]})})]})}function A(t){if(!t.trim())return{valid:!0,parsed:{}};try{const n=JSON.parse(t);return typeof n!="object"||n===null||Array.isArray(n)?{valid:!1,error:"必须是一个 JSON 对象 {}"}:{valid:!0,parsed:n}}catch{return{valid:!1,error:"JSON 格式错误"}}}function se({value:t,onChange:n,className:r,placeholder:a="添加额外参数..."}){const[x,h]=o.useState("list"),l=o.useMemo(()=>Object.keys(t||{}).length>0?JSON.stringify(t,null,2):"",[t]),[f,i]=o.useState(l),[y,j]=o.useState(null);o.useEffect(()=>{i(l)},[l]);const g=o.useMemo(()=>{const c=A(f);return c.valid&&c.parsed?{success:!0,data:c.parsed}:{success:!1,data:{}}},[f]),d=o.useCallback(c=>{const s=c;s==="json"&&x==="list"&&(i(Object.keys(t).length>0?JSON.stringify(t,null,2):""),j(null)),h(s)},[x,t]),u=o.useCallback(c=>{i(c);const s=A(c);s.valid&&s.parsed?(j(null),n(s.parsed)):j(s.error||"JSON 格式错误")},[n]);return e.jsx("div",{className:E("h-full flex flex-col",r),children:e.jsxs(M,{value:x,onValueChange:d,className:"w-full flex-1 flex flex-col",children:[e.jsxs(D,{className:"h-8 p-0.5 bg-muted/60 w-fit",children:[e.jsx(J,{value:"list",className:"h-7 px-3 text-xs data-[state=active]:bg-background data-[state=active]:shadow-sm",children:"可视化编辑"}),e.jsx(J,{value:"json",className:"h-7 px-3 text-xs data-[state=active]:bg-background data-[state=active]:shadow-sm",children:"JSON 编辑"})]}),e.jsx(O,{value:"list",className:"mt-2 flex-1 flex flex-col overflow-hidden data-[state=inactive]:hidden data-[state=inactive]:h-0",children:e.jsx(Q,{value:t,onChange:n,placeholder:a})}),e.jsx(O,{value:"json",className:"mt-2 flex-1 flex flex-col overflow-hidden data-[state=inactive]:hidden data-[state=inactive]:h-0",children:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3 flex-1 overflow-hidden",children:[e.jsxs("div",{className:"flex flex-col gap-2 overflow-hidden",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"编辑"}),y?e.jsxs("div",{className:"flex items-center gap-1 text-xs text-destructive",children:[e.jsx(G,{className:"h-3 w-3"}),e.jsx("span",{className:"truncate max-w-[150px]",children:y})]}):f.trim()&&e.jsxs("div",{className:"flex items-center gap-1 text-xs text-green-600 dark:text-green-400",children:[e.jsx(H,{className:"h-3 w-3"}),e.jsx("span",{children:"有效"})]})]}),e.jsx(K,{value:f,onChange:c=>u(c.target.value),placeholder:`{
"key": "value"
}`,className:E("font-mono text-sm flex-1 resize-none",y&&"border-destructive focus-visible:ring-destructive")}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"支持任意 JSON 类型(包括嵌套对象和数组)"})]}),e.jsxs("div",{className:"flex flex-col gap-2 overflow-hidden",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:"预览"}),e.jsx("div",{className:"flex-1 rounded-md border bg-muted/30 p-3 overflow-auto",children:g.success&&Object.keys(g.data).length>0?e.jsx("pre",{className:"font-mono text-xs whitespace-pre-wrap break-words",children:JSON.stringify(g.data,null,2)}):g.success?e.jsx("div",{className:"flex items-center justify-center h-full text-sm text-muted-foreground",children:"暂无参数"}):e.jsx("div",{className:"flex items-center justify-center h-full text-sm text-destructive",children:"JSON 格式错误"})}),e.jsx("p",{className:"text-xs text-muted-foreground",children:"实时预览解析结果"})]})]})})]})})}export{se as K};