From a31414f4116525af55d4c970c4fb3b4c55f9677b Mon Sep 17 00:00:00 2001 From: Bohdan Bratsiuk <112423003+BogdanBrat@users.noreply.github.com> Date: Mon, 31 Mar 2025 14:16:09 +0200 Subject: [PATCH] Recent Changes for Azure DevOps Extension --- ... EirEvo-EvoLabs.HarvestWidgets-1.1.9.vsix} | Bin 443478 -> 446482 bytes Harvest Billing Widget/package-lock.json | 3 +- .../scripts/widget-configuration.js | 163 +++++++--- Harvest Billing Widget/vss-extension.json | 7 +- .../widget-configuration.html | 191 ++++++++++-- Harvest Billing Widget/widget.html | 279 +++++++++++++++--- 6 files changed, 519 insertions(+), 124 deletions(-) rename Harvest Billing Widget/{EirEvo-EvoLabs.HarvestWidgets-1.0.121.vsix => EirEvo-EvoLabs.HarvestWidgets-1.1.9.vsix} (95%) diff --git a/Harvest Billing Widget/EirEvo-EvoLabs.HarvestWidgets-1.0.121.vsix b/Harvest Billing Widget/EirEvo-EvoLabs.HarvestWidgets-1.1.9.vsix similarity index 95% rename from Harvest Billing Widget/EirEvo-EvoLabs.HarvestWidgets-1.0.121.vsix rename to Harvest Billing Widget/EirEvo-EvoLabs.HarvestWidgets-1.1.9.vsix index 61bac8b220d33d1a17659ae0eea8898e337c54f1..44f1bf08f7d20d2d2d6ce597a0dceff3905396a7 100644 GIT binary patch delta 17507 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 delta 14487 zcmZ|01#liQmM#35nVBhOW@hG?nVB6^%x#P@X2%>eGsg@uGcz+Y+p+)5%+Ai+{ohm7 zEvdTuUbR$Lt=2hp5^@L@!U>Q+%R@lIgFqlyP>nvJPAxJF82UdNY0>@%*x(?LH7p2( z1xlG3gT?{+H58pPSx`H)PJkL7n9qrNjw)@c-Zm)5gSnA(!B#lU0hMWi=Ts{nh6GDU zHHMh?iMyT$9bS{apRV^2wmVA_8Vw6vL7ArE zSY_YBva20_!6Z?S_Dx?*VU<$Ur`D^A(B0#_Zv8rjaZBW7EUMx^RMmxSv3c}Ss>D+IhP3ygT#TZ5A+wb|X;MXi%iNDwm1swaYMmN1 zxkSc&CG%DW!ANH{a@()NgCf(7by8{(xoyVc!GO~`gKyu=?2&DvZiwb@u3Gn{Ws_g8 z{s}?lY^hS;8=>*$vit+s7f-ta8l@3AR`~(?4zLukNNS=Y`?8lfJf*d4u&3EOEg<;) zntKf#at}Sz2Up~QUN|^*NcgYUB)RnnyXqcxeDQX; ze{2cs*_uv&tMYAXM1~RxLO@lUy7HOoQP3PyH|cVoFuFWT%kL(YWK8>H=T=G;+e8z4 zAk`!LnZ88l_F^yKkEwyDmhc(0BX`Ve_P>(|^v@(pG)54@xnbgeC;W^-o=Qxe`A7H6Deh-nJ;U zSfnQ?+pyT8ZP|A9GsguMT&UWLXIiY$>sX3ph+s!{lkdBXxQRbK#aY!gYPr9XQS3}x zyK%Py>j97b2!|RietTz*jD(lTm+dCB%;heWIayBfKVdbo18>gt zry0`4oDQ{pYCN#rx6NYjAnoAQVuJPkas5)H!p3BrvSMDzIXJ8C+}Rr6B#)+l_ea^q zhJKPV@3E^-Q1=?1ALo?1IgfoJ+gT0pfwE?9*$>CWx4y{+{xBKAhjMl zI4(dhvP^yW-b0;V_ACHbB%`2*elBE5)Y(3v^*}akcM|s7U?tk~AuL_=*K!v?N|d|m z+t>?pjLKpIOloex*#}H&Po;_s1ufV%Xzr1fQ1p;Ix<^a7%3#C?VFrYxwb(*0ej!|x zl+vmQKw91F#eV>gPNpx`9KdY*M*p=aoe#)!pvI|b^pDlY;j{mF+6fCyogeplf#7BB zqO81e1*Z@lnH5a70FX^h^g;X5~4jDQ%ojtKdJW6-5sEQ z$-sy}s`R?qBiA2^eRkV= z67wSbdAr1`_`2nvI z7SJ3$E$~qoYviVSS>RJ8qK$n29iXDqsC04c?u8OVa+To}t>D(Us<)OW8Xa)*Y<`l)9id-BFu(M5H;qo(LwJgYtRfpg* zm(A5|#B2;AT-b{6WnHsi#>2Sg_aLD$L_dJiOv%sUp)K1}3} z-+YE5P8SsU^o$}Bf%g6Tk(`Z9;WT+EToh_Yc#cNQ7fFq*q8cQ)eFcrXAsWA z8|AcPV79hn&u6I8KnR$0XKbcDr^k~&^wNr9TNIfZa3$1kYqDXby9_iup)$gsH6fI8 zV;n}k6w7~}r{;E|IA#Gb!yXyJL7uix0)iIkBAlpENMzUqViogNkPD#(^zx__W=Nh6 zv~}?+@B%ZP=Ep-*Xsf3$_l9zTq|liaKC`!>Rhzuh>q=<@*H3uOrZ7Y;alAhWmB^N+ zttD_3z;ia%m35A87b3zmbw7cm0~5v6a70hN_JrIE2;ya}7;FIHhLoFOxY?cVyX!|> z`E}l$8-0)S{CD!#BUBTakOQpsQTFApYT)abyxZ7=f%>Kc!AeqYXG08kPla8nOn>5F z*7r`+Y*=b0Lep{FKg-1m5)CO83Em5dpk6=|78(%CUvi>n?k-8~G_^S)dQyR_ysHX* zey1xfIm~a#XLbjWbepZ*!-BThUyh0J)ryI16vR;(ZF7nnW@r5o5Q)FDOH*htkP>jQ z@m-F{lv!d9;$`NYMdaRn>l~(XXD^tCC(QQ&YbAG?s=xLk`vKyS7H3NrV|M$h1E1ET z-w`nKI%bRW%Q&pwoP-SHM)huAY-JUtJb^PKc+QDS;+{RwO{$}n!W=!qq8;GwU8wIGE`x5d)W2v z{pJ1<2pR__mF<`35J+~L&K=W;h0}KrED0DAWfUlm8sT-|Xl0c=P{-9&b9vfpE5hbH z%!snh3*NT=ix891V@yyWWSn9WTNQjlVf1XlcXo%Gk$=$d*1;2J{dv ztq-?qVns=|%uVf0Z<4fgEaaj={|tzAkkhR~K|BDimw9EUAAhJaRN3!}(hB|z1lQR8 z0#+OU_Ug$8;phn>ohc}MPWaR_t~lbUdkELnJ0xbY2W|bOfV!%O0~YGr?w_H6t04~9 zu7q8#KA$#E!E{xz1+yWiHo@&y#VY>9_DGScFSAtPJax}3c6K)7pWH>-lO1xaF+{B_ zW#3={%FZ6s$U~A(9V#f=c=DNeLxD{iF75L7qv=_!)6(oK7*{X`;=SvjIB|A z-8%yRd1hrwCiO{0O2AP>r3q&)q+cM83>f_hg;JM11-!Sy7HM+GOMIUQrRBNVY`*@% zt#R2e_{eeEH(wP-GoJ1liUHei3b`ckQ{z7Xm+Np@nb5bg{jY!aZ~GlZQ)K$t-Yp~6 z9zV;XN)@PsnGFd9W7!y5-D$Bn8WvI(dvi+B^AOrfYb0*Q4%MuA`zy=Um7cZasL1;i zow3`FOtUWm+ape2dw)ymYYFMWacg6z$bO%l%lB7D!oOOLu|x91Xw5Lt8^o9s zV)(q>@cDHT^2KGOgXiI&>VF%YzxXl*aBZkW`=EqkMhYQrsW#7u^OX1%F63!MX11#; zfx&P$vnmB1EHTdY9~R)K@7^9K`NH8x;#{n<@6d+rB|)u~aHN3W%|y9xin0^l48Y z++$@^-0Vyp&!?Ki054^jW2$-tNH4~GC=i1m(#ewye~0ai6q+rIzSVG~q)T_uF=T@iOz_#nw$uSofmv^g+ubpzbugJqm zXX)uM*i$R$Q%ioPAB|{MzefG_zV%X7`w}mp(8*0RrL;f%2BpP7lZ})C2xwjQpU*k> zq0y^oRfBWBmHo}HEsybCQMH?fcsBS_l-?TtJ?eV=@(0Oxc~8uy;H|5` z`zvzdE^m5MnK9#mK;K|8-Of>v8l(>O+8z3EhJ(=yHx|{{X_3-_s^dkQ>xDa zV7eQ2>@6yoU$BT$&U)}d0SK$TRv1-xeq@-TjQx6KuO=m>hW-Oe$hH<5-tb{lXu;H& zISL5Yq#W_!lHJ5FMe__hE3*OXM20)xIJcsh?&0Sm?x7SvywcZukTm+yOPc(~DX#u> z6X%T0Vg#(A$G8|wKYEdGbvqmwAM2?|wi(uYj@jJ5WtF$GFa7=!1l&H$r^RISvV#XEU=KZDh4!<#juY%$O%vCZmpz|$`GQKo{G5e^mNq58Wq95Q z@K3xu-gqSJF|lid;JOin)98>Omr!oKuGDnk7&dR%z7Cr<-i0;lv}pO3NGzm!i(8gQ zMh8$ek@_3FQ9jnf0>np^&to}y)o_aR9%1;TU#HS{T+W)LUOt6=v;44R@-#EPZF-Yn zuQbzX)8FnXt94@~oMKhR!m06nKVwO2sZjKARVJZF5#amdxL&}fO%t&gHy{$EHd@z~ zLx5P9`pY$(1XdfZrVuhU;p8_L#3988)D)i%V+?^Wgbt|4Qeg`xevKrK@j2E6$6(ac8=+k|;< zu7v3$m33YZcF=7D(S2XDR~3*|(*W;CrhCx6E*Zae zz>#6I*nRvl7p>+Lxaxl$ObiJ-2d&tP=%Z%o&cuF@v*MC&&c!^o7hE@EfsQiwljK2D z{9X5(oo`8l(d4&{GEhetF^^D9PCt5Y7A=c*{bi`W51`ObQRN`fg~R*{*oA)s$l*>goj&LFFXwazC1% z7S-TA!LDiy6W^m}9Zl?lwV-6bl`G#R^xTXOpImk^*s)#Dv`e0)x4>a*(?2CH;9K`hK_K}Do#-D>_il`t zw{g_i* z&)4yg!9!D@bu!&Y!jXBuFr)p&dqZ)CIj?EmAFNdMvK*XQtzR(`?3UT3H0>m8@N^Fu zq4B4Wo@Hzm2@51aTzP6SoCAovV&RI?tJ632UKq5G%SJoHd1 z=2TqQ&-ruBRN@b>VR0Cbt*k6Eek;8RE&vV?NEGaJbzWURfDWzYvB;7EhY4Ma2RG*G zJ@-+CB?l=auC#*MTLQ(OIzu;VNfniK4~=#2>a>#s2DuNasSN!UglKVzwJC;>jn9Uk zk7*AIGr8QQrYgq*7m^}Ro;OsCXwdk|4SOoQ*ylW_%;=!b+%Cmp@GE!?`e{Fx0A4Zu zvJ#)Y&YGfHry;O~KKD2ib~k4xy$gx@`kpRd)}TI$3BGch} zt6P-0mb{pEaCc(9(pkhWC>f*f1H{?0p>81VaUyYQu9fF$FVXFi?hD4@`P&vSny^5P zd}aHp)4(AlJjzfSc+OHD)W7q`L3P^5i})b$r9V8YxKp{WHG$c4 zSo1wZze%?q=`AYPo8r5utN{_bS0bzZLZ9mq)7a%xOQ4WWy^5SCb$Ym&0YKBOQiSf? z$Ej2qIp`e}h%2)%4b)u8G=uuPHs0+3?r9JyG4Tt|q1wZi4G@$K@pgXanOhlmHG**p%%tlhnfTC)wnqe}6lo zemQeC>>4xMSfBJ$0IK@nJz(0}XLjG4wT<6MB9>0IWz@AS-4t#2VeE6r4Iu==$CsCk z=nX_N$ePIwHwob`dBsLGc^iVV|8=ivF2?|}S~H+FI@-zHxtm*i^xb^Z>8^mS8KD0a z_Q+N?uBCwnOP%4+i{^h~rN?+YIHA!un|R9Qw1K0L$jhJdwS{@=9H@bN2hpo{Nz#j( zEC`3`6FJfA%8c?UC#w(5k`D;zzQ@5OzlHLq&C#X=>c`H0JRl{|YY>E9Q<~I)O<>y) zh!!>?!WDtd!6R31vrO+JXaolB#@cUpCD6Z3vrtkN;wD1O3;Q*tGN=4z@=~+*Uydpo zBc))lrnG_IBD@(91M-~1`3T=|DW0rxddbn|W8#+A?t46@4}fKtHEoB_i1x;qB7<3c zcO&ketd?y)NAB zi9bRKG_oK zcXOVHsVhp9wsOn=WQ&rd%v(UIWvGbDNn>>M6m%y|5 z)>x_YTK*VcErq9|0pbHCOnVspx{zaH8Thgq&`8tyK&V6i6bu}Br7toJkG3tXtAkaz zJ%~76(}AZ?&}p=WTH~}UdYmbB7&XCQE7l7>^%e+w3eHg?B8?9PUkYwz{j5SYvJ7uL zQ}(hWF4gPM&ViYG;_TEQk$u2jd~)5pAnm;LpegL5w}&El8D}air-I6`yZ^XDwQBvl z{=2?NkLrdhJ1@uR*MqkX-s)mu@JxUgcG&NWZ)3^*) zqe}C>W7YlY+dQXq%!~|vG!cS9>IRaxK5+gg@ciGn^xp>5Uo&?ybNz2@`d_?AJtZPH z^gl7}M0p5u^)emip*oLoDcc9M?5m!HpIPY*9x#^OIsi0^W(<){n;Km zcDWa_tZL?4L?UG#H;n;>swYZTV7Hb~ZAh8%p(9 zt9_4dI-#|N7}Pv`8mr6?{oSPT>CkC-RzznP@OPe8$omqz=$XENj4jiw z-t#a4Q6_WQG5bxzV%p5&Bf-r4xzGaG^jenH-A}>Cq(8{5?^j6`C@8!t@y!5NUG~2d zHJ*i#2ir=`A6^KnOU(~EJCuq><1dko*3;s;`c<`Y^g2=RG`KimC=s4o8HdPzH@C$5`xet`l>K%JTfqDviKYNjn2n1^SQzFfOiav4 zbzc4?%w`wFv8#_GM0w$NITOI)GaeCk=2$Nh6U*wSRL5lof$JaSlco>IISnEodZX~v zaQS!{3I5FsjrB~9R69{(zi{YN8RJQAf89%bXWBu)OMx0Eu?kmhvW2RjVUulgH-_}j z_InvBl1gQmJ>)0MV>UF`p0w#wUdKUO#lmQd@qm$Fn^!JO>Dbamk2MDtvgMcsc?Pr@ zYG^~822)A|RG)#ec1_)H6&gnZGrQgDr$;*PRqrRNxi!88VPT~U(`sMz0HQ0e;0@?# zo5wScU#NHwamMR1D8y=&`L{19U7gRo&y0AxY0$dgDb*^)gQTvNZ=a6?r19st$`snH z;7;#S`ZM}_L+3-IWFi0-wdYE4f%}FyQ?jz|Zgnd@?(2b};vqbwqURamPE-X5{IZA` zYW!z)v~%?F(fx#u;P!&kgmh=#)rG!+VCeNKl}?bmvUYqfEczglII*5t2%ntdkKZSX zYtUj4ZAt+KZ;U$Fom`@VHwcrwX7anDXzISowYjWWg$N~EWFP=@-#ZIKH!Qd&#Rk^T z%xr|vYF@Ae7m=Kt?sn^o(@)9R1L|(_CAMabJjz`-T=90cT3uGGvIaR?`@_0wY+O+_ zIw&Mt4|z^Z6Ees&(6^Z9;AE(T~?$&GWA$`xa#Fz*bh6t>F=gAjIcD8>j5W)8>k@^-_yy!dM z;lxj2cT43FF;Ni67-qRbATBnmI8whZ9+H0HGCx{mvBd7@gGsnv6-fLx=Q@K z$oih^^#>BFC|XxFpNPw;|5Q`yH5nHTch*iPFg?Z<%VFSrCa*8GJJn=VcP={9&L;69 zu+bW`B(13lov5M?H720wmz+d?ccvAAzQ%s5zFuNr?6rD+U(y!>0ZQ6Z*K06o&L>^) zDn2=}%6b<7r)=!(kA%M14|1+Sq5He^SlZO9qJeH98|{kOZ|W#Cc{ym9o|Mq-EX@h+Du)&OY;bqU)(X%iv1TL8h?5S7d4x`tG#TK7dv^`3V~H$ zmVocv8iyGX_#;nSus3b`yZax`J{#G%OTSXfu?||tDiv4BXp;fvGFQl{-E`fm64S!7 zIj&CY;nmJi`3=K7&*4>e92PHrH#D_hcRC1Z?HwYliOo1P)(dvdHF-s6l@OR*7R*FB zzjS=m4wvCG+lh*XhBHd1XkRMZD=`Ihw6`tB4rx5$yOw3O|J44JtpAK!W9U!##p{Pe zgD#XZPTj*Mu0)(9oZJcveP4ez0QT>F>0g^putrpvMikgz1OICfe+}}lK{abcLGK6x z|JZ|iy;5)S5I~?3RuJfK1^Q}ZZe`)dWbNi)KTq)Ly4v*oxPA_ZEO8`YN7U^L;LlGS zEGg}BD*DFPGo_45k?~D_*bLLV8Px3kE z2w^_)pMv;demDz1-Zvk8*m2ZJ4|c7vGuKpy-1}}uCsm4vfV1%Bj-HhZn+_Z{VNATd zSUFAln_hB2?Ct2MJa2F|Lr}ena-8z3jqG!SzEFC{lPI_69IDFtc@Mv_0jVw*?6-mA zo!4t{iF>DY2pQ(hb<%!L=!g-&!H1tFpW)El4VY6Ahhqed>&LdpA@sawtiFrJ{uX%% zc??AwuIfmHh;fkOW%I(5!<#_;*wB5GV-kefQeif3myyMUSN0~G>Pb^B{5lR_BEsbY zuYPv+rj47%=ERmvFAmKM3#^BGbvZ@5e6YD4Mxg6ort=748PDmyX-ZMN&Wf^?>{$r{ z+s`>l+4q|v-ObOW)xD_*0m4I7<04Ef*^;?Md>p@uf;^dUaf0}IpRHNENf8=Rj4@W~ zyS@jGc=ZKnPuYD$_NvZj^etW`eIh08!yHt{cI@L?^N1 z?}ydmCv0D3KE>*A3$tRMA!70%Kih`{;dpCGF%x}OjUf(!w*8=Z;Bg&ha5K}E8W6~g zzfH-1XT_QwjdRi38|I*2A*p<;c)yg3txhFjWvWm%V2go(`5x8aDxQ^xb|7^=+kI`8 za;!8i-=bnqpx zK$)c55swMskQ&a_Cz|seZ73T2(POWtG$@cP@#z*9AQGma+epMpfwjS;Sq}?V zUs*yZ>jV0lPTr`AfK}nN8{bE0X|dYgALAyo&vUC&-3)%A4Q6m*vgGl$lp5BXfcPb7 zh?X6-JIfXQ`YMt)!T3`p%eRo-McnQ>&szu`S&iBqlQ_7NE^s#C08(W|Wh@!gUigNF zYB44{4va!4V99VPU;o}RWG17QeV~J-I7)$;+^1LBDbRY`tS<2|sr>KasRUx~LXVpy{DXXyg z1J3QX1K?TrY3jU%KX0XqNHAtqHt}&$v5Ay~@Rnw1Dz(WyrV+vzFsS4~$Iq=2kNk${ z&4O1$>fMt3P5H*+99y5rU3bkE@wO#Qc*4(Gpjoqf4P-)NNHLWLWWrIwQVKi~(ULR} z+omfNT*Yj6eTA*8T-3zpxY_Q@4AyjJWI?YX0D^?I&q@%V0DOs|3;if7J7*nl?WQ zhAqVD_xVnqi#VOG#y~l^%eSoi(~H%+$PH}yGSjFQ;j!C=^>*U{Qgacnsh9n|b`4e> zc_U}wcUk54%H$}?O0pKu9#VZ5mk&GqI{+I83l@u%BI_rddxu&xr#>y%3CNon_mW6S zBnp&s54Lt_f*Jon=x==UfZ`!tZjzYRGz$pL}_J# z7ymAzsf`RX2)2I$-z>Sh@0$i8N<3+=wMWWW`C=7m1KEc#7|l7Q9lSc@hUODLI}qB3 zhKW9u4Q`Qf(>rjJhaCJ(_H(f?bzCWRp&ZkeNmp6YNzd;BMrkCktDKPb8$%g=jdkXg zmb!8^J((pomG|vH(LCG|+IT1vp@Ii_sf4itG^}U01EvrTk=6tZhp=Yv6;sy=SzRXY zk-oYB4{DtWuKMs5 zV*v$3vqm;Bfq6T>?-0Y5X^T!FDN0~{zQ7435Duwz{_WZvzpsu?h!V+9vywEK!|#{S zClXf}*!8z%Np8VUPwI&=A=omKXr2&3KlFVWR;0O|MAxGmIdTzJDcyyXc>u`I1~^tv zTAS;>g`0{|C(8HJ47L-M@FlVc6o|a{s&NHhsK~W<4eDopA1FFV3A(TO(~vu#U$UeG zrXm*t7^E-Q#dzaOzR)d^tDbmVu3}56n+1$cs=6eitDgQtYH)&vI$%u~v+JxOsU`5%0Fjv?D81^RPFh>g}2!|KoMG z<_DE&nRQ9rQ8LG;(1!6^O!ho3X{*c$;r(xHg?cWi86Ufl@C?Z8P%^~x8c2+KQoj$yf*jE@A=j3_r2)rhLq$e;&7#nIk{^_jAhTa$VReQ|0(cKJf2FxG7- zQh4YCmS8t7u(Dj!PGR8K7);!ORHlr9{zrtyRqF5FH-sLQT8FU z+(`2E!XElWm#&lJrG8?bHQxWQHWY+Z(8|X?>uTE;RfE*-C>MstD`Qhrk7O=doxvN} zI?*`*C;msRQyh4t!=543GkMZ8j7wWR@@7@(I__<0^elp}j1;qu=ks-oQjSE`$7(2B zD&9abFISnLJ~HhU5asC+e%U}O(d(G#o%Mxki`+rtPS3d4d~E5J*&L{tmwFhPE2W#mL-`d(uMCQP8oN@^`{K0fW=%<~GpkooC7ThCN}N_;ToL z=i@Yafpjy_Pny#AVuE;+LHi=dohslp^HC=Ji9OmU*RDFBr|VdxGn$6w&Ml71b4u1x zj6Gl|Q7t0{Z1>o`U+Ln5IG=2&TNzC!_0cMwJHoW|Ec7oq_q?wdfBDxDEyfa89=?1? zx%&jOQQc&x$MLvCp;-S=UP=VGYc{!^79U>^vMt{J8xi`~pZAkH*!?*S2$W8ln4v`q z=;}GGa$)+D)O>W8X(uAbpU>IM{E7)=nrJen#b@XVFj<12RKdoPo0Fky;y>%UjBC|K z-pNVw0sd~E|R_EK2{iz zROVD>#G`e*n@4B~Ur*c8iG0`QJf$BnmBLuumAm!~K{hImYA)gZw4XpXl8A;LVj_7t zygDBs{1@F^qNwQ560sP$atX2SwHDKl{qk{fF6Gt0GY%$Xr5`8B+>))esUtTynrAfTnPf!|a^le>)Sw z*dHOZArMX}#7s@$e};KVp0{H;GG50Y5^Cju8!`#e3*`LqBhgPR+F4g4a zMaDnae$#PHU@x3yI#)N=>)3m{zGn57+D$?T#h9PK!5Sl@ILA^jcMc?Do!X=(y0$vB zpDn$6>29H=_yg8-))pYbJESXZE2Sr3 z^0Li5?D-9nk5Lx?@`*}WiGjxsJ@UXE;%*o`Jxxb< zBR0vMLP~ljooM+`q;K&)TDUt=gM}N>aUH?Ef$cl5Im(GhJ9H%rSMbUM#PJm}`qO9j%Q|(?7~oyp z1E!Z*FCZ$~$Sc`RamF4(q%u#^O^ec0N`4}vB25sM)OADQ@lIysn2s8E-*Q(QK@|rE zzht#8+onFOr4ZDmQAuYMb$Kt*tKUzWm@ zDpx9C%qB>k60Pi0I8TzPAO|JcM5>rNdGVPmG2sN?brptKe5ma}8X+2FXooWSL{2)7 z9^BNHR9G&teb~%*c>W~EyUFF;gq+{V7MqDHxe+q60CF-Y))D4vwij}%_=E7p`xbdC z_gR*;y1}WpvU&Ym1G1v-i4!fvs(`L9c*G5sYw+Gj_6&LGTj^GpXgp)X3 z{vFLXh7CsR)A_&??WE!Xd`S(L9fhhI^&?2dYt@)nugeFoFzNoj-}x{TgvgO;zk7<( za@tjF_*aE+vuP)-It(w>(x9m`e8}hdHxG6404A`3%Uf)9j@(h&mls;Ruelg#y5NFw z9rs{_^Zt`1q*Njy5;owrhP~GcpTTSWJ|ZW_Xk$`lQKq6#S0Clw7(HbIeG@fU=7B#7 zpBqEEHm_F%DoYt&_iW#i)-VQo(Dnikc&tgo4}>6V6>N(r>T*|QW{I}@8K`Rvp4pB!;$gO&ESPKl+*h_~iz z0OH(1<7d(bz5KiK8&SB?-qoW3>4dp1@X5{Zk=GW zd)+AT)mC}^YZ1vt_8~KG6%Vq^7GVyHyntiC#K6zf5+DW>_AjH!8QIMj0!E;~w-N$?*5f0HJZ^dBM zhp#*ch*@`|4eRkwmSDk$G2GGLI3&!6WD686BDb3wGeAv?mZu@(JhY?W*FVp7cQKvQArsN?D#kh}{FoRp6Z8pXc8-#Lay%KqRR}kQ$8gMm{KRK#S zVCA{f%mU(ZdwR&QzG{rAhQcicel0rFvGKlZL1n-5lx9^;EjGQDH)pX2TaJ)ZONi$j zA~T9To&iymyGZ*cL;8(LO3d$Lqr&zPH1Q6ht7)6N+OaL{yfQQwsm~Xr7Q|@4C(tUI zenLKuVjn9-OqEf?h)6eev`=@LCe1pqkMzXD|r`jBNrRW-T z@y>@ZE;l+;LM{t8jpvo4jhncJggGRBc|%GKUs{$ljhuHsLGUj6(J&a8)^wL4yR#pM zBbva03;n_Tdfvmx{!9!vJVLyZK3Osx6$b+r7&MODrpc9f%dM%D61ol8_riDqBKj1} z`jw&Y-#yp4OCR|M>#OoO)vm4XLw3U<)pf?yFfvFNzYLw0uRQwxelo8jPpk^S7-cWH#V4YV;|BFvln$B$Vi=WY?^zY{ z)e67%WQS^#?$B%Sue)8F0+P8VO?(P|>-UFN$}b1*^@kAAs%%^jObdaK#qKnF1xZA>!0^{Yiyg7s=L{Ke*pErtCeYhzFs&y|*p z<-O(#|FO5NHJOd{h~}w}9q)|9kfM%-%14?n_xr`7FTu5oA~a>XJzo2F!M)L9pXI^8F+u-XJt?kZ(1QOYPyZt?OX(bg=KLqKnsPc0jgPDTcXin~SpDT+|CcY( z1T;RW$A8_mcd~L~a(1-(&r|7RAAMIrz}mSQ^& z4G;aVv7|&z{_T^}KBagPnn?HmMkD+u074n`|4AzR?`iqZISB;9`;XV(mSQ7xVvZJm hO3VZ_BI!T+_}^d7|2+MrBV}(Ang+VK`|q5A{y$dFA5;JU diff --git a/Harvest Billing Widget/package-lock.json b/Harvest Billing Widget/package-lock.json index 1845f3c..88551ea 100644 --- a/Harvest Billing Widget/package-lock.json +++ b/Harvest Billing Widget/package-lock.json @@ -11,8 +11,7 @@ "dependencies": { "chart.js": "^4.4.3", "vss-web-extension-sdk": "^5.141.0" - }, - "devDependencies": {} + } }, "node_modules/@kurkle/color": { "version": "0.3.2", diff --git a/Harvest Billing Widget/scripts/widget-configuration.js b/Harvest Billing Widget/scripts/widget-configuration.js index 8967f73..57ac62c 100644 --- a/Harvest Billing Widget/scripts/widget-configuration.js +++ b/Harvest Billing Widget/scripts/widget-configuration.js @@ -1,4 +1,4 @@ -document.addEventListener("DOMContentLoaded", function() { +document.addEventListener("DOMContentLoaded", function () { VSS.init({ explicitNotifyLoaded: true, usePlatformStyles: true @@ -19,6 +19,13 @@ document.addEventListener("DOMContentLoaded", function() { var $internalColor = document.getElementById("internalColor"); var $rndColor = document.getElementById("rndColor"); var $timePeriod = document.getElementById("timePeriod"); // Time Period Field + var $theme = document.getElementById("themeSelector"); // Theme Selection Field + var $productSupportFilter = document.getElementById("productSupportFilter"); + var $productSupportLabel = document.getElementById("productSupportLabel"); + var $productSupportColor = document.getElementById("productSupportColor"); // Product Support Filter Field + var $unbilledFilter = document.getElementById("unbilledFilter"); + var $unbilledLabel = document.getElementById("unbilledLabel"); + var $unbilledColor = document.getElementById("unbilledColor"); function validateField(field) { if (field) { @@ -32,58 +39,108 @@ document.addEventListener("DOMContentLoaded", function() { } function notifyConfigurationChange(context) { - var customSettings = { - data: JSON.stringify({ - harvestAccountId: $harvestAccountId ? $harvestAccountId.value.trim() : "", - authToken: $authToken ? $authToken.value.trim() : "", - rndFilter: $rndFilter ? $rndFilter.value.trim() : "R&D", // R&D Filter - displayMode: $displayMode ? $displayMode.value : "", - billableLabel: $billableLabel ? $billableLabel.value.trim() : "Billable", - internalLabel: $internalLabel ? $internalLabel.value.trim() : "Internal", - rndLabel: $rndLabel ? $rndLabel.value.trim() : "R&D", // R&D Label - billableColor: $billableColor ? $billableColor.value : "#852d9d", - internalColor: $internalColor ? $internalColor.value : "#ec0bb7", - rndColor: $rndColor ? $rndColor.value : "#76f5ff", - timePeriod: $timePeriod ? $timePeriod.value : "7" // Time Period - }) - }; - - console.log('Custom Settings:', customSettings); // Debugging output - - if (context && typeof context.notify === 'function') { - context.notify(WidgetHelpers.WidgetEvent.ConfigurationChange, WidgetHelpers.WidgetEvent.Args(customSettings)); + try { + var customSettings = { + data: JSON.stringify({ + harvestAccountId: $harvestAccountId ? $harvestAccountId.value.trim() : "", + authToken: $authToken ? $authToken.value.trim() : "", + rndFilter: $rndFilter ? $rndFilter.value.trim() : "R&D", // R&D Filter + displayMode: $displayMode ? $displayMode.value : "", + billableLabel: $billableLabel ? $billableLabel.value.trim() : "Billable", + internalLabel: $internalLabel ? $internalLabel.value.trim() : "Internal", + rndLabel: $rndLabel ? $rndLabel.value.trim() : "R&D", // R&D Label + billableColor: $billableColor ? $billableColor.value : "#852d9d", + internalColor: $internalColor ? $internalColor.value : "#ec0bb7", + rndColor: $rndColor ? $rndColor.value : "#76f5ff", + timePeriod: $timePeriod ? $timePeriod.value : "7", // Time Period + theme: $theme ? $theme.value : "light", // Theme Selection + productSupportLabel: $productSupportLabel ? $productSupportLabel.value.trim() : "Product", + productSupportFilter: $productSupportFilter ? $productSupportFilter.value.trim() : "PRODUCT_SUPPORT", + productSupportColor: $productSupportColor ? $productSupportColor.value : "#FFD700", + unbilledFilter: $unbilledFilter ? $unbilledFilter.value.trim() : "Unbilled", + unbilledLabel: $unbilledLabel ? $unbilledLabel.value.trim() : "Unbilled", + unbilledColor: $unbilledColor ? $unbilledColor.value : "#27CA12" + + }) + }; + + console.log("Custom Settings for Notify:", customSettings); + + if (context && typeof context.notify === "function") { + context.notify(WidgetHelpers.WidgetEvent.ConfigurationChange, WidgetHelpers.WidgetEvent.Args(customSettings)); + } else { + console.error("Configuration context does not support notify."); + } + } catch (error) { + console.error("Error in notifyConfigurationChange:", error); + } + } + + function applyTheme(theme) { + const bodyElement = document.body; + const widgetElement = document.querySelector(".widget"); + + if (!bodyElement) { + console.error("Body element is not found."); + return; + } + + bodyElement.classList.remove("light-theme", "dark-theme"); + + if (theme === "dark") { + bodyElement.classList.add("dark-theme"); } else { - console.error("Configuration context does not support notify."); + bodyElement.classList.add("light-theme"); + } + + if (widgetElement) { + widgetElement.classList.remove("light-theme", "dark-theme"); + widgetElement.classList.add(`${theme}-theme`); + } else { + console.error("Widget element not found."); } } function bindEvents(context) { - var fields = [ - $harvestAccountId, - $authToken, - $rndFilter, // R&D Filter - $displayMode, - $billableLabel, - $internalLabel, - $rndLabel, // R&D Label - $billableColor, - $internalColor, + const fields = [ + $harvestAccountId, + $authToken, + $rndFilter, + $displayMode, + $billableLabel, + $internalLabel, + $rndLabel, + $billableColor, + $internalColor, $rndColor, - $timePeriod // Time Period + $timePeriod, + $productSupportLabel, + $productSupportFilter, + $productSupportColor, + $unbilledLabel, + $unbilledFilter, + $unbilledColor, ]; - fields.forEach(function(field) { + fields.forEach(function (field) { if (field) { - field.addEventListener("input", function() { + field.addEventListener("input", function () { validateField(field); notifyConfigurationChange(context); }); } }); + if ($theme) { + $theme.addEventListener("change", function () { + applyTheme($theme.value); + notifyConfigurationChange(context); + }); + } + if ($displayMode || $timePeriod) { - [$displayMode, $timePeriod].forEach(function(field) { - field.addEventListener("change", function() { + [$displayMode, $timePeriod].forEach(function (field) { + field.addEventListener("change", function () { notifyConfigurationChange(context); }); }); @@ -96,25 +153,26 @@ document.addEventListener("DOMContentLoaded", function() { if ($harvestAccountId) $harvestAccountId.value = settings.harvestAccountId || ""; if ($authToken) $authToken.value = settings.authToken || ""; if ($rndFilter) $rndFilter.value = settings.rndFilter || "R&D"; // R&D Filter + if ($productSupportFilter) $productSupportFilter.value = settings.productSupportFilter || "PRODUCT_SUPPORT"; + if ($unbilledFilter) $unbilledFilter.value = settings.unbilledFilter || "Unbilled"; if ($displayMode) $displayMode.value = settings.displayMode || "hours"; if ($billableLabel) $billableLabel.value = settings.billableLabel || "Billable"; if ($internalLabel) $internalLabel.value = settings.internalLabel || "Internal"; + if ($productSupportLabel) $productSupportLabel.value = settings.productSupportLabel || "Product"; + if ($unbilledLabel) $unbilledLabel.value = settings.unbilledLabel || "Unbilled"; if ($rndLabel) $rndLabel.value = settings.rndLabel || "R&D"; // R&D Label if ($billableColor) $billableColor.value = settings.billableColor || "#852d9d"; if ($internalColor) $internalColor.value = settings.internalColor || "#ec0bb7"; if ($rndColor) $rndColor.value = settings.rndColor || "#76f5ff"; + if ($productSupportColor) $productSupportColor.value = settings.productSupportColor || "#FFD700"; + if ($unbilledColor) $unbilledColor.value = settings.unbilledColor || "#27CA12"; if ($timePeriod) $timePeriod.value = settings.timePeriod || "7"; // Time Period + if ($theme) $theme.value = settings.theme || "light"; // Load Theme + + applyTheme(settings.theme || "light"); validateField($harvestAccountId); validateField($authToken); - validateField($rndFilter); // R&D Filter - validateField($billableLabel); - validateField($internalLabel); - validateField($rndLabel); // R&D Label - validateField($billableColor); - validateField($internalColor); - validateField($rndColor); - validateField($timePeriod); // Time Period VSS.resize(); @@ -128,6 +186,7 @@ document.addEventListener("DOMContentLoaded", function() { validateField($authToken); if (($harvestAccountId && $harvestAccountId.value.trim() === "") || ($authToken && $authToken.value.trim() === "")) { + console.error("Validation failed: Required fields are empty."); return WidgetHelpers.WidgetStatusHelper.Failure("Validation error: fields cannot be empty."); } @@ -143,11 +202,19 @@ document.addEventListener("DOMContentLoaded", function() { billableColor: $billableColor ? $billableColor.value : "#852d9d", internalColor: $internalColor ? $internalColor.value : "#ec0bb7", rndColor: $rndColor ? $rndColor.value : "#76f5ff", - timePeriod: $timePeriod ? $timePeriod.value : "7" // Time Period + timePeriod: $timePeriod ? $timePeriod.value : "7", // Time Period + theme: $theme ? $theme.value : "light", // Theme Selection + productSupportLabel: $productSupportLabel ? $productSupportLabel.value.trim() : "Product", + productSupportFilter: $productSupportFilter ? $productSupportFilter.value.trim() : "PRODUCT_SUPPORT", + productSupportColor: $productSupportColor ? $productSupportColor.value : "#FFD700", + unbilledFilter: $unbilledFilter ? $unbilledFilter.value.trim() : "Unbilled", + unbilledLabel: $unbilledLabel ? $unbilledLabel.value.trim() : "Unbilled", + unbilledColor: $unbilledColor ? $unbilledColor.value : "#27CA12", + }) }; - console.log('Saving Settings:', customSettings); // Debugging output + console.log("Saving Settings:", customSettings); // Debugging output return WidgetHelpers.WidgetConfigurationSave.Valid(customSettings); } @@ -156,4 +223,4 @@ document.addEventListener("DOMContentLoaded", function() { VSS.notifyLoadSucceeded(); }); -}); +}); \ No newline at end of file diff --git a/Harvest Billing Widget/vss-extension.json b/Harvest Billing Widget/vss-extension.json index 0e1b6aa..a95d47c 100644 --- a/Harvest Billing Widget/vss-extension.json +++ b/Harvest Billing Widget/vss-extension.json @@ -1,7 +1,7 @@ { "manifestVersion": 1, "id": "HarvestWidgets", - "version": "1.0.121", + "version": "1.1.9", "name": "Harvest Billing Widget", "description": "Displays hours from Harvest, providing detailed insights into time allocation for projects. The hours are categorized into billable hours, 'R&D' (Research & Development), and Internal hours.", "publisher": "EirEvo-EvoLabs", @@ -50,10 +50,7 @@ "catalogIconUrl": "img/preview.png", "uri": "widget.html", "supportedSizes": [ - { "rowSpan": 2, "columnSpan": 2 }, - { "rowSpan": 2, "columnSpan": 3 }, - { "rowSpan": 3, "columnSpan": 2 }, - { "rowSpan": 3, "columnSpan": 3 } + { "rowSpan": 2, "columnSpan": 2 } ], "supportedScopes": ["project_team"] } diff --git a/Harvest Billing Widget/widget-configuration.html b/Harvest Billing Widget/widget-configuration.html index 9c853b3..9fb618d 100644 --- a/Harvest Billing Widget/widget-configuration.html +++ b/Harvest Billing Widget/widget-configuration.html @@ -33,8 +33,6 @@ .tooltip { display: none; position: absolute; - background: #333; - color: #fff; padding: 5px; border-radius: 3px; font-size: 12px; @@ -48,6 +46,16 @@ word-wrap: break-word; box-sizing: border-box; } + body.light-theme .tooltip { + background: #333; + color: #fff; + border: 1px solid #fff; + } + body.dark-theme .tooltip { + background: #fff; + color: #000; + border: 1px solid #000; + } .info-icon:hover .tooltip { display: block; } @@ -115,79 +123,184 @@ .end-spacing { height: 30px; } + body.light-theme .widget-configuration { + background-color: #fff; + color: #000; + } + body.dark-theme .widget-configuration { + background-color: #333; + color: #fff; + } + body.dark-theme label { + color: #fff; + } + body.dark-theme .color-label { + color: #fff !important; + } + body.dark-theme .color-settings-title { + color: #fff !important; + } + .bold-text { + font-weight: bold; + }
- + +
- Pie Chart Sector Colors - ⓘ - Choose colors for the sectors of the Pie Chart. The selected colors will be reflected in the corresponding segments of the chart. - + Billable Settings
+ ⓘ + Please choose a color for the Billable sector of the Pie Chart. The selected color will be reflected in the corresponding segment of the chart. + +
+ +
+ + +
+ + +
+ Internal Settings
+ ⓘ + Please choose a color for the Internal sector of the Pie Chart. The selected color will be reflected in the corresponding segment of the chart. +
+ +
+ + +
+ + +
+ R&D Settings +
+
+ ⓘ + Please choose a color for the R&D sector of the Pie Chart. The selected color will be reflected in the corresponding segment of the chart. +
- - +
-
+
-
+ + +
+ Product Settings +
+ +
+
+ +
+ ⓘ + Please choose a color for the Product sector of the Pie Chart. The selected color will be reflected in the corresponding segment of the chart. + +
+
-
- +
-
+ + +
+ Unbilled Settings +
+ +
+
+ +
+ ⓘ + Please choose a color for the Unbilled sector of the Pie Chart. The selected color will be reflected in the corresponding segment of the chart. + + +
+ + +
+ - -
+ +
+ +
+ + ⓘ + Filter projects by the term "Unbilled" or another keyword to categorize them under Unbilled work. + + +
+
-
+
-
-
-
+ +
+ + +
+
diff --git a/Harvest Billing Widget/widget.html b/Harvest Billing Widget/widget.html index 076ef64..5387cb3 100644 --- a/Harvest Billing Widget/widget.html +++ b/Harvest Billing Widget/widget.html @@ -6,20 +6,96 @@ @@ -28,6 +104,7 @@

Billable/Non-billable Hours

+