Last fixes to the OH picker
This commit is contained in:
parent
64ec06bfc8
commit
48f66bd17e
11 changed files with 327 additions and 311 deletions
|
@ -210,6 +210,7 @@ export class InitUiElements {
|
||||||
|
|
||||||
// Reset the loading message once things are loaded
|
// Reset the loading message once things are loaded
|
||||||
new CenterMessageBox().AttachTo("centermessage");
|
new CenterMessageBox().AttachTo("centermessage");
|
||||||
|
document.getElementById("centermessage").classList.add("pointer-events-none")
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,10 +49,10 @@ export class OH {
|
||||||
|
|
||||||
let rangeStart = 0;
|
let rangeStart = 0;
|
||||||
let rangeEnd = 0;
|
let rangeEnd = 0;
|
||||||
|
|
||||||
function pushRule(){
|
function pushRule() {
|
||||||
const rule = stringPerWeekday[rangeStart];
|
const rule = stringPerWeekday[rangeStart];
|
||||||
if(rule === ""){
|
if (rule === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (rangeStart == (rangeEnd - 1)) {
|
if (rangeStart == (rangeEnd - 1)) {
|
||||||
|
@ -61,7 +61,7 @@ export class OH {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
rules.push(
|
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
|
* @constructor
|
||||||
*/
|
*/
|
||||||
public static MergeTimes(ohs: OpeningHour[]): OpeningHour[] {
|
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 = [];
|
const newList = [];
|
||||||
while (queue.length > 0) {
|
while (queue.length > 0) {
|
||||||
let maybeAdd = queue.pop();
|
let maybeAdd = queue.pop();
|
||||||
|
|
||||||
let doAddEntry = true;
|
let doAddEntry = true;
|
||||||
if(maybeAdd.weekday == undefined){
|
if (maybeAdd.weekday == undefined) {
|
||||||
doAddEntry = false;
|
doAddEntry = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,8 +149,8 @@ export class OH {
|
||||||
queue.push({
|
queue.push({
|
||||||
startHour: startHour,
|
startHour: startHour,
|
||||||
startMinutes: startMinutes,
|
startMinutes: startMinutes,
|
||||||
endHour:endHour,
|
endHour: endHour,
|
||||||
endMinutes:endMinutes,
|
endMinutes: endMinutes,
|
||||||
weekday: guard.weekday
|
weekday: guard.weekday
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -190,21 +199,6 @@ export class OH {
|
||||||
OH.endTime(checked) <= OH.endTime(mightLieIn)
|
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): {
|
public static parseHHMMRange(hhmmhhmm: string): {
|
||||||
startHour: number,
|
startHour: number,
|
||||||
startMinutes: 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[] {
|
public static ParseRule(rule: string): OpeningHour[] {
|
||||||
try {
|
try {
|
||||||
if (rule.trim() == "24/7") {
|
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) {
|
static Parse(rules: string) {
|
||||||
if (rules === undefined || rules === "") {
|
if (rules === undefined || rules === "") {
|
||||||
|
@ -342,7 +305,7 @@ export class OH {
|
||||||
const split = rules.split(";");
|
const split = rules.split(";");
|
||||||
|
|
||||||
for (const rule of split) {
|
for (const rule of split) {
|
||||||
if(rule === ""){
|
if (rule === "") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -376,7 +339,7 @@ export class OH {
|
||||||
}[][]): [number[], string[]] {
|
}[][]): [number[], string[]] {
|
||||||
const changeHours: number[] = []
|
const changeHours: number[] = []
|
||||||
const changeHourText: string[] = [];
|
const changeHourText: string[] = [];
|
||||||
|
|
||||||
const extrachangeHours: number[] = []
|
const extrachangeHours: number[] = []
|
||||||
const extrachangeHourText: string[] = [];
|
const extrachangeHourText: string[] = [];
|
||||||
|
|
||||||
|
@ -387,7 +350,7 @@ export class OH {
|
||||||
}
|
}
|
||||||
const startOfDay: Date = new Date(range.startDate);
|
const startOfDay: Date = new Date(range.startDate);
|
||||||
startOfDay.setHours(0, 0, 0, 0);
|
startOfDay.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
// The number of seconds since the start of the day
|
// The number of seconds since the start of the day
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const changeMoment: number = (range.startDate - startOfDay) / 1000;
|
const changeMoment: number = (range.startDate - startOfDay) / 1000;
|
||||||
|
@ -417,7 +380,7 @@ export class OH {
|
||||||
changeHours.sort();
|
changeHours.sort();
|
||||||
extrachangeHourText.sort();
|
extrachangeHourText.sort();
|
||||||
extrachangeHours.sort();
|
extrachangeHours.sort();
|
||||||
|
|
||||||
changeHourText.push(...extrachangeHourText);
|
changeHourText.push(...extrachangeHourText);
|
||||||
changeHours.push(...extrachangeHours);
|
changeHours.push(...extrachangeHours);
|
||||||
|
|
||||||
|
@ -476,6 +439,95 @@ export class OH {
|
||||||
}
|
}
|
||||||
return values;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,14 +37,14 @@ export default class OpeningHoursInput extends InputElement<string> {
|
||||||
if (OH.ParseRule(rule) !== null) {
|
if (OH.ParseRule(rule) !== null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (PublicHolidayInput.LoadValue(rule) !== null) {
|
if (OH.ParsePHRule(rule) !== null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
leftOvers.push(rule);
|
leftOvers.push(rule);
|
||||||
}
|
}
|
||||||
return leftOvers;
|
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 rulesFromOhPicker = value.map(OH.Parse);
|
||||||
|
|
||||||
const ph = value.map<string>(str => {
|
const ph = value.map<string>(str => {
|
||||||
|
@ -53,7 +53,7 @@ export default class OpeningHoursInput extends InputElement<string> {
|
||||||
}
|
}
|
||||||
const rules = str.split(";");
|
const rules = str.split(";");
|
||||||
for (const rule of rules) {
|
for (const rule of rules) {
|
||||||
if (PublicHolidayInput.LoadValue(rule) !== null) {
|
if (OH.ParsePHRule(rule) !== null) {
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||||
import OpeningHoursRange from "./OpeningHoursRange";
|
|
||||||
import Combine from "../Base/Combine";
|
|
||||||
import OpeningHoursPickerTable from "./OpeningHoursPickerTable";
|
import OpeningHoursPickerTable from "./OpeningHoursPickerTable";
|
||||||
import {OH, OpeningHour} from "./OpeningHours";
|
import {OH, OpeningHour} from "./OpeningHours";
|
||||||
import {InputElement} from "../Input/InputElement";
|
import {InputElement} from "../Input/InputElement";
|
||||||
|
@ -22,8 +20,6 @@ export default class OpeningHoursPicker extends InputElement<OpeningHour[]> {
|
||||||
|
|
||||||
this._backgroundTable = new OpeningHoursPickerTable(this._ohs);
|
this._backgroundTable = new OpeningHoursPickerTable(this._ohs);
|
||||||
this._backgroundTable.ConstructElement()
|
this._backgroundTable.ConstructElement()
|
||||||
|
|
||||||
ohs.ping();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InnerRender(): BaseUIElement {
|
InnerRender(): BaseUIElement {
|
||||||
|
|
|
@ -51,17 +51,23 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
||||||
|
|
||||||
const table = document.createElement("table")
|
const table = document.createElement("table")
|
||||||
table.classList.add("oh-table")
|
table.classList.add("oh-table")
|
||||||
|
|
||||||
|
const cellHeightInPx = 14;
|
||||||
|
|
||||||
const headerRow = document.createElement("tr")
|
const headerRow = document.createElement("tr")
|
||||||
headerRow.appendChild(document.createElement("th"))
|
headerRow.appendChild(document.createElement("th"))
|
||||||
|
headerRow.classList.add("relative")
|
||||||
for (let i = 0; i < OpeningHoursPickerTable.days.length; i++) {
|
for (let i = 0; i < OpeningHoursPickerTable.days.length; i++) {
|
||||||
let weekday = OpeningHoursPickerTable.days[i].Clone();
|
let weekday = OpeningHoursPickerTable.days[i].Clone();
|
||||||
const cell = document.createElement("th")
|
const cell = document.createElement("th")
|
||||||
cell.style.width = "14%"
|
cell.style.width = "14%"
|
||||||
cell.appendChild(weekday.ConstructElement())
|
cell.appendChild(weekday.ConstructElement())
|
||||||
|
|
||||||
const fullColumnSpan = this.weekdayElements[i]
|
const fullColumnSpan = this.weekdayElements[i]
|
||||||
fullColumnSpan.classList.add("w-full","h-full","relative")
|
fullColumnSpan.classList.add("w-full","relative")
|
||||||
fullColumnSpan.style.height = "42rem"
|
|
||||||
|
// 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(
|
const ranges = new VariableUiElement(
|
||||||
|
@ -98,7 +104,7 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
||||||
const hs = Utils.TwoDigits(h);
|
const hs = Utils.TwoDigits(h);
|
||||||
const firstCell = document.createElement("td")
|
const firstCell = document.createElement("td")
|
||||||
firstCell.rowSpan = 2
|
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())
|
firstCell.appendChild(new FixedUiElement(hs + ":00").ConstructElement())
|
||||||
|
|
||||||
const evenRow = document.createElement("tr")
|
const evenRow = document.createElement("tr")
|
||||||
|
@ -109,6 +115,9 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
||||||
cell.classList.add("oh-timecell", "oh-timecell-full", `oh-timecell-${weekday}`)
|
cell.classList.add("oh-timecell", "oh-timecell-full", `oh-timecell-${weekday}`)
|
||||||
evenRow.appendChild(cell)
|
evenRow.appendChild(cell)
|
||||||
}
|
}
|
||||||
|
evenRow.style.height = (cellHeightInPx)+"px";
|
||||||
|
evenRow.style.maxHeight = evenRow.style.height;
|
||||||
|
evenRow.style.minHeight = evenRow.style.height;
|
||||||
table.appendChild(evenRow)
|
table.appendChild(evenRow)
|
||||||
|
|
||||||
const oddRow = document.createElement("tr")
|
const oddRow = document.createElement("tr")
|
||||||
|
@ -118,6 +127,9 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
||||||
cell.classList.add("oh-timecell", "oh-timecell-half", `oh-timecell-${weekday}`)
|
cell.classList.add("oh-timecell", "oh-timecell-half", `oh-timecell-${weekday}`)
|
||||||
oddRow.appendChild(cell)
|
oddRow.appendChild(cell)
|
||||||
}
|
}
|
||||||
|
oddRow.style.minHeight = evenRow.style.height;
|
||||||
|
oddRow.style.maxHeight = evenRow.style.height;
|
||||||
|
|
||||||
table.appendChild(oddRow)
|
table.appendChild(oddRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,28 +24,28 @@ export default class OpeningHoursRange extends BaseUIElement {
|
||||||
InnerConstructElement(): HTMLElement {
|
InnerConstructElement(): HTMLElement {
|
||||||
const height = this.getHeight();
|
const height = this.getHeight();
|
||||||
const oh = this._oh;
|
const oh = this._oh;
|
||||||
const startTime = new FixedUiElement(Utils.TwoDigits(oh.startHour) + ":" + Utils.TwoDigits(oh.startMinutes)).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)).SetClass("oh-timerange-label")
|
const endTime = new FixedUiElement(Utils.TwoDigits(oh.endHour) + ":" + Utils.TwoDigits(oh.endMinutes))
|
||||||
|
|
||||||
|
|
||||||
const deleteRange =
|
const deleteRange =
|
||||||
Svg.delete_icon_ui()
|
Svg.delete_icon_ui()
|
||||||
.SetClass("oh-delete-range")
|
.SetClass("rounded-full w-6 h-6 block bg-black")
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
this._onDelete()
|
this._onDelete()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
let content = [deleteRange]
|
let content: BaseUIElement;
|
||||||
if (height > 2) {
|
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)
|
const el = new Combine([content]).ConstructElement();
|
||||||
.SetClass("oh-timerange-inner").ConstructElement();
|
|
||||||
|
|
||||||
el.style.top = (100 * OH.startTime(oh) / 24) + "%"
|
el.style.top = `${100 * OH.startTime(oh) / 24}%`
|
||||||
el.style.height = (100 * (OH.endTime(oh) - OH.startTime(oh)) / 24) + "%"
|
el.style.height = `${100 * this.getHeight() / 24}%`
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,166 +5,19 @@ import {TextField} from "../Input/TextField";
|
||||||
import {DropDown} from "../Input/DropDown";
|
import {DropDown} from "../Input/DropDown";
|
||||||
import {InputElement} from "../Input/InputElement";
|
import {InputElement} from "../Input/InputElement";
|
||||||
import Translations from "../i18n/Translations";
|
import Translations from "../i18n/Translations";
|
||||||
import BaseUIElement from "../BaseUIElement";
|
import Toggle from "../Input/Toggle";
|
||||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
|
||||||
|
|
||||||
export default class PublicHolidayInput extends InputElement<string> {
|
export default class PublicHolidayInput extends InputElement<string> {
|
||||||
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
|
||||||
|
|
||||||
private readonly _value: UIEventSource<string>;
|
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>("")) {
|
constructor(value: UIEventSource<string> = new UIEventSource<string>("")) {
|
||||||
super();
|
super();
|
||||||
this._value = value;
|
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> {
|
GetValue(): UIEventSource<string> {
|
||||||
return this._value;
|
return this._value;
|
||||||
}
|
}
|
||||||
|
@ -172,5 +25,97 @@ export default class PublicHolidayInput extends InputElement<string> {
|
||||||
IsValid(t: string): boolean {
|
IsValid(t: string): boolean {
|
||||||
return true;
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -64,6 +64,7 @@
|
||||||
font-size: large;
|
font-size: large;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-right: 0.2em;
|
padding-right: 0.2em;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.oh-timecell-0 {
|
.oh-timecell-0 {
|
||||||
|
@ -119,35 +120,6 @@
|
||||||
overflow: unset;
|
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 ****/
|
/**** Opening hours visualization table ****/
|
||||||
|
|
||||||
.ohviz-table {
|
.ohviz-table {
|
||||||
|
|
|
@ -151,7 +151,8 @@
|
||||||
"open_24_7": "Opened around the clock",
|
"open_24_7": "Opened around the clock",
|
||||||
"ph_not_known": " ",
|
"ph_not_known": " ",
|
||||||
"ph_closed": "closed",
|
"ph_closed": "closed",
|
||||||
"ph_open": "opened"
|
"ph_open": "opened with different hours",
|
||||||
|
"ph_open_as_usual": "opened as usual"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"favourite": {
|
"favourite": {
|
||||||
|
|
12
test.ts
12
test.ts
|
@ -8,6 +8,7 @@ import OpeningHoursPickerTable from "./UI/OpeningHours/OpeningHoursPickerTable";
|
||||||
import OpeningHoursPicker from "./UI/OpeningHours/OpeningHoursPicker";
|
import OpeningHoursPicker from "./UI/OpeningHours/OpeningHoursPicker";
|
||||||
import {OH, OpeningHour} from "./UI/OpeningHours/OpeningHours";
|
import {OH, OpeningHour} from "./UI/OpeningHours/OpeningHours";
|
||||||
import {VariableUiElement} from "./UI/Base/VariableUIElement";
|
import {VariableUiElement} from "./UI/Base/VariableUIElement";
|
||||||
|
import PublicHolidayInput from "./UI/OpeningHours/PublicHolidayInput";
|
||||||
|
|
||||||
|
|
||||||
const tagsSource = new UIEventSource({
|
const tagsSource = new UIEventSource({
|
||||||
|
@ -23,15 +24,8 @@ const tagsSource = new UIEventSource({
|
||||||
const state = new State(undefined)
|
const state = new State(undefined)
|
||||||
State.state = state
|
State.state = state
|
||||||
|
|
||||||
const ohData = new UIEventSource<OpeningHour[]>([{
|
const ohData = new UIEventSource<string>("")
|
||||||
weekday: 1,
|
new OpeningHoursPicker().AttachTo("maindiv")
|
||||||
startHour: 10,
|
|
||||||
startMinutes: 0
|
|
||||||
, endHour: 12,
|
|
||||||
endMinutes: 0
|
|
||||||
}])
|
|
||||||
new OpeningHoursPicker(ohData).AttachTo("maindiv")
|
|
||||||
new VariableUiElement(ohData.map(OH.ToString)).AttachTo("extradiv")
|
|
||||||
/*
|
/*
|
||||||
const allSpecials = SpecialVisualizations.specialVisualizations.map(spec => {
|
const allSpecials = SpecialVisualizations.specialVisualizations.map(spec => {
|
||||||
try{
|
try{
|
||||||
|
|
|
@ -352,6 +352,47 @@ export default class TagSpec extends T{
|
||||||
]);
|
]);
|
||||||
equal(rules, "Tu 10:00-12:00; Su 13:00-17:00");
|
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", () => {
|
["OH 24/7", () => {
|
||||||
const rules = OH.Parse("24/7");
|
const rules = OH.Parse("24/7");
|
||||||
equal(rules.length, 7);
|
equal(rules.length, 7);
|
||||||
|
@ -368,8 +409,10 @@ export default class TagSpec extends T{
|
||||||
equal(rules, null);
|
equal(rules, null);
|
||||||
}],
|
}],
|
||||||
["OH Parse PH 12:00-17:00", () => {
|
["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.mode, " ");
|
||||||
|
equal(rules.start, "12:00")
|
||||||
|
equal(rules.end, "17:00")
|
||||||
}],
|
}],
|
||||||
["Round", () => {
|
["Round", () => {
|
||||||
equal(Utils.Round(15), "15.0")
|
equal(Utils.Round(15), "15.0")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue