|
@@ -3,6 +3,7 @@ import { Event, IEvent } from './Event'
|
|
|
|
|
|
|
|
import { Ressource, IRessource } from './Ressource'
|
|
import { Ressource, IRessource } from './Ressource'
|
|
|
|
|
|
|
|
|
|
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
import { HorizontalResizer } from './components/horizontal-resizer'
|
|
import { HorizontalResizer } from './components/horizontal-resizer'
|
|
|
import { LitElement, html, customElement, property, css, TemplateResult } from 'lit-element';
|
|
import { LitElement, html, customElement, property, css, TemplateResult } from 'lit-element';
|
|
|
import { styleMap } from 'lit-html/directives/style-map';
|
|
import { styleMap } from 'lit-html/directives/style-map';
|
|
@@ -34,7 +35,6 @@ interface legendItem {
|
|
|
}
|
|
}
|
|
|
// TODO define std zoom level
|
|
// TODO define std zoom level
|
|
|
// TODO add selectable Slot
|
|
// TODO add selectable Slot
|
|
|
-// TODO Improve Selected Ressource style
|
|
|
|
|
// TODO enable to rearrange between different component.
|
|
// TODO enable to rearrange between different component.
|
|
|
|
|
|
|
|
|
|
|
|
@@ -360,19 +360,19 @@ class Timeline extends LitElement {
|
|
|
return this.style.getPropertyValue("--default-background");
|
|
return this.style.getPropertyValue("--default-background");
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
- setLegendUnitFormatAll(legend:Partial<UnitLegend>){
|
|
|
|
|
|
|
+ setLegendUnitFormatAll(legend:Partial<UnitLegend>):void{
|
|
|
this.legendUnitFormat = {...this.legendUnitFormat, ...legend}
|
|
this.legendUnitFormat = {...this.legendUnitFormat, ...legend}
|
|
|
this.updateLegend()
|
|
this.updateLegend()
|
|
|
}
|
|
}
|
|
|
- setLegendUnitFormat(unit:dayjsUnit, format:string){
|
|
|
|
|
|
|
+ setLegendUnitFormat(unit:dayjsUnit, format:string):void{
|
|
|
this.legendUnitFormat[unit] = format;
|
|
this.legendUnitFormat[unit] = format;
|
|
|
this.updateLegend()
|
|
this.updateLegend()
|
|
|
}
|
|
}
|
|
|
- addRessources(list:Array<IRessource>){
|
|
|
|
|
|
|
+ addRessources(list:Array<IRessource>):Array<Ressource | undefined>{
|
|
|
return list.map(r=>this.addRessource(r));
|
|
return list.map(r=>this.addRessource(r));
|
|
|
}
|
|
}
|
|
|
// Ressource management
|
|
// Ressource management
|
|
|
- addRessource(ressource: IRessource): IRessource | undefined {
|
|
|
|
|
|
|
+ addRessource(ressource: IRessource): Ressource | undefined {
|
|
|
if (this.rows.filter(o => o.id == ressource.id).length > 0) {
|
|
if (this.rows.filter(o => o.id == ressource.id).length > 0) {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -395,7 +395,7 @@ class Timeline extends LitElement {
|
|
|
removeRessourceById(id: string): TimelineContent {
|
|
removeRessourceById(id: string): TimelineContent {
|
|
|
return this._removeRessourceById(id);
|
|
return this._removeRessourceById(id);
|
|
|
}
|
|
}
|
|
|
- _removeRessourceById(id: string, depth = 0){
|
|
|
|
|
|
|
+ _removeRessourceById(id: string, depth = 0):TimelineContent{
|
|
|
const output: TimelineContent = { ressources: [], items: [] };
|
|
const output: TimelineContent = { ressources: [], items: [] };
|
|
|
|
|
|
|
|
for (let i = 0; i < this.rows.length; i) {
|
|
for (let i = 0; i < this.rows.length; i) {
|
|
@@ -429,20 +429,20 @@ class Timeline extends LitElement {
|
|
|
const tmp = this.rows.filter(r=>r.id===id)
|
|
const tmp = this.rows.filter(r=>r.id===id)
|
|
|
return tmp.length > 0 ? tmp[0] : null;
|
|
return tmp.length > 0 ? tmp[0] : null;
|
|
|
}
|
|
}
|
|
|
- setRowsTitle(title: string) {
|
|
|
|
|
|
|
+ setRowsTitle(title: string):void {
|
|
|
this.rowsTitle = title;
|
|
this.rowsTitle = title;
|
|
|
}
|
|
}
|
|
|
- addTimeSlots(list:Array<IEvent>){
|
|
|
|
|
|
|
+ addTimeSlots(list:Array<IEvent>):Array<Event | undefined>{
|
|
|
return list.map((e)=>this.addTimeSlot(e));
|
|
return list.map((e)=>this.addTimeSlot(e));
|
|
|
}
|
|
}
|
|
|
// TimeSlot management
|
|
// TimeSlot management
|
|
|
- addTimeSlot(slot: IEvent): Event | null {
|
|
|
|
|
|
|
+ addTimeSlot(slot: IEvent): Event | undefined {
|
|
|
if (this.items.filter(o => o.id == slot.id).length > 0) {
|
|
if (this.items.filter(o => o.id == slot.id).length > 0) {
|
|
|
- return null
|
|
|
|
|
|
|
+ return undefined
|
|
|
}
|
|
}
|
|
|
const ressource = this.rows.find(r => r.id === slot.ressourceId);
|
|
const ressource = this.rows.find(r => r.id === slot.ressourceId);
|
|
|
if (ressource === undefined) {
|
|
if (ressource === undefined) {
|
|
|
- return null
|
|
|
|
|
|
|
+ return undefined
|
|
|
}
|
|
}
|
|
|
const timeslot = Event.toTimeSlot(slot);
|
|
const timeslot = Event.toTimeSlot(slot);
|
|
|
this.items = [...this.items, timeslot]
|
|
this.items = [...this.items, timeslot]
|
|
@@ -534,7 +534,7 @@ class Timeline extends LitElement {
|
|
|
return this.items;
|
|
return this.items;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- updateLegend() {
|
|
|
|
|
|
|
+ updateLegend():void {
|
|
|
const legend = [];
|
|
const legend = [];
|
|
|
const legendUnitList:Array<dayjsUnit> = [ "y","M","d","h","m",'s'];
|
|
const legendUnitList:Array<dayjsUnit> = [ "y","M","d","h","m",'s'];
|
|
|
const legendMinUnitSpan = this.slotDuration * this.legendSpan;
|
|
const legendMinUnitSpan = this.slotDuration * this.legendSpan;
|
|
@@ -568,14 +568,14 @@ class Timeline extends LitElement {
|
|
|
this.legend = legend;
|
|
this.legend = legend;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- _handleResizeX(e: CustomEvent<number>) {
|
|
|
|
|
|
|
+ _handleResizeX(e: CustomEvent<number>):void {
|
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|
|
|
this.ressourceWidth += e.detail
|
|
this.ressourceWidth += e.detail
|
|
|
if (this.ressourceWidth < 0) {
|
|
if (this.ressourceWidth < 0) {
|
|
|
this.ressourceWidth = 0
|
|
this.ressourceWidth = 0
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- _grabHeader(e: MouseEvent) {
|
|
|
|
|
|
|
+ _grabHeader(e: MouseEvent):void {
|
|
|
const root = this.shadowRoot;
|
|
const root = this.shadowRoot;
|
|
|
if (root !== null) {
|
|
if (root !== null) {
|
|
|
const gridContainer = root.querySelector(".jc-timeline-grid-container") as HTMLBaseElement;
|
|
const gridContainer = root.querySelector(".jc-timeline-grid-container") as HTMLBaseElement;
|
|
@@ -587,7 +587,7 @@ class Timeline extends LitElement {
|
|
|
gridContainer.scrollLeft += scrollLeft
|
|
gridContainer.scrollLeft += scrollLeft
|
|
|
lastPosX = e.clientX
|
|
lastPosX = e.clientX
|
|
|
}
|
|
}
|
|
|
- const mouseUpListener = function (e: MouseEvent) {
|
|
|
|
|
|
|
+ const mouseUpListener = function (_e: MouseEvent) {
|
|
|
window.removeEventListener("mousemove", scroll)
|
|
window.removeEventListener("mousemove", scroll)
|
|
|
window.removeEventListener("mouseup", mouseUpListener)
|
|
window.removeEventListener("mouseup", mouseUpListener)
|
|
|
}
|
|
}
|
|
@@ -596,7 +596,7 @@ class Timeline extends LitElement {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
_getEventResizerHandler(slot: Event, direction: "end" | "start") {
|
|
_getEventResizerHandler(slot: Event, direction: "end" | "start") {
|
|
|
- return (evt: MouseEvent) => {
|
|
|
|
|
|
|
+ return (evt: MouseEvent):void => {
|
|
|
evt.stopPropagation();
|
|
evt.stopPropagation();
|
|
|
evt.preventDefault()
|
|
evt.preventDefault()
|
|
|
const startPos = evt.clientX;
|
|
const startPos = evt.clientX;
|
|
@@ -612,7 +612,7 @@ class Timeline extends LitElement {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const mouseUpListener = (e: MouseEvent) => {
|
|
|
|
|
|
|
+ const mouseUpListener = (_e: MouseEvent):void => {
|
|
|
window.removeEventListener("mousemove", resizeListener)
|
|
window.removeEventListener("mousemove", resizeListener)
|
|
|
window.removeEventListener("mouseup", mouseUpListener)
|
|
window.removeEventListener("mouseup", mouseUpListener)
|
|
|
localSlot.moving = false;
|
|
localSlot.moving = false;
|
|
@@ -624,7 +624,7 @@ class Timeline extends LitElement {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
_getEventGrabHandler(slot: Event, editable: boolean, ressourceEditable: boolean, callback: (e: MouseEvent, wasModified:boolean) => void) {
|
|
_getEventGrabHandler(slot: Event, editable: boolean, ressourceEditable: boolean, callback: (e: MouseEvent, wasModified:boolean) => void) {
|
|
|
- return (evt: MouseEvent) => {
|
|
|
|
|
|
|
+ return (evt: MouseEvent):void => {
|
|
|
evt.stopPropagation();
|
|
evt.stopPropagation();
|
|
|
evt.preventDefault();
|
|
evt.preventDefault();
|
|
|
|
|
|
|
@@ -647,7 +647,7 @@ class Timeline extends LitElement {
|
|
|
slot.end = dayjs(endDates[index]).add(changeTime, "m").toDate();
|
|
slot.end = dayjs(endDates[index]).add(changeTime, "m").toDate();
|
|
|
return prevStart.getTime()!==slot.start.getTime()
|
|
return prevStart.getTime()!==slot.start.getTime()
|
|
|
}).reduce((prev,curr)=>prev || curr)
|
|
}).reduce((prev,curr)=>prev || curr)
|
|
|
- } : (e: MouseEvent) => { return false };
|
|
|
|
|
|
|
+ } : (_e: MouseEvent) => { return false };
|
|
|
|
|
|
|
|
const updateRessource = ressourceEditable ? (e: MouseEvent) => {
|
|
const updateRessource = ressourceEditable ? (e: MouseEvent) => {
|
|
|
const rowId = this.shadowRoot?.elementsFromPoint(e.clientX, e.clientY)
|
|
const rowId = this.shadowRoot?.elementsFromPoint(e.clientX, e.clientY)
|
|
@@ -662,7 +662,7 @@ class Timeline extends LitElement {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
return false;
|
|
return false;
|
|
|
- } : (e: MouseEvent) => { return false };
|
|
|
|
|
|
|
+ } : (_e: MouseEvent) => { return false };
|
|
|
|
|
|
|
|
const moveListener = (e: MouseEvent) => {
|
|
const moveListener = (e: MouseEvent) => {
|
|
|
// force the handling of potential position move
|
|
// force the handling of potential position move
|
|
@@ -686,13 +686,13 @@ class Timeline extends LitElement {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
private _clearSelectedItems(){
|
|
private _clearSelectedItems(){
|
|
|
- this.selectedList.map(e => {
|
|
|
|
|
- e.selected = false;
|
|
|
|
|
- this.updateTimeslotById(e.id)
|
|
|
|
|
|
|
+ this.selectedList.map(selectable => {
|
|
|
|
|
+ selectable.selected = false;
|
|
|
|
|
+ this.updateTimeslotById(selectable.id)
|
|
|
});
|
|
});
|
|
|
this.selectedList = []
|
|
this.selectedList = []
|
|
|
}
|
|
}
|
|
|
- private _clearSelectionhandler = ()=>{
|
|
|
|
|
|
|
+ private _clearSelectionhandler = (_e: MouseEvent)=>{
|
|
|
this._clearSelectedItems()
|
|
this._clearSelectedItems()
|
|
|
window.removeEventListener("click",this._clearSelectionhandler);
|
|
window.removeEventListener("click",this._clearSelectionhandler);
|
|
|
}
|
|
}
|
|
@@ -702,14 +702,14 @@ class Timeline extends LitElement {
|
|
|
e.stopPropagation()
|
|
e.stopPropagation()
|
|
|
const idx = this.selectedList.indexOf(item)
|
|
const idx = this.selectedList.indexOf(item)
|
|
|
if (idx > -1) {
|
|
if (idx > -1) {
|
|
|
- if(wasModified){
|
|
|
|
|
-
|
|
|
|
|
- }else if (e.ctrlKey) {
|
|
|
|
|
- this.selectedList.splice(idx, 1);
|
|
|
|
|
- item.selected = false;
|
|
|
|
|
- this.updateTimeslotById(item.id)
|
|
|
|
|
- } else {
|
|
|
|
|
- this._clearSelectedItems()
|
|
|
|
|
|
|
+ if(! wasModified){
|
|
|
|
|
+ if (e.ctrlKey) {
|
|
|
|
|
+ this.selectedList.splice(idx, 1);
|
|
|
|
|
+ item.selected = false;
|
|
|
|
|
+ this.updateTimeslotById(item.id)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this._clearSelectedItems()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
if (this.selectedList.length > 0 && ! e.ctrlKey ) {
|
|
if (this.selectedList.length > 0 && ! e.ctrlKey ) {
|
|
@@ -726,10 +726,9 @@ class Timeline extends LitElement {
|
|
|
});
|
|
});
|
|
|
this.dispatchEvent(myEvent);
|
|
this.dispatchEvent(myEvent);
|
|
|
|
|
|
|
|
- //window.addEventListener("click",this._clearSelectionhandler);
|
|
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
- firstUpdated() {
|
|
|
|
|
|
|
+ firstUpdated():void {
|
|
|
const root = this.shadowRoot;
|
|
const root = this.shadowRoot;
|
|
|
if (root !== null) {
|
|
if (root !== null) {
|
|
|
const gridContainer = root.querySelector(".jc-timeline-grid-container") as HTMLBaseElement;
|
|
const gridContainer = root.querySelector(".jc-timeline-grid-container") as HTMLBaseElement;
|
|
@@ -797,31 +796,30 @@ class Timeline extends LitElement {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
_getCollapseRessourceHandler(item:Ressource):(e:MouseEvent)=>void{
|
|
_getCollapseRessourceHandler(item:Ressource):(e:MouseEvent)=>void{
|
|
|
- return (e:MouseEvent) => {
|
|
|
|
|
|
|
+ return (_e:MouseEvent) => {
|
|
|
item.collapseChildren = ! item.collapseChildren;
|
|
item.collapseChildren = ! item.collapseChildren;
|
|
|
this.updateTimeslotPosition(item);
|
|
this.updateTimeslotPosition(item);
|
|
|
// Force rows refresh TODO improve this rerendering
|
|
// Force rows refresh TODO improve this rerendering
|
|
|
this.rows = [...this.rows];
|
|
this.rows = [...this.rows];
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
- _onRessourceDragStart(item:Ressource){
|
|
|
|
|
- return (event:DragEvent)=>{
|
|
|
|
|
|
|
+ _onRessourceDragStart(item:Ressource):(event:DragEvent)=>void{
|
|
|
|
|
+ return (event:DragEvent):void=>{
|
|
|
event.dataTransfer?.setData("text", item.id);
|
|
event.dataTransfer?.setData("text", item.id);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- _onRessourceDragEnter(event:DragEvent){
|
|
|
|
|
|
|
+ _onRessourceDragEnter(event:DragEvent):void{
|
|
|
if (event.target instanceof HTMLElement){
|
|
if (event.target instanceof HTMLElement){
|
|
|
const tgt = event.target;
|
|
const tgt = event.target;
|
|
|
tgt.classList.add("target");
|
|
tgt.classList.add("target");
|
|
|
- }else if(event.target instanceof Node){
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- _onRessourceDragLeave(event:DragEvent){
|
|
|
|
|
|
|
+ _onRessourceDragLeave(event:DragEvent):void{
|
|
|
if (event.target instanceof HTMLElement){
|
|
if (event.target instanceof HTMLElement){
|
|
|
event.target.classList.remove("target");
|
|
event.target.classList.remove("target");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- _onRessourceDrop(event:DragEvent){
|
|
|
|
|
|
|
+ _onRessourceDrop(event:DragEvent):void{
|
|
|
event.preventDefault()
|
|
event.preventDefault()
|
|
|
if (event.target instanceof HTMLElement){
|
|
if (event.target instanceof HTMLElement){
|
|
|
event.target.classList.remove("target");
|
|
event.target.classList.remove("target");
|
|
@@ -868,7 +866,7 @@ class Timeline extends LitElement {
|
|
|
<td class="${item.selected ? "jc-ressource-selected":""}" style="${style}" ressourceId="${item.id}" @click="${this._getEventClickHandler(item)}">
|
|
<td class="${item.selected ? "jc-ressource-selected":""}" style="${style}" ressourceId="${item.id}" @click="${this._getEventClickHandler(item)}">
|
|
|
<div class="jc-ressource-above"></div>
|
|
<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"}" @click="${collapseHandler}"></i>` : html`<i class="jc-spacer"></i>`}
|
|
|
|
|
|
|
+ ${Array(depth).fill(0).map(_i => html`<i class="jc-spacer"></i>`)}${hasChild ? html`<i class="jc-spacer ${item.collapseChildren ? "extend" : "collapse"}" @click="${collapseHandler}"></i>` : html`<i class="jc-spacer"></i>`}
|
|
|
<span>${item.title}</span>
|
|
<span>${item.title}</span>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="jc-ressource-below"></div>
|
|
<div class="jc-ressource-below"></div>
|
|
@@ -892,9 +890,7 @@ class Timeline extends LitElement {
|
|
|
<horizontal-resizer @resize-x="${this._handleResizeX}"></horizontal-resizer>
|
|
<horizontal-resizer @resize-x="${this._handleResizeX}"></horizontal-resizer>
|
|
|
<div class="jc-timeline-grid-title-container">
|
|
<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">`)}
|
|
|
|
|
- </colgroup>
|
|
|
|
|
|
|
+ <colgroup>${columns.map(_o=>html`<col style="min-width:${this.slotWidth}px">`)}</colgroup>
|
|
|
<tbody>
|
|
<tbody>
|
|
|
${this.legend.map(arr=>html`<tr class="jc-timeline-grid-title">${arr.map(o=>html`<th colspan="${o.colspan}">${o.title}</th>`)}</tr>`)}
|
|
${this.legend.map(arr=>html`<tr class="jc-timeline-grid-title">${arr.map(o=>html`<th colspan="${o.colspan}">${o.title}</th>`)}</tr>`)}
|
|
|
</tbody>
|
|
</tbody>
|
|
@@ -913,9 +909,8 @@ class Timeline extends LitElement {
|
|
|
<horizontal-resizer @resize-x="${this._handleResizeX}"></horizontal-resizer>
|
|
<horizontal-resizer @resize-x="${this._handleResizeX}"></horizontal-resizer>
|
|
|
<div class="jc-timeline-grid-container">
|
|
<div class="jc-timeline-grid-container">
|
|
|
<table style="width:${nCol * this.slotWidth}px;">
|
|
<table style="width:${nCol * this.slotWidth}px;">
|
|
|
- <colgroup>
|
|
|
|
|
- ${columns.map(o=>html`<col style="min-width:${this.slotWidth}px">`)}
|
|
|
|
|
- </colgroup>
|
|
|
|
|
|
|
+ <colgroup>${columns.map(_o=>html`<col style="min-width:${this.slotWidth}px">`)}</colgroup>
|
|
|
|
|
+
|
|
|
<tbody>
|
|
<tbody>
|
|
|
${this.rows.length > 0 ? displayedRows.map(o => this.renderGridRow(columns, o.i, o.r.height)) : this.renderGridRow(columns)}
|
|
${this.rows.length > 0 ? displayedRows.map(o => this.renderGridRow(columns, o.i, o.r.height)) : this.renderGridRow(columns)}
|
|
|
</tbody>
|
|
</tbody>
|