forked from MapComplete/MapComplete
Last fixes to the OH picker
This commit is contained in:
parent
64ec06bfc8
commit
48f66bd17e
11 changed files with 327 additions and 311 deletions
|
@ -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<string> {
|
||||
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||
|
||||
private readonly _value: UIEventSource<string>;
|
||||
private readonly _dropdown: BaseUIElement;
|
||||
private readonly _mode: UIEventSource<string>;
|
||||
private readonly _startHour: BaseUIElement;
|
||||
private readonly _endHour: BaseUIElement;
|
||||
private _element: VariableUiElement;
|
||||
|
||||
constructor(value: UIEventSource<string> = new UIEventSource<string>("")) {
|
||||
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<string> {
|
||||
return this._value;
|
||||
}
|
||||
|
@ -172,5 +25,97 @@ export default class PublicHolidayInput extends InputElement<string> {
|
|||
IsValid(t: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
private SetupDataSync(mode: UIEventSource<string>, startTime: UIEventSource<string>, endTime: UIEventSource<string>) {
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue