From 0136a98ff5f62162e56d86797e114911f327b316 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Tue, 30 Jul 2024 13:37:08 +0200 Subject: [PATCH] add annotations in device and in lots --- dashboard/templates/unassigned_devices.html | 12 +-- dashboard/views.py | 7 +- device/forms.py | 12 ++- device/migrations/0002_device_model.py | 18 ---- device/migrations/0003_device_manufacturer.py | 18 ---- device/migrations/0004_delete_device.py | 18 ---- device/models.py | 24 ++++- device/templates/details.html | 29 +++--- device/templates/new_annotation.html | 45 +++++++++ device/urls.py | 1 + device/views.py | 47 +++++++--- dhub/urls.py | 2 +- evidence/management/commands/up_snapshots.py | 2 +- evidence/migrations/0001_initial.py | 9 +- .../migrations/0002_alter_annotation_type.py | 20 ++++ .../0002_remove_annotation_device.py | 17 ---- .../migrations/0003_alter_annotation_type.py | 20 ++++ evidence/models.py | 6 +- lot/migrations/0001_initial.py | 90 +++++++++++------- .../migrations/0002_lotannotation.py | 23 ++++- .../0002_remove_lot_devices_devicelot.py | 39 -------- lot/models.py | 13 +++ lot/templates/annotations.html | 48 ++++++++++ lot/templates/documents.html | 48 ++++++++++ lot/templates/new_annotation.html | 45 +++++++++ lot/urls.py | 4 + lot/views.py | 93 ++++++++++++++++++- 27 files changed, 502 insertions(+), 208 deletions(-) delete mode 100644 device/migrations/0002_device_model.py delete mode 100644 device/migrations/0003_device_manufacturer.py delete mode 100644 device/migrations/0004_delete_device.py create mode 100644 device/templates/new_annotation.html create mode 100644 evidence/migrations/0002_alter_annotation_type.py delete mode 100644 evidence/migrations/0002_remove_annotation_device.py create mode 100644 evidence/migrations/0003_alter_annotation_type.py rename device/migrations/0001_initial.py => lot/migrations/0002_lotannotation.py (55%) delete mode 100644 lot/migrations/0002_remove_lot_devices_devicelot.py create mode 100644 lot/templates/annotations.html create mode 100644 lot/templates/documents.html create mode 100644 lot/templates/new_annotation.html diff --git a/dashboard/templates/unassigned_devices.html b/dashboard/templates/unassigned_devices.html index df71266..afd65b6 100644 --- a/dashboard/templates/unassigned_devices.html +++ b/dashboard/templates/unassigned_devices.html @@ -7,21 +7,17 @@

{{ subtitle }}

- + - {% trans 'Lots' %} - - - - {% trans 'Actions' %} + {% trans 'Documents' %} {% trans 'Exports' %} - + - {% trans 'Labels' %} + {% trans 'Annotations' %}
diff --git a/dashboard/views.py b/dashboard/views.py index bf8f8e2..4a59a8f 100644 --- a/dashboard/views.py +++ b/dashboard/views.py @@ -1,12 +1,7 @@ -import json - from django.utils.translation import gettext_lazy as _ -from django.db.models import Count from dashboard.mixins import InventaryMixin, DetailsMixin from device.models import Device -from evidence.xapian import search -from evidence.models import Annotation -from lot.models import Lot, LotTag +from lot.models import Lot class UnassignedDevicesView(InventaryMixin): diff --git a/device/forms.py b/device/forms.py index cf42dbc..1ad0c6b 100644 --- a/device/forms.py +++ b/device/forms.py @@ -4,8 +4,8 @@ import hashlib import datetime from django import forms -from snapshot.models import Annotation -from snapshot.xapian import search, index +from evidence.models import Annotation +from evidence.xapian import search, index DEVICE_TYPES = [ ("Desktop", "Desktop"), @@ -27,13 +27,19 @@ DEVICE_TYPES = [ class DeviceForm(forms.Form): type = forms.ChoiceField(choices = DEVICE_TYPES, required=False) - amount = forms.IntegerField(required=True, initial=1) + amount = forms.IntegerField(required=False, initial=1) tag = forms.CharField(required=False) name = forms.CharField(required=False) value = forms.CharField(required=False) class BaseDeviceFormSet(forms.BaseFormSet): + def clean(self): + for x in self.cleaned_data: + if x.get("amount"): + return True + return False + def save(self, user, commit=True): self.user = user doc = {} diff --git a/device/migrations/0002_device_model.py b/device/migrations/0002_device_model.py deleted file mode 100644 index 0d02c3d..0000000 --- a/device/migrations/0002_device_model.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.6 on 2024-07-18 09:20 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("device", "0001_initial"), - ] - - operations = [ - migrations.AddField( - model_name="device", - name="model", - field=models.CharField(blank=True, max_length=256, null=True), - ), - ] diff --git a/device/migrations/0003_device_manufacturer.py b/device/migrations/0003_device_manufacturer.py deleted file mode 100644 index 511b7c1..0000000 --- a/device/migrations/0003_device_manufacturer.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.6 on 2024-07-18 09:54 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("device", "0002_device_model"), - ] - - operations = [ - migrations.AddField( - model_name="device", - name="manufacturer", - field=models.CharField(blank=True, max_length=256, null=True), - ), - ] diff --git a/device/migrations/0004_delete_device.py b/device/migrations/0004_delete_device.py deleted file mode 100644 index 10cbd01..0000000 --- a/device/migrations/0004_delete_device.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.6 on 2024-07-18 17:30 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("device", "0003_device_manufacturer"), - ("lot", "0002_remove_lot_devices_devicelot"), - ("snapshot", "0002_remove_annotation_device"), - ] - - operations = [ - migrations.DeleteModel( - name="Device", - ), - ] diff --git a/device/models.py b/device/models.py index a29f8c4..aa0b95f 100644 --- a/device/models.py +++ b/device/models.py @@ -56,10 +56,32 @@ class Device: self.owner = self.annotations[0].owner return self.annotations + + def get_user_annotations(self): + if not self.uuids: + self.get_uuids() + + annotations = Annotation.objects.filter( + uuid__in=self.uuids, + owner=self.owner, + type=Annotation.Type.USER + ) + return annotations + + def get_user_documents(self): + if not self.uuids: + self.get_uuids() + + annotations = Annotation.objects.filter( + uuid__in=self.uuids, + owner=self.owner, + type=Annotation.Type.DOCUMENT + ) + return annotations def get_uuids(self): for a in self.get_annotations(): - if not a.uuid in self.uuids: + if a.uuid not in self.uuids: self.uuids.append(a.uuid) def get_hids(self): diff --git a/device/templates/details.html b/device/templates/details.html index bba1ac9..38e1d78 100644 --- a/device/templates/details.html +++ b/device/templates/details.html @@ -90,7 +90,7 @@ -
Annotations
+
Annotations
@@ -102,8 +102,7 @@ - {% for a in object.annotations %} - {% if a.is_user_annotation %} + {% for a in object.get_user_annotations %} @@ -111,7 +110,6 @@ - {% endif %} {% endfor %} @@ -137,26 +135,35 @@
-
Documents
-
{{ a.key }} {{ a.value }}
+
Documents
+
- - - - + + + + {% for a in object.get_user_documents %} + + + + + + + + {% endfor %}
FileTypeDescriptionUploaded onKeyValueCreated on
{{ a.key }}{{ a.value }}{{ a.created }}
diff --git a/device/templates/new_annotation.html b/device/templates/new_annotation.html new file mode 100644 index 0000000..ac16bf8 --- /dev/null +++ b/device/templates/new_annotation.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block content %} +
+
+

{{ subtitle }}

+
+
+ +{% load django_bootstrap5 %} +
+ {% csrf_token %} + {% if form.errors %} + + {% endif %} + {{ form.management_form }} +
+
+
+
+ {% for f in form %} +
+
+ {% bootstrap_field f %} +
+
+ {% endfor %} +
+ + +
+ +{% endblock %} diff --git a/device/urls.py b/device/urls.py index 3d0b368..3d7c12b 100644 --- a/device/urls.py +++ b/device/urls.py @@ -8,4 +8,5 @@ urlpatterns = [ path("edit//", views.EditDeviceView.as_view(), name="edit"), path("/", views.DetailsView.as_view(), name="details"), path("/annotation/add", views.AddAnnotationView.as_view(), name="add_annotation"), + path("/document/add", views.AddDocumentView.as_view(), name="add_document"), ] diff --git a/device/views.py b/device/views.py index 68344b0..e89cc3c 100644 --- a/device/views.py +++ b/device/views.py @@ -10,8 +10,8 @@ from django.views.generic.edit import ( ) from django.views.generic.base import TemplateView from dashboard.mixins import DashboardView -from snapshot.models import Annotation -from snapshot.xapian import search +from evidence.models import Annotation +from evidence.xapian import search from lot.models import LotTag from device.models import Device from device.forms import DeviceFormSet @@ -95,14 +95,14 @@ class DetailsView(DashboardView, TemplateView): lot_tags = LotTag.objects.filter(owner=self.request.user) context.update({ 'object': self.object, - 'snapshot': self.object.get_last_snapshot(), + 'snapshot': self.object.get_last_evidence(), 'lot_tags': lot_tags, }) return context class AddAnnotationView(DashboardView, CreateView): - template_name = "new_device.html" + template_name = "new_annotation.html" title = _("New annotation") breadcrumb = "Device / New annotation" success_url = reverse_lazy('dashboard:unassigned_devices') @@ -110,25 +110,46 @@ class AddAnnotationView(DashboardView, CreateView): fields = ("key", "value") def form_valid(self, form): - self.device.get_annotations() - self.device.get_uuids() form.instance.owner = self.request.user - form.instance.device = self.device - form.instance.uuid = self.device.uuids[0] + form.instance.uuid = self.annotation.uuid form.instance.type = Annotation.Type.USER response = super().form_valid(form) return response def get_form_kwargs(self): pk = self.kwargs.get('pk') - self.device = get_object_or_404(Device, pk=pk) + self.annotation = Annotation.objects.filter( + owner=self.request.user, value=pk, type=Annotation.Type.SYSTEM + ).first() + if not self.annotation: + get_object_or_404(Annotation, pk=0, owner=self.request.user) self.success_url = reverse_lazy('device:details', args=[pk]) kwargs = super().get_form_kwargs() return kwargs - def get_success_url(self): - url = super().get_success_url() - import pdb; pdb.set_trace() - return url +class AddDocumentView(DashboardView, CreateView): + template_name = "new_annotation.html" + title = _("New Document") + breadcrumb = "Device / New document" + success_url = reverse_lazy('dashboard:unassigned_devices') + model = Annotation + fields = ("key", "value") + def form_valid(self, form): + form.instance.owner = self.request.user + form.instance.uuid = self.annotation.uuid + form.instance.type = Annotation.Type.DOCUMENT + response = super().form_valid(form) + return response + + def get_form_kwargs(self): + pk = self.kwargs.get('pk') + self.annotation = Annotation.objects.filter( + owner=self.request.user, value=pk, type=Annotation.Type.SYSTEM + ).first() + if not self.annotation: + get_object_or_404(Annotation, pk=0, owner=self.request.user) + self.success_url = reverse_lazy('device:details', args=[pk]) + kwargs = super().get_form_kwargs() + return kwargs diff --git a/dhub/urls.py b/dhub/urls.py index 9c77ee8..90252d9 100644 --- a/dhub/urls.py +++ b/dhub/urls.py @@ -21,7 +21,7 @@ urlpatterns = [ # path('api/', include('snapshot.urls')), path("", include("login.urls")), path("dashboard/", include("dashboard.urls")), - path("snapshot/", include("snapshot.urls")), + path("evidence/", include("evidence.urls")), path("device/", include("device.urls")), path("lot/", include("lot.urls")), ] diff --git a/evidence/management/commands/up_snapshots.py b/evidence/management/commands/up_snapshots.py index f8cf0ce..3cb12fa 100644 --- a/evidence/management/commands/up_snapshots.py +++ b/evidence/management/commands/up_snapshots.py @@ -4,7 +4,7 @@ import json from django.core.management.base import BaseCommand from django.contrib.auth import get_user_model -from snapshot.parse import Build +from evidence.parse import Build User = get_user_model() diff --git a/evidence/migrations/0001_initial.py b/evidence/migrations/0001_initial.py index 206cc8a..8b86718 100644 --- a/evidence/migrations/0001_initial.py +++ b/evidence/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.6 on 2024-07-17 14:57 +# Generated by Django 5.0.6 on 2024-07-27 16:23 import django.db.models.deletion from django.conf import settings @@ -10,7 +10,6 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("device", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] @@ -35,12 +34,6 @@ class Migration(migrations.Migration): ), ("key", models.CharField(max_length=256)), ("value", models.CharField(max_length=256)), - ( - "device", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="device.device" - ), - ), ( "owner", models.ForeignKey( diff --git a/evidence/migrations/0002_alter_annotation_type.py b/evidence/migrations/0002_alter_annotation_type.py new file mode 100644 index 0000000..df63e61 --- /dev/null +++ b/evidence/migrations/0002_alter_annotation_type.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.6 on 2024-07-29 14:58 + +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, "Action")] + ), + ), + ] diff --git a/evidence/migrations/0002_remove_annotation_device.py b/evidence/migrations/0002_remove_annotation_device.py deleted file mode 100644 index 326eca2..0000000 --- a/evidence/migrations/0002_remove_annotation_device.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.0.6 on 2024-07-18 17:30 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("snapshot", "0001_initial"), - ] - - operations = [ - migrations.RemoveField( - model_name="annotation", - name="device", - ), - ] diff --git a/evidence/migrations/0003_alter_annotation_type.py b/evidence/migrations/0003_alter_annotation_type.py new file mode 100644 index 0000000..4d18482 --- /dev/null +++ b/evidence/migrations/0003_alter_annotation_type.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.6 on 2024-07-29 15:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("evidence", "0002_alter_annotation_type"), + ] + + operations = [ + migrations.AlterField( + model_name="annotation", + name="type", + field=models.SmallIntegerField( + choices=[(0, "System"), (1, "User"), (2, "Document")] + ), + ), + ] diff --git a/evidence/models.py b/evidence/models.py index 576c172..ece8616 100644 --- a/evidence/models.py +++ b/evidence/models.py @@ -56,6 +56,7 @@ class Annotation(models.Model): class Type(models.IntegerChoices): SYSTEM= 0, "System" USER = 1, "User" + DOCUMENT = 2, "Document" created = models.DateTimeField(auto_now_add=True) uuid = models.UUIDField() @@ -68,8 +69,3 @@ class Annotation(models.Model): constraints = [ models.UniqueConstraint(fields=["type", "key", "uuid"], name="unique_type_key_uuid") ] - - def is_user_annotation(self): - if self.type == self.Type.USER: - return True - return False diff --git a/lot/migrations/0001_initial.py b/lot/migrations/0001_initial.py index cb398b2..28b3e8e 100644 --- a/lot/migrations/0001_initial.py +++ b/lot/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.6 on 2024-07-17 14:57 +# Generated by Django 5.0.6 on 2024-07-27 16:23 import django.db.models.deletion from django.conf import settings @@ -10,11 +10,58 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("device", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ + migrations.CreateModel( + name="Lot", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("updated", models.DateTimeField(auto_now=True)), + ("name", models.CharField(blank=True, max_length=64, null=True)), + ("code", models.CharField(blank=True, max_length=64, null=True)), + ("description", models.CharField(blank=True, max_length=64, null=True)), + ("closed", models.BooleanField(default=True)), + ( + "owner", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="DeviceLot", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("device_id", models.CharField(max_length=256)), + ( + "lot", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="lot.lot" + ), + ), + ], + ), migrations.CreateModel( name="LotTag", fields=[ @@ -37,38 +84,11 @@ class Migration(migrations.Migration): ), ], ), - migrations.CreateModel( - name="Lot", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("created", models.DateTimeField(auto_now_add=True)), - ("updated", models.DateTimeField(auto_now=True)), - ("name", models.CharField(blank=True, max_length=64, null=True)), - ("code", models.CharField(blank=True, max_length=64, null=True)), - ("description", models.CharField(blank=True, max_length=64, null=True)), - ("closed", models.BooleanField(default=True)), - ("devices", models.ManyToManyField(to="device.device")), - ( - "owner", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ( - "type", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="lot.lottag" - ), - ), - ], + migrations.AddField( + model_name="lot", + name="type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="lot.lottag" + ), ), ] diff --git a/device/migrations/0001_initial.py b/lot/migrations/0002_lotannotation.py similarity index 55% rename from device/migrations/0001_initial.py rename to lot/migrations/0002_lotannotation.py index ed68a41..aca7de1 100644 --- a/device/migrations/0001_initial.py +++ b/lot/migrations/0002_lotannotation.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.6 on 2024-07-17 14:57 +# Generated by Django 5.0.6 on 2024-07-29 15:37 import django.db.models.deletion from django.conf import settings @@ -7,15 +7,14 @@ from django.db import migrations, models class Migration(migrations.Migration): - initial = True - dependencies = [ + ("lot", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name="Device", + name="LotAnnotation", fields=[ ( "id", @@ -26,7 +25,21 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("type", models.CharField(blank=True, max_length=64, null=True)), + ("created", models.DateTimeField(auto_now_add=True)), + ( + "type", + models.SmallIntegerField( + choices=[(0, "System"), (1, "User"), (2, "Document")] + ), + ), + ("key", models.CharField(max_length=256)), + ("value", models.CharField(max_length=256)), + ( + "lot", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="lot.lot" + ), + ), ( "owner", models.ForeignKey( diff --git a/lot/migrations/0002_remove_lot_devices_devicelot.py b/lot/migrations/0002_remove_lot_devices_devicelot.py deleted file mode 100644 index 8496dea..0000000 --- a/lot/migrations/0002_remove_lot_devices_devicelot.py +++ /dev/null @@ -1,39 +0,0 @@ -# Generated by Django 5.0.6 on 2024-07-18 17:30 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("lot", "0001_initial"), - ] - - operations = [ - migrations.RemoveField( - model_name="lot", - name="devices", - ), - migrations.CreateModel( - name="DeviceLot", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("device_id", models.CharField(max_length=256)), - ( - "lot", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="lot.lot" - ), - ), - ], - ), - ] diff --git a/lot/models.py b/lot/models.py index 9940594..9078459 100644 --- a/lot/models.py +++ b/lot/models.py @@ -43,3 +43,16 @@ class Lot(models.Model): for d in DeviceLot.objects.filter(lot=self, device_id=v): d.delete() + +class LotAnnotation(models.Model): + class Type(models.IntegerChoices): + SYSTEM= 0, "System" + USER = 1, "User" + DOCUMENT = 2, "Document" + + created = models.DateTimeField(auto_now_add=True) + lot = models.ForeignKey(Lot, on_delete=models.CASCADE) + owner = models.ForeignKey(User, on_delete=models.CASCADE) + type = models.SmallIntegerField(choices=Type) + key = models.CharField(max_length=STR_EXTEND_SIZE) + value = models.CharField(max_length=STR_EXTEND_SIZE) diff --git a/lot/templates/annotations.html b/lot/templates/annotations.html new file mode 100644 index 0000000..7e6747e --- /dev/null +++ b/lot/templates/annotations.html @@ -0,0 +1,48 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block content %} +
+
+

Lot {{ lot.name }}

+
+
+ +
+
+ + +
Annotations
+ + + + + + + + + + + + {% for a in annotations %} + + + + + + + + {% endfor %} + + +
KeyValueCreated on
{{ a.key }}{{ a.value }}{{ a.created }}
+
+
+{% endblock %} diff --git a/lot/templates/documents.html b/lot/templates/documents.html new file mode 100644 index 0000000..f8abac9 --- /dev/null +++ b/lot/templates/documents.html @@ -0,0 +1,48 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block content %} +
+
+

Lot {{ lot.name }}

+
+
+ +
+
+ + +
Documents
+ + + + + + + + + + + + {% for a in documents %} + + + + + + + + {% endfor %} + + +
KeyValueCreated on
{{ a.key }}{{ a.value }}{{ a.created }}
+
+
+{% endblock %} diff --git a/lot/templates/new_annotation.html b/lot/templates/new_annotation.html new file mode 100644 index 0000000..ac16bf8 --- /dev/null +++ b/lot/templates/new_annotation.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block content %} +
+
+

{{ subtitle }}

+
+
+ +{% load django_bootstrap5 %} +
+ {% csrf_token %} + {% if form.errors %} + + {% endif %} + {{ form.management_form }} +
+
+
+
+ {% for f in form %} +
+
+ {% bootstrap_field f %} +
+
+ {% endfor %} +
+ + +
+ +{% endblock %} diff --git a/lot/urls.py b/lot/urls.py index 691e592..eb863b0 100644 --- a/lot/urls.py +++ b/lot/urls.py @@ -10,4 +10,8 @@ urlpatterns = [ path("add/devices/", views.AddToLotView.as_view(), name="add_devices"), path("del/devices/", views.DelToLotView.as_view(), name="del_devices"), path("tag//", views.LotsTagsView.as_view(), name="tag"), + path("/document/", views.LotDocumentsView.as_view(), name="documents"), + path("/document/add", views.LotAddDocumentView.as_view(), name="add_document"), + path("/annotation", views.LotAnnotationsView.as_view(), name="annotations"), + path("/annotation/add", views.LotAddAnnotationView.as_view(), name="add_annotation"), ] diff --git a/lot/views.py b/lot/views.py index 9549076..0045d16 100644 --- a/lot/views.py +++ b/lot/views.py @@ -9,7 +9,7 @@ from django.views.generic.edit import ( FormView, ) from dashboard.mixins import DashboardView -from lot.models import Lot, LotTag +from lot.models import Lot, LotTag, LotAnnotation from lot.forms import LotsForm @@ -134,3 +134,94 @@ class LotsTagsView(DashboardView, TemplateView): }) return context + +class LotAddDocumentView(DashboardView, CreateView): + template_name = "new_annotation.html" + title = _("New Document") + breadcrumb = "Device / New document" + success_url = reverse_lazy('dashboard:unassigned_devices') + model = LotAnnotation + fields = ("key", "value") + + def form_valid(self, form): + form.instance.owner = self.request.user + form.instance.lot = self.lot + form.instance.type = LotAnnotation.Type.DOCUMENT + response = super().form_valid(form) + return response + + def get_form_kwargs(self): + pk = self.kwargs.get('pk') + self.lot = get_object_or_404(Lot, pk=pk, owner=self.request.user) + self.success_url = reverse_lazy('lot:documents', args=[pk]) + kwargs = super().get_form_kwargs() + return kwargs + + +class LotDocumentsView(DashboardView, TemplateView): + template_name = "documents.html" + title = _("New Document") + breadcrumb = "Device / New document" + + def get_context_data(self, **kwargs): + self.pk = kwargs.get('pk') + context = super().get_context_data(**kwargs) + lot = get_object_or_404(Lot, owner=self.request.user, id=self.pk) + documents = LotAnnotation.objects.filter( + lot=lot, + owner=self.request.user, + type=LotAnnotation.Type.DOCUMENT, + ) + context.update({ + 'lot': lot, + 'documents': documents, + 'title': self.title, + 'breadcrumb': self.breadcrumb + }) + return context + + +class LotAnnotationsView(DashboardView, TemplateView): + template_name = "annotations.html" + title = _("New Annotation") + breadcrumb = "Device / New annotation" + + def get_context_data(self, **kwargs): + self.pk = kwargs.get('pk') + context = super().get_context_data(**kwargs) + lot = get_object_or_404(Lot, owner=self.request.user, id=self.pk) + annotations = LotAnnotation.objects.filter( + lot=lot, + owner=self.request.user, + type=LotAnnotation.Type.USER, + ) + context.update({ + 'lot': lot, + 'annotations': annotations, + 'title': self.title, + 'breadcrumb': self.breadcrumb + }) + return context + + +class LotAddAnnotationView(DashboardView, CreateView): + template_name = "new_annotation.html" + title = _("New Annotation") + breadcrumb = "Device / New annotation" + success_url = reverse_lazy('dashboard:unassigned_devices') + model = LotAnnotation + fields = ("key", "value") + + def form_valid(self, form): + form.instance.owner = self.request.user + form.instance.lot = self.lot + form.instance.type = LotAnnotation.Type.USER + response = super().form_valid(form) + return response + + def get_form_kwargs(self): + pk = self.kwargs.get('pk') + self.lot = get_object_or_404(Lot, pk=pk, owner=self.request.user) + self.success_url = reverse_lazy('lot:annotations', args=[pk]) + kwargs = super().get_form_kwargs() + return kwargs