From b4866aad63d9d120b068f43bb552ee713f6fd0e8 Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand <benjamin.bertrand@esss.se> Date: Fri, 1 Dec 2017 23:09:19 +0100 Subject: [PATCH] Implement UI to register items --- app/main/forms.py | 24 +++++++++++++++++++++++- app/main/views.py | 23 +++++++++++++++++++++-- app/templates/create_item.html | 19 +++++++++++++++---- app/utils.py | 9 +++++++++ 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 8ee9fd4..20549c2 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -10,7 +10,7 @@ This module defines the main forms. """ from flask_wtf import FlaskForm -from wtforms import SelectField, StringField, validators +from wtforms import SelectField, StringField, SelectMultipleField, validators from .. import utils, models @@ -37,6 +37,28 @@ class QRCodeForm(FlaskForm): ) +class ItemForm(FlaskForm): + ics_id = StringField('ICS id', + validators=[validators.InputRequired(), + validators.Regexp(models.ICS_ID_RE)]) + serial_number = StringField('Serial number', + validators=[validators.InputRequired()]) + manufacturer_id = SelectField('Manufacturer') + model_id = SelectField('Model') + location_id = SelectField('Location') + status_id = SelectField('Status') + parent_id = SelectField('Parent') + # macs = SelectMultipleField('Macs') + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.manufacturer_id.choices = utils.get_model_choices(models.Manufacturer, allow_blank=True) + self.model_id.choices = utils.get_model_choices(models.Model, allow_blank=True) + self.location_id.choices = utils.get_model_choices(models.Location, allow_blank=True) + self.status_id.choices = utils.get_model_choices(models.Status, allow_blank=True) + self.parent_id.choices = utils.get_model_choices(models.Item, allow_blank=True, attr='ics_id') + + class HostForm(FlaskForm): network_id = SelectField('Network') # The list of IPs is dynamically created on the browser side diff --git a/app/main/views.py b/app/main/views.py index 6b058fb..b8476d0 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -13,7 +13,7 @@ import sqlalchemy as sa from flask import (Blueprint, render_template, jsonify, redirect, url_for, request, flash, current_app) from flask_login import login_required -from .forms import QRCodeForm, HostForm +from .forms import QRCodeForm, HostForm, ItemForm from ..extensions import db from ..decorators import login_groups_accepted from .. import utils, models @@ -72,7 +72,26 @@ def list_items(): @bp.route('/items/create', methods=('GET', 'POST')) @login_groups_accepted('admin', 'create') def create_item(): - form = None + form = ItemForm() + if form.validate_on_submit(): + item = models.Item(ics_id=form.ics_id.data, + serial_number=form.serial_number.data, + manufacturer_id=form.manufacturer_id.data or None, + model_id=form.model_id.data or None, + location_id=form.location_id.data or None, + status_id=form.status_id.data or None, + parent_id=form.parent_id.data or None) + current_app.logger.debug(f'Trying to create: {item!r}') + db.session.add(item) + try: + db.session.commit() + except sa.exc.IntegrityError as e: + db.session.rollback() + current_app.logger.warning(f'{e}') + flash(f'{e}', 'error') + else: + flash(f'Item {item} created!', 'success') + return redirect(url_for('main.create_item')) return render_template('create_item.html', form=form) diff --git a/app/templates/create_item.html b/app/templates/create_item.html index 56a5f18..d9b2931 100644 --- a/app/templates/create_item.html +++ b/app/templates/create_item.html @@ -1,4 +1,5 @@ {%- extends "base.html" %} +{% from "_helpers.html" import render_field %} {% block title %}Items - CSEntry{% endblock %} @@ -14,11 +15,21 @@ <br> - <div class="card"> - <h4 class="card-header">Register new item</h4> - <div class="card-body"> + <form id="itemForm" method="POST"> + {{ form.hidden_tag() }} + {{ render_field(form.ics_id) }} + {{ render_field(form.serial_number) }} + {{ render_field(form.manufacturer_id) }} + {{ render_field(form.model_id) }} + {{ render_field(form.location_id) }} + {{ render_field(form.status_id) }} + {{ render_field(form.parent_id) }} + <div class="form-group row"> + <div class="col-sm-10"> + <button type="submit" class="btn btn-primary">Submit</button> + </div> </div> - </div> + </form> {%- endblock %} {% block csentry_scripts %} diff --git a/app/utils.py b/app/utils.py index aab9a5a..9dc30ce 100644 --- a/app/utils.py +++ b/app/utils.py @@ -107,6 +107,15 @@ def get_choices(iterable, allow_blank=False, allow_null=False): return choices +def get_model_choices(model, allow_blank=False, attr='name'): + """Return a list of (value, label)""" + choices = [] + if allow_blank: + choices = [('', '')] + choices.extend([(str(instance.id), getattr(instance, attr)) for instance in model.query.all()]) + return choices + + def get_query(query, args): """Retrieve the query from the arguments -- GitLab