diff --git a/app/routes/__pycache__/api.cpython-313.pyc b/app/routes/__pycache__/api.cpython-313.pyc index 9091e04..98194e4 100644 Binary files a/app/routes/__pycache__/api.cpython-313.pyc and b/app/routes/__pycache__/api.cpython-313.pyc differ diff --git a/app/routes/__pycache__/dashboard.cpython-313.pyc b/app/routes/__pycache__/dashboard.cpython-313.pyc index 8db7c90..46db649 100644 Binary files a/app/routes/__pycache__/dashboard.cpython-313.pyc and b/app/routes/__pycache__/dashboard.cpython-313.pyc differ 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 @@ -