From 372e5c087e1866172903ccad914641478cd2a8f6 Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 7 Feb 2025 23:35:59 +0100 Subject: [PATCH] Funcionando la lectura de los grupos de scripts --- backend/__init__.py | 0 backend/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 149 bytes backend/app.py | 31 +++++++++-- .../directory_handler.cpython-310.pyc | Bin 833 -> 1016 bytes .../profile_manager.cpython-310.pyc | Bin 3793 -> 4205 bytes .../script_manager.cpython-310.pyc | Bin 3382 -> 4252 bytes backend/core/directory_handler.py | 7 ++- backend/core/profile_manager.py | 43 ++++++++++----- backend/core/script_manager.py | 28 ++++++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 163 bytes .../__pycache__/base_script.cpython-310.pyc | Bin 0 -> 2158 bytes .../__pycache__/x1.cpython-310.pyc | Bin 1640 -> 1657 bytes .../__pycache__/x2.cpython-310.pyc | Bin 1640 -> 1657 bytes backend/script_groups/example_group/x1.py | 2 +- backend/script_groups/example_group/x2.py | 2 +- data/profiles.json | 4 +- files.txt | Bin 1582 -> 2666 bytes frontend/static/css/style.css | 29 ++++++++++ frontend/static/js/main.js | 9 +++- frontend/static/js/scripts.js | 50 ++++++++++++++++-- frontend/templates/index.html | 13 +++-- 21 files changed, 189 insertions(+), 29 deletions(-) create mode 100644 backend/__init__.py create mode 100644 backend/__pycache__/__init__.cpython-310.pyc create mode 100644 backend/script_groups/__pycache__/__init__.cpython-310.pyc create mode 100644 backend/script_groups/__pycache__/base_script.cpython-310.pyc diff --git a/backend/__init__.py b/backend/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/__pycache__/__init__.cpython-310.pyc b/backend/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07d5af7e3b5d4b4d310b6b0305f9459da11ee060 GIT binary patch literal 149 zcmd1j<>g`kf{CA&ri19mAOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUTx6swqkqWsF# z', methods=['PUT']) def update_profile(profile_id): """Update existing profile""" - profile_data = request.json try: + profile_data = request.json + print(f"Received update request for profile {profile_id}: {profile_data}") # Debug profile = profile_manager.update_profile(profile_id, profile_data) + print(f"Profile updated: {profile}") # Debug return jsonify(profile) except Exception as e: + print(f"Error updating profile: {e}") # Debug return jsonify({"error": str(e)}), 400 @app.route('/api/profiles/', methods=['DELETE']) @@ -72,11 +75,33 @@ def delete_profile(profile_id): except Exception as e: return jsonify({"error": str(e)}), 400 +@app.route('/api/script-groups', methods=['GET']) +def get_script_groups(): + """Get all available script groups""" + try: + groups = script_manager.get_available_groups() + return jsonify(groups) + except Exception as e: + return jsonify({"error": str(e)}), 500 + +@app.route('/api/script-groups//scripts', methods=['GET']) +def get_group_scripts(group_id): + """Get scripts for a specific group""" + try: + scripts = script_manager.get_group_scripts(group_id) + return jsonify(scripts) + except ValueError as e: + return jsonify({"error": str(e)}), 404 + except Exception as e: + return jsonify({"error": str(e)}), 500 + # Directory handling endpoints @app.route('/api/select-directory', methods=['GET']) def handle_select_directory(): """Handle directory selection""" + print("Handling directory selection request") # Debug result = select_directory() + print(f"Directory selection result: {result}") # Debug if "error" in result: return jsonify(result), 400 return jsonify(result) diff --git a/backend/core/__pycache__/directory_handler.cpython-310.pyc b/backend/core/__pycache__/directory_handler.cpython-310.pyc index 1bd90e349a95ed3ed384ef361698d297364dd48e..8f1efa00d6707dfa1ca59423a41e13220c91abed 100644 GIT binary patch delta 511 zcmY+Bze~eF6vyAYyQXQX8MKP1U=$I%R2*D7D&716Di%c)^+Ju7M6M^nkf`9~pdbMk z5!yxYKX7&PUoiiLn}diKs}&F4fKS$of#UU#X6Ha+BLl~Z_k)g>1a+> z<3%+IO>98~Av8$~5Q4Q}N>Yv&h#=WPh7+kBWScstE#&NqM5wlz5bxlgq@EDP1lK}z z(4{=fbq6D&9J!Em9Ha`>l%H$CCc+9ZkjBXtLPXVbgUW2kd`K@kNSqZeO7SI5^#_F&yRJ4i z|Fe{>_zA}sf}Ukt9*gg|up7s9S+;_qiV&W#9M@`m=e9fGvb9+3N{Bq%AghNPy6?z+ zE_VDRb0i#B#&0+~$`U3#PbRreDAC&F1noxVq;;WaF|ZrpqGFL>%x(6X9CtrWFhsX zu<$ed35%=rFSLlbhamdk4a_hzFdzPlSBtAv3GNQxo-QZ!SeuTRW2Ln3{^r4ffgER$ zK?*s|0AaW@Y#P?%3QeWw<-VdBDt1p9rl^~Wrx@WiQx)Y!7(!U)M43AV4kj4vB4p%R z>Z)R7N_Wm3f(NId{ETj?^*8V%C7Aq{B+wRiga`H=x9kS3H;&p11(|+_PWl~@MCMBA zv&2qmZ%Dv%KyOhqwzFtOsv;DJL!B!=igB%OjqXmNH+!@30m zHxuGv6EBEqFWfvB55#}Ln+GqwnwWU-;LQ{Irez7cnJ;hN`{qsd{r20?Z{gHZDVyLk z{^nrub>@@v(+Ce)YV#eY0+3KA$_&U7X@Y;#14%Kadt{&P01%Jqon(^B*e-jUZc>jg z#R3SZG^Dx9fXosJoN%&(an-s-+_46p)9({p*w4~^v}*=kp0Pd!q={aC)52mrV9{0E zXlb$y)_?}d+kXGd{90M8s@g(jx$FwBCUj8rGnlVb7f)9Tq5};zh@Yc|P=0ZgJamjo zRhFxse`z{u;$llF+p#L%J!P)I``zJvc9>VSiLYl|L*Kg{>=Fx;{}!qn&S z_yIsM{BA$mjNvIw>H#kID~dnu;Zy?HBZx&q;d+=jezF8>pe}fbrd#FvYzMZ{DPu3G z%1I-jYeeO+ZtA?pTD(nKu{J?))&$Y#1IUt=(MA{nYncIU!!vBHd1GmU;KlLC79k2q z%W5OlC_hWOOylbknQ~-m;VC=dkspyJntX$IktV|riR@+n?Bi8A@12^p@ROoZ@m>f_ z&lf~^n3%kC>_S+_KR`kF*&e7$Rn&Ed^4v+On76x_!lOj?o*Kuwb&Q@zUBgWeRICT; zu1?%Xd3vT)R|@}+s1K66ogBGQ#+sW$p)>*)qenm)eQgu delta 488 zcmX|+!7D^T9LImZnc4T=uHE&PSX+qQQcJ=`DWXu$tfZ9GXlo_RzFno+6lYO$MC~59 zImn5B!O3+U++5_~rYL^1T5tM(-uM09yxx4?`<{B@JF!><=vsTZ%J(O3NBofD3*0uluXIHoRf3C5t9*+&Gs zRw;Itbn11-H%W!gO;%-8v4AW!o`YnU{1}g@OTNWa zN(#-&pi=ZcWaj~^@)}e{4anG;1pB?l6jVc+)yPsq)v1wXb8cM^lFPetBiJfY% diff --git a/backend/core/__pycache__/script_manager.cpython-310.pyc b/backend/core/__pycache__/script_manager.cpython-310.pyc index 3962c1ffab2b0d4e106e163759b37f2e12b7cff1..97eb1135a2a45bceb37af32296d2b2d171e53e5e 100644 GIT binary patch delta 2186 zcmah~O^g&p6z;0->FN31Sy*5f5ZcA;I?FPGKO04YfFMC-QAs$gl1}eb&C<}!46l1| zne?WK5O2hoK7z^2#e_4#7!RC0d)7`odH2G_Y-04i>fPmMG4`asysB3}?|tv9njd!F zd%4=FREipYe}4V_(l2A*Rv*T{Voz!dOlS*SFsVyJ=A_x;6WWB<;(`nPwy}^GIJ(Je zh@3FdYZWw+mj#?{i30YEn`UxR6eaYOL|GQlTi!S&reh3I5mj_o#K?2*%v%$q=&hJn2PvieP9SSWWiL#207}hF;g(XhkTG9 zYM~YJTTJNp^dV!~wS2@d5~IKGv1dggu$0ycqujAZdbNN zng`kS-KI=)p%?lx)q@c56vGIl-%5__TaEh~OeBA?Gx6Ax44w7(}^e$ zcR1D~-?ynA8K;5W>VWOqL02|oujMtfYV@mFURlqc?w6+Rb|=Kiy|!2_EPsCRz&jTk z-5VQfqO3?+l;L@7k4aS#3UmUy_xU`Oun!Xm_gTu8m6gFx980YuzI)YM6zigF-;<{RI*?q; zjmKNmjGzOd6m=7}V;6Q4jFTh3c1Bvt45#Ixc-A{!8)>6#p2}gAivLV}J8*)MPLbDm zjiG>85#>{4{AP_$_4ocydMbzHA#2P~GIgGXNcQtbTaM$kz0h%{laKgh(&IN{Al=sU zY7ZEpHAI5CCNPRtT6OSY@Ne|jbPhyE-N??Mz!eP(#Wn4|Am0(;1Z1%w!^B6PL|}*}gSLGW0Tr$UJDUtFd!Ksz^v>dCc#9@HD@>Klhsht- z;)8RAHe++iqvBjlm$bem+jWW-O%og@c$eS^!BK+u2#ygPCpbYsj~1LHI7OgHpCd~J zNWs@DPu-|b$n_}!{l^eFr#1MP%(DdZ1e61uLrBf+#=R()v?`ZnvlmJyn{y@kx%5R` z%c7uo(z4@R>$yJte>e^pw5d)&F+q-C7eRx7o*8(J;1GdHK()!re}SwgR6Z$R9v$?& i1tdC4+nHl~s=S)qEx&Cl{*EWVmG{@4Uzv5OS#EX{3~p@3PDv`H z2#FVfy>de0zzqq35EtHo<4U{$kHCo?yMU-_$)9I;X6JYPX8Lp8i7FLKk(GNnk3PD@f_QG;nxYyYR! zs7WoUEmM0}ZJAc2wn80d(5ifEY-G@}e=elMzri{d-9yKvxkLA^Dei=*thFJC)7yT} z?=sk$&4r|qWZMlIB<*OE!LZ@?XoC${yPpP8PmJYyuM1H>PCObwTg4XS5C2}AnJ}d6 zszOUx*a2L;SHR*zy=fVq7xaSE^K5=VpWz?K1i!5(BSAd3lv#>WkTQ@?g&t(ih1T;o zn6Q%6hctN>q>qH-$&|z47Rz%Gx*x}^M_mm}8B6GSX2Q(Am|)Aw#h}-T0Oys%M(e7q zvyv6MU6I2VOJ~U>4@*DnEpu>xe(v1EW<2Dp#zEhaCw`Geo5=5<2W4!)ntT&1_PIjI zlw7*%s!#)(#d3)tgPoy`^P#`7PW_9=@F@B)_%~x=B#jGC*w8INUGBk{gec`*Ph3-I z-7s1g)xS;1HLw@W%#}f##o3&SF$BGI`!ujP^xI4n(;y9*(31#KMqNGY7))ZA19;w+ z&gSH$@H#=rTDZam_DvABBYzl|C+a*lZ<5)MU(L%z&(nQvH_3i}(*ANx6p|E#4J`E2 zV3T=il+75XG2V=XYvc*c^09K`P*!LmT7L{j(BS_;K|}5}`Q7rmX>3oEe*9F92sz3R zJIkXR=x$Gbhjcawk~9(4JwNQT6@Uof1iG96$vN*shF4B+~L#J2cv2p7c&rL z&wJYUL;L|e56+=eyd_XZXovy=lY$~*A3{gqY_gWYEtLNCGL!J;LrDVfYl7o96pc7) Yy}*mLB|YoaBEM8SUfX$)Z`Edg13woo?EnA( diff --git a/backend/core/directory_handler.py b/backend/core/directory_handler.py index ef81c63..ea44391 100644 --- a/backend/core/directory_handler.py +++ b/backend/core/directory_handler.py @@ -13,12 +13,17 @@ def select_directory(): root.withdraw() # Hide the main window try: + print("Opening directory dialog...") # Debug directory = filedialog.askdirectory( title="Select Work Directory", initialdir=os.path.expanduser("~") ) - return {"path": directory} if directory else {"error": "No directory selected"} + print(f"Selected directory: {directory}") # Debug + result = {"path": directory} if directory else {"error": "No directory selected"} + print(f"Returning result: {result}") # Debug + return result except Exception as e: + print(f"Error in select_directory: {str(e)}") # Debug return {"error": str(e)} finally: root.destroy() \ No newline at end of file diff --git a/backend/core/profile_manager.py b/backend/core/profile_manager.py index 341b5ec..8b0037b 100644 --- a/backend/core/profile_manager.py +++ b/backend/core/profile_manager.py @@ -58,8 +58,14 @@ class ProfileManager: """Save profiles to file""" if profiles is None: profiles = self.profiles - with open(self.profiles_file, 'w', encoding='utf-8') as f: - json.dump(profiles, f, indent=4) + try: + print(f"Saving profiles to: {self.profiles_file}") # Agregar debug + with open(self.profiles_file, 'w', encoding='utf-8') as f: + json.dump(profiles, f, indent=4) + print("Profiles saved successfully") # Agregar debug + except Exception as e: + print(f"Error saving profiles: {e}") # Agregar debug + raise # Re-lanzar la excepción para que se maneje arriba def get_all_profiles(self) -> List[Dict[str, Any]]: """Get all profiles""" @@ -94,19 +100,28 @@ class ProfileManager: def update_profile(self, profile_id: str, profile_data: Dict[str, Any]) -> Dict[str, Any]: """Update existing profile""" - if profile_id not in self.profiles: - raise ValueError(f"Profile {profile_id} not found") + try: + print(f"Updating profile {profile_id} with data: {profile_data}") + if profile_id not in self.profiles: + raise ValueError(f"Profile {profile_id} not found") + + if profile_id == "default" and "id" in profile_data: + raise ValueError("Cannot change id of default profile") - if profile_id == "default" and "id" in profile_data: - raise ValueError("Cannot change id of default profile") - - # Update timestamp - profile_data["updated_at"] = datetime.now().isoformat() - - # Update profile - self.profiles[profile_id].update(profile_data) - self._save_profiles() - return self.profiles[profile_id] + # Update timestamp + profile_data["updated_at"] = datetime.now().isoformat() + + # Update profile + current_profile = self.profiles[profile_id].copy() # Hacer una copia + current_profile.update(profile_data) # Actualizar la copia + self.profiles[profile_id] = current_profile # Asignar la copia actualizada + + print(f"Updated profile: {self.profiles[profile_id]}") + self._save_profiles() + return self.profiles[profile_id] + except Exception as e: + print(f"Error in update_profile: {e}") # Agregar debug + raise def delete_profile(self, profile_id: str): """Delete profile""" diff --git a/backend/core/script_manager.py b/backend/core/script_manager.py index cf6f0fa..72609a1 100644 --- a/backend/core/script_manager.py +++ b/backend/core/script_manager.py @@ -6,6 +6,34 @@ from typing import Dict, List, Any, Optional import json class ScriptManager: + def get_available_groups(self) -> List[Dict[str, Any]]: + """Get list of available script groups""" + groups = [] + + for group_dir in self.script_groups_dir.iterdir(): + if group_dir.is_dir() and not group_dir.name.startswith('_'): + groups.append({ + "id": group_dir.name, + "name": group_dir.name.replace('_', ' ').title(), + "path": str(group_dir) + }) + + return groups + + def get_group_scripts(self, group_id: str) -> List[Dict[str, Any]]: + """Get scripts for a specific group""" + group_dir = self.script_groups_dir / group_id + + if not group_dir.exists() or not group_dir.is_dir(): + raise ValueError(f"Script group '{group_id}' not found") + + scripts = [] + for script_file in group_dir.glob('x[0-9].py'): + script_info = self._analyze_script(script_file) + if script_info: + scripts.append(script_info) + + return sorted(scripts, key=lambda x: x['id']) """Manages script discovery and execution""" def __init__(self, script_groups_dir: Path): diff --git a/backend/script_groups/__pycache__/__init__.cpython-310.pyc b/backend/script_groups/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97b55df9b40fc8cb8a5e6394ec14663d580e3014 GIT binary patch literal 163 zcmd1j<>g`kf{CA&ri19mAOaaM0yz#qT+9L_QW%06G#UL?G8BP?5yUUI6swqkqWsF# zh($ literal 0 HcmV?d00001 diff --git a/backend/script_groups/__pycache__/base_script.cpython-310.pyc b/backend/script_groups/__pycache__/base_script.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61187d60747202acfa581658a6fe3e08a60d5515 GIT binary patch literal 2158 zcmaJ?-ESL35Z~R~`-o$k5@_fb<)}~_^AXVp5Q-{9DOFWbMHP7nn4pt;yH2h>-q$MnLEd^tBSR5Jae-%J3GJM?&YmkgTVOX?>{%U z0z&>mV|qAXdqK>XnIwfkzdDOWLT;O1KUcCD~>OMakIYYA+l@lV?K4rG`t0 z#g7p7aR_+)1i{xvO3BQGM>FC)>nEEd)iX(+&E%LE-&NavrKs7&D`CAg$Pp^3N2$@1 z@FJ|+91cd>gvnr-$^llOMp-zJW-AxKleboLbMwe0#dW1})p0D>GVLo5`l);nPl=j` zzvnl_%EoP#@8S0KMx9=7+{)u#IyTnjosB!a_@2zfMh#`Osq)cK!&@z*`qlDq&pJ@X z9OTr9UNB#@k9n~SE*n%~Q6gsG#$xbDRd7EB#gG!<7W6FHcS`4wJ|XH>amla}7%d#Z zA349a_PKEmdC8y9eRmy>4kw%(IFw|;WuhtLeKDr@ISnVX70X*!hd{7bW zm`%?Y#to}yF5lI8W~qAaj!gfPFP>5x$SlqUFmTnj>+Wc24A{C@tbhyCyodhrS}S2E zP#l_MJ-M4`qb<*eGPAtO%yF`HHl?w1*LPz%L?T*usFKWde1%=E3DCw2^L0^Cbr5Oa zdbMq-te8=YCeCa?#;Eo#g00VhXtIDYdV)6TxtEKqO;1tIf(Pth?i44da6gW;!O_-Y z+`!Sm13rQOA26oi=f(FWuL!UN@bfA7-3ope;P?I?{;UFD_>bAXCxX)3rs}hVl%QWB zrGx*cNy)B|D*xP=UJLt>|E^nlr7Id@{t*ysdKJ{y2oP<3nrQXgidefqEPqU_X6e5| zEdRcb@jx-qkXW5o@!?u;TfUZ6CVz!f>J4a;I)UO%6bm3$3+M9kr|`k>x24hmx_TR3 zC@kH1hW&<%!Amj$w?%QXW|r=4zlK=qBt|04>KzoPKv*tDgP}s$)mae0!C5Y;_tA9@ z#k(lZqj(Pm-Z4{5nukT@m`WdjOD}@ zMizbpzac9N-B=lr@C6}(CBM6S@A;nOckj~+GT(QJIsW})kCq;Sy(STKNE0fsvV@t+ zhJ3^mZjoamxUgqL*wVUVi7jZ0M9v)FM^^40c9d+T&>v5pXCvx)hR*pVNC|=dqFYw3 zt1PB-s?S+;v}9Dk=$lfQW*}9#3uPQD+u>AodNOiPi?mEBR8;Mu5t{N2)9=4f{UEI+U=wRc_nJ9_=k26vgugWy5?uvKNL`0v4OCI Rzz}d_5#{{}Z0Hjw{062RU9|uJ delta 413 zcmZutyGjE=6rI=3hRtp?3L-JZssyry(JF;li6|CUQHyOt+!;eK%gWuP&?bfcfXp{o zSmqo2i!H28BQ}CoIyYb;IB?H>oO92>{qkS^N)`kju}^$F_TSux%GNPce8^&^F!Pw( zEQTT#v7qFLC`ZYAqNJvGJa!cCkjR}eyC2cQ+wbMNlfdA5G(*ejBxQbJi$Yw2*05kc z*(QxmowpfKbIPN`s%4>U;kFbe8R$H0f{$&r5svd-Uq{}FPBXaK4Pgnj3rGe?YULda z@+(U$n`hpZt4ObzZ{A+VKcVs~FFa*+-MJks;#8P(aV8~}u9=FBa?O?n)lURk=0&_u zn%E09NJg-Os@7lF#@4am+Q`wTLSj;3qGvSYipbL-fhUD%o3IOZF>v?KTS z0R~<@u#Lb}V7{~&Zd#yKz8`{v7cER|2<#ZTeU#8Ke9gd<*}QSxml10M?{aYZYvR+h z3mb_^U>(tOi|iTJ&<@(3x9Ai{2GnHXZG^~DKDK_Kd;#r@dkEq`TdcMa{i+?~HY+q?6x*Te3de#NL#R^!xnJ7|jh7AtvFeQ2k#Pq0r#7?*oy zy(`q^*1f9tk-CI$v({vLie46DmuId+MA&EC|FphIO49OShN|6c@jCi+3v{@jbvc{0vjwK7_vQnXtPVw4~Bw`pB?J$V-L ze5oQ7BC#6Va5=vtC?g^I+B<5fpS~u=h&ish1S^UEK|V?m(o?cG38&{ K43Q1NQ}Yk-(pcsI delta 52 zcmaDQvW|!8|G$lYPB2d56xjTTg^h9Y16Gd7A6V7EbRUb*W=;?Dv=e DOIs9B diff --git a/frontend/static/css/style.css b/frontend/static/css/style.css index bc6f798..60220d9 100644 --- a/frontend/static/css/style.css +++ b/frontend/static/css/style.css @@ -160,4 +160,33 @@ margin-top: 0.5rem; white-space: pre-wrap; font-size: 0.9rem; +} + +/* frontend/static/css/style.css */ + +.script-group-selector { + margin-bottom: 20px; + padding: 1rem; + background: white; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +.script-group-selector label { + display: block; + margin-bottom: 0.5rem; + font-weight: 500; +} + +.script-group-selector select { + width: 100%; + padding: 0.5rem; + border: 1px solid var(--border-color); + border-radius: 4px; + background: white; +} + +#scriptList { + display: none; + margin-top: 1rem; } \ No newline at end of file diff --git a/frontend/static/js/main.js b/frontend/static/js/main.js index 1b2c923..3ca3e02 100644 --- a/frontend/static/js/main.js +++ b/frontend/static/js/main.js @@ -93,19 +93,26 @@ function updateWorkDirDisplay() { async function selectWorkDir() { try { + console.log('Requesting directory selection...'); // Debug const response = await apiRequest('/select-directory'); + console.log('Directory selection response:', response); // Debug + if (response.path) { - await apiRequest(`/profiles/${currentProfile.id}`, { + console.log('Updating profile with new work_dir:', response.path); // Debug + const updateResponse = await apiRequest(`/profiles/${currentProfile.id}`, { method: 'PUT', body: JSON.stringify({ ...currentProfile, work_dir: response.path }) }); + console.log('Profile update response:', updateResponse); // Debug + await selectProfile(currentProfile.id); showSuccess('Work directory updated successfully'); } } catch (error) { + console.error('Error in selectWorkDir:', error); // Debug showError('Failed to update work directory'); } } diff --git a/frontend/static/js/scripts.js b/frontend/static/js/scripts.js index 1b61ff0..6450434 100644 --- a/frontend/static/js/scripts.js +++ b/frontend/static/js/scripts.js @@ -8,16 +8,60 @@ document.addEventListener('DOMContentLoaded', async () => { await loadScriptGroups(); }); -// Load script groups from API +// Load script groups when page loads +document.addEventListener('DOMContentLoaded', async () => { + await loadScriptGroups(); +}); + +// Load available script groups async function loadScriptGroups() { try { - scriptGroups = await apiRequest('/scripts'); - updateScriptGroupsDisplay(); + const groups = await apiRequest('/script-groups'); + const select = document.getElementById('groupSelect'); + + select.innerHTML = ` + + ${groups.map(group => ` + + `).join('')} + `; } catch (error) { showError('Failed to load script groups'); } } +// Load scripts for selected group +async function loadGroupScripts(groupId) { + const scriptList = document.getElementById('scriptList'); + + if (!groupId) { + scriptList.style.display = 'none'; + return; + } + + try { + const scripts = await apiRequest(`/script-groups/${groupId}/scripts`); + + scriptList.innerHTML = scripts.map(script => ` +
+
+

${script.name}

+

${script.description || 'No description available'}

+
+
+ +
+
+ `).join(''); + + scriptList.style.display = 'block'; + } catch (error) { + showError('Failed to load scripts for group'); + } +} + // Update script groups display function updateScriptGroupsDisplay() { const container = document.getElementById('scriptGroups'); diff --git a/frontend/templates/index.html b/frontend/templates/index.html index 89a43a4..d7ea1cd 100644 --- a/frontend/templates/index.html +++ b/frontend/templates/index.html @@ -32,9 +32,16 @@
-

Available Scripts

-
- +

Scripts

+
+ + +
+