27 lines
1 KiB
TypeScript
27 lines
1 KiB
TypeScript
import { splitArrayBy } from '@giraugh/tools'
|
|
import { Temporal } from '@js-temporal/polyfill'
|
|
|
|
/**
|
|
* Calculates the rows required for an availability grid
|
|
* @returns An array of PlainTime or null, where null indicates a spacer row in gaps
|
|
*/
|
|
export const calculateRows = (dates: Temporal.ZonedDateTime[]): (Temporal.PlainTime | null)[] => {
|
|
// Dedupe dates by time and sort
|
|
const sortedDates = [...new Map(dates.map(d => {
|
|
const plain = d.toPlainTime()
|
|
return [plain.toString({ smallestUnit: 'minute' }), plain]
|
|
})).values()]
|
|
.sort(Temporal.PlainTime.compare)
|
|
|
|
// Partition by distance
|
|
const partitionedDates = splitArrayBy(sortedDates, (a, b) => !a.add({ minutes: 15 }).equals(b))
|
|
|
|
// Add end cap time and join
|
|
return partitionedDates.reduce((rows, partition, i) => [
|
|
...rows,
|
|
...partition,
|
|
partition[partition.length - 1].add({ minutes: 15 }),
|
|
...partitionedDates.length - 1 < i ? [null, null] : [], // Add spacer in between partitions
|
|
], [] as (Temporal.PlainTime | null)[])
|
|
}
|