added current state to device details

This commit is contained in:
Thomas Nahuel Rusiecki 2024-12-06 17:48:06 -03:00 committed by Cayo Puigdefabregas
parent 6bd822f732
commit 5b33bf000f
3 changed files with 109 additions and 69 deletions

22
action/forms.py Normal file
View file

@ -0,0 +1,22 @@
from django import forms
from .models import State
class AddStateForm(forms.Form):
add_note = forms.BooleanField(required=False)
note = forms.CharField(
required=False,
widget=forms.Textarea(attrs={'rows': 4, 'maxlength': 200, 'placeholder': 'Max 200 characters'}),
)
state_id = forms.IntegerField(required=True, widget=forms.HiddenInput())
snapshot_uuid = forms.UUIDField(required=True, widget=forms.HiddenInput())
def clean(self):
cleaned_data = super().clean()
add_note = cleaned_data.get('add_note')
note = cleaned_data.get('note')
if add_note == True and not note:
self.add_error('note', 'Please enter a note if you checked "Add a note".')
return cleaned_data

View file

@ -63,77 +63,91 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="tab-content pt-4">
<div class="tab-content pt-2">
<div class="tab-pane fade show active" id="details"> <div class="tab-pane fade show active" id="details">
<h5 class="card-title">{% trans 'Details' %}</h5> <div class="row">
<div class="row mb-3"> <!-- Device Details -->
<div class="col-lg-3 col-md-4 label">Phid</div> <div class="col-lg-6">
<div class="col-lg-9 col-md-8">{{ object.id }}</div> <h5 class="card-title">{% trans 'Details' %}</h5>
</div> <hr>
<div class="row mb-3">
{% if object.is_eraseserver %} <div class="col-sm-4 text-muted fw-bold">{% trans 'Phid' %}</div>
<div class="row mb-3"> <div class="col-sm-8">{{ object.id }}</div>
<div class="col-lg-3 col-md-4 label">
{% trans 'Is a erase server' %}
</div> </div>
<div class="col-lg-9 col-md-8"></div>
</div>
{% endif %}
<div class="row mb-1"> {% if object.is_eraseserver %}
<div class="col-lg-3 col-md-4 label">Type</div> <div class="row mb-3">
<div class="col-lg-9 col-md-8">{{ object.type }}</div> <div class="col-sm-4 text-muted fw-bold">{% trans 'Is an erase server' %}</div>
</div> <div class="col-sm-8">{% trans 'Yes' %}</div>
</div>
{% endif %}
{% if object.is_websnapshot and object.last_user_evidence %} <div class="row mb-3">
{% for k, v in object.last_user_evidence %} <div class="col-sm-4 text-muted fw-bold">{% trans 'Type' %}</div>
<div class="row mb-1"> <div class="col-sm-8">{{ object.type }}</div>
<div class="col-lg-3 col-md-4 label">{{ k }}</div>
<div class="col-lg-9 col-md-8">{{ v|default:'' }}</div>
</div> </div>
{% endfor %}
{% else %} {% if object.is_websnapshot and object.last_user_evidence %}
<div class="row mb-1"> {% for k, v in object.last_user_evidence.items %}
<div class="col-lg-3 col-md-4 label"> <div class="row mb-3">
{% trans 'Manufacturer' %} <div class="col-sm-4 text-muted fw-bold">{{ k }}</div>
<div class="col-sm-8">{{ v|default:'' }}</div>
</div>
{% endfor %}
{% else %}
<div class="row mb-3">
<div class="col-sm-4 text-muted fw-bold">{% trans 'Manufacturer' %}</div>
<div class="col-sm-8">{{ object.manufacturer|default:'' }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4 text-muted fw-bold">{% trans 'Model' %}</div>
<div class="col-sm-8">{{ object.model|default:'' }}</div>
</div>
<div class="row mb-3">
<div class="col-sm-4 text-muted fw-bold">{% trans 'Serial Number' %}</div>
<div class="col-sm-8">{{ object.serial_number|default:'' }}</div>
</div>
{% endif %}
<div class="row mb-3">
<div class="col-sm-4 text-muted fw-bold">{% trans 'Identifiers' %}</div>
<div class="col-sm-8">
{% for chid in object.hids %}
<div>{{ chid|default:'' }}</div>
{% endfor %}
</div>
</div> </div>
<div class="col-lg-9 col-md-8">{{ object.manufacturer|default:'' }}</div>
</div> </div>
<div class="row mb-1">
<div class="col-lg-3 col-md-4 label">
{% trans 'Model' %}
</div>
<div class="col-lg-9 col-md-8">{{ object.model|default:'' }}</div>
</div>
<div class="row mb-1"> <!-- Device Current State -->
<div class="col-lg-3 col-md-4 label"> <div class="col-lg-6">
{% trans 'Version' %} <h5 class="card-title">{% trans 'Current State' %}</h5>
<hr>
<div class="row mb-3">
<div class="col-sm-4 text-muted fw-bold">{% trans 'State' %}</div>
<div class="col-sm-8">{{ device_states.0.state }}</div>
</div> </div>
<div class="col-lg-9 col-md-8">{{ object.version|default:'' }}</div> <div class="row mb-3">
</div> <div class="col-sm-4 text-muted fw-bold">{% trans 'Date' %}</div>
<div class="col-sm-8">{{ device_states.0.date|date:"SHORT_DATETIME_FORMAT" }}</div>
<div class="row mb-1">
<div class="col-lg-3 col-md-4 label">
{% trans 'Serial Number' %}
</div> </div>
<div class="col-lg-9 col-md-8">{{ object.serial_number|default:'' }}</div>
</div>
{% endif %}
<div class="row mb-3"> <!-- TODO: display last note? -->
<div class="col-lg-3 col-md-4 label"> {% if last_note %}
{% trans 'Identifiers' %} <div class="row mb-3">
<div class="col-sm-4 text-muted fw-bold">{% trans 'Note' %}</div>
<div class="col-sm-8">{{ object.last_state.note }}</div>
</div>
{% endif %}
</div> </div>
</div> </div>
{% for chid in object.hids %}
<div class="row mb-3">
<div class="col">{{ chid|default:'' }}</div>
</div>
{% endfor %}
</div> </div>
</div>
<!-- End of Details -->
<div class="tab-pane fade" id="user_properties"> <div class="tab-pane fade" id="user_properties">
<div class="btn-group mt-1 mb-3"> <div class="btn-group mt-1 mb-3">
@ -174,14 +188,14 @@
<i class="bi bi-trash"></i> <i class="bi bi-trash"></i>
</button> </button>
</div> </div>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
<!-- pop up modal for delete confirmation --> <!-- pop up modal for delete confirmation -->
{% for a in object.get_user_properties %} {% for a in object.get_user_properties %}
<div class="modal fade" id="deleteModal{{ a.id }}" tabindex="-1" aria-labelledby="deleteModalLabel{{ a.id }}" aria-hidden="true"> <div class="modal fade" id="deleteModal{{ a.id }}" tabindex="-1" aria-labelledby="deleteModalLabel{{ a.id }}" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
@ -234,7 +248,7 @@
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
@ -370,14 +384,14 @@
<i class="bi bi-arrow-right-circle text-danger me-2"></i> <i class="bi bi-arrow-right-circle text-danger me-2"></i>
<span class="text-danger fw-bold me-2">{% trans "From:" %}</span> <span class="text-danger fw-bold me-2">{% trans "From:" %}</span>
<span class="text-danger fw-italic">state_placeholder</span> <span class="text-danger fw-italic">state_placeholder</span>
</div> </div>
<div class="d-flex align-items-center mt-2"> <div class="d-flex align-items-center mt-2">
<i class="bi bi-arrow-right-circle text-success me-2"></i> <i class="bi bi-arrow-right-circle text-success me-2"></i>
<span class="text-success fw-bold me-2">{% trans "To:" %}</span> <span class="text-success fw-bold me-2">{% trans "To:" %}</span>
<span class="text-success fw-italic">{{ state.state }}</span> <span class="text-success fw-italic">{{ state.state }}</span>
</div> </div>
</div> </div>
<div class="form-check form-switch mt-3 d-flex justify-content-end"> <div class="form-check form-switch mt-3 d-flex justify-content-end">
<label class="form-check-label font-monospace" for="addNoteCheckbox{{ state.id }}"> <label class="form-check-label font-monospace" for="addNoteCheckbox{{ state.id }}">
@ -385,22 +399,23 @@
</label> </label>
<input class="form-check-input ms-2" type="checkbox" id="addNoteCheckbox{{ state.id }}" data-bs-toggle="collapse" data-bs-target="#collapseInput{{ state.id }}" name="add_note"> <input class="form-check-input ms-2" type="checkbox" id="addNoteCheckbox{{ state.id }}" data-bs-toggle="collapse" data-bs-target="#collapseInput{{ state.id }}" name="add_note">
</div> </div>
<div class="mb-3 mt-2 collapse" id="collapseInput{{ state.id }}"> <div class="mb-3 mt-2 collapse" id="collapseInput{{ state.id }}">
<textarea type="text" class="form-control" id="stateNote{{ state.id }}" name="note" rows="4" maxlength="200" placeholder="{% trans "Max 200 characters" %}"></textarea> <textarea type="text" class="form-control" id="stateNote{{ state.id }}" name="note" rows="4" maxlength="200" placeholder="{% trans "Max 200 characters" %}"></textarea>
</div> </div>
<input type="hidden" name="state_id" value="{{ state.id }}"> <input type="hidden" name="state_id" value="{{ state.id }}">
<input type="hidden" name="snapshot_uuid" value="{{ object.last_uuid }}">
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans "Cancel" %}</button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
<button type="submit" class="btn btn-primary">{% trans "Add State" %}</button> <button type="submit" class="btn btn-primary">{% trans "Add State" %}</button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

View file

@ -13,7 +13,7 @@ from django.views.generic.edit import (
DeleteView, DeleteView,
) )
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from action.models import StateDefinition from action.models import StateDefinition, State
from dashboard.mixins import DashboardView, Http403 from dashboard.mixins import DashboardView, Http403
from evidence.models import UserProperty, SystemProperty, Property from evidence.models import UserProperty, SystemProperty, Property
from lot.models import LotTag from lot.models import LotTag
@ -117,12 +117,15 @@ class DetailsView(DashboardView, TemplateView):
uuid__in=self.object.uuids, uuid__in=self.object.uuids,
type=PROOF_TYPE["IssueDPP"] type=PROOF_TYPE["IssueDPP"]
) )
last_evidence= self.object.get_last_evidence(),
uuid=self.object.last_uuid()
context.update({ context.update({
'object': self.object, 'object': self.object,
'snapshot': self.object.get_last_evidence(), 'snapshot': last_evidence,
'lot_tags': lot_tags, 'lot_tags': lot_tags,
'dpps': dpps, 'dpps': dpps,
"state_definitions": StateDefinition.objects.filter(institution=self.request.user.institution).order_by('order'), "state_definitions": StateDefinition.objects.filter(institution=self.request.user.institution).order_by('order'),
"device_states": State.objects.filter(snapshot_uuid=uuid).order_by('date'),
}) })
return context return context