mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-31 19:17:48 +00:00 
			
		
		
		
	chore: Include 11:59 PM slot in business hours display (#12610)
This commit is contained in:
		| @@ -96,11 +96,12 @@ export default { | ||||
|       return parse(this.toTime, 'hh:mm a', new Date()); | ||||
|     }, | ||||
|     totalHours() { | ||||
|       if (this.timeSlot.openAllDay) { | ||||
|         return 24; | ||||
|       } | ||||
|       const totalHours = differenceInMinutes(this.toDate, this.fromDate) / 60; | ||||
|       return totalHours; | ||||
|       if (this.timeSlot.openAllDay) return '24h'; | ||||
|  | ||||
|       const totalMinutes = differenceInMinutes(this.toDate, this.fromDate); | ||||
|       const [h, m] = [Math.floor(totalMinutes / 60), totalMinutes % 60]; | ||||
|  | ||||
|       return [h && `${h}h`, m && `${m}m`].filter(Boolean).join(' ') || '0m'; | ||||
|     }, | ||||
|     hasError() { | ||||
|       return !this.timeSlot.valid; | ||||
| @@ -211,7 +212,7 @@ export default { | ||||
|         v-if="isDayEnabled && !hasError" | ||||
|         class="label bg-n-brand/10 dark:bg-n-brand/30 text-n-blue-text text-xs inline-block px-2 py-1 rounded-lg cursor-default whitespace-nowrap" | ||||
|       > | ||||
|         {{ totalHours }} {{ $t('INBOX_MGMT.BUSINESS_HOURS.DAY.HOURS') }} | ||||
|         {{ totalHours }} | ||||
|       </span> | ||||
|     </div> | ||||
|   </div> | ||||
|   | ||||
| @@ -53,6 +53,7 @@ export const generateTimeSlots = (step = 15) => { | ||||
|     Generates a list of time strings from 12:00 AM to next 24 hours. Each new string | ||||
|      will be generated by adding `step` minutes to the previous one. | ||||
|     The list is generated by starting with a random day and adding step minutes till end of the same day. | ||||
|     Always includes 11:59 PM as the final slot to complete the day. | ||||
|   */ | ||||
|   const date = new Date(1970, 1, 1); | ||||
|   const slots = []; | ||||
| @@ -66,6 +67,13 @@ export const generateTimeSlots = (step = 15) => { | ||||
|     ); | ||||
|     date.setMinutes(date.getMinutes() + step); | ||||
|   } | ||||
|  | ||||
|   // Always add 11:59 PM as the final slot if it's not already included | ||||
|   const lastSlot = '11:59 PM'; | ||||
|   if (!slots.includes(lastSlot)) { | ||||
|     slots.push(lastSlot); | ||||
|   } | ||||
|  | ||||
|   return slots; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -7,10 +7,19 @@ import { | ||||
| } from '../businessHour'; | ||||
|  | ||||
| describe('#generateTimeSlots', () => { | ||||
|   it('returns correct number of time slots', () => { | ||||
|     expect(generateTimeSlots(15).length).toStrictEqual((60 / 15) * 24); | ||||
|   it('returns correct number of time slots for 15-minute intervals', () => { | ||||
|     const slots = generateTimeSlots(15); | ||||
|     // 24 hours * 4 slots per hour + 1 for 11:59 PM = 97 slots | ||||
|     expect(slots.length).toStrictEqual(97); | ||||
|   }); | ||||
|   it('returns correct time slots', () => { | ||||
|  | ||||
|   it('returns correct number of time slots for 30-minute intervals', () => { | ||||
|     const slots = generateTimeSlots(30); | ||||
|     // 24 hours * 2 slots per hour + 1 for 11:59 PM = 49 slots | ||||
|     expect(slots.length).toStrictEqual(49); | ||||
|   }); | ||||
|  | ||||
|   it('returns correct time slots for 4-hour intervals', () => { | ||||
|     expect(generateTimeSlots(240)).toStrictEqual([ | ||||
|       '12:00 AM', | ||||
|       '04:00 AM', | ||||
| @@ -18,8 +27,51 @@ describe('#generateTimeSlots', () => { | ||||
|       '12:00 PM', | ||||
|       '04:00 PM', | ||||
|       '08:00 PM', | ||||
|       '11:59 PM', | ||||
|     ]); | ||||
|   }); | ||||
|  | ||||
|   it('always starts with 12:00 AM', () => { | ||||
|     expect(generateTimeSlots(15)[0]).toStrictEqual('12:00 AM'); | ||||
|     expect(generateTimeSlots(30)[0]).toStrictEqual('12:00 AM'); | ||||
|     expect(generateTimeSlots(60)[0]).toStrictEqual('12:00 AM'); | ||||
|   }); | ||||
|  | ||||
|   it('always ends with 11:59 PM', () => { | ||||
|     const slots15 = generateTimeSlots(15); | ||||
|     const slots30 = generateTimeSlots(30); | ||||
|     const slots60 = generateTimeSlots(60); | ||||
|  | ||||
|     expect(slots15[slots15.length - 1]).toStrictEqual('11:59 PM'); | ||||
|     expect(slots30[slots30.length - 1]).toStrictEqual('11:59 PM'); | ||||
|     expect(slots60[slots60.length - 1]).toStrictEqual('11:59 PM'); | ||||
|   }); | ||||
|  | ||||
|   it('includes 11:59 PM even when it would not be in regular intervals', () => { | ||||
|     const slots = generateTimeSlots(30); | ||||
|     expect(slots).toContain('11:59 PM'); | ||||
|     expect(slots).toContain('11:30 PM'); // Regular interval | ||||
|   }); | ||||
|  | ||||
|   it('does not duplicate 11:59 PM if it already exists in regular intervals', () => { | ||||
|     // Test with a step that would naturally include 11:59 PM | ||||
|     const slots = generateTimeSlots(1); // 1-minute intervals | ||||
|     const count11_59 = slots.filter(slot => slot === '11:59 PM').length; | ||||
|     expect(count11_59).toStrictEqual(1); | ||||
|   }); | ||||
|  | ||||
|   it('generates correct time format', () => { | ||||
|     const slots = generateTimeSlots(60); | ||||
|     expect(slots).toContain('01:00 AM'); | ||||
|     expect(slots).toContain('12:00 PM'); | ||||
|     expect(slots).toContain('01:00 PM'); | ||||
|     expect(slots).toContain('11:00 PM'); | ||||
|   }); | ||||
|  | ||||
|   it('handles edge case with very large step', () => { | ||||
|     const slots = generateTimeSlots(1440); // 24 hours | ||||
|     expect(slots).toStrictEqual(['12:00 AM', '11:59 PM']); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| describe('#getTime', () => { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sivin Varghese
					Sivin Varghese