From 081a1f90d35d0752f9d98128e5c217b68be3ed7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rling?= Date: Fri, 22 May 2026 12:47:46 +0200 Subject: [PATCH] Add expand/collapse for long letter previews on orders page. - Truncate previews over 120 characters with a Visa mer toggle - Allow per-order expand state on pending and completed cards - Add styles for expanded preview and toggle button - Cover long and short message behavior in OrdersPage tests Co-authored-by: Cursor --- frontend/src/__tests__/OrdersPage.spec.ts | 38 +++++++++++ frontend/src/pages/OrdersPage.vue | 78 ++++++++++++++++++++++- 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/frontend/src/__tests__/OrdersPage.spec.ts b/frontend/src/__tests__/OrdersPage.spec.ts index 1c87843..32e8f94 100644 --- a/frontend/src/__tests__/OrdersPage.spec.ts +++ b/frontend/src/__tests__/OrdersPage.spec.ts @@ -337,4 +337,42 @@ describe('OrdersPage', () => { const badge = wrapper.find('.badge') expect(badge.classes()).toContain('badge--primary') }) + + it('shows expand toggle for long messages and reveals full text', async () => { + const longText = + 'Hej! Jag ville nämna en situation i trafiken där vi båda kanske blev lite frustrerade. Det är lätt att det blir så när man kör bil i rusningstid och tempot blir högt.' + const ordersWithLongMessage = [ + { + id: 'c1eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', + plate: 'ABC123', + letterText: longText, + status: 'processing', + trackingId: null, + createdAt: '2026-05-11T12:00:00Z', + }, + ] + mockOrdersFetch(ordersWithLongMessage) + const { wrapper } = mountPage() + await new Promise((r) => setTimeout(r, 50)) + + const card = wrapper.find('.orders__card') + const preview = card.find('.orders__preview') + const toggle = card.find('.orders__preview-toggle') + + expect(toggle.exists()).toBe(true) + expect(toggle.text()).toBe('Visa mer') + expect(preview.classes()).not.toContain('orders__preview--expanded') + + await toggle.trigger('click') + + expect(preview.classes()).toContain('orders__preview--expanded') + expect(toggle.text()).toBe('Visa mindre') + expect(card.text()).toContain(longText) + }) + + it('does not show expand toggle for short messages', async () => { + const { wrapper } = mountPage() + await new Promise((r) => setTimeout(r, 50)) + expect(wrapper.find('.orders__preview-toggle').exists()).toBe(false) + }) }) diff --git a/frontend/src/pages/OrdersPage.vue b/frontend/src/pages/OrdersPage.vue index b23bec4..bb84c35 100644 --- a/frontend/src/pages/OrdersPage.vue +++ b/frontend/src/pages/OrdersPage.vue @@ -12,6 +12,27 @@ const loading = ref(true) const error = ref('') const actionError = ref('') const cancellingId = ref(null) +const expandedPreviewIds = ref>(new Set()) + +const PREVIEW_CHAR_LIMIT = 120 + +function isLongMessage(text: string): boolean { + return text.length > PREVIEW_CHAR_LIMIT +} + +function isPreviewExpanded(orderId: string): boolean { + return expandedPreviewIds.value.has(orderId) +} + +function togglePreview(orderId: string) { + const next = new Set(expandedPreviewIds.value) + if (next.has(orderId)) { + next.delete(orderId) + } else { + next.add(orderId) + } + expandedPreviewIds.value = next +} const pendingOrders = computed(() => orders.value.filter((order) => order.status === 'pending_payment'), @@ -150,7 +171,22 @@ onMounted(loadOrders)
-

{{ order.letterText }}

+

+ {{ order.letterText }} +

+

@@ -233,7 +269,22 @@ onMounted(loadOrders)

-

{{ order.letterText }}

+

+ {{ order.letterText }} +

+

@@ -374,6 +425,29 @@ onMounted(loadOrders) overflow: hidden; } +.orders__preview--expanded { + display: block; + -webkit-line-clamp: unset; + line-clamp: unset; + overflow: visible; +} + +.orders__preview-toggle { + margin-top: var(--space-sm); + font-size: 0.8125rem; + font-weight: 500; + color: var(--color-primary); + background: none; + border: none; + padding: 0; + cursor: pointer; +} + +.orders__preview-toggle:hover { + text-decoration: underline; + text-underline-offset: 2px; +} + .orders__order-date { margin: 0 0 var(--space-sm) 0; font-size: 0.8125rem;