This commit is contained in:
Takeus committed 2025-02-18 15:29:27 +01:00
1 parent eefc23fad8
commit 06b7efd58b
12 files changed
+475 -65

No files matched your search

+22 -4
View File
@@ -1,6 +1,6 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, IntegerField, SelectField
from wtforms.validators import DataRequired, Length, IPAddress, NumberRange
from wtforms import StringField, PasswordField, IntegerField, SelectField, TextAreaField
from wtforms.validators import DataRequired, Length, IPAddress
class LoginForm(FlaskForm):
username = StringField(validators=[DataRequired(),Length(max=128)])
@@ -15,10 +15,12 @@ class NewUserForm(FlaskForm):
username = StringField(validators=[DataRequired(),Length(max=128)])
password = PasswordField(validators=[DataRequired(),Length(max=128)])
is_admin = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
is_readonly = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
class ChangePasswordForm(FlaskForm):
password = PasswordField(validators=[DataRequired(),Length(max=128)])
is_admin = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
is_readonly = SelectField(choices=[(0,'No'),(1,'Yes')],validators=[DataRequired()])
class ChangeAllocationForm(FlaskForm):
hostname = StringField(validators=[Length(max=128)])
@@ -26,6 +28,22 @@ class ChangeAllocationForm(FlaskForm):
is_special = SelectField(choices=[(0,'None'),(1,'DHCP'),(2,'Gateway')],validators=[DataRequired()],label='Special USE ?')
class NewInventoryItem(FlaskForm):
item_name = StringField(validators=[DataRequired(),Length(max=128)])
item_desc = PasswordField(validators=[Length(max=128)])
item_name = StringField(validators=[DataRequired(),Length(max=64)])
item_desc = StringField(validators=[Length(max=64)])
item_type = SelectField(choices=[(1,'Computer'),(2,'Server'),(3,'Virtual Machine'), (4,'Network Device'), (0,'Other')],validators=[DataRequired()])
class ChangeInventoryItem(FlaskForm):
item_name = StringField(validators=[DataRequired(),Length(max=64)])
item_desc = StringField(validators=[Length(max=64)])
item_type = SelectField(choices=[(1,'Computer'),(2,'Server'),(3,'Virtual Machine'), (4,'Network Device'), (0,'Other')],validators=[DataRequired()])
# Hardware Information
item_model = StringField(validators=[Length(max=64)])
item_manufacturer = StringField(validators=[Length(max=64)])
item_serial_number = StringField(validators=[Length(max=64)])
# Network Information
item_os = StringField(validators=[Length(max=64)])
item_location = StringField(validators=[Length(max=64)])
item_owner = StringField(validators=[Length(max=64)])
item_contact = StringField(validators=[Length(max=64)])
# Allocation(s)
item_ip_allocations = StringField()
+3
View File
@@ -6,6 +6,7 @@ class User(UserMixin, db.Model):
username = db.Column(db.String(16))
password = db.Column(db.String(32),unique=True)
is_admin = db.Column(db.Boolean(),default=False)
is_reado = db.Column(db.Boolean(),default=False)
dat_last = db.Column(db.DateTime())
class Network(db.Model):
@@ -41,3 +42,5 @@ class Inventory(db.Model):
host_location = db.Column(db.String(64))
host_owner = db.Column(db.String(64))
host_contact = db.Column(db.String(64))
## Allocation(s)
host_allocations = db.Column(db.Text())
+7 -1
View File
@@ -26,10 +26,13 @@ def home():
return redirect(url_for('admin.home'))
is_admin = False
is_readonly = False
if int(form.is_admin.data) == 1:
is_admin = True
if int(form.is_readonly.data) == 1:
is_readonly = True
db.session.add(User(username=form.username.data, password=generate_password_hash(form.password.data), is_admin=is_admin))
db.session.add(User(username=form.username.data, password=generate_password_hash(form.password.data), is_admin=is_admin, is_reado=is_readonly))
db.session.commit()
flash("User Created", 'success')
return redirect(url_for('admin.home'))
@@ -67,8 +70,11 @@ def user_modal_edit(user_id):
if form.validate_on_submit() and request.method == 'POST':
user.password = generate_password_hash(form.password.data)
user.is_admin = False
user.is_reado = False
if int(form.is_admin.data) == 1:
user.is_admin = True
if int(form.is_readonly.data) == 1:
user.is_reado = True
db.session.commit()
flash("Informations Changed", 'success')
return redirect(url_for('admin.home'))
+197 -10
View File
@@ -1,19 +1,18 @@
from datetime import datetime
from flask import Blueprint, request, render_template, flash, redirect, url_for, session
from flask import Blueprint, request, render_template, flash, redirect, url_for, abort
from flask_login import login_required, current_user
from ipaddress import IPv4Network, IPv4Address
from app._config import app_version
from app.extensions import *
from app.models import *
from app.forms import NewInventoryItem
from app.forms import NewInventoryItem, ChangeInventoryItem
inventory = Blueprint('inventory', __name__)
@inventory.route('/add', methods=['GET','POST'])
@login_required
def add_item():
if current_user.is_reado:
return abort(403)
form = NewInventoryItem()
if form.validate_on_submit() and request.method == 'POST':
add_net = Inventory(host_type=int(form.item_type.data),host_name=str(form.item_name.data),host_desc=str(form.item_desc.data))
@@ -21,22 +20,210 @@ def add_item():
db.session.commit()
flash("Item ADDED", 'success')
return render_template('panel/inventory_add.html', title='ADD ITEM', form=form)
return render_template('panel/inventory_add.html', title='ADD ITEM', form=form, navcolor='success')
@inventory.route('/list/<int:item_type>', methods=['GET','POST'])
@login_required
def list_items(item_type):
db_items = Inventory.query.filter_by(host_type=item_type).all()
return render_template('panel/inventory_view.html', Title='View Items', item_list=db_items)
if item_type == 5:
db_items = Inventory.query.all()
else:
db_items = Inventory.query.filter_by(host_type=item_type).all()
if item_type == 0:
title = 'Others'
elif item_type == 1:
title = 'Computers'
elif item_type == 2:
title = 'Servers'
elif item_type == 3:
title = 'VM\'s'
elif item_type == 4:
title = 'Network'
else:
title = 'All'
return render_template('panel/inventory_view.html', title=title, item_list=db_items, current_page=item_type, navcolor='success')
@inventory.route('/action/<int:item_id>/<int:action>', methods=['GET','POST'])
@login_required
def action_item(item_id,action):
if current_user.is_reado:
return abort(403)
if action == 1:
db_item = Inventory.query.filter_by(id=item_id).first()
db_allocs = Allocation.query.filter_by(device_id=db_item.id).all()
# Delete Link Allocation(s)
if db_allocs != []:
for alloc in db_allocs:
alloc.device_id = None
db.session.delete(db_item)
db.session.commit()
return redirect(url_for('base.dashboard'))
return redirect(url_for('inventory.list_items',item_type=request.args.get('page', type=int)))
## MODAL ROUTES
@inventory.get('/<int:item_id>/view_modal')
@login_required
def item_view_modal(item_id):
db_item = Inventory.query.filter_by(id=item_id).first()
modal = {
'title': f'Informations of <b>{db_item.host_name}</b> ({db_item.id})',
'modal_type': 'infos',
'color': 'info',
'action': 'delete',
'action_text': 'Delete',
'action_url': url_for('inventory.action_item',item_id=item_id,action=1)
}
if db_item.host_type == 0:
host_type = 'Others'
elif db_item.host_type == 1:
host_type = 'Computers'
elif db_item.host_type == 2:
host_type = 'Servers'
elif db_item.host_type == 3:
host_type = 'VM\'s'
elif db_item.host_type == 4:
host_type = 'Network'
else:
host_type = 'Error'
informations = [
('Type',host_type,'col-6'),
('Name',db_item.host_name,'col-6'),
('Description',db_item.host_desc,'col-6'),
('Model',db_item.host_model,'col-6'),
('Manufacturer',db_item.host_manufacturer,'col-6'),
('SerialNumber',db_item.host_serialnumber,'col-6'),
('OS',db_item.host_os,'col-6'),
('Location',db_item.host_location,'col-6'),
('Owner',db_item.host_owner,'col-6'),
('Contact',db_item.host_contact,'col-6'),
('Allocations',db_item.host_allocations,'col-12'),
]
return render_template('panel/_modal.html', modal=modal, item_id=item_id, informations=informations, old_page=request.args.get('page', type=int), pagination_active=True)
@inventory.get('/<int:item_id>/del_modal')
@login_required
def item_del_modal(item_id):
db_item = Inventory.query.filter_by(id=item_id).first()
modal = {
'title': 'Delete Item',
'body': f'Are you sure you want to delete <b>{db_item.host_name}</b> ?',
'color': 'danger',
'action': 'delete',
'action_text': 'Delete',
'action_url': url_for('inventory.action_item',item_id=item_id,action=1)
}
return render_template('panel/_modal.html', modal=modal, item_id=item_id, old_page=request.args.get('page', type=int), pagination_active=True)
@inventory.route('/<int:item_id>/edit_modal', methods=['GET','POST'])
@login_required
def item_edit_modal(item_id):
if current_user.is_reado:
return abort(403)
db_item = Inventory.query.filter_by(id=item_id).first()
form = ChangeInventoryItem()
if form.validate_on_submit() and request.method == 'POST':
db_item.host_type = form.item_type.data
db_item.host_name = form.item_name.data
# Description
if form.item_desc.data != '' and form.item_desc.data != 'None':
db_item.host_desc = form.item_desc.data
else:
db_item.host_desc = None
# Model
if form.item_model.data != '' and form.item_model.data != 'None':
db_item.host_model = form.item_model.data
else:
db_item.host_model = None
# Serial Number
if form.item_serial_number.data != '' and form.item_serial_number.data != 'None':
db_item.host_serialnumber = form.item_serial_number.data
else:
db_item.host_serialnumber = None
# OS
if form.item_os.data != '' and form.item_os.data != 'None':
db_item.host_os = form.item_os.data
else:
db_item.host_os = None
# Location
if form.item_location.data != '' and form.item_location.data != 'None':
db_item.host_location = form.item_location.data
else:
db_item.host_location = None
# Owner
if form.item_owner.data != '' and form.item_owner.data != 'None':
db_item.host_owner = form.item_owner.data
else:
db_item.host_owner = None
# Contact
if form.item_contact.data != '' and form.item_contact.data != 'None':
db_item.host_contact = form.item_contact.data
else:
db_item.host_contact = None
# Allocations
db_existing_allocs = Allocation.query.filter_by(device_id=db_item.id).all()
# Unlink old Allocation(s)
if db_existing_allocs != []:
for alloc in db_existing_allocs:
alloc.device_id = None
if form.item_ip_allocations.data != '' and form.item_ip_allocations.data != 'None':
allocs = form.item_ip_allocations.data.split(',')
put_allocs_db = ""
for alloc in allocs:
db_alloc = Allocation.query.filter_by(ipv4=alloc).first()
if db_alloc != None:
put_allocs_db += db_alloc.ipv4+','
db_alloc.device_id = db_item.id
elif allocs[-1] == '':
pass
else:
flash('Unknown IPv4', 'warning')
return redirect(url_for('inventory.list_items',item_type=request.args.get('page', type=int)))
db_item.host_allocations = put_allocs_db
else:
db_item.host_allocations = None
db.session.commit()
flash("Item Updated", 'success')
return redirect(url_for('inventory.list_items',item_type=request.args.get('page', type=int)))
# Setting default values
form.item_name.default = db_item.host_name
form.item_desc.default = db_item.host_desc
form.item_type.default = db_item.host_type
form.item_model.default =db_item.host_model
form.item_manufacturer.default = db_item.host_manufacturer
form.item_serial_number.default = db_item.host_serialnumber
form.item_os.default = db_item.host_os
form.item_location.default = db_item.host_location
form.item_owner.default = db_item.host_owner
form.item_contact.default = db_item.host_contact
form.item_ip_allocations.default = db_item.host_allocations
form.process()
modal = {
'title': 'Update Item',
'body': f'Change informations for <b>{db_item.host_name}</b>.',
'color': 'primary',
'modal_type': 'form',
'action_text': 'Save',
'form_url': url_for('inventory.item_edit_modal',item_id=item_id),
'inventory':True,
}
return render_template('panel/_modal.html', modal=modal, form=form, old_page=request.args.get('page', type=int), pagination_active=True)
+39 -17
View File
@@ -1,5 +1,4 @@
from datetime import datetime
from flask import Blueprint, request, render_template, flash, redirect, url_for, session
from flask import Blueprint, request, render_template, flash, redirect, url_for, session, abort
from flask_login import login_required, current_user
from ipaddress import IPv4Network, IPv4Address
@@ -16,25 +15,26 @@ network = Blueprint('network', __name__)
def networks():
networks = Network.query.all()
form = NewPrefixForm()
if request.method == 'POST' and form.validate_on_submit():
try:
network = IPv4Network(f"{str(form.subnet.data)}/{str(form.prefix.data)}", False)
if current_user.is_reado == False:
if request.method == 'POST' and form.validate_on_submit():
try:
network = IPv4Network(f"{str(form.subnet.data)}/{str(form.prefix.data)}", False)
add_net = Network(network_address=str(network.network_address),prefix=network.prefixlen,hosts=network.num_addresses-2,description=str(form.description.data))
db.session.add(add_net)
db.session.commit()
add_net = Network(network_address=str(network.network_address),prefix=network.prefixlen,hosts=network.num_addresses-2,description=str(form.description.data))
db.session.add(add_net)
db.session.commit()
for ip in network.hosts():
db.session.add(Allocation(ipv4=str(ip), net_id=add_net.id))
for ip in network.hosts():
db.session.add(Allocation(ipv4=str(ip), net_id=add_net.id))
db.session.commit()
return redirect(url_for('network.networks'))
db.session.commit()
return redirect(url_for('network.networks'))
except:
flash("Invalid Subnet or Prefix", 'danger')
return redirect(url_for('network.networks'))
elif form.errors:
flash(form.errors, 'danger')
except:
flash("Invalid Subnet or Prefix", 'danger')
return redirect(url_for('network.networks'))
elif form.errors:
flash(form.errors, 'danger')
return render_template('panel/networks.html', title="Prefixes", is_networks=True, app_version=app_version, prefixes=networks, form=form, Allocation=Allocation, navcolor='dark')
@@ -95,6 +95,9 @@ def allocation_del_modal(net_id,ipv4):
@network.route('/<int:net_id>/allocations/<string:ipv4>/edit_modal', methods=['GET','POST'])
@login_required
def allocation_edit_modal(net_id, ipv4):
if current_user.is_reado:
return abort(403)
db_alloc = Allocation.query.filter_by(ipv4=ipv4).first()
form = ChangeAllocationForm()
@@ -130,15 +133,28 @@ def allocation_edit_modal(net_id, ipv4):
'action_text': 'Save',
'form_url': url_for('network.allocation_edit_modal',net_id=db_alloc.net_id,ipv4=db_alloc.ipv4),
}
old_page = request.args.get('page', type=int)
if old_page == 0:
old_page = 1
form.hostname.default = db_alloc.hostname
form.description.default = db_alloc.description
if db_alloc.is_dhcp:
form.is_special.default = 1
elif db_alloc.is_gateway:
form.is_special.default = 2
form.process()
return render_template('panel/_modal.html', modal=modal, form=form, old_page=old_page, pagination_active=True)
## MODIFICATION ROUTES
@network.get('/<int:net_id>/allocations/<string:ipv4>/unallocate')
@login_required
def allocation_delete(net_id,ipv4):
if current_user.is_reado:
return abort(403)
db_alloc = Allocation.query.filter_by(net_id=net_id,ipv4=ipv4).first()
db_alloc.is_used = False
db_alloc.hostname = None
@@ -152,6 +168,9 @@ def allocation_delete(net_id,ipv4):
@network.get('/<int:net_id>/allocations/<string:ipv4>/decom/<int:action>')
@login_required
def allocation_decom(net_id,ipv4,action):
if current_user.is_reado:
return abort(403)
db_alloc = Allocation.query.filter_by(net_id=net_id,ipv4=ipv4).first()
if action == 1:
db_alloc.is_decom = True
@@ -163,6 +182,9 @@ def allocation_decom(net_id,ipv4,action):
@network.get('/<int:net_id>/delete')
@login_required
def network_delete(net_id):
if current_user.is_reado:
return abort(403)
db_network = Network.query.filter_by(id=net_id).first()
db_alloc = Allocation.query.filter_by(net_id=db_network.id).all()
+6
View File
@@ -22,6 +22,7 @@
<th>ID</th>
<th>Username</th>
<th>Admin User</th>
<th>RO</th>
<th>Last Connection</th>
<th>Actions</th>
</tr>
@@ -32,6 +33,7 @@
<td>{{user.id}}</td>
<td>{{user.username}}</td>
<td>{{user.is_admin}}</td>
<td>{{user.is_reado}}</td>
<td>{% if user.dat_last != None %}{{user.dat_last.strftime('%Y-%m-%d %H:%M:%S')}}{%else%}N/A{%endif%}</td>
<td>
<button
@@ -80,6 +82,10 @@
<label class="form-label">Is Admin?</label>
{{ form.is_admin(class="form-control") }}
</div>
<div class="mb-3">
<label class="form-label">Is Readonly?</label>
{{ form.is_readonly(class="form-control") }}
</div>
<button type="submit" class="btn btn-secondary w-100">Submit</button>
</form>
</div>
+50 -3
View File
@@ -1,5 +1,5 @@
{% if modal.modal_type == 'form' %}
<div class="modal-dialog modal-dialog-centered">
<div class="modal-dialog">
<form method="post" action="{{modal.form_url}}{% if pagination_active %}?page={{old_page}}{%endif%}">
{{ form.csrf_token }}
<div class="modal-content">
@@ -8,8 +8,29 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% if modal.inventory %}
{{ modal.body|safe }}<hr>
<div class="row">
{% for entry in form %}
{% if entry.id != 'csrf_token' %}
{% if entry.id == 'item_ip_allocations' %}
<div class="col-12">
{{ entry.label(class="form-label") }}<br>
{{ entry(class="form-control",placeholder='192.168.1.1,192.168.1.2 (separate with ,)') }}
</div>
{% else %}
<div class="col-6">
<div class="mb-2">
{{ entry.label(class="form-label") }}<br>
{{ entry(class="form-control") }}
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}
</div>
{% else %}
<p>
{{ modal.body|safe }}<hr>
{% for entry in form %}
{% if entry.id != 'csrf_token' %}
<div class="mb-3">
@@ -19,6 +40,7 @@
{% endif %}
{% endfor %}
</p>
{% endif %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
@@ -27,11 +49,36 @@
</div>
</form>
</div>
{% elif modal.modal_type == 'infos' %}
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title text-{{modal.color}}">{{ modal.title|safe }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
{% for info in informations %}
<div class="{{info[2]}}">
<div class="mb-3">
<label for="{{info[0]}}">{{info[0]}}</label>
<input class="form-control" type="text" id="{{info[0]}}" value="{{info[1]}}" readonly>
<!--{{ key }} : {{ value }}-->
</div>
</div>
{% endfor %}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
{% else %}
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title text-{{modal.color}}">{{ modal.title }}</h5>
<h5 class="modal-title text-{{modal.color}}">{{ modal.title|safe }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
+2 -1
View File
@@ -20,7 +20,8 @@
<li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=3) }}"><i class="bi bi-server"></i> Virtual Machines</a></li>
<li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=4) }}"><i class="bi bi-ethernet"></i> Networks Devices</a></li>
<li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=0) }}"><i class="bi bi-collection"></i> Others</a></li>
<li><a class="dropdown-item" href="{{ url_for('inventory.add_item') }}"><i class="bi bi-plus-circle"></i> ADD NEW</a></li>
<li><a class="dropdown-item" href="{{ url_for('inventory.list_items',item_type=5) }}"><i class="bi bi-collection"></i> All</a></li>
{% if current_user.is_reado == False %}<li><a class="dropdown-item" href="{{ url_for('inventory.add_item') }}"><i class="bi bi-plus-circle"></i> ADD NEW</a></li>{% endif %}
</ul>
</li>
{% if current_user.is_admin %}
+12 -1
View File
@@ -5,7 +5,16 @@
<td>{{allocation.description}}</td>
<td>
{% if Inventory.query.filter_by(id=allocation.device_id).first() %}
<a href="{{Inventory.query.filter_by(id=allocation.device_id).first().id}}" style="text-decoration:none;">link</a>
<button
hx-get="{{ url_for('inventory.item_view_modal',item_id=allocation.device_id) }}"
hx-trigger="click"
hx-target="#modal-view"
data-bs-toggle="modal"
data-bs-target="#modal-view"
class="btn btn-sm btn-outline-primary"
style="padding-top:1px;padding-bottom:1px"
> Details
</button>
{% else %}
N/A
{% endif %}
@@ -13,6 +22,7 @@
<td>{{allocation.is_dhcp}}</td>
<td>{{allocation.is_gateway}}</td>
<td>{{allocation.is_decom}}</td>
{% if current_user.is_reado == False %}
<td>
{% if allocation.is_used %}
<button
@@ -53,5 +63,6 @@
</button>
{% endif %}
</td>
{% endif %}
</tr>
{% endfor %}
+11 -2
View File
@@ -18,7 +18,7 @@
</div>
<!-- IPV4 TABLE -->
<div class="col-12">
<table class="table table-striped table-hover table-sm">
<table class="table table-hover table-sm">
<thead>
<tr>
<th scope="col">IPv4</th>
@@ -28,7 +28,7 @@
<th scope="col">DHCP</th>
<th scope="col">GATEWAY</th>
<th scope="col">DECOM</th>
<th scope="col">Actions</th>
{% if current_user.is_reado == False %}<th scope="col">Actions</th>{% endif %}
</tr>
</thead>
<tbody id="search-results">
@@ -73,4 +73,13 @@
<div class="modal-content"></div>
</div>
</div>
<div id="modal-view"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
{% endblock %}
+121 -25
View File
@@ -2,36 +2,132 @@
{% block content %}
{% include 'panel/_nav.html' %}
{% include 'panel/_flash.html' %}
<div class="container" style="margin-top:5vh;">
<div class="container" style="margin-top:4vh;">
<div class="row">
<div class="col-2"></div>
<div class="col-8">
<table class="table table-striped table-hover table-sm">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Hostname</th>
<th scope="col">Description</th>
<th scope="col">Type</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for item in item_list %}
<tr>
<td>{{item.id}}</td>
<td>{{item.host_name}}</td>
<td>{{item.host_desc}}</td>
<td>{{item.host_type}}</td>
<td>
<a href="{{ url_for('inventory.action_item',action=1,item_id=item.id) }}?page={{active_page}}" class="btn btn-sm btn-outline-danger" style="padding-top:1px;padding-bottom:1px">Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<h1>{{title}}</h1>
<div class="card shadow-sm">
<div class="card-body">
<table class="table table-hover table-sm">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Hostname</th>
<th scope="col">Description</th>
<th scope="col">Type</th>
<th scope="col">Owner</th>
<th scope="col">Allocation(s)</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{% for item in item_list %}
<tr>
<th scope="row">{{item.id}}</th>
<td>{{item.host_name}}</td>
<td>{{item.host_desc}}</td>
{% if item.host_type == 1 %}
<td><i class="bi bi-pc-display"></i> (PC)</td>
{% elif item.host_type == 2 %}
<td><i class="bi bi-server"></i> (SRV)</td>
{% elif item.host_type == 3 %}
<td><i class="bi bi-server"></i> (VM)</td>
{% elif item.host_type == 4 %}
<td><i class="bi bi-ethernet"></i> (NT)</td>
{% elif item.host_type == 0 %}
<td>Other</td>
{% endif %}
<!--
{% if 'WINDOWS' in item.host_os|upper or 'WS' in item.host_os|upper %}
<td><i class="bi bi-windows"></i> {{item.host_os}}</td>
{% elif 'UBUNTU' in item.host_os|upper %}
<td><i class="bi bi-ubuntu"></i> {{item.host_os}}</td>
{% elif 'MACOS' in item.host_os|upper or 'APPLE' in item.host_os|upper %}
<td><i class="bi bi-apple"></i> {{item.host_os}}</td>
{% else %}
<td>{{item.host_os}}</td>
{% endif %}
-->
<td>{{item.host_owner}}</td>
<td>
{% if item.host_allocations != None %}
{% set alloc_count = item.host_allocations.split(',')|length-1 %}
{{alloc_count}}
{% else %}
{{item.host_allocations}}
{% endif %}
</td>
<td>
<button
hx-get="{{ url_for('inventory.item_view_modal',item_id=item.id) }}?page={{current_page}}"
hx-trigger="click"
hx-target="#modal-view"
data-bs-toggle="modal"
data-bs-target="#modal-view"
class="btn btn-sm btn-outline-info"
style="padding-top:1px;padding-bottom:1px"
> Details
</button>
{% if current_user.is_reado == False %}
<button
hx-get="{{ url_for('inventory.item_edit_modal',item_id=item.id) }}?page={{current_page}}"
hx-trigger="click"
hx-target="#modal-edit"
data-bs-toggle="modal"
data-bs-target="#modal-edit"
class="btn btn-sm btn-outline-primary"
style="padding-top:1px;padding-bottom:1px"
> Edit
</button>
<button
hx-get="{{ url_for('inventory.item_del_modal',item_id=item.id) }}?page={{current_page}}"
hx-trigger="click"
hx-target="#modal-del"
data-bs-toggle="modal"
data-bs-target="#modal-del"
class="btn btn-sm btn-outline-danger"
style="padding-top:1px;padding-bottom:1px"
> Delete
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div class="col-2"></div>
</div>
</div>
<!-- MODAL -->
<div id="modal-del"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
<div id="modal-edit"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
<div id="modal-view"
class="modal modal-blur fade"
style="display: none"
aria-hidden="false"
tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content"></div>
</div>
</div>
{% endblock %}
+5 -1
View File
@@ -5,7 +5,7 @@
<div class="container" style="margin-top:5vh;">
<div class="row">
<!-- PREFIXES TABLE -->
<div class="col-9">
<div class="col-{% if current_user.is_reado == False %}9{% else %}12{% endif %}">
<table class="table table-striped table-hover">
<thead>
<tr>
@@ -27,6 +27,7 @@
<td><b>{{network.description}}</b></td>
<td>
<a href="{{ url_for('network.allocations',net_id=network.id) }}?page=1" class="btn btn-sm btn-outline-info" style="padding-top:1px;padding-bottom:1px">Allocations</a>
{% if current_user.is_reado == False %}
<button
hx-get="{{ url_for('network.network_del_modal',net_id=network.id) }}"
hx-trigger="click"
@@ -37,6 +38,7 @@
style="padding-top:1px;padding-bottom:1px"
> Delete
</button>
{% endif %}
</td>
</tr>
{% endfor %}
@@ -44,6 +46,7 @@
</table>
</div>
<!-- PREFIX FORM -->
{% if current_user.is_reado == False %}
<div class="col-3">
<div class="card p-4 shadow rounded-3">
<h2 class="text-center mb-4">Add Network</h2>
@@ -65,6 +68,7 @@
</form>
</div>
</div>
{% endif %}
</div>
</div>
<!-- MODAL -->