From a3d5e04946544f3aea14e0c5c31ee866836d475c Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 20 Aug 2021 16:25:31 -0700 Subject: [PATCH] Fixes #6990: Fix query param and query filter handling in API select --- netbox/project-static/dist/config.js | Bin 107894 -> 107922 bytes netbox/project-static/dist/config.js.map | Bin 411243 -> 411298 bytes netbox/project-static/dist/jobs.js | Bin 108314 -> 108342 bytes netbox/project-static/dist/jobs.js.map | Bin 413408 -> 413463 bytes netbox/project-static/dist/lldp.js | Bin 108592 -> 108620 bytes netbox/project-static/dist/lldp.js.map | Bin 413757 -> 413812 bytes netbox/project-static/dist/netbox.js | Bin 316404 -> 316559 bytes netbox/project-static/dist/netbox.js.map | Bin 1133155 -> 1136705 bytes netbox/project-static/dist/status.js | Bin 127993 -> 128021 bytes netbox/project-static/dist/status.js.map | Bin 462011 -> 462066 bytes netbox/project-static/src/select/api.ts | 113 +++++++++++++++++++---- netbox/project-static/src/util.ts | 8 +- 12 files changed, 97 insertions(+), 24 deletions(-) diff --git a/netbox/project-static/dist/config.js b/netbox/project-static/dist/config.js index feeaacd2ff750856cfa0f8c4631449b8d858f937..291dd4aeb0901bc5a4ceba6e7432dc3a9431820b 100644 GIT binary patch delta 3226 zcmZV=e{dAld0u{zKm!Tn2l)ken`E<_Y?c&|>0I2LfQM2_B9IWnc_ho-Uf$Zh-Phf{ zkdS1Iqhcp5;^iS%5Q9K}fK{vRw2@N&uyjDHBV{^utlCZ;ZKqPIZ5_dx*0$ffJ3!mn znQ!0w-uHd)`~AJEzbu-0wP=ALh)UP^h-&+AYC(G*u~YuaRL^mQQ~&5egswv)i?At2 zRl^WmNfUXV&`Fj9k1=VW|vIDZK(Gtqa$n0?Y)*7X2Cao6Fun`B+NQr;68l!;8oA=Ydc?4pJ|6 zR?~l1mbDPE)7IRiZBA+ekql5ODU+mw1vrRXw!o~3D}>%srNb>ptG)%Wt@`ifAScV` zOSWU@_wmRl)MG=B{;JTi=y*;VyAv0@GMc&wSFx z`7G1NwPAX;hL^Dv6+1&bAChCLs|r{$q=Y!hKFMUiPNtD&D+yN+wqmcmwgQ#ICD(OT zeY)wx-kQ3-sFnb?DvtZ{#Dw5t-H|mzOK7I6VERVA0t!|%tOmHTVXEbZnw({VCbBz5 zv`)qoRwF#0TL_r`tzjKRXRN!9b}uXS=eQC|G8~OeOhh}?a3Z2$*i24JaWI%Fz8Zwn z%gRtSeP-F+)i|sMIYW!PT!6FnVeE1dsaL^X{qg{deZTK4z)JrVz=M7b;J^I$036_a z0QYe98O%Vw8pQNt&JVlFMs~8MaV@~n#y|-(SnB0@Km9{X1-;nV4ERqPp9FZY=^hR% z(I5`A1Cf#ls)2S@;#^xb9Yb}sRWX5uprW~{I^(sB!yL`M%W`yAw@fg;r+E_ydc1i# zz%$LAOThdLRn&0=aG51an3nK9KC`}&J=uuJmf6d$%E$_tF%iV^Ye3Lmz8m0gcoE=# zcxGXJO9Q|_OD({@7T;nl$89U|`Mc=DEw`6tZ@j4heY-_m04n9u64OP(BOrmu74#{7 z$+AwYu%KFTA6693OeS_|HW$QgT*Bc3n7${h0^(}X-E!S3%gp#Dqp)Vi1PmD%2Q#cM zpp|&ijAs3l)A0ZJ=sV(uc_0<)4pXsp1sFtZi)gkx)~zNqNE}S>ZH21${@B{W(x6mY z3XqphHUk${bf;VGhUS8jvW<2|ve0OgU+nVuT&XRBN0g9Yz*k;NdnZ_62IJD9Z{+PigiE!M&3)~ed*jq)EWYCaVodpazQ)d$EVY55xfc~dD&acGE zU?;v+iFM+(HZhw*mNDRjapdN0p&Kf&1Mh`!GrR50$Tfh!+S#{|L=?qL8V1h`TA0vP zgZoQ}F1woJ3OXH{tD^GIeEOHcCLk{xdLQ5?Lm0H)sh(X>`nm2ICZ3RR=Yi9naM>)l z7IF8=|?UC&xBNT|7IHApzIXObn6f8rFtS0_$`st--B zggHZBoVo*%nfv!JQ0>j!|JPzbPE9YZAyD%$GZ+-%mvOW*?80<;e!3oLUY`bkdzYs# zA&w|kaJ?&7Vt~1{YZ|FQ-w@3LIiN=TV}7|EnX`|ivS z`rS+Wq2+kL-ydRm)s$i*ER_l_hl0uVkq}FY?Sd|i6GM$=<_8qjM=7xoixDYA{U>Ya znwcewZ*q)d`K6fp^QXgT-uGvrNc(3KEvkcTQb^!|y)zWVL6s`*r*yN1CQvzDv z2HketJ^}+-V{eOJKl>r@{`^PVmfQ_iLoEGRwxJifTC7*KVa!8E`y#@x!2FNF_#FnK zEDg-4|3%4Bh^wlbFimLUTq7u!I@hrjiaBgRlN8ub8J}d1>SGT2?YXDHCwqVK9`nh) z=OeIr`Mk_F*DegeX3NV>u<=G-DK4zSjxrQA^yt@{#{2cjrtzpVIV2J9!0UyKHIAMPXE9{-vCW&2)Ya^6u_G4pRm#6wZK-g4=uZo zxDZ|=sthHpq@#gr?56PyE_wr(baSXApyF0E>F8z-6TgnJZV<%)#bS}8z}YPf+8lxa z!ok+=?6y=&Yy+Eq;l?H8Xbez|J+xOpgk-=<+G?J{n{)lf%TVXQC0fNEGh$s ReKw0$!fkUMPofQl{{;d%bNB!N delta 3204 zcmZV=ZEO_BRpT#gr~!jNu(9E8ZLfFj^Q!yYY4#s`T;bdNmh|VDL+~&AWa3eszzx-t45?%LTS<#0g?Lo=I(%` z)k<$?-n{qbeZSfFZqdzO6wML@QCT@MsM3OsaPX2*>2p_G@Lx|A2{2c(llYgoRizAkRX-@%{TY66x2nC3E$BG}! zN7%bI%a4G0cBu?dDZK_K&9hga0>T8x=6nMCb#vcC`9w<66UFy?1M`OSXMj*W4pJ|* zSJ8i0%x%JAyRErN+Z@vbEE%9wQYJ|U3vdv(Y=K!5S1`S&Qioe6E58M>rRr~GAScV` zOSW*WTnnbH3k*0ru%M*`w{Q_ol=_tP^Z`^uKUuIG4(h6#>xh`~j;auOKy&YRU0dIp zbm3xgbd=Cob>~cA^;xEmYa#SZH7^q>Dz=AsJ|xFfR~3k4NC|O_eUiz3?Myw*RuZlt zY#?4)O*txqOKvN!`gGGrycG*~q8bd`syN~&qoab0bw}0=EuopNLg;(73Mg1!$JAU? zH{NtdP0lhw6WJXmT07$js}Y{hEd)aUTK52iYPe$|?O0Um&v7M`WH=fb9gViD;Y36s zuo)YZ;$SdUeAS4g7tKXg^tDBgRgth7e-W&c?MM=%vQR08clz&j<4}R8hwfz-5*w5n96g_{{oFDrF-gTV@x#DkCdo#zYXu zuK+Bvfo(0tOM=BAV?Ecc=*s5{J-j z&Cmk8KQ=e9G$@r80OX}(jle||-RV#};QC-&fJoV}xaz=wX0Or=br`bex-`nzh&%zJ zu^x+Q=0d>TceTm369%!+jCx4p~E^mf>WO zazY&vu(zu_%=+J_n>NAi_w{UHoRht)i*V3ru>(};s-k(DcUEF088l>8X8}Xb)S1K@ z+M&%0f&Ryv&n+cNUpu*1iM5lK7BQPbmeK2kN#yQrp*t$D1MkgnBfIVW$Sr`s+R{B6 zM-;_O8V1h`S{T!1eS1oMzBB9G_TFjiKhDKQk!8FXL!sz=cus z#zZa9T$})Zdsio>5r-8k_@FCTVt~1VL z6mAO=*yN1Cy8>F?YTb6+ZUO^YV-JmApZpAXfA*t|^B)7NA(nn3+t7<#E!L&lFy^77 zeHGzXVE)Ho{0;z7mIh|j|Dxn5#8uTzm?kuFwjLBqoo!nH#T+)ENeb+zjEpfybu$P3 z_UxwGV4)?a9VjW_sCabYEKl>VrpN59c9(xZKtFR+B#bnO`+ynOAmq5`a} z#NNg0vsidOxY2}g`eYo&eD%%6u$-QQ%IUhB4~bZDh@QELOF-rbqrz0aRat>04!XGp?<#F{w8533rh%^a)~Q-XhvlfDI?f}y zIrSg;6>d;y^PxC(XFpyb3^eQ8-tw$gF;VJXQD)cOzj)#yA#8*S;Xx>b$ zI1n0Ejp$o~P<~r**J35=YPEWUG(~$Ai33PM})Nyxo4gpE}>i9c41_N2nNjkpMdu`bim~vdU KueW8}!vO${ZaI|z delta 128 zcmZ3~EBU%dvY~~sg{g&k3rpxE+v1X<%)E4k8il;l+@#bZAR{S1KPNRY4=j|E1Efmx zQc}}0^HNjnG-C1;6v`5FN>i;A!gONtrl(C}32pyBiDmo$NvuVy_?&%oTpgV&ophWX bovWOtH`uaiOh0DJCdXv#y#1Li+a3-8<>)RP diff --git a/netbox/project-static/dist/jobs.js b/netbox/project-static/dist/jobs.js index c20046e824331a1ca7c436478549fe3bf6bab6cc..e8ca9e45a282d49eb22d1bdec6e4486474be7770 100644 GIT binary patch delta 1759 zcmZ8ieQXnD7|+vnbuip;BBL8)TiM4IZl>49kIyG;gp(CvVKB_8RLJhEaeG==QEB3u zC}MY&I*6{NK`Jr_tmQ!T5o>)iDp|R+P&Vc|5!#G*R6fgl7nRKXR^yqj>6K9aq(au$8YhO5XGYA{9(`rCe+*}JwToOg}C(a5Z69-!`mDrtK zjHn7Bme6=n>Lf+wB$f57T1E7g>^`s{ZjTZ@+Z8hs)+?(~KB}~%v{f~r3|AFnJ+Ug; zNOgSe)Ml!=Nk)jY*4Bv05Y zytTA$K{yl%OM;}*ymqL zwp*lvsabU^ zrL-)tyjC^Pik!iLqvMd%eBfVHnh$0e%itL_#K>aM@RO|B`h{Q9Ek|BQ}j{!`E?Q%qKVxe^)a&GQ57~S3qC={-V2Uu5p60at|`Ma zFu(o7yNo58d#oMhu4BLBD{GH)7Ce4AbvkPzQCJ(}>zZd{{KKNQu$8Fh#fhI%JqH{r35o z)5jZ(7K-vVx$2p>_&M4ZUKqy1K6~NsH@xQHjZr%h+eNC6-38?8U&O; zxI3YCCDiBU9@ITS(X%{Z_k>^63!)1}4BCm{a-qi??tVr~zy!GncSgpz841*<;ztG_ z#PP&WnqXuC@bPu&V8H_7{S#pTbC2h}3P$7O7bk(7glE|lsK#o!SgRFs;(M*opNwc> zF3h!Hb?!naL3MK>tbjzX7fS+Ft94w>jHNhXM!c~YUcsit+bFOYOkW9D&A`Xj&ICKE zpUi|y7%1LR4#lYm?^ysrge}!@_9cvep&oFO@o5cEW;XFb?asZdct{Hy-L^3o$-a`8qO1-!fZv9k1gqg@+@?bg)S;guYAESkJ*R%K*qq6*TFoaZO!Z9C!>v} z8{sIVCHAa7Obd1gANz9?e2cb=n?W&r%eTOy3E7ph%=O^cd+ek{yGvw(g5*~N6{Xtw MQ?JE$#bABrAr^PIGvPNT6UQ>EiJY5LBUajYaerWXSx%*GuxSI zOIZ+FBtQ`)3}tyFh0;i(G(Z?+1NZ|7A<@Jl#>6O!Mifx|A(U4@)H7vCh=0z#=R4;+ z_q=BJ)QDr>h~s#l4T!PTRtB8$rR_9u=B9+(@tkef~yP((3to zinvP)J;XFpAQ_qc&SD_uh_faUm5i)8DC@Gk2yMYTDxb}G2bJ{fChM8bnPqm8mzQn) zoIlCDJac3sVgvKC5(zE(h);tiEj zdUse*#2F!$b!oaP$*rzZVw|g(YJB0%N+WE@P3u8P^YM)=DU~T=KJk`VnRwWoX~gaA zWF%b(v4qBpRxN8fFYBy-%^G5^X7_^wad(86Q%j>(!e&_o%132xl&f(j;lRJBG#pH`mcc)0jb-ED6O7z*C>sq!hps2sILS!um~I|E z{Es!>kB;n}Pgrca5)KQhR}!i0>}r_`(ZubJh>R-ub&ZXvf+(oid%;s7p-soc4Q+T9 z<~K0B+ghUe$68SCKK47lvi>;lz~h%wr!yuJjdd{rUgrz=u!OBNj$HAeW&n8yZYDkFUAR^F{QB}AUs3=V@a^Rj?w63Rv7^&Y0dr+Q$TR@`w0XDBA`q~z{nP*#qQXnA6Igv4-5&>0@~@2B{mP4aPGqr!K|2s!DRc*vu4lA3OpuFkM|g~z7Dq)Le`N4M z98c_|4Mrva7u%2u4lE$nHxc?V_t=bA!D@W$;v`TL@GP1F6<94FZE`|pY@ZYQ5)sYK zg82@t&X)@XsBX!HRS@s>Qdyv?jP|SP(IhX-iq+-AE7-JHGX)NdDHed!4qSBoY;dFc z$!xfUfnx2&ke`h3-bK)cu%iObzJ&2F)BsL0HoX>#>^82=xN|Qf*4_Y{t;`?43wtf< zELx~vz9Gtfm9Iw^%-{eoQ`vk&!xih(C@fCX0D8s3MWtTq;I mf}@ZU-?JKp7Tg{#`sZf&7Ht=|fM)p?Z-pfjVgpgwllmVvFksUF diff --git a/netbox/project-static/dist/jobs.js.map b/netbox/project-static/dist/jobs.js.map index 4013840f9e2cc6966e2caf6be160a583ebb9c335..98a83549c9460eb5e12fd541f98b40e54717c327 100644 GIT binary patch delta 158 zcmaDbS91D1$%Yoj7N!>FEi68h1WWU>^YY8{>@>;}b4pXK6vC!=PGSk=bu21Mtklaa z2Gi5|C$oqPfEDQFq~@iUWGL7v7);li%%ar(VG_&s50hA@ZRB?>bk=cobj)?uadvbz zcbz`Pg-t`sS0~WXF;K_d(K!Sp>8s=K=ok!SIVVkLoXjdd{k#hsH&c$w_B$?YEL;FW CqBJJ} delta 128 zcmbO}Px8TB$%Yoj7N!>FEi68hY>P{ZGV{_EY83KHbCXhwfQ+R4{G8OpJg`ts4v;F% zOG!=3%u7wN(}>AaP$)~xDNVIf2-Atln;tufCA9t9B$n;pCb6#A$mi^%7?WA b=v?JAeXR?d#`MoFY;sJ-&fA4u*;u#$?1wEV diff --git a/netbox/project-static/dist/lldp.js b/netbox/project-static/dist/lldp.js index 2cc3f625548e95f368f3ee2873db889034299ce3..823621db22ab37e135640d97c7382ff99b1856c8 100644 GIT binary patch delta 49 zcmdmRf$hu%wuUW?P1B_vi;5B}^)idWv___;eWqScYF>IthMmFWgWE*6Pn*s-O8@}; Cv=hhx delta 17 ZcmX?efo;PDwuUW?P1Co}o6fjS002*12qFLg diff --git a/netbox/project-static/dist/lldp.js.map b/netbox/project-static/dist/lldp.js.map index 44d85ee92f49335d342d0a21ef73d9b0718075d1..2a6e258062c678878596fdf60f45267eff1ecdcc 100644 GIT binary patch delta 172 zcmdnHK=R81$%Yoj7N!>FEiA#41WWU>^YY8{>@>;}b4pXK6vC!Yn8Xrl;#gFaSgDs; z45lG+nwkpLF?k9=P?TCyT9l^%)}fb^nwMUZp9b< zS;y7UG1png+0ohDb^1CNHVqkHoj^y&Kpl5S=Ma#jua3W?V=$2AoTTGB{fY~l0#lC5 K_HQn1?%V**PdZ@$ delta 133 zcmeyeKyvQ_$%Yoj7N!>FEiA#4Y>P{ZGV{_EY83KHbCXhwfQ+R4{G8OpJg`ts4v;F% zOG!=3%u7wN(}>AaP$)~xDNVIf2-Atlo1QX>C3O0<$t*(c{F7O>^G{}7xslJ=N5|FC gxzb6;+0nVmY5H*&HjU}Lu55Bl#?ISyUD@2Z0j~`$6951J diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 31b84deb8982768f26bf81fc17df1858b6e04b04..c55ebf672dce7ad2e664f270872701fe7fbb6268 100644 GIT binary patch delta 11022 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 X$G-=~r};DAlYTiJ1W!CCogVtXeV;Y* diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index 7e670e1fc2c74558ee54fba5e6f4d3da080628d4..1918ceb177eca15daf781e8ddfdc5a938850f9b3 100644 GIT binary patch delta 4503 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 I^T_G{0tF$p5&!@I delta 1281 zcma)3Piz!b7|-tP)^=Xm?odjgrRf7IJ6m6~T?*8ewB(!VWHVhiYh7yvTIjSpZ5Ot) zo82u!W2~A998A1u@+Br3HC%`nV>At?V!{E!8Rh0lqX*>z?@f!cO&}cJ%zN+q ze*eCA^=sq)$Hu#Ezzw>R8*;;LgZqNp=r(;TUl|*&)+z;Ofxb!Z)*}Qqi^? z|EgHzzhx(H&lem!KcY@Kl%BJS%k~g`gH1X3!{wJv`_ z@cwOC_3*CzJ&|gaW&CG5+3TJAP2O>&;~8Et@vD5mySj_KAI4yes5r2Xlw0khy<|Hz zTBy=m#hN?Ir-(o8Bhz>>Mq2TmZyK5~dbv^YQv1o37Hs-gCf?Kl846(6csPu=UnVE; z-p}FCwi>P2<)Srb=jkxT(jeJ`l|!L6{9{dOz?K0LZGK$mSz@T9crEga)bU?KD}H*E zbmEaA@}AGwTE|$nDpfm=e|D0#pn$JQ?LKStN!GY{kB2uUwVw3HopU9pT1V$UzR%VW zi}^5ElXm!wk$Og)86pQTyP0Cc?D}AQPG~QSM1-Sn5|bl{QQb|k1B1eIY>Fa&Z~U-2Jj@KAf`XQ;hd*`UAV~9yGU+v i;ZNlM-2Kn(B47#|yMoD4?*UaSY##X^l)x`%Jx@)V%bP3_Am>?USxCrpp2V)F7M3ln(>Vl7^Rn~u%k%6s$`W%*Q>_%jreEP;4K;BrDoU)> z%Pa=d5IIdvh3c3*1t2I&Eh#O^QvmDG%Sp{kFUe4_Q!tob%E_wKZq3QM-I|l_+-rWv zLT4RUN5@=e9cM>pbJywOU)eNde02gH9RqdT9i2l!lD<0rj*h`VmUEJh?{wR*Yzj;{ MF5Bb3vc-r404^RlQ~&?~ delta 130 zcmew~Q)c%}nT8g|7N!>F7M3ln(>ZL5ONuh{(iLhH@=9})Qj36$r2PDx)WkfnP)-hz zD$PqtP0P$nO|jF6$x~1$OUx-vwNePviOHM3f`c`*-I0@ZyCWytgV%h{K02-Enfft diff --git a/netbox/project-static/src/select/api.ts b/netbox/project-static/src/select/api.ts index 3e1e75252..0e6a189ff 100644 --- a/netbox/project-static/src/select/api.ts +++ b/netbox/project-static/src/select/api.ts @@ -17,12 +17,34 @@ import { findFirstAdjacent, } from '../util'; +import type { Stringifiable } from 'query-string'; import type { Option } from 'slim-select/dist/data'; -type QueryFilter = Map; +/** + * Map of string keys to primitive array values accepted by `query-string`. Keys are used as + * URL query parameter keys. Values correspond to query param values, enforced as an array + * for easier handling. For example, a mapping of `{ site_id: [1, 2] }` is serialized by + * `query-string` as `?site_id=1&site_id=2`. Likewise, `{ site_id: [1] }` is serialized as + * `?site_id=1`. + */ +type QueryFilter = Map; +/** + * Map of string keys to primitive values. Used to track variables within URLs from the server. For + * example, `/api/$key/thing`. `PathFilter` tracks `$key` as `{ key: '' }` in the map, and when the + * value is later known, the value is set — `{ key: 'value' }`, and the URL is transformed to + * `/api/value/thing`. + */ +type PathFilter = Map; + +/** + * Merge or replace incoming options with current options. + */ type ApplyMethod = 'merge' | 'replace'; +/** + * Trigger for which the select instance should fetch its data from the NetBox API. + */ export type Trigger = /** * Load data when the select element is opened. @@ -40,11 +62,9 @@ export type Trigger = // Various one-off patterns to replace in query param keys. const REPLACE_PATTERNS = [ // Don't query `termination_a_device=1`, but rather `device=1`. - [new RegExp(/termination_(a|b)_(.+)/g), '$2_id'], + [new RegExp(/termination_(a|b)_(.+)/g), '$2'], // A tenant's group relationship field is `group`, but the field name is `tenant_group`. - [new RegExp(/tenant_(group)/g), '$1_id'], - // Append `_id` to any fields - [new RegExp(/^([A-Za-z0-9]+)(_id)?$/g), '$1_id'], + [new RegExp(/tenant_(group)/g), '$1'], ] as [RegExp, string][]; // Empty placeholder option. @@ -130,7 +150,7 @@ class APISelect { * `1`, `pathValues` would be updated to reflect a `"rack" => 1` mapping. When the query URL is * updated, the URL would change from `/dcim/racks/{{rack}}/` to `/dcim/racks/1/`. */ - private readonly pathValues: QueryFilter = new Map(); + private readonly pathValues: PathFilter = new Map(); /** * Original API query URL passed via the `data-href` attribute from the server. This is kept so @@ -226,7 +246,7 @@ class APISelect { this.updatePathValues(filter); } - this.queryParams.set('brief', true); + this.queryParams.set('brief', [true]); this.updateQueryUrl(); // Initialize element styling. @@ -608,7 +628,7 @@ class APISelect { private updateQueryUrl(): void { // Create new URL query parameters based on the current state of `queryParams` and create an // updated API query URL. - const query = {} as Dict; + const query = {} as Dict; for (const [key, value] of this.queryParams.entries()) { query[key] = value; } @@ -651,11 +671,32 @@ class APISelect { } } - if (isTruthy(element.value)) { + // Force related keys to end in `_id`, if they don't already. + if (key.substring(key.length - 3) !== '_id') { + key = `${key}_id`; + } + + // Initialize the element value as an array, in case there are multiple values. + let elementValue = [] as Stringifiable[]; + + if (element.multiple) { + // If this is a multi-select (form filters, tags, etc.), use all selected options as the value. + elementValue = Array.from(element.options) + .filter(o => o.selected) + .map(o => o.value); + } else if (element.value !== '') { + // If this is single-select (most fields), use the element's value. This seemingly + // redundant/verbose check is mainly for performance, so we're not running the above three + // functions (`Array.from()`, `Array.filter()`, `Array.map()`) every time every select + // field's value changes. + elementValue = [element.value]; + } + + if (elementValue.length > 0) { // If the field has a value, add it to the map. if (this.filterParams.has(id)) { - // If this element is tracking the neighbor element, add its value to the map. - this.queryParams.set(key, element.value); + // If this instance is filtered by the neighbor element, add its value to the map. + this.queryParams.set(key, elementValue); } } else { // Otherwise, delete it (we don't want to send an empty query like `?site_id=`) @@ -771,6 +812,34 @@ class APISelect { .map(v => v.name) .filter(v => v.includes('data')); + /** + * Properly handle preexistence of keys, value types, and deduplication when adding a filter to + * `filterParams`. + * + * _Note: This is an unnamed function so that it can access `this`._ + */ + const addFilter = (key: string, value: Stringifiable): void => { + const current = this.filterParams.get(key); + + if (typeof current !== 'undefined') { + // This instance is already filtered by `key`, so we should add the new `value`. + // Merge and deduplicate the current filter parameter values with the incoming value. + const next = Array.from( + new Set([...(current as Stringifiable[]), value]), + ); + this.filterParams.set(key, next); + } else { + // This instance is not already filtered by `key`, so we should add a new mapping. + if (value === '') { + // Don't add placeholder values. + this.filterParams.set(key, []); + } else { + // If the value is not a placeholder, add it. + this.filterParams.set(key, [value]); + } + } + }; + for (const key of keys) { if (key.match(keyPattern) && key !== 'data-query-param-exclude') { const value = this.base.getAttribute(key); @@ -778,29 +847,33 @@ class APISelect { try { const parsed = JSON.parse(value) as string | string[]; if (Array.isArray(parsed)) { + // Query param contains multiple values. for (const item of parsed) { if (item.match(/^\$.+$/g)) { - const replaced = item.replaceAll(pattern, ''); - this.filterParams.set(replaced, ''); + // Value is an unfulfilled variable. + addFilter(item.replaceAll(pattern, ''), ''); } else { - this.filterParams.set(key.replaceAll(keyPattern, ''), item); + // Value has been fulfilled and is a real value to query. + addFilter(key.replaceAll(keyPattern, ''), item); } } } else { if (parsed.match(/^\$.+$/g)) { - const replaced = parsed.replaceAll(pattern, ''); - this.filterParams.set(replaced, ''); + // Value is an unfulfilled variable. + addFilter(parsed.replaceAll(pattern, ''), ''); } else { - this.filterParams.set(key.replaceAll(keyPattern, ''), parsed); + // Value has been fulfilled and is a real value to query. + addFilter(key.replaceAll(keyPattern, ''), parsed); } } } catch (err) { console.warn(err); if (value.match(/^\$.+$/g)) { - const replaced = value.replaceAll(pattern, ''); - this.filterParams.set(replaced, ''); + // Value is an unfulfilled variable. + addFilter(value.replaceAll(pattern, ''), ''); } else { - this.filterParams.set(key.replaceAll(keyPattern, ''), value); + // Value has been fulfilled and is a real value to query. + addFilter(key.replaceAll(keyPattern, ''), value); } } } diff --git a/netbox/project-static/src/util.ts b/netbox/project-static/src/util.ts index 4b144fb2f..5c9110091 100644 --- a/netbox/project-static/src/util.ts +++ b/netbox/project-static/src/util.ts @@ -46,11 +46,11 @@ export function slugify(slug: string, chars: number): string { /** * Type guard to determine if a value is not null, undefined, or empty. */ -export function isTruthy( - value: V, -): value is NonNullable { +export function isTruthy(value: V): value is NonNullable { const badStrings = ['', 'null', 'undefined']; - if (typeof value === 'string' && !badStrings.includes(value)) { + if (Array.isArray(value)) { + return value.length > 0; + } else if (typeof value === 'string' && !badStrings.includes(value)) { return true; } else if (typeof value === 'number') { return true;