forked from MapComplete/MapComplete
Reformat all files with prettier
This commit is contained in:
parent
e22d189376
commit
b541d3eab4
382 changed files with 50893 additions and 35566 deletions
|
@ -2,61 +2,61 @@
|
|||
* This is the base-table which is selectable by hovering over it.
|
||||
* It will genarate the currently selected opening hour.
|
||||
*/
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
import {Utils} from "../../Utils";
|
||||
import {OpeningHour} from "./OpeningHours";
|
||||
import {InputElement} from "../Input/InputElement";
|
||||
import Translations from "../i18n/Translations";
|
||||
import {Translation} from "../i18n/Translation";
|
||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||
import {VariableUiElement} from "../Base/VariableUIElement";
|
||||
import Combine from "../Base/Combine";
|
||||
import OpeningHoursRange from "./OpeningHoursRange";
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
import { Utils } from "../../Utils"
|
||||
import { OpeningHour } from "./OpeningHours"
|
||||
import { InputElement } from "../Input/InputElement"
|
||||
import Translations from "../i18n/Translations"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
import { FixedUiElement } from "../Base/FixedUiElement"
|
||||
import { VariableUiElement } from "../Base/VariableUIElement"
|
||||
import Combine from "../Base/Combine"
|
||||
import OpeningHoursRange from "./OpeningHoursRange"
|
||||
|
||||
export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]> {
|
||||
public static readonly days: Translation[] =
|
||||
[
|
||||
Translations.t.general.weekdays.abbreviations.monday,
|
||||
Translations.t.general.weekdays.abbreviations.tuesday,
|
||||
Translations.t.general.weekdays.abbreviations.wednesday,
|
||||
Translations.t.general.weekdays.abbreviations.thursday,
|
||||
Translations.t.general.weekdays.abbreviations.friday,
|
||||
Translations.t.general.weekdays.abbreviations.saturday,
|
||||
Translations.t.general.weekdays.abbreviations.sunday
|
||||
]
|
||||
public static readonly days: Translation[] = [
|
||||
Translations.t.general.weekdays.abbreviations.monday,
|
||||
Translations.t.general.weekdays.abbreviations.tuesday,
|
||||
Translations.t.general.weekdays.abbreviations.wednesday,
|
||||
Translations.t.general.weekdays.abbreviations.thursday,
|
||||
Translations.t.general.weekdays.abbreviations.friday,
|
||||
Translations.t.general.weekdays.abbreviations.saturday,
|
||||
Translations.t.general.weekdays.abbreviations.sunday,
|
||||
]
|
||||
/*
|
||||
These html-elements are an overlay over the table columns and act as a host for the ranges in the weekdays
|
||||
*/
|
||||
public readonly weekdayElements: HTMLElement[] = Utils.TimesT(7, () => document.createElement("div"))
|
||||
private readonly source: UIEventSource<OpeningHour[]>;
|
||||
public readonly weekdayElements: HTMLElement[] = Utils.TimesT(7, () =>
|
||||
document.createElement("div")
|
||||
)
|
||||
private readonly source: UIEventSource<OpeningHour[]>
|
||||
|
||||
constructor(source?: UIEventSource<OpeningHour[]>) {
|
||||
super();
|
||||
this.source = source ?? new UIEventSource<OpeningHour[]>([]);
|
||||
this.SetStyle("width:100%;height:100%;display:block;");
|
||||
super()
|
||||
this.source = source ?? new UIEventSource<OpeningHour[]>([])
|
||||
this.SetStyle("width:100%;height:100%;display:block;")
|
||||
}
|
||||
|
||||
IsValid(t: OpeningHour[]): boolean {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
|
||||
GetValue(): UIEventSource<OpeningHour[]> {
|
||||
return this.source;
|
||||
return this.source
|
||||
}
|
||||
|
||||
protected InnerConstructElement(): HTMLElement {
|
||||
|
||||
const table = document.createElement("table")
|
||||
table.classList.add("oh-table")
|
||||
table.classList.add("relative") // Workaround for webkit-based viewers, see #1019
|
||||
|
||||
const cellHeightInPx = 14;
|
||||
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();
|
||||
let weekday = OpeningHoursPickerTable.days[i].Clone()
|
||||
const cell = document.createElement("th")
|
||||
cell.style.width = "14%"
|
||||
cell.appendChild(weekday.ConstructElement())
|
||||
|
@ -65,22 +65,25 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
|||
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"
|
||||
|
||||
fullColumnSpan.style.height = cellHeightInPx * 48 + "px"
|
||||
|
||||
const ranges = new VariableUiElement(
|
||||
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)
|
||||
this.source.ping()
|
||||
})))
|
||||
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)
|
||||
this.source.ping()
|
||||
})
|
||||
)
|
||||
)
|
||||
})
|
||||
)
|
||||
fullColumnSpan.appendChild(ranges.ConstructElement())
|
||||
|
||||
|
||||
const fullColumnSpanWrapper = document.createElement("div")
|
||||
fullColumnSpanWrapper.classList.add("absolute")
|
||||
fullColumnSpanWrapper.style.zIndex = "10"
|
||||
|
@ -95,26 +98,25 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
|||
|
||||
table.appendChild(headerRow)
|
||||
|
||||
const self = this;
|
||||
const self = this
|
||||
for (let h = 0; h < 24; h++) {
|
||||
|
||||
const hs = Utils.TwoDigits(h);
|
||||
const hs = Utils.TwoDigits(h)
|
||||
const firstCell = document.createElement("td")
|
||||
firstCell.rowSpan = 2
|
||||
firstCell.classList.add("oh-left-col", "oh-timecell-full", "border-box")
|
||||
firstCell.appendChild(new FixedUiElement(hs + ":00").ConstructElement())
|
||||
|
||||
const evenRow = document.createElement("tr")
|
||||
evenRow.appendChild(firstCell);
|
||||
evenRow.appendChild(firstCell)
|
||||
|
||||
for (let weekday = 0; weekday < 7; weekday++) {
|
||||
const cell = document.createElement("td")
|
||||
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;
|
||||
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")
|
||||
|
@ -124,64 +126,62 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
|||
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;
|
||||
oddRow.style.minHeight = evenRow.style.height
|
||||
oddRow.style.maxHeight = evenRow.style.height
|
||||
|
||||
table.appendChild(oddRow)
|
||||
}
|
||||
|
||||
|
||||
/**** Event handling below ***/
|
||||
|
||||
|
||||
let mouseIsDown = false;
|
||||
let selectionStart: [number, number] = undefined;
|
||||
let selectionEnd: [number, number] = undefined;
|
||||
let mouseIsDown = false
|
||||
let selectionStart: [number, number] = undefined
|
||||
let selectionEnd: [number, number] = undefined
|
||||
|
||||
function h(timeSegment: number) {
|
||||
return Math.floor(timeSegment / 2);
|
||||
return Math.floor(timeSegment / 2)
|
||||
}
|
||||
|
||||
function m(timeSegment: number) {
|
||||
return (timeSegment % 2) * 30;
|
||||
return (timeSegment % 2) * 30
|
||||
}
|
||||
|
||||
function startSelection(i: number, j: number) {
|
||||
mouseIsDown = true;
|
||||
selectionStart = [i, j];
|
||||
selectionEnd = [i, j];
|
||||
mouseIsDown = true
|
||||
selectionStart = [i, j]
|
||||
selectionEnd = [i, j]
|
||||
}
|
||||
|
||||
function endSelection() {
|
||||
if (selectionStart === undefined) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (!mouseIsDown) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
mouseIsDown = false
|
||||
const dStart = Math.min(selectionStart[1], selectionEnd[1]);
|
||||
const dEnd = Math.max(selectionStart[1], selectionEnd[1]);
|
||||
const timeStart = Math.min(selectionStart[0], selectionEnd[0]) - 1;
|
||||
const timeEnd = Math.max(selectionStart[0], selectionEnd[0]) - 1;
|
||||
const dStart = Math.min(selectionStart[1], selectionEnd[1])
|
||||
const dEnd = Math.max(selectionStart[1], selectionEnd[1])
|
||||
const timeStart = Math.min(selectionStart[0], selectionEnd[0]) - 1
|
||||
const timeEnd = Math.max(selectionStart[0], selectionEnd[0]) - 1
|
||||
for (let weekday = dStart; weekday <= dEnd; weekday++) {
|
||||
const oh: OpeningHour = {
|
||||
weekday: weekday,
|
||||
startHour: h(timeStart),
|
||||
startMinutes: m(timeStart),
|
||||
endHour: h(timeEnd + 1),
|
||||
endMinutes: m(timeEnd + 1)
|
||||
endMinutes: m(timeEnd + 1),
|
||||
}
|
||||
if (oh.endHour > 23) {
|
||||
oh.endHour = 24;
|
||||
oh.endMinutes = 0;
|
||||
oh.endHour = 24
|
||||
oh.endMinutes = 0
|
||||
}
|
||||
self.source.data.push(oh);
|
||||
self.source.data.push(oh)
|
||||
}
|
||||
self.source.ping();
|
||||
self.source.ping()
|
||||
|
||||
// Clear the highlighting
|
||||
let header = table.rows[0];
|
||||
let header = table.rows[0]
|
||||
for (let j = 1; j < header.cells.length; j++) {
|
||||
header.cells[j].classList?.remove("oh-timecol-selected")
|
||||
}
|
||||
|
@ -189,66 +189,63 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
|||
let row = table.rows[i]
|
||||
for (let j = 0; j < row.cells.length; j++) {
|
||||
let cell = row.cells[j]
|
||||
cell?.classList?.remove("oh-timecell-selected");
|
||||
row.classList?.remove("oh-timerow-selected");
|
||||
cell?.classList?.remove("oh-timecell-selected")
|
||||
row.classList?.remove("oh-timerow-selected")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.onmouseup = () => {
|
||||
endSelection();
|
||||
};
|
||||
endSelection()
|
||||
}
|
||||
table.onmouseleave = () => {
|
||||
endSelection();
|
||||
};
|
||||
endSelection()
|
||||
}
|
||||
|
||||
let lastSelectionIend, lastSelectionJEnd;
|
||||
let lastSelectionIend, lastSelectionJEnd
|
||||
|
||||
function selectAllBetween(iEnd, jEnd) {
|
||||
|
||||
if (lastSelectionIend === iEnd && lastSelectionJEnd === jEnd) {
|
||||
return; // We already did this
|
||||
return // We already did this
|
||||
}
|
||||
lastSelectionIend = iEnd;
|
||||
lastSelectionJEnd = jEnd;
|
||||
lastSelectionIend = iEnd
|
||||
lastSelectionJEnd = jEnd
|
||||
|
||||
let iStart = selectionStart[0];
|
||||
let jStart = selectionStart[1];
|
||||
let iStart = selectionStart[0]
|
||||
let jStart = selectionStart[1]
|
||||
|
||||
if (iStart > iEnd) {
|
||||
const h = iStart;
|
||||
iStart = iEnd;
|
||||
iEnd = h;
|
||||
const h = iStart
|
||||
iStart = iEnd
|
||||
iEnd = h
|
||||
}
|
||||
if (jStart > jEnd) {
|
||||
const h = jStart;
|
||||
jStart = jEnd;
|
||||
jEnd = h;
|
||||
const h = jStart
|
||||
jStart = jEnd
|
||||
jEnd = h
|
||||
}
|
||||
|
||||
let header = table.rows[0];
|
||||
let header = table.rows[0]
|
||||
for (let j = 1; j < header.cells.length; j++) {
|
||||
let cell = header.cells[j]
|
||||
cell.classList?.remove("oh-timecol-selected-round-left");
|
||||
cell.classList?.remove("oh-timecol-selected-round-right");
|
||||
cell.classList?.remove("oh-timecol-selected-round-left")
|
||||
cell.classList?.remove("oh-timecol-selected-round-right")
|
||||
|
||||
if (jStart + 1 <= j && j <= jEnd + 1) {
|
||||
cell.classList?.add("oh-timecol-selected")
|
||||
if (jStart + 1 == j) {
|
||||
cell.classList?.add("oh-timecol-selected-round-left");
|
||||
cell.classList?.add("oh-timecol-selected-round-left")
|
||||
}
|
||||
if (jEnd + 1 == j) {
|
||||
cell.classList?.add("oh-timecol-selected-round-right");
|
||||
cell.classList?.add("oh-timecol-selected-round-right")
|
||||
}
|
||||
|
||||
} else {
|
||||
cell.classList?.remove("oh-timecol-selected")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (let i = 1; i < table.rows.length; i++) {
|
||||
let row = table.rows[i];
|
||||
let row = table.rows[i]
|
||||
if (iStart <= i && i <= iEnd) {
|
||||
row.classList?.add("oh-timerow-selected")
|
||||
} else {
|
||||
|
@ -257,28 +254,23 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
|||
for (let j = 0; j < row.cells.length; j++) {
|
||||
let cell = row.cells[j]
|
||||
if (cell === undefined) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
let offset = 0;
|
||||
let offset = 0
|
||||
if (i % 2 == 1) {
|
||||
if (j == 0) {
|
||||
// This is the first column of a full hour -> This is the time indication (skip)
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
offset = -1;
|
||||
offset = -1
|
||||
}
|
||||
|
||||
|
||||
if (iStart <= i && i <= iEnd &&
|
||||
jStart <= j + offset && j + offset <= jEnd) {
|
||||
if (iStart <= i && i <= iEnd && jStart <= j + offset && j + offset <= jEnd) {
|
||||
cell?.classList?.add("oh-timecell-selected")
|
||||
} else {
|
||||
cell?.classList?.remove("oh-timecell-selected")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,63 +278,54 @@ export default class OpeningHoursPickerTable extends InputElement<OpeningHour[]>
|
|||
let row = table.rows[i]
|
||||
for (let j = 0; j < row.cells.length; j++) {
|
||||
let cell = row.cells[j]
|
||||
let offset = 0;
|
||||
let offset = 0
|
||||
if (i % 2 == 1) {
|
||||
if (j == 0) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
offset = -1;
|
||||
offset = -1
|
||||
}
|
||||
|
||||
|
||||
cell.onmousedown = (ev) => {
|
||||
ev.preventDefault();
|
||||
ev.preventDefault()
|
||||
startSelection(i, j + offset)
|
||||
selectAllBetween(i, j + offset);
|
||||
selectAllBetween(i, j + offset)
|
||||
}
|
||||
cell.ontouchstart = (ev) => {
|
||||
ev.preventDefault();
|
||||
startSelection(i, j + offset);
|
||||
selectAllBetween(i, j + offset);
|
||||
ev.preventDefault()
|
||||
startSelection(i, j + offset)
|
||||
selectAllBetween(i, j + offset)
|
||||
}
|
||||
cell.onmouseenter = () => {
|
||||
if (mouseIsDown) {
|
||||
selectionEnd = [i, j + offset];
|
||||
selectionEnd = [i, j + offset]
|
||||
selectAllBetween(i, j + offset)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cell.ontouchmove = (ev: TouchEvent) => {
|
||||
|
||||
ev.preventDefault();
|
||||
ev.preventDefault()
|
||||
for (const k in ev.targetTouches) {
|
||||
const touch = ev.targetTouches[k];
|
||||
const touch = ev.targetTouches[k]
|
||||
if (touch.clientX === undefined || touch.clientY === undefined) {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
const elUnderTouch = document.elementFromPoint(
|
||||
touch.clientX,
|
||||
touch.clientY
|
||||
);
|
||||
const elUnderTouch = document.elementFromPoint(touch.clientX, touch.clientY)
|
||||
// @ts-ignore
|
||||
const f = elUnderTouch.onmouseenter;
|
||||
const f = elUnderTouch.onmouseenter
|
||||
if (f) {
|
||||
f();
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cell.ontouchend = (ev) => {
|
||||
ev.preventDefault();
|
||||
endSelection();
|
||||
ev.preventDefault()
|
||||
endSelection()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return table
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue