From ce71f7f286819ee1399fef5f1819f9cc812149a6 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 13 Mar 2025 13:30:02 +0100 Subject: ✨ sheets: refactor document listing - add edit and unlink actions (refs #6221) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ishtar_common/models.py | 4 ++ ishtar_common/models_common.py | 4 ++ .../templates/ishtar/blocks/api_document_list.html | 4 +- .../ishtar/blocks/sheet_document_list.html | 53 +++++++++++++++++++++ .../templates/ishtar/blocks/sheet_geographic.html | 16 +++---- ishtar_common/templates/ishtar/sheet_area.html | 7 +-- ishtar_common/templates/ishtar/sheet_document.html | 2 +- ishtar_common/templates/ishtar/sheet_town.html | 7 +-- ishtar_common/templatetags/ishtar_helpers.py | 12 +++++ ishtar_common/templatetags/link_to_window.py | 2 +- ishtar_common/urls.py | 7 +++ ishtar_common/views.py | 55 +++++++++++++++++++++- ishtar_common/views_item.py | 1 + 13 files changed, 156 insertions(+), 18 deletions(-) create mode 100644 ishtar_common/templates/ishtar/blocks/sheet_document_list.html (limited to 'ishtar_common') diff --git a/ishtar_common/models.py b/ishtar_common/models.py index ae0656c6d..6a793e326 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2480,6 +2480,10 @@ class Area(HierarchicalType, DocumentItem, MainItem): return self.label return "{} ({})".format(self.label, self.reference) + def can_edit(self, request): + print("TODO: define specific permissions for areas") + return False + @classmethod def get_or_create_by_towns(cls, towns, get_geo=False): if hasattr(towns, "all"): # queryset diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py index 0b1be5313..8f6ff5338 100644 --- a/ishtar_common/models_common.py +++ b/ishtar_common/models_common.py @@ -3605,6 +3605,10 @@ class Town(GeographicItem, Imported, DocumentItem, MainItem, models.Model): def history_compress(self): return {"numero_insee": self.numero_insee, "year": self.year or ""} + def can_edit(self, request): + print("TODO: define specific permissions for towns") + return False + @classmethod def get_documentation_string(cls): """ diff --git a/ishtar_common/templates/ishtar/blocks/api_document_list.html b/ishtar_common/templates/ishtar/blocks/api_document_list.html index 251885a19..2b2380496 100644 --- a/ishtar_common/templates/ishtar/blocks/api_document_list.html +++ b/ishtar_common/templates/ishtar/blocks/api_document_list.html @@ -2,7 +2,9 @@ id="{{window_id}}-docs-table"> {% for values in item.documents_list %}{% if not forloop.counter0 %} - {% for value in values %}{{value}}{% endfor %} + + {% for value in values %}{{value}}{% endfor %} + {% else %} diff --git a/ishtar_common/templates/ishtar/blocks/sheet_document_list.html b/ishtar_common/templates/ishtar/blocks/sheet_document_list.html new file mode 100644 index 000000000..1a1849636 --- /dev/null +++ b/ishtar_common/templates/ishtar/blocks/sheet_document_list.html @@ -0,0 +1,53 @@ +{% load i18n l10n ishtar_helpers link_to_window %} + {% with can_edit_current_item=item|can_edit_item:request %} +

{% trans "Associated documents" %}

+ {% if item.documents.count %} + + {% for doc in item.documents.all %}{% if not forloop.counter0 %} + + + + + + + + {% if not IS_HISTORY and permission_change_document %}{% endif %} + {% if not IS_HISTORY and permission_change_item %}{% endif %} + + + {% endif %} + + + + + + + {% if not IS_HISTORY and permission_change_document %}{% endif %} + {% if not IS_HISTORY and permission_change_item %}{% endif %} + + {% endfor %} +
 {% trans "Title" %}{% trans "Type" %}{% trans "Authors" %}{% trans "Numerical ressource" %}  
+ + + {{doc.title|default:'-'}} + + {{doc.source_type|default:'-'}} + + {{doc.authors_list|default:'-'}} + {% if doc.associated_url %} + {% trans "Link" %} + {% else%}-{% endif %} + + {% autoescape off %}{% if doc|can_edit_item:request %} + + {% else %}–{% endif %}{% endautoescape %} + + {% autoescape off %} + + {% endautoescape %} +
+ {% elif item.documents_list %} + {% include "ishtar/blocks/api_document_list.html" %} + {% endif %} + {% endwith %} diff --git a/ishtar_common/templates/ishtar/blocks/sheet_geographic.html b/ishtar_common/templates/ishtar/blocks/sheet_geographic.html index 12846ef78..6212c9573 100644 --- a/ishtar_common/templates/ishtar/blocks/sheet_geographic.html +++ b/ishtar_common/templates/ishtar/blocks/sheet_geographic.html @@ -2,7 +2,6 @@ {% with search_url=item.get_search_url %} - {% if not IS_HISTORY and permission_change_geo %}{% endif %} @@ -13,14 +12,10 @@ {% if not IS_HISTORY and permission_change_geo %}{% endif %} + {% if not IS_HISTORY and permission_change_geo %}{% endif %} {% for geo in geo_item.geodata.all %} - {% if not IS_HISTORY and permission_change_geo %}{% endif %} @@ -30,11 +25,16 @@ + {% if not IS_HISTORY and permission_change_geo %}{% endif %} {% if not IS_HISTORY and permission_change_geo and output != "ODT" and output != "PDF" %}{% endif %} diff --git a/ishtar_common/templates/ishtar/sheet_area.html b/ishtar_common/templates/ishtar/sheet_area.html index c4f67885e..682722dcd 100644 --- a/ishtar_common/templates/ishtar/sheet_area.html +++ b/ishtar_common/templates/ishtar/sheet_area.html @@ -92,8 +92,9 @@ {% endcomment %} {% if display_documents and item.documents.count %} - {% trans "Documents" as area_docs %} - {% dynamic_table_document area_docs 'documents' 'areas' item.pk '' output %} + {% with permission_change_item=item|can_edit_item:request %} + {% include "ishtar/blocks/sheet_document_list.html" %} + {% endwith %} {% endif %} @@ -126,4 +127,4 @@ $(document).ready( function () { {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ishtar_common/templates/ishtar/sheet_document.html b/ishtar_common/templates/ishtar/sheet_document.html index 02c32638b..ca382f137 100644 --- a/ishtar_common/templates/ishtar/sheet_document.html +++ b/ishtar_common/templates/ishtar/sheet_document.html @@ -58,7 +58,7 @@

{% trans "Content" %}

{% trans "File" context "Not directory" as file_label %} {% field_flex_file file_label item.associated_file %} - {% trans "Web link" as weblink_label %} + {% trans "Numerical ressource (web address)" as weblink_label %} {% field_flex_url weblink_label item.associated_url %} {% field_flex_multiple_obj "Tags" item 'tags' %} {% endif %} diff --git a/ishtar_common/templates/ishtar/sheet_town.html b/ishtar_common/templates/ishtar/sheet_town.html index e92c03b54..235182993 100644 --- a/ishtar_common/templates/ishtar/sheet_town.html +++ b/ishtar_common/templates/ishtar/sheet_town.html @@ -116,8 +116,9 @@ {% endif %} {% if display_documents and item.documents.count %} - {% trans "Documents" as town_docs %} - {% dynamic_table_document town_docs 'documents' 'towns' item.pk '' output %} + {% with permission_change_item=item|can_edit_item:request %} + {% include "ishtar/blocks/sheet_document_list.html" %} + {% endwith %} {% endif %} {% if perm_files and item.file.count %} @@ -167,4 +168,4 @@ $(document).ready( function () { {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} {% endwith %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ishtar_common/templatetags/ishtar_helpers.py b/ishtar_common/templatetags/ishtar_helpers.py index cfd04a5d7..b668b8f0b 100644 --- a/ishtar_common/templatetags/ishtar_helpers.py +++ b/ishtar_common/templatetags/ishtar_helpers.py @@ -113,6 +113,18 @@ def can_edit_item(item, context): return True +@register.filter +def can_delete_item(item, context): + if hasattr(context, "request"): # WSGIRequest + request = context.request + elif "request" in context: # RequestContext + request = context['request'] + else: + request = context + if item.can_delete(request): + return True + + @register.filter def user_can_do(ishtar_user, permission): return ishtar_user.user_ptr.has_perm(permission) diff --git a/ishtar_common/templatetags/link_to_window.py b/ishtar_common/templatetags/link_to_window.py index 285d9b1fd..0f857c8c5 100644 --- a/ishtar_common/templatetags/link_to_window.py +++ b/ishtar_common/templatetags/link_to_window.py @@ -76,7 +76,7 @@ def add_links(items, extra_attr=''): lbl = item.fancy_str() else: lbl = str(item) - html.append("{} {}".format(lbl, simple_link_to_window(item_lnk))) + html.append("{} {}".format(simple_link_to_window(item_lnk), lbl)) return mark_safe("
".join(html)) diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py index aa1f1948e..d2c954e58 100644 --- a/ishtar_common/urls.py +++ b/ishtar_common/urls.py @@ -686,6 +686,13 @@ urlpatterns += [ )(views.QADocumentDuplicateFormView.as_view()), name="document-qa-duplicate", ), + path( + "document-qa-unlink//-/", + check_permissions( + ["ishtar_common.change_document", "ishtar_common.change_own_document"] + )(views.QADocumentUnlink.as_view()), + name="document-qa-unlink", + ), url( r"^document-qa-packaging/(?P[0-9-]+)?/$", check_permissions( diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 4c83fd818..5f175c186 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -77,6 +77,7 @@ from ishtar_common.models_common import QuickAction from ishtar_common.templatetags.link_to_window import simple_link_to_window from ishtar_common.utils_migrations import HOMEPAGE_TITLE from ishtar_common.utils import ( + BSMessage, clean_session_cache, CSV_OPTIONS, get_current_item_keys, @@ -1236,10 +1237,12 @@ ACTION_MODEL_DICT = { "archaeological_operations", "AdministrativeAct"), 'file': apps.get_model("archaeological_files", "File"), 'site': apps.get_model("archaeological_operations", "ArchaeologicalSite"), + 'contextrecord': apps.get_model("archaeological_context_records", "ContextRecord"), 'record': apps.get_model("archaeological_context_records", "ContextRecord"), 'find': apps.get_model("archaeological_finds", "Find"), 'treatment': apps.get_model("archaeological_finds", "Treatment"), 'treatmentfle': apps.get_model("archaeological_finds", "TreatmentFile"), + 'treatmentfile': apps.get_model("archaeological_finds", "TreatmentFile"), 'exhibition': apps.get_model("archaeological_finds", "Exhibition"), 'container': apps.get_model("archaeological_warehouse", "Container"), 'warehouse': apps.get_model("archaeological_warehouse", "Warehouse"), @@ -3160,6 +3163,9 @@ class QAItemForm(IshtarMixin, LoginRequiredMixin, FormView): action_name = None permissions = [] + def get_permissions(self): + return self.permissions + def get_quick_action(self): quick_action = self.model.get_quick_action_by_url(self.base_url) if quick_action: @@ -3169,7 +3175,7 @@ class QAItemForm(IshtarMixin, LoginRequiredMixin, FormView): url=self.base_url, icon_class=self.icon, text=self.page_name, - rights=self.permissions + rights=self.get_permissions() ) def pre_dispatch(self, request, *args, **kwargs): @@ -3401,6 +3407,53 @@ class QADocumentDuplicateFormView(QAItemForm): return data +class QADocumentUnlink(QAItemForm): + model = models.Document + page_name = _("Unlink") + form_class = forms.QAForm + base_url = "document-qa-unlink" + icon = "fa fa-chain-broken" + action_name = _("Unlink") + + def pre_dispatch(self, request, *args, **kwargs): + related_model = kwargs.get("related_model") + # model, related_id + if related_model not in ACTION_MODEL_DICT: + raise Http404() + related_model = ACTION_MODEL_DICT[related_model] + related_id = kwargs.get("related_id") + try: + self.related_item = related_model.objects.get(pk=related_id) + except related_model.DoesNotExist: + raise Http404() + return super().pre_dispatch(request, *args, **kwargs) + + def get_permissions(self): + rel_meta = self.related_item.__class__._meta + return [ + f"{rel_meta.app_label}.change_{rel_meta.model_name}", + f"{rel_meta.app_label}.change_own_{rel_meta.model_name}", + ] + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs["confirm"] = True + return kwargs + + def form_valid(self, form): + self.related_item.documents.remove(self.items[0]) + return HttpResponseRedirect(reverse("success")) + + def get_context_data(self, **kwargs): + data = super().get_context_data(**kwargs) + data["messages"] = [ + BSMessage( + str(_('Unlink document "{}" from this item.')).format(self.items[0]), + "info", "", no_dismiss=True) + ] + return data + + class QADocumentPackagingFormView(QAItemForm): template_name = "ishtar/forms/qa_document_packaging.html" model = models.Document diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 9ee5b9040..080a6600b 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -530,6 +530,7 @@ def show_item(model, name, extra_dct=None, model_for_perms=None, callback=None): if current_language not in PUNCTUATION: current_language = "en" dct["PUNCTUATION"] = PUNCTUATION[current_language] + dct["model_slug"] = model.SLUG dct["current_window_url"] = url_name date = None if "date" in dct: -- cgit v1.2.3
 {% trans "Main" %} {% trans "Data type" %} {% trans "Source" %}{% trans "Acquisition date" %} {% trans "Comment" %}  
- {% autoescape off %} - {% if geo|can_edit_item:request %}{% else %}–{% endif %} - {% endautoescape %} - {% if geo.id == geo_item.main_geodata_id %}{% else %}–{% endif %} {% if geo.data_type %}{{ geo.data_type }}{% else %}-{% endif %} {{ geo.source_label }}{% if geo.provider %}{{ geo.provider }}{% else %}-{% endif %} {% if geo.acquisition_date %}{{ geo.acquisition_date|date:"DATE_FORMAT"|default:"-" }}{% else %}-{% endif %} {% if geo.comment %}{{ geo.comment }}{% else %}-{% endif %} + {% autoescape off %} + {% if geo|can_edit_item:request %}{% else %}–{% endif %} + {% endautoescape %} + {% autoescape off %} - - {% if geo|can_edit_item:request %}{% else %}–{% endif %} + {% else %}–{% endif %} {% endautoescape %}