From 9433d9d235e269fee61dc97550ff47ff2f5f57e7 Mon Sep 17 00:00:00 2001 From: pika Date: Sun, 30 Mar 2025 22:01:42 +0200 Subject: [PATCH] wip --- app/routes/__pycache__/api.cpython-313.pyc | Bin 12747 -> 13023 bytes .../__pycache__/dashboard.cpython-313.pyc | Bin 15971 -> 16282 bytes app/routes/api.py | 30 ++- app/routes/dashboard.py | 15 +- app/templates/dashboard/app_form.html | 6 +- app/templates/layout.html | 222 ++++++++++++------ instance/app.db | Bin 36864 -> 36864 bytes 7 files changed, 189 insertions(+), 84 deletions(-) diff --git a/app/routes/__pycache__/api.cpython-313.pyc b/app/routes/__pycache__/api.cpython-313.pyc index 9091e04912cf730b074884b428d15efb697d2056..98194e4443c4b3ca1e8ffd1e1c1dd70b08aa6f22 100644 GIT binary patch delta 2539 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 diff --git a/app/routes/__pycache__/dashboard.cpython-313.pyc b/app/routes/__pycache__/dashboard.cpython-313.pyc index 8db7c902d27791a413caa5178b68ee6de80abad3..46db6499f054faa0bfbbb1704b4120991838ddde 100644 GIT binary patch delta 572 zcmaD{GpnBWGcPX}0}wo2_%eO&MqW!DCKr}TS|yVmSU4wli)k=sZhoiZ!o(;y*-(ED zqtN7Y`YIxd4AD9uEg-X>nd`S^YytL1)>eXl0YJq-INi+=3_8s z3T8KDg76d=N5EGPgKgE0R+SK;pMJit=-Ek`j}%Z!s5_6lroy z?lRQTy2Y4U%mK7l0Sb!rfSg+#K=a~LQ!-16>VRBXpfihiPrhTgTU||adG5m84V4$w z9PR+wX$#XfFmGqu$aYc9>@zEqgvE0U+nubt*(dKaacK>I*;r{ z9@#5A@^^RyF9?}z$h^Yia7S2rj{5}_ivz;P#SV&Hl<~MM?0JF5^9vUPkMv{{W5wtn zUpN^ABtJ7SA)6zAkw^Xtk0Qt%5rZwl8v-|rZQ!^dWVyrQI*-dm9+%%ASV8K46-xr0 ze$>>F&0Un?xG0y0Jo9mRGY=`|6H=@|_U0(#PmHV$KqbMO15LNEa5n*&Ma>|hWwL;k zG;2GMnXuWw>N6uZC=7}kKt%gwJsT;;iJLubmNSYNF|vJTW?&Kk5kSuZxgRnnv)IK0 E0QwrE_5c6? delta 387 zcmbPL|G0+tGcPX}0}%Ajf0@p`k=Ig(X$A8nt&+(OES!_O#WWZ*HowzxVVXQm(tUEZ zeh8z$WR@s678K-UCMT9;=I1HsDrkyLzGPU)q{%)x-bhEi zm>p=g0t6K40ok`W5(^6AQ-S)5s(@TsMh1rBGRDb$W>S+c7%foO&|c5Gl6QyXMGdDr zKsMV-whhYL)i$bK)Uf!>$|Pa++{%8Z>TdPP(~TWXpKx&Xb9HiE=a9U}A$f&E`UwZ` z1wMlfnpZe%?(mDxVZWeYvLkqZ*v_zv5-ykdT`zFBKH-*{ENY@Sd7UiV=1C?W8Ch$9 zP6*iCVYY=uyAH@Kss|AbK%$r#NC2G;b#rlQNl9j2dT~)RP&jsTy7gy9HIVa*Kn8#X yS27eCfY=Z}+T`Y^l;)(`74>dzuwBk5qR+_onVEq}07Te+U;%PJBu%!qj|Tui!E{mp diff --git a/app/routes/api.py b/app/routes/api.py index 15e8c8a..1e819a1 100644 --- a/app/routes/api.py +++ b/app/routes/api.py @@ -10,13 +10,31 @@ bp = Blueprint('api', __name__, url_prefix='/api') @bp.route('/subnets', methods=['GET']) def get_subnets(): - """Get all subnets""" + """Get all subnets grouped by site""" subnets = Subnet.query.all() - return jsonify([{ - 'id': subnet.id, - 'cidr': subnet.cidr, - 'location': subnet.location - } for subnet in subnets]) + + # Group subnets by location (site) + sites = {} + for subnet in subnets: + location = subnet.location + if location not in sites: + sites[location] = [] + + sites[location].append({ + 'id': subnet.id, + 'cidr': subnet.cidr, + 'location': location + }) + + # Convert to list of site objects + result = [ + { + 'name': site_name, + 'subnets': subnets + } for site_name, subnets in sites.items() + ] + + return jsonify(result) @bp.route('/subnets/', methods=['GET']) @login_required diff --git a/app/routes/dashboard.py b/app/routes/dashboard.py index 5caf064..9f3abf6 100644 --- a/app/routes/dashboard.py +++ b/app/routes/dashboard.py @@ -305,8 +305,8 @@ def app_edit(app_id): # Check if name changed and already exists on the same server existing_app = App.query.filter(App.name == name, - App.server_id == server_id, - App.id != app.id).first() + App.server_id == server_id, + App.id != app.id).first() if existing_app: flash('Application with this name already exists on the selected server', 'danger') return render_template( @@ -321,10 +321,13 @@ def app_edit(app_id): app.server_id = server_id app.documentation = documentation - db.session.commit() - - flash('Application updated successfully', 'success') - return redirect(url_for('dashboard.app_view', app_id=app.id)) + try: + db.session.commit() + flash('Application updated successfully', 'success') + return redirect(url_for('dashboard.app_view', app_id=app.id)) + except Exception as e: + db.session.rollback() + flash(f'Error updating application: {str(e)}', 'danger') return render_template( 'dashboard/app_form.html', diff --git a/app/templates/dashboard/app_form.html b/app/templates/dashboard/app_form.html index e8ddabe..e9e191d 100644 --- a/app/templates/dashboard/app_form.html +++ b/app/templates/dashboard/app_form.html @@ -54,9 +54,11 @@ {% if app %} Cancel - {% else %} - Cancel + {% else %} + Cancel {% endif %} diff --git a/app/templates/layout.html b/app/templates/layout.html index 3705117..46b75d1 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -101,6 +101,45 @@ font-style: italic; padding: 5px 15px; } + + .site-item { + display: flex; + align-items: center; + padding: 0.5rem 0.75rem; + color: var(--sidebar-color); + cursor: pointer; + background-color: rgba(0, 0, 0, 0.02); + border-radius: 4px; + margin: 2px 0; + } + + .site-item:hover { + background-color: rgba(0, 0, 0, 0.04); + } + + .site-toggle-icon { + transition: transform 0.2s; + cursor: pointer; + } + + .site-item-container { + margin-bottom: 0.25rem; + } + + .subnet-item { + margin-left: 1rem; + } + + .subnet-item a { + padding-left: 1rem; + display: block; + color: var(--sidebar-color); + } + + .subnet-item a:hover { + background-color: rgba(0, 0, 0, 0.03); + border-radius: 4px; + } @@ -128,7 +167,7 @@ -