Merge #1800
1800: AdminLTE 3 r=mergify[bot] a=DjVinnii ## What type of PR? Enhancement ## What does this PR do? This PR implements AdminLTE 3 for the admin interface. It also includes the implementation of DataTables and a language selector. ### Related issue(s) - closes: #1567 - closes: #1764 ## Prerequistes - [x] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/guide.html#changelog) entry file. Co-authored-by: Vincent Kling <vincentkling@msn.com> Co-authored-by: DjVinnii <vincentkling@msn.com> Co-authored-by: Dimitri Huisman <52963853+Diman0@users.noreply.github.com> Co-authored-by: Diman0 <diman@huisman.xyz> Co-authored-by: Dimitri Huisman <diman@huisman.xyz>master
commit
71cc8b0a81
@ -1,10 +1,17 @@
|
|||||||
require('./app.css');
|
require('./app.css');
|
||||||
|
|
||||||
import 'select2';
|
import 'admin-lte/plugins/select2/js/select2.js';
|
||||||
|
import 'admin-lte/plugins/datatables/jquery.dataTables.js';
|
||||||
|
import 'admin-lte/plugins/datatables-bs4/js/dataTables.bootstrap4.js';
|
||||||
|
import 'admin-lte/plugins/datatables-responsive/js/dataTables.responsive.js';
|
||||||
|
import 'admin-lte/plugins/datatables-responsive/js/responsive.bootstrap4.js';
|
||||||
|
|
||||||
jQuery("document").ready(function() {
|
jQuery("document").ready(function() {
|
||||||
jQuery(".mailselect").select2({
|
jQuery(".mailselect").select2({
|
||||||
tags: true,
|
tags: true,
|
||||||
tokenSeparators: [',', ' ']
|
tokenSeparators: [',', ' ']
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
jQuery(".dataTable").DataTable({
|
||||||
|
"responsive": true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% call macros.box() %}
|
{% call macros.card() %}
|
||||||
{{ macros.form(form) }}
|
{{ macros.form(form) }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,120 +1,144 @@
|
|||||||
<section class="sidebar">
|
<div class="sidebar">
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<h4 class="text-center text-primary">{{ current_user }}</h4>
|
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
|
||||||
|
<div class="info">
|
||||||
|
<span class="text-center text-primary">{{ current_user }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<ul class="sidebar-menu" data-widget="tree">
|
<nav class="mt-2">
|
||||||
|
<ul class="nav nav-pills nav-sidebar flex-column" role="menu">
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<li class="header">{% trans %}My account{% endtrans %}</li>
|
<li class="nav-header">{% trans %}My account{% endtrans %}</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.user_settings') }}">
|
<a href="{{ url_for('.user_settings') }}" class="nav-link">
|
||||||
<i class="fa fa-wrench"></i> <span>{% trans %}Settings{% endtrans %}</span>
|
<i class="nav-icon fa fa-wrench"></i>
|
||||||
|
<p class="text">{% trans %}Settings{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.user_password') }}">
|
<a href="{{ url_for('.user_password') }}" class="nav-link">
|
||||||
<i class="fa fa-lock"></i> <span>{% trans %}Update password{% endtrans %}</span>
|
<i class="nav-icon fa fa-lock"></i>
|
||||||
|
<p class="text">{% trans %}Update password{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.user_reply') }}">
|
<a href="{{ url_for('.user_reply') }}" class="nav-link">
|
||||||
<i class="fa fa-plane"></i> <span>{% trans %}Auto-reply{% endtrans %}</span>
|
<i class="nav-icon fa fa-plane"></i>
|
||||||
|
<p class="text">{% trans %}Auto-reply{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.fetch_list') }}">
|
<a href="{{ url_for('.fetch_list') }}" class="nav-link">
|
||||||
<i class="fa fa-download"></i> <span>{% trans %}Fetched accounts{% endtrans %}</span>
|
<i class="nav-icon fas fa-download"></i>
|
||||||
|
<p class="text">{% trans %}Fetched accounts{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.token_list') }}">
|
<a href="{{ url_for('.token_list') }}" class="nav-link">
|
||||||
<i class="fa fa-ticket"></i> <span>{% trans %}Authentication tokens{% endtrans %}</span>
|
<i class="nav-icon fas fa-ticket-alt"></i>
|
||||||
|
<p class="text">{% trans %}Authentication tokens{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% if current_user.manager_of or current_user.global_admin %}
|
{% if current_user.manager_of or current_user.global_admin %}
|
||||||
<li class="header">{% trans %}Administration{% endtrans %}</li>
|
<li class="nav-header">{% trans %}Administration{% endtrans %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if current_user.global_admin %}
|
{% if current_user.global_admin %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.announcement') }}">
|
<a href="{{ url_for('.announcement') }}" class="nav-link">
|
||||||
<i class="fa fa-bullhorn"></i> <span>{% trans %}Announcement{% endtrans %}</span>
|
<i class="nav-icon fa fa-bullhorn"></i>
|
||||||
|
<p class="text">{% trans %}Announcement{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.admin_list') }}">
|
<a href="{{ url_for('.admin_list') }}" class="nav-link">
|
||||||
<i class="fa fa-user"></i> <span>{% trans %}Administrators{% endtrans %}</span>
|
<i class="nav-icon fa fa-user"></i>
|
||||||
|
<p class="text">{% trans %}Administrators{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.relay_list') }}">
|
<a href="{{ url_for('.relay_list') }}" class="nav-link">
|
||||||
<i class="fa fa-reply-all"></i> <span>{% trans %}Relayed domains{% endtrans %}</span>
|
<i class="nav-icon fa fa-reply-all"></i>
|
||||||
|
<p class="text">{% trans %}Relayed domains{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ config["WEB_ADMIN"] }}/antispam/" target="_blank">
|
<a href="{{ config["WEB_ADMIN"] }}/antispam/" target="_blank" class="nav-link">
|
||||||
<i class="fa fa-trash-o"></i> <span>{% trans %}Antispam{% endtrans %}</span>
|
<i class="nav-icon fas fa-trash-alt"></i>
|
||||||
|
<p class="text">{% trans %}Antispam{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if current_user.manager_of or current_user.global_admin %}
|
{% if current_user.manager_of or current_user.global_admin %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.domain_list') }}">
|
<a href="{{ url_for('.domain_list') }}" class="nav-link">
|
||||||
<i class="fa fa-envelope"></i> <span>{% trans %}Mail domains{% endtrans %}</span>
|
<i class="nav-icon fa fa-envelope"></i>
|
||||||
|
<p class="text">{% trans %}Mail domains{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<li class="header">{% trans %}Go to{% endtrans %}</li>
|
<li class="nav-header">{% trans %}Go to{% endtrans %}</li>
|
||||||
{% if config["WEBMAIL"] != "none" %}
|
{% if config["WEBMAIL"] != "none" %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ config["WEB_WEBMAIL"] }}" target="_blank">
|
<a href="{{ config["WEB_WEBMAIL"] }}" target="_blank" class="nav-link">
|
||||||
<i class="fa fa-envelope-o"></i> <span>{% trans %}Webmail{% endtrans %}</span>
|
<i class="nav-icon far fa-envelope"></i>
|
||||||
|
<p class="text">{% trans %}Webmail{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.client') }}">
|
<a href="{{ url_for('.client') }}" class="nav-link">
|
||||||
<i class="fa fa-laptop"></i> <span>{% trans %}Client setup{% endtrans %}</span>
|
<i class="nav-icon fa fa-laptop"></i>
|
||||||
|
<p class="text">{% trans %}Client setup{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ config["WEBSITE"] }}" target="_blank">
|
<a href="{{ config["WEBSITE"] }}" target="_blank" class="nav-link">
|
||||||
<i class="fa fa-globe"></i> <span>{% trans %}Website{% endtrans %}</span>
|
<i class="nav-icon fa fa-globe"></i>
|
||||||
|
<p class="text">{% trans %}Website{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="https://mailu.io" target="_blank">
|
<a href="https://mailu.io" target="_blank" class="nav-link">
|
||||||
<i class="fa fa-life-ring"></i> <span>{% trans %}Help{% endtrans %}</span>
|
<i class="nav-icon fa fa-life-ring"></i>
|
||||||
|
<p class="text">{% trans %}Help{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% if config['DOMAIN_REGISTRATION'] %}
|
{% if config['DOMAIN_REGISTRATION'] %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.domain_signup') }}">
|
<a href="{{ url_for('.domain_signup') }}" class="nav-link">
|
||||||
<i class="fa fa-plus-square"></i> <span>{% trans %}Register a domain{% endtrans %}</span>
|
<i class="nav-icon fa fa-plus-square"></i>
|
||||||
|
<p class="text">{% trans %}Register a domain{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.logout') }}">
|
<a href="{{ url_for('.logout') }}" class="nav-link">
|
||||||
<i class="fa fa-sign-out"></i> <span>{% trans %}Sign out{% endtrans %}</span>
|
<i class="nav-icon fas fa-sign-out-alt"></i>
|
||||||
|
<p class="text">{% trans %}Sign out{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.login') }}">
|
<a href="{{ url_for('.login') }}" class="nav-link">
|
||||||
<i class="fa fa-sign-in"></i> <span>{% trans %}Sign in{% endtrans %}</span>
|
<i class="nav-icon fas fa-sign-in-alt"></i>
|
||||||
|
<p class="text">{% trans %}Sign in{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% if signup_domains %}
|
{% if signup_domains %}
|
||||||
<li>
|
<li class="nav-item">
|
||||||
<a href="{{ url_for('.user_signup') }}">
|
<a href="{{ url_for('.user_signup') }}" class="nav-link">
|
||||||
<i class="fa fa-user-plus"></i> <span>{% trans %}Sign up{% endtrans %}</span>
|
<i class="nav-icon fa fa-user-plus"></i>
|
||||||
|
<p class="text">{% trans %}Sign up{% endtrans %}</p>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</nav>
|
||||||
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
__all__ = [
|
__all__ = [
|
||||||
'admins', 'aliases', 'alternatives', 'base', 'domains', 'fetches',
|
'admins', 'aliases', 'alternatives', 'base', 'domains', 'fetches',
|
||||||
'managers', 'users', 'relays', 'tokens'
|
'managers', 'users', 'relays', 'tokens', 'languages'
|
||||||
]
|
]
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
from mailu.ui import ui, forms, access
|
||||||
|
|
||||||
|
import flask
|
||||||
|
|
||||||
|
|
||||||
|
@ui.route('/language/<language>', methods=['GET'])
|
||||||
|
def set_language(language=None):
|
||||||
|
flask.session['language'] = language
|
||||||
|
return flask.redirect(flask.url_for('.user_settings'))
|
@ -0,0 +1 @@
|
|||||||
|
Implement a language selector for the admin interface.
|
@ -0,0 +1 @@
|
|||||||
|
Implement AdminLTE 3 for the admin interface.
|
Loading…
Reference in New Issue