From 1b7b515ef0975c19575d001fe266824cdd96526e Mon Sep 17 00:00:00 2001 From: jaylin <chieh.lin@rwth-aachen.de> Date: Thu, 21 Mar 2024 18:48:58 +0100 Subject: [PATCH] fix SQLite and reset button --- my_flask_app/__pycache__/main.cpython-39.pyc | Bin 26082 -> 26650 bytes my_flask_app/main.py | 48 +++++-- my_flask_app/templates/app.html | 124 +++++++++---------- 3 files changed, 96 insertions(+), 76 deletions(-) diff --git a/my_flask_app/__pycache__/main.cpython-39.pyc b/my_flask_app/__pycache__/main.cpython-39.pyc index 068245242330937a344b5e4907b246345019b383..0f6447fa55eaa8f10df992e71e8b5cd526f6f6d1 100644 GIT binary patch delta 8621 zcmaEKnsL?zM!rN|UM>a(28OwLe^Mu`naC%@7`IVdl({~YCCfF%E=3}pF-5AEDaAg; zp@pHDF)Ap<F~zBcAu2dEB*l3SV~R_PYYR(MXo_2kdkaHUSZa8R#~j8K&lIl~mZ*r- zNU$336rUEBsHha*6u%aRsOS{`lz<k7sF;+%l%N)dsMyr-)R2_mIZP=bDWNSaQE^~? zJxCxdCA@_tDn6wyB{C(dg)u52B|0Uhg&`_2B{n6lg&`^_B|asgg&`_AB{3zbg&`^> zr9LG&C8dQiDmA4cH5?2>QbCX*l_51GC3OyGN?J;K3u{zbYDj8$O2!<fl+2W@7M7^= zl*W|ol$;jEsEm}Rl-!iOfELE6%#{3;f)<9Ttdzo(q85gz?3Ch^k`{)joRrd(vKEG@ z+?4W^iWY{byp+n6suqT*{M3S!>TIS7EJabNELnvqH7T{djEoE^Ou-DA&6~?uq*w%b z7#J9w85kIfk1;VYOkk>No4k-in6YN_Rt^s)j}-YD)*7}No*M2N-WvWI!5YpQt`vn{ zu5gB6h7zF^`DR8CE1V(Ef`y?(cmh-90Y-*e5k`h8xfI0`ks6U^#@P&WnNpM{*K^A= zDo>uzoy>S^GBeM;$?3cbjGmJ_c#|1LC%@sHHF++d7h4<y14B{#<hOjXrYRt1Du_q` z5uOYT47b=z5|eULiw&c=(u)!cGU8qQLkx?OKr$?OiMgpo$&>B*%^0gDm+_ZzvdXdW zF$pjh)lB}*@2{55u#l;ixr8N!rJ0eDp@u1iHJho(sfKw0YYpQ<Mn;A_sT!sfw#hjH z%8cxjCkTkzaWu2kvXyYvu+^}pa7r?yaDiYmYb|>TcMW?pV=YGsPYp*3cQ0cwgC>vP zEtbrZ)ZANaiOD6I`FTaIlV1qPtHd%eFob9_79}$<Flh1?34**K0wOX&gb;{Go2)G; z>6Hs&=7ETO5K#akctM&ti_91p7@{~qhR1__SO<~=2Td`ERSF_1K|~dZNS@p$=vm*y zz`#%?tY4H`oLZt=l30`urjl|}K@I`sDlq0`U|?W_Mf?;728I%b6h=_slrSz}N?}T2 zUdU9-P{Lfp(9BrNn9fkbn8ISi0G4A-0R<)#n9Y{L4hh(1hFX>q)*8kdrur0y8s=t} zT2>G@g(00Gg&iE0Z0QU&EGZn43@Mx-2o6hjNLZ$DrEs?})UdjMEMqO<sNtw#P2uSU zB~f0#TdZK86uE$W=ma8ML4*g00Hq4IB5*(_GlIRvz+eNSnHU%tm>C!tf<ehzfPsM_ zouP&ymZO%jhH)ZOAxkhrkp)OUh*-&Vi%HMm7ArVyP3{+#mR-ld!0;JlN|hSe>Uc;X z#zRyn*o)RPfg`mj5fVvhAfv$X365D+5EoCJI)dcE(Faf2Mc{}m2T35sCWs4iA;hhg zpmZ(-c90Q@i{^p+C<Ssa69*#?BL^dh<Y8uG<YVMx6k+6G;$tf6+<ZfDDI;G60|UcK zrlMAmQEbVRC&r3$wKFg<90J+YF?oZq5nDHi*)#ctup(pTWG;~g#>UCrBC^g6AmJjA zHuj>_f}F(UR83xR;w<U{$$)%wi#<6%uOv0EqzGijEk1B)#b@Rfmn7yTrxx{0ek~%! zIB_zYXdvUJ$q}N4j0-n+iP|wTW==jSrepyQLvW&JhnTwvW-i!<TWmRrNvS!-QM}N& zfN+aKCM%1pFkYJMA+F50Vsei74x6Q*IAO<{+rXYcSi}OcXeG!ZcMuUWIYB~}@%iLB z30cNfo99UAGl>R(#JxcTC?yqvlV8Z>2U4aMKA^y0bS?4))4oN1U^=+SA4D?+yWC>S zPs&P7E-CT?Wnoqe5YS{Q3YhFKEytKSIZs-N8|)sCpNrBa&z4qF1X~8m@kJoZZgGMA z7@w0_TvD_e<b*Yo?@6mNZko&@qs;hivWAQ=_YP22mjGw=$&Rurlb6VtDuZ1MHfj?n zD42`DDRV2x0FYfP8H+Ye{v)F;sKm&?Pz)*o7?^|@*_euUO}3B?5CZFADuOF7+Btca ztQNl(NHGgIjj=Hn?cRJ@R*W$KYzf#pkgi*-Wr;bZsbIGkfwB-dXo}W?ECvNu(RvUI z6ih`MKrB!|X>vkb2hKNJCtJ!ZD}&>w5#(~VBCrJ@vmr4BPJhfrsgo7N#U@Xc7iKh= zyi(qfasTGq^4^SLdl(oPesO1%<mTuVBo-B?7TsbhNrAW~1Y{qmd?*S7vA|9OyD$h8 zS<K1#IYl79X)@hnDap)DE!qfD1$OR+$<>PT+<QTMa4@D#UaF{O4{}}+C@?i4C3F$k zWh}+{r3JT`OHzu9_JK5jBasIZiOKmnrMY=Uhe6^SCvz#uGkQ<fQZi>ewK+*?9iuha zS%Dx)kc+^MzQql4N<35}DE@Ep<`<Nt7v+~0_<-_45!hFulf6|^{4apQi?0Y=@_^k5 z4p2mmGYe!iIJtoe##<c4B}D}w<BLF{eM=y<qNFG>xg_4#6<Wr9R53II<!MN`gIx#C z=O8Z?ody{Oa!}D3P}1gxq;p6*-8MNw)tVdRoT7^$WtS$;Q&nKhn!I1tmGSmwRy6@e zQAikoB*CVEeZe?c(NScwow}7GxM*U`gcNz;!VgsL6@f~rd5jDUMIDo8s%tUUOg^IC zEjkkvdu*u{C8>ESw^)l3^U_m`rcO@LaAtfqd4+~6<HX7DG&C7sY?jb;WUM~`vhg5@ z0B2%wV1pvP2o&NkLBRqJ_Lrbqqlzmfu_RF!lAb{hd<j+wPC;iuMw|!bJ7#qqg`#sH zZYU`DIg1QI>?5Es;Yd#{i7x>KE2zT1#hR0!nwU~t1df4+AXOlzg9Bfa3!He0j)O!` zfCzBfxej81Tzd=blz50!)_^?Bm{@cNBnu84FaZuBP#Rq~*;d<}aqr|(?Tymlzy+1} zn%qU|Absp9nTa`|0;yuMqmG#YSY8%nkT!?_I}MZ?G&zdEF%ORK5|C6hh?qNhxsD<0 zbOr{7Gn4P?$ku~c$)K<Tl?fmWYD99t+7m2{p!Ni~?Z8~aoW+>Ml){+JRLfGsuz-0X zL;s~(R;VabHdB#T2}=!QGh;1V3Udw9Y=#t;8n)RCDXcZ1h9g@od!7JX93;Y0%U;8} zpq{ma4b*m6$hd%gAww-k4eJ7qg$#@g=?t};H5@Jsv0=4bC7_lnn<PUsV+mI_Q_-># z?h>9Ft`s&&h6TI}8Ja;>a_32bL`(P<@Iz!4G9u(^xNA7e7>jCZI2Q=iaD!Tjg*7FD zHJqSEl4%WRI0F+y3IhuR3qvzABSSEQA;ScQ;%^2Fj9?haz{rro5X_*-?sto=xG*QP zB(><nWL`ZT(V~x_@C3ySxW>!_MaiehetOFFpeVV;l9HKRa*MU3v>+$7Xc{QuSh7<q zi;F-Bspt(zD<Z0RkfI9I3Mc}_R}@EPad4ndW=ZNTmgM}rydqHi-C`{)O)aXt#a5JB zT$)o-G#_Lzb5VYI5y&Bs+-8eNOfx{zpdw!d6t$oR1v3{DsA(a=B)}}h#KFYE$iXDQ zD8?kk%)!XR#KBlJW3sG%8RrL(`@S+TFif7WFD-!ZD0691PEp+CQ~KIQ;KT)P0)edq z6W|1#&A`C$2V^I>=Lc@c@GvSd6=hFWH#k)f%3?*}yaQR>6h2Sdr7n6>HCVSC; zknP}-?;nW81u8GVB_AkYi$GaUlO0^A+~UkltcXv}FU>0{S^)AYCn(V4LCx%2tPo*P zZE}k_uQV4DHj@hs735i&7#NB{@xZ{y!pOtO!^pxYz-Y%P2WoOL6$wmUZx|#Fb_3Wd zX0TO7d>~gWm@HwWDl81r56UAD{X$Gdf|~=3l9|}R^_=(SohBC<8G|Nwo5^{BTpYz_ zZe(n3WDG9os|0LHQWOxylC63ble%5eOHgUUW?^J(VPsr{7DnLU;hy~2Ove!%C;}jt z2!aT35d?NAD93}7)-BeQ(%gdLB5<IAgAW{XptPnbP&9jTg1M0rxY(%y1uZDhig+0r z7;bSx>NiOFv}f`ba|5|UAQf*x1UPcR1UQC4jSA_>OcsfZTPI(%7TH{3!NOQC1agot zhycZD6^l(tkzJ7ph%X8v#6W~NBLjmbQxVwN;IL&Ynhi34Du|E-sQ}vvc3&+>3~VQu z09!nXfq@|a6!<dW<jlgz!o<PI!pOlW#5DQ0B|k4nUXuyj&@6gC`J#0@;|FMk#5sA7 zm9_~eHi{HL27_|TN=8VL-3Jl?TLLD)Hi7D?EGBS0C2ehD4-R)w>5ItpMV~<0K;4U? zFCZ2u1~l0qc7yW<C=Y}4Y|+%oeb#EMM;RCxQYUBIN>9FG-Gbz>G8=Cju)~x<#(;cQ zBnM)FoLD3S3KU!pEQL7muZ@<BEGT4g+3swstaOZlfuR5tbbR2T6JX?Elw#yz<YVMu zDgw#9JTbY$_NFc<<5%$oyZX2~hbU+%xCQz9Dir+y)slP)KAygwAqrM`rMXF|MWA4w z+-GN}-wSdpDBv_9{gEPY6oLdGISwA2lOV4BZD&*e6Ql=caQ*_xs)2~#AmR^*00%KB z5#M3~wWBq;kxEQ?Mh1o`9%!cp(tKe61sgm9qPU9-bK;>2ikKJ`85oMdNsbw$49%&N z85kI<CttVMW}3_}d4r+CWEF>b@!(1n)NIgXEdskN3*;zp3k~GjTO4VrCCM52d8wMr z;1qC+xwtR~68UJxgHp{LP&|NJ?2H_&QjA5PCM!C+>wujb4>A``OAZ4A!!nQ-P{v|l z;b1JvnLNeOR~$6bpvi(15MUG9CZDww7hDHY54D0(gt2JKWF@DS0-)F}`UbM%JBauJ z&K&QZ43t5wwIXbx0m=vaAra@~Yz&Dwcy$2D0-ykZ1PVO5G&zx61+UPGz_9|V#fm_E zmLeulxx)$?4k?Bt6|ld->17!M1H%@O7a*lH2O|f#*5Z+15@6y371T^c%O<(pXZ$ev zfr~5SkI8DTY4vE%0_RL{T!B*?$d$J^auW**GV{`lixfdI56-g4DGA&nz6lDNTOb1L zR7Q|1xj+?gDr8Uy988c#F-Q^E(H0C0JPbu(r(a`WU^qHi+)ch7#M0yhrw4G86w=@Z z_enr)QAjb5u<bnq14A-sGzXMHL0E%<fq@&=63b&@V5nhOz_5^^ma~Kr+#=(u;mTsl zVy@*bVX0xLVQglq<*8v!VU%Q8z`Bs3mbbo!HH8Vv;j3YROYo;K*9z3|WU&<`fk<#e zjVFtFHp5)zJeC@sEaqCl8bPoqSS+2fR;Y$0g%x5_3R^bw1jeEwBoX#(CXh%8dkP1r zMODMIfTM<gA!BX5aE)*lXVE?onZ=dGoX3>HTq{x|Jb|$&1|$ZiMM}6A@T72NGAv{& zV*rVO{UXxLR4ZB|n#DGOv4{;sgPkJ^ccf?*bFEkkSB=<gh7@k7V}(JoDLh~?7LfV% zAc47DwE{Il3wR;I5X%-aF5syVS;#n>A%(Ywe>THhR#2NTPYkRM;&ZTJbD2TnCG07D zV1Kcqg~0+O^}L|agR15SsZM98trxFhb76?xR4b7pP$N;sFoCJaCq)p(s*y-xND*oU zMG#+#z(U3trdr8bsT!#Td?~^U89^);hS-=|=^E}7k!+?3OhsZ)e@f0~ND-}(p3RUV z1|sLO*UIFn)o`bXgH_q2NWj$9&t^!G1Sv_80+Dk$YGrD~7x31|fZREOvG7fv2$ByZ zU_O|@Sh%5tJw+PiixlAn{53)~;^GVo8Ea*01Zw4K5TO8ycc!8{DKbzCd1o`E$j)W0 zm9Jr+z*Mxard~cp4l2bwn;}JhE~`01t$Yo~1m+@%8dNz2h+Ljc3NuvupBj0%!9?m# zQLK@j&5)u5wo|!A4&;C38u{4_DJnG}BUI;d*D92-r>KE_re4FB$ylpc!#;tzD5{3N zMlnUhh5_ujj2ey_#S~2&h7$G^tr~@9CPolTyG9Yjs*(WpB1!~n6q*@p6c;ir5L(Dk zs{|i4XRbWM$WW^c8Z|GeXHU_oQ3ef~gDgyE2xnkph-64%s8z004u;YO3<jXCj!KP^ z3qx#Ot!jx#jcPMvtr}AHVgrx)Gt{Up5KUpM;a|wa$bb|H5Lp`(^~@7kiZoJ~>hqXV z7;Du*8f(-cWdT?-$RMT~CNNuN0dI{OI6W{IUaL`YVTk3cRV`r$If9X40!v|3jY=?s zrmi1&SOwfj1-H||ErKFYeRzwdI5j5?Qs>))ibK#SSrwO$t6RwA7hZ}kNG*L(iOUTl zK($a6i>{rWdKIg>f@82k5vZq8#hX=}pBE46YbPd`XjHN4D5$IGRk5jSPFD2}Vf;S1 z%3Ft93Zx%WWKQ1bZB{Q<1TNgsni8N<@LR0KB}JJ9kUAJt(BI-rPc3l<58vEkNz2Yp zD{2F|7hH#fn|Gkr1-RLKizO>RGp`6#V<6RQg&@@mpvr(PGp{(cs6<nvC=lGx12+!9 zEjV!ffwO=ISAU>7I*J$6{!dCQPK8Vc%mEpF5=2N%p6TPlxO(zEpJ;&_AOUdY32xyp znC$86B@P}`s0MWwIMXuo5_95<Qj3e287Hsu)eXABz`$@DRB3`*{0yMZ3?m047r2AN z!^pxU$0)$80u~WrRAA&{RAAI#)L;^0<X{p4k1m7S(ISjuj9g$fGK^e|GLz-~!gxW( zYBE7akls&j@_WDrY1L28@VB!DRfe}%l2dbX(5vvPpqh)BfuR@_!VF9-%%JgX4n{5} zE=D0nE~cWZlOOt*a43V?t*k`~lVbzQM8Tm6u5`;leg{no6eUi65um9IYU+f541=@> zKu%?07GUOKW?|%F=3?ezD$3hz5-85d0ZLmd8H=L9Et~WpeZ`^{1_p+ej78?4lmo7- z!L>A~UDL=6Zr|?<GOjlO$$|#|AVY7c=_!gIJPHJwvI56faghp0IXJz5nsY_qrUom> z$)HXRxSOX5?b3sN1GXD9#{llv-$KNGNo7H56jx%-<bq%s#;(b|!Sa&eL<w;x$P%z) zjTspjawZ=QHfJ=R{5SX|qs8RsA*za2prGR|!tM0Qx}mb#U<crFAlz9+){{#^HJI8M zCeIHIVl`o8VCbLxEmWJ)WV2G3G!wT4$Ti?DN$})f5$TiHM@U14o}54u&LFqQV|9xy zNFLmLkDmN1qAC&G@CJn)EQk;;um>px2LM<RxFZ3w@)iduzkmX(2yR<ZKPbGx0R<+& z0cFa_z_5Pu)yP^#)6KzAml;Jtt_F1tK!diBxC<$&m~0&*nPCIU$pS^GX{kj;sVUIm z*<wv$oPLNB1Eqq}yv)MVR8U`{xTGjCGq0o=Qo?A1`XC&c#Sr-@b_iWu)G&EZjCQ>p z$TH@t%z`3tNuvYurvoU+gdy!@EI|+@1Tg~Hswk$?<RWm10P=hkZ$UPaY!S%7B1e!r zxY9rpAU_uuf&9r-<T^Pc){fPTk%8gM<khi(jAonv#-=ecCQeR?H<1JdF?#OJXJBAZ znY=MxkuiVr<@hg>pt($Q76yi5$e<3WjNo7tU@R(_{2<{SW9;Pfi3atcsWN+z8gM3M z;$Y<a&jcaa!0hiuAQiVb;^T7@GxOr(Lo^w0v8JRZm8NSl7RiBvgUQcN6NH)l{M^8d zq9V|MZWLQVVqQvOanU`{7!OZwWqevrVsUnSVnIO>Xy`JEH#a{eb#h(OJy9=E(0YRi zHV|O~N+gda7bb6E%$ls0qE!zb^#Dz*7IlK87J`TsAYv7W08PUb?E<lOgNXeg;uMIu z4I*BE2+;6s5vUp{0*#y&fd<$hqX?j3uUpKSc_l@N@fpxSNfBsJq6pOaFFMBH&%jUw z>R>{8PB|b0L6ubzsJ~ML>Ms<5O4}k(*;xcC^NK)OzX+5Wi$H0+2o!@wptvalMMzQZ zWXV)h#wnBiQ%zXa`53u`C%2^P8Y=N|^6_zSaF}w43UCW>b18Cgad2?3aR_pWDP#x; Xa!GJ0b0~1Qau{$3b8v9*b1?z{UZe>; delta 7776 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 O!+=AWgM)*gixB{jXo>9r diff --git a/my_flask_app/main.py b/my_flask_app/main.py index b7d9e78..36e5cf9 100644 --- a/my_flask_app/main.py +++ b/my_flask_app/main.py @@ -94,7 +94,7 @@ def index(): print("111") for name in dropped_items: print(name) - if dropped_items==[]: + if dropped_items == []: image2 = "" else: tables2 = importMetadata(engine, None, dropped_items, False) @@ -103,7 +103,7 @@ def index(): print("222") - extract_ME_table(engine, 'event_data', 'E', 'time', ['col', 'machine_id'], [' col ', ' name ', ' Z_ACTUAL_ZERO_POINT '], ['value(fine, coarse)'], datetime(2022, 11, 1, 17, 5), datetime(2022, 11, 3, 0, 0)) + # extract_ME_table(engine, 'event_data', 'E', 'time', ['col', 'machine_id'], [' col ', ' name ', ' Z_ACTUAL_ZERO_POINT '], ['value(fine, coarse)'], datetime(2022, 11, 1, 17, 5), datetime(2022, 11, 3, 0, 0)) return render_template('app.html', database=database, schemas=schemas, show_all=show_all, schema_Selected=schema_Selected, tables=tables1, image1=image1, image2=image2, dropped_items=dropped_items, self_labels=self_labels) @@ -138,7 +138,7 @@ def handle_drop(): item_name = data.get('item') action = data.get('action') - dropped_items = session.get('target_table_names', '') + dropped_items = session.get('target_table_names', []) print("444") if action == 'added': dropped_items.append(item_name) @@ -155,6 +155,25 @@ def handle_drop(): return jsonify(image2=image2) +@app.route('/reset-target-table', methods=['POST']) +def reset_target_table(): + print("reset") + database_uri = session.get('db_uri', '') + engine = create_engine(database_uri) + session['target_table_names'] = [] + schema_Selected = session.get('schema_selected', None) + show_all = session.get('show_all', False) + + # Regenerate ERD based on the updated dropped_items + themes = getThemes() + tables1 = importMetadata(engine, schema_Selected, None, show_all) + tables2 = importMetadata(engine, None, [], False) + graph_DOT2 = createGraph([], themes["Blue Navy"], True, True, True) + image2 = generate_erd(graph_DOT2) + + tables1 = [table for table in tables1] # Ensure CustomTable has a to_dict method + + return jsonify(image2=image2, tables=tables1) @app.route('/get-table-data', methods=['POST']) def get_table_data(): @@ -454,6 +473,7 @@ def check_json_column(engine, table_name) -> list: def handle_json_column(engine, table_name, column_name): insp = inspect(engine) + isSQLite = insp.dialect.name == 'sqlite' # Create a connection from the engine with engine.connect() as conn: @@ -470,11 +490,17 @@ def handle_json_column(engine, table_name, column_name): conn.close() jsonKeys = [] - for row in result: # row is a tuple, row[0] is a dictionary - # print(row[0]) - name = tuple(sorted(row[0].keys()))if type(row[0]) == dict else json.loads(row[0]).keys() + for row in result: # row is a tuple, row[0] is a dictionary + # Convert the keys to a sorted tuple for consistency + if type(row[0]) == dict: + name = tuple(sorted(row[0].keys())) + else: + name = tuple(sorted(json.loads(row[0]).keys())) + + # Append the key list if it's not already in jsonKeys if name not in jsonKeys: jsonKeys.append(name) + print(jsonKeys) return jsonKeys @@ -606,7 +632,7 @@ def getObjectColumns(table_name:str) -> list: return object_columns -def query_database_for_table_content(engine, table_name, number=100): +def query_database_for_table_content(engine, table_name, number=200): # Initialize content list content_list = [] # Create a connection from the engine @@ -701,9 +727,10 @@ def get_min_max_datetime(engine, table_name, time_column, start_time=None, end_t return None, None - def extract_ME_table(engine, table_name: str, type: str, time_column: str, object: list, label: list, features_name: list, start_time: datetime = None, end_time: datetime = None) -> list: conn = engine.connect() + insp = inspect(engine) + database_name = insp.dialect.name # 'postgresql' or 'sqlite' table_instance = getTableInstance(engine, table_name) label_column = label[1].strip() label_value = label[2].strip() @@ -737,7 +764,10 @@ def extract_ME_table(engine, table_name: str, type: str, time_column: str, objec column_name, keys = feature[:-1].split('(') keys = keys.split(', ') for key in keys: - json_extraction = f"{full_table_name}.{column_name}->>'{key}' AS {key}" + if database_name == 'postgresql': + json_extraction = f"{full_table_name}.{column_name}->>'{key}' AS {key}" + elif database_name == 'sqlite': + json_extraction = f"json_extract({full_table_name}.{column_name}, '$.{key}') AS {key}" json_extractions.append(json_extraction) else: sql_columns.append(f"{full_table_name}.{feature}") diff --git a/my_flask_app/templates/app.html b/my_flask_app/templates/app.html index 2583177..f8e43df 100644 --- a/my_flask_app/templates/app.html +++ b/my_flask_app/templates/app.html @@ -42,7 +42,7 @@ background-color: #add8e6; padding: 10px; margin: 0; - margin-top: -1px; + margin-top: 0px; box-sizing: border-box; position: fixed; /* Fixed positioning */ @@ -195,6 +195,7 @@ justify-content: space-between; align-items: center; margin-top: -4vh; + text-align: center; } .terminal-body { padding: 1rem; @@ -407,20 +408,17 @@ <legend style="margin-top: 3px;">Target Tables:</legend> <div class="border border-secondary rounded" id="table_list" > - <div id="dropped_items"> - <div uk-sortable="group: sortable-group" class="uk-list uk-list-collapse "> - {% for item in dropped_items %} - <div class="uk-margin" style="height: 15px; margin-bottom: -4px;"> - <div class="list-group-item-action uk-card uk-card-default uk-card-body uk-card-small" style="height: 15px; padding-top: 5px;">{{ item }}</div> - </div> - {% endfor %} - </div> + <div id="dropped_items" uk-sortable="group: sortable-group" class="uk-list uk-list-collapse "> + <!-- <div > --> + {% for item in dropped_items %} + <div class="uk-margin" style="height: 15px; margin-bottom: -4px;"> + <div class="list-group-item-action uk-card uk-card-default uk-card-body uk-card-small" style="height: 15px; padding-top: 5px;">{{ item }}</div> + </div> + {% endfor %} + <!-- </div> --> </div> </div> - <!-- don't use form, try use javascript to handle the reset button --> - <form action="/handle-drop" method="POST"> - <button id="resetButton" type="submit" class="btn btn-secondary headerButton">Reset</button> - </form> + <button id="resetButton" class="btn btn-secondary headerButton">Reset</button> </div> <div id="content"> @@ -654,10 +652,8 @@ <div class="custom-buttom-bar"> <div id="terminal" class="terminal"> <div id="terminal-header" class="terminal-header"> - <span style="position: absolute; left: 5px;">Table</span> <span uk-icon="menu" style="position: absolute; right: 70vh;"></span> - <!-- <span id="close-terminal" uk-icon="close" style="position: absolute; right: 1vh; z-index: 1000;"></span> --> - <button type="button" class="btn-close" aria-label="Close" data-bs-dismiss="modal" style="position: absolute; right: 1vh; margin-top: 1px; z-index: 1000;" onclick="toggleTerminal()"></button> - <!-- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> --> + <span style="position: absolute; left: 5px; margin-top: 7px">Table</span><span aria-hidden="true" uk-icon="menu" style="margin-top: 4px;"></span> + <button id="myModal" type="button" class="btn-close" aria-label="Close" data-bs-dismiss="modal" style="position: absolute; right: 1vh; margin-top: 1px; z-index: 1000;" onclick="closeTerminal()"></button> </div> <div id=terminal-body class="terminal-body"> <p> No table selected.</p> @@ -707,7 +703,7 @@ <div id="resize-handle-left" class="resize-handle-left"></div> </div> - +<!-----------------------------------------------------------------------------------------------------> <script> var jq = jQuery.noConflict(); function initializeSlider(minDatetime, maxDatetime) { @@ -748,7 +744,6 @@ } // Initialize the slider with dynamic datetime values - console.log("initialize slider with dynamic datetime values"); jq("#slider-range").slider({ range: true, min: toTimestamp(minDatetime), // Use minDatetime from the server @@ -763,6 +758,13 @@ var endDateTime = new Date(ui.values[1]); jq("#amount1").val(formatDateTime(startDateTime)); jq("#amount2").val(formatDateTime(endDateTime)); + }, + create: function(event, ui) { + // Set the initial datetime values when the slider is created + var startDateTime = new Date(jq("#slider-range").slider("values", 0)); + var endDateTime = new Date(jq("#slider-range").slider("values", 1)); + jq("#amount1").val(formatDateTime(startDateTime)); + jq("#amount2").val(formatDateTime(endDateTime)); } }); } @@ -803,7 +805,6 @@ } - function click_all_MD_table(element) { var checkboxes = document.querySelectorAll('#MD-table tbody input[type="checkbox"]'); checkboxes.forEach(function(checkbox) { @@ -1272,9 +1273,9 @@ } - function closeTerminal() { + function closeTerminal() { var terminal = document.getElementById('terminal'); - terminal.style.height = `0 px`; + terminal.style.height = '0px'; // Correctly set height to 0px without space } @@ -1494,6 +1495,39 @@ } } + document.getElementById('resetButton').addEventListener('click', function() { + // event.preventDefault(); // Prevent the default form submission + console.log('Reset button clicked'); + // Send a POST request to the server + fetch('/reset-target-table', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }) + .then(response => response.json()) + .then(data => { + document.getElementById('show_tables1').innerHTML = ''; + document.getElementById('dropped_items').innerHTML =''; // Clear the dropped items + for (let i = 0; i < data.tables.length; i++) { + var item1 = document.createElement('div'); + item1.className = "list-group-item-action uk-card uk-card-default uk-card-body uk-card-small"; + item1.style = "height: 15px; padding-top: 5px;"; + item1.textContent = data.tables[i]; + var item2 = document.createElement('div'); + item2.className = "uk-margin"; + item2.style = "height: 15px; margin-bottom: -4px;"; + item2.appendChild(item1); + document.getElementById('show_tables1').appendChild(item2); + } + + showErdCanvas("erdCanvas2", "zoomInBtn2", "zoomOutBtn2", data.image2); + showErdCanvas("erdCanvas3", "zoomInBtn3", "zoomOutBtn3", data.image2); + + }) + .catch(error => console.error('Error:', error)); + }); + document.querySelectorAll('.type-radio').forEach(function(radio) { radio.addEventListener('change', function() { @@ -1587,10 +1621,7 @@ }); - document.getElementById('close-terminal').addEventListener('click', function() { - closeTerminal(); - }); - + // function select_schema(){ @@ -1659,47 +1690,6 @@ // }); // } - - - // document.getElementById('resetButton').addEventListener('click', function(event) { - // event.preventDefault(); // Prevent the default form submission - - // // Send a POST request to the server - // fetch('/handle-drop', { - // method: 'POST', - // body: JSON.stringify({'reset': true}), - // headers: { - // 'Content-Type': 'application/json' - // } - // }) - // .then(response => response.json()) - // .then(data => { - // // let tables_list = data['tables']; - // document.getElementById('tables').innerHTML = data.tables; - // // for (let i = 0; i < tables_list.length; i++) { - // // let table = tables_list[i]; - // // let item_inner = document.createElement('div'); - // // item_inner.className = 'ist-group-item-action uk-card uk-card-default uk-card-body uk-card-small'; - // // item_inner.style = "height: 15px; padding-top: 5px;" - // // item_inner.textContent = table; - - // // let item_outer = document.createElement('div'); - // // item_outer.className = 'uk-margin'; - // // item_outer.style = "height: 15px; margin-bottom: -4px;" - // // item_outer.appendChild(item_inner); - - // // document.getElementById('show_tables1').appendChild(item_outer); - // // } - // document.getElementById('dropped_items').innerHTML =data.dropped_items; - // showErdCanvas("erdCanvas2", "zoomInBtn2", "zoomOutBtn2", data.image2); - // showErdCanvas("erdCanvas3", "zoomInBtn3", "zoomOutBtn3", data.image2); - - // }) - // .catch(error => console.error('Error:', error)); - // }); - - // Attach click event listener to each dropped item - }); </script> -- GitLab