From 4ec4dd2bdbe6b84b74d72777ab052ffc7a74baff Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Mon, 2 Mar 2026 22:32:21 +0000 Subject: [PATCH] fix(ts_web): use actionContext for dispatches in web state actions and bump @push.rocks/smartstate to ^2.2.0 --- .../console-2026-03-02T19-29-32-708Z.log | 6 ++ .../console-2026-03-02T19-30-09-759Z.log | 5 ++ .../console-2026-03-02T19-34-55-496Z.log | 3 + .../page-2026-03-02T19-32-32-890Z.png | Bin 0 -> 15062 bytes .../page-2026-03-02T19-33-32-637Z.png | Bin 0 -> 15062 bytes changelog.md | 8 ++ package.json | 2 +- pnpm-lock.yaml | 12 +-- ts/00_commitinfo_data.ts | 2 +- ts_web/00_commitinfo_data.ts | 2 +- ts_web/appstate.ts | 69 +++++++----------- 11 files changed, 59 insertions(+), 50 deletions(-) create mode 100644 .playwright-mcp/console-2026-03-02T19-29-32-708Z.log create mode 100644 .playwright-mcp/console-2026-03-02T19-30-09-759Z.log create mode 100644 .playwright-mcp/console-2026-03-02T19-34-55-496Z.log create mode 100644 .playwright-mcp/page-2026-03-02T19-32-32-890Z.png create mode 100644 .playwright-mcp/page-2026-03-02T19-33-32-637Z.png diff --git a/.playwright-mcp/console-2026-03-02T19-29-32-708Z.log b/.playwright-mcp/console-2026-03-02T19-29-32-708Z.log new file mode 100644 index 0000000..39e9af7 --- /dev/null +++ b/.playwright-mcp/console-2026-03-02T19-29-32-708Z.log @@ -0,0 +1,6 @@ +[ 95ms] TypeError: Cannot read properties of null (reading 'appendChild') + at TypedserverStatusPill.show (http://localhost:3000/typedserver/devtools:17607:21) + at TypedserverStatusPill.updateStatus (http://localhost:3000/typedserver/devtools:17567:10) + at ReloadChecker.checkReload (http://localhost:3000/typedserver/devtools:18137:23) + at async ReloadChecker.start (http://localhost:3000/typedserver/devtools:18224:9) +[ 992ms] [ERROR] Error while trying to use the following icon from the Manifest: http://localhost:3000/assetbroker/manifest/icon-144x144.png (Download error or resource isn't a valid image) @ http://localhost:3000/overview:0 diff --git a/.playwright-mcp/console-2026-03-02T19-30-09-759Z.log b/.playwright-mcp/console-2026-03-02T19-30-09-759Z.log new file mode 100644 index 0000000..4f67481 --- /dev/null +++ b/.playwright-mcp/console-2026-03-02T19-30-09-759Z.log @@ -0,0 +1,5 @@ +[ 329ms] [ERROR] method: >>getMergedRoutes<< got an ERROR: "unauthorized" with data undefined @ http://localhost:3000/bundle.js:13 +[ 727ms] [ERROR] Error while trying to use the following icon from the Manifest: http://localhost:3000/assetbroker/manifest/icon-144x144.png (Download error or resource isn't a valid image) @ http://localhost:3000/routes:0 +[ 260513ms] [ERROR] method: >>adminLoginWithUsernameAndPassword<< got an ERROR: "login failed" with data undefined @ http://localhost:3000/bundle.js:13 +[ 260514ms] [ERROR] Login failed: Ns @ http://localhost:3000/bundle.js:38066 +[ 260518ms] [WARNING] FontAwesome icon not found: circle-xmark @ http://localhost:3000/bundle.js:1203 diff --git a/.playwright-mcp/console-2026-03-02T19-34-55-496Z.log b/.playwright-mcp/console-2026-03-02T19-34-55-496Z.log new file mode 100644 index 0000000..f459a8c --- /dev/null +++ b/.playwright-mcp/console-2026-03-02T19-34-55-496Z.log @@ -0,0 +1,3 @@ +[ 397ms] [ERROR] method: >>getMergedRoutes<< got an ERROR: "unauthorized" with data undefined @ http://localhost:3000/bundle.js:13 +[ 657ms] [ERROR] Error while trying to use the following icon from the Manifest: http://localhost:3000/assetbroker/manifest/icon-144x144.png (Download error or resource isn't a valid image) @ http://localhost:3000/routes:0 +[ 24180ms] [WARNING] FontAwesome icon not found: circle-check @ http://localhost:3000/bundle.js:1203 diff --git a/.playwright-mcp/page-2026-03-02T19-32-32-890Z.png b/.playwright-mcp/page-2026-03-02T19-32-32-890Z.png new file mode 100644 index 0000000000000000000000000000000000000000..e9b5925b855aa6189a05193df222b92f556d7cd5 GIT binary patch literal 15062 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 z%0D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 R0V@R3P}No`fBZW5KL8np^t}K8 literal 0 HcmV?d00001 diff --git a/.playwright-mcp/page-2026-03-02T19-33-32-637Z.png b/.playwright-mcp/page-2026-03-02T19-33-32-637Z.png new file mode 100644 index 0000000000000000000000000000000000000000..e9b5925b855aa6189a05193df222b92f556d7cd5 GIT binary patch literal 15062 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 z%0DbTd_#e*K^RQcaJ-!1(gbmN`SKGs1XQOkAt}ic)19pVU03+4;a<5$up)53r(74L zk>9@EjqAaAHxf85V{XP@X0NKQmXMOtQwKGV#RVPY6%_Dl`#)q-q4%6~uLs;cRuA+S zjX?=vqoM^3z3Qp<=K}GRnj#2E-)by+`?{c@puf(0JX}4PCO|Q#z|LRi!r#)i>C5}a z2iX@f0K@rbfZb^_XyApB(QV;e3bX$U>;JDq24j*ZJM{R3UL z%5TqqO?scFNo|4+5OMLfx3^#4X`*Cubi6?q|I1INgEMFwMd|S(T&a1u-u=aT)-`ks zaYuOn39XI}Cut5k2BD+dHK+(U8^}EP-P!qj-jCMXac5{mPLEGe@Ri6tVH;onlhtrT zgKc5|vlQTdqv5kM(7@OG>v9UJjTK+ZjtF_%FHdLvrbuy@wgd&4?A0!Sv{kw16AVbp zxG2+F;mMbJdU|_PTjf%mFyyPnA?PUQE4!>$&v%bkZe2+%b12k-Z9jkQwSr#Ci3uoM z?2wtXxLHJg?bo}=6Sg6l)TcwR~MV2g9mv&q$5H7twQ)Sf) zH5tto7MQGBk6$Gq`4k|2(+*)g8Q7dvv-;O-K{BIR*>@it^Uc#nUq#7tmFfiV*3z<2 z9@Kq5y#{h+ix1UIA6=r)>$12NzgiWcDOm=6V0>6%21%1Yj*kzF0e3go>+v2|oW1Vg zqRUf{;&E8m`Z;Wn2Z!Gd*G~QDc$02psPwH&Rg1RDiB4e4+p$cblSQ<4W8mBK52Ug8 z%8wN+)U9dOBh}9x63W6iXf#rM{L?E;$c29|rVNIkA2X?`c%jsXioD&TPBUdRf>?ASP~mmiGn5G0v2u{)@l$Qt6ghEY(?#;@bk zU^A@UtR7!;Y0oxx$p7H4c$s86g~vhgz>6ShIRGYJfm9GbNufrRqroHRhv!1f^)OB2 z$&=h91_{Q79EgS=PU7h-`@)o*E!pT&&{W#H4lh{Zk8|e1H38HRN-Qf2eCQHORATP4aRhS%dV|f5V3FthuGuzrzMgw)^>n z&P_H8;&8s<&Npzf-L9k)gQ@iF_|p6nQQ6{tju^|LriKs-bZTJ^)z`CJ4J-9kI_q01 z@s7f!iYaneK&!#(kH1F^poGU8f)16hMcyZJ%2u^h+O{dvmL0@q2AII&l{NXOTRaX= zlp%Dx9L43{%$87-)3~gU2E?}ZuVX+)=u6Cgkc{;RxJ#FtkkxgVye^oeO=m-Z4hmKv zBlm~qk@fTSGxtCbnKGS~hmh8Tu$5{lrsf9MkrCMxBa1|&GqmWn{Tz5bLU=&wpflKH zl+(TXU^VNL*L0MJdl}dVRo5wTTCdT;#KwqAva9X)bF$wv#v1N*rZLng?)J|2mLbM5 zlKX2Z<$fnAgIXt6v#NJm2+4sh=UEp)o^&JF0pX#!$0ZdNaS;*2(5s+FA;K&}R|=>9 z_i7rHT%$BQhx61h&b5Op4h{~ZP{z+0SE;GT9`rj(hX1kl*IYRO;_D`xjJt}8|KVnl z-76!bRKS&BUOG6G46a-|tD~o*`$Cj%tzYnD4aUabQG2Yc3?-~viKX4;ey9fc5#Gdm zVq#+4-1+tO#@lZ1JXE>4>evryqQd*RKbPt;&WS(si8n#o zR+1UOya0!=5~}{#6>wwe1#1dd-s#!>i?x^LQ=tzwF)?8s=eof3<@ z9@6-{pQ1lUC9^RN64zX!Sx}3;oc`RPcaZD;w4lpHM`wm;Qk4!Tss{u*dk*KGI~66= z``?YY3`!BvuKm&|T}c>=kmBu8Aw)-NG`sCpnq{|I45AJBATXRbP^n_NhsKIZvXRxzf=u{=|JoX9X}{wsT1!p*wX~Q_LdESXwt5EkGIE0ap@;#PeoesGXN3 zX+X&;N$~gwgDqd8`o0lNG;$(i2Y`!blE#D)F=>+np!jr{3X| zxxWH(eKcz2Md~H3t53 z&XMovu8E3@r;t?Iv%r&st7m%8c)Q-@!h?E*bi~p+JKl4H>Mpx-Q(=_*9dLZ*5x#H7 z2G;+4g3ro@>Umv2Aa*#n=QXt&r!$+J3_g;8YyN7lS)=SgIALwHXMYKiXjy$;I_w5K zaaWl7XPO>|eMzumr3c= z=h5=b098}}EJu0gT-e;K$jiHIF@5vhe$=4nWx3e@NzBMq7xv*pO-;@EAI+$)srm3> zPmrQ5#zrJKqrgrvM`!yUDD&6KK7jd%H(O=65^l`2cXa$yt)!Etw`gc-$Dvo}GH+=7 zkCr|Hv5n8nu(7b%OJ)GL?H`H;QBetn17@HTx9b{6|2YqhHi+vP{r%f> zlY!wcdkPdKXdna*|EqSI)GsxA6wq8#BZ=y{&`>lq^jvEc7*pm$sOBZW1&2;LE^ml| z=Hvl;@oxx;{}qz`7els&A<6Rx^KmYJtZJ(7!{0s6>F#OlRHfdn?tT$5I?)9165 zR#A)U_InTr=tJGTiXHyPC-9UvF7xbQG5-U#>KGVI&B`R7DkU!=Dk`C{l7ft)iGagv z{g-e)%lU=8yahCz3U+PX6ibg+erXi>x!`GM9xXLxcK)V}x;Vci;4cz*5NuDklKho+ znOa9jOG}HB)H|tqiUR-f$C_DHo=dpAQ9Vw9y-1|{S_tq{Z`1>yiK^5#a~9kZq&%xo z+M2X>ImU6C90rbRb6;pxeW%|3^~dd_91qgwTCdqZVcjnI4r*M9+zF)yhbIqan+5hq zaRx#3kZXg9f(|)Gb;Bh_Mrp}OO)!VAdMb-UHaUbkG4Db2Q#!gL>`B^gL+Rp&q)|?P zvaKK!3tKkPCEMHGhmE?Uxr*x$eqk7wuVA43sXwR=JT$l!P0!h=9 zaHj2mQ});PgmH6+9v&ARE5VA*yt#ZBK@Vfp+j+VhTUN)2#d*jlyirDK%`ab6zO|^- z@0@_W#Xp~Hv1x&qwB75rEzwsgCAq+g-j1F*=GnhFcPNi2$G*A;9w@U4ALWhRG$Tz0 z(M_HkfAz67c-3)2TVvFtP34H%{&A0CbRAuO{pHK3e2k=MS;d%rDa0K8QQqyTcNHAr zg8$Tb;v?$SYm==c#bTr2(p1`tT-&(T&;b;uh^#7rT=B0Iq0Z0NgIkqMUI`dtAM97B zjWYv@LKvw%OtZI`7OL90;TUgPp}yCt<}t1$Z+-OZi*iNpFVt4eOqDI6eX;b*-VEBl zzWmJwnQT00!^|XH?x|h#(z#5NRqi)X#G`HD61A1dB`b-Zcy73ogas@36Sp~~Q^%hB z7+K`y#Z`Y)Q=;LCm&|pLfa(&~*O_lPFL&Hb-SmbpFU*ml=iD(8u zv0Z0lX*+ML%{y0kG9;a*s_e+>ny(3~@%!WYjz(f$Z%aK$9xZGhD;Z;urN@@9&=TQF zCC(Eq)s;SIiQ%8hiH9y_o(3uU#6cE&1>D0YIG>>FT<;~?Mt@hoQe1|2*wQ zr#LxjG#6ADC64+VCf`cZH~B!b#ZRBX#_u)e)q^i}Zjq9$Ilt$16El6^i<+9ksp9hMq7gnttV{-U+qE1z$1gT2Kg>SQGGI+^O5wy5pn*w3^= zM_F2}<gx+>g$wl6R(H0I)BS}H2J z9xK9Wj>d|1KnQqpq#EwxzgGRTP%`0m1$6PaD6sa~V7;tY-{#;GZ4NuaQxViV29T%C zf9i0a0B+$jb+he5CN_=#z1r9ipxkz)=l@j*3HlqnK=3~&RKNga>Pp82lo*4-<^j81 z4i%`w+7^=5_M>-ER{%2T23M$n=+5!jOWm zH%d0h_2uuRaUHTr85|yPTx%xSDU$>nd@56|Vvr9`$TN4P&w%{w~frKQi z_(djlbttqEEB<-9=pS)N{l^U1O2>fn({W!_6~`9xj(Npfmn>1=PKWcGbfVTMQL5S*Hh!Cs`8>R1tvT0v3HVql9{shKB^Ch9mq#LN*}_* zX_>{|l1>Op$3JzPn~#?*w+W{t7Zkz3%nWm|Hd6Ot!O>h z>c(x0MWjX-Sh{39{b!pYmTmumGoQh--(kK^FLS>wd_74ZNtnPy|)lV zmg^tPN$Z9wX5PlSy7A?IRu#b7U&aTs{pMp|nuH4CzA#x^Mg17lgJfrq34<4kbDBkn zv5MfyxTd|0>p%m75+wUrJW)M>EIt_BbRV2M`@>lHOm_DG7D64r>oqob(vi zA5)gW}#XvlYi2eBSXl%KP{42Pn>d)6E0+$W77&C(hm$>i{TJ4?tG_*&{h0 z{MlRx?Nd$7IKkRUM=C0+uV23ccuF~(X3Xo!+{Hi2SI8poyEA5J4(#vw^acT-B!L<3 z?6}h16A%bEClN1I^p_E%TWSA9iFZT8!m@(Ayde;Xy84gP?G_k-^obkeI)%gUu7v^( z0w`-|+%=y*eVU`#1i38~2vE3ljccm#6|7 zD!Z~#%kcN#&(+_&`JziV&zr~C6vhn({#fT7=D~M{hCcEZHY(WCMqFt9$^~!91A+Gl zx)pF0Q|l4v$Ni#lt7UJy^Qo;d=nc>+8rUqv;o)H(1Xiap3S1VR`Q5R#>mfn~@>JpG zf>+npo|4Maxt?u58ffA8Ad=Gp6iI{F=`{Yb0H*7-MgM!8%Zo=qpsEa&_2+_F@T?iI z3DdOw%$_+^RladH>tug}g1QcjpW1NF!n#Qp*Nebf1<$Jw2Wc_>y zdulgLNI91>q|Tg2`a-0H1Te(ykPSwfNhyzoOll6gJoq@-;5|{Q*U)7Wa`Ng|tPJc- zPAwbs_v#Ie)q?xk?4%Zo>nG-yD9nakIuB53*Uo)ya<&_&1`D@?R{OIKH&`9P7LD^h zw3y###H0*48WxO*sL~iWm~O3up$U4v{ho7<3j_*!u0r2Xbnp{~HL7&B{MjIwan-z6 zM%tsV!Z2w3qZ^z2>Xw{H`9A1Vk&9Bse(QxoI9z4gk-azONgmv_8GwbcK7F@HQBx<4 z`+}mBqotSFp5FL=xM733fxHNmV*@kdcj-u>>G|`e^mg%GT9Yb1!Fq1QsRF}@;{_)t z1;E*X+kzxDwF}H;VCo!B$3x#vTd~NF=Gyv6%ad6m)>^=S305N!<;#|HwhL24VBE*Q zmkXU!fG#rwf{|FeFxj;DiRA=W=4I11Qn~BKq?ZAZwE-7mr-=7{1 zLB+bA{9-%ZjUObMM6EjqQ}7$&o5_g1lrt_L@|Skcjv1ao>a(6tT$jpkOP|D}LLjCm zN7N7KL8kW~Pfbq~vM*q?0|Nt}J?pD?DXgxpChv^91%d~9o-<{Im`nB?Gz$m_0BQvy zWmO2XwEDCIuVnmpU-o+JdW||Bjg~|eN}s%YM`wcs)ajoh#3 znzjE6H_8Ay=rnwD83E+T^x}r{@Qf%*ne%41+EoA0uu#_rfPO0j`W+S;8k*r>Ra?vH zR!_)Y3b1#tSDot6VgVFMRtyOJc1V9(eE9IHU1D5!*05i#L+ceSV4a4tzuN!PIC<4p zX*PD1hJ^v480Y}78Gp!}4`E?u*3Le)M_K03voa^AN2lX|DJys0V6^}JxbF#&fILw9 z(=asjvOgF=0sRwbES94QhLqvv=5}=ycn6r0K)}ZMzkdu6xzy{Aul}``4|oy~m@4J! z)J2eM(3K6Ia$vcX?*5;AIWCw6;C%rymXLk%p{uQv6E*cx<1NqDQ5xBy2mLGie~8<; zx&7k@TBHAx)%$FhKD!NYPoTE<>cJ2=_iC#JLOM$uRS3GlW-64@WdZOp|49Gcpr;=J zvfka@Pf(N>ToI@1B^BU1ca$GLJ^(U`K*BFDG(0@xSwThf$x}cgOq-fd*7=c>j{jh; zFfacFv7Wj&VgPOgs4y7?rT_r&gY3WF4ZJcj2~^CP-S&~qijR-KNe`IqM>c?M7E0+| z0r=*B;jlgMiGTa7?thcQ0ygvCHoyGuWG3gFrPkkXj!_4P R0V@R3P}No`fBZW5KL8np^t}K8 literal 0 HcmV?d00001 diff --git a/changelog.md b/changelog.md index cc6b815..956414f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2026-03-02 - 10.1.6 - fix(ts_web) +use actionContext for dispatches in web state actions and bump @push.rocks/smartstate to ^2.2.0 + +- Action handlers in ts_web/appstate.ts now accept an actionContext parameter and call await actionContext.dispatch(...) instead of using statePartArg.dispatchAction(...). +- Handlers return the awaited dispatch result (ensuring callers receive refreshed state) instead of returning the previous statePartArg.getState(). +- Dependency bumped in package.json: @push.rocks/smartstate from ^2.1.1 to ^2.2.0. +- Playwright artifacts (logs and page screenshots) were added under .playwright-mcp. + ## 2026-03-02 - 10.1.5 - fix(monitoring) use a per-second ring buffer for DNS query metrics, improve DNS logging rate limiting and security event aggregation, and bump smartmta dependency diff --git a/package.json b/package.json index a65ddaa..0d7b027 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@push.rocks/smartradius": "^1.1.1", "@push.rocks/smartrequest": "^5.0.1", "@push.rocks/smartrx": "^3.0.10", - "@push.rocks/smartstate": "^2.1.1", + "@push.rocks/smartstate": "^2.2.0", "@push.rocks/smartunique": "^3.0.9", "@serve.zone/catalog": "^2.5.0", "@serve.zone/interfaces": "^5.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a40e00c..7059870 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,8 +87,8 @@ importers: specifier: ^3.0.10 version: 3.0.10 '@push.rocks/smartstate': - specifier: ^2.1.1 - version: 2.1.1 + specifier: ^2.2.0 + version: 2.2.0 '@push.rocks/smartunique': specifier: ^3.0.9 version: 3.0.9 @@ -1086,8 +1086,8 @@ packages: '@push.rocks/smartspawn@3.0.3': resolution: {integrity: sha512-DyrGPV69wwOiJgKkyruk5hS3UEGZ99xFAqBE9O2nM8VXCRLbbty3xt1Ug5Z092ZZmJYaaGMSnMw3ijyZJFCT0Q==} - '@push.rocks/smartstate@2.1.1': - resolution: {integrity: sha512-4OM9TXfiiSYIgVz2pQdM2UCTurXwd8o9LCtyZ/o+rnntnXp/X8UTWZ+WyTxgnfuzXhpIYXt83t34bVBJ2EPUOw==} + '@push.rocks/smartstate@2.2.0': + resolution: {integrity: sha512-e41vA1y9b0HBauzjMSh3l0YlRhcG4jhArm43/HHNdT+inxEGIeRL24VGeq+sl2MUr/eFWqgrETXhvL3YrsYFaw==} '@push.rocks/smartstream@2.0.8': resolution: {integrity: sha512-GlF/9cCkvBHwKa3DK4DO5wjfSgqkj6gAS4TrY9uD5NMHu9RQv4WiNrElTYj7iCEpnZgUnLO3tzw1JA3NRIMnnA==} @@ -5013,7 +5013,7 @@ snapshots: '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartrouter': 1.3.3 '@push.rocks/smartrx': 3.0.10 - '@push.rocks/smartstate': 2.1.1 + '@push.rocks/smartstate': 2.2.0 '@push.rocks/smartstring': 4.1.0 '@push.rocks/smarturl': 3.1.0 '@push.rocks/webrequest': 3.0.37 @@ -6501,7 +6501,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@push.rocks/smartstate@2.1.1': + '@push.rocks/smartstate@2.2.0': dependencies: '@push.rocks/smarthash': 3.2.6 '@push.rocks/smartjson': 6.0.0 diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 823405b..08c64aa 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '10.1.5', + version: '10.1.6', description: 'A multifaceted routing service handling mail and SMS delivery functions.' } diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 823405b..08c64aa 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '10.1.5', + version: '10.1.6', description: 'A multifaceted routing service handling mail and SMS delivery functions.' } diff --git a/ts_web/appstate.ts b/ts_web/appstate.ts index eddf256..68e31dd 100644 --- a/ts_web/appstate.ts +++ b/ts_web/appstate.ts @@ -581,7 +581,7 @@ export const fetchCertificateOverviewAction = certificateStatePart.createAction( }); export const reprovisionCertificateAction = certificateStatePart.createAction( - async (statePartArg, domain) => { + async (statePartArg, domain, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -596,8 +596,7 @@ export const reprovisionCertificateAction = certificateStatePart.createAction( - async (statePartArg, domain) => { + async (statePartArg, domain, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -623,8 +622,7 @@ export const deleteCertificateAction = certificateStatePart.createAction }); // Re-fetch overview after deletion - await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchCertificateOverviewAction, null); } catch (error) { return { ...currentState, @@ -643,7 +641,7 @@ export const importCertificateAction = certificateStatePart.createAction<{ publicKey: string; csr: string; }>( - async (statePartArg, cert) => { + async (statePartArg, cert, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -658,8 +656,7 @@ export const importCertificateAction = certificateStatePart.createAction<{ }); // Re-fetch overview after import - await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchCertificateOverviewAction, null); } catch (error) { return { ...currentState, @@ -737,7 +734,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{ listenPorts?: number[]; autoDerivePorts?: boolean; tags?: string[]; -}>(async (statePartArg, dataArg) => { +}>(async (statePartArg, dataArg, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -756,7 +753,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{ if (response.success) { // Refresh the list - await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null); + await actionContext.dispatch(fetchRemoteIngressAction, null); return { ...statePartArg.getState(), @@ -774,7 +771,7 @@ export const createRemoteIngressAction = remoteIngressStatePart.createAction<{ }); export const deleteRemoteIngressAction = remoteIngressStatePart.createAction( - async (statePartArg, edgeId) => { + async (statePartArg, edgeId, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -788,8 +785,7 @@ export const deleteRemoteIngressAction = remoteIngressStatePart.createAction(async (statePartArg, dataArg) => { +}>(async (statePartArg, dataArg, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -823,8 +819,7 @@ export const updateRemoteIngressAction = remoteIngressStatePart.createAction<{ tags: dataArg.tags, }); - await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchRemoteIngressAction, null); } catch (error) { return { ...currentState, @@ -877,7 +872,7 @@ export const clearNewEdgeIdAction = remoteIngressStatePart.createAction( export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{ id: string; enabled: boolean; -}>(async (statePartArg, dataArg) => { +}>(async (statePartArg, dataArg, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -892,8 +887,7 @@ export const toggleRemoteIngressAction = remoteIngressStatePart.createAction<{ enabled: dataArg.enabled, }); - await remoteIngressStatePart.dispatchAction(fetchRemoteIngressAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchRemoteIngressAction, null); } catch (error) { return { ...currentState, @@ -939,7 +933,7 @@ export const fetchMergedRoutesAction = routeManagementStatePart.createAction(asy export const createRouteAction = routeManagementStatePart.createAction<{ route: any; enabled?: boolean; -}>(async (statePartArg, dataArg) => { +}>(async (statePartArg, dataArg, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -954,8 +948,7 @@ export const createRouteAction = routeManagementStatePart.createAction<{ enabled: dataArg.enabled, }); - await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchMergedRoutesAction, null); } catch (error) { return { ...currentState, @@ -965,7 +958,7 @@ export const createRouteAction = routeManagementStatePart.createAction<{ }); export const deleteRouteAction = routeManagementStatePart.createAction( - async (statePartArg, routeId) => { + async (statePartArg, routeId, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -979,8 +972,7 @@ export const deleteRouteAction = routeManagementStatePart.createAction( id: routeId, }); - await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchMergedRoutesAction, null); } catch (error) { return { ...currentState, @@ -993,7 +985,7 @@ export const deleteRouteAction = routeManagementStatePart.createAction( export const toggleRouteAction = routeManagementStatePart.createAction<{ id: string; enabled: boolean; -}>(async (statePartArg, dataArg) => { +}>(async (statePartArg, dataArg, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -1008,8 +1000,7 @@ export const toggleRouteAction = routeManagementStatePart.createAction<{ enabled: dataArg.enabled, }); - await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchMergedRoutesAction, null); } catch (error) { return { ...currentState, @@ -1021,7 +1012,7 @@ export const toggleRouteAction = routeManagementStatePart.createAction<{ export const setRouteOverrideAction = routeManagementStatePart.createAction<{ routeName: string; enabled: boolean; -}>(async (statePartArg, dataArg) => { +}>(async (statePartArg, dataArg, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -1036,8 +1027,7 @@ export const setRouteOverrideAction = routeManagementStatePart.createAction<{ enabled: dataArg.enabled, }); - await routeManagementStatePart.dispatchAction(fetchMergedRoutesAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchMergedRoutesAction, null); } catch (error) { return { ...currentState, @@ -1047,7 +1037,7 @@ export const setRouteOverrideAction = routeManagementStatePart.createAction<{ }); export const removeRouteOverrideAction = routeManagementStatePart.createAction( - async (statePartArg, routeName) => { + async (statePartArg, routeName, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -1061,8 +1051,7 @@ export const removeRouteOverrideAction = routeManagementStatePart.createAction( - async (statePartArg, tokenId) => { + async (statePartArg, tokenId, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -1142,8 +1131,7 @@ export const revokeApiTokenAction = routeManagementStatePart.createAction(async (statePartArg, dataArg) => { +}>(async (statePartArg, dataArg, actionContext) => { const context = getActionContext(); const currentState = statePartArg.getState(); @@ -1171,8 +1159,7 @@ export const toggleApiTokenAction = routeManagementStatePart.createAction<{ enabled: dataArg.enabled, }); - await routeManagementStatePart.dispatchAction(fetchApiTokensAction, null); - return statePartArg.getState(); + return await actionContext.dispatch(fetchApiTokensAction, null); } catch (error) { return { ...currentState,