live-sfu-demo/internal/server/static/assets/manage-14L7BkQx.js

1 line
28 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import{B as e,C as t,G as n,L as r,N as i,O as a,S as o,T as s,U as c,V as l,_ as u,a as d,b as f,g as p,j as m,m as h,n as g,p as _,r as v,t as y,u as b,x,z as S}from"./ui-BjxGELcM.js";import{n as C,t as w}from"./eye-8xrL_Squ.js";import{t as T}from"./globe-Cy3sFr4f.js";import{t as E}from"./hash-Dadu1FEQ.js";import{n as D,r as O,t as k}from"./users-D75l7xkO.js";import{t as A}from"./log-out-BYvt6A8x.js";import{t as j}from"./message-square-DGTwCJY8.js";import{t as M}from"./radio-tower-Dfdb9MI0.js";import{n as N,t as ee}from"./user-round-BD5O3Mh0.js";import{t as P}from"./shield-check-CU6M0J1d.js";import{t as F}from"./video-02fL9iqS.js";import{n as I,r as L}from"./index-BsK239Bd.js";var R=[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`,key:`1s6t7t`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`w0ekpg`}]],z=e=>r(u,n(e,{iconNode:R,name:`key-round`})),te=[[`path`,{d:`M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z`,key:`zw3jo`}],[`path`,{d:`M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12`,key:`1wduqc`}],[`path`,{d:`M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17`,key:`kqbvx6`}]],B=e=>r(u,n(e,{iconNode:te,name:`layers`})),V=[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]],ne=e=>r(u,n(e,{iconNode:V,name:`refresh-cw`})),H=[[`path`,{d:`M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z`,key:`1c8476`}],[`path`,{d:`M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7`,key:`1ydtos`}],[`path`,{d:`M7 3v4a1 1 0 0 0 1 1h7`,key:`t51u73`}]],U=e=>r(u,n(e,{iconNode:H,name:`save`})),W=[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]],G=e=>r(u,n(e,{iconNode:W,name:`settings`})),K=[[`path`,{d:`M10 5H3`,key:`1qgfaw`}],[`path`,{d:`M12 19H3`,key:`yhmn1j`}],[`path`,{d:`M14 3v4`,key:`1sua03`}],[`path`,{d:`M16 17v4`,key:`1q0r14`}],[`path`,{d:`M21 12h-9`,key:`1o4lsq`}],[`path`,{d:`M21 19h-5`,key:`1rlt1p`}],[`path`,{d:`M21 5h-7`,key:`1oszz2`}],[`path`,{d:`M8 10v4`,key:`tgpxqk`}],[`path`,{d:`M8 12H3`,key:`a7s4jb`}]],q=e=>r(u,n(e,{iconNode:K,name:`sliders-horizontal`})),J=[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]],Y=e=>r(u,n(e,{iconNode:J,name:`trash-2`})),X=a(`<div class="flex flex-wrap gap-1.5">`),Z=a(`<button type=button>`),re=[{path:`overview`,label:`概览`,icon:B,perms:[`room:list`]},{path:`rooms`,label:`房间`,icon:M,perms:[`room:manage`]},{path:`permissions`,label:`权限`,icon:z,perms:[`room:manage`]},{path:`system`,label:`系统`,icon:G,perms:[`system:manage`,`config:read`]}];function ie(t){L();let n=e(()=>re.filter(e=>e.perms.some(e=>_.can(e))||_.isAdminOrAbove()));return(()=>{var e=X();return o(e,r(m,{get each(){return n()},children:e=>{let n=e.icon,i=()=>t.value===e.path;return(()=>{var a=Z();return a.$$click=()=>t.onChange(e.path),o(a,r(n,{class:`size-3.5`}),null),o(a,()=>e.label,null),l(e=>{var t=`inline-flex h-9 items-center gap-1.5 border px-3 text-xs font-medium transition-colors ${i()?`border-line bg-acid-lime text-black`:`border-line bg-card text-muted-foreground hover:bg-accent`}`,n=i()?`page`:void 0;return t!==e.e&&f(a,e.e=t),n!==e.t&&s(a,`aria-current`,e.t=n),e},{e:void 0,t:void 0}),a})()}})),e})()}x([`click`]);var ae=a(`<div>`),oe=a(`<p class="mt-3 max-w-2xl text-sm text-muted-foreground">`),se=a(`<div class="flex shrink-0 items-center gap-2">`),ce=a(`<div class="flex flex-wrap items-start justify-between gap-4"><div class="min-w-0 flex-1"><p class="mono-label text-muted-foreground">manage / console</p><h1 class="display mt-2 text-4xl sm:text-5xl">`);function le(e){return(()=>{var t=ae();return o(t,()=>e.children),l(()=>f(t,`mx-auto max-w-[1400px] space-y-6 px-4 py-8 sm:px-6 sm:py-10 ${e.class??``}`)),t})()}function ue(e){return(()=>{var t=ce(),n=t.firstChild,a=n.firstChild.nextSibling;return o(a,()=>e.title),o(n,r(i,{get when(){return e.description},get children(){var t=oe();return o(t,()=>e.description),t}}),null),o(t,r(i,{get when(){return e.actions},get children(){var t=se();return o(t,()=>e.actions),t}}),null),t})()}var de=a(`<p class="mt-1 text-xs text-muted-foreground">`),fe=a(`<div class="relative border border-line bg-card/60 p-4"><div class="flex items-start justify-between gap-3"><div><p class="micro-label text-muted-foreground"></p><p class="display mt-2 text-3xl"></p></div><span class="flex size-8 items-center justify-center border border-line bg-background text-muted-foreground">`),pe=a(`<p class="py-6 text-center text-sm text-muted-foreground">暂无房间数据`),me=a(`<div class=space-y-6><div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4"></div><div class="grid gap-4 lg:grid-cols-3"><div class="border border-line bg-card/50 p-4 lg:col-span-2"><div class="flex items-center justify-between gap-3"><h3 class=font-semibold>房间分发状态</h3><span class="mono-label text-muted-foreground"> rooms</span></div><div class="mt-4 space-y-2"></div></div><div class="border border-line bg-card/50 p-4"><h3 class=font-semibold>后端能力</h3><div class="mt-4 space-y-2">`),he=a(`<div class="flex items-center justify-between gap-3 border border-line/60 bg-background/50 px-3 py-2.5"><div class="flex min-w-0 items-center gap-2.5"><span class="truncate font-mono text-sm"></span></div><div class="flex items-center gap-3 text-xs text-muted-foreground"><span class="hidden sm:inline"> 成员</span><span> targets`),ge=a(`<div class="flex items-center justify-between border border-line/60 px-3 py-2.5"><span class="font-mono text-xs uppercase">`);function Q(e){let t=e.icon;return(()=>{var n=fe(),a=n.firstChild.firstChild,s=a.firstChild,c=s.nextSibling,l=a.nextSibling;return o(s,()=>e.label),o(c,()=>e.value),o(a,r(i,{get when(){return e.hint},get children(){var t=de();return o(t,()=>e.hint),t}}),null),o(l,r(t,{class:`size-4`})),n})()}function _e(e){let t=()=>e.overview,n=()=>e.rooms;return(()=>{var e=me(),a=e.firstChild,s=a.nextSibling.firstChild,c=s.firstChild,l=c.firstChild.nextSibling,u=l.firstChild,f=c.nextSibling,p=s.nextSibling.firstChild.nextSibling;return o(a,r(Q,{label:`房间总数`,get value(){return t()?.rooms_total??`-`},get hint(){return`${t()?.rooms_live??0} 个正在直播`},icon:B}),null),o(a,r(Q,{label:`在线房间`,get value(){return t()?.rooms_live??`-`},hint:`有推流目标的房间`,icon:F}),null),o(a,r(Q,{label:`房间成员`,get value(){return t()?.members_total??`-`},hint:`所有房间成员汇总`,icon:k}),null),o(a,r(Q,{label:`系统用户`,get value(){return t()?.users_total??`-`},hint:`已注册账号`,icon:P}),null),o(l,()=>n().length,u),o(f,r(m,{get each(){return n().slice(0,6)},children:e=>(()=>{var t=he(),n=t.firstChild,i=n.firstChild,a=n.nextSibling.firstChild,s=a.firstChild,c=a.nextSibling,l=c.firstChild;return o(n,r(d,{get active(){return e.live}}),i),o(i,()=>e.room.name),o(n,r(g,{get variant(){return e.live?`success`:`muted`},class:`hidden sm:inline-flex`,get children(){return e.live?`LIVE`:`IDLE`}}),null),o(a,()=>e.member_count,s),o(c,()=>e.targets?.length??0,l),t})()}),null),o(f,r(i,{get when(){return n().length===0},get children(){return pe()}}),null),o(p,r(m,{get each(){return t()?.backends||[]},children:e=>(()=>{var t=ge(),n=t.firstChild;return o(n,()=>e.name||e.kind),o(t,r(g,{get variant(){return e.configured?`success`:`muted`},get children(){return e.configured?`已配置`:`未配置`}}),null),t})()})),e})()}var $=[`send_chat`,`view_chat_history`,`view_members`,`subscribe`,`watch_room`,`publish`,`stop_stream`,`broadcast`,`manage_members`,`add_members`,`remove_members`,`manage_permissions`,`manage_room`,`delete_room`,`delete_chat_messages`,`control_stream`],ve={send_chat:`发弹幕`,view_chat_history:`看记录`,view_members:`看成员`,subscribe:`拉流`,watch_room:`监听`,publish:`推流`,stop_stream:`停播`,broadcast:`广播`,manage_members:`管成员`,add_members:`邀成员`,remove_members:`踢人`,manage_permissions:`管权限`,manage_room:`管房间`,delete_room:`删房间`,delete_chat_messages:`删消息`,control_stream:`控流`},ye={creator:{label:`房主`,color:`border-amber-400/40 bg-amber-400/10 text-amber-600`},admin:{label:`管理员`,color:`border-acid-magenta/30 bg-acid-magenta/10 text-acid-magenta`},member:{label:`成员`,color:`border-acid-cyan/30 bg-acid-cyan/10 text-acid-cyan`},guest:{label:`访客`,color:`border-line bg-muted text-muted-foreground`},root:{label:`超管`,color:`border-amber-500/40 bg-amber-500/10 text-amber-600`},viewer:{label:`观看者`,color:`border-acid-cyan/30 bg-acid-cyan/10 text-acid-cyan`},publisher:{label:`发布者`,color:`border-warning/30 bg-warning/10 text-warning`}},be=a(`<div class="border border-line bg-card/60 p-4"><div class="flex flex-wrap items-start justify-between gap-3"><div class=min-w-0><p class="mono-label text-muted-foreground">room / </p><h3 class="display mt-1 truncate text-2xl"></h3></div></div><div class="mt-4 grid gap-3 sm:grid-cols-2"><div class=space-y-1.5><label class=label>描述</label><input class=field></div><div class=space-y-1.5><label class=label>人数上限</label><input class="field field-mono"></div></div><div class="mt-3 flex flex-wrap gap-2">`),xe=a(`<div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h4 class=font-semibold>成员 </h4></div><div class="divide-y divide-line/60">`),Se=a(`<div class="mt-4 grid gap-4 sm:grid-cols-2"><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 聊天</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 访客加入</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 需审批</span><input type=checkbox></label><label class="flex items-center justify-between gap-3 border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2 text-sm"> 公开</span><input type=checkbox>`),Ce=a(`<div class="border border-line bg-card/50 p-4"><h4 class="flex items-center gap-2 font-semibold">房间设置`),we=a(`<div class="grid gap-4 lg:grid-cols-3"><div class="lg:col-span-1 space-y-4"><div class="border border-line bg-card/60 p-4"><h3 class=font-semibold>创建房间</h3><div class="mt-4 space-y-3"><div class=space-y-1.5><label class=label>房间名 *</label><div class="flex items-center gap-2 border border-line bg-background px-3 py-2 focus-within:border-ring"><input class="w-full bg-transparent font-mono text-sm outline-none"placeholder="如 live-101"></div></div><div class=space-y-1.5><label class=label>描述</label><input class=field placeholder=一句话介绍></div><div class="grid grid-cols-2 gap-3"><div class=space-y-1.5><label class=label>可见性</label></div><div class=space-y-1.5><label class=label>人数上限</label><input class="field field-mono"></div></div><div class=space-y-1.5><label class=label>房间密码(可选)</label><div class="flex items-center gap-2 border border-line bg-background px-3 py-2 focus-within:border-ring"><input class="w-full bg-transparent font-mono text-sm outline-none"placeholder=留空为无密码><button type=button class=text-muted-foreground></button></div></div></div></div><div class="border border-line bg-card/50"><div class="flex items-center justify-between border-b border-line/80 px-4 py-3"><h3 class=font-semibold>房间列表</h3><span class="mono-label text-muted-foreground"></span></div><div class="max-h-[480px] overflow-auto"></div></div></div><div class="space-y-4 lg:col-span-2">`),Te=a(`<button type=button><div class=min-w-0><p class="truncate font-mono text-sm font-medium"></p><p class="truncate text-xs text-muted-foreground"></p></div><div class="flex shrink-0 flex-col items-end gap-1"><span class="micro-label text-muted-foreground"> 成员`),Ee=a(`<div class="border border-dashed border-line p-8 text-center text-sm text-muted-foreground">选择一个房间以管理`),De=a(`<div class="flex flex-wrap items-center gap-3 px-4 py-3"><span></span><div class="min-w-0 flex-1"><p class="truncate font-mono text-sm font-medium"></p><p class="micro-label truncate text-muted-foreground">`),Oe=a(`<p class="mt-3 text-sm text-muted-foreground">加载中…`);function ke(e){return(()=>{var t=we(),n=t.firstChild,a=n.firstChild,c=a.firstChild.nextSibling,u=c.firstChild,p=u.firstChild.nextSibling,h=p.firstChild,_=u.nextSibling,y=_.firstChild.nextSibling,x=_.nextSibling,S=x.firstChild;S.firstChild;var k=S.nextSibling.firstChild.nextSibling,A=x.nextSibling.firstChild.nextSibling,M=A.firstChild,P=M.nextSibling,F=a.nextSibling.firstChild,L=F.firstChild.nextSibling,R=F.nextSibling,z=n.nextSibling;return o(p,r(E,{class:`size-4 shrink-0 text-muted-foreground`}),h),h.$$input=t=>e.setNewRoom({name:t.currentTarget.value}),y.$$input=t=>e.setNewRoom({desc:t.currentTarget.value}),o(S,r(b,{get value(){return e.newRoom.isPublic?`public`:`private`},onChange:t=>e.setNewRoom({isPublic:t===`public`}),options:[{value:`public`,label:`公开`},{value:`private`,label:`私密`}]}),null),k.$$input=t=>e.setNewRoom({max:t.currentTarget.value}),o(A,r(O,{class:`size-4 shrink-0 text-muted-foreground`}),M),M.$$input=t=>e.setNewRoom({pwd:t.currentTarget.value}),P.$$click=()=>e.setNewRoom({showPwd:!e.newRoom.showPwd}),o(P,r(i,{get when(){return e.newRoom.showPwd},get fallback(){return r(w,{class:`size-4`})},get children(){return r(C,{class:`size-4`})}})),o(c,r(v,{class:`w-full`,get onClick(){return e.onCreate},get disabled(){return e.loading||!e.newRoom.name.trim()},get children(){return[r(D,{class:`size-4`}),`创建房间`]}}),null),o(L,()=>e.rooms.length),o(R,r(m,{get each(){return e.rooms},children:t=>(()=>{var n=Te(),i=n.firstChild,a=i.firstChild,s=a.nextSibling,c=i.nextSibling,u=c.firstChild,p=u.firstChild;return n.$$click=()=>e.onSelectRoom(t.room.name),o(a,()=>t.room.name),o(s,()=>t.room.description||`—`),o(c,r(d,{get active(){return t.live}}),u),o(u,()=>t.member_count,p),l(()=>f(n,`flex w-full items-center justify-between gap-3 border-b border-line/60 px-4 py-3 text-left hover:bg-accent/40 ${e.selectedRoom===t.room.name?`bg-acid-lime/10`:``}`)),n})()})),o(z,r(i,{get when(){return e.selectedRoom},get fallback(){return Ee()},get children(){return[(()=>{var t=be(),n=t.firstChild,i=n.firstChild.firstChild;i.firstChild;var a=i.nextSibling,s=n.nextSibling,c=s.firstChild,u=c.firstChild.nextSibling,d=c.nextSibling.firstChild.nextSibling,f=s.nextSibling;return o(i,()=>e.selectedRoom,null),o(a,()=>e.editingRoom?.display_name||e.selectedRoom),o(n,r(g,{get variant(){return e.editingRoom?.is_public?`success`:`warning`},get children(){return e.editingRoom?.is_public?`公开`:`私密`}}),null),u.$$input=t=>e.setEdit({desc:t.currentTarget.value}),d.$$input=t=>e.setEdit({max:t.currentTarget.value}),o(f,r(v,{class:`gap-1.5`,get onClick(){return e.onSave},get children(){return[r(U,{class:`size-4`}),`保存`]}}),null),o(f,r(v,{variant:`danger`,class:`gap-1.5`,onClick:()=>e.onDelete(e.selectedRoom),get children(){return[r(Y,{class:`size-4`}),`删除`]}}),null),l(()=>u.value=e.edit.desc),l(()=>d.value=e.edit.max),t})(),(()=>{var t=xe(),n=t.firstChild,a=n.firstChild;a.firstChild;var s=n.nextSibling;return o(a,()=>e.members.length,null),o(s,r(m,{get each(){return e.members},children:t=>(()=>{var n=De(),a=n.firstChild,s=a.nextSibling.firstChild,c=s.nextSibling;return o(a,()=>(t.username[0]||`?`).toUpperCase()),o(s,()=>t.username),o(c,()=>t.effective_permissions?.join(`, `)||``),o(n,r(b,{class:`w-28`,get value(){return t.role},onChange:n=>e.onChangeRole(e.selectedRoom,t.username,n),options:[{value:`creator`,label:`房主`},{value:`admin`,label:`管理员`},{value:`member`,label:`成员`},{value:`guest`,label:`访客`}]}),null),o(n,r(i,{get when(){return t.role!==`creator`},get children(){return r(v,{variant:`ghost`,class:`h-8 px-2 text-destructive`,onClick:()=>e.onKick(e.selectedRoom,t.username),get children(){return r(I,{class:`size-4`})}})}}),null),l(()=>f(a,`flex size-8 items-center justify-center border font-mono text-xs font-bold ${ye[t.role]?.color||``}`)),n})()})),t})(),(()=>{var t=Ce(),n=t.firstChild,a=n.firstChild;return o(n,r(q,{class:`size-4`}),a),o(t,r(i,{get when(){return e.roomSettings},get fallback(){return Oe()},get children(){return[(()=>{var t=Se(),n=t.firstChild,i=n.firstChild,a=i.firstChild,s=i.nextSibling,c=n.nextSibling,u=c.firstChild,d=u.firstChild,f=u.nextSibling,p=c.nextSibling,m=p.firstChild,h=m.firstChild,g=m.nextSibling,_=p.nextSibling.firstChild,v=_.firstChild,y=_.nextSibling;return o(i,r(j,{class:`size-4 text-muted-foreground`}),a),s.$$input=t=>e.setRoomSettings({...e.roomSettings,chat_enabled:t.currentTarget.checked}),o(u,r(ee,{class:`size-4 text-muted-foreground`}),d),f.$$input=t=>e.setRoomSettings({...e.roomSettings,allow_guest_join:t.currentTarget.checked}),o(m,r(N,{class:`size-4 text-muted-foreground`}),h),g.$$input=t=>e.setRoomSettings({...e.roomSettings,require_approval:t.currentTarget.checked}),o(_,r(T,{class:`size-4 text-muted-foreground`}),v),y.$$input=t=>e.setRoomSettings({...e.roomSettings,is_public:t.currentTarget.checked}),l(()=>s.checked=!!e.roomSettings?.chat_enabled),l(()=>f.checked=!!e.roomSettings?.allow_guest_join),l(()=>g.checked=!!e.roomSettings?.require_approval),l(()=>y.checked=!!e.roomSettings?.is_public),t})(),r(v,{class:`mt-4 gap-1.5`,get onClick(){return e.onSaveSettings},get children(){return[r(U,{class:`size-4`}),`保存设置`]}})]}}),null),t})()]}})),l(()=>s(M,`type`,e.newRoom.showPwd?`text`:`password`)),l(()=>h.value=e.newRoom.name),l(()=>y.value=e.newRoom.desc),l(()=>k.value=e.newRoom.max),l(()=>M.value=e.newRoom.pwd),t})()}x([`input`,`click`]);var Ae=a(`<div class=overflow-auto><table class="w-full min-w-[900px] border-collapse"><thead><tr class="border-b border-line bg-muted/20"><th class="px-3 py-2 text-left text-xs font-mono text-muted-foreground">成员 / 角色</th></tr></thead><tbody>`),je=a(`<div class=space-y-4><div class="border border-line bg-card/60 p-4"><h3 class=font-semibold>角色默认权限</h3><p class="mt-1 text-xs text-muted-foreground">Creator 全量 · Guest 只读,个人覆盖 added/removed 生效。</p><div class="mt-4 overflow-auto"><table class="w-full min-w-[520px] border-collapse text-xs"><thead><tr class="border-b border-line"><th class="px-2 py-2 text-left font-mono text-muted-foreground">permission</th></tr></thead><tbody></tbody></table></div></div><div class="border border-line bg-card/50"><div class="flex flex-wrap items-center justify-between gap-3 border-b border-line/80 px-4 py-3"><h3 class=font-semibold>成员生效权限 · `),Me=a(`<th class="px-2 py-2 text-center font-mono text-muted-foreground">`),Ne=a(`<tr class="border-b border-line/60"><td class="px-2 py-2 font-mono">`),Pe=a(`<td class="px-2 py-2 text-center">`),Fe=a(`<span class="inline-flex size-2 bg-acid-lime">`),Ie=a(`<span class="inline-flex size-2 border border-line">`),Le=a(`<p class="px-4 py-8 text-center text-sm text-muted-foreground">请选择房间`),Re=a(`<th class="px-1 py-2 text-center text-[10px] font-mono text-muted-foreground">`),ze=a(`<tr class="border-b border-line/40"><td class="px-3 py-2"><div class="flex items-center gap-2"><span class="font-mono text-xs font-medium">`),Be=a(`<td class="px-1 py-1 text-center"><button type=button>`);function Ve(e){return(()=>{var t=je(),n=t.firstChild,a=n.firstChild.nextSibling.nextSibling.firstChild.firstChild,s=a.firstChild;s.firstChild;var c=a.nextSibling,l=n.nextSibling,u=l.firstChild,d=u.firstChild;return d.firstChild,o(s,r(m,{each:[`creator`,`admin`,`member`,`guest`],children:e=>(()=>{var t=Me();return o(t,e),t})()}),null),o(c,r(m,{each:$,children:t=>(()=>{var n=Ne(),i=n.firstChild;return o(i,()=>ve[t]||t),o(n,r(m,{each:[`creator`,`admin`,`member`,`guest`],children:n=>{let r=e.permDefs?.roles?.[n]?.perms?.includes(t);return(()=>{var e=Pe();return o(e,r?Fe():Ie()),e})()}}),null),n})()})),o(d,()=>e.selectedRoom||`未选择`,null),o(u,r(b,{get value(){return e.selectedRoom},get onChange(){return e.onSelectRoom},get options(){return e.rooms.map(e=>({value:e.room.name,label:e.room.name}))},class:`w-48`}),null),o(l,r(i,{get when(){return e.selectedRoom},get fallback(){return Le()},get children(){var t=Ae(),n=t.firstChild.firstChild,i=n.firstChild;i.firstChild;var a=n.nextSibling;return o(i,r(m,{each:$,children:e=>(()=>{var t=Re();return o(t,()=>ve[e]||e),t})()}),null),o(a,r(m,{get each(){return e.members},children:t=>(()=>{var n=ze(),i=n.firstChild.firstChild,a=i.firstChild;return o(a,()=>t.username),o(i,r(g,{get class(){return`text-[10px] ${ye[t.role]?.color||``}`},get children(){return t.role}}),null),o(n,r(m,{each:$,children:n=>{let r=t.effective_permissions?.includes(n),i=t.role===`creator`;return(()=>{var a=Be(),s=a.firstChild;return s.$$click=()=>e.onTogglePerm(e.selectedRoom,t.username,n,!!r),s.disabled=i,f(s,`inline-flex size-6 items-center justify-center border text-[10px] ${r?`border-acid-lime bg-acid-lime text-black`:`border-line bg-background text-muted-foreground hover:border-ring`} ${i?`opacity-50`:``}`),o(s,r?`✓`:``),a})()}}),null),n})()})),t}}),null),t})()}x([`click`]);var He=a(`<div class=space-y-4><div class="grid gap-4 lg:grid-cols-2"><div class="border border-line bg-card/60 p-4"><h3 class="flex items-center gap-2 font-semibold">系统与 SFU</h3><div class="mt-4 space-y-3 text-sm"><div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class=text-muted-foreground>HTTP 端口</span><span class=font-mono>8088</span></div><div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class=text-muted-foreground>gRPC</span><span class=font-mono>9090</span></div></div></div><div class="border border-line bg-card/60 p-4"><h3 class="flex items-center gap-2 font-semibold">安全与策略</h3><div class="mt-4 space-y-2 text-xs leading-relaxed text-muted-foreground"><p><span class="font-mono text-foreground">JWT_SECRET</span> 需显式配置;推流 token<span class="font-mono text-foreground"> HS256</span> 签发。</p><p>私密房间支持密码;<span class="font-mono text-foreground">is_public</span> 与<span class="font-mono text-foreground"> allow_guest_join</span> 联动。</p></div></div></div><div class="border border-line bg-card/50 p-4"><h3 class=font-semibold>快捷操作</h3><div class="mt-4 flex flex-wrap gap-2">`),Ue=a(`<div class="flex items-center justify-between border border-line bg-background px-3 py-2.5"><span class="flex items-center gap-2">`);function We(e){return(()=>{var t=He(),n=t.firstChild,i=n.firstChild,a=i.firstChild,s=a.firstChild,c=a.nextSibling;c.firstChild.nextSibling;var l=i.nextSibling.firstChild,u=l.firstChild,d=n.nextSibling.firstChild.nextSibling;return o(a,r(G,{class:`size-4`}),s),o(c,r(m,{get each(){return e.overview?.backends||[]},children:e=>(()=>{var t=Ue(),n=t.firstChild;return o(n,r(M,{class:`size-4 text-muted-foreground`}),null),o(n,()=>e.name||e.kind,null),o(t,r(g,{get variant(){return e.configured?`success`:`muted`},get children(){return e.configured?`已配置`:`未配置`}}),null),t})()}),null),o(l,r(z,{class:`size-4`}),u),o(d,r(v,{variant:`ghost`,onClick:()=>window.open(`/api/config`,`_blank`),get children(){return[r(T,{class:`size-4`}),`/api/config`]}}),null),o(d,r(v,{variant:`ghost`,onClick:()=>{localStorage.clear(),location.reload()},get children(){return[r(A,{class:`size-4`}),`清理缓存`]}}),null),t})()}var Ge=a(`<span class="flex items-center gap-2">`),Ke=a(`<button class="text-xs underline">关闭`),qe=()=>{let[e,n]=c(`overview`),[a,s]=c(null),[l,u]=c([]),[d,f]=c(null),[m,b]=c(``),[x,C]=c([]),[w,T]=c(``),[E,D]=c(!1),[O,k]=c(``),[A,j]=c(``),[M,ee]=c(!0),[F,I]=c(`100`),[L,R]=c(``),[z,te]=c(!1),[B,V]=c(null),[H,U]=c(``),[W,G]=c(``),[K,q]=c(null),J=async()=>{try{let e=await p.manageOverview();s(e)}catch(e){T(String(e?.message||e))}},Y=async()=>{try{let e=await p.manageRooms();u(e.rooms||[]),!m()&&e.rooms?.length&&b(e.rooms[0].room.name)}catch(e){T(String(e?.message||e))}},X=async()=>{try{let e=await p.managePermMatrix();f(e)}catch{}},Z=async e=>{if(e)try{let t=await p.manageMembers(e);C(t.members||[]);let n=await p.manageRoomDetail(e);V(n.room),U(n.room.description||``),G(String(n.room.max_members||100)),q(n.room.settings||null)}catch(e){T(String(e?.message||e))}};S(()=>{J(),Y(),X()}),S(()=>{let t=m();t&&(e()===`rooms`||e()===`permissions`)&&Z(t)});let re=async()=>{let e=O().trim();if(e){D(!0);try{await p.manageCreateRoom({name:e,description:A().trim()||void 0,is_public:M(),max_members:parseInt(F())||100,password:L().trim()||void 0}),k(``),j(``),R(``),await Y(),await J()}catch(e){T(String(e?.message||e))}finally{D(!1)}}},ae=async()=>{let e=m();if(!(!e||!B()))try{await p.manageUpdateRoom(e,{description:H(),max_members:parseInt(W())||void 0,is_public:B().is_public}),await Y(),await Z(e)}catch(e){T(String(e?.message||e))}},oe=async e=>{if(confirm(`删除房间 ${e} ?`))try{await p.manageDeleteRoom(e),await Y(),await J()}catch(e){T(String(e?.message||e))}},se=async(e,t,n)=>{try{await p.manageUpdateMemberRole(e,t,n),await Z(e)}catch(e){T(String(e?.message||e))}},ce=async(e,t)=>{if(confirm(`踢出 ${t} ?`))try{await p.manageKickMember(e,t),await Z(e)}catch(e){T(String(e?.message||e))}},de=async(e,t,n,r)=>{let i=1<<$.indexOf(n),a=x().find(e=>e.username===t);if(!a)return;let o=Number(a.added||0),s=Number(a.removed||0);r?(o&=~i,s|=i):(o|=i,s&=~i);try{await p.manageUpdateMemberPerms(e,t,o,s,!1),await Z(e)}catch(e){T(String(e?.message||e))}},fe=async()=>{let e=m();if(!(!e||!K()))try{await p.manageUpdateRoomSettings(e,K()),await Z(e)}catch(e){T(String(e?.message||e))}};return r(le,{get children(){return[r(ue,{title:`管理控制台`,description:`统一管理房间、角色与权限。房主全量,管理员/成员/访客基于角色默认值 + 个人覆盖计算生效权限。`,get actions(){return[r(g,{variant:`outline`,class:`gap-1.5`,get children(){return[r(P,{class:`size-3.5`}),t(()=>h.user()?.username||`guest`),` · `,t(()=>_.role())]}}),r(v,{variant:`ghost`,class:`h-9 gap-1.5`,onClick:()=>{J(),Y(),m()&&Z(m())},get children(){return[r(ne,{class:`size-4`}),`刷新`]}})]}}),r(i,{get when(){return w()},get children(){return r(y,{tone:`error`,class:`flex items-center justify-between gap-3`,get children(){return[(()=>{var e=Ge();return o(e,r(N,{class:`size-4`}),null),o(e,w,null),e})(),(()=>{var e=Ke();return e.$$click=()=>T(``),e})()]}})}}),r(ie,{get value(){return e()},onChange:n}),r(i,{get when(){return e()===`overview`},get children(){return r(_e,{get overview(){return a()},get rooms(){return l()}})}}),r(i,{get when(){return e()===`rooms`},get children(){return r(ke,{get rooms(){return l()},get selectedRoom(){return m()},onSelectRoom:b,get members(){return x()},get editingRoom(){return B()},get roomSettings(){return K()},setRoomSettings:q,get newRoom(){return{name:O(),desc:A(),isPublic:M(),max:F(),pwd:L(),showPwd:z()}},setNewRoom:e=>{e.name!==void 0&&k(e.name),e.desc!==void 0&&j(e.desc),e.isPublic!==void 0&&ee(e.isPublic),e.max!==void 0&&I(e.max),e.pwd!==void 0&&R(e.pwd),e.showPwd!==void 0&&te(e.showPwd)},get edit(){return{desc:H(),max:W()}},setEdit:e=>{e.desc!==void 0&&U(e.desc),e.max!==void 0&&G(e.max)},get loading(){return E()},onCreate:re,onSave:ae,onDelete:oe,onChangeRole:se,onKick:ce,onSaveSettings:fe})}}),r(i,{get when(){return e()===`permissions`},get children(){return r(Ve,{get rooms(){return l()},get selectedRoom(){return m()},onSelectRoom:b,get members(){return x()},get permDefs(){return d()},onTogglePerm:de})}}),r(i,{get when(){return e()===`system`},get children(){return r(We,{get overview(){return a()}})}})]}})};x([`click`]);export{qe as Manage};