show error msg for forms with errors of validations
This commit is contained in:
parent
65a774550e
commit
10c756a884
|
@ -389,7 +389,7 @@ class NewActionForm(FlaskForm):
|
||||||
Lot.owner_id == g.user.id).one()
|
Lot.owner_id == g.user.id).one()
|
||||||
|
|
||||||
devices = set(self.devices.data.split(","))
|
devices = set(self.devices.data.split(","))
|
||||||
self._devices = set(Device.query.filter(Device.id.in_(devices)).filter(
|
self._devices = OrderedSet(Device.query.filter(Device.id.in_(devices)).filter(
|
||||||
Device.owner_id == g.user.id).all())
|
Device.owner_id == g.user.id).all())
|
||||||
|
|
||||||
if not self._devices:
|
if not self._devices:
|
||||||
|
@ -397,26 +397,34 @@ class NewActionForm(FlaskForm):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.instance = Action()
|
|
||||||
self.populate_obj(self.instance)
|
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
self.instance.devices = self._devices
|
Model = db.Model._decl_class_registry.data[self.type.data]()
|
||||||
self.instance.severity = Severity[self.severity.data]
|
self.instance = Model()
|
||||||
|
self.devices.data = self._devices
|
||||||
|
self.severity.data = Severity[self.severity.data]
|
||||||
|
|
||||||
|
self.populate_obj(self.instance)
|
||||||
db.session.add(self.instance)
|
db.session.add(self.instance)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return self.instance
|
return self.instance
|
||||||
|
|
||||||
|
|
||||||
class AllocateForm(NewActionForm):
|
class AllocateForm(NewActionForm):
|
||||||
def __init__(self, *args, **kwargs):
|
start_time = DateField(u'Start time')
|
||||||
# import pdb; pdb.set_trace()
|
end_time = DateField(u'End time')
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
start_time = DateField(u'Start time', validators=(validators.Optional(),))
|
|
||||||
end_time = DateField(u'End time', validators=(validators.Optional(),))
|
|
||||||
final_user_code = StringField(u'Final user code', [validators.length(max=50)])
|
final_user_code = StringField(u'Final user code', [validators.length(max=50)])
|
||||||
transaction = StringField(u'Transaction', [validators.length(max=50)])
|
transaction = StringField(u'Transaction', [validators.length(max=50)])
|
||||||
end_users = IntegerField(u'End users')
|
end_users = IntegerField(u'End users')
|
||||||
|
|
||||||
|
def validate(self, extra_validators=None):
|
||||||
|
is_valid = super().validate(extra_validators)
|
||||||
|
|
||||||
|
start_time = self.start_time.data
|
||||||
|
end_time = self.end_time.data
|
||||||
|
if start_time and end_time and end_time < start_time:
|
||||||
|
error = ['The action cannot finish before it starts.']
|
||||||
|
self.start_time.errors = error
|
||||||
|
self.end_time.errors = error
|
||||||
|
is_valid = False
|
||||||
|
|
||||||
|
return is_valid
|
||||||
|
|
|
@ -12,11 +12,11 @@ from ereuse_devicehub.inventory.forms import LotDeviceForm, LotForm, UploadSnaps
|
||||||
devices = Blueprint('inventory.devices', __name__, url_prefix='/inventory')
|
devices = Blueprint('inventory.devices', __name__, url_prefix='/inventory')
|
||||||
|
|
||||||
|
|
||||||
class DeviceListView(View):
|
class DeviceListMix(View):
|
||||||
decorators = [login_required]
|
decorators = [login_required]
|
||||||
template_name = 'inventory/device_list.html'
|
template_name = 'inventory/device_list.html'
|
||||||
|
|
||||||
def dispatch_request(self, lot_id=None):
|
def get_context(self, lot_id):
|
||||||
# TODO @cayop adding filter
|
# TODO @cayop adding filter
|
||||||
# https://github.com/eReuse/devicehub-teal/blob/testing/ereuse_devicehub/resources/device/views.py#L56
|
# https://github.com/eReuse/devicehub-teal/blob/testing/ereuse_devicehub/resources/device/views.py#L56
|
||||||
filter_types = ['Desktop', 'Laptop', 'Server']
|
filter_types = ['Desktop', 'Laptop', 'Server']
|
||||||
|
@ -34,16 +34,22 @@ class DeviceListView(View):
|
||||||
Device.updated.desc())
|
Device.updated.desc())
|
||||||
form_new_action = NewActionForm()
|
form_new_action = NewActionForm()
|
||||||
|
|
||||||
allocate = AllocateForm(start_time=datetime.datetime.now(),
|
form_new_allocate = AllocateForm()
|
||||||
end_time=datetime.datetime.now()+datetime.timedelta(1))
|
|
||||||
|
|
||||||
context = {'devices': devices,
|
self.context = {'devices': devices,
|
||||||
'lots': lots,
|
'lots': lots,
|
||||||
'form_lot_device': LotDeviceForm(),
|
'form_lot_device': LotDeviceForm(),
|
||||||
'form_new_action': form_new_action,
|
'form_new_action': form_new_action,
|
||||||
'form_allocate': allocate,
|
'form_new_allocate': form_new_allocate,
|
||||||
'lot': lot}
|
'lot': lot}
|
||||||
return flask.render_template(self.template_name, **context)
|
return self.context
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceListView(DeviceListMix):
|
||||||
|
|
||||||
|
def dispatch_request(self, lot_id=None):
|
||||||
|
self.get_context(lot_id)
|
||||||
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
|
||||||
class DeviceDetailsView(View):
|
class DeviceDetailsView(View):
|
||||||
|
@ -167,20 +173,38 @@ class CreateDeviceView(View):
|
||||||
class NewActionView(View):
|
class NewActionView(View):
|
||||||
methods = ['POST']
|
methods = ['POST']
|
||||||
decorators = [login_required]
|
decorators = [login_required]
|
||||||
|
_form = NewActionForm
|
||||||
|
|
||||||
def dispatch_request(self):
|
def dispatch_request(self):
|
||||||
form = NewActionForm()
|
self.form = self._form()
|
||||||
# import pdb; pdb.set_trace()
|
if self.form.validate_on_submit():
|
||||||
next_url = url_for('inventory.devices.devicelist')
|
self.form.save()
|
||||||
if form.validate_on_submit():
|
if self.form.lot.data:
|
||||||
# form.save()
|
next_url = url_for('inventory.devices.lotdevicelist', id=self.form.lot.data)
|
||||||
if form.lot.data:
|
|
||||||
next_url = url_for('inventory.devices.lotdevicelist', id=form.lot.data)
|
|
||||||
|
|
||||||
|
next_url = url_for('inventory.devices.devicelist')
|
||||||
return flask.redirect(next_url)
|
return flask.redirect(next_url)
|
||||||
|
|
||||||
|
|
||||||
|
class NewAllocateView(NewActionView, DeviceListMix):
|
||||||
|
methods = ['POST']
|
||||||
|
decorators = [login_required]
|
||||||
|
template_name = 'inventory/device_list.html'
|
||||||
|
_form = AllocateForm
|
||||||
|
|
||||||
|
def dispatch_request(self):
|
||||||
|
dispatch = super().dispatch_request()
|
||||||
|
if self.form.validate_on_submit():
|
||||||
|
return dispatch
|
||||||
|
|
||||||
|
lot_id = self.form.lot.data
|
||||||
|
self.get_context(lot_id)
|
||||||
|
self.context['form_new_allocate'] = self.form
|
||||||
|
return flask.render_template(self.template_name, **self.context)
|
||||||
|
|
||||||
|
|
||||||
devices.add_url_rule('/action/add/', view_func=NewActionView.as_view('action_add'))
|
devices.add_url_rule('/action/add/', view_func=NewActionView.as_view('action_add'))
|
||||||
|
devices.add_url_rule('/action/allocate/add/', view_func=NewAllocateView.as_view('allocate_add'))
|
||||||
devices.add_url_rule('/device/', view_func=DeviceListView.as_view('devicelist'))
|
devices.add_url_rule('/device/', view_func=DeviceListView.as_view('devicelist'))
|
||||||
devices.add_url_rule('/device/<string:id>/', view_func=DeviceDetailsView.as_view('device_details'))
|
devices.add_url_rule('/device/<string:id>/', view_func=DeviceDetailsView.as_view('device_details'))
|
||||||
devices.add_url_rule('/lot/<string:lot_id>/device/', view_func=DeviceListView.as_view('lotdevicelist'))
|
devices.add_url_rule('/lot/<string:lot_id>/device/', view_func=DeviceListView.as_view('lotdevicelist'))
|
||||||
|
|
|
@ -215,13 +215,13 @@ class Action(Thing):
|
||||||
|
|
||||||
@validates('end_time')
|
@validates('end_time')
|
||||||
def validate_end_time(self, _, end_time: datetime):
|
def validate_end_time(self, _, end_time: datetime):
|
||||||
if self.start_time and end_time <= self.start_time:
|
if self.start_time and end_time < self.start_time:
|
||||||
raise ValidationError('The action cannot finish before it starts.')
|
raise ValidationError('The action cannot finish before it starts.')
|
||||||
return end_time
|
return end_time
|
||||||
|
|
||||||
@validates('start_time')
|
@validates('start_time')
|
||||||
def validate_start_time(self, _, start_time: datetime):
|
def validate_start_time(self, _, start_time: datetime):
|
||||||
if self.end_time and start_time >= self.end_time:
|
if self.end_time and start_time > self.end_time:
|
||||||
raise ValidationError('The action cannot start after it finished.')
|
raise ValidationError('The action cannot start after it finished.')
|
||||||
return start_time
|
return start_time
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,7 @@ class ActionView(View):
|
||||||
return erased.post()
|
return erased.post()
|
||||||
|
|
||||||
a = resource_def.schema.load(json)
|
a = resource_def.schema.load(json)
|
||||||
|
import pdb; pdb.set_trace()
|
||||||
Model = db.Model._decl_class_registry.data[json['type']]()
|
Model = db.Model._decl_class_registry.data[json['type']]()
|
||||||
action = Model(**a)
|
action = Model(**a)
|
||||||
db.session.add(action)
|
db.session.add(action)
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$(".deviceSelect").on("change", deviceSelect);
|
var show_action_form = $("#allocateModal").data('show-action-form');
|
||||||
// $('#selectLot').selectpicker();
|
if (show_action_form != "None") {
|
||||||
|
$("#allocateModal .btn-primary").show();
|
||||||
|
newAllocate(show_action_form);
|
||||||
|
} else {
|
||||||
|
$(".deviceSelect").on("change", deviceSelect);
|
||||||
|
}
|
||||||
|
// $('#selectLot').selectpicker();
|
||||||
})
|
})
|
||||||
|
|
||||||
function deviceSelect() {
|
function deviceSelect() {
|
||||||
|
@ -17,19 +23,15 @@ function deviceSelect() {
|
||||||
$("#actionModal .btn-primary").hide();
|
$("#actionModal .btn-primary").hide();
|
||||||
} else {
|
} else {
|
||||||
$("#addingLotModal .text-danger").hide();
|
$("#addingLotModal .text-danger").hide();
|
||||||
$("#addingLotModal .btn-primary").removeClass('d-none');
|
|
||||||
$("#addingLotModal .btn-primary").show();
|
$("#addingLotModal .btn-primary").show();
|
||||||
|
|
||||||
$("#removeLotModal .text-danger").hide();
|
$("#removeLotModal .text-danger").hide();
|
||||||
$("#removeLotModal .btn-primary").removeClass('d-none');
|
|
||||||
$("#removeLotModal .btn-primary").show();
|
$("#removeLotModal .btn-primary").show();
|
||||||
|
|
||||||
$("#actionModal .text-danger").hide();
|
$("#actionModal .text-danger").hide();
|
||||||
$("#actionModal .btn-primary").removeClass('d-none');
|
|
||||||
$("#actionModal .btn-primary").show();
|
$("#actionModal .btn-primary").show();
|
||||||
|
|
||||||
$("#allocateModal .text-danger").hide();
|
$("#allocateModal .text-danger").hide();
|
||||||
$("#allocateModal .btn-primary").removeClass('d-none');
|
|
||||||
$("#allocateModal .btn-primary").show();
|
$("#allocateModal .btn-primary").show();
|
||||||
}
|
}
|
||||||
$.map($(".devicesList"), function(x) {
|
$.map($(".devicesList"), function(x) {
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
<input type="submit" class="btn btn-primary d-none" value="Create" />
|
<input type="submit" class="btn btn-primary" style="display: none;" value="Create" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
<input type="submit" class="btn btn-primary d-none" value="Save changes" />
|
<input type="submit" class="btn btn-primary" style="display: none;" value="Save changes" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<div class="modal fade" id="allocateModal" tabindex="-1" style="display: none;" aria-hidden="true">
|
<div class="modal fade" id="allocateModal" tabindex="-1" style="display: none;" aria-hidden="true"
|
||||||
|
data-show-action-form="{{ form_new_allocate.type.data }}">
|
||||||
<div class="modal-dialog modal-fullscreen">
|
<div class="modal-dialog modal-fullscreen">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
|
||||||
|
@ -7,26 +8,26 @@
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="{{ url_for('inventory.devices.action_add') }}" method="post">
|
<form action="{{ url_for('inventory.devices.allocate_add') }}" method="post">
|
||||||
{{ form_new_allocate.csrf_token }}
|
{{ form_new_allocate.csrf_token }}
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p class="text-danger">
|
<p class="text-danger" id="pol" style="display: none;">
|
||||||
You need select first some device before to do one action
|
You need select first some device before to do one action
|
||||||
</p>
|
</p>
|
||||||
{% for field in form_new_action %}
|
{% for field in form_new_allocate %}
|
||||||
{% if field != form_new_action.csrf_token %}
|
{% if field != form_new_allocate.csrf_token %}
|
||||||
{% if field == form_new_action.devices %}
|
{% if field == form_new_allocate.devices %}
|
||||||
{{ field(class_="devicesList") }}
|
{{ field(class_="devicesList") }}
|
||||||
{% elif field == form_new_action.lot %}
|
{% elif field == form_new_allocate.lot %}
|
||||||
{{ field(class_="form-control") }}
|
{{ field(class_="form-control") }}
|
||||||
{% elif field == form_new_action.type %}
|
{% elif field == form_new_allocate.type %}
|
||||||
{{ field(class_="form-control") }}
|
{{ field(class_="form-control") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
{{ field.label(class_="form-label") }}
|
{{ field.label(class_="form-label") }}
|
||||||
{{ field(class_="form-control") }}
|
{{ field(class_="form-control") }}
|
||||||
{% if field.errors %}
|
{% if field.errors %}
|
||||||
<p class="text-danger">
|
<p class="text-danger {% if field.errors %}field-error{% endif %}">
|
||||||
{% for error in field.errors %}
|
{% for error in field.errors %}
|
||||||
{{ error }}<br/>
|
{{ error }}<br/>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -41,7 +42,7 @@
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
<input type="submit" class="btn btn-primary d-none" value="Create" />
|
<input type="submit" class="btn btn-primary" style="display: none;" value="Create" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnLots"">
|
<ul class="dropdown-menu" aria-labelledby="btnLots">
|
||||||
<li>
|
<li>
|
||||||
<a href="javascript:void()" class="dropdown-item" data-bs-toggle="modal" data-bs-target="#addingLotModal">
|
<a href="javascript:void()" class="dropdown-item" data-bs-toggle="modal" data-bs-target="#addingLotModal">
|
||||||
<i class="bi bi-plus"></i>
|
<i class="bi bi-plus"></i>
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
</button>
|
</button>
|
||||||
<span class="d-none" id="activeActionModal" data-bs-toggle="modal" data-bs-target="#actionModal"></span>
|
<span class="d-none" id="activeActionModal" data-bs-toggle="modal" data-bs-target="#actionModal"></span>
|
||||||
<span class="d-none" id="activeAllocateModal" data-bs-toggle="modal" data-bs-target="#allocateModal"></span>
|
<span class="d-none" id="activeAllocateModal" data-bs-toggle="modal" data-bs-target="#allocateModal"></span>
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnActions"">
|
<ul class="dropdown-menu" aria-labelledby="btnActions">
|
||||||
<li>
|
<li>
|
||||||
Status actions
|
Status actions
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
<input type="submit" class="btn btn-primary d-none" value="Save changes" />
|
<input type="submit" class="btn btn-primary" style="display: none;" value="Save changes" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
Reference in a new issue