Admin dashboard improvements

This commit is contained in:
Tim Van Baak 2020-01-24 13:11:50 -08:00
parent f7aa7f2471
commit 9004f60a0c
5 changed files with 48 additions and 30 deletions

View File

@ -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
} }

View File

@ -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'))

View File

@ -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:
lid = index.get(form.lexiconName.data) for name, lid in index.items():
if lid is not None: lexicons.append(LexiconModel.by(lid=lid))
with json_ro('lexicon', lid, 'config.json') as cfg:
form.configText.data = json.dumps(cfg, indent=2) return render_template('home/admin.html', users=users, lexicons=lexicons)
form.lexiconName.data = ""
elif form.configText.data:
return "Update config"
else:
pass
return render_template('home/admin.html', form=form)
return bp return bp

View File

@ -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()] %}

View File

@ -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 }} &mdash; Last login: {{ user.last_login }}</p>
</div>
{% endmacro %}