Admin dashboard improvements
This commit is contained in:
parent
f7aa7f2471
commit
9004f60a0c
|
@ -6,6 +6,8 @@
|
||||||
"email": null,
|
"email": null,
|
||||||
"password": null,
|
"password": null,
|
||||||
"created": null,
|
"created": null,
|
||||||
|
"last_login": null,
|
||||||
|
"last_activity": null,
|
||||||
"new_password_required": true,
|
"new_password_required": true,
|
||||||
"is_admin": false
|
"is_admin": false
|
||||||
}
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
|
import time
|
||||||
|
|
||||||
from flask import Blueprint, render_template, redirect, url_for, flash
|
from flask import Blueprint, render_template, redirect, url_for, flash
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import StringField, PasswordField, BooleanField, SubmitField
|
from wtforms import StringField, PasswordField, BooleanField, SubmitField
|
||||||
from wtforms.validators import DataRequired
|
from wtforms.validators import DataRequired
|
||||||
from flask_login import current_user, login_user, logout_user, login_required
|
from flask_login import current_user, login_user, logout_user, login_required
|
||||||
|
|
||||||
from amanuensis.config import logger
|
from amanuensis.config import logger, json_rw
|
||||||
from amanuensis.user import UserModel
|
from amanuensis.user import UserModel
|
||||||
|
|
||||||
class LoginForm(FlaskForm):
|
class LoginForm(FlaskForm):
|
||||||
|
@ -30,6 +32,8 @@ def get_bp(login_manager):
|
||||||
if u is not None and u.check_password(form.password.data):
|
if u is not None and u.check_password(form.password.data):
|
||||||
remember_me = form.remember.data
|
remember_me = form.remember.data
|
||||||
login_user(u, remember=remember_me)
|
login_user(u, remember=remember_me)
|
||||||
|
with json_rw(u.config_path) as cfg:
|
||||||
|
cfg.last_login = int(time.time())
|
||||||
logger.info("Logged in user '{}' ({})".format(
|
logger.info("Logged in user '{}' ({})".format(
|
||||||
u.username, u.uid))
|
u.username, u.uid))
|
||||||
return redirect(url_for('home.home'))
|
return redirect(url_for('home.home'))
|
||||||
|
|
|
@ -7,11 +7,9 @@ from flask_wtf import FlaskForm
|
||||||
from wtforms import TextAreaField, SubmitField, StringField
|
from wtforms import TextAreaField, SubmitField, StringField
|
||||||
|
|
||||||
from amanuensis.config import json_ro
|
from amanuensis.config import json_ro
|
||||||
|
from amanuensis.lexicon import LexiconModel
|
||||||
|
from amanuensis.user import UserModel
|
||||||
|
|
||||||
class AdminDashboardForm(FlaskForm):
|
|
||||||
lexiconName = StringField("Lexicon name")
|
|
||||||
configText = TextAreaField("Config file")
|
|
||||||
submit = SubmitField("Submit")
|
|
||||||
|
|
||||||
def admin_required(route):
|
def admin_required(route):
|
||||||
"""Requires the user to be an admin"""
|
"""Requires the user to be an admin"""
|
||||||
|
@ -23,6 +21,7 @@ def admin_required(route):
|
||||||
return route(*args, **kwargs)
|
return route(*args, **kwargs)
|
||||||
return admin_route
|
return admin_route
|
||||||
|
|
||||||
|
|
||||||
def get_bp():
|
def get_bp():
|
||||||
"""Create a blueprint for pages outside of a specific lexicon"""
|
"""Create a blueprint for pages outside of a specific lexicon"""
|
||||||
bp = Blueprint('home', __name__, url_prefix='/home')
|
bp = Blueprint('home', __name__, url_prefix='/home')
|
||||||
|
@ -34,22 +33,16 @@ def get_bp():
|
||||||
@bp.route('/admin/', methods=['GET', 'POST'])
|
@bp.route('/admin/', methods=['GET', 'POST'])
|
||||||
@admin_required
|
@admin_required
|
||||||
def admin():
|
def admin():
|
||||||
form = AdminDashboardForm()
|
users = []
|
||||||
if not form.is_submitted():
|
with json_ro('user', 'index.json') as index:
|
||||||
return render_template('home/admin.html', form=form)
|
for name, uid in index.items():
|
||||||
|
users.append(UserModel.by(uid=uid))
|
||||||
|
|
||||||
if form.lexiconName.data:
|
lexicons = []
|
||||||
lid = None
|
with json_ro('lexicon', 'index.json') as index:
|
||||||
with json_ro('lexicon', 'index.json') as index:
|
for name, lid in index.items():
|
||||||
lid = index.get(form.lexiconName.data)
|
lexicons.append(LexiconModel.by(lid=lid))
|
||||||
if lid is not None:
|
|
||||||
with json_ro('lexicon', lid, 'config.json') as cfg:
|
return render_template('home/admin.html', users=users, lexicons=lexicons)
|
||||||
form.configText.data = json.dumps(cfg, indent=2)
|
|
||||||
form.lexiconName.data = ""
|
|
||||||
elif form.configText.data:
|
|
||||||
return "Update config"
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
return render_template('home/admin.html', form=form)
|
|
||||||
|
|
||||||
return bp
|
return bp
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
{% extends "page_2col.html" %}
|
{% extends "page_2col.html" %}
|
||||||
|
{% import 'macros.html' as macros %}
|
||||||
{% block title %}Admin | Amanuensis{% endblock %}
|
{% block title %}Admin | Amanuensis{% endblock %}
|
||||||
{% block header %}<h2>Amanuensis - Admin Dashboard</h2>{% endblock %}
|
{% block header %}<h2>Amanuensis - Admin Dashboard</h2>{% endblock %}
|
||||||
|
|
||||||
{% block sb_topline %}<b>{{ current_user.displayname }}</b>{% endblock %}
|
|
||||||
{% block sb_logout %}<a href="{{ url_for('auth.logout') }}">Log out</a>{% endblock %}
|
|
||||||
{% block sb_home %}<a href="{{ url_for('home.home') }}">Home</a>{% endblock %}
|
{% block sb_home %}<a href="{{ url_for('home.home') }}">Home</a>{% endblock %}
|
||||||
{% set template_sidebar_rows = [self.sb_topline(), self.sb_logout(), self.sb_home()] %}
|
{% set template_sidebar_rows = [self.sb_home()] %}
|
||||||
|
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<form action="" method="post" novalidate>
|
<p>Users:</p>
|
||||||
{{ form.hidden_tag() }}
|
{% for user in users %}
|
||||||
<p>{{ form.lexiconName.label }}<br>{{ form.lexiconName(size=32) }}</p>
|
{{ macros.dashboard_user_item(user) }}
|
||||||
<p>{{ form.configText.label }}<br>{{ form.configText(rows=20) }}</p>
|
{% endfor %}
|
||||||
<p>{{ form.submit() }}</p>
|
<p>Lexicons:</p>
|
||||||
</form>
|
{% for lexicon in lexicons %}
|
||||||
|
{{ macros.dashboard_lexicon_item(lexicon) }}
|
||||||
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% set template_content_blocks = [self.main()] %}
|
{% set template_content_blocks = [self.main()] %}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{% macro dashboard_lexicon_item(lexicon) %}
|
||||||
|
<div class="dashboard-lexicon-item dashboard-lexicon-{{ lexicon.status() }}">
|
||||||
|
<p>
|
||||||
|
<span class="dashboard-lexicon-item-title">
|
||||||
|
<a href="{{ url_for('lexicon.session', name=lexicon.name) }}">Lexicon {{ lexicon.name }}</a>
|
||||||
|
</span>
|
||||||
|
[{{ lexicon.status().capitalize() }}]
|
||||||
|
</p>
|
||||||
|
<p><i>{{ lexicon.prompt }}</i></p>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro dashboard_user_item(user) %}
|
||||||
|
<div class="dashboard-lexicon-item">
|
||||||
|
<p><b>{{ user.username }}</b> {% if user.username != user.displayname %} / {{ user.displayname }}{% endif %} ({{user.uid}})</p>
|
||||||
|
<p>Last activity: {{ user.last_activity }} — Last login: {{ user.last_login }}</p>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
Loading…
Reference in New Issue