From 502b0ba01d9c950f0d0190bec0c1a67f1f8a982f Mon Sep 17 00:00:00 2001 From: Broque Thomas Date: Tue, 12 Aug 2025 16:25:01 -0700 Subject: [PATCH] dashboard cancel button --- .../__pycache__/dashboard.cpython-310.pyc | Bin 111939 -> 115147 bytes .../__pycache__/dashboard.cpython-312.pyc | Bin 196684 -> 205738 bytes ui/pages/dashboard.py | 195 +++++++++++++++++- 3 files changed, 184 insertions(+), 11 deletions(-) diff --git a/ui/pages/__pycache__/dashboard.cpython-310.pyc b/ui/pages/__pycache__/dashboard.cpython-310.pyc index 5733fff684f6c92ca0dd4fe7298a724c7136a8c2..e27f8664d684bb4349091ab345ade739535b798b 100644 GIT binary patch delta 21162 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Ͳ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 X^~OO=LyxNO4}#L16V)w;VDSF~*vqL2 diff --git a/ui/pages/__pycache__/dashboard.cpython-312.pyc b/ui/pages/__pycache__/dashboard.cpython-312.pyc index 7636d622146f387847882499a1de83c11b93dcce..b761b68faba7b46620ad8e844d955bf432f631a2 100644 GIT binary patch delta 25636 zcmbun34Bw<_BfuItWDEB-M6F*ZMrYevX!k+C`(z2iYT<9NukhfH=bSln z?)_k`?&)`Q{{Qmx)5_rYt8>Q^(<=x4pU5Kh;tN@ig@>(|&5yE#1B|vr0F1E|SR&UG zadEbz#F7OWd6sN|`Ia1jL#b@C%#yoaX34V-dq$23WwQANmV78HvfyU zWd6uPvECZ?B5$f$_6(8IP#)i(yL60%VI2R% zUenMJ7Ue?|i6?)u_~1r8Yx#=$ky3H_Cm~|nB^{Z@QyrIl#r^quGNk=TzLDtUHmlto zSY@uSveveD4c$!0B+*i^U3ap)P)HSh=iU(? ziAe=?EvOJ=;-djmS(wTe56sP1#bQz^em!?F87|JaA&2G=aa~7>2eFFR<7Bu+FuoC+O< zlQ-HQS@;5BuAwwad~V9{_MMfTgl#@VLd3O68s>b1=&41uby+-nU;zyg%N7~M&lc&G zN{jj#Dh8V4`IE|`k)Bv<2UHq2KR}E&>)E#LK(sJ(r1;0F5Nb~n*9OJ1AFh!Q)~cd@ zSVR2wGu{ndnu*-SemX>SVx&3Dn=hXDS4Vi6%#Cr7`ztblsW=mnNcHlj72( z>?8Z~yENJVnVZ+8$r4{!V(}U4(u_SyyEMfjttlr8@wAx5+V)dlaqae4mJ>)cO!GVO zV>ic=P_c5FCUBx`3ta%DxfMvUhOD71_ahR{0$-&1_Q<6^RQn7J8Gmb3%s8HgiGfpf zY~*yRW!>Xw01F;Y^`Sl%{_h#2Bm9W0S-mt-Jjg=C?dCD!*kyXwyO!wFiACG2@(Ly* zv!_VaWipG_D-I^g7TgM5Y4{+-1t}q6&7>JPMyk2Sr`g9wHYGIshaBu+Ea8?{HPi~tkg}od2j=knBpy*SvxcOK zx7F)aSFw&ue7Jrn?8W!%KW~XN?C{xG+M^5Y)+M@hi5*E}x^!btg&JBTJ44eqmh|X? zyLHJfU2>~=U(mks`<8d(X4h zw0*hz%x#ffx=|NZvWVD6W{ayX$mD)yWQ)8fJi0qP#TA|+zTQwo3**E;8&-kbT-mq~ zw(cj5qge8tG*m5vrP?54?7?hcqPAB^SfGXUEgx;B!WW{eJ&X&CM_#2ddJA2a3Z#3@ z?gK>NKZ~68b`b+x`x^-$a}U^%-h9M!vlQ%~&w;EuH(yt^T8;lq8b{H1i^U*m3B#f$yS<^_U~e#( z4Yo#WRZVqGl|g7&X-I9TuU&1ZZV(K0H8xvK{bJ;ks%174=MDjx^AdtLm@pI8%6t}> zL(4ikX|#CX#1OXjI8|)xCEDOjSn&p7q#@B#l|O9guu%prTYjACS=&ge)~sAoW4HEY z^}bD1Y-TUL1WiRy*kzXI8yxi(MMn-|%;2n;R9e9su{~lG|aC71Rx)5r;7kjR?(3(GVlood? z%YBbTiMu1h*jNWuGTQ{2G0v@%SgC^Zhe_^MS1qwtEwftOYT%=a8p|qS0q}`O8?5C! z{iy~(p%n7VOo4(GWsMfBAdf`i!bd2DT)`KrxOE_}xIRO@<@UF= zSnV@v>TBwn>O2|nY+mJk<{}SjL7RrECflrr+M24>0@{Rb-vK#pby)*{1PVY6pnz~5 z>Ii6Wn3S9dZaK_JxD!X`H*mVS^?ZajRMwS9Xig<}#D61;W7PjhwFIQmNx%g(>eWYd z>yupiq;7q-OP}2)Z=2nzFWl&J(pUdTWOt;=6=~{>Oz)1&bw%cOM&`FIKOQ;!R7}b~ zMQ2Rr#u+`j$Zp*bmu^U_urIGmm&Kn`UAokL!TaX4bm?*iWq6-cT)LEVvKUj~MOlnr z(7BN^zo>26Bn9B*uN>5SbvlS^khn%I?Q?$Ryl4UOv#O?HJQ zcZQ~TBsEK7?)3t<#v^cj)beJza3hG#*`YBS zkh>FMK_)OV3v_zR&sy>A<$4s9YDKd`Ff=Pr@QNS*sB5tY0QLCKqG%>NWV>jeaFwlA zdjFYJj&W0JEY|CUDGJT&rRmBgR* z@rYMQBi{a&9&Bbi7uRJb4d;46L?%aF%h}zn0s&h$-tJbdV+(a`GiaHOyUt0G5A zjdnuHrc8$l$c7$1j9LPdyl#KOU~q#sGs`Ug&HcuUYCzus%_`_GaF@KlKO(Cq z3R$yi?G1x^4eIN)l%0N)griN1)(@E73o<-Lw+8LnhxdSr#!=MtjUu{P19Rw~aqxfd zbzSzLUPJnNO&HK#kL?F+Up7`v!&{nF7WsitZvz6hGX67#IWmg*5ozH5m3D2WVP%7` z%w~Z7X0BgtXk22pS^G_)63M>aDRTSzl0Pi#x!sRGW00`bf-3k1vYNs?`7MUITog$A z8;VC794bR9>?gxjVk#4UfO>9UyLnNqwW6lpVqN9-_ilXYxd}ZGyoVAr;tggvg{`pm zNe6>N&rP>J{F1P6M}V1cuC29-6L$wCG@*}T01i)CtyC8+KJny{*p{YjZ?(BX&EmyY z0ZXbH>KbdUc=F@@T;KhE;#S+5s;b~vZ3_E4xg_jHiPH+etp&Y0sUD|l5mcDF3IQH$ z+-e|li`i}$gs(ohY2bN0eg1dIU%=;SB_P5u*}io=w;XX_J=g-M^D^LOnKk z3L9v=#C6NTTybmpiUXmm8*Exs^IQ~iAe~b-LnB8vcXIsvtGb0(pNDepCn#7eJExL` zM*cUY`~OqYc?2DodnT9Ov@f}GTe?lO(&7&*1mG_6ZB9S$~u z;alt-vDsY#Ij53Ro|v?8VwcXyPt>t4O>DQu=+YQl6T37+dIR;{fl02wq}Fm*plPG> zl*X?ka7b&@UdJ9sYi-+*!y$*2hi7;AkL}WogMOppS~mIvdR@qtp&gOwUA`GTF^2A# zTvtr)1)0JxYKx{PB$|zWaCEC*XGm6CVrR&(p5)BEx9+*MBX7dd;?CqLTgtfDE9{@+}=vw|40loYY62^MUr~{AIeR4qxMwi}zVNhL&{=nc0(=(w#WYl{l_DvBZ^F z(%F(Yh4=Jez!v$I`8^@AY|MjWS~ELCa@vYJLkfG6Q$0P5IGoinqO_xQK}XcWE`7yy zJtQAUX-n!DenVH+EbT{lt&?3I4?Fj#wmq| zAT1toWRYLRpB&@z3b2TqigL+R)OifyYQbD*mCQppVj(X|OlS}*ZYv-g+PB>{O%Z(z zTOUF2PXKO(Z3)$6a7^t8Xry(ZEM5Hf%f~>>gD9T*m`F*IV-By z$B|#eA?xGGhvH)!QpKDdDu3AEt18U(=GxV^8k@8Ij`f9<91~x@`*q?YIyNMdkD=x$ za#D0}7)5`kT%n488g&{Aalqkz4VYXTBjs@V6@#|w{Vnnx3X5Wwe2td@(F(=ZfH*exB>1ns*tmcw+4%rChn+hHhs1NAQ?0oCo&}^){P-SYv=a1>W}yD5 zztQ3&VdPqoT8L=8w}HKw34V}s^Zi)FTO3ZEk=!910C@V=q*eIV&p zpt#`T$gN&!7V1Gt3SVHw$yjk00z8%UOE;5BT4!Icv;i?MG(Zct59k3&%!}EZ62s6z z3abu3Y2iBnjbkWCpCRJ?oBUO$Q1BFpdp1RB^zp662WM{d5ntZ)Lq7L$pjo}o)TJ9b zz<0*wL*%~kUD;!g>N>M$oY0iI-l})n8GOvy<)+Z6kiP{ zk;{Z5;*u?;)CDv@mm<2igp!Nx=eGP#l6d7uu~|3*ZGQty9YgTG7$C-wN|x8Ru_OEvO#^TYQO^0WBwZR4oFT+C(j zXtf;teo<)907MjNU_U7OZ64rXarX0}VHTx_ePNW+4>|kc*+d`OSHv$kuyE5y z&Eg(&7@HMH^#KZt%HDT_U{Q;E9tjn97Ke!MJyJxJqI$atVD9!zk~DDq2}-(!Y#KE% zD^C1sdyHDceMv#=_2)>!);AR`CZ95)8!5*v4sN$Zf@X!w(UPaa1+CD zm5wyM)5ntM6BEN|<_QQq7V+k}<-k$xKj>K^jq(q{VM&LBTnF{|v z@RYb>cW!`09yC?BT_e7{J3S3uh{Ax1P-we;KI#yl zpGF$;-(o42ix;2VU58E$^!OrIR8*U5&~QV0UFbw?zd#E5;HWs}>qx*m;#QY(d6QLG zEu4T>HgtqmN1cWT_@@*gD5yAj-_2yNxMyF+Ff14R0hn}BZ_98D z|Fz3ttp1cp_fG{En^?BLl$OZbx9?ZWCs8axxA;{paJXT1leG!X<$io2C9CoRPK>iW zGO=3?K5lN6{sVh_7PIo0ua@Mgz5E^btR-adVhRVLnz-}X0#zt<=a|S>kvtbo=gQmT zo_mbu-im!pL4@3-mE*)z9#+F5z9LUzxdF!ur1+^VnfQqz2ZxO1_U}?G;}tk(A!URb z%$p1VyaRki5;6C>k@<Gmbd?Putx67d*c&*O0>PWHK9+q zn+WG28w^h7(M-s1j+xvpUg(SxEr){1I&tM8Q{c}yj(#isfY^2@0c?-XL+M37Vi9K= z1s|f@pIh(f|Kol{H?c@8qQHLOCn>=T@Z`B?gsy0#yxrkkp(0O-=U>YT680m-UO>!F z1pg2Vjw}d>fw`BMeBBCr4H#5Eh>ssB)bT@tch&wlk`j(1^&T2HL**jHGQ?4@#{=?P zUe6_I;{C5rA?w>edHt{=gj0tT{Y7Y40yN1J_q>@(Vz*tUvEsLHMo0A1OD!!y0U|U| zG3u>U72IAUkK=7A93({Htx)o8`^L8n^09npDzK^rXMom-BV>GStwFHbg&M2PAZ@%X zU<4@UEQ})%qVO@Air>DQME)V_-b*dO)rJ}MGX*~=@dH&XR_1GKMS}Gmyo69HE`84s z#0P+MC{@m^dU_b%dw#ns?HX-V<{n*-boFqy0GC6m|M4e#GUXsd$Feu_lJgNp;r zSN?+=^6PzS;@U6M#l}0e;;Dc6unR{?c+@k14u1k!Ewd=WfRm4gC%8=ciW%D|zpM+@ zTU2;Hv#9N0NlHJ92K6aZ+yr`9E)@^b-Gm+7L_&RhJjz=mX3fi^;C+b^hVY9*67i$5WjWX1Fv9@00_*GelDjf8zL$jgpPNJWn6d zM*t)<{~>Xf4#lRSJ`QLE_Ip%+Szk1S)K}~m#2}X~9pw#H(3^tFI43sU2yM|zy8HSZ+o5!(=Mo^}q5pMsj!ivGRkqsn#ldTC2xHG#p8A`aC zGsQ`&n|mJkhT?nay3MnP$Yz1DjDwki!vKzwgs^ZCQ$1Ml1*ROB;_{&vAJ^j}-i?BU zg3Br4D}3fs{Q{WS9mX5E1;y1+Io9W=l1q^CoFpV=@iZ3kJ&PK{?O)X-;LUD@G@<{n zDfVGV#f0?ZXlQj&FqfNbH(PhjXFv?V<&7Z zI~fq$k&xF`-(67ZDk$wNnC42Db}BIR5#QFbj>P4+1J0r;D_LZHRN!}|+PQHTgV+xPh zCMpT?Qb^lSNO^VASQLPgG{5CU47u9A>cmnKT>`mof9a41oYqjg!gDd?ju6MVBZj&a z)>YOjlV=>fwyw@x-(;?>sB5sm-4}{Y5VMkyeGNJV>tXiyDPm)HETxL}&D{$LsHUHL z9;Chsaox%J!FkZ5fP?WOohklwGL@D}lY>5~Rw2%FFJ|!@sE=w9n3)@V+dpt`BkaCe zRGS8lX_Z&_!kMYkj<;?6H_&AbCFNq!PhnaJr63E6WwLvHnfVP8rn|=%WyKm|kzrWH zaEdh+n9w26ENAPsgNMB4Ubrr8Cj7`A=5ao!G|Sgek2{$Pr@&bqzV+u2{XM=IIwSQC z2YrPQ*sNd&E5KC%?&Rot0>^(P1Xw6RUPjrW6X|F1Z5CZ0g+^X4hd1rI$M+sz2(G|V z7=d^U0xE<6DdBISIB>w}2l|QPQ1vku|D9@ZN23dr|2F!An(u!!wDKF!r?rZKA@H~=mMw}d|j;)h0H?NsIeRG zK>Gg*^DQCvVQh9KjX|Q&r6auIAzF)mCtbtGDt>S(65KYq`QfC9i{>OBOK7v^K$tf& zg-4jEE#asZ*Qht8LXQ#6?4X^5qSHUpK9;>!NaHYeW(hn;?NYAMHmg1NX(7#8OLVgu z@?#(`oZqogODwJqv-O+wq6NogOs+96UXMq5+i&5Lt-Qor4YHv zsCNPq`W5vbxWA zZnX^1J1c8!OKNLuaK~oN1jjR|r-piAFJJ^m1-Fj4Sza%L`J1c2fq{ zCF&d4)n&NDKY+CN8W}Vh-o_2OWEW;ZEpCpdh()JE*}6w)NXrNX2rWFVUHJ}ghmR*L ze|L6k?%rX0hV6^(Oe{QHbRuzzD`EL>HmE1NGtNkw5+T9qHy*Aey>TO`IS0js7#yh> zL?T(G22L`(uDqUpW08Q45uEU-@x3^zg@!uAEO0pfFSHl8eqKNhitl~CN-X)}t(GL= z42(|TE~%54dJpL2aZX|CI|NoN;HsCqCFTNE+&aMur%xNGMYtl7c!%F9a7WV!Y`~Q> z*X*d0g)vC+{u_sTpo&|rg_|Icnik7@$EhS;EoJFwqzI9mO62>8{6Tkj=q1#l*;e-+#W*@XqzAV}=(HN*-xLE5H+ zp@RDG{>DjqrHp)4dNIHJVK z^s-DAJB5CQm(;m!+1+_1uDp_t+{sWlg^Z`?Kqf>_z)GRT^xPzZv_1zGq`}y(IrBYH zaW4N(yz-?{^#-s8xPZY52;knl3QxevY(@JGUx^ALZ$JB8B$;{^IY?qkOmRo-qsZJf z2)JLsbLdtI*2db^0yiETp^$HXWEqKDjsmx&iz~kmqc?%U@%?25Nf+<_cUsH0h==bP zC3e8=q!LU`MgU{?c>GpkY8C=+v~uq*w_%TA9=ELii79@A!A&kcSu>6V@@1Z3tOR~` z44>$U+?`P)W}nNVn-uL8=kAn8IH6)0n8IgpOs^w0R1-p^NG@hl4LYe)#d#O?q^-T~ z;#v~a0JsLohepcIHGxYQnmF=-u&LtM%f95T_Gy==kl|+$B^MrxAmvt8)q?X&_&25% zHhV*(&;`u~nSzL&`{?mtA4LB3!j(ldwtppXo)DU`xV}NK3erf#maA6M+5Yv_&4dP1 zamBSH{Im1gt>nx0->yxExG@}X5EZBY8Liv|>9b<(pQg0?Aq9FN7RKVWOEGKEVD5no zM+qLxS*siZV1ND7pM2M@`s+J6bivM1qBn8mC@9^!IUq&AK{81Y8U%@XK1DimmI$9KRI8L6Bi-(u=|uGE+YUs5HtuU*kMkmzvy4MzdTE$yVucoP~Ux_h=xlTB&sI){qoAjiT&bUy?MA`zzK1 zddX?Q9UgnI@5d3KOcwlbthZt68UU{W%-u9b$})6h8!R$=Q%73W-pplw#58R;U-NESumML zbCj$wgscq~Zor{%gbyKBU&=Z{NCo*5o#~TkoRY27li$cFwmg(XwS0#Jx(VxDK>$J$ zlp}%|EXY9+haet-8o_-C_yyJ;OyT9XU_kIIHv14$JqSKV(1E~(;5dSB5&Vn*530g% zqy-@Qu?6nF^}&&&LsW=IfKELj4O8eC6Y>%4!^+&5i6FljAl2{R~jJ`0^s4OEFN{C!J?1I*$%(!qP@lnnv7s4`?)5(Q}BwiVFVJc)LUI^1D z^DjX7fAEDIqMS%Bs6v%9$%P!9vWZ-XQ7Dry=oEljr&4DA5*Vt?ypYAfA|IhjfaDay zmWPv2^%&&@a$y2>ZVD%I>WiCMZ~_>qWRFIYq2zw{aU?mM%iY;JoGCX$dA0d4Q?D=J zF`V_lO6=7P63b3Rks)-f()mXec|%FAuww?|G#$F$-6nDiC1&<}I(eORuvaq3X!@j* z{gy$V4|8F4GawkKa@MjVnIw+9;QTC;3{|Unomk2uhLN#4E^D}@|1@D$!$=ePkewVx zj*$~=M*-QCaRLy!Rko%@bv1S&2}j18;~lTigPk2m(21anl^2qU@P@)8g(QWXW=9K2 zo{DSZUUsFB%z>d#8%~N8O5s;nBDQHXiO=uAhFmOjyA*|^SKjfFaXk*Uovcrdf5ko@ z4dnaF8CXPiDAag!3<3Y_h4G|;JjoI!kR&pnO`br8Q<&nq3FKI8-xS>ew#Ei~P4(&u zvtWkImhmp0wW}TkF9} zhE^~+$wZmOcFzJMs#e90&4j;KshImm2>Y1P+L#z@9)}Qj&VpT}$GhosZl~GD&nY(xRVp zxVq#U8WYQffXJrK`Q^9LW&s)hKWF~vInmj!r8*rDwT_Ms*5(8s!V4RzA zwS{M~;BHLu(cy@_SBpqOnBw-uq>zkduEivVK6K?(?KutEf;A`v`I#NA_~RQZs0 z6i94~6r#~;=fpY^Lt}9wC2qAvdPz#K;F|1Lc_zu$G>~{{YmJ9`gB^T9h%;Tn`B4K2 zqlIecHw|#8A&)bYK;l%~;F-;42(Y^%%^(yih{fLUE<04q@Y7pqP?EGqy;9G;O5UfzMI0q<- z8VC%5It>nTsHg!8XW$SgB51_NY64jm1jY+}Uf*_u1*?Lk&USKb;CpE$AA%DNe>+D8M>)Eio$Sm>_yZbIs zICrs=caci+8XI{x`7<;LDqmHm7#6KIxaDOHE6YIB+{0#UAZehpR&5{_a+H0xf!w58 z3KfM~Rv751{XH!pF`zTZmPzx*r-iOf2Yb2$GJw7v3KHR3yISN9VU9Y;x5Glq?m@ ze;e$^yAX9Q%iBh#lIPi)Z6t$Saz4F{)GJcIhiVShjdgR%%STGLxWB@hn!?<=DdWp4 z=1eM|dBdFINx}g(ZU>1Zud?|&$g=P`fDb}q?XbUWD{Jgaq`5xFPVFFuptrHmr_Nf} zAgr#aTLk8i-%g-z8ymfoq*FhQvt}oGOi5ap=5a7{K=oQ5Co6)Hwp{70T`Mv4R`%25 zWFoy$!}6aXGs2KT+=^w^)iy~Ea*=V8ZF_=D%j2;gkqz|~UPiQ|)65h7i&4$E9l5Vd zie?jbvydmrgLJ6I`P7r-ZJK`)kPCMMCGco2VaA-#5PXi{3k1CYyu7%Z?cPfwRi8qZ zBTZU@uDx&?yhX#l-%H+!e*zmk4&eIWp)avTw$$RAeI$}vHH_>hX(}16*D02}pA7Te zgRMFLJj0gnC-E~5V8%fNyAW_0^&qAmLhuNJ#}M#t@52-_hwwatHU!@xz|jg{dSsLX z9}wKHKJ+vJt>=)lRuhR}hG$5r>NJ+_W)07fhIm{Ww@R{xy)R_&t#BSIZDxNwLx!uC z!I9J!$7UTRdgsgo@Rql6EtalBa0db;FT`Z=NCl}iYkr>G9CHQ>xm}Nx_FB^nbC0cm^z!CD<7f5T~Z%_i> z?ixEpr}LXiJU@ETb7SHP_Av^{j&)%ov#*eN_E zPzD0EX^}K=sU#K~VCb#)+%$OjNp9aI4J)hy$lukqo*-Q84J>N-NxSJH>v##&w5V}@ z_Y#>xW8j4dk0*>m%4?BJ6k*d}1$*UHw*FOe)hLk$X{pBz1{cooij4q%T+hp6zq8%1 z!PUolcI-94uTij*uYr|wj9q?>)am$*(y*;ZNDcXQ@3kWYlnqwm zE97xs@QlrJ@GV8N?4zJN-f>PlN(xjyi+~Ph1pt=u4vAy?-X`Cs;JTbeEA%WnMkITR zuaFGTN-sUI%|a?W^bSc>;cCIr`ipnSP}N^B67yv?>oj@H>3o+gBvpJ7|8D)j1L9dk z92$m}NlH&zqP{g9u#ADyZ8iqU)>N78;HZ)olC65544;UndN1Ain@}SlW3ZKl^l(I# zOC6Q-yZ&OJJ)U`+8Y`M=K5$-qpO~pfojGs$kSwJwCP3r%DQ>8*hnL>17Ke6@6%Ix9 zHY>zU9>aB{a56xbx)6k5F)qkwARr;G7$PTwF%Pe$u4?Ck5cR}UhCuFIh|UVdQcj#O zOsSBP;h5seF9K7+=+E@}pgel^#tv{U>wTP$b-;VW^d~tRcZ5WSaUsSzgxg|VQ^rYb zqSYcQ1aEIUPR7DbFdKiI{G#HuA7CRp!E8_VaW3y9TED#ho#_t^9HDqYW0(QKZ*c4} z8*Y$JKLWDDS$|wZnSwprOKyS>S13<|=P5w$oPL`8MN~mJ8#9~zB}Ae8$!fkNlZnZB z@JrGoSEpf7fP!uL7VO6}&O_glSYrA+CgGd>dR}1Hz9TUq$XIUG46CK4sm{v?>1WAo z&IoRQ?*|?{!eBb~h#c+K^_46#3vLap{Ty>Wyx{Ty)PVRu?t2){j-Dl*r7Xmph%JLHCJ!&QyJdrD45a;GE6K#++5SOU*6 zS(xSv%^lVG_&5{+AK@@e;Yhf)g0ll3j?^VG)&wjsMlcb8jm`N5sCv@*=r80fG3KCJ z=KPlgg=fJilzJ85UKh7U4tw$vxu2Y6d6!9pp`TN@$=YvSO-1x`Jo3eW4+xTc*jJZH zIW;KQh+oMaDlX@9*|A?qgE0Z|dye@xU;{2sr5ZRUt_g;zuK2)^6C@?jdWBq31aX^+ zD}ex2TmN+hT8NTuhzA9D1*^7pKxqF7 zM9ZU^xNrG9+Z;q6re>{kNHD#Lk`3&3J)IX=i72^Y#j(w0-{|Q$-~K*Uu-s4@LLOw3 zLg^6Nq;=MXQn&--raN!T?J*HXGFXy7#Ja+u!97}bEsS=@@T%Nu+lEzft9cdmBkbSd zG?{MJvakrc1FYm1B4{xcwa#B7=wUespSBp9K|=c{dl9G2NBAi_A4{Xb)#Vol3jQ=p zi=z`kF*n4~Vs?8u9IW1squ>wII=_gcp$c*byOcop=ih}>&O+)OKn}VeAGzTx;l#ZD z&bTFgp1Bg~NI1;tl4vH`$VMj70&>K;Jc*Xc!Sj1Gg$|4ACs{2b>_^?p0#bnqeq>px zbPUQZSsaXYuC(hf2lJ4X|ow?2(s4`_(<6cO2vP%wyQ53)UJG?jesd_RpYQU!C7 z!lgM9))Xp4vN5@Ie^lQNgm?sqrm$NpmOxAeuxu;?x6m?D!0Pe+#J&N}iXHq`+v{Je1L3_{2UM zFgz}epz-P#p^KuMZnKRQEd9hG|J!Wl6ndUVPqFZ!-j%yNEnM~o@zJbIilI@GB^&`7f}^0 z@O7>zqWcy2-ueWpPvWvI6;aBtIZhkob2F~U8U(ik81%t~Og}tuK%FhvsDd4wK*Lm9 zA?+xVy7{#j&b?PAz~$OzU#2UjnJxXI@xM-$%TaC`a8sjij*|CnF%GTIR2H~>B?Xkj zYo5{vfTXv_3!x%@4??imK-;cvXtIM^O_r=Io50T|(_pCllC2UfX#7c5bSwL;nC8$m zzRrM&bc#F`Re>YOv-D`7fnT(y$|mW80rX-mlW7!5XOB*%(J>fdZc;dcOCXTcwgf^{ zyjR6GA)UD<)AB5IA3zNq7tmHi`RaPWnGStj4Vnc5M(?Z5V1ryR&%l>EX9~5{a6A2F zL>++cAl!%RGZdR19V=Q^^0@@H1iL?f_Ili{M@73eN`w zxYZ)@2kV(ZW6%t^JcDMWA%A$S(*cu$>Dl0aS^rW$&RWW86ss-VffH_wDCX2zVM+YrC`*b$_apX>1N&o-18F4!(ih=DCs^aQ5mc^9Q7?p?o zW6Eg+`Iy~QPE*JeILI{8<$SuFYKaP2*Ykdy^P{NohVGx@85O7P7Rb7PI&j3Ln6vEV(%^lu%&hP0G+4T=IsvPUv9 zxD$>eSDc1<^gQu@ANh(e7KSb{!+biE{EIctrzRSpbMBZ=kE&ICe0MVQBKWe}I<|EY zEh0Oe9gFA?67~QzpDRG%p~r9>jclC8bQYRTV-&2&LL=t&tFivs&cb?JtDVAmzk!c9 zGXclr4ydtJR5!uBhhVLS`S$Q3bQy?r@a1<NsBNV`6q!bKbg;`)yO@o$)}0oJ@)$BG*0{J^|1fdBW5>3F#>})q^!G}brHyuF;7Hv% z>3Xk%f9k;-T=OTC46=~EXGM0JL0fdrWp-*MLpc*gA#ErqRYCI6<0H4$xCw5C$ANdu zKQP4#An~0#Hf#m`B^BGDf1P9ENH`~6-|9S@wUR>klg_zzC4H3o;h4(=+_yp>G^$my>=uwy zFF0>(p%0PdexsNlUHEb5dV)2vfOTM1A8{6~qf?0QN}Lm~eT8kggI18YoagWlsbjO& zQ&TY~0iSpt@;thzJ+nhz=VS8Ro}9ppMqE^=(=VJ=O7`k{n2O8!)q1djbsu1d9*N9u zxtrz$pM;!2%=94&=qTpAn+8y~j)9a;cK&oXEmq}7q8i6=3eoTzJ>>nX0oVIuzQFRG ztnz-kV*Y7Jn_@g?7#t;^6vy>n1vMY$97KZGZ0>+MkH4n^zkdQIy+o=enY(n_pCfpiKMeKYl)BwSxKtvBMc~HZD(lSiRPCo#& z{L1OGnU0mKFC&IXC7ZdGrmMM(i&C<6u#eNHKuMYK8$hq_<)yJ$4~ zY%A4Je?RB9Tj3Z9-xvVIKSS#h?yKXz8i6ane|x&jdYC3nmL!aiL{Hvku*wk5VQo%I zK3T2;uV=_`C3|ieyvf$~Ff4bdpYzzm)Ip6gxX5t`;sFd|k6ADY$8eUrohD1s+$nxg z&4_gq5LDt4Uw}%I+hs2j7eg4z=7NX~!Wv&=7Dh7k->6IX?L1b&<7D!KChh?E_DTgf z(QDufsY@Eb#hME3rQF304Hh1`z(Tfz#q<@+*bZCL;OCsT9rj|vWbCLE!BhZ)iH?JC zB;gD~*@*@cK=b_A&>ipv)oD=BuPCRmt2^irV;}vz+LGU^Uau`_3^2z5K)7o+_0f8L zdK3KE?K|l=^N~{={^NPjipOPX5l}%2zv2>c-ocF|Tmj%=9FL=Xu#UXWijC#$lSoVa zP%%b2ukE72#P~b*ruBONz%QJG6IOfT;ss#R?A&t~m`7lI_$vJS<&{FwrIFw*jL?Jsxl&8mptv+Y#yU zljA3X@Y2xx$spMNeD*L|ZYalLizNv79ytLiuRQ=pZ>HzgxE4u*GFLc+03C2VXc8=8 z{7K5i%$|M%RPj7N*7F4Y%y+;|uk+}Ww2QRh`A~Qj`#OT)H3a-Z83rtKD02)GvLV_H zyFzcSLur_S8L#6KDh<;xjc$I2g4cT;T9?5ZE=4T-CI-Ey-ZdQ1IW&PA-A1dGg}{|G z7!Z1z67Xh<3?P??a9i&qM$|HB}wf=sv=#RUxWGP_qF z--c^xz_kozar@~I)w9rfm7L951BUa${gh>6hHw;zF62QMUKu$IyTh`<+ttF7o~G%v z#gEN?nii|yz^T5aVCO?=1Z#hqemRck{8P$?vNsVim`Z&#@#6QiydJ-meew*5j`eJhD2trnaWXqopQRHO;Mc1=NR$21 zRa^!KM6U5#7E| zGo7@M9AX=s^wu~op@m0*_>MrY!@>YA4*~9&ATW>|rlABZ_(Rmg4L(0p~*G(83dhXvVz1wdzJNhylst!88ewiA5LhBJ@HR8S(d2SPeFIn`PVCllA zL#Mw<(^TBLx|=n>NmFRFk{REGwSMJIn%u${jU(WuFUP{ImI0^`Jy*JTM3eOGbvD|k zI1_F_^Nw0@EL>OP%g4f9@aUc0dMrY#gMVs3U=Y@*kH-p*h(5O?cT-l?HrT9_R)BA! z+qv~E8l{}UkN0>3kCANs<`vI=4hO);h!^nvp$-Bc%J+~rc)QJFzrRltXt2LC{$KE^ zU+~87{0NqLIXm(ZP4GR7*tpgDKKlXkCFeO`DJ={C7%H}*g&WW2eGEsLIDhAokLimP zqEh0HgO+~MS$LePl#}P;lJjvsj}+wY2=49VrdYqd?Xkyjqx_9+yNa#vhJ`HjcfQyS z@ld3aC4EXCDt!-Ya~z!ZeBHR6$FB!?*S%OJ7ze>Si&`R_3G6! z4`U^+Xp1q`O4#S8>1}kazw?$e)F_AE)_e`VlS=mC*R&|Uzc)T|-VI02JO725z5yF< zr$770H}n;fE1pk!ZPq=kNH&VP+yU+Hp0Zy};nSb@7$_}hvX5TyK@*BzL}WY&lZPtu*ho8~ z;z3WRF~yzTT3j;&0`6$#OK4%Wf57$RZO(iDpleBhIgrHd3%@ACzZc7lEb=eo=JcJ3n(rgD9A(F zgIiGW1R^{RMG+MjP(eg+L@r$cMNVOrMg3Rxn@I@kx8MKE&n^1(QC(eKU03()tNZPT z=GnszhK7a&;oo`w;*=+sZwY%Tn~evNHUwg|e`GI=Ywe0%0AmwfaSMXRCb{AfCc6?A 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%0Am|pegtp<5 zu`>uc@i}1b`~$I;nvC-?aiZVd{TC8YHHzHBQOs@9A8830N}Qy{Z!9JKlGfYe{WdU* zc}${fTNviNLsZYA$%qchd@cz3g(;!+4KnVCH`>Ca;o}iE0_u)A)L9nn~l}PbZM+mEzid85b*O+3qUb6

TH@2HA;Ciyj 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 diff --git a/ui/pages/dashboard.py b/ui/pages/dashboard.py index 607eb1b..c047fb8 100644 --- a/ui/pages/dashboard.py +++ b/ui/pages/dashboard.py @@ -296,6 +296,7 @@ class DownloadMissingWishlistTracksModal(QDialog): self.download_in_progress = False self.cancel_requested = False self.permanently_failed_tracks = [] + self.cancelled_tracks = set() # Track indices of cancelled tracks self.analysis_results = [] self.missing_tracks = [] self.active_workers = [] @@ -481,19 +482,22 @@ class DownloadMissingWishlistTracksModal(QDialog): layout.setContentsMargins(15, 15, 15, 15) self.track_table = QTableWidget() - # Change column count from 5 to 4 - self.track_table.setColumnCount(4) - # Remove "Duration" from the labels - self.track_table.setHorizontalHeaderLabels(["Track", "Artist", "Matched", "Status"]) + # Change column count from 4 to 5 for Cancel column + self.track_table.setColumnCount(5) + # Add "Cancel" column (no Duration column) + self.track_table.setHorizontalHeaderLabels(["Track", "Artist", "Matched", "Status", "Cancel"]) - # Adjust resize modes for new column indices + # Adjust resize modes for column indices self.track_table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch) - self.track_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Interactive) # "Matched" is now column 2 + self.track_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Interactive) # "Matched" is column 2 + self.track_table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.Fixed) # "Cancel" is column 4 self.track_table.setColumnWidth(2, 140) # Set width for "Matched" column + self.track_table.setColumnWidth(4, 70) # Set width for "Cancel" column self.track_table.setStyleSheet("QTableWidget { background-color: #3a3a3a; alternate-background-color: #424242; selection-background-color: #1db954; gridline-color: #555; color: #fff; border: 1px solid #555; font-size: 12px; } QHeaderView::section { background-color: #1db954; color: #000; font-weight: bold; font-size: 13px; padding: 12px 8px; border: none; } QTableWidget::item { padding: 12px 8px; border-bottom: 1px solid #4a4a4a; }") self.track_table.setAlternatingRowColors(True) self.track_table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows) + self.track_table.verticalHeader().setDefaultSectionSize(50) self.track_table.verticalHeader().setVisible(False) layout.addWidget(self.track_table) @@ -519,7 +523,16 @@ class DownloadMissingWishlistTracksModal(QDialog): status_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.track_table.setItem(i, 3, status_item) - # Loop over 4 columns instead of 5 + # Create empty container for cancel button (will be populated later for missing tracks only) + container = QWidget() + container.setStyleSheet("background: transparent;") + layout = QVBoxLayout(container) + layout.setContentsMargins(5, 5, 5, 5) + layout.setAlignment(Qt.AlignmentFlag.AlignCenter) + + self.track_table.setCellWidget(i, 4, container) + + # Loop over 4 columns instead of 5 (don't include cancel column) for col in range(4): item = self.track_table.item(i, col) if item: @@ -529,6 +542,107 @@ class DownloadMissingWishlistTracksModal(QDialog): if not duration_ms: return "0:00" seconds = duration_ms // 1000 return f"{seconds // 60}:{seconds % 60:02d}" + + def add_cancel_button_to_row(self, row): + """Add cancel button to a specific row (only for missing tracks)""" + container = self.track_table.cellWidget(row, 4) + if container and container.layout().count() == 0: # Only add if container is empty + cancel_button = QPushButton("×") + cancel_button.setFixedSize(20, 20) + cancel_button.setMinimumSize(20, 20) + cancel_button.setMaximumSize(20, 20) + cancel_button.setStyleSheet(""" + QPushButton { + background-color: #dc3545; + color: white; + border: 1px solid #c82333; + border-radius: 3px; + font-size: 14px; + font-weight: bold; + padding: 0px; + margin: 0px; + text-align: center; + min-width: 20px; + max-width: 20px; + width: 20px; + } + QPushButton:hover { + background-color: #c82333; + border-color: #bd2130; + } + QPushButton:pressed { + background-color: #bd2130; + border-color: #b21f2d; + } + QPushButton:disabled { + background-color: #28a745; + color: white; + border-color: #1e7e34; + } + """) + cancel_button.setFocusPolicy(Qt.FocusPolicy.NoFocus) + cancel_button.clicked.connect(lambda checked, row_idx=row: self.cancel_track(row_idx)) + + layout = container.layout() + layout.addWidget(cancel_button) + + def hide_cancel_button_for_row(self, row): + """Hide cancel button for a specific row (when track is downloaded)""" + container = self.track_table.cellWidget(row, 4) + if container: + layout = container.layout() + if layout and layout.count() > 0: + cancel_button = layout.itemAt(0).widget() + if cancel_button: + cancel_button.setVisible(False) + print(f"🫥 Hidden cancel button for downloaded track at row {row}") + + def cancel_track(self, row): + """Cancel a specific track - works at any phase""" + # Get cancel button and disable it + container = self.track_table.cellWidget(row, 4) + if container: + layout = container.layout() + if layout and layout.count() > 0: + cancel_button = layout.itemAt(0).widget() + if cancel_button: + cancel_button.setEnabled(False) + cancel_button.setText("✓") + + # Update status to cancelled (column 3 for dashboard) + self.track_table.setItem(row, 3, QTableWidgetItem("🚫 Cancelled")) + + # Add to cancelled tracks set + if not hasattr(self, 'cancelled_tracks'): + self.cancelled_tracks = set() + self.cancelled_tracks.add(row) + + track = self.wishlist_tracks[row] + print(f"🚫 Track cancelled: {track.name} (row {row})") + + # If downloads are active, also handle active download cancellation + download_index = None + + # Check active_downloads list + if hasattr(self, 'active_downloads'): + for download in self.active_downloads: + if download.get('table_index') == row: + download_index = download.get('download_index', row) + print(f"🚫 Found active download {download_index} for cancelled track") + break + + # Check parallel_search_tracking for download index + if download_index is None and hasattr(self, 'parallel_search_tracking'): + for idx, track_info in self.parallel_search_tracking.items(): + if track_info.get('table_index') == row: + download_index = idx + print(f"🚫 Found parallel tracking {download_index} for cancelled track") + break + + # If we found an active download, trigger completion to free up the worker + if download_index is not None and hasattr(self, 'on_parallel_track_completed'): + print(f"🚫 Triggering completion for active download {download_index}") + self.on_parallel_track_completed(download_index, success=False) def create_buttons(self): button_frame = QFrame(styleSheet="background-color: transparent; padding: 10px;") @@ -617,6 +731,7 @@ class DownloadMissingWishlistTracksModal(QDialog): def on_track_analyzed(self, track_index, result): self.analysis_progress.setValue(track_index) + row_index = track_index - 1 if result.exists_in_plex: matched_text = f"✅ Found ({result.confidence:.1f})" self.matched_tracks_count += 1 @@ -633,7 +748,9 @@ class DownloadMissingWishlistTracksModal(QDialog): matched_text = "❌ Missing" self.tracks_to_download_count += 1 self.download_count_label.setText(str(self.tracks_to_download_count)) - self.track_table.setItem(track_index - 1, 2, QTableWidgetItem(matched_text)) + # Add cancel button for missing tracks only + self.add_cancel_button_to_row(row_index) + self.track_table.setItem(row_index, 2, QTableWidgetItem(matched_text)) def on_analysis_completed(self, results): @@ -677,6 +794,13 @@ class DownloadMissingWishlistTracksModal(QDialog): track = track_result.spotify_track track_index = self.find_track_index_in_playlist(track) if track_index != -1: + # Skip if track was cancelled + if hasattr(self, 'cancelled_tracks') and track_index in self.cancelled_tracks: + print(f"🚫 Skipping cancelled track at index {track_index}: {track.name}") + self.download_queue_index += 1 + self.completed_downloads += 1 + continue + # FIX: Changed column index from 4 to 3 to target the "Status" column. self.track_table.setItem(track_index, 3, QTableWidgetItem("🔍 Searching...")) self.search_and_download_track_parallel(track, self.download_queue_index, track_index) @@ -852,11 +976,16 @@ class DownloadMissingWishlistTracksModal(QDialog): self.start_validated_download_parallel(next_candidate, track_info['spotify_track'], track_info['track_index'], track_info['table_index'], download_index) def on_parallel_track_completed(self, download_index, success): + if not hasattr(self, 'parallel_search_tracking'): + print(f"⚠️ parallel_search_tracking not initialized yet, skipping completion for download {download_index}") + return track_info = self.parallel_search_tracking.get(download_index) if not track_info or track_info.get('completed', False): return track_info['completed'] = True if success: self.track_table.setItem(track_info['table_index'], 3, QTableWidgetItem("✅ Downloaded")) + # Hide cancel button since track is now downloaded + self.hide_cancel_button_for_row(track_info['table_index']) self.downloaded_tracks_count += 1 self.downloaded_count_label.setText(str(self.downloaded_tracks_count)) self.successful_downloads += 1 @@ -866,10 +995,16 @@ class DownloadMissingWishlistTracksModal(QDialog): logger.info(f"Successfully downloaded and removed '{track_info['spotify_track'].name}' from wishlist.") else: - self.track_table.setItem(track_info['table_index'], 3, QTableWidgetItem("❌ Failed")) + # Check if track was cancelled (don't overwrite cancelled status) + table_index = track_info['table_index'] + current_status = self.track_table.item(table_index, 3) + if current_status and "🚫 Cancelled" in current_status.text(): + print(f"🔧 Track {download_index} was cancelled - preserving cancelled status") + else: + self.track_table.setItem(table_index, 3, QTableWidgetItem("❌ Failed")) + if track_info not in self.permanently_failed_tracks: + self.permanently_failed_tracks.append(track_info) self.failed_downloads += 1 - if track_info not in self.permanently_failed_tracks: - self.permanently_failed_tracks.append(track_info) self.update_failed_matches_button() self.completed_downloads += 1 self.active_parallel_downloads -= 1 @@ -911,6 +1046,44 @@ class DownloadMissingWishlistTracksModal(QDialog): if self.successful_downloads > 0 and hasattr(self.parent_dashboard, 'scan_manager') and self.parent_dashboard.scan_manager: self.parent_dashboard.scan_manager.request_scan(f"Wishlist download completed ({self.successful_downloads} tracks)") + # Add cancelled tracks that were missing from Plex to permanently_failed_tracks for wishlist re-addition + if hasattr(self, 'cancelled_tracks') and hasattr(self, 'missing_tracks'): + for cancelled_row in self.cancelled_tracks: + # Check if this cancelled track was actually missing from Plex + cancelled_track = self.wishlist_tracks[cancelled_row] + missing_track_result = None + + # Find the corresponding missing track result + for missing_result in self.missing_tracks: + if missing_result.spotify_track.id == cancelled_track.id: + missing_track_result = missing_result + break + + # Only add to wishlist if track was actually missing from Plex AND not successfully downloaded + if missing_track_result: + # Check if track was successfully downloaded (don't re-add downloaded tracks to wishlist) + status_item = self.track_table.item(cancelled_row, 3) + current_status = status_item.text() if status_item else "" + + if "✅ Downloaded" in current_status: + print(f"🚫 Cancelled track {cancelled_track.name} was already downloaded, skipping wishlist re-addition") + else: + cancelled_track_info = { + 'download_index': cancelled_row, + 'table_index': cancelled_row, + 'track': cancelled_track, + 'track_name': cancelled_track.name, + 'artist_name': cancelled_track.artists[0] if cancelled_track.artists else "Unknown", + 'retry_count': 0, + 'spotify_track': missing_track_result.spotify_track # Include the spotify track for wishlist + } + # Check if not already in permanently_failed_tracks + if not any(t.get('table_index') == cancelled_row for t in self.permanently_failed_tracks): + self.permanently_failed_tracks.append(cancelled_track_info) + print(f"🚫 Added cancelled missing track {cancelled_track.name} to failed list for wishlist re-addition") + else: + print(f"🚫 Cancelled track {cancelled_track.name} was not missing from Plex, skipping wishlist re-addition") + wishlist_added_count = 0 if self.permanently_failed_tracks: source_context = {'added_from': 'wishlist_modal', 'timestamp': datetime.now().isoformat()}