|
|
@@ -191,8 +191,7 @@ class Timeline extends LitElement {
|
|
|
const r = Ressource.toRessource(ressource);
|
|
|
|
|
|
if (r.parent !== undefined) {
|
|
|
- r.parent =
|
|
|
- this.getRessourceFromId(r.parent.id) ?? this.addRessource(r.parent);
|
|
|
+ r.parent = this.getRessourceFromId(r.parent.id) ?? this.addRessource(r.parent);
|
|
|
const idx = this.rows.indexOf(r.parent as Ressource);
|
|
|
if (idx > -1) {
|
|
|
this.rows[idx].children.push(r);
|
|
|
@@ -221,16 +220,11 @@ class Timeline extends LitElement {
|
|
|
output.ressources.push(ressource);
|
|
|
// remove the top level children from it's parent.
|
|
|
if (ressource.parent && depth === 0) {
|
|
|
- ressource.parent.children = ressource.parent.children.filter(
|
|
|
- (o) => o.id !== id
|
|
|
- );
|
|
|
+ ressource.parent.children = ressource.parent.children.filter((o) => o.id !== id);
|
|
|
}
|
|
|
this.rows.splice(i, 1);
|
|
|
} else if (ressource.parentId === id) {
|
|
|
- const partialOutput = this._removeRessourceById(
|
|
|
- ressource.id,
|
|
|
- depth + 1
|
|
|
- );
|
|
|
+ const partialOutput = this._removeRessourceById(ressource.id, depth + 1);
|
|
|
output.ressources.push(...partialOutput.ressources);
|
|
|
output.items.push(...partialOutput.items);
|
|
|
} else {
|
|
|
@@ -266,9 +260,7 @@ class Timeline extends LitElement {
|
|
|
this.addEvents(content.items);
|
|
|
} else {
|
|
|
ressource[key] = value;
|
|
|
- this.rows = this.rows.map((r) =>
|
|
|
- r.id == ressource.id ? ressource : r
|
|
|
- );
|
|
|
+ this.rows = this.rows.map((r) => (r.id == ressource.id ? ressource : r));
|
|
|
}
|
|
|
this._updateEventPosition(ressource);
|
|
|
return ressource;
|
|
|
@@ -304,8 +296,7 @@ class Timeline extends LitElement {
|
|
|
this.items = [...this.items, timeslot];
|
|
|
// Update timeslot status
|
|
|
timeslot.isDisplayed =
|
|
|
- timeslot.end > this._start.toDate() ||
|
|
|
- timeslot.start < this._end.toDate();
|
|
|
+ timeslot.end > this._start.toDate() || timeslot.start < this._end.toDate();
|
|
|
this._updateEventPosition(ressource);
|
|
|
return timeslot;
|
|
|
}
|
|
|
@@ -354,19 +345,14 @@ class Timeline extends LitElement {
|
|
|
start: points[i],
|
|
|
end: points[i + 1],
|
|
|
slots: timeslots.filter(
|
|
|
- (slot) =>
|
|
|
- slot.start.getTime() <= startTime && endTime <= slot.end.getTime()
|
|
|
+ (slot) => slot.start.getTime() <= startTime && endTime <= slot.end.getTime()
|
|
|
),
|
|
|
});
|
|
|
}
|
|
|
// Update rows height
|
|
|
- const lineCount = intervals.reduce(
|
|
|
- (acc, interval) => Math.max(acc, interval.slots.length),
|
|
|
- 0
|
|
|
- );
|
|
|
+ const lineCount = intervals.reduce((acc, interval) => Math.max(acc, interval.slots.length), 0);
|
|
|
ressource.height =
|
|
|
- this.rowHeight * Math.max(lineCount, 1) +
|
|
|
- (ressource.collapseChildren ? 5 : 0); // to avoid collapse rows
|
|
|
+ this.rowHeight * Math.max(lineCount, 1) + (ressource.collapseChildren ? 5 : 0); // to avoid collapse rows
|
|
|
// Solve the offset positioning of all items
|
|
|
const sortTimeslots = (a: Event, b: Event): number => {
|
|
|
const t = a.start.getTime() - b.start.getTime();
|
|
|
@@ -386,12 +372,8 @@ class Timeline extends LitElement {
|
|
|
}
|
|
|
intervals.forEach((intervals) => {
|
|
|
intervals.slots.sort(sortTimeslots);
|
|
|
- const usedOffset = intervals.slots
|
|
|
- .map((o) => o.offset)
|
|
|
- .filter((i) => i > -1);
|
|
|
- const availableOffset = potentialOffset.filter(
|
|
|
- (i) => !usedOffset.includes(i)
|
|
|
- );
|
|
|
+ const usedOffset = intervals.slots.map((o) => o.offset).filter((i) => i > -1);
|
|
|
+ const availableOffset = potentialOffset.filter((i) => !usedOffset.includes(i));
|
|
|
intervals.slots.forEach((slot) => {
|
|
|
if (slot.offset === -1) {
|
|
|
slot.offset = availableOffset.shift() || 0;
|
|
|
@@ -421,8 +403,7 @@ class Timeline extends LitElement {
|
|
|
// Starting & Ending date have different legend
|
|
|
(nextColumn.format(format) !== currentDate.format(format) ||
|
|
|
// OR 2 consecutive legends can accomodate at least 1 grid cell
|
|
|
- currentDate.add(1, legendUnit).diff(currentDate, "m") >=
|
|
|
- legendMinUnitSpan);
|
|
|
+ currentDate.add(1, legendUnit).diff(currentDate, "m") >= legendMinUnitSpan);
|
|
|
|
|
|
if (isLegendPossible) {
|
|
|
let currentHeader = currentDate.format(format);
|
|
|
@@ -463,9 +444,7 @@ class Timeline extends LitElement {
|
|
|
private _grabHeader(e: MouseEvent): void {
|
|
|
const root = this.shadowRoot;
|
|
|
if (root !== null) {
|
|
|
- const gridContainer = root.querySelector(
|
|
|
- ".jc-timeline-grid-container"
|
|
|
- ) as HTMLBaseElement;
|
|
|
+ const gridContainer = root.querySelector(".jc-timeline-grid-container") as HTMLBaseElement;
|
|
|
const headerContainer = root.querySelector(
|
|
|
".jc-timeline-grid-title-container"
|
|
|
) as HTMLBaseElement;
|
|
|
@@ -494,17 +473,9 @@ class Timeline extends LitElement {
|
|
|
const initialDate = slot[direction];
|
|
|
const resizeListener = (e: MouseEvent) => {
|
|
|
const newDate = dayjs(initialDate)
|
|
|
- .add(
|
|
|
- Math.round((e.clientX - startPos) / this.slotWidth) *
|
|
|
- this.slotDuration,
|
|
|
- "m"
|
|
|
- )
|
|
|
+ .add(Math.round((e.clientX - startPos) / this.slotWidth) * this.slotDuration, "m")
|
|
|
.toDate();
|
|
|
- if (
|
|
|
- direction === "start"
|
|
|
- ? newDate < localSlot.end
|
|
|
- : localSlot.start < newDate
|
|
|
- ) {
|
|
|
+ if (direction === "start" ? newDate < localSlot.end : localSlot.start < newDate) {
|
|
|
if (localSlot[localDir] !== newDate) {
|
|
|
localSlot[localDir] = newDate;
|
|
|
this.updateEventById(slot.id);
|
|
|
@@ -556,14 +527,11 @@ class Timeline extends LitElement {
|
|
|
const updatePosition = editable
|
|
|
? (e: MouseEvent) => {
|
|
|
const changeTime =
|
|
|
- Math.round((e.clientX - startPos) / this.slotWidth) *
|
|
|
- this.slotDuration;
|
|
|
+ Math.round((e.clientX - startPos) / this.slotWidth) * this.slotDuration;
|
|
|
return localSlots
|
|
|
.map((slot, index) => {
|
|
|
const prevStart = slot.start;
|
|
|
- slot.start = dayjs(startDates[index])
|
|
|
- .add(changeTime, "m")
|
|
|
- .toDate();
|
|
|
+ slot.start = dayjs(startDates[index]).add(changeTime, "m").toDate();
|
|
|
slot.end = dayjs(endDates[index]).add(changeTime, "m").toDate();
|
|
|
return prevStart.getTime() !== slot.start.getTime();
|
|
|
})
|
|
|
@@ -582,9 +550,7 @@ class Timeline extends LitElement {
|
|
|
if (rowId) {
|
|
|
const ressourceId = this.rows[Number(rowId)].id;
|
|
|
if (ressourceId !== localSlot.ressourceId) {
|
|
|
- const oldRessource = this.getRessourceFromId(
|
|
|
- localSlot.ressourceId
|
|
|
- ) as Ressource;
|
|
|
+ const oldRessource = this.getRessourceFromId(localSlot.ressourceId) as Ressource;
|
|
|
localSlot.ressourceId = ressourceId;
|
|
|
this._updateEventPosition(oldRessource);
|
|
|
return true;
|
|
|
@@ -669,19 +635,10 @@ class Timeline extends LitElement {
|
|
|
firstUpdated(): void {
|
|
|
const root = this.shadowRoot;
|
|
|
if (root !== null) {
|
|
|
- const gridContainer = root.querySelector(
|
|
|
- ".jc-timeline-grid-container"
|
|
|
- ) as HTMLBaseElement;
|
|
|
- const simplebar = new SimpleBar(
|
|
|
- gridContainer
|
|
|
- ).getScrollElement() as HTMLBaseElement;
|
|
|
+ const gridContainer = root.querySelector(".jc-timeline-grid-container") as HTMLBaseElement;
|
|
|
+ const simplebar = new SimpleBar(gridContainer).getScrollElement() as HTMLBaseElement;
|
|
|
syncronizeElementsScrolling(
|
|
|
- [
|
|
|
- simplebar,
|
|
|
- root.querySelector(
|
|
|
- ".jc-timeline-grid-title-container"
|
|
|
- ) as HTMLBaseElement,
|
|
|
- ],
|
|
|
+ [simplebar, root.querySelector(".jc-timeline-grid-title-container") as HTMLBaseElement],
|
|
|
"h"
|
|
|
);
|
|
|
syncronizeElementsScrolling(
|
|
|
@@ -701,11 +658,7 @@ class Timeline extends LitElement {
|
|
|
let rowTop = 0;
|
|
|
let ressource: Ressource;
|
|
|
let i: number;
|
|
|
- for (
|
|
|
- i = 0;
|
|
|
- i < this.rows.length && this.rows[i].id !== evt.ressourceId;
|
|
|
- i++
|
|
|
- ) {
|
|
|
+ for (i = 0; i < this.rows.length && this.rows[i].id !== evt.ressourceId; i++) {
|
|
|
ressource = this.rows[i];
|
|
|
if (ressource.show) {
|
|
|
rowTop += ressource.height ? ressource.height : this.rowHeight;
|
|
|
@@ -731,22 +684,14 @@ class Timeline extends LitElement {
|
|
|
if (!ressource.show) {
|
|
|
style.height = "";
|
|
|
style.top = rowTop - 6 + "px";
|
|
|
- return html`<div
|
|
|
- class="jc-timeslot empty"
|
|
|
- style="${styleMap(style)}"
|
|
|
- ></div>`;
|
|
|
+ return html`<div class="jc-timeslot empty" style="${styleMap(style)}"></div>`;
|
|
|
}
|
|
|
|
|
|
- let content: TemplateResult = html`<div class="jc-timeslot-title">
|
|
|
- ${evt.title}
|
|
|
- </div>
|
|
|
+ let content: TemplateResult = html`<div class="jc-timeslot-title">${evt.title}</div>
|
|
|
${evt.content ? unsafeHTML(evt.content) : ""}`;
|
|
|
- const resizer =
|
|
|
- evt.editable === null ? ressource.eventEditable : evt.editable;
|
|
|
+ const resizer = evt.editable === null ? ressource.eventEditable : evt.editable;
|
|
|
const editableRessource =
|
|
|
- evt.ressourceEditable === null
|
|
|
- ? ressource.eventRessourceEditable
|
|
|
- : evt.ressourceEditable;
|
|
|
+ evt.ressourceEditable === null ? ressource.eventRessourceEditable : evt.ressourceEditable;
|
|
|
if (resizer) {
|
|
|
content = html`<div
|
|
|
class="jc-timeslot-resizer-start"
|
|
|
@@ -759,9 +704,7 @@ class Timeline extends LitElement {
|
|
|
></div>`;
|
|
|
}
|
|
|
return html`<div
|
|
|
- class="jc-timeslot ${evt.moving ? "moving" : ""} ${evt.selected
|
|
|
- ? "selected"
|
|
|
- : ""}"
|
|
|
+ class="jc-timeslot ${evt.moving ? "moving" : ""} ${evt.selected ? "selected" : ""}"
|
|
|
start="${evt.start.getHours()}"
|
|
|
end="${evt.end.getHours()}"
|
|
|
style="${styleMap(style)}"
|
|
|
@@ -775,9 +718,7 @@ class Timeline extends LitElement {
|
|
|
${content}
|
|
|
</div>`;
|
|
|
}
|
|
|
- private _getCollapseRessourceHandler(
|
|
|
- item: Ressource
|
|
|
- ): (e: MouseEvent) => void {
|
|
|
+ private _getCollapseRessourceHandler(item: Ressource): (e: MouseEvent) => void {
|
|
|
return (_e: MouseEvent) => {
|
|
|
item.collapseChildren = !item.collapseChildren;
|
|
|
this._updateEventPosition(item);
|
|
|
@@ -806,9 +747,7 @@ class Timeline extends LitElement {
|
|
|
if (event.target instanceof HTMLElement) {
|
|
|
event.target.classList.remove("target");
|
|
|
const srcId = event.dataTransfer?.getData("text");
|
|
|
- const destinationId = event.target.parentElement?.getAttribute(
|
|
|
- "ressourceId"
|
|
|
- );
|
|
|
+ const destinationId = event.target.parentElement?.getAttribute("ressourceId");
|
|
|
if (srcId && destinationId && destinationId !== srcId) {
|
|
|
// Check if destination is not child of parent
|
|
|
const src = this.getRessourceFromId(srcId) as Ressource;
|
|
|
@@ -827,10 +766,7 @@ class Timeline extends LitElement {
|
|
|
let idx = this.rows.findIndex((v) => v.id === destinationId);
|
|
|
if (event.target.classList.contains("jc-ressource-below")) {
|
|
|
idx += 1;
|
|
|
- while (
|
|
|
- idx < this.rows.length &&
|
|
|
- this.rows[idx].descendantOf(destination)
|
|
|
- ) {
|
|
|
+ while (idx < this.rows.length && this.rows[idx].descendantOf(destination)) {
|
|
|
idx += 1;
|
|
|
}
|
|
|
}
|
|
|
@@ -850,8 +786,7 @@ class Timeline extends LitElement {
|
|
|
}
|
|
|
renderRessource(item: Ressource): TemplateResult {
|
|
|
const depth = item.depth;
|
|
|
- const style =
|
|
|
- `--depth:${depth};` + (item.height ? `height:${item.height}px;` : "");
|
|
|
+ const style = `--depth:${depth};` + (item.height ? `height:${item.height}px;` : "");
|
|
|
const hasChild = item.children.length > 0;
|
|
|
const collapseHandler = this._getCollapseRessourceHandler(item);
|
|
|
return html`<tr>
|
|
|
@@ -862,18 +797,12 @@ class Timeline extends LitElement {
|
|
|
@click="${this._getEventClickHandler(item)}"
|
|
|
>
|
|
|
<div class="jc-ressource-above"></div>
|
|
|
- <div
|
|
|
- class="jc-ressource"
|
|
|
- draggable="true"
|
|
|
- @dragstart="${this._onRessourceDragStart(item)}"
|
|
|
- >
|
|
|
+ <div class="jc-ressource" draggable="true" @dragstart="${this._onRessourceDragStart(item)}">
|
|
|
${Array(depth)
|
|
|
.fill(0)
|
|
|
.map((_i) => html`<i class="jc-spacer"></i>`)}${hasChild
|
|
|
? html`<i
|
|
|
- class="jc-spacer ${item.collapseChildren
|
|
|
- ? "extend"
|
|
|
- : "collapse"}"
|
|
|
+ class="jc-spacer ${item.collapseChildren ? "extend" : "collapse"}"
|
|
|
@click="${collapseHandler}"
|
|
|
></i>`
|
|
|
: html`<i class="jc-spacer"></i>`}
|
|
|
@@ -883,11 +812,7 @@ class Timeline extends LitElement {
|
|
|
</td>
|
|
|
</tr>`;
|
|
|
}
|
|
|
- private renderGridRow(
|
|
|
- columns: Array<Dayjs>,
|
|
|
- rowId = -1,
|
|
|
- height = 30
|
|
|
- ): TemplateResult {
|
|
|
+ private renderGridRow(columns: Array<Dayjs>, rowId = -1, height = 30): TemplateResult {
|
|
|
return html`<tr row-id="${rowId}">
|
|
|
${columns.map(
|
|
|
(d, i) =>
|
|
|
@@ -902,8 +827,7 @@ class Timeline extends LitElement {
|
|
|
</tr>`;
|
|
|
}
|
|
|
render(): TemplateResult {
|
|
|
- const nCol =
|
|
|
- Math.floor(this._end.diff(this._start, "m") / this.slotDuration) + 1;
|
|
|
+ const nCol = Math.floor(this._end.diff(this._start, "m") / this.slotDuration) + 1;
|
|
|
const columns: Array<Dayjs> = [];
|
|
|
for (let i = 0; i < nCol; i++) {
|
|
|
columns.push(this._start.add(this.slotDuration * i, "m"));
|
|
|
@@ -927,26 +851,17 @@ class Timeline extends LitElement {
|
|
|
>
|
|
|
${this.rowsTitle}
|
|
|
</div>
|
|
|
- <horizontal-resizer
|
|
|
- @resize-x="${this._handleResizeX}"
|
|
|
- ></horizontal-resizer>
|
|
|
+ <horizontal-resizer @resize-x="${this._handleResizeX}"></horizontal-resizer>
|
|
|
<div class="jc-timeline-grid-title-container">
|
|
|
- <table
|
|
|
- @mousedown="${this._grabHeader}"
|
|
|
- style="width:${nCol * this.slotWidth}px;"
|
|
|
- >
|
|
|
+ <table @mousedown="${this._grabHeader}" style="width:${nCol * this.slotWidth}px;">
|
|
|
<colgroup>
|
|
|
- ${columns.map(
|
|
|
- (_o) => html`<col style="min-width:${this.slotWidth}px" />`
|
|
|
- )}
|
|
|
+ ${columns.map((_) => html`<col style="min-width:${this.slotWidth}px" />`)}
|
|
|
</colgroup>
|
|
|
<tbody>
|
|
|
${this.legend.map(
|
|
|
(arr) =>
|
|
|
html`<tr class="jc-timeline-grid-title">
|
|
|
- ${arr.map(
|
|
|
- (o) => html`<th colspan="${o.colspan}"><div>${o.title}</div></th>`
|
|
|
- )}
|
|
|
+ ${arr.map((o) => html`<th colspan="${o.colspan}"><div>${o.title}</div></th>`)}
|
|
|
</tr>`
|
|
|
)}
|
|
|
</tbody>
|
|
|
@@ -968,22 +883,16 @@ class Timeline extends LitElement {
|
|
|
<td>No ressource</td>
|
|
|
</tr>`}
|
|
|
</table>
|
|
|
- <horizontal-resizer
|
|
|
- @resize-x="${this._handleResizeX}"
|
|
|
- ></horizontal-resizer>
|
|
|
+ <horizontal-resizer @resize-x="${this._handleResizeX}"></horizontal-resizer>
|
|
|
<div class="jc-timeline-grid-container">
|
|
|
<table style="width:${nCol * this.slotWidth}px;">
|
|
|
<colgroup>
|
|
|
- ${columns.map(
|
|
|
- (_o) => html`<col style="min-width:${this.slotWidth}px" />`
|
|
|
- )}
|
|
|
+ ${columns.map((_) => html`<col style="min-width:${this.slotWidth}px" />`)}
|
|
|
</colgroup>
|
|
|
|
|
|
<tbody>
|
|
|
${this.rows.length > 0
|
|
|
- ? displayedRows.map((o) =>
|
|
|
- this.renderGridRow(columns, o.i, o.r.height)
|
|
|
- )
|
|
|
+ ? displayedRows.map((o) => this.renderGridRow(columns, o.i, o.r.height))
|
|
|
: this.renderGridRow(columns)}
|
|
|
</tbody>
|
|
|
</table>
|