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