Skip to content
Snippets Groups Projects
Commit 99536bdd authored by Benjamin Bertrand's avatar Benjamin Bertrand
Browse files

Add page to create QR codes

This can be done via the Admin interface but this latter shall be
restricted to admin users. This simple page allows the group "create"
to easily add new Manufacturer, Model or Location.
parent fa2dcb65
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
"""
app.main.forms
~~~~~~~~~~~~~~
This module defines the main forms.
:copyright: (c) 2017 European Spallation Source ERIC
:license: BSD 2-Clause, see LICENSE for more details.
"""
from flask_wtf import FlaskForm
from wtforms import SelectField, StringField, validators
from .. import utils
class QRCodeForm(FlaskForm):
kind = SelectField('Kind')
name = StringField('name', validators=[validators.DataRequired()])
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.kind.choices = utils.get_choices(
('Manufacturer', 'Model', 'Location')
)
......@@ -9,10 +9,14 @@ This module implements the main blueprint.
:license: BSD 2-Clause, see LICENSE for more details.
"""
from flask import Blueprint, render_template, jsonify
import sqlalchemy as sa
from flask import (Blueprint, render_template, jsonify,
redirect, url_for, request, flash)
from flask_login import login_required
from .forms import QRCodeForm
from ..extensions import db
from ..models import Action, Manufacturer, Model, Location, Status, Item
from ..decorators import login_groups_accepted
from .. import utils
bp = Blueprint('main', __name__)
......@@ -70,3 +74,33 @@ def qrcodes():
for item in items]
codes[model.__name__] = images
return render_template('qrcodes.html', codes=codes)
@bp.route('/qrcodes/create', methods=('GET', 'POST'))
@login_groups_accepted('admin', 'create')
def create_qrcodes():
kind = request.args.get('kind', 'Manufacturer')
form = QRCodeForm(request.form, kind=kind)
if form.validate_on_submit():
model = globals()[form.kind.data]
new_model = model(name=form.name.data)
db.session.add(new_model)
try:
db.session.commit()
except sa.exc.IntegrityError as e:
db.session.rollback()
flash(f'{form.name.data} already exists! Item not created.', 'error')
return redirect(url_for('main.create_qrcodes', kind=form.kind.data))
return render_template('create_qrcodes.html', form=form)
@bp.route('/_retrieve_qrcodes_name/<kind>')
@login_required
def retrieve_qrcodes_name(kind):
try:
model = globals()[kind]
except KeyError:
raise utils.InventoryError(f"Unknown model '{kind}'", status_code=422)
items = db.session.query(model).order_by(model.name)
data = [[item.name] for item in items]
return jsonify(data=data)
$(document).ready(function() {
var qrcodes_table = $("#qrcodes_table").DataTable({
"ajax": function(data, callback, settings) {
var kind = $("#kind").val();
$.getJSON(
$SCRIPT_ROOT + "/_retrieve_qrcodes_name/" + kind,
function(json) {
callback(json);
});
},
"paging": false
});
$("#kind").on('change', function() {
qrcodes_table.ajax.reload();
});
});
{% macro nav_a(active) -%}
<a class="nav-item nav-link{% if active %} active{% endif %}"
{% macro is_active(active) -%}
{% if active %}active{% endif %}
{%- endmacro %}
{%- extends "bootstrap/base.html" %}
{% import "bootstrap/utils.html" as utils %}
{% from "_helpers.html" import nav_a %}
{% from "_helpers.html" import is_active %}
{% block styles %}
{{super()}}
......@@ -23,15 +23,23 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<div class="navbar-nav mr-auto">
{% set path = request.path %}
{{ nav_a(path in ("/", "/index", "/index/")) }} href="{{ url_for('main.index') }}">Index</a>
{{ nav_a(path == "/qrcodes") }} href="{{ url_for('main.qrcodes') }}">QR Codes</a>
<a class="nav-item nav-link {{ is_active(path in ("/", "/index", "/index/")) }}" href="{{ url_for('main.index') }}">Index</a>
<div class="dropdown {{ is_active(path.startswith("/qrcodes")) }}">
<a class="nav-link dropdown-toggle" href="#" id="qrcodesDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
QR Codes
</a>
<div class="dropdown-menu" aria-labelledby="qrcodesDropdownMenuLink">
<a class="dropdown-item" href="{{ url_for('main.qrcodes') }}">View</a>
<a class="dropdown-item" href="{{ url_for('main.create_qrcodes') }}">Create</a>
</div>
</div>
{% if current_user.is_authenticated and current_user.is_admin %}
<a class="nav-item nav-link" href="{{ url_for('admin.index') }}">Admin</a>
{% endif %}
</div>
<div class="navbar-nav">
{% if current_user.is_authenticated %}
<div class="dropdown">
<div class="dropdown {{ is_active(path == "/profile") }}">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{current_user}}
</a>
......
{%- extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Create QR Codes{% endblock %}
{% block main %}
<h2>Create QR Codes</h2>
<form method="POST" class="form-inline">
{{ form.csrf_token }}
{{ form.kind.label(class="sr-only") | safe }}
{{ form.kind(class="form-control mb-2 mr-sm-2 mb-sm-0") }}
{{ form.name.label(class="sr-only") | safe }}
{{ form.name(class="form-control mb-2 mr-sm-2 mb-sm-0", placeholder="name", required=True) }}
<button type="submit" class="btn btn-primary">Create</button>
</form>
<hr class="separator">
<table id="qrcodes_table" class="table table-bordered table-hover table-sm">
<thead>
<tr>
<th>Name</th>
</tr>
</thead>
</table>
{%- endblock %}
{% block inventory_scripts %}
<script src="{{ url_for('static', filename='js/qrcodes.js') }}"></script>
{% endblock %}
......@@ -92,3 +92,14 @@ def attribute_to_string(value):
return value[0]
else:
return value
def get_choices(iterable, allow_blank=False, allow_null=False):
"""Return a list of (value, label)"""
choices = []
if allow_blank:
choices = [('', '')]
if allow_null:
choices.append(('null', 'not set'))
choices.extend([(val, val) for val in iterable])
return choices
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment