From 2d5823679ba38c87bcb521bc580288b63f0ca764 Mon Sep 17 00:00:00 2001 From: JoeyStk Date: Tue, 13 Aug 2024 13:01:33 +0200 Subject: [PATCH] Add form for contact information Co-authored-by: David Venhoff Co-authored-by: Peter Nerlich --- integreat_cms/cms/fixtures/test_data.json | 6 +- integreat_cms/cms/forms/__init__.py | 1 + integreat_cms/cms/forms/contacts/__init__.py | 3 + .../cms/forms/contacts/contact_form.py | 62 +++++ .../cms/migrations/0103_update_contact.py | 39 +++ integreat_cms/cms/models/contact/contact.py | 15 +- .../cms/templates/ajax_poi_form/poi_box.html | 25 +- .../cms/templates/contacts/contact_form.html | 135 ++++++++++ .../cms/templates/contacts/contact_list.html | 40 +-- .../templates/contacts/contact_list_row.html | 16 +- .../pois/poi_form_sidebar/action_box.html | 6 +- integreat_cms/cms/urls/protected.py | 10 + integreat_cms/cms/views/contacts/__init__.py | 1 + .../cms/views/contacts/contact_actions.py | 8 +- .../views/contacts/contact_context_mixin.py | 1 + .../cms/views/contacts/contact_form_view.py | 148 +++++++++++ .../cms/views/contacts/contact_list_view.py | 6 +- .../cms/views/events/event_context_mixin.py | 3 + .../cms/views/events/event_form_view.py | 1 + .../cms/views/regions/region_actions.py | 2 +- integreat_cms/locale/de/LC_MESSAGES/django.po | 244 ++++++++++++++---- integreat_cms/static/src/index.ts | 2 +- .../event-query-pois.ts => poi_box.ts} | 26 +- 23 files changed, 695 insertions(+), 105 deletions(-) create mode 100644 integreat_cms/cms/forms/contacts/__init__.py create mode 100644 integreat_cms/cms/forms/contacts/contact_form.py create mode 100644 integreat_cms/cms/migrations/0103_update_contact.py create mode 100644 integreat_cms/cms/templates/contacts/contact_form.html create mode 100644 integreat_cms/cms/views/contacts/contact_form_view.py rename integreat_cms/static/src/js/{events/event-query-pois.ts => poi_box.ts} (92%) diff --git a/integreat_cms/cms/fixtures/test_data.json b/integreat_cms/cms/fixtures/test_data.json index 8c073f4fe8..f96b24803b 100644 --- a/integreat_cms/cms/fixtures/test_data.json +++ b/integreat_cms/cms/fixtures/test_data.json @@ -958,7 +958,7 @@ "fields": { "title": "Integrationsbeauftragte", "name": "Martina Musterfrau", - "poi": 6, + "location": 6, "email": "martina-musterfrau@example.com", "phone_number": "0123456789", "website": "", @@ -973,7 +973,7 @@ "fields": { "title": "Integrationsberaterin", "name": "Melanie Musterfrau", - "poi": 6, + "location": 6, "email": "melanie-musterfrau@example.com", "phone_number": "0987654321", "website": "www.random-page.com", @@ -988,7 +988,7 @@ "fields": { "title": "Integrationsbeauftragte", "name": "Mariana Musterfrau", - "poi": 6, + "location": 6, "email": "mariana-musterfrau@example.com", "phone_number": "0123456789", "website": "https://integreat-app.de/", diff --git a/integreat_cms/cms/forms/__init__.py b/integreat_cms/cms/forms/__init__.py index 8334077334..918ca0575a 100644 --- a/integreat_cms/cms/forms/__init__.py +++ b/integreat_cms/cms/forms/__init__.py @@ -6,6 +6,7 @@ from __future__ import annotations from .chat.chat_message_form import ChatMessageForm +from .contacts.contact_form import ContactForm from .events.event_filter_form import EventFilterForm from .events.event_form import EventForm from .events.event_translation_form import EventTranslationForm diff --git a/integreat_cms/cms/forms/contacts/__init__.py b/integreat_cms/cms/forms/contacts/__init__.py new file mode 100644 index 0000000000..303c896a53 --- /dev/null +++ b/integreat_cms/cms/forms/contacts/__init__.py @@ -0,0 +1,3 @@ +""" +Forms for creating and modifying contact objects +""" diff --git a/integreat_cms/cms/forms/contacts/contact_form.py b/integreat_cms/cms/forms/contacts/contact_form.py new file mode 100644 index 0000000000..f30bf7e24b --- /dev/null +++ b/integreat_cms/cms/forms/contacts/contact_form.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING + +from django import forms +from django.utils.translation import gettext_lazy as _ + +from ...models import Contact +from ..custom_model_form import CustomModelForm + +if TYPE_CHECKING: + from typing import Any + +logger = logging.getLogger(__name__) + + +class ContactForm(CustomModelForm): + """ + Form for creating and modifying contact objects + """ + + class Meta: + """ + This class contains additional meta configuration of the form class, see the :class:`django.forms.ModelForm` + for more information. + """ + + #: The model of this :class:`django.forms.ModelForm` + model = Contact + #: The fields of the model which should be handled by this form + fields = [ + "title", + "name", + "location", + "email", + "phone_number", + "website", + ] + + def clean(self) -> dict[str, Any]: + """ + Validate the fields + + :return: The cleaned form data + """ + cleaned_data = super().clean() + + related_location = self.instance.region.pois.filter( + id=self.data["location"] + ).first() + + if related_location is None: + self.add_error( + None, + forms.ValidationError( + _("Location cannot be empty."), + code="invalid", + ), + ) + + return cleaned_data diff --git a/integreat_cms/cms/migrations/0103_update_contact.py b/integreat_cms/cms/migrations/0103_update_contact.py new file mode 100644 index 0000000000..913838fbaa --- /dev/null +++ b/integreat_cms/cms/migrations/0103_update_contact.py @@ -0,0 +1,39 @@ +# Generated by Django 4.2.13 on 2024-08-20 16:10 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + """ + Make the field name not mandatory. + Rename the field from "poi" to "location". + Add new fields to save whether the information must be taken over from the location. + """ + + dependencies = [ + ("cms", "0102_alter_contact_poi"), + ] + + operations = [ + migrations.AlterField( + model_name="contact", + name="name", + field=models.CharField(blank=True, max_length=200, verbose_name="name"), + ), + migrations.RenameField( + model_name="contact", + old_name="poi", + new_name="location", + ), + migrations.AlterField( + model_name="contact", + name="location", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="contacts", + to="cms.poi", + verbose_name="location", + ), + ), + ] diff --git a/integreat_cms/cms/models/contact/contact.py b/integreat_cms/cms/models/contact/contact.py index ce343c1cae..962de27010 100644 --- a/integreat_cms/cms/models/contact/contact.py +++ b/integreat_cms/cms/models/contact/contact.py @@ -14,16 +14,21 @@ class Contact(AbstractBaseModel): """ title = models.CharField(max_length=200, verbose_name=_("title")) - name = models.CharField(max_length=200, verbose_name=_("name")) - poi = models.ForeignKey( - POI, on_delete=models.PROTECT, verbose_name=_("POI"), related_name="contacts" + name = models.CharField(max_length=200, blank=True, verbose_name=_("name")) + location = models.ForeignKey( + POI, + on_delete=models.PROTECT, + verbose_name=_("location"), + related_name="contacts", ) email = models.EmailField( blank=True, verbose_name=_("email address"), ) phone_number = models.CharField( - max_length=250, blank=True, verbose_name=_("phone number") + max_length=250, + blank=True, + verbose_name=_("phone number"), ) website = models.URLField(blank=True, max_length=250, verbose_name=_("website")) archived = models.BooleanField( @@ -46,7 +51,7 @@ def region(self) -> Region: :return: Region this contact belongs to """ - return self.poi.region + return self.location.region def __str__(self) -> str: """ diff --git a/integreat_cms/cms/templates/ajax_poi_form/poi_box.html b/integreat_cms/cms/templates/ajax_poi_form/poi_box.html index 1d5dd3e949..c172044bf3 100644 --- a/integreat_cms/cms/templates/ajax_poi_form/poi_box.html +++ b/integreat_cms/cms/templates/ajax_poi_form/poi_box.html @@ -11,17 +11,24 @@ {{ title }} {% endblock collapsible_box_title %} {% block collapsible_box_content %} - {% render_field form.has_not_location class+='inline-block' %} - + {% if current_menu_item == "events_form" %} + {% render_field form.has_not_location class+='inline-block' %} + + {% endif %} + {% if current_menu_item == "contacts" %} +
+ {{ help_text }} +
+ {% endif %}
- {% translate "Name of event location" as poi_title_placeholder %} + {% translate "Name of location" as poi_title_placeholder %}

- {% translate "Create an event location or start typing the name of an existing location. Only published locations can be set as event venues" %}. + {% if current_menu_item == "events_form" %} + {{ help_text }} + {% endif %}

{% include "_poi_query_result.html" %} diff --git a/integreat_cms/cms/templates/contacts/contact_form.html b/integreat_cms/cms/templates/contacts/contact_form.html new file mode 100644 index 0000000000..32be55e400 --- /dev/null +++ b/integreat_cms/cms/templates/contacts/contact_form.html @@ -0,0 +1,135 @@ +{% extends "_base.html" %} +{% load i18n %} +{% load widget_tweaks %} +{% block content %} + {% with request.region.default_language as current_language %} +
+ {% csrf_token %} +
+

+ {% if contact_form.instance.id %} + {% translate "Edit contact" %} + {% else %} + {% translate "Create new contact" %} + {% endif %} +

+
+ {% if perms.cms.change_contact and not contact_form.instance.archived %} +
+ +
+ {% endif %} +
+
+
+ {% include "ajax_poi_form/poi_box.html" with form=contact_form box_id="contact-location" title=_("Connect a location") %} +
+
+

+ {% translate "Manage contact data" %} +

+
+
+
+ {% translate "Add missing data or change existing data. Select the data you want to import." %} +
+ + {% render_field contact_form.title|add_error_class:"border-red-500" %} + + {% render_field contact_form.name|add_error_class:"border-red-500" %} + + {% render_field contact_form.email|add_error_class:"border-red-500" %} + + {% render_field contact_form.phone_number|add_error_class:"border-red-500" %} + + {% render_field contact_form.website|add_error_class:"border-red-500" %} +
+
+ {% if contact_form.instance.id %} +
+
+

+ {% translate "Contact information" %} +

+
+
+
+ {% trans "This contact is referred to in those contents." %} +
+
+ {% include "../_related_contents_table.html" with contents=referring_pages table_title=_("Pages") no_content_message=_("This contact is not currently referred to on any page.") %} + {% include "../_related_contents_table.html" with contents=referring_locations table_title=_("Locations") no_content_message=_("This contact is not currently referred to in any location.") %} + {% include "../_related_contents_table.html" with contents=referring_events table_title=_("Events") no_content_message=_("This contact is not currently referred to in any event.") %} +
+ {% endif %} +
+ {% if contact_form.instance.id %} +
+ {% if perms.cms.change_contact and not contact_form.instance.archived %} + + {% endif %} + {% if perms.cms.change_contact and contact_form.instance.archived %} + + {% endif %} + {% if perms.cms.delete_contact %} +
+ +
+ {% endif %} +
+ {% endif %} +
+
+
+ {% include "generic_confirmation_dialog.html" %} + {% endwith %} +{% endblock content %} diff --git a/integreat_cms/cms/templates/contacts/contact_list.html b/integreat_cms/cms/templates/contacts/contact_list.html index 82ab91aa3c..50e0b79f97 100644 --- a/integreat_cms/cms/templates/contacts/contact_list.html +++ b/integreat_cms/cms/templates/contacts/contact_list.html @@ -11,23 +11,29 @@

{% translate "Contacts" %} {% endif %}

- + {% if is_archive %} + + {% translate "Back to contacts" %} + + {% else %} + + + + {% translate "Archived contacts" %} + ({{ archived_count }}) + + + {% endif %} +
+
+ {% if perms.cms.change_contact %} + + {% translate "Create contact" %} + + {% endif %}
diff --git a/integreat_cms/cms/templates/contacts/contact_list_row.html b/integreat_cms/cms/templates/contacts/contact_list_row.html index b6b877dfd0..d2040330c0 100644 --- a/integreat_cms/cms/templates/contacts/contact_list_row.html +++ b/integreat_cms/cms/templates/contacts/contact_list_row.html @@ -8,28 +8,32 @@ class="bulk-select-item" /> - + {{ contact.title }} - + {{ contact.name }} - - {{ contact.poi }} + {{ contact.location }} - + {{ contact.email }} - + {{ contact.phone_number }} diff --git a/integreat_cms/cms/templates/pois/poi_form_sidebar/action_box.html b/integreat_cms/cms/templates/pois/poi_form_sidebar/action_box.html index fa9b548d93..fe115284bb 100644 --- a/integreat_cms/cms/templates/pois/poi_form_sidebar/action_box.html +++ b/integreat_cms/cms/templates/pois/poi_form_sidebar/action_box.html @@ -66,7 +66,8 @@

{% for contact in poi_form.instance.contacts.all %} - + {{ contact.title }} {{ contact.name }} {% endfor %} @@ -127,7 +128,8 @@

{% for contact in poi_form.instance.contacts.all %} - + {{ contact.title }} {{ contact.name }} {% endfor %} diff --git a/integreat_cms/cms/urls/protected.py b/integreat_cms/cms/urls/protected.py index a56b4a1f7c..12f6376f8c 100644 --- a/integreat_cms/cms/urls/protected.py +++ b/integreat_cms/cms/urls/protected.py @@ -1404,10 +1404,20 @@ contacts.ContactListView.as_view(archived=True), name="archived_contacts", ), + path( + "new/", + contacts.ContactFormView.as_view(), + name="new_contact", + ), path( "/", include( [ + path( + "edit/", + contacts.ContactFormView.as_view(), + name="edit_contact", + ), path( "copy/", contacts.copy_contact, diff --git a/integreat_cms/cms/views/contacts/__init__.py b/integreat_cms/cms/views/contacts/__init__.py index 232875651a..e3aef5a205 100644 --- a/integreat_cms/cms/views/contacts/__init__.py +++ b/integreat_cms/cms/views/contacts/__init__.py @@ -4,4 +4,5 @@ delete_contact, restore_contact, ) +from .contact_form_view import ContactFormView from .contact_list_view import ContactListView diff --git a/integreat_cms/cms/views/contacts/contact_actions.py b/integreat_cms/cms/views/contacts/contact_actions.py index 52df42b8b6..65f63cd4c1 100644 --- a/integreat_cms/cms/views/contacts/contact_actions.py +++ b/integreat_cms/cms/views/contacts/contact_actions.py @@ -26,7 +26,7 @@ def archive_contact( :return: A redirection to the :class:`~integreat_cms.cms.views.contacts.contact_list_view.ContactListView` """ to_be_archived_contact = get_object_or_404( - Contact, id=contact_id, poi__region=request.region + Contact, id=contact_id, location__region=request.region ) to_be_archived_contact.archive() @@ -55,7 +55,7 @@ def delete_contact( :return: A redirection to the :class:`~integreat_cms.cms.views.contacts.contact_list_view.ContactListView` """ to_be_deleted_contact = get_object_or_404( - Contact, id=contact_id, poi__region=request.region + Contact, id=contact_id, location__region=request.region ) to_be_deleted_contact.delete() messages.success( @@ -82,7 +82,7 @@ def restore_contact( :return: A redirection to the :class:`~integreat_cms.cms.views.contacts.contact_list_view.ContactListView` """ to_be_restored_contact = get_object_or_404( - Contact, id=contact_id, poi__region=request.region + Contact, id=contact_id, location__region=request.region ) to_be_restored_contact.restore() @@ -112,7 +112,7 @@ def copy_contact( :return: A redirection to the :class:`~integreat_cms.cms.views.contacts.contact_list_view.ContactListView` """ to_be_copied_contact = get_object_or_404( - Contact, id=contact_id, poi__region=request.region + Contact, id=contact_id, location__region=request.region ) to_be_copied_contact.copy() diff --git a/integreat_cms/cms/views/contacts/contact_context_mixin.py b/integreat_cms/cms/views/contacts/contact_context_mixin.py index a3c88fa88c..acf8123426 100644 --- a/integreat_cms/cms/views/contacts/contact_context_mixin.py +++ b/integreat_cms/cms/views/contacts/contact_context_mixin.py @@ -27,6 +27,7 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]: context.update( { + "current_menu_item": "contacts", "archive_dialog_title": _( "Please confirm that you really want to archive this contact" ), diff --git a/integreat_cms/cms/views/contacts/contact_form_view.py b/integreat_cms/cms/views/contacts/contact_form_view.py new file mode 100644 index 0000000000..78db05ebd8 --- /dev/null +++ b/integreat_cms/cms/views/contacts/contact_form_view.py @@ -0,0 +1,148 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from django.contrib import messages +from django.shortcuts import redirect, render +from django.utils.decorators import method_decorator +from django.utils.translation import gettext_lazy as _ +from django.views.generic import TemplateView + +from ...decorators import permission_required +from ...forms import ContactForm +from ...models import Contact +from ...utils.translation_utils import gettext_many_lazy as __ +from .contact_context_mixin import ContactContextMixin + +if TYPE_CHECKING: + from typing import Any + + from django.http import HttpRequest, HttpResponse + + +@method_decorator(permission_required("cms.view_contact"), name="dispatch") +@method_decorator(permission_required("cms.change_contact"), name="post") +class ContactFormView(TemplateView, ContactContextMixin): + """ + Class for rendering the contact form + """ + + #: The template to render (see :class:`~django.views.generic.base.TemplateResponseMixin`) + template_name = "contacts/contact_form.html" + + def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: + r""" + Render contact form for HTTP GET requests + + :param request: Object representing the user call + :param \*args: The supplied arguments + :param \**kwargs: The supplied keyword arguments + :return: The rendered template response + """ + region = request.region + contact_instance = Contact.objects.filter( + id=kwargs.get("contact_id"), location__region=region + ).first() + + if contact_instance and contact_instance.archived: + disabled = True + messages.warning( + request, _("You cannot edit this contact because it is archived.") + ) + elif not request.user.has_perm("cms.change_contact"): + disabled = True + messages.warning( + request, _("You don't have the permission to edit contacts.") + ) + else: + disabled = False + + contact_form = ContactForm( + instance=contact_instance, + disabled=disabled, + additional_instance_attributes={"region": region}, + ) + + help_text = ( + _("This location is used for the contact.") + if contact_instance + else _( + "Select a location to use for your contact or create a new location. Only published locations can be set." + ) + ) + + return render( + request, + self.template_name, + { + **self.get_context_data(**kwargs), + "contact_form": contact_form, + "poi": contact_instance.location if contact_instance else None, + "referring_pages": None, # to implement later, how do we collect such pages? + "referring_locations": None, # to implement later, how do we collect such POIs? + "referring_events": None, # to implement later, how do we collect such Events? + "help_text": help_text, + }, + ) + + def post(self, request: HttpRequest, **kwargs: Any) -> HttpResponse: + r""" + Save contact and ender contact form for HTTP POST requests + + :param request: Object representing the user call + :param \**kwargs: The supplied keyword arguments + :raises ~django.core.exceptions.PermissionDenied: If user does not have the permission to change contact + + :return: The rendered template response + """ + region = request.region + + contact_instance = Contact.objects.filter( + id=kwargs.get("contact_id"), location__region=region + ).first() + contact_form = ContactForm( + data=request.POST, + instance=contact_instance, + additional_instance_attributes={"region": region}, + ) + + if not contact_form.is_valid(): + contact_form.add_error_messages(request) + else: + contact_form.save() + if not contact_instance: + messages.success( + request, + _('Contact "{}" was successfully created').format( + contact_form.instance + ), + ) + elif not contact_form.has_changed(): + messages.info(request, _("No changes detected, but date refreshed")) + else: + messages.success( + request, + _('Contact "{}" was successfully saved').format( + contact_form.instance + ), + ) + return redirect( + "edit_contact", + **{ + "contact_id": contact_form.instance.id, + "region_slug": region.slug, + }, + ) + + return render( + request, + self.template_name, + { + **self.get_context_data(**kwargs), + "contact_form": contact_form, + "poi": contact_instance.location if contact_instance else None, + "referring_pages": None, + "referring_locations": None, + "referring_events": None, + }, + ) diff --git a/integreat_cms/cms/views/contacts/contact_list_view.py b/integreat_cms/cms/views/contacts/contact_list_view.py index 07e1c51a4c..72cd84313d 100644 --- a/integreat_cms/cms/views/contacts/contact_list_view.py +++ b/integreat_cms/cms/views/contacts/contact_list_view.py @@ -40,11 +40,11 @@ def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: region = request.region contacts = Contact.objects.filter( - poi__region=region, archived=self.archived - ).select_related("poi") + location__region=region, archived=self.archived + ).select_related("location") archived_count = Contact.objects.filter( - poi__region=region, archived=True + location__region=region, archived=True ).count() chunk_size = int(request.GET.get("size", settings.PER_PAGE)) diff --git a/integreat_cms/cms/views/events/event_context_mixin.py b/integreat_cms/cms/views/events/event_context_mixin.py index a8837180ea..3a4b375238 100644 --- a/integreat_cms/cms/views/events/event_context_mixin.py +++ b/integreat_cms/cms/views/events/event_context_mixin.py @@ -48,6 +48,9 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]: "delete_dialog_text": _( "All translations of this event will also be deleted." ), + "help_text": _( + "Create an event location or start typing the name of an existing location. Only published locations can be set as event venues." + ), } ) return context diff --git a/integreat_cms/cms/views/events/event_form_view.py b/integreat_cms/cms/views/events/event_form_view.py index 58a5e748d3..2e947840b4 100644 --- a/integreat_cms/cms/views/events/event_form_view.py +++ b/integreat_cms/cms/views/events/event_form_view.py @@ -112,6 +112,7 @@ def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ) url_link = f"{settings.WEBAPP_URL}/{region.slug}/{language.slug}/{event_translation_form.instance.url_infix}/" + return render( request, self.template_name, diff --git a/integreat_cms/cms/views/regions/region_actions.py b/integreat_cms/cms/views/regions/region_actions.py index e98ca0da59..dde1908597 100644 --- a/integreat_cms/cms/views/regions/region_actions.py +++ b/integreat_cms/cms/views/regions/region_actions.py @@ -97,7 +97,7 @@ def delete_region( # Prevent ProtectedError when media files get deleted before their usages as organization logo region.organizations.all().delete() # Prevent ProtectedError when location gets deleted before their contacts - Contact.objects.filter(poi__region=region).delete() + Contact.objects.filter(location__region=region).delete() # Prevent IntegrityError when multiple feedback objects exist region.feedback.all().delete() # Disable linkchecking while deleting this region diff --git a/integreat_cms/locale/de/LC_MESSAGES/django.po b/integreat_cms/locale/de/LC_MESSAGES/django.po index 4677719fb7..5fc231c74d 100644 --- a/integreat_cms/locale/de/LC_MESSAGES/django.po +++ b/integreat_cms/locale/de/LC_MESSAGES/django.po @@ -1806,6 +1806,10 @@ msgstr "Vierte Woche" msgid "Last week" msgstr "Letzte Woche" +#: cms/forms/contacts/contact_form.py +msgid "Location cannot be empty." +msgstr "Ort darf nicht leer sein." + #: cms/forms/custom_content_model_form.py msgid "" "Could not update because this content because it is already being edited by " @@ -2708,8 +2712,9 @@ msgstr "Nutzer-Chats" msgid "name" msgstr "Name" -#: cms/models/contact/contact.py -msgid "POI" +#: cms/models/contact/contact.py cms/models/events/event.py +#: cms/models/pois/poi.py cms/models/pois/poi_translation.py +msgid "location" msgstr "Ort" #: cms/models/contact/contact.py cms/models/pois/poi.py @@ -2747,11 +2752,6 @@ msgstr "Kontakt" msgid "contacts" msgstr "Kontakte" -#: cms/models/events/event.py cms/models/pois/poi.py -#: cms/models/pois/poi_translation.py -msgid "location" -msgstr "Ort" - #: cms/models/events/event.py msgid "start" msgstr "Beginn" @@ -2973,7 +2973,8 @@ msgid "imprint feedback" msgstr "Impressums-Feedback" #: cms/models/feedback/map_feedback.py cms/models/regions/region.py -#: cms/templates/_base.html cms/templates/organizations/organization_form.html +#: cms/templates/_base.html cms/templates/contacts/contact_form.html +#: cms/templates/organizations/organization_form.html #: cms/templates/pois/poi_list.html msgid "Locations" msgstr "Orte" @@ -4113,11 +4114,13 @@ msgid "used budget" msgstr "verbrauchtes Budget" #: cms/models/regions/region.py cms/templates/_base.html +#: cms/templates/contacts/contact_form.html #: cms/templates/organizations/organization_form.html msgid "Pages" msgstr "Seiten" #: cms/models/regions/region.py cms/templates/_base.html +#: cms/templates/contacts/contact_form.html #: cms/templates/events/event_list.html msgid "Events" msgstr "Veranstaltungen" @@ -4723,8 +4726,9 @@ msgstr "Kontaktperson" msgid "Spoken Languages" msgstr "Gesprochene Sprachen" -#: cms/templates/_tinymce_config.html cms/templates/events/event_form.html -#: cms/templates/hix_widget.html cms/templates/imprint/imprint_form.html +#: cms/templates/_tinymce_config.html cms/templates/contacts/contact_form.html +#: cms/templates/events/event_form.html cms/templates/hix_widget.html +#: cms/templates/imprint/imprint_form.html #: cms/templates/imprint/imprint_sbs.html #: cms/templates/languagetreenodes/languagetreenode_form.html #: cms/templates/pages/page_form.html cms/templates/pages/page_sbs.html @@ -4781,21 +4785,12 @@ msgid "Publish" msgstr "Veröffentlichen" #: cms/templates/ajax_poi_form/poi_box.html -msgid "Name of event location" -msgstr "Name des Veranstaltungsortes" - -#: cms/templates/ajax_poi_form/poi_box.html -msgid "Remove location from event" -msgstr "Veranstaltungsort von Veranstaltung entfernen" +msgid "Name of location" +msgstr "Name des Ortes" #: cms/templates/ajax_poi_form/poi_box.html -msgid "" -"Create an event location or start typing the name of an existing location. " -"Only published locations can be set as event venues" -msgstr "" -"Erstellen Sie einen Veranstaltungsort oder beginnen Sie den Namen eines " -"bestehenden Veranstaltungsortes einzutippen. Nur öffentliche Orte können als " -"Veranstaltungsorte verwendet werden" +msgid "Remove location" +msgstr "Ort entfernen" #: cms/templates/ajax_poi_form/poi_box.html #: cms/templates/pois/poi_form_sidebar/position_box.html @@ -5163,6 +5158,80 @@ msgstr "Chat" msgid "Send message" msgstr "Nachricht abschicken" +#: cms/templates/contacts/contact_form.html +msgid "Edit contact" +msgstr "Kontakt bearbeiten" + +#: cms/templates/contacts/contact_form.html +msgid "Create new contact" +msgstr "Kontakt erstellen" + +#: cms/templates/contacts/contact_form.html +#: cms/templates/languagetreenodes/languagetreenode_form.html +#: cms/templates/offertemplates/offertemplate_form.html +#: cms/views/media/media_context_mixin.py +msgid "Create" +msgstr "Erstellen" + +#: cms/templates/contacts/contact_form.html +msgid "Connect a location" +msgstr "Ort verknüpfen" + +#: cms/templates/contacts/contact_form.html +msgid "Manage contact data" +msgstr "Kontaktdaten verwalten" + +#: cms/templates/contacts/contact_form.html +msgid "" +"Add missing data or change existing data. Select the data you want to import." +msgstr "" +"Ergänzen Sie fehlende Daten oder ändern bestehende Daten. Wählen Sie die " +"Daten aus, die übernommen werden sollen." + +#: cms/templates/contacts/contact_form.html +msgid "Contact information" +msgstr "Kontaktinformationen" + +#: cms/templates/contacts/contact_form.html +msgid "This contact is referred to in those contents." +msgstr "Dieser Kontakt wird in folgenden Inhalten verwendet." + +#: cms/templates/contacts/contact_form.html +msgid "This contact is not currently referred to on any page." +msgstr "Zur Zeit wird dieser Kontakt in keiner Seite verwendet." + +#: cms/templates/contacts/contact_form.html +msgid "This contact is not currently referred to in any location." +msgstr "Zur Zeit wird dieser Kontakt in keinem Ort verwendet." + +#: cms/templates/contacts/contact_form.html +msgid "This contact is not currently referred to in any event." +msgstr "Zur Zeit wird dieser Kontakt in keiner Veranstaltung verwendet." + +#: cms/templates/contacts/contact_form.html +#: cms/templates/contacts/contact_list_row.html +msgid "Archive contact" +msgstr "Kontakte archivieren" + +#: cms/templates/contacts/contact_form.html +msgid "Archive this contact" +msgstr "Kontakt archivieren" + +#: cms/templates/contacts/contact_form.html +#: cms/templates/pages/page_form_sidebar/actions_box.html +#: cms/templates/pages/page_tree_archived_node.html +msgid "Restore page" +msgstr "Seite wiederherstellen" + +#: cms/templates/contacts/contact_form.html +msgid "Restore this contact" +msgstr "Kontakt wiederherstellen" + +#: cms/templates/contacts/contact_form.html +#: cms/templates/contacts/contact_list_row.html +msgid "Delete contact" +msgstr "Kontakt löschen" + #: cms/templates/contacts/contact_list.html msgid "Archived Contacts" msgstr "Archivierte Kontakte" @@ -5175,6 +5244,10 @@ msgstr "Zurück zu Kontakte" msgid "Archived contacts" msgstr "Archivierte Kontakte" +#: cms/templates/contacts/contact_list.html +msgid "Create contact" +msgstr "Kontakt erstellen" + #: cms/templates/contacts/contact_list.html #: cms/templates/pages/_page_xliff_import_diff.html #: cms/templates/push_notifications/push_notification_list.html @@ -5275,14 +5348,6 @@ msgstr "Kontakt wiederherstellen" msgid "Copy contact" msgstr "Kontakt kopieren" -#: cms/templates/contacts/contact_list_row.html -msgid "Archive contact" -msgstr "Kontakte archivieren" - -#: cms/templates/contacts/contact_list_row.html -msgid "Delete contact" -msgstr "Kontakt löschen" - #: cms/templates/content_versions.html #, python-format msgid "\"Versions of %(content_title)s\"" @@ -6502,12 +6567,6 @@ msgstr "Sprach-Knoten \"%(translated_language_name)s\" bearbeiten" msgid "Add language to this region" msgstr "Sprache zu dieser Region hinzufügen" -#: cms/templates/languagetreenodes/languagetreenode_form.html -#: cms/templates/offertemplates/offertemplate_form.html -#: cms/views/media/media_context_mixin.py -msgid "Create" -msgstr "Erstellen" - #: cms/templates/languagetreenodes/languagetreenode_form.html msgid "Create and add more" msgstr "Erstellen und weitere hinzufügen" @@ -6964,11 +7023,6 @@ msgstr "Archiviert, weil eine übergeordnete Seite archiviert ist" msgid "Mark this page as up-to-date" msgstr "Seite als aktuell markieren" -#: cms/templates/pages/page_form_sidebar/actions_box.html -#: cms/templates/pages/page_tree_archived_node.html -msgid "Restore page" -msgstr "Seite wiederherstellen" - #: cms/templates/pages/page_form_sidebar/actions_box.html msgid "Restore this page" msgstr "Diese Seite wiederherstellen" @@ -8916,6 +8970,41 @@ msgstr "" msgid "Please confirm that you really want to delete this contact" msgstr "Bitte bestätigen Sie, dass dieser Kontakt gelöscht werden soll" +#: cms/views/contacts/contact_form_view.py +msgid "You cannot edit this contact because it is archived." +msgstr "Sie können diesen Kontakt nicht bearbeiten, weil er archiviert ist." + +#: cms/views/contacts/contact_form_view.py +msgid "You don't have the permission to edit contacts." +msgstr "Sie haben nicht die nötige Berechtigung, um Kontakte zu bearbeiten." + +#: cms/views/contacts/contact_form_view.py +msgid "This location is used for the contact." +msgstr "Dieser Ort wird für den Kontakt verwendet." + +#: cms/views/contacts/contact_form_view.py +msgid "" +"Select a location to use for your contact or create a new location. Only " +"published locations can be set." +msgstr "" +"Wählen Sie einen Ort aus, der für ihren Kontakt verwendet werden soll oder " +"erstellen Sie einen neuen Ort. Nur veröffentlichte Orte können verwendet " +"werden." + +#: cms/views/contacts/contact_form_view.py +msgid "Contact \"{}\" was successfully created" +msgstr "Kontakt \"{}\" wurde erfolgreich erstellt" + +#: cms/views/contacts/contact_form_view.py cms/views/content_version_view.py +#: cms/views/events/event_form_view.py cms/views/pages/page_form_view.py +#: cms/views/pois/poi_form_view.py +msgid "No changes detected, but date refreshed" +msgstr "Keine Änderungen vorgenommen, aber Datum aktualisiert" + +#: cms/views/contacts/contact_form_view.py +msgid "Contact \"{}\" was successfully saved" +msgstr "Kontakt \"{}\" wurde erfolgreich gespeichert" + #: cms/views/content_version_view.py msgid "Back to the form" msgstr "Zurück zum Formular" @@ -8939,11 +9028,6 @@ msgstr "" "Sie können keine Änderungen ablehnen, wenn es keine Version gibt, zu der Sie " "zurückkehren können." -#: cms/views/content_version_view.py cms/views/events/event_form_view.py -#: cms/views/pages/page_form_view.py cms/views/pois/poi_form_view.py -msgid "No changes detected, but date refreshed" -msgstr "Keine Änderungen vorgenommen, aber Datum aktualisiert" - #: cms/views/content_version_view.py msgid "No changes detected, but status changed to published" msgstr "Keine Änderungen vorgenommen, aber Status zu veröffentlicht geändert" @@ -9042,6 +9126,15 @@ msgstr "Bitte bestätigen Sie, dass diese Veranstaltung gelöscht werden soll" msgid "All translations of this event will also be deleted." msgstr "Alle Übersetzungen dieser Veranstaltung werden gelöscht." +#: cms/views/events/event_context_mixin.py +msgid "" +"Create an event location or start typing the name of an existing location. " +"Only published locations can be set as event venues." +msgstr "" +"Erstellen Sie einen Ort oder beginnen Sie den Namen eines bestehenden " +"Veranstaltungsortes einzutippen. Nur veröffentlichte Orte können als " +"Veranstaltungsorte verwendet werden." + #: cms/views/events/event_form_view.py msgid "You cannot edit this event because it is archived." msgstr "" @@ -10769,6 +10862,51 @@ msgstr "" "Diese Seite konnte nicht importiert werden, da sie zu einer anderen Region " "gehört ({})." +#~ msgid "E-mail from location" +#~ msgstr "E-mail des Ortes" + +#~ msgid "Will be taken over from the location." +#~ msgstr "Wird vom Ort übernommen." + +#~ msgid "phone number from location" +#~ msgstr "Telefonnummer des Ortes" + +#~ msgid "website from location" +#~ msgstr "Website des Ortes" + +#~ msgid "" +#~ "E-mail address does not match with that of the selected location. Please " +#~ "check again." +#~ msgstr "" +#~ "Die E-mail Adresse stimmt nicht mit der vom ausgewählten Ort überein. " +#~ "Bitte überprüfen Sie sie erneut." + +#~ msgid "" +#~ "Phone number does not match with that of the selected location. Please " +#~ "check again." +#~ msgstr "" +#~ "Die Telefonnummer stimmt nicht mit der vom ausgewählten Ort überein. " +#~ "Bitte überprüfen Sie sie erneut." + +#~ msgid "" +#~ "Website URL does not match with that of the selected location. Please " +#~ "check again." +#~ msgstr "" +#~ "Die Website URL stimmt nicht mit der vom ausgewählten Ort überein. Bitte " +#~ "überprüfen Sie sie erneut." + +#~ msgid "Delete this contact" +#~ msgstr "Diesen Kontakt löschen" + +#~ msgid "Name of related POI" +#~ msgstr "Name des verlinkten Ortes" + +#~ msgid "Only published locations can be set as event venues" +#~ msgstr "Nur veröffentlichte Orte können verwendet werden" + +#~ msgid "Remove location from event" +#~ msgstr "Ort entfernen" + #~ msgid "Opening hours" #~ msgstr "Öffnungszeiten" @@ -10781,9 +10919,6 @@ msgstr "" #~ msgid "Back to the location form" #~ msgstr "Zurück zum Orts-Formular" -#~ msgid "Name of related POI" -#~ msgstr "Name des verlinkten Ortes" - #~ msgid "You cannot archive a location which is used by an event." #~ msgstr "" #~ "Der Ort kann nicht archiviert werden, da er von einer Veranstaltung " @@ -10797,6 +10932,12 @@ msgstr "" #~ msgid "Manage Contacts" #~ msgstr "Kontakte verwalten" +#~ msgid "Whether or not the website must be taken from the location." +#~ msgstr "Ob Statistiken für die Region aktiviert sind oder nicht" + +#~ msgid "POI" +#~ msgstr "Ort" + #~ msgid "Contents" #~ msgstr "Inhalte" @@ -11799,9 +11940,6 @@ msgstr "" #~ msgid "POI is not public." #~ msgstr "POI ist nicht veröffentlicht." -#~ msgid "Translation cannot be imported" -#~ msgstr "Übersetzung kann nicht importiert werden" - #~ msgid "The page or target language does not exist." #~ msgstr "Die Seite oder Zielsprache existiert nicht." diff --git a/integreat_cms/static/src/index.ts b/integreat_cms/static/src/index.ts index 4216dce99f..b81aae6203 100644 --- a/integreat_cms/static/src/index.ts +++ b/integreat_cms/static/src/index.ts @@ -49,7 +49,7 @@ import "./js/grids/toggle-grid-checkbox"; import "./js/chat/send-chat-message"; import "./js/chat/delete-chat-message"; -import "./js/events/event-query-pois"; +import "./js/poi_box"; import "./js/events/conditional-fields"; import "./js/events/auto-complete"; diff --git a/integreat_cms/static/src/js/events/event-query-pois.ts b/integreat_cms/static/src/js/poi_box.ts similarity index 92% rename from integreat_cms/static/src/js/events/event-query-pois.ts rename to integreat_cms/static/src/js/poi_box.ts index 6e6193d27b..a52214063a 100644 --- a/integreat_cms/static/src/js/events/event-query-pois.ts +++ b/integreat_cms/static/src/js/poi_box.ts @@ -1,5 +1,5 @@ -import { createIconsAt } from "../utils/create-icons"; -import { getCsrfToken } from "../utils/csrf-token"; +import { createIconsAt } from "./utils/create-icons"; +import { getCsrfToken } from "./utils/csrf-token"; const toggleContactInfo = (infoType: string, info: string) => { document.getElementById(infoType).textContent = `${info}`; @@ -11,6 +11,26 @@ const toggleContactInfo = (infoType: string, info: string) => { } }; +const toggleContactFieldBox = (show: boolean) => { + console.log("!!!!!!!!!!!"); + const contactFieldsBox = document.getElementById("contact_fields"); + if (contactFieldsBox) { + if (show) { + contactFieldsBox.classList.remove("hidden"); + } else { + contactFieldsBox.classList.add("hidden"); + } + } + const contactUsageBox = document.getElementById("contact_usage"); + if (contactUsageBox) { + if (show) { + contactUsageBox.classList.remove("hidden"); + } else { + contactUsageBox.classList.add("hidden"); + } + } +}; + const renderPoiData = ( queryPlaceholder: string, id: string, @@ -42,6 +62,7 @@ const renderPoiData = ( ); document.getElementById("poi-query-result").classList.add("hidden"); (document.getElementById("poi-query-input") as HTMLInputElement).value = ""; + toggleContactFieldBox(true); }; const hidePoiFormWidget = () => { @@ -203,6 +224,7 @@ const removePoi = () => { document.getElementById("poi-address-container")?.classList.add("hidden"); // Clear the poi form hidePoiFormWidget(); + toggleContactFieldBox(false); console.debug("Removed POI data"); };