Re-formatted base view template to be more in-line with PEP8 standards.

Working on dashboard clean-up and redesign.

Added custom Jinja date/time formatting function to utils.py.
This commit is contained in:
Matt Scott 2023-02-19 08:52:00 -05:00
parent bad36b5e75
commit 58aabacd91
4 changed files with 790 additions and 768 deletions

View File

@ -74,9 +74,9 @@ def create_app(config=None):
app.jinja_env.filters['display_record_name'] = utils.display_record_name app.jinja_env.filters['display_record_name'] = utils.display_record_name
app.jinja_env.filters['display_master_name'] = utils.display_master_name app.jinja_env.filters['display_master_name'] = utils.display_master_name
app.jinja_env.filters['display_second_to_time'] = utils.display_time app.jinja_env.filters['display_second_to_time'] = utils.display_time
app.jinja_env.filters[ app.jinja_env.filters['display_setting_state'] = utils.display_setting_state
'display_setting_state'] = utils.display_setting_state
app.jinja_env.filters['pretty_domain_name'] = utils.pretty_domain_name app.jinja_env.filters['pretty_domain_name'] = utils.pretty_domain_name
app.jinja_env.filters['format_datetime_local'] = utils.format_datetime
# Register context proccessors # Register context proccessors
from .models.setting import Setting from .models.setting import Setting

View File

@ -225,6 +225,7 @@ class customBoxes:
} }
order = ["reverse", "ip6arpa", "inaddrarpa"] order = ["reverse", "ip6arpa", "inaddrarpa"]
def pretty_domain_name(domain_name): def pretty_domain_name(domain_name):
# Add a debugging statement to print out the domain name # Add a debugging statement to print out the domain name
print("Received domain name:", domain_name) print("Received domain name:", domain_name)
@ -264,3 +265,10 @@ def to_idna(value, action):
else: else:
raise Exception('No valid action received') raise Exception('No valid action received')
return '.'.join(result) return '.'.join(result)
def format_datetime(value, format_str="%Y-%m-%d %I:%M %p"):
"""Format a date time to (Default): YYYY-MM-DD HH:MM P"""
if value is None:
return ""
return value.strftime(format_str)

View File

@ -5,22 +5,15 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="icon" href="{{ url_for('static', filename='img/favicon.png') }}"> <link rel="icon" href="{{ url_for('static', filename='img/favicon.png') }}">
{% block title %} {% block title %}<title>{{ SITE_NAME }}</title>{% endblock %}
<title>
{{ SITE_NAME }}
</title>
{% endblock %}
<link rel="stylesheet" href="{{ url_for('static', filename='assets/css/style.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='assets/css/style.css') }}">
<!-- Get Google Fonts we like -->
<link rel="stylesheet" href="{{ url_for('static', filename='assets/css/source_sans_pro.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='assets/css/source_sans_pro.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='assets/css/roboto_mono.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='assets/css/roboto_mono.css') }}">
<!-- Tell the browser to be responsive to screen width --> <!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Tell Safari to not recognise telephone numbers --> <!-- Tell Safari to not recognise telephone numbers -->
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
{% assets "css_main" -%} {% assets "css_main" -%}<link rel="stylesheet" href="{{ ASSET_URL }}">{%- endassets %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{%- endassets %}
{% if SETTING.get('custom_css') %} {% if SETTING.get('custom_css') %}
<link rel="stylesheet" href="/static/custom/{{ SETTING.get('custom_css') }}"> <link rel="stylesheet" href="/static/custom/{{ SETTING.get('custom_css') }}">
{% endif %} {% endif %}
@ -55,7 +48,8 @@
<aside class="main-sidebar sidebar-dark-primary"> <aside class="main-sidebar sidebar-dark-primary">
<!-- Logo --> <!-- Logo -->
<a href="{{ url_for('index.index') }}" class="brand-link"> <a href="{{ url_for('index.index') }}" class="brand-link">
<img src="{{ url_for('static', filename='img/favicon.png') }}" alt="PowerDNS-Admin FavIcon" class="brand-image img-circle elevation-3" style="opacity: .8"> <img src="{{ url_for('static', filename='img/favicon.png') }}" alt="PowerDNS-Admin FavIcon"
class="brand-image img-circle elevation-3" style="opacity: .8">
<span class="brand-text font-weight-light"> <span class="brand-text font-weight-light">
{% if SETTING.get('site_name') %} {% if SETTING.get('site_name') %}
<b>{{ SITE_NAME }}</b> <b>{{ SITE_NAME }}</b>
@ -72,7 +66,8 @@
<img src="{{ user_image_url }}" class="img-circle elevation-2" alt="User Image"> <img src="{{ user_image_url }}" class="img-circle elevation-2" alt="User Image">
</div> </div>
<div class="info"> <div class="info">
<a href="{{ url_for('user.profile') }}" class="d-block">{{ current_user.firstname }} {{ current_user.lastname }}</a> <a href="{{ url_for('user.profile') }}"
class="d-block">{{ current_user.firstname }} {{ current_user.lastname }}</a>
</div> </div>
</div> </div>
<!-- sidebar menu: : style can be found in sidebar.less --> <!-- sidebar menu: : style can be found in sidebar.less -->
@ -164,7 +159,8 @@
<i class="right fa-solid fa-angle-left"></i> <i class="right fa-solid fa-angle-left"></i>
</p> </p>
</a> </a>
<ul class="nav nav-treeview" {% if active_page == 'admin_settings' %}style="display: block;"{% endif %}> <ul class="nav nav-treeview"
{% if active_page == 'admin_settings' %}style="display: block;"{% endif %}>
<li class="nav-item"> <li class="nav-item">
<a href="{{ url_for('admin.setting_basic') }}" class="nav-link"> <a href="{{ url_for('admin.setting_basic') }}" class="nav-link">
<i class="nav-icon fa-solid fa-circle"></i> <i class="nav-icon fa-solid fa-circle"></i>
@ -236,15 +232,14 @@
</div> </div>
<!-- /.content-wrapper --> <!-- /.content-wrapper -->
<footer class="main-footer"> <footer class="main-footer">
<strong><a href="https://github.com/PowerDNS-Admin/PowerDNS-Admin">PowerDNS-Admin</a></strong> - A PowerDNS web interface with advanced features. <strong><a href="https://github.com/PowerDNS-Admin/PowerDNS-Admin">PowerDNS-Admin</a></strong> - A PowerDNS web
interface with advanced features.
</footer> </footer>
</div> </div>
<!-- ./wrapper --> <!-- ./wrapper -->
<script type="text/javascript"> <script type="text/javascript">
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }}; $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script> var PDNS_VERSION = '{{ pdns_version }}';
<script type="text/javascript">
var PDNS_VERSION = '{{ pdns_version }}'
</script> </script>
{% block scripts %} {% block scripts %}
{% assets "js_main" -%} {% assets "js_main" -%}
@ -332,7 +327,8 @@
}, },
onPriorCallback: function (jTimeout) { onPriorCallback: function (jTimeout) {
$("#modal_session_warning").modal('show');; $("#modal_session_warning").modal('show');
;
}, },
onSessionExtended: function (jTimeout) { onSessionExtended: function (jTimeout) {
@ -412,7 +408,8 @@
<p>To coninue your ssession, select <strong>Stay Signed In</strong></p> <p>To coninue your ssession, select <strong>Stay Signed In</strong></p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-success float-right button_stay_signed_in" data-dismiss="modal"> <button type="button" class="btn btn-success float-right button_stay_signed_in"
data-dismiss="modal">
Stay Signed In Stay Signed In
</button> </button>
<button type="button" class="btn btn-danger float-left button_sign_out" data-dismiss="modal"> <button type="button" class="btn btn-danger float-left button_sign_out" data-dismiss="modal">

View File

@ -1,12 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% set active_page = "dashboard" %} {% set active_page = "dashboard" %}
{% block title %}<title>Dashboard - {{ SITE_NAME }}</title>{% endblock %}
{% block title %}
<title>
Dashboard - {{ SITE_NAME }}
</title>
{% endblock %}
{% block dashboard_stat %} {% block dashboard_stat %}
<div class="content-header"> <div class="content-header">
@ -33,17 +27,17 @@
{% block content %} {% block content %}
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<div class="row"> <div class="row">
<div class="col-3"> <div class="col-lg-12">
<div class="card"> <div class="card card-outline card-secondary">
<div class="card-header"> <div class="card-header">
<h3 class="card-title">Statistics</h3> <h3 class="card-title">Statistics</h3>
</div> </div>
<!-- /.card-header -->
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6 col-sm-3">
<!-- small box -->
<div class="small-box bg-info"> <div class="small-box bg-info">
<div class="inner"> <div class="inner">
<h3>{{ domain_count }}</h3> <h3>{{ domain_count }}</h3>
@ -54,8 +48,22 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-6 col-sm-3">
<a href="{{ url_for('admin.history') }}">
<div class="small-box bg-green">
<div class="inner">
<h3>{{ history_number }}</h3>
<p>{% if history_number > 1 %}Histories{% else %}
History{% endif %}</p>
</div>
<div class="icon">
<i class="fa-solid fa-calendar"></i>
</div>
</div>
</a>
</div>
{% if current_user.role.name in ['Administrator', 'Operator'] %} {% if current_user.role.name in ['Administrator', 'Operator'] %}
<div class="col-6"> <div class="col-6 col-sm-3">
<a href="{{ url_for('admin.manage_user') }}"> <a href="{{ url_for('admin.manage_user') }}">
<div class="small-box bg-green"> <div class="small-box bg-green">
<div class="inner"> <div class="inner">
@ -68,28 +76,13 @@
</div> </div>
</a> </a>
</div> </div>
{% endif %} <div class="col-6 col-sm-3">
</div>
<div class="row">
<div class="col-6">
<a href="{{ url_for('admin.history') }}">
<div class="small-box bg-green">
<div class="inner">
<h3>{{ history_number }}</h3>
<p>{% if history_number > 1 %}Histories{% else %}History{% endif %}</p>
</div>
<div class="icon">
<i class="fa-solid fa-calendar"></i>
</div>
</div>
</a>
</div>
{% if current_user.role.name in ['Administrator', 'Operator'] %}
<div class="col-6">
<a href="{{ url_for('admin.pdns_stats') }}"> <a href="{{ url_for('admin.pdns_stats') }}">
<div class="small-box bg-green"> <div class="small-box bg-green">
<div class="inner"> <div class="inner">
<h3><span style="font-size: 18px">{{ uptime|display_second_to_time }}</span></h3> <h3><span
style="font-size: 18px">{{ uptime|display_second_to_time }}</span>
</h3>
<p>Uptime</p> <p>Uptime</p>
</div> </div>
<div class="icon"> <div class="icon">
@ -100,22 +93,32 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
<!-- /.row -->
</div> </div>
<!-- /.card-body -->
</div> </div>
<!-- /.card -->
</div> </div>
<div class="col-9"> <!-- /.col -->
<div class="card"> </div>
<!-- /.row -->
{% if current_user.role.name in ['Administrator', 'Operator'] or SETTING.get('allow_user_view_history') %}
<div class="row">
<div class="col-12">
<div class="card card-outline card-secondary">
<div class="card-header"> <div class="card-header">
<h3 class="card-title">Recent History</h3> <h3 class="card-title">Recent History</h3>
</div> </div>
<div class="card-body"> <!-- /.card-header -->
<table id="tbl_history" class="table table-bordered table-striped"> <div class="card-body table-responsive p-0">
<table class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>Changed By</th> <th>User</th>
<th>Content</th> <th>Log Message</th>
<th>Time</th> <th>Timestamp</th>
<th>Detail</th> <th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -123,8 +126,8 @@
<tr class="odd"> <tr class="odd">
<td>{{ history.history.created_by }}</td> <td>{{ history.history.created_by }}</td>
<td>{{ history.history.msg }}</td> <td>{{ history.history.msg }}</td>
<td>{{ history.history.created_on }}</td> <td>{{ history.history.created_on | format_datetime_local }}</td>
<td width="6%"> <td>
<div id="history-info-div-{{ loop.index0 }}" style="display: none;"> <div id="history-info-div-{{ loop.index0 }}" style="display: none;">
{{ history.detailed_msg | safe }} {{ history.detailed_msg | safe }}
{% if history.change_set %} {% if history.change_set %}
@ -147,10 +150,15 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<!-- /.card-body -->
</div> </div>
<!-- /.card -->
</div> </div>
<!-- /.col -->
</div> </div>
<!-- /.row -->
{% endif %} {% endif %}
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
@ -158,13 +166,15 @@
<div class="nav-tabs-custom"> <div class="nav-tabs-custom">
<ul class="nav nav-tabs card-header-tabs" id="custom-content-below-tab" role="tablist"> <ul class="nav nav-tabs card-header-tabs" id="custom-content-below-tab" role="tablist">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link active" href="#tab_{{custom_boxes.order[0]}}" data-toggle="pill" role="tab"> <a class="nav-link active" href="#tab_{{ custom_boxes.order[0] }}"
data-toggle="pill" role="tab">
Hosted Domains <b>{{ custom_boxes.boxes[custom_boxes.order[0]][0] }}</b> Hosted Domains <b>{{ custom_boxes.boxes[custom_boxes.order[0]][0] }}</b>
</a> </a>
</li> </li>
{% for boxId in custom_boxes.order[1:] %} {% for boxId in custom_boxes.order[1:] %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="#tab_{{boxId}}" data-toggle="pill" role="tab">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></a> <a class="nav-link" href="#tab_{{ boxId }}" data-toggle="pill" role="tab">Hosted
Domains <b>{{ custom_boxes.boxes[boxId][0] }}</b></a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
@ -175,16 +185,19 @@
{% for boxId in custom_boxes.order %} {% for boxId in custom_boxes.order %}
<div class="tab-pane fade show" id='tab_{{ boxId }}'> <div class="tab-pane fade show" id='tab_{{ boxId }}'>
<div class="card-header"> <div class="card-header">
<h3 class="card-title">Hosted Domains <b>{{custom_boxes.boxes[boxId][0]}}</b></h3> <h3 class="card-title">Hosted Domains
<b>{{ custom_boxes.boxes[boxId][0] }}</b></h3>
{% if show_bg_domain_button %} {% if show_bg_domain_button %}
<button type="button" class="btn btn-primary refresh-bg-button float-right"> <button type="button"
class="btn btn-primary refresh-bg-button float-right">
<i class="fa-solid fa-sync"></i> <i class="fa-solid fa-sync"></i>
&nbsp;Sync Domains &nbsp;Sync Domains
</button> </button>
{% endif %} {% endif %}
</div> </div>
<div class="card-body"> <div class="card-body table-responsive p-0 pt-2">
<table id='tbl_domain_list_{{boxId}}' class="table table-bordered table-striped"> <table id='tbl_domain_list_{{ boxId }}'
class="table table-striped table-hover">
<thead> <thead>
<tr> <tr>
<th>Name</th> <th>Name</th>
@ -226,7 +239,10 @@
"ordering": true, "ordering": true,
"columnDefs": [ "columnDefs": [
{"orderable": false, "targets": [-1]} {"orderable": false, "targets": [-1]}
{% if current_user.role.name not in ['Administrator', 'Operator'] %},{ "visible": false, "targets": [-2] }{% endif %} {% if current_user.role.name not in ['Administrator', 'Operator'] %},{
"visible": false,
"targets": [-2]
}{% endif %}
], ],
"processing": true, "processing": true,
"serverSide": true, "serverSide": true,
@ -243,6 +259,7 @@
"pageLength": {{ SETTING.get('default_domain_table_size') }} "pageLength": {{ SETTING.get('default_domain_table_size') }}
}); });
} }
$('#tab_{{custom_boxes.order[0]}}').addClass("active"); $('#tab_{{custom_boxes.order[0]}}').addClass("active");
{% for boxId in custom_boxes.order %} {% for boxId in custom_boxes.order %}
setUpDomainList("#tbl_domain_list_{{boxId}}", "{{url_for('dashboard.domains_custom',boxId=boxId)}}"); setUpDomainList("#tbl_domain_list_{{boxId}}", "{{url_for('dashboard.domains_custom',boxId=boxId)}}");