From b5c48f65b0fb744f210ec3d23c41d74ab2e042b9 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Jun 2022 17:27:23 +0200 Subject: [PATCH] Fix instabilities with complicated opening hours, fix #902 --- UI/OpeningHours/OpeningHoursInput.ts | 24 ++++++++++++++-------- UI/OpeningHours/OpeningHoursPicker.ts | 8 ++++++++ UI/OpeningHours/OpeningHoursPickerTable.ts | 3 ++- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/UI/OpeningHours/OpeningHoursInput.ts b/UI/OpeningHours/OpeningHoursInput.ts index d46b31853..ab0b0f62e 100644 --- a/UI/OpeningHours/OpeningHoursInput.ts +++ b/UI/OpeningHours/OpeningHoursInput.ts @@ -38,7 +38,8 @@ export default class OpeningHoursInput extends InputElement { return str.substring(prefix.length, str.length - postfix.length) } return str - }, [], noPrefix => { + }, [], + noPrefix => { if (noPrefix === undefined) { return undefined; } @@ -84,23 +85,30 @@ export default class OpeningHoursInput extends InputElement { // Note: MUST be bound AFTER the leftover rules! const rulesFromOhPicker: UIEventSource = valueWithoutPrefix.sync(str => { - console.log(">> Parsing '"+ str+"'") return OH.Parse(str); }, [leftoverRules, phSelector.GetValue()], (rules, oldString) => { - let str = OH.ToString(rules); + // We always add a ';', to easily add new rules. We remove the ';' again at the end of the function + // Important: spaces are _not_ allowed after a ';' as it'll destabilize the parsing! + let str = OH.ToString(rules) + ";" const ph = phSelector.GetValue().data; if(ph){ - str += "; "+ph + str += ph + ";" } - str += leftoverRules.data.join("; ") - if(!str.endsWith(";")){ - str += ";" + str += leftoverRules.data.join(";") + ";" + + str = str.trim() + if(str.endsWith(";")){ + str = str.substring(0, str.length - 1) } + if(str.startsWith(";")){ + str = str.substring(1) + } + str.trim() + if(str === oldString){ return oldString; // We pass a reference to the old string to stabilize the EventSource } - console.log("Reconstructed '"+ str+"'") return str; }); diff --git a/UI/OpeningHours/OpeningHoursPicker.ts b/UI/OpeningHours/OpeningHoursPicker.ts index e0c339f5b..54f1676af 100644 --- a/UI/OpeningHours/OpeningHoursPicker.ts +++ b/UI/OpeningHours/OpeningHoursPicker.ts @@ -34,6 +34,14 @@ export default class OpeningHoursPicker extends InputElement { return true; } + /** + * + * const rules = OH.ParseRule("Jul-Aug Sa closed; Mo,Tu,Th,Fr,PH 12:00-22:30, We 17:00-22:30, Sa 14:00-19:00, Su 10:00-21:00; Dec 24,25,31 off; Jan 1 off") + * const v = new UIEventSource(rules) + * const ohpicker = new OpeningHoursPicker(v) + * const html = ohpicker.InnerConstructElement() + * html !== undefined // => true + */ protected InnerConstructElement(): HTMLElement { return this._backgroundTable.ConstructElement(); } diff --git a/UI/OpeningHours/OpeningHoursPickerTable.ts b/UI/OpeningHours/OpeningHoursPickerTable.ts index 90fbd93c7..94ddb7a51 100644 --- a/UI/OpeningHours/OpeningHoursPickerTable.ts +++ b/UI/OpeningHours/OpeningHoursPickerTable.ts @@ -68,7 +68,8 @@ export default class OpeningHoursPickerTable extends InputElement const ranges = new VariableUiElement( - this.source.map(ohs => ohs.filter((oh: OpeningHour) => oh.weekday === i)) + this.source.map(ohs => + (ohs ?? []).filter((oh: OpeningHour) => oh.weekday === i)) .map(ohsForToday => { return new Combine(ohsForToday.map(oh => new OpeningHoursRange(oh, () => { this.source.data.splice(this.source.data.indexOf(oh), 1)