From d25f1e673a62c156ee4c225cd976a1c900f23af5 Mon Sep 17 00:00:00 2001 From: Adam Goldsmith Date: Mon, 9 Sep 2024 17:17:45 -0400 Subject: [PATCH] membershipworks: Copy EventMeetingTime start date to end in admin, when blank just a minor improvement in UX --- membershipworks/admin.py | 17 +++++++++++++ .../event_meeting_time_admin_helper.entry.ts | 25 +++++++++++++++++++ package.json | 1 + pnpm-lock.yaml | 15 +++++++++++ 4 files changed, 58 insertions(+) create mode 100644 membershipworks/js/event_meeting_time_admin_helper.entry.ts diff --git a/membershipworks/admin.py b/membershipworks/admin.py index deb5001..88eb817 100644 --- a/membershipworks/admin.py +++ b/membershipworks/admin.py @@ -1,3 +1,5 @@ +from dataclasses import dataclass + from django.contrib import admin from django.contrib.humanize.templatetags.humanize import naturaltime from django.http import HttpRequest @@ -10,6 +12,7 @@ from django_object_actions import ( ) from django_q.models import Task from django_q.tasks import async_task +from django_vite.templatetags.django_vite import vite_asset_url from simple_history.admin import SimpleHistoryAdmin from .models import ( @@ -225,6 +228,20 @@ class EventAdmin(DjangoObjectActions, admin.ModelAdmin): ), ] + class Media: + @dataclass(frozen=True) + class LazyViteAssetUrl(str): + asset: str + + def __str__(self) -> str: + return vite_asset_url(self.asset) + + js = [ + LazyViteAssetUrl( + "membershipworks/js/event_meeting_time_admin_helper.entry.ts" + ) + ] + @property def refresh_membershipworks_data(self): return run_task_action(self, "Refresh Data", scrape_events) diff --git a/membershipworks/js/event_meeting_time_admin_helper.entry.ts b/membershipworks/js/event_meeting_time_admin_helper.entry.ts new file mode 100644 index 0000000..f8a56f2 --- /dev/null +++ b/membershipworks/js/event_meeting_time_admin_helper.entry.ts @@ -0,0 +1,25 @@ +function maybeUpdateEndField(start_date_field: HTMLInputElement) { + let end_date_field: HTMLInputElement | null | undefined = start_date_field + ?.closest(".form-row") + ?.querySelector(".field-end .vDateField"); + if (end_date_field && !end_date_field.value) { + end_date_field.value = start_date_field.value; + } +} + +function setupListeners(element: ParentNode) { + for (let start_date_field of element.querySelectorAll( + "#meeting_times-group .field-start .vDateField", + ) as NodeListOf) { + start_date_field.addEventListener("change", () => { + maybeUpdateEndField(start_date_field); + }); + // element is focused after selecting a date using Django's DateTimeShortcuts + start_date_field.addEventListener("focus", () => { + maybeUpdateEndField(start_date_field); + }); + } +} + +$(() => setupListeners(document)); +$(document).on("formset:added", (event) => setupListeners(event.target)); diff --git a/package.json b/package.json index 8b12a2b..ec55d94 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "devDependencies": { "@types/bootstrap": "^5.2.10", + "@types/jquery": "^3.5.30", "@types/tabulator-tables": "^6.2.3", "globby": "^14.0.2", "prettier": "^3.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f5d2f1..a1f7a93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,6 +24,9 @@ importers: '@types/bootstrap': specifier: ^5.2.10 version: 5.2.10 + '@types/jquery': + specifier: ^3.5.30 + version: 3.5.30 '@types/tabulator-tables': specifier: ^6.2.3 version: 6.2.3 @@ -288,6 +291,12 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/jquery@3.5.30': + resolution: {integrity: sha512-nbWKkkyb919DOUxjmRVk8vwtDb0/k8FKncmUKFi+NY+QXqWltooxTrswvz4LspQwxvLdvzBN1TImr6cw3aQx2A==} + + '@types/sizzle@2.3.8': + resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} + '@types/tabulator-tables@6.2.3': resolution: {integrity: sha512-ZeRF/WvtwFXml/4aT7kzfkHEiwbjHZdlIsjrgqcfdmpkl9GQ9XBHY6u9BblUaHX4NUiOlBeHrQKjvai6/bQH0g==} @@ -624,6 +633,12 @@ snapshots: '@types/estree@1.0.5': {} + '@types/jquery@3.5.30': + dependencies: + '@types/sizzle': 2.3.8 + + '@types/sizzle@2.3.8': {} + '@types/tabulator-tables@6.2.3': {} anymatch@3.1.3: