qBitrr2 5.4.1__tar.gz → 5.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qbitrr2-5.4.1/qBitrr2.egg-info → qbitrr2-5.4.3}/PKG-INFO +1 -1
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/pyproject.toml +1 -1
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/bundled_data.py +2 -2
- qbitrr2-5.4.3/qBitrr/static/assets/ArrView.js +2 -0
- qbitrr2-5.4.3/qBitrr/static/assets/ArrView.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/ConfigView.js +4 -0
- qbitrr2-5.4.3/qBitrr/static/assets/ConfigView.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/LogsView.js +230 -0
- qbitrr2-5.4.3/qBitrr/static/assets/LogsView.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/ProcessesView.js +2 -0
- qbitrr2-5.4.3/qBitrr/static/assets/ProcessesView.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/app.css +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/app.js +11 -0
- qbitrr2-5.4.3/qBitrr/static/assets/app.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/build.svg +3 -0
- qbitrr2-5.4.3/qBitrr/static/assets/check-mark.svg +5 -0
- qbitrr2-5.4.3/qBitrr/static/assets/close.svg +4 -0
- qbitrr2-5.4.3/qBitrr/static/assets/download.svg +5 -0
- qbitrr2-5.4.3/qBitrr/static/assets/gear.svg +5 -0
- qbitrr2-5.4.3/qBitrr/static/assets/lidarr.svg +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/live-streaming.svg +8 -0
- qbitrr2-5.4.3/qBitrr/static/assets/log.svg +3 -0
- qbitrr2-5.4.3/qBitrr/static/assets/plus.svg +4 -0
- qbitrr2-5.4.3/qBitrr/static/assets/process.svg +15 -0
- qbitrr2-5.4.3/qBitrr/static/assets/react-select.esm.js +14 -0
- qbitrr2-5.4.3/qBitrr/static/assets/react-select.esm.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/refresh-arrow.svg +3 -0
- qbitrr2-5.4.3/qBitrr/static/assets/table.js +23 -0
- qbitrr2-5.4.3/qBitrr/static/assets/table.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/trash.svg +8 -0
- qbitrr2-5.4.3/qBitrr/static/assets/up-arrow.svg +3 -0
- qbitrr2-5.4.3/qBitrr/static/assets/useInterval.js +2 -0
- qbitrr2-5.4.3/qBitrr/static/assets/useInterval.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/vendor.js +33 -0
- qbitrr2-5.4.3/qBitrr/static/assets/vendor.js.map +1 -0
- qbitrr2-5.4.3/qBitrr/static/assets/visibility.svg +9 -0
- qbitrr2-5.4.3/qBitrr/static/index.html +47 -0
- qbitrr2-5.4.3/qBitrr/static/manifest.json +23 -0
- qbitrr2-5.4.3/qBitrr/static/sw.js +105 -0
- qbitrr2-5.4.3/qBitrr/static/vite.svg +1 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/webui.py +7 -3
- {qbitrr2-5.4.1 → qbitrr2-5.4.3/qBitrr2.egg-info}/PKG-INFO +1 -1
- qbitrr2-5.4.3/qBitrr2.egg-info/SOURCES.txt +68 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/setup.cfg +1 -1
- qbitrr2-5.4.1/qBitrr2.egg-info/SOURCES.txt +0 -31
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/LICENSE +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/MANIFEST.in +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/README.md +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/config.example.toml +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/__init__.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/arss.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/auto_update.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/config.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/db_lock.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/env_config.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/errors.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/ffprobe.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/gen_config.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/home_path.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/logger.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/main.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/search_activity_store.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/tables.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/utils.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr/versioning.py +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr2.egg-info/dependency_links.txt +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr2.egg-info/entry_points.txt +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr2.egg-info/requires.txt +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/qBitrr2.egg-info/top_level.txt +0 -0
- {qbitrr2-5.4.1 → qbitrr2-5.4.3}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qBitrr2
|
|
3
|
-
Version: 5.4.
|
|
3
|
+
Version: 5.4.3
|
|
4
4
|
Summary: Intelligent automation for qBittorrent and *Arr apps (Radarr/Sonarr/Lidarr) - health monitoring, instant imports, quality upgrades, request integration
|
|
5
5
|
Home-page: https://github.com/Feramance/qBitrr
|
|
6
6
|
Author: Feramance
|
|
@@ -28,7 +28,7 @@ target-version = ['py312']
|
|
|
28
28
|
|
|
29
29
|
[tool.poetry]
|
|
30
30
|
name = "pypi-public"
|
|
31
|
-
version = "5.4.
|
|
31
|
+
version = "5.4.3"
|
|
32
32
|
description = "Intelligent automation for qBittorrent and *Arr apps (Radarr/Sonarr/Lidarr) - health monitoring, instant imports, quality upgrades, request integration"
|
|
33
33
|
authors = ["Drapersniper", "Feramance"]
|
|
34
34
|
readme = "README.md"
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as e,u as ts,h as ns,i as ls,k as is,l as Ge,m as rs,I as Oe,R as Ve,n as Ye,o as Je}from"./app.js";import{r as s,u as Ie,g as _e,f as Ce,a as os,b as js,c as ps}from"./table.js";import{u as Ee}from"./useInterval.js";import"./vendor.js";function Ns({data:r,columns:t,getRowKey:c}){const g=Ie({data:r,columns:t,getCoreRowModel:_e()});return e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:g.getHeaderGroups().map(x=>e.jsx("tr",{children:x.headers.map(p=>e.jsx("th",{children:p.isPlaceholder?null:Ce(p.column.columnDef.header,p.getContext())},p.id))},x.id))}),e.jsx("tbody",{children:g.getRowModel().rows.map(x=>{const p=c?c(x.original):x.id;return e.jsx("tr",{children:x.getVisibleCells().map(M=>e.jsx("td",{"data-label":String(M.column.columnDef.header),children:Ce(M.column.columnDef.cell,M.getContext())},M.id))},p)})})]})})}const vs=s.memo(Ns,(r,t)=>r.data===t.data&&r.columns===t.columns);function ys(r){let t=2166136261;for(let c=0;c<r.length;c++)t^=r.charCodeAt(c),t+=(t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24);return(t>>>0).toString(36)}function as(r,t){const c=t.map(g=>{const x=r[g];return x==null?"":typeof x=="boolean"?x?"1":"0":typeof x=="object"?JSON.stringify(x):String(x)});return ys(c.join("|"))}function Ss(r,t,c,g){const x=[],p=[],M=[],w=new Set;for(const n of t){const S=c(n),f=as(n,g);w.add(S);const k=r.byId.get(S),z=r.byHash.get(S);k?z!==f&&p.push(n):x.push(n)}for(const n of r.allIds)w.has(n)||M.push(n);const b=t.length-x.length-p.length,P=x.length>0||p.length>0||M.length>0;return{added:x,updated:p,removed:M,unchanged:b,hasChanges:P}}function Rs(r,t,c,g){if(!t.hasChanges)return r;const x=new Map(r.byId),p=new Map(r.byHash),M=[...r.allIds];for(const w of t.added){const b=c(w),P=as(w,g);x.set(b,w),p.set(b,P),M.push(b)}for(const w of t.updated){const b=c(w),P=as(w,g);x.set(b,w),p.set(b,P)}for(const w of t.removed){x.delete(w),p.delete(w);const b=M.indexOf(w);b!==-1&&M.splice(b,1)}return{byId:x,byHash:p,allIds:M,lastUpdate:Date.now()}}function Xe(r){return r.allIds.map(t=>r.byId.get(t)).filter(Boolean)}function gs(){return{byId:new Map,byHash:new Map,allIds:[],lastUpdate:0}}function Le(r){const{getKey:t,hashFields:c}=r,g=s.useRef(gs()),[x,p]=s.useState(0),M=s.useCallback(P=>{const n=Ss(g.current,P,t,c);if(!n.hasChanges)return{data:Xe(g.current),hasChanges:!1,changes:null,lastUpdate:g.current.lastUpdate};const S=Rs(g.current,n,t,c);return g.current=S,p(S.lastUpdate),{data:Xe(S),hasChanges:!0,changes:n,lastUpdate:S.lastUpdate}},[t,c]),w=s.useCallback(()=>Xe(g.current),[]),b=s.useCallback(()=>{g.current=gs(),p(0)},[]);return{syncData:M,getData:w,reset:b,lastUpdate:x}}const qe=50,He=50,hs=500,Cs=s.memo(function({loading:t,rows:c,total:g,page:x,totalPages:p,onPageChange:M,onRefresh:w,lastUpdated:b,sort:P,onSort:n,summary:S,instanceCount:f,isAggFiltered:k=!1}){const z=s.useMemo(()=>[...f>1?[{accessorKey:"__instance",header:"Instance",size:150}]:[],{accessorKey:"title",header:"Title",cell:D=>D.getValue()},{accessorKey:"year",header:"Year",size:80},{accessorKey:"monitored",header:"Monitored",cell:D=>{const Q=D.getValue();return e.jsx("span",{className:`track-status ${Q?"available":"missing"}`,children:Q?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:D=>{const Q=D.getValue();return e.jsx("span",{className:`track-status ${Q?"available":"missing"}`,children:Q?"✓":"✗"})},size:100},{accessorKey:"reason",header:"Reason",cell:D=>{const Q=D.getValue();return Q?e.jsx("span",{className:"table-badge table-badge-reason",children:Q}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[f]);return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated movies across all instances"," ",b?`(updated ${b})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",S.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",S.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",S.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",S.total.toLocaleString(void 0,{maximumFractionDigits:0}),k&&g<S.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",g.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",S.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:w,disabled:t,children:[e.jsx(Oe,{src:Ve}),"Refresh"]})]}),t?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Radarr library…"]}):g?e.jsx(vs,{data:c,columns:z,getRowKey:D=>`${D.__instance}-${D.title}-${D.year}`}):e.jsx("div",{className:"hint",children:"No movies found."}),g>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",x+1," of ",p," (",g.toLocaleString()," items · page size"," ",He,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>M(Math.max(0,x-1)),disabled:x===0||t,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>M(Math.min(p-1,x+1)),disabled:x>=p-1||t,children:"Next"})]})]})]})}),ws=s.memo(function({loading:t,data:c,page:g,totalPages:x,pageSize:p,allMovies:M,onlyMissing:w,reasonFilter:b,onPageChange:P,onRefresh:n,onRestart:S,lastUpdated:f}){const k=s.useMemo(()=>{let y=M;return w&&(y=y.filter(C=>!C.hasFile)),y},[M,w]),z=s.useMemo(()=>b==="all"?k:b==="Not being searched"?k.filter(y=>y.reason==="Not being searched"||!y.reason):k.filter(y=>y.reason===b),[k,b]),D=s.useMemo(()=>M.length,[M]),Q=b!=="all",ee=z.length,I=s.useMemo(()=>[{accessorKey:"title",header:"Title",cell:y=>y.getValue()},{accessorKey:"year",header:"Year",size:80},{accessorKey:"monitored",header:"Monitored",cell:y=>{const C=y.getValue();return e.jsx("span",{className:`track-status ${C?"available":"missing"}`,children:C?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:y=>{const C=y.getValue();return e.jsx("span",{className:`track-status ${C?"available":"missing"}`,children:C?"✓":"✗"})},size:100},{accessorKey:"reason",header:"Reason",cell:y=>{const C=y.getValue();return C?e.jsx("span",{className:"table-badge table-badge-reason",children:C}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[]),R=Ie({data:z.slice(g*p,g*p+p),columns:I,getCoreRowModel:_e(),getSortedRowModel:os()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[c?.counts?`Available: ${c.counts.available??0} • Monitored: ${c.counts.monitored??0}`:"",f?` (updated ${f})`:"",Q&&D>0&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",ee.toLocaleString()," of"," ",D.toLocaleString()]})]}),e.jsxs("button",{className:"btn ghost",onClick:S,disabled:t,children:[e.jsx(Oe,{src:Ve}),"Restart"]})]}),t?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading…"]}):M.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:R.getHeaderGroups().map(y=>e.jsx("tr",{children:y.headers.map(C=>e.jsx("th",{children:C.isPlaceholder?null:Ce(C.column.columnDef.header,C.getContext())},C.id))},y.id))}),e.jsx("tbody",{children:R.getRowModel().rows.map(y=>{const C=y.original,l=`${C.title}-${C.year}`;return e.jsx("tr",{children:y.getVisibleCells().map(u=>e.jsx("td",{"data-label":String(u.column.columnDef.header),children:Ce(u.column.columnDef.cell,u.getContext())},u.id))},l)})})]})}):e.jsx("div",{className:"hint",children:"No movies found."}),z.length>p&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",g+1," of ",x," (",z.length.toLocaleString()," items · page size"," ",p,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>P(Math.max(0,g-1)),disabled:g===0||t,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>P(Math.min(x-1,g+1)),disabled:g>=x-1||t,children:"Next"})]})]})]})});function Fs({active:r}){const{push:t}=ts(),{value:c,setValue:g,register:x,clearHandler:p}=ns(),{liveArr:M,setLiveArr:w}=ls(),[b,P]=s.useState([]),[n,S]=s.useState(""),[f,k]=s.useState(null),[z,D]=s.useState(0),[Q,ee]=s.useState(""),[I,R]=s.useState(!1),[y,C]=s.useState(null),[l,u]=s.useState({}),[h,U]=s.useState(qe),[K,B]=s.useState(1),d=s.useRef(""),$=s.useRef({}),A=s.useRef(c),G=s.useRef(!1),Y=Le({getKey:i=>`${i.title}-${i.year}`,hashFields:["title","year","hasFile","monitored","reason"]}),[te,J]=s.useState([]),[ce,je]=s.useState(!1),[pe,fe]=s.useState(0),[Ne,ve]=s.useState(""),[oe,we]=s.useState(null),ye=Le({getKey:i=>`${i.__instance}-${i.title}-${i.year}`,hashFields:["__instance","title","year","hasFile","monitored","reason"]}),[xe,Pe]=s.useState({key:"__instance",direction:"asc"}),[Ae,Se]=s.useState(!1),[q,de]=s.useState("all"),[re,me]=s.useState({available:0,monitored:0,missing:0,total:0}),he=s.useCallback(async()=>{try{const i=await is();i.ready===!1&&!G.current?(G.current=!0,t("Radarr backend is still initialising. Check the logs if this persists.","info")):i.ready&&(G.current=!0);const j=(i.arr||[]).filter(N=>N.type==="radarr");if(P(j),!j.length){S("aggregate"),k(null),J([]),me({available:0,monitored:0,missing:0,total:0});return}n===""?S(j.length===1?j[0].category:"aggregate"):n!=="aggregate"&&!j.some(N=>N.category===n)&&S(j[0].category)}catch(i){t(i instanceof Error?i.message:"Unable to load Radarr instances","error")}},[t,n]),Re=s.useCallback(async(i,j,N,T,E)=>{if(T.length)try{const V=[];for(const _ of T){const F=await Ge(i,_,N,j),L=F.page??_;if(V.push({page:L,movies:F.movies??[]}),d.current!==E)return}if(d.current!==E)return;u(_=>{const F={..._};let L=!1;for(const{page:W,movies:ne}of V){const se=Y.syncData(ne);se.hasChanges&&(F[W]=se.data,L=!0)}return $.current=F,L?F:_})}catch(V){t(V instanceof Error?V.message:`Failed to load additional pages for ${i}`,"error")}},[t]),ge=s.useCallback(async(i,j,N,T={})=>{const E=T.preloadAll!==!1;(T.showLoading??!0)&&R(!0);try{const _=`${i}::${N}`,F=d.current!==_;F&&(d.current=_,u(()=>($.current={},{})));const L=await Ge(i,j,qe,N);k(L);const W=L.page??j;D(W),ee(N);const ne=L.page_size??qe,se=L.total??(L.movies??[]).length,H=Math.max(1,Math.ceil((se||0)/ne));U(ne),B(H);const X=L.movies??[],Z=F?{}:$.current,ae=Y.syncData(X),ke=ae.hasChanges;if(F&&Y.reset(),(F||ke)&&(u(ue=>{const le={...F?{}:ue,[W]:ae.data};return $.current=le,le}),C(new Date().toLocaleTimeString())),E){const ue=[];for(let O=0;O<H;O+=1)O!==W&&(Z[O]||ue.push(O));Re(i,N,ne,ue,_)}}catch(_){t(_ instanceof Error?_.message:`Failed to load ${i} movies`,"error")}finally{R(!1)}},[t,Re]),ie=s.useCallback(async i=>{if(!b.length){J([]),me({available:0,monitored:0,missing:0,total:0});return}(i?.showLoading??!0)&&je(!0);try{const N=[];let T=0,E=0;for(const W of b){let ne=0,se=!1;const H=W.name||W.category;for(;ne<100;){const X=await Ge(W.category,ne,hs,"");if(!se){const ae=X.counts;ae&&(T+=ae.available??0,E+=ae.monitored??0),se=!0}const Z=X.movies??[];if(Z.forEach(ae=>{N.push({...ae,__instance:H})}),!Z.length||Z.length<hs)break;ne+=1}}const V=ye.syncData(N),_=V.hasChanges;_&&J(V.data);const F={available:T,monitored:E,missing:N.length-T,total:N.length},L=re.available!==F.available||re.monitored!==F.monitored||re.missing!==F.missing||re.total!==F.total;L&&me(F),Ne!==c&&(fe(0),ve(c)),(_||L)&&we(new Date().toLocaleTimeString())}catch(N){J([]),me({available:0,monitored:0,missing:0,total:0}),t(N instanceof Error?N.message:"Failed to load aggregated Radarr data","error")}finally{je(!1)}},[b,c,t,Ne]);s.useEffect(()=>{r&&he()},[r,he]),s.useEffect(()=>{if(!r||!n||n==="aggregate")return;$.current={},u({}),B(1),D(0);const i=A.current;ge(n,0,i,{preloadAll:!0,showLoading:!0})},[r,n,ge]),s.useEffect(()=>{r&&n==="aggregate"&&ie()},[r,n,ie]),Ee(()=>{n==="aggregate"&&M&&ie({showLoading:!1})},n==="aggregate"&&M?1e4:null),s.useEffect(()=>{if(!r)return;const i=j=>{n==="aggregate"?(ve(j),fe(0)):n&&(D(0),ge(n,0,j,{preloadAll:!0,showLoading:!0}))};return x(i),()=>{p(i)}},[r,n,x,p,ge]),Ee(()=>{if(n&&n!=="aggregate"){if(A.current?.trim?.()||"")return;ge(n,z,Q,{preloadAll:!1,showLoading:!1})}},r&&n&&n!=="aggregate"&&M?1e3:null),s.useEffect(()=>{A.current=c},[c]),s.useEffect(()=>{n==="aggregate"&&ve(c)},[n,c]);const be=s.useMemo(()=>{let i=te;if(Ne){const j=Ne.toLowerCase();i=i.filter(N=>{const T=(N.title??"").toString().toLowerCase(),E=(N.__instance??"").toLowerCase();return T.includes(j)||E.includes(j)})}return Ae&&(i=i.filter(j=>!j.hasFile)),q!=="all"&&(q==="Not being searched"?i=i.filter(j=>j.reason==="Not being searched"||!j.reason):i=i.filter(j=>j.reason===q)),i},[te,Ne,Ae,q]),Te=!!Ne||q!=="all",Me=s.useMemo(()=>{const i=[...be],j=(N,T)=>{switch(T){case"__instance":return(N.__instance||"").toLowerCase();case"title":return(N.title||"").toLowerCase();case"year":return N.year??0;case"monitored":return N.monitored?1:0;case"hasFile":return N.hasFile?1:0;default:return""}};return i.sort((N,T)=>{const E=j(N,xe.key),V=j(T,xe.key);let _=0;return typeof E=="number"&&typeof V=="number"?_=E-V:typeof E=="string"&&typeof V=="string"?_=E.localeCompare(V):_=String(E).localeCompare(String(V)),xe.direction==="asc"?_:-_}),i},[be,xe]),Fe=Math.max(1,Math.ceil(Me.length/He)),ze=s.useMemo(()=>Me.slice(pe*He,pe*He+He),[Me,pe]),Ke=s.useMemo(()=>{const i=Object.keys(l).map(Number).sort((N,T)=>N-T),j=[];return i.forEach(N=>{l[N]&&j.push(...l[N])}),j},[l]),Ue=s.useCallback(async()=>{if(!(!n||n==="aggregate"))try{await rs(n),t(`Restarted ${n}`,"success")}catch(i){t(i instanceof Error?i.message:`Failed to restart ${n}`,"error")}},[n,t]),De=s.useCallback(()=>{ie({showLoading:!0})},[ie]),o=s.useCallback(i=>{Pe(j=>j.key===i?{key:i,direction:j.direction==="asc"?"desc":"asc"}:{key:i,direction:"asc"})},[]),a=s.useCallback(()=>{n&&n!=="aggregate"&&ge(n,z,Q,{preloadAll:!1,showLoading:!0})},[n,z,Q,ge]),m=s.useCallback(i=>{const j=i.target.value||"aggregate";S(j),j!=="aggregate"&&g("")},[S,g]),v=n==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Radarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[b.length>1&&e.jsx("button",{className:`btn ${v?"active":""}`,onClick:()=>S("aggregate"),children:"All Radarr"}),b.map(i=>e.jsx("button",{className:`btn ghost ${n===i.category?"active":""}`,onClick:()=>{S(i.category),g("")},children:i.name||i.category},i.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:n||"aggregate",onChange:m,disabled:!b.length,children:[b.length>1&&e.jsx("option",{value:"aggregate",children:"All Radarr"}),b.map(i=>e.jsx("option",{value:i.category,children:i.name||i.category},i.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter movies",value:c,onChange:i=>g(i.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:i=>{const j=i.target.value;Se(j==="missing")},value:Ae?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Movies"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:i=>de(i.target.value),value:q,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),v?e.jsx(Cs,{loading:ce,rows:ze,total:Me.length,page:pe,totalPages:Fe,onPageChange:fe,onRefresh:De,lastUpdated:oe,sort:xe,onSort:o,summary:re,instanceCount:b.length,isAggFiltered:Te}):e.jsx(ws,{loading:I,data:f,page:z,totalPages:K,pageSize:h,allMovies:Ke,onlyMissing:Ae,reasonFilter:q,onPageChange:i=>{D(i),ge(n,i,Q,{preloadAll:!0})},onRefresh:a,onRestart:()=>void Ue(),lastUpdated:y})]})]})})]})}const es=25,Qe=50,us=200;function As(r,t){if(!t)return r;const c=[];for(const g of r){const x=g.seasons??{},p={};for(const[M,w]of Object.entries(x)){const b=(w.episodes??[]).filter(P=>!P.hasFile);b.length&&(p[M]={...w,episodes:b})}Object.keys(p).length!==0&&c.push({...g,seasons:p})}return c}function Be(r,t){return JSON.stringify(As(r,t))}function Ms({active:r}){const{push:t}=ts(),{value:c,setValue:g,register:x,clearHandler:p}=ns(),{liveArr:M,setLiveArr:w,groupSonarr:b,setGroupSonarr:P}=ls(),[n,S]=s.useState([]),[f,k]=s.useState("aggregate"),[z,D]=s.useState(null),[Q,ee]=s.useState(0),[I,R]=s.useState(""),[y,C]=s.useState(!1),[l,u]=s.useState(null),[h,U]=s.useState({}),K=s.useRef({}),B=s.useRef(null),d=s.useRef(""),[$,A]=s.useState(es),[G,Y]=s.useState(1),[te,J]=s.useState(0),ce=s.useRef(c),je=s.useRef(!1),[pe,fe]=s.useState([]),[Ne,ve]=s.useState(!1),[oe,we]=s.useState(0),[ye,xe]=s.useState(""),[Pe,Ae]=s.useState(null),Se=Le({getKey:a=>`${a.__instance}-${a.series}-${a.season}-${a.episode}`,hashFields:["__instance","series","season","episode","title","hasFile","monitored","airDate","reason"]}),[q,de]=s.useState(!1),[re,me]=s.useState("all"),[he,Re]=s.useState({available:0,monitored:0,missing:0,total:0}),ge=s.useCallback(async()=>{try{const a=await is();a.ready===!1&&!je.current?(je.current=!0,t("Sonarr backend is still initialising. Check the logs if this persists.","info")):a.ready&&(je.current=!0);const m=(a.arr||[]).filter(v=>v.type==="sonarr");if(S(m),!m.length){k("aggregate"),D(null),fe([]),Re({available:0,monitored:0,missing:0,total:0});return}f===""?k(m.length===1?m[0].category:"aggregate"):f!=="aggregate"&&!m.some(v=>v.category===f)&&k(m[0].category)}catch(a){t(a instanceof Error?a.message:"Unable to load Sonarr instances","error")}},[t,f]),ie=s.useCallback(async(a,m,v,i={})=>{const{preloadAll:j=!0,showLoading:N=!0,missingOnly:T}=i,E=T??q;N&&C(!0);try{const V=`${a}::${v}::${E?"missing":"all"}`,_=d.current!==V;_&&(d.current=V,U(()=>(K.current={},{})),J(0),Y(1));const F=await Ye(a,m,es,v,{missingOnly:E});console.log(`[Sonarr Instance] Response for ${a} page ${m}:`,{total:F.total,page:F.page,page_size:F.page_size,series_count:F.series?.length??0,counts:F.counts,missingOnly:E,firstSeries:F.series?.[0]?{title:F.series[0].series?.title,seasonsCount:Object.keys(F.series[0].seasons??{}).length,firstSeasonEpisodes:Object.values(F.series[0].seasons??{})[0]?.episodes?.length??0}:null});const L=F.page??m,W=F.page_size??es,ne=F.total??(F.series??[]).length,se=Math.max(1,Math.ceil((ne||0)/W)),H=F.series??[],X=_?{}:K.current,Z={...X,[L]:H},ae=Be(X[L]??[],E),ke=Be(H,E),ue=_||ae!==ke;if(K.current=Z,ue&&U(Z),D(O=>{const le=O?.counts??null,$e=F.counts??null;return!O||O.total!==F.total||O.page!==F.page||O.page_size!==F.page_size||(le?.available??null)!==($e?.available??null)||(le?.monitored??null)!==($e?.monitored??null)||(le?.missing??null)!==($e?.missing??null)||ue?(B.current=F,F):O}),ee(O=>O===L?O:L),R(O=>O===v?O:v),A(O=>O===W?O:W),Y(O=>O===se?O:se),J(O=>O===ne?O:ne),ue&&u(new Date().toLocaleTimeString()),j){const O=[];for(let le=0;le<se;le+=1)le!==L&&(Z[le]||O.push(le));for(const le of O)try{const $e=await Ye(a,le,W,v,{missingOnly:E});if(d.current!==V)break;const We=$e.page??le,Ze=$e.series??[],cs=K.current,bs=Be(cs[We]??[],E),fs=Be(Ze,E);if(bs===fs){K.current={...cs,[We]:Ze};continue}U(xs=>{const ds={...xs,[We]:Ze};return K.current=ds,ds})}catch{break}}}catch(V){t(V instanceof Error?V.message:`Failed to load ${a} series`,"error")}finally{N&&C(!1)}},[t,q]),be=s.useCallback(async a=>{if(!n.length){fe([]),Re({available:0,monitored:0,missing:0,total:0});return}console.log(`[Sonarr Aggregate] Starting aggregation for ${n.length} instances`),(a?.showLoading??!0)&&ve(!0);try{const v=[];let i=0,j=0,N=0;for(const L of n){let W=0,ne=!1;const se=L.name||L.category;for(console.log(`[Sonarr Aggregate] Processing instance: ${se}`);W<200;){const H=await Ye(L.category,W,us,"",{missingOnly:q});if(console.log(`[Sonarr Aggregate] Response for ${se} page ${W}:`,{total:H.total,page:H.page,page_size:H.page_size,series_count:H.series?.length??0,counts:H.counts,missingOnly:q,firstSeries:H.series?.[0]?{title:H.series[0].series?.title,seasonsCount:Object.keys(H.series[0].seasons??{}).length,firstSeasonEpisodes:Object.values(H.series[0].seasons??{})[0]?.episodes?.length??0,firstEpisode:Object.values(H.series[0].seasons??{})[0]?.episodes?.[0]}:null}),!ne){const ae=H.counts;ae&&(i+=ae.available??0,j+=ae.monitored??0,N+=ae.missing??0),ne=!0}const X=H.series??[];let Z=0;if(X.forEach(ae=>{const ke=Object.keys(ae.seasons??{}).length;let ue=0;Object.values(ae.seasons??{}).forEach(O=>{ue+=(O.episodes??[]).length}),Z+=ue}),console.log(`[Sonarr Aggregate] Instance: ${se}, Page: ${W}, Series count: ${X.length}, Total episodes so far: ${v.length}, Episodes in this response: ${Z}`),X.forEach(ae=>{const ke=ae.series?.title||"";Object.entries(ae.seasons??{}).forEach(([ue,O])=>{(O.episodes??[]).forEach(le=>{const $e=le.reason??null;v.push({__instance:se,series:ke,season:ue,episode:le.episodeNumber??"",title:le.title??"",monitored:!!le.monitored,hasFile:!!le.hasFile,airDate:le.airDateUtc??"",reason:$e})})})}),!X.length||X.length<us){console.log(`[Sonarr Aggregate] Breaking pagination for ${se} - series.length=${X.length}`);break}W+=1}}const T=Se.syncData(v),E=T.hasChanges,V=new Map;v.forEach(L=>{const W=L.reason||"null/empty";V.set(W,(V.get(W)||0)+1)}),console.log("[Sonarr Aggregate] Reason distribution:",Object.fromEntries(V)),E?(console.log(`[Sonarr Aggregate] Data changed, updating from ${pe.length} to ${v.length} episodes`),fe(T.data)):console.log("[Sonarr Aggregate] Data unchanged, skipping update");const _={available:i,monitored:j,missing:N,total:v.length},F=he.available!==_.available||he.monitored!==_.monitored||he.missing!==_.missing||he.total!==_.total;F&&Re(_),ye!==c&&(we(0),xe(c)),(E||F)&&Ae(new Date().toLocaleTimeString())}catch(v){fe([]),Re({available:0,monitored:0,missing:0,total:0}),t(v instanceof Error?v.message:"Failed to load aggregated Sonarr data","error")}finally{ve(!1)}},[n,c,t,q,ye]);s.useEffect(()=>{r&&ge()},[r,ge]),s.useEffect(()=>{if(!r||!f||f==="aggregate")return;ee(0);const a=ce.current;ie(f,0,a,{preloadAll:!0,showLoading:!0,missingOnly:q})},[r,f,ie]),s.useEffect(()=>{r&&f==="aggregate"&&be()},[r,f,be]),Ee(()=>{f==="aggregate"&&M&&be({showLoading:!1})},f==="aggregate"&&M?1e4:null),s.useEffect(()=>{if(!r)return;const a=m=>{f==="aggregate"?(xe(m),we(0)):f&&(ee(0),ie(f,0,m,{preloadAll:!0,showLoading:!0,missingOnly:q}))};return x(a),()=>p(a)},[r,f,x,p,ie,q]),Ee(()=>{if(f&&f!=="aggregate"){if(ce.current?.trim?.()||"")return;ie(f,Q,I,{preloadAll:!1,showLoading:!1,missingOnly:q})}},r&&f&&f!=="aggregate"&&M?1e3:null),s.useEffect(()=>{ce.current=c},[c]),s.useEffect(()=>{f==="aggregate"&&xe(c)},[f,c]);const Te=s.useMemo(()=>{let a=pe;if(ye){const m=ye.toLowerCase();a=a.filter(v=>v.series.toLowerCase().includes(m)||v.title.toLowerCase().includes(m)||v.__instance.toLowerCase().includes(m))}if(q&&(a=a.filter(m=>!m.hasFile)),re!=="all"){console.log(`[Sonarr Filter] Applying reason filter: "${re}"`);const m=a.length;re==="Not being searched"?a=a.filter(v=>v.reason==="Not being searched"||!v.reason):a=a.filter(v=>v.reason===re),console.log(`[Sonarr Filter] Filtered from ${m} to ${a.length} episodes for reason "${re}"`),a.length<10&&console.log("[Sonarr Filter] Sample filtered rows:",a.slice(0,5).map(v=>({series:v.series,episode:v.episode,reason:v.reason})))}return a},[pe,ye,q,re]),Me=!!ye||q||re!=="all",Fe=Te,ze=Math.max(1,Math.ceil(Fe.length/Qe));s.useMemo(()=>Fe.slice(oe*Qe,oe*Qe+Qe),[Fe,oe]);const Ke=h[Q]??[],Ue=s.useCallback(async()=>{if(!(!f||f==="aggregate"))try{await rs(f),t(`Restarted ${f}`,"success")}catch(a){t(a instanceof Error?a.message:`Failed to restart ${f}`,"error")}},[f,t]),De=s.useCallback(a=>{const m=a.target.value||"aggregate";k(m),m!=="aggregate"&&g("")},[k,g]),o=f==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Sonarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[n.length>1&&e.jsx("button",{className:`btn ${o?"active":""}`,onClick:()=>k("aggregate"),children:"All Sonarr"}),n.map(a=>e.jsx("button",{className:`btn ghost ${f===a.category?"active":""}`,onClick:()=>{k(a.category),g("")},children:a.name||a.category},a.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:f||"aggregate",onChange:De,disabled:!n.length,children:[n.length>1&&e.jsx("option",{value:"aggregate",children:"All Sonarr"}),n.map(a=>e.jsx("option",{value:a.category,children:a.name||a.category},a.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter series or episodes",value:c,onChange:a=>g(a.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:a=>{const v=a.target.value==="missing";de(v),f&&f!=="aggregate"&&ie(f,0,ce.current||"",{preloadAll:!0,showLoading:!0,missingOnly:v})},value:q?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Episodes"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:a=>me(a.target.value),value:re,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),o?e.jsx($s,{loading:Ne,rows:Fe,total:Fe.length,page:oe,totalPages:ze,onPageChange:we,onRefresh:()=>void be({showLoading:!0}),lastUpdated:Pe,groupSonarr:b,summary:he,instanceCount:n.length,isAggFiltered:Me}):e.jsx(Ds,{loading:y,counts:z?.counts??null,series:Ke,page:Q,pageSize:$,totalPages:G,totalItems:te,onlyMissing:q,reasonFilter:re,onPageChange:a=>{ee(a),ie(f,a,I,{preloadAll:!1,showLoading:!0,missingOnly:q})},onRestart:()=>void Ue(),lastUpdated:l,groupSonarr:b})]})]})})]})}function $s({loading:r,rows:t,total:c,page:g,totalPages:x,onPageChange:p,onRefresh:M,lastUpdated:w,groupSonarr:b,summary:P,instanceCount:n,isAggFiltered:S=!1}){const f=s.useRef([]),k=s.useRef([]),z=s.useMemo(()=>{if(t===f.current)return k.current;if(t.length===f.current.length){let A=!0;for(let G=0;G<t.length;G++){const Y=t[G],te=f.current[G];if(Y.__instance!==te.__instance||Y.series!==te.series||Y.season!==te.season||Y.episode!==te.episode||Y.hasFile!==te.hasFile||Y.monitored!==te.monitored){A=!1;break}}if(A)return k.current}const d=new Map;t.forEach(A=>{const G=A.__instance,Y=A.series,te=String(A.season);d.has(G)||d.set(G,new Map);const J=d.get(G);J.has(Y)||J.set(Y,new Map);const ce=J.get(Y);ce.has(te)||ce.set(te,[]),ce.get(te).push(A)});const $=[];return d.forEach((A,G)=>{A.forEach((Y,te)=>{$.push({instance:G,series:te,subRows:Array.from(Y.entries()).map(([J,ce])=>({seasonNumber:J,isSeason:!0,subRows:ce.map(je=>({...je,isEpisode:!0}))}))})})}),f.current=t,k.current=$,$},[t]),D=s.useMemo(()=>z.slice(g*50,(g+1)*50),[z,g]),Q=s.useMemo(()=>t.slice(g*50,(g+1)*50),[t,g]),ee=b?D:Q,I=s.useMemo(()=>[{accessorKey:"title",header:"Title",cell:({row:d})=>d.original.isEpisode?d.original.title:d.original.isSeason?`Season ${d.original.seasonNumber}`:d.original.series},{accessorKey:"monitored",header:"Monitored",cell:({row:d})=>{const $=(d.original.isEpisode,d.original.monitored);return e.jsx("span",{className:`track-status ${$?"available":"missing"}`,children:$?"✓":"✗"})}},{accessorKey:"hasFile",header:"Has File",cell:({row:d})=>{if(d.original.isEpisode){const $=d.original.hasFile;return e.jsx("span",{className:`track-status ${$?"available":"missing"}`,children:$?"✓":"✗"})}return null}},{accessorKey:"airDate",header:"Air Date",cell:({row:d})=>d.original.isEpisode?d.original.airDate||"—":null}],[]),R=s.useMemo(()=>[...n>1?[{accessorKey:"__instance",header:"Instance"}]:[],{accessorKey:"series",header:"Series"},{accessorKey:"season",header:"Season"},{accessorKey:"episode",header:"Episode"},{accessorKey:"title",header:"Title"},{accessorKey:"monitored",header:"Monitored",cell:({getValue:d})=>{const $=d();return e.jsx("span",{className:`track-status ${$?"available":"missing"}`,children:$?"✓":"✗"})}},{accessorKey:"hasFile",header:"Has File",cell:({getValue:d})=>{const $=d();return e.jsx("span",{className:`track-status ${$?"available":"missing"}`,children:$?"✓":"✗"})}},{accessorKey:"airDate",header:"Air Date",cell:({getValue:d})=>d()||"—"},{accessorKey:"reason",header:"Reason",cell:({getValue:d})=>{const $=d();return $?e.jsx("span",{className:"table-badge table-badge-reason",children:$}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})}}],[n]),y=b?I:R,C=Ie({data:ee,columns:y,getCoreRowModel:_e(),getExpandedRowModel:js()}),l=Ie({data:ee,columns:y,getCoreRowModel:_e(),getSortedRowModel:os(),getPaginationRowModel:ps(),state:{pagination:{pageIndex:g,pageSize:50}},manualPagination:!0,pageCount:x}),u=b?C:l,h=50,U=Math.ceil(b?z.length/h:t.length/h),K=Math.min(g,Math.max(0,U-1)),B=b?`${z.length} series`:t.length.toLocaleString();return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated episodes across all instances"," ",w?`(updated ${w})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",P.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",P.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",P.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total Episodes:"})," ",P.total.toLocaleString(void 0,{maximumFractionDigits:0}),S&&t.length<P.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",t.length.toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",P.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:M,disabled:r,children:[e.jsx(Oe,{src:Ve}),"Refresh"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Sonarr library…"]}):b?e.jsx("div",{className:"sonarr-hierarchical-view",children:D.map(d=>e.jsxs("details",{className:"series-details",children:[e.jsxs("summary",{className:"series-summary",children:[e.jsx("span",{className:"series-title",children:d.series}),e.jsxs("span",{className:"series-instance",children:["(",d.instance,")"]})]}),e.jsx("div",{className:"series-content",children:d.subRows.map($=>e.jsxs("details",{className:"season-details",children:[e.jsxs("summary",{className:"season-summary",children:[e.jsxs("span",{className:"season-title",children:["Season ",$.seasonNumber]}),e.jsxs("span",{className:"season-count",children:["(",$.subRows.length," episodes)"]})]}),e.jsx("div",{className:"season-content",children:e.jsx("div",{className:"episodes-table-wrapper",children:e.jsxs("table",{className:"episodes-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:$.subRows.map(A=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Episode",children:A.episode}),e.jsx("td",{"data-label":"Title",children:A.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${A.monitored?"available":"missing"}`,children:A.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${A.hasFile?"available":"missing"}`,children:A.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:A.airDate||"—"}),e.jsx("td",{"data-label":"Reason",children:A.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:A.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${A.__instance}-${A.series}-${A.season}-${A.episode}`))})]})})})]},`${d.instance}-${d.series}-${$.seasonNumber}`))})]},`${d.instance}-${d.series}`))}):!r&&P.total===0&&n>0?e.jsxs("div",{className:"hint",children:[e.jsx("p",{children:"No episodes found in the database."}),e.jsx("p",{children:"The backend may still be initializing and syncing data from your Sonarr instances. Please check the logs or wait a few moments and refresh."})]}):ee.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:e.jsx("tr",{children:u.getFlatHeaders().map(d=>e.jsxs("th",{className:d.column.getCanSort()?"sortable":"",onClick:d.column.getToggleSortingHandler(),children:[d.isPlaceholder?null:Ce(d.column.columnDef.header,d.getContext()),d.column.getCanSort()&&e.jsx("span",{className:"sort-arrow",children:{asc:"▲",desc:"▼"}[d.column.getIsSorted()]??null})]},d.id))})}),e.jsx("tbody",{children:u.getRowModel().rows.map(d=>{const $=d.original,A=`${$.__instance}-${$.series}-${$.season}-${$.episode}`;return e.jsx("tr",{children:d.getVisibleCells().map(G=>e.jsx("td",{"data-label":G.column.columnDef.header,children:Ce(G.column.columnDef.cell,G.getContext())},G.id))},A)})})]})}):e.jsx("div",{className:"hint",children:"No series found."}),ee.length>0&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",K+1," of ",U," (",B," items · page size ",h,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>p(Math.max(0,K-1)),disabled:K===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>p(Math.min(U-1,K+1)),disabled:K>=U-1||r,children:"Next"})]})]})]})}function Ds({loading:r,counts:t,series:c,page:g,pageSize:x,totalPages:p,totalItems:M,onlyMissing:w,reasonFilter:b,onPageChange:P,groupSonarr:n}){const S=Math.min(g,Math.max(0,p-1)),f=s.useRef([]),k=s.useRef([]),z=s.useMemo(()=>{if(c===f.current)return k.current;const l=[];for(const u of c){const h=u.series?.title||"";Object.entries(u.seasons??{}).forEach(([U,K])=>{(K.episodes??[]).forEach(B=>{l.push({__instance:"Instance",series:h,season:U,episode:B.episodeNumber??"",title:B.title??"",monitored:!!B.monitored,hasFile:!!B.hasFile,airDate:B.airDateUtc??"",reason:B.reason??null})})})}return f.current=c,k.current=l,l},[c]),D=s.useMemo(()=>{let l=z;if(w&&(l=l.filter(u=>!u.hasFile)),b!=="all"){console.log(`[Sonarr Instance Filter] Applying reason filter: "${b}"`);const u=l.length;b==="Not being searched"?l=l.filter(h=>h.reason==="Not being searched"||!h.reason):l=l.filter(h=>h.reason===b),console.log(`[Sonarr Instance Filter] Filtered from ${u} to ${l.length} episodes for reason "${b}"`),l.length<10&&console.log("[Sonarr Instance Filter] Sample filtered rows:",l.slice(0,5).map(h=>({series:h.series,episode:h.episode,reason:h.reason})))}return l},[z,w,b]),Q=s.useRef([]),ee=s.useRef([]),I=s.useMemo(()=>{if(D===Q.current)return ee.current;const l=new Map;D.forEach(h=>{const U=h.series;l.has(U)||l.set(U,new Map);const K=l.get(U),B=String(h.season);K.has(B)||K.set(B,[]),K.get(B).push(h)});const u=Array.from(l.entries()).map(([h,U])=>({series:h,subRows:Array.from(U.entries()).map(([K,B])=>({seasonNumber:K,isSeason:!0,subRows:B.map(d=>({...d,isEpisode:!0}))}))}));return Q.current=D,ee.current=u,u},[D]),R=s.useMemo(()=>z.length,[z]),y=b!=="all",C=D.length;return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsx("div",{className:"row",style:{justifyContent:"space-between"},children:e.jsx("div",{className:"hint",children:t?e.jsxs(e.Fragment,{children:[e.jsx("strong",{children:"Available:"})," ",t.available.toLocaleString()," •"," ",e.jsx("strong",{children:"Monitored:"})," ",t.monitored.toLocaleString()," •"," ",e.jsx("strong",{children:"Missing:"})," ",t.missing?.toLocaleString()??0,y&&R>0&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",C.toLocaleString()," of"," ",R.toLocaleString()]})]}):"Loading series information..."})}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading series…"]}):n?e.jsx("div",{className:"sonarr-hierarchical-view",children:I.map(l=>e.jsxs("details",{className:"series-details",children:[e.jsx("summary",{className:"series-summary",children:e.jsx("span",{className:"series-title",children:l.series})}),e.jsx("div",{className:"series-content",children:l.subRows.map(u=>e.jsxs("details",{className:"season-details",children:[e.jsxs("summary",{className:"season-summary",children:[e.jsxs("span",{className:"season-title",children:["Season ",u.seasonNumber]}),e.jsxs("span",{className:"season-count",children:["(",u.subRows.length," episodes)"]})]}),e.jsx("div",{className:"season-content",children:e.jsx("div",{className:"episodes-table-wrapper",children:e.jsxs("table",{className:"episodes-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:u.subRows.map(h=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Episode",children:h.episode}),e.jsx("td",{"data-label":"Title",children:h.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${h.monitored?"available":"missing"}`,children:h.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${h.hasFile?"available":"missing"}`,children:h.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:h.airDate||"—"}),e.jsx("td",{"data-label":"Reason",children:h.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:h.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${h.series}-${h.season}-${h.episode}`))})]})})})]},`${l.series}-${u.seasonNumber}`))})]},`${l.series}`))}):!r&&c.length>0&&D.length===0&&z.length===0?e.jsxs("div",{className:"hint",children:[e.jsx("p",{children:"No episodes found for these series."}),e.jsx("p",{children:"The backend may still be syncing episode data from Sonarr. Please check the logs or wait a few moments and refresh."})]}):!r&&c.length>0&&D.length===0&&z.length>0?e.jsx("div",{className:"hint",children:"No episodes match the current filter."}):D.length?e.jsxs("div",{className:"table-wrapper",children:[e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Series"}),e.jsx("th",{children:"Season"}),e.jsx("th",{children:"Episode"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Monitored"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Air Date"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:D.slice(S*x,S*x+x).map((l,u)=>e.jsxs("tr",{children:[e.jsx("td",{"data-label":"Series",children:l.series}),e.jsx("td",{"data-label":"Season",children:l.season}),e.jsx("td",{"data-label":"Episode",children:l.episode}),e.jsx("td",{"data-label":"Title",children:l.title}),e.jsx("td",{"data-label":"Monitored",children:e.jsx("span",{className:`track-status ${l.monitored?"available":"missing"}`,children:l.monitored?"✓":"✗"})}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${l.hasFile?"available":"missing"}`,children:l.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Air Date",children:l.airDate||"—"}),e.jsx("td",{"data-label":"Reason",children:l.reason?e.jsx("span",{className:"table-badge table-badge-reason",children:l.reason}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${l.series}-${l.season}-${l.episode}-${u}`))})]}),e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",S+1," of ",p," (",D.length.toLocaleString()," items · page size ",x,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>P(Math.max(0,S-1)),disabled:S===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>P(Math.min(p-1,S+1)),disabled:S>=p-1||r,children:"Next"})]})]})]}):e.jsx("div",{className:"hint",children:"No series found."})]})}const ss=50,ms=500;function ks({loading:r,rows:t,trackRows:c,page:g,onPageChange:x,onRefresh:p,lastUpdated:M,summary:w,instanceCount:b,groupLidarr:P,isAggFiltered:n=!1}){const S=s.useRef([]),f=s.useRef([]),k=s.useMemo(()=>{if(t===S.current)return f.current;if(t.length===S.current.length){let y=!0;for(let C=0;C<t.length;C++){const l=t[C],u=S.current[C],h=l.album,U=u.album;if(l.__instance!==u.__instance||h?.title!==U?.title||h?.artistName!==U?.artistName||h?.hasFile!==U?.hasFile||h?.monitored!==U?.monitored){y=!1;break}}if(y)return f.current}const I=new Map;t.forEach(y=>{const C=y.__instance,l=y.album?.artistName||"Unknown Artist";I.has(C)||I.set(C,new Map);const u=I.get(C);u.has(l)||u.set(l,[]),u.get(l).push(y)});const R=[];return I.forEach((y,C)=>{y.forEach((l,u)=>{R.push({instance:C,artist:u,albums:l})})}),S.current=t,f.current=R,R},[t]),z=s.useMemo(()=>k.slice(g*50,(g+1)*50),[k,g]),D=s.useMemo(()=>{const R=g*50,y=R+50;return c.slice(R,y)},[c,g]),Q=s.useMemo(()=>[...b>1?[{accessorKey:"__instance",header:"Instance",size:120}]:[],{accessorKey:"artistName",header:"Artist",size:150},{accessorKey:"albumTitle",header:"Album",size:150},{accessorKey:"trackNumber",header:"#",size:50},{accessorKey:"title",header:"Track"},{accessorKey:"duration",header:"Duration",cell:I=>{const R=I.getValue();return R?`${Math.floor(R/60)}:${String(R%60).padStart(2,"0")}`:e.jsx("span",{className:"hint",children:"—"})},size:80},{accessorKey:"monitored",header:"Monitored",cell:I=>{const R=I.getValue();return e.jsx("span",{className:`track-status ${R?"available":"missing"}`,children:R?"✓":"✗"})},size:100},{accessorKey:"hasFile",header:"Has File",cell:I=>{const R=I.getValue();return e.jsx("span",{className:`track-status ${R?"available":"missing"}`,children:R?"✓":"✗"})},size:100},{accessorKey:"reason",header:"Reason",cell:I=>{const R=I.getValue();return R?e.jsx("span",{className:"table-badge table-badge-reason",children:R}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[b]),ee=Ie({data:D,columns:Q,getCoreRowModel:_e()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:["Aggregated albums across all instances"," ",M?`(updated ${M})`:"",e.jsx("br",{}),e.jsx("strong",{children:"Available:"})," ",w.available.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Monitored:"})," ",w.monitored.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Missing:"})," ",w.missing.toLocaleString(void 0,{maximumFractionDigits:0})," •"," ",e.jsx("strong",{children:"Total:"})," ",w.total.toLocaleString(void 0,{maximumFractionDigits:0}),n&&(P?t.length:c.length)<w.total&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",(P?t.length:c.length).toLocaleString(void 0,{maximumFractionDigits:0})," of"," ",w.total.toLocaleString(void 0,{maximumFractionDigits:0})]})]}),e.jsxs("button",{className:"btn ghost",onClick:p,disabled:r,children:[e.jsx(Oe,{src:Ve}),"Refresh"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading Lidarr library…"]}):P?e.jsx("div",{className:"lidarr-hierarchical-view",children:z.map(I=>e.jsxs("details",{className:"artist-details",children:[e.jsxs("summary",{className:"artist-summary",children:[e.jsx("span",{className:"artist-title",children:I.artist}),e.jsxs("span",{className:"artist-instance",children:["(",I.instance,")"]}),e.jsxs("span",{className:"artist-count",children:["(",I.albums.length," albums)"]})]}),e.jsx("div",{className:"artist-content",children:I.albums.map(R=>{const y=R.album,C=y?.title||"Unknown Album",l=y?.id||0,u=y?.artistName||"",h=y?.releaseDate,U=y?.monitored,K=y?.hasFile,B=y?.reason,d=R.tracks||[],$=R.totals;return e.jsxs("details",{className:"album-details",children:[e.jsxs("summary",{className:"album-summary",children:[e.jsx("span",{className:"album-title",children:C}),h&&e.jsx("span",{className:"album-date",children:new Date(h).toLocaleDateString()}),d&&d.length>0&&e.jsxs("span",{className:"album-track-count",children:["(",$.available||0,"/",$.monitored||d.length," tracks)"]}),e.jsx("span",{className:`album-status ${K?"has-file":"missing"}`,children:K?"✓":"✗"})]}),e.jsx("div",{className:"album-content",children:d&&d.length>0?e.jsx("div",{className:"tracks-table-wrapper",children:e.jsxs("table",{className:"tracks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"#"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Duration"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:d.map(A=>e.jsxs("tr",{className:A.hasFile?"track-available":"track-missing",children:[e.jsx("td",{"data-label":"#",children:A.trackNumber}),e.jsx("td",{"data-label":"Title",children:A.title}),e.jsx("td",{"data-label":"Duration",children:A.duration?`${Math.floor(A.duration/60)}:${String(A.duration%60).padStart(2,"0")}`:"—"}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${A.hasFile?"available":"missing"}`,children:A.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Reason",children:B?e.jsx("span",{className:"table-badge table-badge-reason",children:B}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${l}-${A.id}`))})]})}):e.jsxs("div",{className:"album-info",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Monitored:"})," ",U?"Yes":"No"," | ",e.jsx("strong",{children:"Has File:"})," ",K?"Yes":"No"]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Reason:"})," ",B?e.jsx("span",{className:"table-badge table-badge-reason",children:B}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})]})]})})]},`${R.__instance}-${u}-${C}`)})})]},`${I.instance}-${I.artist}`))}):c.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:ee.getHeaderGroups().map(I=>e.jsx("tr",{children:I.headers.map(R=>e.jsx("th",{children:R.isPlaceholder?null:Ce(R.column.columnDef.header,R.getContext())},R.id))},I.id))}),e.jsx("tbody",{children:ee.getRowModel().rows.map(I=>{const R=I.original,y=`${R.__instance}-${R.artistName}-${R.albumTitle}-${R.trackNumber}`;return e.jsx("tr",{children:I.getVisibleCells().map(C=>e.jsx("td",{"data-label":String(C.column.columnDef.header),children:Ce(C.column.columnDef.cell,C.getContext())},C.id))},y)})})]})}):e.jsx("div",{className:"hint",children:"No tracks found."}),(P?z.length>0:D.length>0)&&e.jsxs("div",{className:"pagination",children:[e.jsx("div",{children:P?e.jsxs(e.Fragment,{children:["Page ",g+1," of ",Math.ceil(k.length/50)," (",k.length," artists · page size 50)"]}):e.jsxs(e.Fragment,{children:["Page ",g+1," of ",Math.ceil(c.length/50)," (",c.length.toLocaleString()," tracks · page size 50)"]})}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>x(Math.max(0,g-1)),disabled:g===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>x(Math.min(Math.ceil(P?k.length/50:c.length/50)-1,g+1)),disabled:g>=Math.ceil(P?k.length/50:c.length/50)-1||r,children:"Next"})]})]})]})}function Ls({loading:r,data:t,page:c,totalPages:g,pageSize:x,allAlbums:p,onlyMissing:M,reasonFilter:w,onPageChange:b,onRestart:P,lastUpdated:n,groupLidarr:S}){const f=s.useMemo(()=>{let l=p;return M&&(l=l.filter(u=>!u.album?.hasFile)),l},[p,M]),k=s.useMemo(()=>w==="all"?f:w==="Not being searched"?f.filter(l=>{const u=l.album;return u?.reason==="Not being searched"||!u?.reason}):f.filter(l=>l.album?.reason===w),[f,w]),z=s.useMemo(()=>p.length,[p]),D=w!=="all",Q=k.length,ee=s.useRef([]),I=s.useRef([]),R=s.useMemo(()=>{if(k===ee.current)return I.current;const l=new Map;k.forEach(h=>{const K=h.album?.artistName||"Unknown Artist";l.has(K)||l.set(K,[]),l.get(K).push(h)});const u=Array.from(l.entries()).map(([h,U])=>({artist:h,albums:U}));return ee.current=k,I.current=u,u},[k]),y=s.useMemo(()=>[{id:"title",header:"Album",cell:l=>l.row.original.album?.title||"Unknown Album"},{id:"artistName",header:"Artist",cell:l=>l.row.original.album?.artistName||"Unknown Artist",size:150},{id:"releaseDate",header:"Release Date",cell:l=>{const h=l.row.original.album?.releaseDate;return h?new Date(h).toLocaleDateString():e.jsx("span",{className:"hint",children:"—"})},size:120},{id:"monitored",header:"Monitored",cell:l=>{const h=l.row.original.album?.monitored;return e.jsx("span",{className:`track-status ${h?"available":"missing"}`,children:h?"✓":"✗"})},size:100},{id:"hasFile",header:"Has File",cell:l=>{const h=l.row.original.album?.hasFile;return e.jsx("span",{className:`track-status ${h?"available":"missing"}`,children:h?"✓":"✗"})},size:100},{id:"reason",header:"Reason",cell:l=>{const h=l.row.original.album?.reason;return h?e.jsx("span",{className:"table-badge table-badge-reason",children:h}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})},size:120}],[]),C=Ie({data:k.slice(c*x,c*x+x),columns:y,getCoreRowModel:_e(),getSortedRowModel:os()});return e.jsxs("div",{className:"stack animate-fade-in",children:[e.jsxs("div",{className:"row",style:{justifyContent:"space-between"},children:[e.jsxs("div",{className:"hint",children:[t?.counts?`Available: ${t.counts.available??0} • Monitored: ${t.counts.monitored??0}`:"",n?` (updated ${n})`:"",D&&z>0&&e.jsxs(e.Fragment,{children:[" ","• ",e.jsx("strong",{children:"Filtered:"})," ",Q.toLocaleString()," of"," ",z.toLocaleString()]})]}),e.jsxs("button",{className:"btn ghost",onClick:P,disabled:r,children:[e.jsx(Oe,{src:Ve}),"Restart"]})]}),r?e.jsxs("div",{className:"loading",children:[e.jsx("span",{className:"spinner"})," Loading…"]}):S?e.jsx("div",{className:"lidarr-hierarchical-view",children:R.map(l=>e.jsxs("details",{className:"artist-details",children:[e.jsxs("summary",{className:"artist-summary",children:[e.jsx("span",{className:"artist-title",children:l.artist}),e.jsxs("span",{className:"artist-count",children:["(",l.albums.length," albums)"]})]}),e.jsx("div",{className:"artist-content",children:l.albums.map(u=>{const h=u.album,U=h?.title||"Unknown Album",K=h?.id||0,B=h?.artistName||"",d=h?.releaseDate,$=h?.monitored,A=h?.hasFile,G=h?.reason,Y=u.tracks||[],te=u.totals;return e.jsxs("details",{className:"album-details",children:[e.jsxs("summary",{className:"album-summary",children:[e.jsx("span",{className:"album-title",children:U}),d&&e.jsx("span",{className:"album-date",children:new Date(d).toLocaleDateString()}),Y&&Y.length>0&&e.jsxs("span",{className:"album-track-count",children:["(",te.available||0,"/",te.monitored||Y.length," tracks)"]}),e.jsx("span",{className:`album-status ${A?"has-file":"missing"}`,children:A?"✓":"✗"})]}),e.jsx("div",{className:"album-content",children:Y&&Y.length>0?e.jsx("div",{className:"tracks-table-wrapper",children:e.jsxs("table",{className:"tracks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"#"}),e.jsx("th",{children:"Title"}),e.jsx("th",{children:"Duration"}),e.jsx("th",{children:"Has File"}),e.jsx("th",{children:"Reason"})]})}),e.jsx("tbody",{children:Y.map(J=>e.jsxs("tr",{className:J.hasFile?"track-available":"track-missing",children:[e.jsx("td",{"data-label":"#",children:J.trackNumber}),e.jsx("td",{"data-label":"Title",children:J.title}),e.jsx("td",{"data-label":"Duration",children:J.duration?`${Math.floor(J.duration/60)}:${String(J.duration%60).padStart(2,"0")}`:"—"}),e.jsx("td",{"data-label":"Has File",children:e.jsx("span",{className:`track-status ${J.hasFile?"available":"missing"}`,children:J.hasFile?"✓":"✗"})}),e.jsx("td",{"data-label":"Reason",children:G?e.jsx("span",{className:"table-badge table-badge-reason",children:G}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})})]},`${K}-${J.id}`))})]})}):e.jsxs("div",{className:"album-info",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Monitored:"})," ",$?"Yes":"No"," | ",e.jsx("strong",{children:"Has File:"})," ",A?"Yes":"No"]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Reason:"})," ",G?e.jsx("span",{className:"table-badge table-badge-reason",children:G}):e.jsx("span",{className:"table-badge table-badge-reason",children:"Not being searched"})]})]})})]},`${B}-${U}`)})})]},l.artist))}):p.length?e.jsx("div",{className:"table-wrapper",children:e.jsxs("table",{className:"responsive-table",children:[e.jsx("thead",{children:C.getHeaderGroups().map(l=>e.jsx("tr",{children:l.headers.map(u=>e.jsx("th",{children:u.isPlaceholder?null:Ce(u.column.columnDef.header,u.getContext())},u.id))},l.id))}),e.jsx("tbody",{children:C.getRowModel().rows.map(l=>{const h=l.original.album,U=h?.title||"Unknown",K=h?.artistName||"Unknown",B=`${U}-${K}`;return e.jsx("tr",{children:l.getVisibleCells().map(d=>e.jsx("td",{"data-label":String(d.column.columnDef.header),children:Ce(d.column.columnDef.cell,d.getContext())},d.id))},B)})})]})}):e.jsx("div",{className:"hint",children:"No albums found."}),k.length>x&&e.jsxs("div",{className:"pagination",children:[e.jsxs("div",{children:["Page ",c+1," of ",g," (",k.length.toLocaleString()," items · page size"," ",x,")"]}),e.jsxs("div",{className:"inline",children:[e.jsx("button",{className:"btn",onClick:()=>b(Math.max(0,c-1)),disabled:c===0||r,children:"Prev"}),e.jsx("button",{className:"btn",onClick:()=>b(Math.min(g-1,c+1)),disabled:c>=g-1||r,children:"Next"})]})]})]})}function Is({active:r}){const{push:t}=ts(),{value:c,setValue:g,register:x,clearHandler:p}=ns(),{liveArr:M,groupLidarr:w}=ls(),[b,P]=s.useState([]),[n,S]=s.useState("aggregate"),[f,k]=s.useState(null),[z,D]=s.useState(0),[Q,ee]=s.useState(""),[I,R]=s.useState(!1),[y,C]=s.useState(null),[l,u]=s.useState({}),[h,U]=s.useState(ss),[K,B]=s.useState(1),d=s.useRef(""),$=s.useRef({}),A=s.useRef(c),G=s.useRef(!1),Y=Le({getKey:o=>{const a=o.album,m=a?.artistName||"",v=a?.title||"";return`${m}-${v}`},hashFields:["album","tracks","totals"]}),[te,J]=s.useState([]),[ce,je]=s.useState([]),[pe,fe]=s.useState(!1),[Ne,ve]=s.useState(0),[oe,we]=s.useState(""),[ye,xe]=s.useState(null),Pe=Le({getKey:o=>{const a=o.album,m=a?.artistName||"",v=a?.title||"";return`${o.__instance}-${m}-${v}`},hashFields:["__instance","album","tracks","totals"]}),Ae=Le({getKey:o=>`${o.__instance}-${o.artistName}-${o.albumTitle}-${o.trackNumber}`,hashFields:["__instance","artistName","albumTitle","trackNumber","title","hasFile","monitored","reason"]}),[Se,q]=s.useState(!1),[de,re]=s.useState("all"),[me,he]=s.useState({available:0,monitored:0,missing:0,total:0}),Re=s.useCallback(async()=>{try{const o=await is();o.ready===!1&&!G.current?(G.current=!0,t("Lidarr backend is still initialising. Check the logs if this persists.","info")):o.ready&&(G.current=!0);const a=(o.arr||[]).filter(m=>m.type==="lidarr");if(P(a),!a.length){S("aggregate"),k(null),J([]),he({available:0,monitored:0,missing:0,total:0});return}n===""?S(a.length===1?a[0].category:"aggregate"):n!=="aggregate"&&!a.some(m=>m.category===n)&&S(a[0].category)}catch(o){t(o instanceof Error?o.message:"Unable to load Lidarr instances","error")}},[t,n]),ge=s.useCallback(async(o,a,m,v,i)=>{if(v.length)try{const j=[];for(const N of v){const T=await Je(o,N,m,a),E=T.page??N;if(j.push({page:E,albums:T.albums??[]}),d.current!==i)return}if(d.current!==i)return;u(N=>{const T={...N};let E=!1;for(const{page:V,albums:_}of j){const F=Y.syncData(_);F.hasChanges&&(T[V]=F.data,E=!0)}return $.current=T,E?T:N})}catch(j){t(j instanceof Error?j.message:`Failed to load additional pages for ${o}`,"error")}},[t]),ie=s.useCallback(async(o,a,m,v={})=>{const i=v.preloadAll!==!1;(v.showLoading??!0)&&R(!0);try{const N=`${o}::${m}`,T=d.current!==N;T&&(d.current=N,u(()=>($.current={},{})));const E=await Je(o,a,ss,m);k(E);const V=E.page??a;D(V),ee(m);const _=E.page_size??ss,F=E.total??(E.albums??[]).length,L=Math.max(1,Math.ceil((F||0)/_));U(_),B(L);const W=E.albums??[],ne=T?{}:$.current,se=Y.syncData(W),H=se.hasChanges;if(T&&Y.reset(),(T||H)&&(u(X=>{const ae={...T?{}:X,[V]:se.data};return $.current=ae,ae}),C(new Date().toLocaleTimeString())),i){const X=[];for(let Z=0;Z<L;Z+=1)Z!==V&&(ne[Z]||X.push(Z));ge(o,m,_,X,N)}}catch(N){t(N instanceof Error?N.message:`Failed to load ${o} albums`,"error")}finally{R(!1)}},[t,ge]),be=s.useCallback(async o=>{if(!b.length){J([]),he({available:0,monitored:0,missing:0,total:0});return}(o?.showLoading??!0)&&fe(!0);try{const m=[];let v=0,i=0;for(const L of b){let W=0,ne=!1;const se=L.name||L.category;for(;W<100;){const H=await Je(L.category,W,ms,"");if(console.log("=== Lidarr API Response ==="),console.log("Instance:",L.category),console.log("Response:",H),console.log("Albums count:",H.albums?.length),H.albums&&H.albums.length>0&&(console.log("First album entry:",H.albums[0]),console.log("First album.album:",H.albums[0].album),console.log("First album.totals:",H.albums[0].totals),console.log("First album.tracks:",H.albums[0].tracks)),console.log("========================="),!ne){const Z=H.counts;Z&&(v+=Z.available??0,i+=Z.monitored??0),ne=!0}const X=H.albums??[];if(X.forEach(Z=>{m.push({...Z,__instance:se})}),!X.length||X.length<ms)break;W+=1}}const j=[];m.forEach(L=>{const W=L.album,ne=W?.artistName||"Unknown Artist",se=W?.title||"Unknown Album",H=W?.reason,X=L.tracks||[];X&&X.length>0&&X.forEach(Z=>{j.push({__instance:L.__instance,artistName:ne,albumTitle:se,trackNumber:Z.trackNumber||0,title:Z.title||"Unknown Track",duration:Z.duration,hasFile:Z.hasFile||!1,monitored:Z.monitored||!1,reason:H})})});const N=Pe.syncData(m),T=N.hasChanges,E=Ae.syncData(j),V=E.hasChanges;T&&J(N.data),V&&je(E.data);const _=w?{available:v,monitored:i,missing:m.length-v,total:m.length}:{available:j.filter(L=>L.hasFile).length,monitored:j.filter(L=>L.monitored).length,missing:j.filter(L=>!L.hasFile).length,total:j.length},F=me.available!==_.available||me.monitored!==_.monitored||me.missing!==_.missing||me.total!==_.total;F&&he(_),oe!==c&&(ve(0),we(c)),(T||F)&&xe(new Date().toLocaleTimeString())}catch(m){J([]),he({available:0,monitored:0,missing:0,total:0}),t(m instanceof Error?m.message:"Failed to load aggregated Lidarr data","error")}finally{fe(!1)}},[b,c,t,oe,w]);s.useEffect(()=>{r&&Re()},[r,Re]),s.useEffect(()=>{if(!r||!n||n==="aggregate")return;$.current={},u({}),B(1),D(0);const o=A.current;ie(n,0,o,{preloadAll:!0,showLoading:!0})},[r,n,ie]),s.useEffect(()=>{r&&n==="aggregate"&&be()},[r,n,be]),Ee(()=>{n==="aggregate"&&M&&be({showLoading:!1})},n==="aggregate"&&M?1e4:null),s.useEffect(()=>{if(!r)return;const o=a=>{n==="aggregate"?(we(a),ve(0)):n&&(D(0),ie(n,0,a,{preloadAll:!0,showLoading:!0}))};return x(o),()=>{p(o)}},[r,n,x,p,ie]),Ee(()=>{if(n&&n!=="aggregate"){if(A.current?.trim?.()||"")return;ie(n,z,Q,{preloadAll:!1,showLoading:!1})}},r&&n&&n!=="aggregate"&&M?1e3:null),s.useEffect(()=>{A.current=c},[c]),s.useEffect(()=>{n==="aggregate"&&we(c)},[n,c]);const Te=s.useMemo(()=>{let o=te;if(oe){const a=oe.toLowerCase();o=o.filter(m=>{const v=m.album,i=(v?.title??"").toString().toLowerCase(),j=(v?.artistName??"").toString().toLowerCase(),N=(m.__instance??"").toLowerCase();return i.includes(a)||j.includes(a)||N.includes(a)})}return Se&&(o=o.filter(a=>!a.album?.hasFile)),de!=="all"&&(de==="Not being searched"?o=o.filter(a=>{const m=a.album;return m?.reason==="Not being searched"||!m?.reason}):o=o.filter(a=>a.album?.reason===de)),o},[te,oe,Se,de]),Me=!!oe||de!=="all",Fe=s.useMemo(()=>{let o=ce;if(oe){const a=oe.toLowerCase();o=o.filter(m=>m.artistName.toLowerCase().includes(a)||m.albumTitle.toLowerCase().includes(a)||m.title.toLowerCase().includes(a)||m.__instance.toLowerCase().includes(a))}return Se&&(o=o.filter(a=>!a.hasFile)),de!=="all"&&(de==="Not being searched"?o=o.filter(a=>a.reason==="Not being searched"||!a.reason):o=o.filter(a=>a.reason===de)),o},[ce,oe,Se,de]),ze=s.useMemo(()=>{const o=Object.keys(l).map(Number).sort((m,v)=>m-v),a=[];return o.forEach(m=>{l[m]&&a.push(...l[m])}),a},[l]),Ke=s.useCallback(async()=>{if(!(!n||n==="aggregate"))try{await rs(n),t(`Restarted ${n}`,"success")}catch(o){t(o instanceof Error?o.message:`Failed to restart ${n}`,"error")}},[n,t]),Ue=s.useCallback(o=>{const a=o.target.value||"aggregate";S(a),a!=="aggregate"&&g("")},[S,g]),De=n==="aggregate";return e.jsxs("section",{className:"card",children:[e.jsx("div",{className:"card-header",children:"Lidarr"}),e.jsx("div",{className:"card-body",children:e.jsxs("div",{className:"split",children:[e.jsxs("aside",{className:"pane sidebar",children:[b.length>1&&e.jsx("button",{className:`btn ${De?"active":""}`,onClick:()=>S("aggregate"),children:"All Lidarr"}),b.map(o=>e.jsx("button",{className:`btn ghost ${n===o.category?"active":""}`,onClick:()=>{S(o.category),g("")},children:o.name||o.category},o.category))]}),e.jsxs("div",{className:"pane",children:[e.jsxs("div",{className:"field mobile-instance-select",children:[e.jsx("label",{children:"Instance"}),e.jsxs("select",{value:n||"aggregate",onChange:Ue,disabled:!b.length,children:[b.length>1&&e.jsx("option",{value:"aggregate",children:"All Lidarr"}),b.map(o=>e.jsx("option",{value:o.category,children:o.name||o.category},o.category))]})]}),e.jsxs("div",{className:"row",style:{alignItems:"flex-end",gap:"12px",flexWrap:"wrap"},children:[e.jsxs("div",{className:"col field",style:{flex:"1 1 200px"},children:[e.jsx("label",{children:"Search"}),e.jsx("input",{placeholder:"Filter albums",value:c,onChange:o=>g(o.target.value)})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Status"}),e.jsxs("select",{onChange:o=>{const a=o.target.value;q(a==="missing")},value:Se?"missing":"all",children:[e.jsx("option",{value:"all",children:"All Albums"}),e.jsx("option",{value:"missing",children:"Missing Only"})]})]}),e.jsxs("div",{className:"field",style:{flex:"0 0 auto",minWidth:"140px"},children:[e.jsx("label",{children:"Search Reason"}),e.jsxs("select",{onChange:o=>re(o.target.value),value:de,children:[e.jsx("option",{value:"all",children:"All Reasons"}),e.jsx("option",{value:"Not being searched",children:"Not Being Searched"}),e.jsx("option",{value:"Missing",children:"Missing"}),e.jsx("option",{value:"Quality",children:"Quality"}),e.jsx("option",{value:"CustomFormat",children:"Custom Format"}),e.jsx("option",{value:"Upgrade",children:"Upgrade"})]})]})]}),De?e.jsx(ks,{loading:pe,rows:Te,trackRows:Fe,page:Ne,onPageChange:ve,onRefresh:()=>void be({showLoading:!0}),lastUpdated:ye,summary:me,instanceCount:b.length,groupLidarr:w,isAggFiltered:Me}):e.jsx(Ls,{loading:I,data:f,page:z,totalPages:K,pageSize:h,allAlbums:ze,onlyMissing:Se,reasonFilter:de,onPageChange:o=>{D(o),ie(n,o,Q,{preloadAll:!0})},onRestart:()=>void Ke(),lastUpdated:y,groupLidarr:w})]})]})})]})}function zs({type:r,active:t}){return r==="radarr"?e.jsx(Fs,{active:t}):r==="lidarr"?e.jsx(Is,{active:t}):e.jsx(Ms,{active:t})}export{zs as ArrView};
|
|
2
|
+
//# sourceMappingURL=ArrView.js.map
|