Files
op-packages/luci-app-honk/root/etc/honk/dashboard/assets/Connections-DAjj-jeW.js
T

4 lines
26 KiB
JavaScript

import{j as s,r as v}from"./vendor-react-Bf71BWbF.js";import{aB as sn,aC as on,aD as ue,aE as le,u as J,as as Be,X as he,_ as fe,ag as z,aF as Z,aG as an,aw as Ie,aH as ln,ax as pe,E as xe,W as se,aI as rn,aJ as cn,O as ie,Q as oe,S as dn,V as ge,aK as we,aL as Ee,aM as me,ah as un,aN as pn,aO as mn,aP as bn,al as je,aQ as hn,aR as Ve,ay as be,av as te,M as fn,I as _e,aS as We,aT as ae,B as O,aU as xn,aV as gn,aW as Ue,aX as wn,$ as He,a1 as Q,a5 as vn,a3 as yn,aY as jn,aZ as _n,a_ as kn,a$ as Nn,b0 as K,b1 as ke,b2 as Cn,N as Mn,a0 as Ln,b3 as Sn,R as Tn,a2 as An,b4 as Pn,b5 as Qe,b6 as Rn,a as Ne,b7 as Dn,b8 as Fn,A as On,T as Ce,b9 as de,ba as Bn,bb as In,at as En,au as Me,bc as Vn}from"./index-zQjLFfuj.js";import{F as Wn}from"./FactStrip-vcLr7nBw.js";import{B as Un,r as Hn}from"./ranked-C_Wt6A1w.js";import{u as Qn,C as Kn,s as Le,a as Gn,p as Se}from"./layout-B3T-zLsm.js";import{D as Jn}from"./Table-DLlwyNFJ.js";import{T as $n}from"./TimeCell-DxlzlVpw.js";import{t as Y,r as Ke,w as Te,a as Xn}from"./link-CaqmdEp1.js";import{c as Ae,d as Yn,e as Zn}from"./files-BxEOxSF8.js";import{D as qn}from"./DaeCode-B4MDdwFy.js";import{u as zn}from"./outbounds-CM0Hhk3q.js";import{u as et}from"./flows-Bv2rvXJX.js";import"./useGridSelectionCheckbox-BK6qtlfZ.js";import"./Virtualizer-CTh266-x.js";import"./ListLayout-DU_9AgrU.js";const H=64,nt=22,X=8,tt=28;function st({label:n,series:t,fmt:e,onSelect:l,regions:c,height:i=260}){const o=sn(),[a,r]=on(),{ref:p,tip:g,show:m,hide:h}=Qn(),w=Math.max(1,...t.flatMap(b=>b.points.flatMap(N=>[N.x,N.y]))),{end:u,ticks:R}=Gn(w),M=Math.max((r??0)-H-tt,1),_=i-X-nt,j=b=>H+Le(b,u)*M,y=b=>X+(1-Le(b,u))*_,D=new Map,k=t.flatMap(b=>b.points.map(N=>{const T=j(N.x),A=y(N.y),F=T+","+A,L=D.get(F)??0;return D.set(F,L+1),{point:N,color:b.color,cx:T,cy:A,nth:L,spot:F}})).map(b=>({...b,twins:D.get(b.spot)}));return s.jsx("div",{className:"rp-scatter",ref:a,children:s.jsxs("div",{className:"rp-chart-hover",ref:p,onPointerLeave:h,children:[r!==null&&s.jsxs("svg",{width:r,height:i,role:"img","aria-label":n,"aria-describedby":o,children:[R.map(b=>s.jsxs("g",{children:[s.jsx("line",{className:"grid",x1:j(b),x2:j(b),y1:X,y2:X+_}),s.jsx("line",{className:"grid",x1:H,x2:H+M,y1:y(b),y2:y(b)}),s.jsx("text",{className:"tick",x:j(b),y:i-6,textAnchor:"middle",children:e(b)}),s.jsx("text",{className:"tick",x:H-8,y:y(b)+4,textAnchor:"end",children:e(b)})]},b)),c&&s.jsxs("g",{className:"diagonal",children:[s.jsx("line",{x1:j(0),y1:y(0),x2:j(u),y2:y(u)}),s.jsx("text",{x:H+8,y:X+14,children:c.above}),s.jsx("text",{x:H+M-8,y:X+_-8,textAnchor:"end",children:c.below})]}),k.map(({point:b,color:N,cx:T,cy:A,nth:F,twins:L})=>{const P=2*Math.PI*F/L,S=L>1?6:0;return s.jsx("circle",{className:l?"pick":void 0,cx:T+S*Math.cos(P),cy:A+S*Math.sin(P),r:5,fill:N,onClick:l?()=>l(b.id):void 0,onPointerMove:E=>m(E,[b.name,b.detail])},b.id)})]}),s.jsx(Kn,{tip:g})]})})}function ot({series:n}){return s.jsx("div",{className:"rp-legend",children:n.map(t=>s.jsx(ue,{swatch:t.color,label:t.label,value:String(t.points.length)},t.id))})}function at(n){const t=new Map;let e=0;for(const o of n){if(o.upload_bytes===null||o.download_bytes===null){e++;continue}const a={id:o.id,up:Number(o.upload_bytes),down:Number(o.download_bytes),name:o.domain||o.dst||o.id},r=t.get(o.outbound);r?r.push(a):t.set(o.outbound,[a])}const l=[...t].map(([o,a])=>({outbound:o,points:a})).sort((o,a)=>le(o.outbound??"",a.outbound??""));let c,i=-1n;for(const o of n){if(o.upload_bytes===null||o.download_bytes===null)continue;const a=BigInt(o.upload_bytes)+BigInt(o.download_bytes);a>i&&(i=a,c={id:o.id,up:Number(o.upload_bytes),down:Number(o.download_bytes),name:o.domain||o.dst||o.id,outbound:o.outbound})}return{series:l,unknown:e,heaviest:c,placed:n.length-e}}const Pe=[0,2,3,1,4,5,6,7],lt=v.memo(function({records:t,outbounds:e,latency:l,latencyError:c,retryLatency:i,truncated:o,onSelect:a}){const r=J(),p=Be(),g=he[fe()],m=v.useCallback(M=>z(M,g),[g]),h=v.useMemo(()=>at(t),[t]),w=v.useMemo(()=>{const M=e.filter(j=>j!=="block"),_=j=>j==="block"?p.negative:p.cat[Pe[Math.max(0,M.indexOf(j))%Pe.length]];return h.series.map(j=>({id:j.outbound??"",label:Z(j.outbound,r),color:_(j.outbound),points:j.points.map(y=>({id:y.id,x:y.up,y:y.down,name:y.name,detail:r("conn.chart.point",{down:m(y.down),up:m(y.up)})}))}))},[h,e,p,r,m]),u=h.heaviest?[{label:r("conn.chart.busiest"),icon:s.jsx(an,{}),tint:"c3",value:h.heaviest.name,caption:Z(h.heaviest.outbound,r)},{label:r("conn.chart.down"),value:m(h.heaviest.down),icon:s.jsx(Ie,{}),tint:"c1"},{label:r("conn.chart.up"),value:m(h.heaviest.up),icon:s.jsx(ln,{}),tint:"c4"}]:[],R=h.unknown?r("conn.chart.sampleUnknown",{n:t.length,unknown:h.unknown}):r("conn.chart.sample",{n:t.length});return s.jsxs("div",{className:"rp-chart-page",children:[s.jsx(Wn,{facts:u,lead:!0}),s.jsxs(pe,{title:r("conn.chart.title"),note:R,children:[o&&s.jsx("p",{className:"rp-note",children:r("conn.truncated")}),h.placed>0&&s.jsxs(s.Fragment,{children:[s.jsx(st,{label:r("conn.chart.title"),series:w,fmt:m,onSelect:a,regions:{above:r("conn.chart.moreDown"),below:r("conn.chart.moreUp")}}),s.jsx(ot,{series:w}),s.jsx("p",{className:"rp-note",children:r("conn.chart.hint")})]})]}),l?s.jsx(it,{latency:l}):c&&s.jsx(pe,{title:r("conn.latency.title"),children:s.jsx(xe,{error:c,onRetry:i})})]})});function it({latency:n}){const t=J(),e=Be(),l=o=>rn(o,t),c=he[fe()],i=o=>!n.chains||o?e.cat[0]:e.muted;return s.jsx(pe,{title:t("conn.latency.title"),note:t("conn.latency.sample",{n:n.samples.length,missing:n.missing}),children:n.samples.length?s.jsxs(s.Fragment,{children:[s.jsx("p",{className:"rp-note",children:t("conn.latency.percentiles",{p50:l(n.p50),p90:l(n.p90)})}),n.weightedP50!==null&&s.jsx("p",{className:"rp-note",children:n.unplaced?t("conn.latency.weightedUnplaced",{p50:l(n.weightedP50),n:n.unplaced}):t("conn.latency.weighted",{p50:l(n.weightedP50)})}),s.jsx(Un,{label:t("conn.latency.title"),points:n.samples.map(o=>({id:o.node,value:o.value,color:i(o.connections>0),lines:[o.name,l(o.value),...o.connections?[t("conn.chart.sample",{n:o.connections})]:[]]})),fmt:l}),n.chains&&s.jsxs("div",{className:"rp-legend",children:[s.jsx(ue,{swatch:i(!0),label:t("conn.latency.inUse"),value:se(n.used,c)}),s.jsx(ue,{swatch:i(!1),label:t("conn.latency.others"),value:se(n.samples.length-n.used,c)})]}),s.jsx("p",{className:"rp-note",children:t("conn.latency.hint")})]}):s.jsx("p",{className:"rp-note",children:t("conn.latency.pending")})})}const Re={userspace:"conn.observed.userspace",ebpf:"conn.observed.ebpf",mixed:"conn.observed.mixed"};function rt(n,t){return[["ui.device",n.src??"—"],["conn.f.dst",n.dst??"—"],["ui.domain",n.domain??"—"],["conn.f.ingress",Te(n.ingress)],["conn.f.domainSource",Te(n.domain_source)],["ui.process",n.pname??"—"],["conn.f.observedBy",Re[n.observed_by]?{key:Re[n.observed_by]}:n.observed_by],["ui.upload",z(n.upload_bytes,t)],["ui.download",z(n.download_bytes,t)],["conn.f.uploadRate",me(n.upload_bytes_per_second,t)],["conn.f.downloadRate",me(n.download_bytes_per_second,t)],["conn.f.started",un(n.started_at,t)]]}const G=[{id:"dst",label:"ui.target",minWidth:200,sortable:!0},{id:"src",label:"ui.device",minWidth:128,sortable:!0,drop:5},{id:"node",label:"conn.node",minWidth:120,drop:3},{id:"rule",label:"conn.rule",minWidth:220,drop:2},{id:"state",label:"ui.state",minWidth:88,sortable:!0,drop:7},{id:"down",label:"ui.download",minWidth:96,align:"end",sortable:!0,drop:4},{id:"downRate",label:"conn.f.downloadRate",minWidth:128,align:"end",sortable:!0,drop:1},{id:"age",label:"ui.started",minWidth:132,align:"end",sortable:!0,drop:6}],De=cn.connectionsView;function Fe(n){const t={hidden:[],sort:null,group:"source"};try{const e=JSON.parse(n??"null");if(!e||typeof e!="object")return t;const l=Array.isArray(e.hidden)?e.hidden.map(o=>o==="chain"?"node":o):[],c=G.filter(o=>l.includes(o.id)).map(o=>o.id),i=e.sort;return{hidden:c.length===G.length?[]:c,sort:i&&G.some(o=>o.sortable&&o.id===i.column)&&["ascending","descending"].includes(i.direction)?{column:i.column,direction:i.direction}:null,group:e.group==="none"||e.group==="outbound"?e.group:"source"}}catch{return t}}function ct(n,t,e){return n.map(l=>({item:l,key:t(l)})).sort((l,c)=>e(l.key,c.key)).map(l=>l.item)}function dt(n,t,e){let l=n;if(t.sort){const{column:i,direction:o}=t.sort;l=ct(n,r=>{switch(i){case"dst":return r.domain||r.dst;case"src":return r.src;case"state":return ge(we,r.state,e);case"down":return je(r.download_bytes);case"downRate":return je(r.download_bytes_per_second);case"age":return r.started_at?Date.parse(r.started_at):null;default:return null}},(r,p)=>{if(r==null)return p==null?0:1;if(p==null)return-1;const g=typeof r=="string"&&typeof p=="string"?le(r,p):r<p?-1:r>p?1:0;return o==="descending"?-g:g})}if(t.group==="none")return l.map(i=>({id:i.id,connection:i}));const c=new Map;for(const i of l){const o=t.group==="source"?ie(i.src??void 0)??i.src??"—":Z(i.outbound,e),a=c.get(o);a?a.push(i):c.set(o,[i])}return[...c].map(([i,o],a)=>({id:a,group:i,children:o,active:o.filter(r=>r.state==="active").length,download:pn(...o.map(r=>r.download_bytes))}))}const Oe=new WeakMap;function ut(n,t,e,l,c,i){const o=a=>{const r=Oe.get(a);if(r&&r.locale===e&&r.names===l&&r.rulesListed===c&&r.t===i)return r.row;const p={id:a.id,target:a.domain||a.dst||"—",source:a.src??"—",node:bn(a,i,l),path:mn(a,i,l),rule:{expression:a.rule_expression,href:Ke(a.rule_id,c)},recomputed:a.rule_source==="recomputed"?i("conn.recomputed"):null,state:ge(we,a.state,i),download:z(a.download_bytes,e),downloadRate:me(a.download_bytes_per_second,e),startedAt:a.started_at};return Oe.set(a,{locale:e,names:l,rulesListed:c,t:i,row:p}),p};return dt(n,t,i).map(a=>"connection"in a?{id:a.id,connection:o(a.connection)}:{id:a.id,group:a.group,children:a.children.map(o),label:i("conn.groupCount",{name:a.group,n:a.children.length}),totals:{down:z(a.download,e),state:i("conn.activeCount",{n:a.active})}})}function pt(n,t,e,l,c,i){const o=a=>{const r=a.flatMap(p=>p?[p]:[]);return Hn(r,12).top};return{networks:[["all",i("ui.allCount",{n:n.length})],["tcp",i("ui.tcp")],["udp",i("ui.udp")]],outbounds:[{id:"all",label:i("conn.allOutbounds")},...[...new Set(n.flatMap(a=>a.outbound?[a.outbound]:[]))].map(a=>({id:a,label:Z(a,i)}))],picks:[{title:i("ui.device"),value:Y("src",e??""),items:o(n.map(a=>ie(a.src))).map(({key:a,count:r})=>({id:Y("src",a),label:a,desc:se(r,c)}))},{title:i("conn.rule"),value:Y("rule",l),items:o(n.map(a=>a.rule_expression)).map(({key:a,count:r})=>({id:Y("rule",a),label:a,desc:se(r,c)}))}],visibility:t&&t.visibility!=="full"?i(t.visibility==="none"?"conn.visibilityNone":"conn.visibilityPartial"):null}}function mt(n,t,e){const[l,c]=n.picks,i=(o,a,r,p)=>({filter:o,label:a,sections:[{title:a,items:r,value:p}]});return{active:[t.network!=="all",t.out!=="all",!!t.src,t.rule!=="all"].filter(Boolean).length,submenus:[i("network",e("ui.network"),n.networks.map(([o,a])=>({id:o,label:a})),t.network),i("out",e("ui.outbound"),n.outbounds,t.out),i("src",l.title,[{id:Y("src",""),label:e("conn.allDevices")},...l.items],l.value),i("rule",c.title,[{id:Y("rule","all"),label:e("conn.allRules")},...c.items],c.value)]}}function bt(n,t,e,l,c){return n?{id:n.id,title:n.domain||n.dst||n.id,tone:n.state==="blocked"||n.state==="failed"?"err":n.state==="active"?"ok":"info",status:e("ui.aside",{text:ge(we,n.state,e),note:n.network.toUpperCase()}),chain:dn(n,e,l),outbound:Z(n.outbound,e),rule:{expression:n.rule_expression,href:Ke(n.rule_id,c)},fields:rt(n,t).map(([i,o])=>[e(i),typeof o=="string"?o:e(o.key,o.params)]),flowQuery:oe("",{tab:"flows",...n.flow_id?{id:n.flow_id}:{connection_id:n.id}}),source:n.src?ie(n.src)??n.src:null,closable:n.state==="active"||n.state==="dialing"||n.state==="routing"}:null}function ht(n,t){return[Ae(["id","target","domain","source","network","state","outbound","chain","rule","upload_bytes","download_bytes","started_at"]),...n.map(e=>Ae([e.id,e.dst,e.domain,e.src,e.network,e.state,e.outbound,Ee(e.chain,t).join(" > "),e.rule_expression,e.upload_bytes,e.download_bytes,e.started_at]))].join(`
`)+`
`}function ft(n,t){const e=n.map(c=>c.id),l=t.bulkLimit!=null&&e.length>t.bulkLimit;return t.narrowed||t.truncated||l?{ids:e}:{ids:e,query:{type:t.network,src:t.src,all:!0}}}const xt=n=>n.target;function gt({collection:n,view:t,loading:e,selected:l,onSelect:c,selectOnFocus:i,onSort:o}){const a=J(),[r,p]=hn(442),g=v.useMemo(()=>{const w={dst:u=>s.jsx(te,{children:u.target}),src:u=>s.jsx(te,{className:"rp-code",children:u.source}),node:u=>s.jsx(te,{className:"rp-chain",text:u.path??void 0,children:u.node}),rule:u=>s.jsxs("span",{className:"rp-rule",children:[s.jsx(Ve,{...u.rule}),u.recomputed&&s.jsx(be,{children:u.recomputed})]}),state:u=>u.state,down:u=>u.download,downRate:u=>u.downloadRate,age:u=>s.jsx($n,{at:u.startedAt})};return G.filter(u=>!t.hidden.includes(u.id)).map(u=>({...u,label:a(u.label),grow:1,render:w[u.id]}))},[t.hidden,a]),m=v.useMemo(()=>n.map(w=>"connection"in w?w.connection:w),[n]),h=v.useMemo(()=>({grouped:t.group!=="none"}),[t.group]);return s.jsx("div",{ref:r,children:s.jsx(Jn,{label:a("nav.connections"),rowDetail:!0,cols:g,rows:m,height:p,selected:l,onSelect:c,selectOnFocus:i,reveal:!0,empty:a("conn.empty"),loading:e,sort:t.sort&&{column:String(t.sort.column),direction:t.sort.direction},onSort:o,getTextValue:xt,stream:!0,tree:h})})}function wt({dialog:n}){const t=J();return s.jsxs(fn,{title:t("rule.add"),narrow:!0,isOpen:!!n,onOpenChange:e=>{e||n?.close()},footer:()=>s.jsxs(s.Fragment,{children:[s.jsx(O,{onPress:()=>n?.close(),children:t("ui.cancel")}),s.jsx(O,{isDisabled:n?.disabled,isPending:n?.busy,onPress:()=>n?.applyNow(),children:t("rule.addApply")}),s.jsx(O,{accent:!0,isDisabled:n?.disabled||n?.busy,onPress:()=>n?.hold(),children:t("rule.hold")})]}),children:[n?.failure&&s.jsx(_e,{takeFocus:!0,children:n.failure.text},n.failure.id),n&&s.jsxs("div",{className:"rp-list",children:[n.failure?.lines.map((e,l)=>s.jsx("span",{className:"rp-label",children:e},l)),s.jsx(xe,{error:n.loadError,onRetry:n.retry}),s.jsx("span",{className:"rp-label",children:t("rule.holdHelp")}),n.targets&&s.jsx(We,{isDisabled:n.busy,label:t("rule.kind"),value:n.target,onChange:n.setTarget,items:n.targets}),s.jsxs("div",{className:"rp-toolbar top",children:[s.jsx(ae,{isDisabled:n.busy,label:t("ui.outbound"),value:n.outbound,onChange:n.setOutbound,items:n.outbounds}),s.jsx(ae,{isDisabled:n.busy||!n.positions.length,label:t("rule.position"),value:n.before,onChange:n.setBefore,items:n.positions})]}),n.moved&&s.jsx(_e,{tone:"informative",children:t("conn.ruleMoved")}),n.unplaceable&&s.jsx("p",{className:"rp-note",children:t("conn.ruleNoPosition")}),s.jsx(qn,{text:n.preview})]})]})}function vt(n,t){if(!t.some(m=>m.health?.length))return null;const e=[];let l=0;for(const m of t){const h=xn(gn(m.health??[]));h===void 0?l++:e.push({node:m.id,name:m.name,value:h,connections:0})}e.sort((m,h)=>m.value-h.value||le(m.name,h.name));const c=new Map(e.map(m=>[m.node,m])),i=n.some(m=>m.chain?.length);let o=0;for(const m of n){const h=m.chain?.at(-1);if(h===void 0)continue;const w=c.get(h);w?w.connections++:o++}const a=e.reduce((m,h)=>m+h.connections,0);let r=0;const p=e.find(m=>(r+=m.connections)>=Math.max(1,Math.ceil(a/2))),g=e.map(m=>m.value);return{samples:e,chains:i,missing:l,unplaced:o,used:e.filter(m=>m.connections).length,p50:Se(g,50),p90:Se(g,90),weightedP50:a?p.value:null}}function yt(n){const t=c=>c.flatMap(([i,o])=>{const a=wn(i,o);return a?[{kind:i,condition:a}]:[]}),e=n.domain?t([["domain",n.domain],["domainSuffix",n.domain]]):[],l=ie(n.dst);return e.length?e:l?t([["dip",l]]):[]}function jt(n,t,e,l){const c=r=>{const p=t.find(g=>g.id===r.source?.source_id);return!!p?.writable&&Ue(p,r)!==null},i=n.find(r=>r.rule_id===e&&c(r)),o=n.find(c),a=r=>r===n[0]?l("conn.ruleTop"):l("rule.positionBefore",{n:r.index+1});return[...i?[{rule:i,label:l("conn.ruleBeforeMatched")}]:[],...o&&o!==i?[{rule:o,label:a(o)}]:[]].map(({rule:r,label:p})=>({id:r.rule_id,label:p,desc:r.expression}))}function _t(n,t,e){if(!t)return{before:n[0]?.id,moved:!1};const l=n.find(c=>c.id===t.rule.rule_id&&(e===t.generation||c.desc===t.rule.expression));return l?{before:l.id,moved:!1}:{before:n[0]?.id,moved:!0}}function kt(n){const t=J(),e=He().data?.resources,l=Q(e,"rules",{whileLoading:!1})&&Q(e,"config",{whileLoading:!1})&&e?.config.writable===!0,[c,i]=v.useState(null),[o,a]=v.useState(null),r=!!c,p=et(r),g=vn(r),m=Q(e,"groups",{whileLoading:!1}),h=yn(r&&m),w=()=>{p.refetch(),g.refetch(),m&&h.refetch()},u=jn(),R=g.data?.sources??[],M=jt(p.data?.rules??[],R,c?.matched??null,t),_=_n(h.data??[]),j=!m||!!h.data,y=c?.outbound||_.find(f=>f.id===c?.current)?.id||(j?_[0].id:""),D=p.data?.generation_id,V=f=>{const C=p.data?.rules.find(W=>W.rule_id===f);return C&&D?{generation:D,rule:C}:null},{before:k,moved:b}=_t(M,c?.pin??null,D),N=c&&!c.pin?V(k):null;N&&i({...c,pin:N});const T=c?.targets[c.target],A=f=>{c&&!u.busy&&i({...c,...f})},F=()=>{u.busy&&(u.cancel(),w()),i(null),a(null)},L=()=>{K("negative",t("rule.stale")),w()},P=()=>{const f=p.data?.rules.find(W=>W.rule_id===k),C=R.find(W=>W.id===f?.source?.source_id);return!T||!f||!C||!Ue(C,f)||p.data?.generation_id!==g.data?.generation_id?(L(),null):(b&&i({...c,pin:V(k)}),{condition:T.condition,outbound:y,must:!1,before:f,sourceId:C.id})},S=()=>{const f=P();f&&(Nn.add(f),K("positive",t("rule.held")),F())},E=async()=>{const f=P();if(!f)return;a(null);const C=await u.apply([{...f,id:0}]);if(C){if(!C.written){a({id:Date.now(),...C.failure});return}K(C.failure?"negative":"positive",C.failure?C.failure.text:t("rule.added")),i(null)}},B=n?yt(n):[];return{canAdd:l&&B.length>0,canShow:Q(e,"rules",{whileLoading:!1})&&!!n?.rule_id,openAdd:()=>{n&&i({targets:B,matched:n.rule_id,current:n.outbound,target:0,outbound:"",pin:null})},dialog:c&&{targets:c.targets.length>1?c.targets.map((f,C)=>[String(C),t(`rule.kind.${f.kind}`)]):null,target:String(c.target),setTarget:f=>A({target:Number(f)}),outbounds:_,outbound:y,setOutbound:f=>A({outbound:f}),positions:M,before:k??"",setBefore:f=>A({pin:V(f)}),preview:T?y?kn(T.condition,y):T.condition:"",busy:u.busy,loadError:p.error??g.error??h.error,retry:w,moved:b,unplaceable:!!p.data&&!!g.data&&!M.length,disabled:!T||!k||!j,failure:o,hold:S,applyNow:()=>void E(),close:F}}}const Ge=["traffic","list"],Je=n=>["id","src","network","out","rule","q"].some(t=>new URLSearchParams(n).has(t))?"list":"traffic",q=(n,t)=>oe(n,Je(n)==="list"?{tab:Qe(n,Ge,"list"),...t}:t);function Nt({go:n,query:t}){const e=J(),l=he[fe()],[c,i]=v.useState(()=>{try{return Fe(localStorage.getItem(De))}catch{return Fe(null)}}),o=ke(Fn),a=ke(Dn),r=d=>{const x={...c,...d};i(x);try{localStorage.setItem(De,JSON.stringify(x))}catch{}},p=v.useMemo(()=>new URLSearchParams(t),[t]),[g,m]=v.useState(p.get("q")??""),h=p.get("network")??"all",w=p.get("out")??"all",u=p.get("rule")??"all",R=(d,x)=>n("connections",q(t,{[d]:x==="all"?null:x})),M=p.get("id"),[_,j]=v.useState(null);Cn(p.get("q"),d=>m(d??""));const y=v.useRef(t);v.useEffect(()=>{y.current=t});const D=d=>n("connections",q(y.current,{id:d})),V=v.useDeferredValue(g),k=Mn(p.get("src")??""),b=Ln(k),N=He(),T=N.data?.resources.connections.can_close===!0,A=Q(N.data?.resources,"rules",{whileLoading:!1}),F=Q(N.data?.resources,"flows",{whileLoading:!1}),L=zn(),P=Sn(b.refetch),S=v.useMemo(()=>Tn(b.data),[b.data]),E=Q(N.data?.resources,"nodes",{whileLoading:!1}),B=An(E),f=v.useMemo(()=>E&&B.data?vt(S,B.data):null,[E,B.data,S]),C=E&&!B.data?B.error:null,W=v.useMemo(()=>[...new Set(S.map(d=>d.outbound))].sort((d,x)=>le(d??"",x??"")),[S]),ee=V.trim().toLowerCase(),$=v.useMemo(()=>S.filter(d=>(h==="all"||d.network===h)&&(w==="all"||d.outbound===w)&&(u==="all"||d.rule_expression===u)&&(!ee||[d.dst,d.domain,d.src,d.pname,Z(d.outbound,e),Ee(d.chain,L).join(" "),d.rule_expression].join(" ").toLowerCase().includes(ee))),[S,h,w,u,ee,L,e]),U=M?S.find(d=>d.id===M):void 0,$e=kt(U),ve=v.useMemo(()=>pt(S,b.data,k,u,l,e),[S,b.data,k,u,l,e]),Xe=v.useMemo(()=>bt(U,l,e,L,A),[U,l,e,L,A]),I={...ve,detail:Xe},Ye=v.useMemo(()=>ut($,c,l,L,A,e),[$,c,l,L,A,e]),Ze=async()=>{if(!I.detail)return;const{id:d}=I.detail;try{if(!await P.close(d))return;new URLSearchParams(y.current).get("id")===d&&D(null),K("positive",e("conn.closed",{name:I.detail.title}))}catch(x){x instanceof On&&x.code==="state_conflict"?K("negative",e("conn.notClosable")):K("negative",e("conn.closeFailed"),{detail:Ne(x,e)})}},qe=async()=>{if(_)try{const d=await P.closeAll(_);if(!d)return;D(null),K(Rn(d),e("conn.closedAll",{closed:d.closed,skipped:d.skipped}))}catch(d){return e("ui.valuePair",{label:e("conn.closeFailed"),value:Ne(d,e)})}},re=d=>{const x=Xn(String(d),["src","rule"]);x?.kind==="src"?(m(""),n("connections",q(t,{src:!x.value||k===x.value?null:x.value,q:null}))):x?.kind==="rule"&&R("rule",u===x.value?"all":x.value)},ye=mt(ve,{network:h,out:w,src:k,rule:u},e),ze={network:d=>R("network",d),out:d=>R("out",d),src:re,rule:re},en={active:ye.active,submenus:ye.submenus.map(({filter:d,...x})=>({...x,sections:x.sections.map(ne=>({...ne,onChange:ze[d]}))}))},ce=Je(t),nn=v.useCallback(d=>n("connections",oe(t,{tab:"list",id:d})),[n,t]);return{...I,tab:Qe(t,Ge,ce),setTab:d=>n("connections",Pn(t,d,ce==="traffic"?ce:null)),openInList:nn,view:c,updateView:r,wide:o,text:g,setText:m,network:h,out:w,sel:M,select:D,collection:Ye,rows:S,outboundKeys:W,latency:f,latencyError:C,retryLatency:B.refetch,setNetwork:d=>R("network",d),setOut:d=>R("out",d),pick:re,compact:a,filterMenu:en,columns:G.map(d=>({id:d.id,label:e(d.label)})),visibleColumns:G.filter(d=>!c.hidden.includes(d.id)).map(d=>d.id),toggleColumn:d=>{const x=String(d),ne=c.hidden.includes(x)?c.hidden.filter(tn=>tn!==x):[...c.hidden,x];ne.length<G.length&&r({hidden:ne})},filtered:h!=="all"||w!=="all"||u!=="all"||!!k||g.trim()!=="",clear:()=>{m(""),n("connections",q(t,{network:null,out:null,rule:null,q:null,src:null}))},error:b.error,retry:b.refetch,loading:b.loading&&!b.data,truncated:!!b.data?.truncated,canClose:T,canViewFlow:F,closeAll:{confirmationText:_?.query?e(_.query.type==="all"?"conn.closeAllLive":_.query.type==="tcp"?"conn.closeAllLiveTcp":"conn.closeAllLiveUdp",k?{n:_.ids.length,src:k}:{n:_.ids.length,src:e("conn.anySource")}):e("conn.closeAllHelp",{n:_?.ids.length??0}),open:!!_,setOpen:d=>j(d?ft($,{network:h,src:k,narrowed:w!=="all"||u!=="all"||!!ee,truncated:!!b.data?.truncated,bulkLimit:N.data?.resources.connections.max_bulk_close}):null),isDisabled:!$.length||!!P.busy||g!==V,isPending:P.busy==="all",onConfirm:qe,onAbort:P.cancel},close:{pending:P.busy===U?.id,disabled:!!P.busy,run:()=>void Ze()},ruleAction:$e,showRule:()=>{U?.rule_id&&n("rules",oe("",{tab:"list",rule:U.rule_id}))},showFlow:()=>{I.detail&&F&&n("rules",I.detail.flowQuery)},onlyClient:()=>{I.detail?.source&&(m(""),n("connections",q(t,{src:I.detail.source,q:null})))},canExport:$.length>0,export:()=>Yn(Zn("connections","csv"),ht($,L),"text/csv;charset=utf-8"),detailTitle:I.detail?.title??"",notInSnapshot:!!M&&!U&&!!b.data}}function Wt(n){const t=J(),e=Nt(n),l=e.detail,c=s.jsxs(s.Fragment,{children:[e.error&&s.jsx(xe,{error:e.error,onRetry:e.retry}),s.jsxs("div",{className:"rp-toolbar",children:[e.compact?s.jsxs("span",{className:"rp-filter-row",children:[s.jsx(Ce,{search:!0,label:t("ui.filter"),value:e.text,onChange:e.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),s.jsx(de,{label:e.filterMenu.active?t("conn.filtersActive",{n:e.filterMenu.active}):t("conn.filters"),count:e.filterMenu.active,submenus:e.filterMenu.submenus,children:t("conn.filters")})]}):s.jsxs(s.Fragment,{children:[s.jsx(Ce,{search:!0,label:t("ui.filter"),value:e.text,onChange:e.setText,placeholder:t("conn.filterHint"),className:"rp-filter"}),s.jsx(We,{label:t("ui.network"),value:e.network,onChange:e.setNetwork,items:e.networks}),s.jsx(ae,{label:t("ui.outbound"),side:!0,value:e.out,onChange:e.setOut,items:e.outbounds}),s.jsx(de,{quiet:!0,label:t("conn.pick"),sections:e.picks,onAction:e.pick,children:t("conn.pick")})]}),s.jsx(ae,{label:t("conn.group"),side:!0,value:e.view.group,onChange:i=>e.updateView({group:i}),items:[{id:"source",label:t("conn.byClient")},{id:"outbound",label:t("ui.outbound")},{id:"none",label:t("conn.ungrouped")}]}),s.jsx(de,{label:t("conn.columns"),selectionMode:"multiple",items:e.columns,value:e.visibleColumns,onAction:e.toggleColumn,children:t("conn.columns")}),e.filtered&&s.jsx(O,{quiet:!0,onPress:e.clear,children:t("ui.clearFilters")}),e.truncated&&s.jsx(be,{tone:"warn",children:t("conn.truncated")}),e.visibility&&s.jsx(te,{text:t("conn.visibilityNote"),children:s.jsx(be,{children:e.visibility})}),s.jsx("span",{className:"rp-grow"}),e.canClose&&s.jsx(Bn,{label:t("conn.closeAll"),...e.closeAll}),s.jsxs(O,{isDisabled:!e.canExport,onPress:e.export,children:[s.jsx(Ie,{}),t("conn.export")]})]}),s.jsxs("div",{className:"rp-with-panel","data-open":l?"":void 0,children:[s.jsx(gt,{collection:e.collection,loading:e.loading,selected:e.sel,onSelect:e.select,selectOnFocus:e.wide,view:e.view,onSort:i=>e.updateView({sort:i})}),s.jsx(In,{open:!!l,title:e.detailTitle,onClose:()=>e.select(null),children:l&&s.jsxs(s.Fragment,{children:[s.jsx(En,{small:!0,tone:l.tone,children:l.status}),s.jsxs("div",{className:"rp-cluster",children:[s.jsxs("div",{className:"rp-cluster",children:[e.ruleAction.canAdd&&s.jsx(O,{onPress:e.ruleAction.openAdd,children:t("rule.add")}),e.ruleAction.canShow&&s.jsx(O,{onPress:e.showRule,children:t("conn.showRule")}),e.canViewFlow&&s.jsx(O,{onPress:e.showFlow,children:t("conn.viewFlow")}),l.source&&s.jsx(O,{onPress:e.onlyClient,children:t("conn.onlyThisClient")})]}),e.canClose&&l.closable&&s.jsx(O,{negative:!0,quiet:!0,isPending:e.close.pending,isDisabled:e.close.disabled,onPress:e.close.run,children:t("conn.close")})]}),s.jsx(Me,{items:l.fields}),s.jsx(Me,{items:[[t("ui.outbound"),l.outbound],[t("conn.chain"),l.chain]]}),s.jsxs("div",{className:"rp-list",children:[s.jsx("span",{className:"rp-label",children:t("conn.rule")}),s.jsx(Ve,{...l.rule})]})]})})]}),e.notInSnapshot&&s.jsx("span",{className:"rp-label",children:t("conn.notInSnapshot")}),s.jsx(wt,{dialog:e.ruleAction.dialog})]});return s.jsx("div",{className:"rp-page",children:s.jsx(Vn,{keepMounted:!0,label:t("nav.connections"),value:e.tab,onChange:e.setTab,items:[{id:"traffic",label:t("conn.tab.traffic"),content:s.jsx(lt,{records:e.rows,outbounds:e.outboundKeys,latency:e.latency,latencyError:e.latencyError,retryLatency:e.retryLatency,truncated:e.truncated,onSelect:e.openInList})},{id:"list",label:t("conn.tab.list"),content:c}]})})}export{Wt as Connections};