Finished making dashboards
This commit is contained in:
parent
1312729836
commit
f6763b85fd
@ -42,10 +42,10 @@
|
||||
aria-labelledby="dropdown-account"
|
||||
>
|
||||
<li>
|
||||
<a href="{{ url_for('admin_views.users') }}" id="link-users" class="dropdown-item">Manage Users</a>
|
||||
<a href="{{ url_for('admin_views.users') }}" id="link-users" class="dropdown-item">Users</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ url_for('admin_views.questions') }}" id="link-questions" class="dropdown-item">Manage Questions</a>
|
||||
<a href="{{ url_for('admin_views.questions') }}" id="link-questions" class="dropdown-item">Question Datasets</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -1 +1,93 @@
|
||||
{% extends "admin/components/base.html" %}
|
||||
{% block title %}Settings — SKA Referee Test | Admin Console{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
Settings
|
||||
</h1>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="card m-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Admin Users</h5>
|
||||
<div class="card-text">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
Username
|
||||
</th>
|
||||
<th>
|
||||
Email Address
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="
|
||||
{% if user._id == get_id_from_cookie() %}
|
||||
{{ url_for('admin_auth.account') }}
|
||||
{% else %}
|
||||
{{ url_for('admin_views.update_user', _id=user._id) }}
|
||||
{% endif%}
|
||||
">{{ user.username }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="mailto:{{ user.email }}">{{ user.email }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<a href="{{ url_for('admin_views.users') }}" class="btn btn-primary">Manage Users</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="card m-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Question Datasets</h5>
|
||||
{% if datasets %}
|
||||
<div class="card-text">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
File Name
|
||||
</th>
|
||||
<th>
|
||||
Exams
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for dataset in datasets %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ dataset.filename }}
|
||||
</td>
|
||||
<td>
|
||||
{{ dataset.use }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<a href="{{ url_for('admin_views.questions') }}" class="btn btn-primary">Manage Datasets</a>
|
||||
{% else %}
|
||||
<div class="alert alert-primary">
|
||||
There are currently no question datasets uploaded.
|
||||
</div>
|
||||
<a href="{{ url_for('admin_views.questions') }}" class="btn btn-primary">Upload Dataset</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -16,7 +16,7 @@ import secrets
|
||||
from main import mail
|
||||
from datetime import datetime, date
|
||||
from .models.tests import Test
|
||||
from common.data_tools import get_default_dataset, get_time_options, available_datasets
|
||||
from common.data_tools import get_default_dataset, get_time_options, available_datasets, get_datasets
|
||||
|
||||
views = Blueprint(
|
||||
'admin_views',
|
||||
@ -76,13 +76,26 @@ def disable_if_logged_in(function):
|
||||
@admin_account_required
|
||||
@login_required
|
||||
def home():
|
||||
return render_template('/admin/index.html')
|
||||
tests = db.tests.find()
|
||||
results = decrypt_find(db.entries, {})
|
||||
current_tests = [ test for test in tests if test['expiry_date'].date() >= date.today() and test['start_date'].date() <= date.today() ]
|
||||
current_tests.sort(key= lambda x: x['expiry_date'], reverse=True)
|
||||
upcoming_tests = [ test for test in tests if test['start_date'].date() > date.today()]
|
||||
upcoming_tests.sort(key= lambda x: x['start_date'])
|
||||
recent_results = [result for result in results if 'submission_time' in result ]
|
||||
recent_results.sort(key= lambda x: x['submission_time'], reverse=True)
|
||||
for result in recent_results:
|
||||
result['percent'] = round(100*result['results']['score']/result['results']['max'])
|
||||
return render_template('/admin/index.html', current_tests = current_tests[:5], upcomimg_tests = upcoming_tests[:5], recent_results = recent_results[:5])
|
||||
|
||||
@views.route('/settings/')
|
||||
@admin_account_required
|
||||
@login_required
|
||||
def settings():
|
||||
return render_template('/admin/settings/index.html')
|
||||
users = decrypt_find(db.users, {})
|
||||
users.sort(key= lambda x: x['username'])
|
||||
datasets = get_datasets()
|
||||
return render_template('/admin/settings/index.html', users=users[:5], datasets=datasets[:5])
|
||||
|
||||
@views.route('/settings/users/', methods=['GET','POST'])
|
||||
@admin_account_required
|
||||
@ -245,22 +258,7 @@ def questions():
|
||||
from common.data_tools import check_json_format, validate_json_contents, store_data_file
|
||||
form = UploadDataForm()
|
||||
if request.method == 'GET':
|
||||
files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
|
||||
data = []
|
||||
if files:
|
||||
for file in files:
|
||||
filename = file.rsplit('/')[-1]
|
||||
with open(file) as _file:
|
||||
load = loads(_file.read())
|
||||
_author = load['meta']['author']
|
||||
author = decrypt_find_one(db.users, {'_id': _author})['username']
|
||||
data_element = {
|
||||
'filename': filename,
|
||||
'timestamp': datetime.strptime(load['meta']['timestamp'], '%Y-%m-%d %H%M%S'),
|
||||
'author': author,
|
||||
'use': len(load['meta']['tests'])
|
||||
}
|
||||
data.append(data_element)
|
||||
data = get_datasets()
|
||||
default = get_default_dataset()
|
||||
return render_template('/admin/settings/questions.html', form=form, data=data, default=default)
|
||||
if request.method == 'POST':
|
||||
|
@ -3,13 +3,12 @@ import pathlib
|
||||
from json import dump, loads
|
||||
from datetime import datetime, timedelta
|
||||
from glob import glob
|
||||
|
||||
from flask.json import jsonify
|
||||
from main import app
|
||||
from random import shuffle
|
||||
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
from main import app, db
|
||||
from .security.database import decrypt_find_one
|
||||
|
||||
def check_data_folder_exists():
|
||||
if not os.path.exists(app.config['DATA_FILE_DIRECTORY']):
|
||||
pathlib.Path(app.config['DATA_FILE_DIRECTORY']).mkdir(parents='True', exist_ok='True')
|
||||
@ -200,3 +199,22 @@ def get_time_options():
|
||||
('120', '2 hours')
|
||||
]
|
||||
return time_options
|
||||
|
||||
def get_datasets():
|
||||
files = glob(os.path.join(app.config["DATA_FILE_DIRECTORY"],'*.json'))
|
||||
data = []
|
||||
if files:
|
||||
for file in files:
|
||||
filename = file.rsplit('/')[-1]
|
||||
with open(file) as _file:
|
||||
load = loads(_file.read())
|
||||
_author = load['meta']['author']
|
||||
author = decrypt_find_one(db.users, {'_id': _author})['username']
|
||||
data_element = {
|
||||
'filename': filename,
|
||||
'timestamp': datetime.strptime(load['meta']['timestamp'], '%Y-%m-%d %H%M%S'),
|
||||
'author': author,
|
||||
'use': len(load['meta']['tests'])
|
||||
}
|
||||
data.append(data_element)
|
||||
return data
|
Loading…
Reference in New Issue
Block a user