diff --git a/InitUiElements.ts b/InitUiElements.ts index 75b5824a4d..cb7cdc5623 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -210,6 +210,7 @@ export class InitUiElements { // Reset the loading message once things are loaded new CenterMessageBox().AttachTo("centermessage"); + document.getElementById("centermessage").classList.add("pointer-events-none") } diff --git a/UI/OpeningHours/OpeningHours.ts b/UI/OpeningHours/OpeningHours.ts index ede3e87c40..1b43f16c7b 100644 --- a/UI/OpeningHours/OpeningHours.ts +++ b/UI/OpeningHours/OpeningHours.ts @@ -49,10 +49,10 @@ export class OH { let rangeStart = 0; let rangeEnd = 0; - - function pushRule(){ + + function pushRule() { const rule = stringPerWeekday[rangeStart]; - if(rule === ""){ + if (rule === "") { return; } if (rangeStart == (rangeEnd - 1)) { @@ -61,7 +61,7 @@ export class OH { ); } else { rules.push( - `${OH.days[rangeStart]}-${OH.days[rangeEnd-1]} ${rule}` + `${OH.days[rangeStart]}-${OH.days[rangeEnd - 1]} ${rule}` ); } } @@ -90,13 +90,22 @@ export class OH { * @constructor */ public static MergeTimes(ohs: OpeningHour[]): OpeningHour[] { - const queue = [...ohs]; + const queue = ohs.map(oh => { + if (oh.endHour === 0 && oh.endMinutes === 0) { + const newOh = { + ...oh + } + newOh.endHour = 24 + return newOh + } + return oh; + }); const newList = []; while (queue.length > 0) { let maybeAdd = queue.pop(); let doAddEntry = true; - if(maybeAdd.weekday == undefined){ + if (maybeAdd.weekday == undefined) { doAddEntry = false; } @@ -140,8 +149,8 @@ export class OH { queue.push({ startHour: startHour, startMinutes: startMinutes, - endHour:endHour, - endMinutes:endMinutes, + endHour: endHour, + endMinutes: endMinutes, weekday: guard.weekday }); @@ -190,21 +199,6 @@ export class OH { OH.endTime(checked) <= OH.endTime(mightLieIn) } - private static parseHHMM(hhmm: string): { hours: number, minutes: number } { - if(hhmm === undefined || hhmm == null){ - return null; - } - const spl = hhmm.trim().split(":"); - if(spl.length != 2){ - return null; - } - const hm = {hours: Number(spl[0].trim()), minutes: Number(spl[1].trim())}; - if(isNaN(hm.hours) || isNaN(hm.minutes) ){ - return null; - } - return hm; - } - public static parseHHMMRange(hhmmhhmm: string): { startHour: number, startMinutes: number, @@ -226,80 +220,6 @@ export class OH { } } - private static ParseHhmmRanges(hhmms: string): { - startHour: number, - startMinutes: number, - endHour: number, - endMinutes: number - }[] { - if (hhmms === "off") { - return []; - } - return hhmms.split(",") - .map(s => s.trim()) - .filter(str => str !== "") - .map(OH.parseHHMMRange) - .filter(v => v != null) - } - - private static ParseWeekday(weekday: string): number { - return OH.daysIndexed[weekday.trim().toLowerCase()]; - } - - private static ParseWeekdayRange(weekdays: string): number[] { - const split = weekdays.split("-"); - if (split.length == 1) { - const parsed = OH.ParseWeekday(weekdays); - if(parsed == null){ - return null; - } - return [parsed]; - } else if (split.length == 2) { - let start = OH.ParseWeekday(split[0]); - let end = OH.ParseWeekday(split[1]); - if ((start ?? null) === null || (end ?? null) === null) { - return null; - } - let range = []; - for (let i = start; i <= end; i++) { - range.push(i); - } - return range; - } else { - return null; - } - } - - private static ParseWeekdayRanges(weekdays: string): number[] { - let ranges = []; - let split = weekdays.split(","); - for (const weekday of split) { - const parsed = OH.ParseWeekdayRange(weekday) - if (parsed === undefined || parsed === null) { - return null; - } - ranges.push(...parsed); - } - return ranges; - } - - private static multiply(weekdays: number[], timeranges: { startHour: number, startMinutes: number, endHour: number, endMinutes: number }[]) { - if ((weekdays ?? null) == null || (timeranges ?? null) == null) { - return null; - } - const ohs: OpeningHour[] = [] - for (const timerange of timeranges) { - for (const weekday of weekdays) { - ohs.push({ - weekday: weekday, - startHour: timerange.startHour, startMinutes: timerange.startMinutes, - endHour: timerange.endHour, endMinutes: timerange.endMinutes, - }); - } - } - return ohs; - } - public static ParseRule(rule: string): OpeningHour[] { try { if (rule.trim() == "24/7") { @@ -331,6 +251,49 @@ export class OH { } } + public static ParsePHRule(str: string): { + mode: string, + start?: string, + end?: string + } { + str = str.trim(); + if (!str.startsWith("PH")) { + return null; + } + + str = str.trim(); + if (str === "PH off") { + return { + mode: "off" + } + } + + if (str === "PH open") { + return { + mode: "open" + } + } + + if (!str.startsWith("PH ")) { + return null; + } + try { + + const timerange = OH.parseHHMMRange(str.substring(2)); + if (timerange === null) { + return null; + } + + return { + mode: " ", + start: OH.hhmm(timerange.startHour, timerange.startMinutes), + end: OH.hhmm(timerange.endHour, timerange.endMinutes), + + } + } catch (e) { + return null; + } + } static Parse(rules: string) { if (rules === undefined || rules === "") { @@ -342,7 +305,7 @@ export class OH { const split = rules.split(";"); for (const rule of split) { - if(rule === ""){ + if (rule === "") { continue; } try { @@ -376,7 +339,7 @@ export class OH { }[][]): [number[], string[]] { const changeHours: number[] = [] const changeHourText: string[] = []; - + const extrachangeHours: number[] = [] const extrachangeHourText: string[] = []; @@ -387,7 +350,7 @@ export class OH { } const startOfDay: Date = new Date(range.startDate); startOfDay.setHours(0, 0, 0, 0); - + // The number of seconds since the start of the day // @ts-ignore const changeMoment: number = (range.startDate - startOfDay) / 1000; @@ -417,7 +380,7 @@ export class OH { changeHours.sort(); extrachangeHourText.sort(); extrachangeHours.sort(); - + changeHourText.push(...extrachangeHourText); changeHours.push(...extrachangeHours); @@ -476,6 +439,95 @@ export class OH { } return values; } - + + private static parseHHMM(hhmm: string): { hours: number, minutes: number } { + if (hhmm === undefined || hhmm == null) { + return null; + } + const spl = hhmm.trim().split(":"); + if (spl.length != 2) { + return null; + } + const hm = {hours: Number(spl[0].trim()), minutes: Number(spl[1].trim())}; + if (isNaN(hm.hours) || isNaN(hm.minutes)) { + return null; + } + return hm; + } + + private static ParseHhmmRanges(hhmms: string): { + startHour: number, + startMinutes: number, + endHour: number, + endMinutes: number + }[] { + if (hhmms === "off") { + return []; + } + return hhmms.split(",") + .map(s => s.trim()) + .filter(str => str !== "") + .map(OH.parseHHMMRange) + .filter(v => v != null) + } + + private static ParseWeekday(weekday: string): number { + return OH.daysIndexed[weekday.trim().toLowerCase()]; + } + + private static ParseWeekdayRange(weekdays: string): number[] { + const split = weekdays.split("-"); + if (split.length == 1) { + const parsed = OH.ParseWeekday(weekdays); + if (parsed == null) { + return null; + } + return [parsed]; + } else if (split.length == 2) { + let start = OH.ParseWeekday(split[0]); + let end = OH.ParseWeekday(split[1]); + if ((start ?? null) === null || (end ?? null) === null) { + return null; + } + let range = []; + for (let i = start; i <= end; i++) { + range.push(i); + } + return range; + } else { + return null; + } + } + + private static ParseWeekdayRanges(weekdays: string): number[] { + let ranges = []; + let split = weekdays.split(","); + for (const weekday of split) { + const parsed = OH.ParseWeekdayRange(weekday) + if (parsed === undefined || parsed === null) { + return null; + } + ranges.push(...parsed); + } + return ranges; + } + + private static multiply(weekdays: number[], timeranges: { startHour: number, startMinutes: number, endHour: number, endMinutes: number }[]) { + if ((weekdays ?? null) == null || (timeranges ?? null) == null) { + return null; + } + const ohs: OpeningHour[] = [] + for (const timerange of timeranges) { + for (const weekday of weekdays) { + ohs.push({ + weekday: weekday, + startHour: timerange.startHour, startMinutes: timerange.startMinutes, + endHour: timerange.endHour, endMinutes: timerange.endMinutes, + }); + } + } + return ohs; + } + } diff --git a/UI/OpeningHours/OpeningHoursInput.ts b/UI/OpeningHours/OpeningHoursInput.ts index 1ac60467fa..f19a2cf6e3 100644 --- a/UI/OpeningHours/OpeningHoursInput.ts +++ b/UI/OpeningHours/OpeningHoursInput.ts @@ -37,14 +37,14 @@ export default class OpeningHoursInput extends InputElement { if (OH.ParseRule(rule) !== null) { continue; } - if (PublicHolidayInput.LoadValue(rule) !== null) { + if (OH.ParsePHRule(rule) !== null) { continue; } leftOvers.push(rule); } return leftOvers; }) - // NOte: MUST be bound AFTER the leftover rules! + // Note: MUST be bound AFTER the leftover rules! const rulesFromOhPicker = value.map(OH.Parse); const ph = value.map(str => { @@ -53,7 +53,7 @@ export default class OpeningHoursInput extends InputElement { } const rules = str.split(";"); for (const rule of rules) { - if (PublicHolidayInput.LoadValue(rule) !== null) { + if (OH.ParsePHRule(rule) !== null) { return rule; } } diff --git a/UI/OpeningHours/OpeningHoursPicker.ts b/UI/OpeningHours/OpeningHoursPicker.ts index a74c41c4db..e0c339f5b1 100644 --- a/UI/OpeningHours/OpeningHoursPicker.ts +++ b/UI/OpeningHours/OpeningHoursPicker.ts @@ -1,6 +1,4 @@ import {UIEventSource} from "../../Logic/UIEventSource"; -import OpeningHoursRange from "./OpeningHoursRange"; -import Combine from "../Base/Combine"; import OpeningHoursPickerTable from "./OpeningHoursPickerTable"; import {OH, OpeningHour} from "./OpeningHours"; import {InputElement} from "../Input/InputElement"; @@ -22,8 +20,6 @@ export default class OpeningHoursPicker extends InputElement { this._backgroundTable = new OpeningHoursPickerTable(this._ohs); this._backgroundTable.ConstructElement() - - ohs.ping(); } InnerRender(): BaseUIElement { diff --git a/UI/OpeningHours/OpeningHoursPickerTable.ts b/UI/OpeningHours/OpeningHoursPickerTable.ts index bbdee204fb..f9a430ce37 100644 --- a/UI/OpeningHours/OpeningHoursPickerTable.ts +++ b/UI/OpeningHours/OpeningHoursPickerTable.ts @@ -51,17 +51,23 @@ export default class OpeningHoursPickerTable extends InputElement const table = document.createElement("table") table.classList.add("oh-table") + + const cellHeightInPx = 14; const headerRow = document.createElement("tr") headerRow.appendChild(document.createElement("th")) + headerRow.classList.add("relative") for (let i = 0; i < OpeningHoursPickerTable.days.length; i++) { let weekday = OpeningHoursPickerTable.days[i].Clone(); const cell = document.createElement("th") cell.style.width = "14%" cell.appendChild(weekday.ConstructElement()) + const fullColumnSpan = this.weekdayElements[i] - fullColumnSpan.classList.add("w-full","h-full","relative") - fullColumnSpan.style.height = "42rem" + fullColumnSpan.classList.add("w-full","relative") + + // We need to round! The table height is rounded as following, we use this to calculate the actual number of pixels afterwards + fullColumnSpan.style.height = ( (cellHeightInPx) * 48) + "px" const ranges = new VariableUiElement( @@ -98,7 +104,7 @@ export default class OpeningHoursPickerTable extends InputElement const hs = Utils.TwoDigits(h); const firstCell = document.createElement("td") firstCell.rowSpan = 2 - firstCell.classList.add("oh-left-col", "oh-timecell-full", "border-box","h-2") + firstCell.classList.add("oh-left-col", "oh-timecell-full", "border-box") firstCell.appendChild(new FixedUiElement(hs + ":00").ConstructElement()) const evenRow = document.createElement("tr") @@ -109,6 +115,9 @@ export default class OpeningHoursPickerTable extends InputElement cell.classList.add("oh-timecell", "oh-timecell-full", `oh-timecell-${weekday}`) evenRow.appendChild(cell) } + evenRow.style.height = (cellHeightInPx)+"px"; + evenRow.style.maxHeight = evenRow.style.height; + evenRow.style.minHeight = evenRow.style.height; table.appendChild(evenRow) const oddRow = document.createElement("tr") @@ -118,6 +127,9 @@ export default class OpeningHoursPickerTable extends InputElement cell.classList.add("oh-timecell", "oh-timecell-half", `oh-timecell-${weekday}`) oddRow.appendChild(cell) } + oddRow.style.minHeight = evenRow.style.height; + oddRow.style.maxHeight = evenRow.style.height; + table.appendChild(oddRow) } diff --git a/UI/OpeningHours/OpeningHoursRange.ts b/UI/OpeningHours/OpeningHoursRange.ts index 24ec3db4d5..439aac490e 100644 --- a/UI/OpeningHours/OpeningHoursRange.ts +++ b/UI/OpeningHours/OpeningHoursRange.ts @@ -24,28 +24,28 @@ export default class OpeningHoursRange extends BaseUIElement { InnerConstructElement(): HTMLElement { const height = this.getHeight(); const oh = this._oh; - const startTime = new FixedUiElement(Utils.TwoDigits(oh.startHour) + ":" + Utils.TwoDigits(oh.startMinutes)).SetClass("oh-timerange-label") - const endTime = new FixedUiElement(Utils.TwoDigits(oh.endHour) + ":" + Utils.TwoDigits(oh.endMinutes)).SetClass("oh-timerange-label") - + const startTime = new FixedUiElement(Utils.TwoDigits(oh.startHour) + ":" + Utils.TwoDigits(oh.startMinutes)) + const endTime = new FixedUiElement(Utils.TwoDigits(oh.endHour) + ":" + Utils.TwoDigits(oh.endMinutes)) const deleteRange = Svg.delete_icon_ui() - .SetClass("oh-delete-range") + .SetClass("rounded-full w-6 h-6 block bg-black") .onClick(() => { this._onDelete() }); - let content = [deleteRange] + let content: BaseUIElement; if (height > 2) { - content = [startTime, deleteRange, endTime]; + content = new Combine([startTime, deleteRange, endTime]).SetClass("flex flex-col h-full").SetStyle("justify-content: space-between;"); + } else { + content = new Combine([deleteRange]).SetClass("flex flex-col h-full").SetStyle("flex-content: center; overflow-x: unset;") } - const el = new Combine(content) - .SetClass("oh-timerange-inner").ConstructElement(); + const el = new Combine([content]).ConstructElement(); - el.style.top = (100 * OH.startTime(oh) / 24) + "%" - el.style.height = (100 * (OH.endTime(oh) - OH.startTime(oh)) / 24) + "%" + el.style.top = `${100 * OH.startTime(oh) / 24}%` + el.style.height = `${100 * this.getHeight() / 24}%` return el; } diff --git a/UI/OpeningHours/PublicHolidayInput.ts b/UI/OpeningHours/PublicHolidayInput.ts index e470dcf98b..dd3c7b9f5f 100644 --- a/UI/OpeningHours/PublicHolidayInput.ts +++ b/UI/OpeningHours/PublicHolidayInput.ts @@ -5,166 +5,19 @@ import {TextField} from "../Input/TextField"; import {DropDown} from "../Input/DropDown"; import {InputElement} from "../Input/InputElement"; import Translations from "../i18n/Translations"; -import BaseUIElement from "../BaseUIElement"; -import {VariableUiElement} from "../Base/VariableUIElement"; +import Toggle from "../Input/Toggle"; export default class PublicHolidayInput extends InputElement { IsSelected: UIEventSource = new UIEventSource(false); private readonly _value: UIEventSource; - private readonly _dropdown: BaseUIElement; - private readonly _mode: UIEventSource; - private readonly _startHour: BaseUIElement; - private readonly _endHour: BaseUIElement; - private _element: VariableUiElement; constructor(value: UIEventSource = new UIEventSource("")) { super(); this._value = value; - - const dropdown = new DropDown( - Translations.t.general.opening_hours.open_during_ph, - [ - {shown: Translations.t.general.opening_hours.ph_not_known, value: ""}, - {shown: Translations.t.general.opening_hours.ph_closed, value: "off"}, - {shown:Translations.t.general.opening_hours.ph_open, value: " "} - ] - ); - this._dropdown = dropdown.SetStyle("display:inline-block;"); - this._mode = dropdown.GetValue(); - - const start = new TextField({ - placeholder: "starthour", - htmlType: "time" - }); - const end = new TextField({ - placeholder: "starthour", - htmlType: "time" - }); - this._startHour = start.SetStyle("display:inline-block;"); - this._endHour = end.SetStyle("display:inline-block;"); - const self = this; - - this._value.addCallbackAndRun(ph => { - if (ph === undefined) { - return; - } - const parsed = PublicHolidayInput.LoadValue(ph); - if (parsed === null) { - return; - } - - dropdown.GetValue().setData(parsed.mode); - if (parsed.start) { - start.GetValue().setData(parsed.start); - } - if (parsed.end) { - end.GetValue().setData(parsed.end); - } - - }) - - - function updateValue() { - const phStart = dropdown.GetValue().data; - if (phStart === undefined || phStart === "") { - // Unknown - self._value.setData(""); - return; - } - - if (phStart === " ") { - // THey are open, we need to include the start- and enddate - const startV = start.GetValue().data; - const endV = end.GetValue().data; - if (startV === undefined || endV === undefined) { - self._value.setData(`PH open`); - return; - } - - self._value.setData(`PH ${startV}-${endV}`); - return; - } - self._value.setData(`PH ${phStart}`); - } - - dropdown.GetValue().addCallbackAndRun(() => { - updateValue(); - }); - start.GetValue().addCallbackAndRun(() => { - updateValue(); - }); - end.GetValue().addCallbackAndRun(() => { - updateValue(); - }); - - this._element = new VariableUiElement(this._mode.map( - mode => { - if (mode === " ") { - return new Combine([this._dropdown, - " ", - Translations.t.general.opening_hours.opensAt, - " ", - this._startHour, - " ", - Translations.t.general.opening_hours.openTill, - " ", - this._endHour]); - } - return this._dropdown; - - })) } - protected InnerConstructElement(): HTMLElement { - return this._element.ConstructElement(); - } - - public static LoadValue(str: string): { - mode: string, - start?: string, - end?: string - } { - str = str.trim(); - if (!str.startsWith("PH")) { - return null; - } - - str = str.trim(); - if (str === "PH off") { - return { - mode: "off" - } - } - - if(str === "PH open"){ - return { - mode: " " - } - } - - if (!str.startsWith("PH ")) { - return null; - } - try { - - const timerange = OH.parseHHMMRange(str.substring(2)); - if (timerange === null) { - return null; - } - - return { - mode: " ", - start: OH.hhmm(timerange.startHour, timerange.startMinutes), - end: OH.hhmm(timerange.endHour, timerange.endMinutes), - - } - } catch (e) { - return null; - } - } - - + GetValue(): UIEventSource { return this._value; } @@ -172,5 +25,97 @@ export default class PublicHolidayInput extends InputElement { IsValid(t: string): boolean { return true; } + + private SetupDataSync(mode: UIEventSource, startTime: UIEventSource, endTime: UIEventSource) { + + const value = this._value; + value.addCallbackAndRun(ph => { + if (ph === undefined) { + return; + } + const parsed = OH.ParsePHRule(ph); + if (parsed === null) { + return; + } + mode.setData(parsed.mode) + startTime.setData(parsed.start) + endTime.setData(parsed.end) + }) + + // We use this as a 'addCallbackAndRun' + mode.map(mode => { + if (mode === undefined || mode === "") { + // not known + value.setData(undefined) + return + } + if (mode === "off") { + value.setData("PH off"); + return; + } + if (mode === "open") { + value.setData("PH open"); + return; + } + + + // Open during PH with special hours + if (startTime.data === undefined || endTime.data === undefined) { + // hours not filled in - not saveable + value.setData(undefined) + return + } + const oh = `PH ${startTime.data}-${endTime.data}` + value.setData(oh) + + + }, [startTime, endTime] + ) + } + + + protected InnerConstructElement(): HTMLElement { + const dropdown = new DropDown( + Translations.t.general.opening_hours.open_during_ph.Clone(), + [ + {shown: Translations.t.general.opening_hours.ph_not_known.Clone(), value: ""}, + {shown: Translations.t.general.opening_hours.ph_closed.Clone(), value: "off"}, + {shown:Translations.t.general.opening_hours.ph_open_as_usual.Clone(), value: "open"}, + {shown: Translations.t.general.opening_hours.ph_open.Clone(), value: " "}, + ] + ).SetClass("inline-block"); + /* + * Either "" (unknown), " " (opened) or "off" (closed) + * */ + const mode = dropdown.GetValue(); + + + const start = new TextField({ + placeholder: "starthour", + htmlType: "time" + }).SetClass("inline-block"); + const end = new TextField({ + placeholder: "starthour", + htmlType: "time" + }).SetClass("inline-block"); + + const askHours = new Toggle( + new Combine([ + Translations.t.general.opening_hours.opensAt.Clone(), + start, + Translations.t.general.opening_hours.openTill.Clone(), + end + ]), + undefined, + mode.map(mode => mode === " ") + ) + + this.SetupDataSync(mode, start.GetValue(), end.GetValue()) + + return new Combine([ + dropdown, + askHours + ]).ConstructElement() + } } \ No newline at end of file diff --git a/css/openinghourstable.css b/css/openinghourstable.css index a18958a5e1..fddff2496e 100644 --- a/css/openinghourstable.css +++ b/css/openinghourstable.css @@ -64,6 +64,7 @@ font-size: large; padding: 0; padding-right: 0.2em; + box-sizing: border-box; } .oh-timecell-0 { @@ -119,35 +120,6 @@ overflow: unset; } -.oh-timerange-inner { - display: flex; - flex-direction: column; - justify-content: center; - align-content: center; - height: 100%; - overflow-x: unset; -} - -.oh-timerange-inner-small { - display: flex; - flex-direction: row; - justify-content: space-between; - height: 100%; - width:100%; -} -.oh-delete-range{ - width: 1.5em; - height: 1.5em; - background:black; - border-radius:0.75em; -} - -.oh-delete-range img { - height: 100%; - max-width: 2em; -} - - /**** Opening hours visualization table ****/ .ohviz-table { diff --git a/langs/en.json b/langs/en.json index f5cd5594e6..b62ea003f8 100644 --- a/langs/en.json +++ b/langs/en.json @@ -151,7 +151,8 @@ "open_24_7": "Opened around the clock", "ph_not_known": " ", "ph_closed": "closed", - "ph_open": "opened" + "ph_open": "opened with different hours", + "ph_open_as_usual": "opened as usual" } }, "favourite": { diff --git a/test.ts b/test.ts index eeb50e7af4..5e1525b224 100644 --- a/test.ts +++ b/test.ts @@ -8,6 +8,7 @@ import OpeningHoursPickerTable from "./UI/OpeningHours/OpeningHoursPickerTable"; import OpeningHoursPicker from "./UI/OpeningHours/OpeningHoursPicker"; import {OH, OpeningHour} from "./UI/OpeningHours/OpeningHours"; import {VariableUiElement} from "./UI/Base/VariableUIElement"; +import PublicHolidayInput from "./UI/OpeningHours/PublicHolidayInput"; const tagsSource = new UIEventSource({ @@ -23,15 +24,8 @@ const tagsSource = new UIEventSource({ const state = new State(undefined) State.state = state -const ohData = new UIEventSource([{ - weekday: 1, - startHour: 10, - startMinutes: 0 - , endHour: 12, - endMinutes: 0 -}]) -new OpeningHoursPicker(ohData).AttachTo("maindiv") -new VariableUiElement(ohData.map(OH.ToString)).AttachTo("extradiv") +const ohData = new UIEventSource("") +new OpeningHoursPicker().AttachTo("maindiv") /* const allSpecials = SpecialVisualizations.specialVisualizations.map(spec => { try{ diff --git a/test/Tag.spec.ts b/test/Tag.spec.ts index b1bc0ae103..70f3b19055 100644 --- a/test/Tag.spec.ts +++ b/test/Tag.spec.ts @@ -352,6 +352,47 @@ export default class TagSpec extends T{ ]); equal(rules, "Tu 10:00-12:00; Su 13:00-17:00"); }], + ["JOIN OH with end hours", () =>{ + const rules = OH.ToString( + OH.MergeTimes([ + + { + weekday: 1, + endHour: 23, + endMinutes: 30, + startHour: 23, + startMinutes: 0 + }, { + weekday: 1, + endHour: 24, + endMinutes: 0, + startHour: 23, + startMinutes: 30 + }, + + ])); + equal(rules, "Tu 23:00-00:00"); + }], ["JOIN OH with overflowed hours", () =>{ + const rules = OH.ToString( + OH.MergeTimes([ + + { + weekday: 1, + endHour: 23, + endMinutes: 30, + startHour: 23, + startMinutes: 0 + }, { + weekday: 1, + endHour: 0, + endMinutes: 0, + startHour: 23, + startMinutes: 30 + }, + + ])); + equal(rules, "Tu 23:00-00:00"); + }], ["OH 24/7", () => { const rules = OH.Parse("24/7"); equal(rules.length, 7); @@ -368,8 +409,10 @@ export default class TagSpec extends T{ equal(rules, null); }], ["OH Parse PH 12:00-17:00", () => { - const rules = PublicHolidayInput.LoadValue("PH 12:00-17:00"); + const rules = OH.ParsePHRule("PH 12:00-17:00"); equal(rules.mode, " "); + equal(rules.start, "12:00") + equal(rules.end, "17:00") }], ["Round", () => { equal(Utils.Round(15), "15.0")