From 5835a93d917bbfca06b0c6be71948dd475a488cc Mon Sep 17 00:00:00 2001 From: Paul Schilling Date: Wed, 6 Mar 2024 11:22:19 +0100 Subject: [PATCH] [#2098] Display/hide older questions --- src/open_inwoner/cms/cases/urls.py | 4 +- src/open_inwoner/cms/cases/views/__init__.py | 4 +- src/open_inwoner/cms/cases/views/status.py | 6 +- .../js/components/card/ToggleHideSelection.js | 43 +++++++++ src/open_inwoner/js/components/index.js | 2 + .../openzaak/tests/test_case_detail.py | 96 ++++++++++++++++++- .../scss/components/Card/Card.scss | 6 +- .../templates/pages/cases/status_inner.html | 47 +-------- .../templates/pages/cases/status_outer.html | 2 +- .../templates/pages/questions/questions.html | 37 +++++++ 10 files changed, 195 insertions(+), 52 deletions(-) create mode 100644 src/open_inwoner/js/components/card/ToggleHideSelection.js create mode 100644 src/open_inwoner/templates/pages/questions/questions.html diff --git a/src/open_inwoner/cms/cases/urls.py b/src/open_inwoner/cms/cases/urls.py index 3e9cff7c97..241e991c6f 100644 --- a/src/open_inwoner/cms/cases/urls.py +++ b/src/open_inwoner/cms/cases/urls.py @@ -11,7 +11,7 @@ CaseDocumentUploadFormView, InnerCaseDetailView, InnerCaseListView, - KCM_RedirectView, + KCMRedirectView, OuterCaseDetailView, OuterCaseListView, ) @@ -31,7 +31,7 @@ ), path( "contactmoment//", - KCM_RedirectView.as_view(), + KCMRedirectView.as_view(), name="kcm_redirect", ), path( diff --git a/src/open_inwoner/cms/cases/views/__init__.py b/src/open_inwoner/cms/cases/views/__init__.py index 43ed5820a8..b258a60981 100644 --- a/src/open_inwoner/cms/cases/views/__init__.py +++ b/src/open_inwoner/cms/cases/views/__init__.py @@ -4,7 +4,7 @@ CaseDocumentDownloadView, CaseDocumentUploadFormView, InnerCaseDetailView, - KCM_RedirectView, + KCMRedirectView, OuterCaseDetailView, ) @@ -16,5 +16,5 @@ "CaseDocumentUploadFormView", "InnerCaseDetailView", "OuterCaseDetailView", - "KCM_RedirectView", + "KCMRedirectView", ] diff --git a/src/open_inwoner/cms/cases/views/status.py b/src/open_inwoner/cms/cases/views/status.py index e67f1a4ef1..8256da2435 100644 --- a/src/open_inwoner/cms/cases/views/status.py +++ b/src/open_inwoner/cms/cases/views/status.py @@ -643,7 +643,7 @@ def get_anchors(self, statuses, documents): return anchors -class KCM_RedirectView(KlantContactMomentAccessMixin, View): +class KCMRedirectView(KlantContactMomentAccessMixin, View): """ Redirect to `KlantContactMomentDetailView` on the basis of contactmoment uuid @@ -663,7 +663,9 @@ def get(self, request, *args, **kwargs): raise Http404 contactmoment_uuid = kwargs["uuid"] - kcm = next((kcm for kcm in kcms if kcm.uuid == contactmoment_uuid)) + kcm = next( + (kcm for kcm in kcms if str(kcm.contactmoment.uuid) == contactmoment_uuid) + ) if not kcm: raise Http404 diff --git a/src/open_inwoner/js/components/card/ToggleHideSelection.js b/src/open_inwoner/js/components/card/ToggleHideSelection.js new file mode 100644 index 0000000000..4d35f536fe --- /dev/null +++ b/src/open_inwoner/js/components/card/ToggleHideSelection.js @@ -0,0 +1,43 @@ +export class ToggleHideSelection { + static selector = '.card' + + constructor(node) { + this.node = node + this.button = document.querySelector('#toggle-hide-elements') + this.button?.addEventListener('click', this.toggleHide.bind(this)) + + // save default button text for toggling + this.node.buttonText = this.button.textContent + + // hide all but the first 3 cards by default + var allCards = document.querySelectorAll('.card') + var cardsTail = Array.from(allCards).slice(3) + cardsTail.forEach((element) => { + element.classList.add('hide-me') + }) + } + + toggleHide() { + var allCards = document.querySelectorAll('.card') + var cardsTail = Array.from(allCards).slice(3) + + cardsTail.forEach((e) => { + this.node.classList.toggle('hide-me') + }) + + // toggle button text + for (var i = 0; i < cardsTail.length; i++) { + if (cardsTail[i].classList.contains('hide-me')) { + this.button.textContent = this.node.buttonText + break + } else { + this.button.textContent = 'Minder toon' + break + } + } + } +} + +document + .querySelectorAll(ToggleHideSelection.selector) + .forEach((toggleHide) => new ToggleHideSelection(toggleHide)) diff --git a/src/open_inwoner/js/components/index.js b/src/open_inwoner/js/components/index.js index c505e303c0..b5bce81559 100644 --- a/src/open_inwoner/js/components/index.js +++ b/src/open_inwoner/js/components/index.js @@ -32,6 +32,7 @@ import { StatusAccordion } from './cases/status_accordion' import './session' import './twofactor-sms' import { FileInput } from './form/FileInput' +import { ToggleHideSelection } from './card/ToggleHideSelection' const htmx = (window.htmx = require('htmx.org')) @@ -55,6 +56,7 @@ const elementWrappers = [ [AnchorMobile.selector, (elt) => new AnchorMobile(elt)], [StatusAccordion.selector, (elt) => new StatusAccordion(elt)], [FileInput.selector, (elt) => new FileInput(elt)], + [ToggleHideSelection.selector, (elt) => new ToggleHideSelection(elt)], ] // harden against multiple events diff --git a/src/open_inwoner/openzaak/tests/test_case_detail.py b/src/open_inwoner/openzaak/tests/test_case_detail.py index 8e83a2c53e..e4c2e716a1 100644 --- a/src/open_inwoner/openzaak/tests/test_case_detail.py +++ b/src/open_inwoner/openzaak/tests/test_case_detail.py @@ -57,6 +57,7 @@ CONTACTMOMENTEN_ROOT = "https://contactmomenten.nl/api/v1/" +KLANTEN_ROOT = "https://klanten.nl/api/v1/" @requests_mock.Mocker() @@ -461,7 +462,7 @@ def setUp(self): bestandsomvang=123, ) # - # (object-) contactmomenten + # contactmomenten # self.contactmoment = generate_oas_component_cached( "cmc", @@ -472,7 +473,8 @@ def setUp(self): type="SomeType", kanaal="Contactformulier", status=ContactMomentStatus.afgehandeld, - antwoord="yes", + tekst="Garage verbouwen?", + antwoord="Nee", onderwerp="e_suite_subject_code", ) self.contactmoment2 = generate_oas_component_cached( @@ -576,8 +578,10 @@ def _setUpMocks(self, m, use_eindstatus=True): self.status_type_new, self.status_type_in_behandeling, self.status_type_finish, + # self.klant, self.contactmoment, self.contactmoment2, + # self.klant_contactmoment, self.objectcontactmoment, self.objectcontactmoment2, ]: @@ -676,6 +680,24 @@ def _setUpMocks(self, m, use_eindstatus=True): ), ) + # klanten, contactmomenten, etc. + # m.get( + # f"{KLANTEN_ROOT}klanten?subjectNatuurlijkPersoon__inpBsn={self.user.bsn}", + # json=paginated_response([self.klant]), + # ) + # m.get( + # f"{KLANTEN_ROOT}klanten?subjectNietNatuurlijkPersoon__innNnpId={self.eherkenning_user.rsin}", + # json=paginated_response([self.klant]), + # ) + # m.get( + # f"{CONTACTMOMENTEN_ROOT}klantcontactmomenten?klant={self.klant['url']}", + # json=paginated_response([self.klant_contactmoment]), + # ) + # m.get( + # f"{CONTACTMOMENTEN_ROOT}objectcontactmomenten?contactmoment={self.contactmoment['url']}", + # json=paginated_response([self.objectcontactmoment]), + # ) + @patch("open_inwoner.userfeed.hooks.case_status_seen") @patch("open_inwoner.userfeed.hooks.case_documents_seen") def test_status_is_retrieved_when_user_logged_in_via_digid( @@ -1265,10 +1287,14 @@ def test_page_displays_expected_data(self, m): @patch( "open_inwoner.cms.cases.views.status.InnerCaseDetailView.get_objectcontactmomenten" ) + # @patch( + # "open_inwoner.openklant.clients.KlantenClient" + # ) def test_page_displays_expected_data_for_eherkenning_user(self, m, ocm_mock): self._setUpMocks(m) ocm_mock.return_value = [] + # klant_mock.return_value.retrieve_client.return_value = None for fetch_eherkenning_zaken_with_rsin in [True, False]: with self.subTest( @@ -2213,3 +2239,69 @@ def test_request_error_in_connecting_doc_with_zaak_shows_proper_message( f"Een fout is opgetreden bij het uploaden van {self.uploaded_informatie_object['bestandsnaam']}" ), ) + + def test_kcm_redirect(self, m): + """Check redirect from question embedded in case detail to klant_contactmoment detail""" + + self._setUpMocks(m) + + # + # extra configs + mocks + # + self.klanten_service = ServiceFactory( + api_root=KLANTEN_ROOT, api_type=APITypes.kc + ) + self.openklant_config.klanten_service = self.klanten_service + self.openklant_config.save() + + klant = generate_oas_component_cached( + "kc", + "schemas/Klant", + uuid="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + url=f"{KLANTEN_ROOT}klant/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", + emailadres="new@example.com", + telefoonnummer="0612345678", + ) + + klant_contactmoment = generate_oas_component_cached( + "cmc", + "schemas/KlantContactMoment", + uuid="aaaaaaaa-aaaa-aaaa-aaaa-cccccccccccc", + url=f"{CONTACTMOMENTEN_ROOT}klantcontactmomenten/aaaaaaaa-aaaa-aaaa-aaaa-cccccccccccc", + klant=klant["url"], + contactmoment=self.contactmoment["url"], + ) + + m.get( + f"{KLANTEN_ROOT}klanten?subjectNatuurlijkPersoon__inpBsn={self.user.bsn}", + json=paginated_response([klant]), + ) + m.get( + f"{KLANTEN_ROOT}klanten?subjectNietNatuurlijkPersoon__innNnpId={self.eherkenning_user.rsin}", + json=paginated_response([klant]), + ) + m.get( + f"{CONTACTMOMENTEN_ROOT}klantcontactmomenten?klant={klant['url']}", + json=paginated_response([klant_contactmoment]), + ) + m.get( + f"{CONTACTMOMENTEN_ROOT}objectcontactmomenten?contactmoment={self.contactmoment['url']}", + json=paginated_response([self.objectcontactmoment]), + ) + + # + # asserts + # + response = self.app.get( + reverse("cases:kcm_redirect", kwargs={"uuid": self.contactmoment["uuid"]}), + user=self.user, + ) + self.assertRedirects( + response, + reverse( + "cases:contactmoment_detail", + kwargs={"kcm_uuid": klant_contactmoment["uuid"]}, + ), + status_code=302, + target_status_code=200, + ) diff --git a/src/open_inwoner/scss/components/Card/Card.scss b/src/open_inwoner/scss/components/Card/Card.scss index 9fac8ed3c2..9a294b083a 100644 --- a/src/open_inwoner/scss/components/Card/Card.scss +++ b/src/open_inwoner/scss/components/Card/Card.scss @@ -1,3 +1,7 @@ +.hide-me { + display: none; +} + .card { --card-color-background: white; --card-color-border: var(--color-gray); @@ -11,7 +15,7 @@ border: var(--card-size-border) solid var(--card-color-border); border-radius: var(--border-radius); box-sizing: border-box; - display: flex; + // display: flex; flex-direction: column; min-height: 70px; min-width: var(--header-height); diff --git a/src/open_inwoner/templates/pages/cases/status_inner.html b/src/open_inwoner/templates/pages/cases/status_inner.html index 461874fb9a..ae8ab94846 100644 --- a/src/open_inwoner/templates/pages/cases/status_inner.html +++ b/src/open_inwoner/templates/pages/cases/status_inner.html @@ -11,13 +11,13 @@ {% if case %} {% render_grid %} {% render_column span=12 %} - {# Title/dashboard. #} + {# Title/dashboard #}

{{ case.description }}

{% include "components/Dashboard/Dashboard.html" with metrics=metrics only %} {% endrender_column %} {% render_column start=4 span=6 %} - {# Status history. #} + {# Status history #}
{% include 'pages/cases/statuses.html' %}
@@ -41,7 +41,7 @@

{% trans "Voeg documenten toe" %}

{% endif %} - {# Upload document form. #} + {# Upload document form #}
{% include 'pages/cases/document_form.html' %}
@@ -75,45 +75,8 @@

{% tran {# Questions/contactmomenten #} {% if case.questions %} - - {% endif %} - - {% if case.questions.paginator %} - {% pagination page_obj=case.questions paginator=case.questions.paginator request=request %} + {% include "pages/questions/questions.html" with questions=case.questions only %} + {% endif %} {% endrender_column %} diff --git a/src/open_inwoner/templates/pages/cases/status_outer.html b/src/open_inwoner/templates/pages/cases/status_outer.html index 89c3d1dbab..6482f690cf 100644 --- a/src/open_inwoner/templates/pages/cases/status_outer.html +++ b/src/open_inwoner/templates/pages/cases/status_outer.html @@ -9,7 +9,7 @@
-
+
{% icon icon="rotate_right" extra_classes="spinner-icon rotate" %}
{% trans "Gegevens laden..." %}
diff --git a/src/open_inwoner/templates/pages/questions/questions.html b/src/open_inwoner/templates/pages/questions/questions.html new file mode 100644 index 0000000000..9b85da33d9 --- /dev/null +++ b/src/open_inwoner/templates/pages/questions/questions.html @@ -0,0 +1,37 @@ +{% load i18n icon_tags list_tags %} + +