Просмотр исходного кода

Show an accepted quote as accepted on the calendar (#590)

The calendar looked for a quote status of approved, which quotes never have, so an accepted quote stayed violet and its card said Draft. It now reads accepted, and the card names every quote status the way the quote list does.
Bernt Christian Egeland 13 часов назад
Родитель
Сommit
01d6a5e593

+ 16 - 0
src/__tests__/features/calendar/calendar-events-card.test.tsx

@@ -121,6 +121,22 @@ describe('calendar events card', () => {
     expect(within(screen.getByRole('dialog')).getByText(`Booking for ${TODAY}`)).toBeInTheDocument()
   })
 
+  it('names a quote by the status the quote list gives it, not "Draft"', () => {
+    renderCard([
+      event({
+        id: 'quote-1',
+        title: 'Brake quote',
+        type: 'quote',
+        status: 'accepted',
+        invoiceNumber: 'Q-0042',
+      }),
+    ])
+
+    fireEvent.click(screen.getByText('Brake quote'))
+    expect(screen.getByText('Accepted')).toBeInTheDocument()
+    expect(screen.queryByText('Draft')).not.toBeInTheDocument()
+  })
+
   it('says when nothing is coming and still offers a booking', () => {
     renderCard([event({ id: 'job-2', title: 'Oil change', status: 'completed' })])
 

+ 16 - 4
src/features/calendar/Components/EventPeek.tsx

@@ -202,6 +202,17 @@ function typeIcon(event: CalendarEvent) {
   }
 }
 
+/** What a quote can be, as the quote list names them (`quotes.statusLabels`). */
+const QUOTE_STATUSES = [
+  'draft',
+  'sent',
+  'accepted',
+  'rejected',
+  'expired',
+  'converted',
+  'changes_requested',
+]
+
 function statusKey(event: CalendarEvent): string {
   if (event.type === 'service') {
     switch (event.status) {
@@ -221,9 +232,6 @@ function statusKey(event: CalendarEvent): string {
   if (event.type === 'message') {
     return event.status === 'sent' ? 'sent' : event.status === 'failed' ? 'failed' : 'queued'
   }
-  if (event.type === 'quote') {
-    return event.status === 'sent' ? 'sent' : event.status === 'approved' ? 'approved' : 'draft'
-  }
   if (event.type === 'external') return 'busy'
   if (event.type === 'closure') return 'closed'
   if (event.type === 'absence') return 'away'
@@ -246,6 +254,7 @@ function PeekCard({
 }) {
   const t = useTranslations('calendar')
   const tc = useTranslations('common')
+  const tq = useTranslations('quotes.statusLabels')
   const format = useDayFormatter()
   const { timeFormat } = useDateSettings()
   const formatCurrency = useFormatCurrency()
@@ -306,7 +315,10 @@ function PeekCard({
           {/* "Closed" and "Leave" already say it all; a second badge repeated them. */}
           {event.type !== 'closure' && event.type !== 'absence' && (
             <Badge variant="outline" className="text-[10px]">
-              {t(`events.status.${statusKey(event)}`)}
+              {/* A quote says what the quote list says: accepted, expired, changes requested. */}
+              {event.type === 'quote'
+                ? tq(QUOTE_STATUSES.includes(event.status) ? event.status : 'draft')
+                : t(`events.status.${statusKey(event)}`)}
             </Badge>
           )}
         </div>

+ 1 - 1
src/features/calendar/Components/calendar-utils.ts

@@ -165,7 +165,7 @@ export function eventHue(event: Pick<CalendarEvent, 'type' | 'status'>): Hue {
           return 'amber'
       }
     case 'quote':
-      return event.status === 'approved' ? 'emerald' : 'violet'
+      return event.status === 'accepted' ? 'emerald' : 'violet'
     case 'message':
       return event.status === 'failed' ? 'red' : 'teal'
     case 'closure':