From c6529d7a720545acec7feafa47133c1743b1d31d Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Fri, 24 Jul 2026 18:51:22 +0200 Subject: [PATCH 1/3] feat: compact appointment list without descriptions, add heading buttons to editor - Hide description in the appointment list; full text lives on the detail page (#108) - Make card titles link to the detail page with a chevron and add a "Show details" button (#108) - Remove the description from the check-in screen header (#108) - Add H1/H2/H3 buttons to the markdown editor toolbar (#109) --- src/App.vue | 1 + .../appointment/AppointmentCard.vue | 98 +++++++++++++++++-- .../checkin/CheckinAppointmentInfo.vue | 46 +-------- src/components/common/MarkdownEditor.vue | 10 ++ src/views/AllAppointments.vue | 4 + 5 files changed, 105 insertions(+), 54 deletions(-) diff --git a/src/App.vue b/src/App.vue index 43767f85..9ffde1a0 100644 --- a/src/App.vue +++ b/src/App.vue @@ -230,6 +230,7 @@ @navigateToUpcoming="setView('current')" @navigateToUnanswered="setView('unanswered')" @showAuditLog="openAuditLog" + @openDetail="navigateToAppointment" @clearSearch="searchQuery = ''" /> diff --git a/src/components/appointment/AppointmentCard.vue b/src/components/appointment/AppointmentCard.vue index b943eea1..3e559e45 100644 --- a/src/components/appointment/AppointmentCard.vue +++ b/src/components/appointment/AppointmentCard.vue @@ -4,12 +4,28 @@
diff --git a/src/components/common/MarkdownEditor.vue b/src/components/common/MarkdownEditor.vue index d5a4508c..4ce5f4ab 100644 --- a/src/components/common/MarkdownEditor.vue +++ b/src/components/common/MarkdownEditor.vue @@ -66,6 +66,9 @@ onMounted(() => { // Icon paths from vue-material-design-icons (same as Nextcloud uses) const iconPaths = { + header1: 'M3,4H5V10H9V4H11V18H9V12H5V18H3V4M14,18V16H16V6.31L13.5,7.75V5.44L16,4H18V16H20V18H14Z', + header2: 'M3,4H5V10H9V4H11V18H9V12H5V18H3V4M21,18H15A2,2 0 0,1 13,16C13,15.47 13.2,15 13.54,14.64L18.41,9.41C18.78,9.05 19,8.55 19,8A2,2 0 0,0 17,6A2,2 0 0,0 15,8H13A4,4 0 0,1 17,4A4,4 0 0,1 21,8C21,9.1 20.55,10.1 19.83,10.83L15,16H21V18Z', + header3: 'M3,4H5V10H9V4H11V18H9V12H5V18H3V4M15,4H19A2,2 0 0,1 21,6V16A2,2 0 0,1 19,18H15A2,2 0 0,1 13,16V15H15V16H19V12H15V10H19V6H15V7H13V6A2,2 0 0,1 15,4Z', bold: 'M13.5,15.5H10V12.5H13.5A1.5,1.5 0 0,1 15,14A1.5,1.5 0 0,1 13.5,15.5M10,6.5H13A1.5,1.5 0 0,1 14.5,8A1.5,1.5 0 0,1 13,9.5H10M15.6,10.79C16.57,10.11 17.25,9 17.25,8C17.25,5.74 15.5,4 13.25,4H7V18H14.04C16.14,18 17.75,16.3 17.75,14.21C17.75,12.69 16.89,11.39 15.6,10.79Z', italic: 'M10,4V7H12.21L8.79,15H6V18H14V15H11.79L15.21,7H18V4H10Z', strikethrough: 'M3,14H21V12H3M5,4V7H10V10H14V7H19V4M10,19H14V16H10V19Z', @@ -88,6 +91,10 @@ onMounted(() => { { name: 'italic', action: EasyMDE.toggleItalic, className: 'mde-btn-italic', title: t('attendance', 'Italic') }, { name: 'strikethrough', action: EasyMDE.toggleStrikethrough, className: 'mde-btn-strikethrough', title: t('attendance', 'Strikethrough') }, '|', + { name: 'heading-1', action: EasyMDE.toggleHeading1, className: 'mde-btn-header1', title: t('attendance', 'Heading 1') }, + { name: 'heading-2', action: EasyMDE.toggleHeading2, className: 'mde-btn-header2', title: t('attendance', 'Heading 2') }, + { name: 'heading-3', action: EasyMDE.toggleHeading3, className: 'mde-btn-header3', title: t('attendance', 'Heading 3') }, + '|', { name: 'unordered-list', action: EasyMDE.toggleUnorderedList, className: 'mde-btn-bullet', title: t('attendance', 'Bullet list') }, { name: 'ordered-list', action: EasyMDE.toggleOrderedList, className: 'mde-btn-numbered', title: t('attendance', 'Numbered list') }, { name: 'quote', action: EasyMDE.toggleBlockquote, className: 'mde-btn-quote', title: t('attendance', 'Quote') }, @@ -108,6 +115,9 @@ onMounted(() => { injectIcon('mde-btn-bold', iconPaths.bold) injectIcon('mde-btn-italic', iconPaths.italic) injectIcon('mde-btn-strikethrough', iconPaths.strikethrough) + injectIcon('mde-btn-header1', iconPaths.header1) + injectIcon('mde-btn-header2', iconPaths.header2) + injectIcon('mde-btn-header3', iconPaths.header3) injectIcon('mde-btn-bullet', iconPaths.bulletList) injectIcon('mde-btn-numbered', iconPaths.numberedList) injectIcon('mde-btn-quote', iconPaths.quote) diff --git a/src/views/AllAppointments.vue b/src/views/AllAppointments.vue index 0b97c0b5..5f8faf38 100644 --- a/src/views/AllAppointments.vue +++ b/src/views/AllAppointments.vue @@ -113,6 +113,9 @@ :canSeeComments="permissions.canSeeComments" :canSeeAuditLog="canSeeAuditLog" :displayOrder="config.displayOrder" + :showDescription="false" + :showDetailsLink="true" + @openDetail="(id) => emit('openDetail', id)" @startCheckin="startCheckin" @edit="editAppointment" @copy="copyAppointment" @@ -191,6 +194,7 @@ const emit = defineEmits([ 'appointmentDeleted', 'clearSearch', 'showAuditLog', + 'openDetail', ]) const activeSearch = computed(() => props.searchQuery.trim()) From 0ef567a2f95089973a3dd886d06688e89f26739b Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Fri, 24 Jul 2026 18:51:23 +0200 Subject: [PATCH 2/3] fix(l10n): add German for untranslated strings --- l10n/de.js | 8 +++++++- l10n/de.json | 8 +++++++- l10n/de_DE.js | 7 ++++++- l10n/de_DE.json | 7 ++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/l10n/de.js b/l10n/de.js index a5bb8c4d..ad95187d 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -695,6 +695,12 @@ OC.L10N.register( "{actor} cancelled the appointment" : "{actor} hat diesen Termin abgesagt", "{actor} reactivated the appointment" : "{actor} hat diesen Termin reaktiviert", "{actor} performed {verb}" : "{actor} hat {verb} durchgeführt", - "Guests" : "Gäste" + "Guests" : "Gäste", + "Heading 1" : "Überschrift 1", + "Heading 2" : "Überschrift 2", + "Heading 3" : "Überschrift 3", + "Show details" : "Details anzeigen", + "Some users may appear in the section \"Others\" in the response summary because they are not configured for tracking." : "Einige Personen erscheinen möglicherweise im Abschnitt \"Andere\" in der Antwortübersicht, weil sie nicht für die Erfassung konfiguriert sind.", + "year" : "Jahr" }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/de.json b/l10n/de.json index 3d834c42..a49f1369 100644 --- a/l10n/de.json +++ b/l10n/de.json @@ -693,6 +693,12 @@ "{actor} cancelled the appointment" : "{actor} hat diesen Termin abgesagt", "{actor} reactivated the appointment" : "{actor} hat diesen Termin reaktiviert", "{actor} performed {verb}" : "{actor} hat {verb} durchgeführt", - "Guests" : "Gäste" + "Guests" : "Gäste", + "Heading 1" : "Überschrift 1", + "Heading 2" : "Überschrift 2", + "Heading 3" : "Überschrift 3", + "Show details" : "Details anzeigen", + "Some users may appear in the section \"Others\" in the response summary because they are not configured for tracking." : "Einige Personen erscheinen möglicherweise im Abschnitt \"Andere\" in der Antwortübersicht, weil sie nicht für die Erfassung konfiguriert sind.", + "year" : "Jahr" },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file diff --git a/l10n/de_DE.js b/l10n/de_DE.js index 0b5de8ec..4d4dd0f1 100644 --- a/l10n/de_DE.js +++ b/l10n/de_DE.js @@ -696,6 +696,11 @@ OC.L10N.register( "{actor} cancelled the appointment" : "{actor} hat diesen Termin abgesagt", "{actor} reactivated the appointment" : "{actor} hat diesen Termin reaktiviert", "{actor} performed {verb}" : "{actor} hat {verb} durchgeführt", - "Guests" : "Gäste" + "Guests" : "Gäste", + "Heading 1" : "Überschrift 1", + "Heading 2" : "Überschrift 2", + "Heading 3" : "Überschrift 3", + "Show details" : "Details anzeigen", + "Some users may appear in the section \"Others\" in the response summary because they are not configured for tracking." : "Einige Personen erscheinen möglicherweise im Abschnitt \"Andere\" in der Antwortübersicht, weil sie nicht für die Erfassung konfiguriert sind." }, "nplurals=2; plural=(n != 1);"); diff --git a/l10n/de_DE.json b/l10n/de_DE.json index 4ca2f8aa..01f7212a 100644 --- a/l10n/de_DE.json +++ b/l10n/de_DE.json @@ -694,6 +694,11 @@ "{actor} cancelled the appointment" : "{actor} hat diesen Termin abgesagt", "{actor} reactivated the appointment" : "{actor} hat diesen Termin reaktiviert", "{actor} performed {verb}" : "{actor} hat {verb} durchgeführt", - "Guests" : "Gäste" + "Guests" : "Gäste", + "Heading 1" : "Überschrift 1", + "Heading 2" : "Überschrift 2", + "Heading 3" : "Überschrift 3", + "Show details" : "Details anzeigen", + "Some users may appear in the section \"Others\" in the response summary because they are not configured for tracking." : "Einige Personen erscheinen möglicherweise im Abschnitt \"Andere\" in der Antwortübersicht, weil sie nicht für die Erfassung konfiguriert sind." },"pluralForm" :"nplurals=2; plural=(n != 1);" } \ No newline at end of file From a141023041a343fb5437dfe0ca3004a8e1f998f4 Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Fri, 24 Jul 2026 20:03:01 +0200 Subject: [PATCH 3/3] refactor: deduplicate card title markup, editor toolbar config and detail URL - Merge the two display-order title branches into one block via titleText/subtitleText - Replace the showDescription/showDetailsLink prop pair with a single 'variant' prop - Derive the EasyMDE toolbar and icon injection from one button descriptor list - Centralize the appointment detail URL in utils/appointment.js (also used by copyShareLink) - Generalize the response-section divider rule instead of enumerating preceding blocks --- .../appointment/AppointmentCard.vue | 162 +++++++----------- src/components/common/MarkdownEditor.vue | 69 +++----- src/utils/appointment.js | 11 ++ src/views/AllAppointments.vue | 3 +- 4 files changed, 101 insertions(+), 144 deletions(-) diff --git a/src/components/appointment/AppointmentCard.vue b/src/components/appointment/AppointmentCard.vue index 3e559e45..81e3d6c0 100644 --- a/src/components/appointment/AppointmentCard.vue +++ b/src/components/appointment/AppointmentCard.vue @@ -2,89 +2,49 @@
- - + + + {{ subtitleText }} + + + +
@@ -240,7 +200,7 @@
-