Merge branch 'main' into feature/90-implement-public-website-for-device
This commit is contained in:
commit
49b3931ac9
|
@ -70,10 +70,17 @@ class SearchView(InventaryMixin):
|
|||
return self.search_hids(query, offset, limit)
|
||||
|
||||
devices = []
|
||||
dev_id = []
|
||||
|
||||
for x in matches:
|
||||
devices.append(self.get_annotations(x))
|
||||
# devices.append(self.get_annotations(x))
|
||||
dev = self.get_annotations(x)
|
||||
if dev.id not in dev_id:
|
||||
devices.append(dev)
|
||||
dev_id.append(dev.id)
|
||||
|
||||
count = matches.size()
|
||||
# TODO fix of pagination, the count is not correct
|
||||
return devices, count
|
||||
|
||||
def get_annotations(self, xp):
|
||||
|
|
|
@ -108,6 +108,22 @@ class Device:
|
|||
return
|
||||
annotation = annotations.first()
|
||||
self.last_evidence = Evidence(annotation.uuid)
|
||||
|
||||
def is_eraseserver(self):
|
||||
if not self.uuids:
|
||||
self.get_uuids()
|
||||
if not self.uuids:
|
||||
return False
|
||||
|
||||
annotation = Annotation.objects.filter(
|
||||
uuid__in=self.uuids,
|
||||
owner=self.owner,
|
||||
type=Annotation.Type.ERASE_SERVER
|
||||
).first()
|
||||
|
||||
if annotation:
|
||||
return True
|
||||
return False
|
||||
|
||||
def last_uuid(self):
|
||||
return self.uuids[0]
|
||||
|
|
|
@ -2,38 +2,126 @@
|
|||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ object.shortid }}</h3>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ object.shortid }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<ul class="nav nav-tabs nav-tabs-bordered">
|
||||
<li class="nav-items">
|
||||
<a href="#details" class="nav-link active" data-bs-toggle="tab" data-bs-target="#details">{% trans "General details" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#annotations" class="nav-link" data-bs-toggle="tab" data-bs-target="#annotations">{% trans "User annotations" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#documents" class="nav-link" data-bs-toggle="tab" data-bs-target="#documents">{% trans "Documents" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#lots" class="nav-link" data-bs-toggle="tab" data-bs-target="#lots">{% trans "Lots" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#components" class="nav-link" data-bs-toggle="tab" data-bs-target="#components">{% trans "Components" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#evidences" class="nav-link" data-bs-toggle="tab" data-bs-target="#evidences">{% trans "Evidences" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#web" class="nav-link" href="">Web</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-content pt-2">
|
||||
|
||||
<div class="tab-pane fade show active" id="details">
|
||||
<h5 class="card-title">{% trans "Details" %}</h5>
|
||||
<div class="row mb-3">
|
||||
<div class="col-lg-3 col-md-4 label ">Phid</div>
|
||||
<div class="col-lg-9 col-md-8">{{ object.id }}</div>
|
||||
</div>
|
||||
|
||||
{% if object.is_eraseserver %}
|
||||
<div class="row mb-3">
|
||||
<div class="col-lg-3 col-md-4 label">{% trans "Is a erase server" %}</div>
|
||||
<div class="col-lg-9 col-md-8"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 label ">{% trans "Type" %}</div>
|
||||
<div class="col-lg-9 col-md-8">{{ object.type }}</div>
|
||||
</div>
|
||||
|
||||
{% if object.is_websnapshot %}
|
||||
{% for k, v in object.last_user_evidence %}
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 label">{{ k }}</div>
|
||||
<div class="col-lg-9 col-md-8">{{ v|default:"" }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 label">Manufacturer</div>
|
||||
<div class="col-lg-9 col-md-8">{{ object.manufacturer|default:"" }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 label">Model</div>
|
||||
<div class="col-lg-9 col-md-8">{{ object.model|default:"" }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 label">Serial Number</div>
|
||||
<div class="col-lg-9 col-md-8">{{ object.last_evidence.doc.device.serialNumber|default:"" }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-lg-3 col-md-4 label">Identifiers</div>
|
||||
</div>
|
||||
{% for chid in object.hids %}
|
||||
<div class="row">
|
||||
<div class="col">{{ chid |default:"" }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<ul class="nav nav-tabs nav-tabs-bordered">
|
||||
<li class="nav-items">
|
||||
<a href="#details" class="nav-link active" data-bs-toggle="tab" data-bs-target="#details">General details</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#annotations" class="nav-link" data-bs-toggle="tab" data-bs-target="#annotations">User annotations</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#documents" class="nav-link" data-bs-toggle="tab" data-bs-target="#documents">Documents</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#lots" class="nav-link" data-bs-toggle="tab" data-bs-target="#lots">Lots</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#components" class="nav-link" data-bs-toggle="tab" data-bs-target="#components">Components</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="#evidences" class="nav-link" data-bs-toggle="tab" data-bs-target="#evidences">Evidences</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a class="nav-link" href="{% url 'device:device_web' object.id %}">Web</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-pane fade profile-overview" id="annotations">
|
||||
<div class="btn-group dropdown ml-1 mt-1" uib-dropdown="">
|
||||
<a href="{% url 'device:add_annotation' object.pk %}" class="btn btn-primary">
|
||||
<i class="bi bi-plus"></i>
|
||||
{% trans "Add new annotation" %}
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h5 class="card-title mt-2">{% trans "Annotations" %}</h5>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Key</th>
|
||||
<th scope="col">Value</th>
|
||||
<th scope="col" data-type="date" data-format="YYYY-MM-DD hh:mm">Created on</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for a in object.get_user_annotations %}
|
||||
<tr>
|
||||
<td>{{ a.key }}</td>
|
||||
<td>{{ a.value }}</td>
|
||||
<td>{{ a.created }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-content pt-2">
|
||||
<div class="tab-pane fade show active" id="details">
|
||||
|
|
|
@ -162,3 +162,56 @@ class ImportForm(forms.Form):
|
|||
return table
|
||||
|
||||
return
|
||||
|
||||
|
||||
class EraseServerForm(forms.Form):
|
||||
erase_server = forms.BooleanField(label=_("Is a Erase Server"), required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.pk = None
|
||||
self.uuid = kwargs.pop('uuid', None)
|
||||
self.user = kwargs.pop('user')
|
||||
instance = Annotation.objects.filter(
|
||||
uuid=self.uuid,
|
||||
type=Annotation.Type.ERASE_SERVER,
|
||||
key='ERASE_SERVER',
|
||||
owner=self.user.institution
|
||||
).first()
|
||||
|
||||
if instance:
|
||||
kwargs["initial"]["erase_server"] = instance.value
|
||||
self.pk = instance.pk
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
self.erase_server = self.cleaned_data.get('erase_server', False)
|
||||
self.instance = Annotation.objects.filter(
|
||||
uuid=self.uuid,
|
||||
type=Annotation.Type.ERASE_SERVER,
|
||||
key='ERASE_SERVER',
|
||||
owner=self.user.institution
|
||||
).first()
|
||||
|
||||
return True
|
||||
|
||||
def save(self, user, commit=True):
|
||||
if not commit:
|
||||
return
|
||||
|
||||
if not self.erase_server:
|
||||
if self.instance:
|
||||
self.instance.delete()
|
||||
return
|
||||
|
||||
if self.instance:
|
||||
return
|
||||
|
||||
Annotation.objects.create(
|
||||
uuid=self.uuid,
|
||||
type=Annotation.Type.ERASE_SERVER,
|
||||
key='ERASE_SERVER',
|
||||
value=self.erase_server,
|
||||
owner=self.user.institution,
|
||||
user=self.user
|
||||
)
|
||||
|
|
25
evidence/migrations/0002_alter_annotation_type.py
Normal file
25
evidence/migrations/0002_alter_annotation_type.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 5.0.6 on 2024-10-28 12:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("evidence", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="annotation",
|
||||
name="type",
|
||||
field=models.SmallIntegerField(
|
||||
choices=[
|
||||
(0, "System"),
|
||||
(1, "User"),
|
||||
(2, "Document"),
|
||||
(3, "EraseServer"),
|
||||
]
|
||||
),
|
||||
),
|
||||
]
|
|
@ -14,6 +14,7 @@ class Annotation(models.Model):
|
|||
SYSTEM= 0, "System"
|
||||
USER = 1, "User"
|
||||
DOCUMENT = 2, "Document"
|
||||
ERASE_SERVER = 3, "EraseServer"
|
||||
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
uuid = models.UUIDField()
|
||||
|
|
|
@ -12,13 +12,16 @@
|
|||
<div class="col">
|
||||
<ul class="nav nav-tabs nav-tabs-bordered">
|
||||
<li class="nav-items">
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#device">Devices</button>
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#device">{% trans "Devices" %}</button>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tag">Tag</button>
|
||||
<li class="nav-items">
|
||||
<a href="{% url 'evidence:download' object.uuid %}" class="nav-link">Download File</a>
|
||||
<a href="#tag" class="nav-link" data-bs-toggle="tab" data-bs-target="#tag">{% trans "Tag" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="{% url 'evidence:erase_server' object.uuid %}" class="nav-link">{% trans "Erase Server" %}</a>
|
||||
</li>
|
||||
<li class="nav-items">
|
||||
<a href="{% url 'evidence:download' object.uuid %}" class="nav-link">{% trans "Download File" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -83,3 +86,24 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extrascript %}
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Obtener el hash de la URL (ejemplo: #components)
|
||||
const hash = window.location.hash;
|
||||
|
||||
// Verificar si hay un hash en la URL
|
||||
if (hash) {
|
||||
// Buscar el botón o enlace que corresponde al hash y activarlo
|
||||
const tabTrigger = document.querySelector(`[data-bs-target="${hash}"]`);
|
||||
|
||||
if (tabTrigger) {
|
||||
// Crear una instancia de tab de Bootstrap para activar el tab
|
||||
const tab = new bootstrap.Tab(tabTrigger);
|
||||
tab.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -18,6 +18,7 @@ urlpatterns = [
|
|||
path("upload", views.UploadView.as_view(), name="upload"),
|
||||
path("import", views.ImportView.as_view(), name="import"),
|
||||
path("<uuid:pk>", views.EvidenceView.as_view(), name="details"),
|
||||
path("<uuid:pk>/eraseserver", views.EraseServerView.as_view(), name="erase_server"),
|
||||
path("<uuid:pk>/download", views.DownloadEvidenceView.as_view(), name="download"),
|
||||
path('annotation/<int:pk>/del', views.AnnotationDeleteView.as_view(), name='delete_annotation'),
|
||||
]
|
||||
|
|
|
@ -11,18 +11,14 @@ from django.views.generic.edit import (
|
|||
FormView,
|
||||
)
|
||||
|
||||
|
||||
from dashboard.mixins import DashboardView, Http403
|
||||
from evidence.models import Evidence, Annotation
|
||||
from evidence.forms import UploadForm, UserTagForm, ImportForm
|
||||
# from django.shortcuts import render
|
||||
# from rest_framework import viewsets
|
||||
# from snapshot.serializers import SnapshotSerializer
|
||||
|
||||
|
||||
# class SnapshotViewSet(viewsets.ModelViewSet):
|
||||
# queryset = Snapshot.objects.all()
|
||||
# serializer_class = SnapshotSerializer
|
||||
from evidence.forms import (
|
||||
UploadForm,
|
||||
UserTagForm,
|
||||
ImportForm,
|
||||
EraseServerForm
|
||||
)
|
||||
|
||||
|
||||
class ListEvidencesView(DashboardView, TemplateView):
|
||||
|
@ -167,3 +163,48 @@ class AnnotationDeleteView(DashboardView, DeleteView):
|
|||
|
||||
|
||||
return redirect(url_name, **kwargs_view)
|
||||
|
||||
|
||||
class EraseServerView(DashboardView, FormView):
|
||||
template_name = "ev_eraseserver.html"
|
||||
section = "evidences"
|
||||
title = _("Evidences")
|
||||
breadcrumb = "Evidences / Details"
|
||||
success_url = reverse_lazy('evidence:list')
|
||||
form_class = EraseServerForm
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.pk = kwargs['pk']
|
||||
self.object = Evidence(self.pk)
|
||||
if self.object.owner != self.request.user.institution:
|
||||
raise Http403
|
||||
|
||||
self.object.get_annotations()
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context.update({
|
||||
'object': self.object,
|
||||
})
|
||||
return context
|
||||
|
||||
def get_form_kwargs(self):
|
||||
self.pk = self.kwargs.get('pk')
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['uuid'] = self.pk
|
||||
kwargs['user'] = self.request.user
|
||||
return kwargs
|
||||
|
||||
def form_valid(self, form):
|
||||
form.save(self.request.user)
|
||||
response = super().form_valid(form)
|
||||
return response
|
||||
|
||||
def form_invalid(self, form):
|
||||
response = super().form_invalid(form)
|
||||
return response
|
||||
|
||||
def get_success_url(self):
|
||||
success_url = reverse_lazy('evidence:details', args=[self.pk])
|
||||
return success_url
|
||||
|
|
18
lot/migrations/0002_alter_lot_closed.py
Normal file
18
lot/migrations/0002_alter_lot_closed.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 5.0.6 on 2024-10-28 12:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("lot", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="lot",
|
||||
name="closed",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
Loading…
Reference in a new issue