summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2025-03-10 16:55:21 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2025-03-10 18:23:34 +0100
commit4f2c8b7d8564d3f4bf59d437a79e86a7a81c88e2 (patch)
tree06bf4f465d02bcb5fe7a7b281fbd4b12c9c967fb
parent9b3f2e0d6523958742256840266119395af860c3 (diff)
downloadIshtar-4f2c8b7d8564d3f4bf59d437a79e86a7a81c88e2.tar.bz2
Ishtar-4f2c8b7d8564d3f4bf59d437a79e86a7a81c88e2.zip
✨ sheet account: display attached items (refs #6208)
-rw-r--r--archaeological_context_records/models.py3
-rw-r--r--archaeological_files/models.py3
-rw-r--r--archaeological_finds/models_finds.py3
-rw-r--r--archaeological_operations/models.py4
-rw-r--r--archaeological_warehouse/forms.py4
-rw-r--r--archaeological_warehouse/models.py5
-rw-r--r--ishtar_common/models.py31
-rw-r--r--ishtar_common/templates/ishtar/sheet_ishtaruser.html22
8 files changed, 66 insertions, 9 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py
index 9b955eafc..8631f49d1 100644
--- a/archaeological_context_records/models.py
+++ b/archaeological_context_records/models.py
@@ -28,7 +28,7 @@ from django.contrib.sites.models import Site
from django.db import transaction, OperationalError, IntegrityError
from django.db.models import Q
from django.db.models.signals import post_delete, post_save, m2m_changed
-from django.urls import reverse
+from django.urls import reverse, reverse_lazy
from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy, pgettext
from django.utils.text import slugify
@@ -843,6 +843,7 @@ class ContextRecord(
"m2m_listing", "interpretation", "activity", "taq", "taq_estimated", "tpq",
"tpq_estimated"
]
+ DEFAULT_WIZARD = reverse_lazy("record_search", args=["general-record_search"])
history = HistoricalRecords(bases=[HistoryModel])
objects = UUIDModelManager()
diff --git a/archaeological_files/models.py b/archaeological_files/models.py
index d6dde5c2c..d92925c78 100644
--- a/archaeological_files/models.py
+++ b/archaeological_files/models.py
@@ -29,7 +29,7 @@ from django.core.cache import cache
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db.models import Q, Max
from django.db.models.signals import post_save, m2m_changed, post_delete
-from django.urls import reverse
+from django.urls import reverse, reverse_lazy
from ishtar_common.models_common import OrderedHierarchicalType
from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy, get_current_profile, \
@@ -636,6 +636,7 @@ class File(
QUICK_ACTIONS = [
QA_LINK
]
+ DEFAULT_WIZARD = reverse_lazy("file_search", args=["general-file_search"])
# fields
year = models.IntegerField(_("Year"), default=get_current_year)
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index f49685199..08cf4f4d2 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -28,7 +28,7 @@ from django.contrib.postgres.indexes import GinIndex
from django.db.models import Max, Q, F
from django.db.models.signals import m2m_changed, post_save, post_delete, pre_delete
from django.core.exceptions import ObjectDoesNotExist
-from django.urls import reverse
+from django.urls import reverse, reverse_lazy
from ishtar_common.data_importer import post_importer_action, ImporterError
from ishtar_common.utils import (
@@ -2059,6 +2059,7 @@ class Find(
SHEET_ALTERNATIVES = [("museum", "museum_find")]
SHEET_EMPTY_KEYS = ["container_ref", "upstream_treatment", "downstream_treatment",
"documents_count", "m2m_listing"]
+ DEFAULT_WIZARD = reverse_lazy("find_search", args=["generalwarehouse-find_search"])
objects = UUIDModelManager()
# fields
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py
index 093959fbe..0b629f453 100644
--- a/archaeological_operations/models.py
+++ b/archaeological_operations/models.py
@@ -34,7 +34,7 @@ from django.db import transaction, OperationalError, IntegrityError
from django.db.models import Q, Max
from django.db.models.signals import post_save, m2m_changed, post_delete
from django.forms import ValidationError
-from django.urls import reverse
+from django.urls import reverse, reverse_lazy
from ishtar_common.data_importer import post_importer_action
from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy, get_generated_id
@@ -630,6 +630,7 @@ class ArchaeologicalSite(
QA_LOCK,
QA_LINK
]
+ DEFAULT_WIZARD = reverse_lazy("site_search", args=["general-site_search"])
objects = SiteManager()
@@ -1329,6 +1330,7 @@ class Operation(
(("archaeological_files", "file"),
"associated_file_id"),
]
+ DEFAULT_WIZARD = reverse_lazy("operation_search", args=["general-operation_search"])
objects = UUIDModelManager()
# alternative names of fields for searches
diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py
index b100c72bc..9a740057f 100644
--- a/archaeological_warehouse/forms.py
+++ b/archaeological_warehouse/forms.py
@@ -70,9 +70,9 @@ from ishtar_common.forms import (
FormSet,
CustomForm,
FieldType,
+ HistorySelect,
DocumentItemSelect,
FormHeader,
- TableSelect,
CustomFormSearch,
MultiSearchForm,
LockForm,
@@ -138,7 +138,7 @@ SelectedDivisionFormset.form_admin_name = _("Warehouse - 020 - Divisions")
SelectedDivisionFormset.form_slug = "warehouse-020-divisions"
-class WarehouseSelect(CustomForm, TableSelect):
+class WarehouseSelect(HistorySelect):
_model = models.Warehouse
form_admin_name = _("Warehouse - 001 - Search")
form_slug = "warehouse-001-search"
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index be4349121..800cfbccf 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -28,7 +28,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q, Max
from django.db.models.signals import post_save, post_delete, m2m_changed, pre_delete
from django.template.defaultfilters import slugify
-from django.urls import reverse
+from django.urls import reverse, reverse_lazy
from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy
from django.apps import apps
@@ -374,6 +374,7 @@ class Warehouse(
"precise_town__areas__label__iexact"
),
}
+ ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES)
GEO_LABEL = "name"
CACHED_LABELS = ["cached_town_label"]
@@ -412,6 +413,7 @@ class Warehouse(
QA_LOCK,
QA_LINK
]
+ DEFAULT_WIZARD = reverse_lazy("warehouse_search", args=["selec-warehouse_search"])
objects = UUIDModelManager()
@@ -1180,6 +1182,7 @@ class Container(
(("archaeological_finds", "Find"), "finds__pk"),
(("archaeological_finds", "Find"), "finds_ref__pk"),
]
+ DEFAULT_WIZARD = reverse_lazy("container_search", args=["selec-container_search"])
objects = UUIDModelManager()
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 29995a5ba..ae0656c6d 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -48,7 +48,7 @@ from ooopy.Transformer import Transformer as OOTransformer
import ooopy.Transforms as OOTransforms
import uuid
import zipfile
-from urllib.parse import urlencode
+from urllib.parse import urlencode, quote
# nosec: ElementTree used to create XML not for parsing
from xml.etree import ElementTree as ET # nosec
@@ -4170,6 +4170,35 @@ class IshtarUser(FullSearch):
self.need_permission_update = False
self.save()
+ def get_attached_items(self):
+ model_list = [
+ ("archaeological_files", "file"),
+ ("archaeological_operations", "operation"),
+ ("archaeological_operations", "archaeologicalsite"),
+ ("archaeological_context_records", "contextrecord"),
+ ("archaeological_finds", "find"),
+ ("archaeological_warehouse", "warehouse"),
+ ("archaeological_warehouse", "container"),
+ ]
+ attached_items = []
+ search_key = str(pgettext_lazy("key for text search", "user-attached"))
+ for app_label, model_name in model_list:
+ ct = ContentType.objects.get(app_label=app_label, model=model_name)
+ model = ct.model_class()
+ q = model.objects.filter(ishtar_users__pk=self.pk)
+ if not q.exists():
+ continue
+ url = getattr(model, "DEFAULT_WIZARD", None)
+ if url:
+ url = str(url) + "?"
+ url += urlencode(
+ {"query": quote(f'{search_key}="{self.person.cached_label}"')}
+ )
+ attached_items.append(
+ (model._meta.verbose_name_plural, q.all(), url)
+ )
+ return attached_items
+
def has_permission_dict(self):
"""
Get permission dict with permission codename as key and True or False as result.
diff --git a/ishtar_common/templates/ishtar/sheet_ishtaruser.html b/ishtar_common/templates/ishtar/sheet_ishtaruser.html
index 193093990..0f2b54883 100644
--- a/ishtar_common/templates/ishtar/sheet_ishtaruser.html
+++ b/ishtar_common/templates/ishtar/sheet_ishtaruser.html
@@ -10,6 +10,7 @@
{% block content %}
{% if ADMIN %} {# extra check #}
{% with has_permission_dict=item.has_permission_dict %}
+{% with attached_items=item.get_attached_items %}
<ul class="nav nav-tabs" id="{{window_id}}-tabs" role="tablist">
<li class="nav-item">
@@ -19,6 +20,15 @@
{% trans "General" %}
</a>
</li>
+ {% if attached_items %}
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-attached-tab"
+ data-toggle="tab" href="#{{window_id}}-attached" role="tab"
+ aria-controls="{{window_id}}-attached" aria-selected="false">
+ {% trans "Attached items" %}
+ </a>
+ </li>
+ {% endif %}
<li class="nav-item">
<a class="nav-link" id="{{window_id}}-view-tab"
data-toggle="tab" href="#{{window_id}}-view" role="tab"
@@ -93,6 +103,16 @@
{% endif %}
</div>
+ {% if attached_items %}
+ <div class="tab-pane fade show" id="{{window_id}}-attached"
+ role="tabpanel" aria-labelledby="{{window_id}}-attached-tab">
+ {% for model_name, items, search_url in attached_items %}
+ <h3>{{model_name}}{% if search_url %} &nbsp;<a href='{{search_url}}'><i class="fa fa-search" aria-hidden="true"></i></a>{% endif %}</h3>
+ {% field_flex_detail_multiple_full "" items %}
+ {% endfor %}
+ </div>
+ {% endif %}
+
<div class="tab-pane fade show" id="{{window_id}}-view"
role="tabpanel" aria-labelledby="{{window_id}}-view-tab">
<h2>{% trans "View permissions" %}</h2>
@@ -502,6 +522,6 @@
</div>
-{% endwith %}
+{% endwith %}{% endwith %}
{% endif %}
{% endblock %}