Refactoring: port small part of OHInput into svelte
This commit is contained in:
parent
013c2e4b61
commit
5f355aa3e2
3 changed files with 101 additions and 116 deletions
|
@ -10,9 +10,10 @@ import Combine from "../Base/Combine"
|
|||
import { FixedUiElement } from "../Base/FixedUiElement"
|
||||
import { OH, OpeningHour } from "./OpeningHours"
|
||||
import { InputElement } from "../Input/InputElement"
|
||||
import PublicHolidayInput from "./PublicHolidayInput"
|
||||
import Translations from "../i18n/Translations"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
import SvelteUIElement from "../Base/SvelteUIElement"
|
||||
import PublicHolidaySelector from "./PublicHolidaySelector.svelte"
|
||||
|
||||
export default class OpeningHoursInput extends InputElement<string> {
|
||||
private readonly _value: UIEventSource<string>
|
||||
|
@ -87,19 +88,19 @@ export default class OpeningHoursInput extends InputElement<string> {
|
|||
break
|
||||
}
|
||||
}
|
||||
const phSelector = new PublicHolidayInput(new UIEventSource<string>(ph))
|
||||
const phSelectorValue = new UIEventSource<string>(ph ?? "")
|
||||
|
||||
// Note: MUST be bound AFTER the leftover rules!
|
||||
const rulesFromOhPicker: UIEventSource<OpeningHour[]> = valueWithoutPrefix.sync(
|
||||
(str) => {
|
||||
return OH.Parse(str)
|
||||
},
|
||||
[leftoverRules, phSelector.GetValue()],
|
||||
[leftoverRules, phSelectorValue],
|
||||
(rules, oldString) => {
|
||||
// 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
|
||||
const ph = phSelectorValue.data
|
||||
if (ph) {
|
||||
str += ph + ";"
|
||||
}
|
||||
|
@ -138,7 +139,7 @@ export default class OpeningHoursInput extends InputElement<string> {
|
|||
|
||||
const ohPicker = new OpeningHoursPicker(rulesFromOhPicker)
|
||||
|
||||
this._element = new Combine([leftoverWarning, ohPicker, phSelector])
|
||||
this._element = new Combine([leftoverWarning, ohPicker, new SvelteUIElement(PublicHolidaySelector, {value: phSelectorValue})])
|
||||
}
|
||||
|
||||
GetValue(): UIEventSource<string> {
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
import { OH } from "./OpeningHours"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Combine from "../Base/Combine"
|
||||
import { TextField } from "../Input/TextField"
|
||||
import { DropDown } from "../Input/DropDown"
|
||||
import { InputElement } from "../Input/InputElement"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Toggle from "../Input/Toggle"
|
||||
|
||||
export default class PublicHolidayInput extends InputElement<string> {
|
||||
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false)
|
||||
|
||||
private readonly _value: UIEventSource<string>
|
||||
|
||||
constructor(value: UIEventSource<string> = new UIEventSource<string>("")) {
|
||||
super()
|
||||
this._value = value
|
||||
}
|
||||
|
||||
GetValue(): UIEventSource<string> {
|
||||
return this._value
|
||||
}
|
||||
|
||||
IsValid(_: string): boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
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 w-full")
|
||||
/*
|
||||
* 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]).SetClass("w-full flex").ConstructElement()
|
||||
}
|
||||
|
||||
private SetupDataSync(
|
||||
mode: UIEventSource<string>,
|
||||
startTime: UIEventSource<string>,
|
||||
endTime: UIEventSource<string>
|
||||
) {
|
||||
const value = this._value
|
||||
value
|
||||
.map((ph) => OH.ParsePHRule(ph))
|
||||
.addCallbackAndRunD((parsed) => {
|
||||
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]
|
||||
)
|
||||
}
|
||||
}
|
95
src/UI/OpeningHours/PublicHolidaySelector.svelte
Normal file
95
src/UI/OpeningHours/PublicHolidaySelector.svelte
Normal file
|
@ -0,0 +1,95 @@
|
|||
<script lang="ts">
|
||||
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import Dropdown from "../Base/Dropdown.svelte"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import ToSvelte from "../Base/ToSvelte.svelte"
|
||||
import { TextField } from "../Input/TextField"
|
||||
import { OH } from "./OpeningHours"
|
||||
|
||||
export let value: UIEventSource<string>
|
||||
let startValue: UIEventSource<string> = new UIEventSource<string>(undefined)
|
||||
let endValue: UIEventSource<string> = new UIEventSource<string>(undefined)
|
||||
|
||||
const t = Translations.t.general.opening_hours
|
||||
let mode = new UIEventSource("")
|
||||
|
||||
|
||||
value
|
||||
.map((ph) => OH.ParsePHRule(ph))
|
||||
.addCallbackAndRunD((parsed) => {
|
||||
if (parsed === null) {
|
||||
return
|
||||
}
|
||||
mode.setData(parsed.mode)
|
||||
startValue.setData(parsed.start)
|
||||
endValue.setData(parsed.end)
|
||||
})
|
||||
|
||||
function updateValue() {
|
||||
if (mode.data === undefined || mode.data === "") {
|
||||
// not known
|
||||
value.setData("")
|
||||
} else if (mode.data === "off") {
|
||||
value.setData("PH off")
|
||||
} else if (mode.data === "open") {
|
||||
value.setData("PH open")
|
||||
} else if (startValue.data === undefined || endValue.data === undefined) {
|
||||
// Open during PH with special hours
|
||||
// hours not filled in - not saveable
|
||||
value.setData(undefined)
|
||||
} else {
|
||||
value.setData(`PH ${startValue.data}-${endValue.data}`)
|
||||
}
|
||||
}
|
||||
|
||||
startValue.addCallbackAndRunD(() => updateValue())
|
||||
endValue.addCallbackAndRunD(() => updateValue())
|
||||
mode.addCallbackAndRunD(() => updateValue())
|
||||
|
||||
</script>
|
||||
|
||||
<label>
|
||||
|
||||
<Tr t={t.open_during_ph} />
|
||||
|
||||
<Dropdown value={mode}>
|
||||
<option value={""}>
|
||||
<Tr t={t.ph_not_known} />
|
||||
</option>
|
||||
|
||||
<option value={"off"}>
|
||||
<Tr t={t.ph_closed} />
|
||||
</option>
|
||||
|
||||
<option value={"open"}>
|
||||
<Tr t={t.ph_open_as_usual} />
|
||||
</option>
|
||||
|
||||
<option value={" "}> <!-- Yes, the value is a single space-->
|
||||
<Tr t={t.ph_open} />
|
||||
</option>
|
||||
</Dropdown>
|
||||
</label>
|
||||
|
||||
{#if $mode === " "}
|
||||
<div class="flex">
|
||||
<Tr t={t.opensAt} />
|
||||
<ToSvelte construct={
|
||||
|
||||
new TextField({
|
||||
value: startValue,
|
||||
placeholder: "starthour",
|
||||
htmlType: "time",
|
||||
}).SetClass("inline-block")
|
||||
} />
|
||||
<Tr t={t.openTill} />
|
||||
<ToSvelte construct={ new TextField({
|
||||
value: endValue,
|
||||
placeholder: "endhour",
|
||||
htmlType: "time",
|
||||
}).SetClass("inline-block")
|
||||
} />
|
||||
</div>
|
||||
{/if}
|
Loading…
Reference in a new issue