forked from MapComplete/MapComplete
Refactoring: port opening hours visualisation to svelte
This commit is contained in:
parent
3b2c2462c5
commit
cc96df94e9
12 changed files with 290 additions and 285 deletions
|
|
@ -0,0 +1,129 @@
|
|||
<script lang="ts">/**
|
||||
* The main visualisation which shows ranges, one or more top/bottom headers, ...
|
||||
* Does not handle the special cases
|
||||
*/
|
||||
import opening_hours from "opening_hours"
|
||||
import OpeningHoursHeader from "./OpeningHoursHeader.svelte"
|
||||
import { default as Transl } from "../../Base/Tr.svelte" /* The IDE confuses <tr> (table row) and <Tr> (translation) as they are normally case insensitive -> import under a different name */
|
||||
import OpeningHoursRangeElement from "./OpeningHoursRangeElement.svelte"
|
||||
import { Translation } from "../../i18n/Translation"
|
||||
import Translations from "../../i18n/Translations"
|
||||
import { OH } from "../OpeningHours"
|
||||
import { Utils } from "../../../Utils"
|
||||
|
||||
export let oh: opening_hours
|
||||
export let ranges: {
|
||||
isOpen: boolean
|
||||
isSpecial: boolean
|
||||
comment: string
|
||||
startDate: Date
|
||||
endDate: Date
|
||||
}[][] // Per weekday
|
||||
export let rangeStart: Date
|
||||
let isWeekstable: boolean = oh.isWeekStable()
|
||||
let today = new Date()
|
||||
today.setHours(0, 0, 0, 0)
|
||||
let todayIndex = Math.ceil((today.getTime() - rangeStart.getTime()) / (1000 * 60 * 60 * 24))
|
||||
|
||||
|
||||
let weekdayRanges = ranges.map(ranges => ranges.filter(r => r.startDate.getDay() != 0 && r.startDate.getDay() != 6))
|
||||
let weekendRanges = ranges.map(ranges => ranges.filter(r => r.startDate.getDay() == 0 || r.startDate.getDay() == 6))
|
||||
let todayRanges = ranges.map(((r, i) => r.filter(() => i === todayIndex)))
|
||||
|
||||
|
||||
const [changeHours, changeHourText] = OH.allChangeMoments(weekdayRanges)
|
||||
const [changeHoursWeekend, changeHourTextWeekend] = OH.allChangeMoments(weekendRanges)
|
||||
|
||||
const weekdayHeaders: {
|
||||
changeHours: number[];
|
||||
changeTexts: string[]
|
||||
}[] = OH.partitionOHForDistance(changeHours, changeHourText)
|
||||
const weekendDayHeaders: {
|
||||
changeHours: number[];
|
||||
changeTexts: string[]
|
||||
}[] = OH.partitionOHForDistance(changeHoursWeekend, changeHourTextWeekend)
|
||||
|
||||
let allChangeMoments: number[] = Utils.DedupT([...changeHours, ...changeHoursWeekend])
|
||||
let todayChangeMoments: Set<number> = new Set(OH.allChangeMoments(todayRanges)[0])
|
||||
// By default, we always show the range between 8 - 19h, in order to give a stable impression
|
||||
// Ofc, a bigger range is used if needed
|
||||
let earliestOpen = Math.min(8 * 60 * 60, ...changeHours)
|
||||
// We always make sure there is 30m of leeway in order to give enough room for the closing entry
|
||||
let latestclose = Math.max(19 * 60 * 60, Math.max(...changeHours) + 30 * 60)
|
||||
let availableArea = latestclose - earliestOpen
|
||||
|
||||
function calcLineOffset(moment: number) {
|
||||
return 100 * (moment - earliestOpen) / availableArea
|
||||
}
|
||||
|
||||
let weekdays: Translation[] = [
|
||||
Translations.t.general.weekdays.abbreviations.monday,
|
||||
Translations.t.general.weekdays.abbreviations.tuesday,
|
||||
Translations.t.general.weekdays.abbreviations.wednesday,
|
||||
Translations.t.general.weekdays.abbreviations.thursday,
|
||||
Translations.t.general.weekdays.abbreviations.friday,
|
||||
Translations.t.general.weekdays.abbreviations.saturday,
|
||||
Translations.t.general.weekdays.abbreviations.sunday
|
||||
]
|
||||
|
||||
</script>
|
||||
<div class="w-full h-fit relative">
|
||||
{#each allChangeMoments as moment}
|
||||
<div class="w-full absolute h-full">
|
||||
<div class="w-full h-full flex">
|
||||
<div style="height: 5rem; width: 5%; min-width: 2.75rem" />
|
||||
<div class="grow">
|
||||
|
||||
<div class="border-x h-full"
|
||||
style={`width: calc( ${calcLineOffset(moment)}% ); border-color: ${todayChangeMoments.has(moment) ? "#000" : "#bbb"}`} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
<table class="w-full" style="border-collapse: collapse; word-break: normal; word-wrap: normal">
|
||||
{#each weekdayHeaders as weekdayHeader}
|
||||
<tr>
|
||||
<td style="width: 5%; min-width: 2.75rem;"></td>
|
||||
<td class="relative h-8">
|
||||
<OpeningHoursHeader {earliestOpen} {availableArea} changeHours={weekdayHeader.changeHours}
|
||||
{todayChangeMoments}
|
||||
changeHourText={weekdayHeader.changeTexts} />
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
{#each weekdays as weekday, i}
|
||||
<tr class:interactive={i >= 5}>
|
||||
<td style="width: 5%">
|
||||
<Transl t={weekday} />
|
||||
</td>
|
||||
<td class="relative p-0 m-0" class:ohviz-today={i===todayIndex}>
|
||||
<div class="w-full" style="margin-left: -0px">
|
||||
{#each ranges[i] as range}
|
||||
<OpeningHoursRangeElement
|
||||
{availableArea}
|
||||
{earliestOpen}
|
||||
{latestclose}
|
||||
{range}
|
||||
{isWeekstable}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/each}
|
||||
|
||||
{#each weekendDayHeaders as weekdayHeader}
|
||||
<tr>
|
||||
<td style="width: 5%"></td>
|
||||
<td class="relative h-8">
|
||||
<OpeningHoursHeader {earliestOpen} {availableArea} changeHours={weekdayHeader.changeHours}
|
||||
{todayChangeMoments}
|
||||
changeHourText={weekdayHeader.changeTexts} />
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue