@operato/gantt 7.0.20 → 7.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/src/draw-time-scale-header.d.ts +5 -0
- package/dist/src/draw-time-scale-header.js +154 -0
- package/dist/src/draw-time-scale-header.js.map +1 -0
- package/dist/src/gantt-chart-controller.d.ts +1 -1
- package/dist/src/gantt-chart-controller.js +6 -161
- package/dist/src/gantt-chart-controller.js.map +1 -1
- package/dist/src/ox-gantt-chart.d.ts +6 -1
- package/dist/src/ox-gantt-chart.js +39 -8
- package/dist/src/ox-gantt-chart.js.map +1 -1
- package/dist/src/ox-gantt-resize-splitter.js +8 -7
- package/dist/src/ox-gantt-resize-splitter.js.map +1 -1
- package/dist/src/ox-gantt.d.ts +24 -15
- package/dist/src/ox-gantt.js +224 -82
- package/dist/src/ox-gantt.js.map +1 -1
- package/dist/src/ox-resource-chart.d.ts +42 -0
- package/dist/src/ox-resource-chart.js +317 -0
- package/dist/src/ox-resource-chart.js.map +1 -0
- package/dist/src/types.d.ts +5 -0
- package/dist/src/types.js.map +1 -1
- package/dist/stories/ox-gantt.stories.js +75 -4
- package/dist/stories/ox-gantt.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/draw-time-scale-header.ts +192 -0
- package/src/gantt-chart-controller.ts +6 -189
- package/src/ox-gantt-chart.ts +46 -9
- package/src/ox-gantt-resize-splitter.ts +8 -7
- package/src/ox-gantt.ts +231 -86
- package/src/ox-resource-chart.ts +328 -0
- package/src/types.ts +6 -0
- package/stories/ox-gantt.stories.ts +75 -4
- package/translations/en.json +4 -1
- package/translations/ja.json +3 -1
- package/translations/ko.json +4 -1
- package/translations/ms.json +3 -1
- package/translations/zh.json +3 -1
package/src/ox-gantt.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { LitElement, html, css, PropertyValues, PropertyValueMap } from 'lit'
|
|
1
|
+
import { LitElement, html, css, PropertyValues, PropertyValueMap, nothing, TemplateResult } from 'lit'
|
|
2
|
+
import * as d3 from 'd3'
|
|
2
3
|
import i18next from 'i18next'
|
|
3
4
|
import { customElement, property, query, state } from 'lit/decorators.js'
|
|
4
5
|
import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
|
|
5
6
|
import { ScrollbarStyles } from '@operato/styles'
|
|
6
7
|
|
|
7
8
|
import './ox-gantt-chart.js'
|
|
9
|
+
import './ox-resource-chart.js'
|
|
8
10
|
import './ox-gantt-resize-splitter.js'
|
|
9
11
|
import { OxGanttChart } from './ox-gantt-chart.js'
|
|
10
|
-
import {
|
|
12
|
+
import { OxResourceChart } from './ox-resource-chart.js'
|
|
13
|
+
import { ColumnConfig, Task, TimeScale, Resource } from './types.js'
|
|
11
14
|
|
|
12
15
|
@customElement('ox-gantt')
|
|
13
16
|
export class OxGantt extends LitElement {
|
|
@@ -23,13 +26,24 @@ export class OxGantt extends LitElement {
|
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
.container {
|
|
29
|
+
flex: 1;
|
|
30
|
+
|
|
26
31
|
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
27
33
|
width: 100%;
|
|
28
34
|
height: 100%;
|
|
29
35
|
box-sizing: border-box;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
.
|
|
38
|
+
.resource-container {
|
|
39
|
+
height: 300px;
|
|
40
|
+
|
|
41
|
+
display: flex;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
box-sizing: border-box;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.resource-table-container {
|
|
33
47
|
padding: 0;
|
|
34
48
|
overflow: auto;
|
|
35
49
|
overflow-y: overlay;
|
|
@@ -37,16 +51,34 @@ export class OxGantt extends LitElement {
|
|
|
37
51
|
border: 1px solid var(--ox-gantt-border-color, var(--md-sys-color-on-surface));
|
|
38
52
|
}
|
|
39
53
|
|
|
40
|
-
.chart-container {
|
|
54
|
+
.resource-chart-container {
|
|
55
|
+
flex: 1;
|
|
56
|
+
padding: 0;
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
border: 1px solid var(--ox-gantt-border-color, var(--md-sys-color-on-surface));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.task-container {
|
|
41
62
|
flex: 1;
|
|
63
|
+
|
|
64
|
+
display: flex;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
box-sizing: border-box;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.task-table-container {
|
|
42
70
|
padding: 0;
|
|
71
|
+
overflow: auto;
|
|
72
|
+
overflow-y: overlay;
|
|
43
73
|
box-sizing: border-box;
|
|
44
74
|
border: 1px solid var(--ox-gantt-border-color, var(--md-sys-color-on-surface));
|
|
45
75
|
}
|
|
46
76
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
77
|
+
.task-chart-container {
|
|
78
|
+
flex: 1;
|
|
79
|
+
padding: 0;
|
|
80
|
+
box-sizing: border-box;
|
|
81
|
+
border: 1px solid var(--ox-gantt-border-color, var(--md-sys-color-on-surface));
|
|
50
82
|
}
|
|
51
83
|
|
|
52
84
|
table {
|
|
@@ -77,6 +109,7 @@ export class OxGantt extends LitElement {
|
|
|
77
109
|
th {
|
|
78
110
|
height: 40px;
|
|
79
111
|
box-sizing: border-box;
|
|
112
|
+
text-align: center;
|
|
80
113
|
}
|
|
81
114
|
|
|
82
115
|
td {
|
|
@@ -91,6 +124,7 @@ export class OxGantt extends LitElement {
|
|
|
91
124
|
]
|
|
92
125
|
|
|
93
126
|
@property({ type: Array }) tasks: Task[] = []
|
|
127
|
+
@property({ type: Array }) resources: Resource[] = []
|
|
94
128
|
@property({ type: String, attribute: 'from-date' })
|
|
95
129
|
fromDate: string = new Date(new Date().getFullYear(), 0, 1).toISOString().split('T')[0] /* beginning of this year */
|
|
96
130
|
@property({ type: String, attribute: 'to-date' })
|
|
@@ -136,41 +170,90 @@ export class OxGantt extends LitElement {
|
|
|
136
170
|
visible: true,
|
|
137
171
|
width: 100,
|
|
138
172
|
order: 9
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'resources',
|
|
176
|
+
label: i18next.t('label.gantt-task-resources') || 'resources',
|
|
177
|
+
visible: true,
|
|
178
|
+
width: 100,
|
|
179
|
+
order: 10
|
|
139
180
|
}
|
|
140
181
|
]
|
|
141
182
|
|
|
142
183
|
@state() selectedTaskId?: string
|
|
143
184
|
|
|
144
|
-
@query('.container') container!: HTMLDivElement
|
|
145
185
|
@query('.task-container') taskContainer!: HTMLDivElement
|
|
146
|
-
@query('.
|
|
147
|
-
@query('
|
|
186
|
+
@query('.task-table-container') taskTableContainer!: HTMLDivElement
|
|
187
|
+
@query('.resource-container') resourceContainer!: HTMLDivElement
|
|
188
|
+
@query('.resource-table-container') resourceTableContainer!: HTMLDivElement
|
|
189
|
+
@query('.task-table') taskTable!: HTMLTableElement
|
|
148
190
|
@query('ox-gantt-chart') ganttChart!: OxGanttChart
|
|
191
|
+
@query('ox-resource-chart') resourceChart!: OxResourceChart
|
|
149
192
|
|
|
150
193
|
private _startWidth: number = 0
|
|
194
|
+
private _startHeight: number = 0
|
|
151
195
|
private _isDragging: boolean = false
|
|
152
196
|
|
|
153
197
|
render() {
|
|
154
198
|
return html`
|
|
155
199
|
<div class="container md-typescale-body-medium">
|
|
156
|
-
<div class="task-container"
|
|
200
|
+
<div class="task-container">
|
|
201
|
+
<div class="task-table-container" @scroll=${this.syncScroll}>${this.renderTaskTable()}</div>
|
|
202
|
+
<ox-gantt-resize-splitter
|
|
203
|
+
vertical
|
|
204
|
+
@splitter-dragstart=${(e: CustomEvent) => this.resizeHorizontalStart(e)}
|
|
205
|
+
@splitter-drag=${(e: CustomEvent) => this.resizeHorizontalDrag(e)}
|
|
206
|
+
@splitter-dragend=${(e: CustomEvent) => this.resizeHorizontalEnd(e)}
|
|
207
|
+
></ox-gantt-resize-splitter>
|
|
208
|
+
<ox-gantt-chart
|
|
209
|
+
class="task-chart-container"
|
|
210
|
+
@scroll=${this.syncScroll}
|
|
211
|
+
.fromDate=${this.fromDate}
|
|
212
|
+
.toDate=${this.toDate}
|
|
213
|
+
.tasks=${this.tasks}
|
|
214
|
+
.selectedTaskId=${this.selectedTaskId}
|
|
215
|
+
.axisScale=${this.timeScale}
|
|
216
|
+
?extend-grid-lines=${this.extendGridLines}
|
|
217
|
+
@task-clicked=${this.handleTaskClicked}
|
|
218
|
+
@timescale-changed=${(e: CustomEvent) => this.syncTimeScale(e)}
|
|
219
|
+
></ox-gantt-chart>
|
|
220
|
+
</div>
|
|
157
221
|
<ox-gantt-resize-splitter
|
|
158
|
-
|
|
159
|
-
@splitter-dragstart=${(e: CustomEvent) => this.
|
|
160
|
-
@splitter-drag=${(e: CustomEvent) => this.
|
|
161
|
-
@splitter-dragend=${(e: CustomEvent) => this.
|
|
222
|
+
horizontal
|
|
223
|
+
@splitter-dragstart=${(e: CustomEvent) => this.resizeVerticalStart(e)}
|
|
224
|
+
@splitter-drag=${(e: CustomEvent) => this.resizeVerticalDrag(e)}
|
|
225
|
+
@splitter-dragend=${(e: CustomEvent) => this.resizeVerticalEnd(e)}
|
|
162
226
|
></ox-gantt-resize-splitter>
|
|
163
|
-
<
|
|
164
|
-
class="
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
227
|
+
<div class="resource-container">
|
|
228
|
+
<div class="resource-table-container" @scroll=${this.syncScroll}>
|
|
229
|
+
<table>
|
|
230
|
+
<thead>
|
|
231
|
+
<tr>
|
|
232
|
+
<th style="width: 100px">${i18next.t('label.gantt-resource-type')}</th>
|
|
233
|
+
<th>${i18next.t('label.gantt-resource-allocated')}</th>
|
|
234
|
+
</tr>
|
|
235
|
+
</thead>
|
|
236
|
+
<tbody>
|
|
237
|
+
${this.resources.map(resource => this.renderResourceRow(resource))}
|
|
238
|
+
</tbody>
|
|
239
|
+
</table>
|
|
240
|
+
</div>
|
|
241
|
+
<ox-gantt-resize-splitter
|
|
242
|
+
vertical
|
|
243
|
+
@splitter-dragstart=${(e: CustomEvent) => this.resizeHorizontalStart(e)}
|
|
244
|
+
@splitter-drag=${(e: CustomEvent) => this.resizeHorizontalDrag(e)}
|
|
245
|
+
@splitter-dragend=${(e: CustomEvent) => this.resizeHorizontalEnd(e)}
|
|
246
|
+
></ox-gantt-resize-splitter>
|
|
247
|
+
<ox-resource-chart
|
|
248
|
+
class="resource-chart-container"
|
|
249
|
+
.fromDate=${this.fromDate}
|
|
250
|
+
.toDate=${this.toDate}
|
|
251
|
+
.tasks=${this.tasks}
|
|
252
|
+
.resources=${this.resources}
|
|
253
|
+
.axisScale=${this.timeScale}
|
|
254
|
+
@scroll=${this.syncScroll}
|
|
255
|
+
></ox-resource-chart>
|
|
256
|
+
</div>
|
|
174
257
|
</div>
|
|
175
258
|
`
|
|
176
259
|
}
|
|
@@ -180,42 +263,55 @@ export class OxGantt extends LitElement {
|
|
|
180
263
|
return
|
|
181
264
|
}
|
|
182
265
|
|
|
183
|
-
const mergedTasks = this.mergeTasksBySection(this.tasks)
|
|
184
|
-
|
|
185
266
|
// Sort columns by the configured order
|
|
186
267
|
const sortedColumns = [...this.columnConfig].sort((a, b) => a.order - b.order)
|
|
187
268
|
|
|
188
269
|
return html`
|
|
189
|
-
<table>
|
|
270
|
+
<table class="task-table">
|
|
190
271
|
<thead>
|
|
191
272
|
<tr>
|
|
192
273
|
${sortedColumns.map(col =>
|
|
193
|
-
col.visible ? html`<th style="width: ${col.width}px">${col.label}</th>` :
|
|
274
|
+
col.visible ? html`<th style="width: ${col.width}px">${col.label}</th>` : nothing
|
|
194
275
|
)}
|
|
195
276
|
</tr>
|
|
196
277
|
</thead>
|
|
197
278
|
<tbody>
|
|
198
|
-
${
|
|
199
|
-
({ task, showSection, rowSpan }) => html`
|
|
200
|
-
<tr class="${this.selectedTaskId === task.id ? 'selected' : ''}" @click=${() => this.selectTask(task.id)}>
|
|
201
|
-
${sortedColumns.map(col => {
|
|
202
|
-
if (col.name === 'section') {
|
|
203
|
-
return col.visible && showSection
|
|
204
|
-
? html`<td rowspan=${rowSpan} style="width: ${col.width}px">${task.section?.name || ''}</td>`
|
|
205
|
-
: null
|
|
206
|
-
}
|
|
207
|
-
return col.visible
|
|
208
|
-
? html`<td style="width: ${col.width}px">${this.getTaskFieldValue(task, col.name)}</td>`
|
|
209
|
-
: null
|
|
210
|
-
})}
|
|
211
|
-
</tr>
|
|
212
|
-
`
|
|
213
|
-
)}
|
|
279
|
+
${this.renderTaskRows(this.tasks)}
|
|
214
280
|
</tbody>
|
|
215
281
|
</table>
|
|
216
282
|
`
|
|
217
283
|
}
|
|
218
284
|
|
|
285
|
+
renderTaskRows(tasks: Task[], level: number = 0): TemplateResult[] {
|
|
286
|
+
return tasks.flatMap(task => [
|
|
287
|
+
this.renderTaskRow(task, level),
|
|
288
|
+
...this.renderTaskRows(task.children || [], level + 1)
|
|
289
|
+
])
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
renderTaskRow(task: Task, level: number) {
|
|
293
|
+
return html`
|
|
294
|
+
<tr class=${this.selectedTaskId === task.id ? 'selected' : ''} @click=${() => this.selectTask(task.id)}>
|
|
295
|
+
${this.columnConfig.map(col =>
|
|
296
|
+
col.visible
|
|
297
|
+
? html`<td class="task-row" style="padding-left: ${col.name == 'title' ? level * 8 + 4 : 4}px">
|
|
298
|
+
${this.getTaskFieldValue(task, col.name)}
|
|
299
|
+
</td>`
|
|
300
|
+
: null
|
|
301
|
+
)}
|
|
302
|
+
</tr>
|
|
303
|
+
`
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
renderResourceRow(resource: Resource) {
|
|
307
|
+
return html`
|
|
308
|
+
<tr>
|
|
309
|
+
<td>${resource.type}</td>
|
|
310
|
+
<td>${resource.allocated}</td>
|
|
311
|
+
</tr>
|
|
312
|
+
`
|
|
313
|
+
}
|
|
314
|
+
|
|
219
315
|
getTaskFieldValue(task: Task, field: string) {
|
|
220
316
|
switch (field) {
|
|
221
317
|
case 'id':
|
|
@@ -236,34 +332,13 @@ export class OxGantt extends LitElement {
|
|
|
236
332
|
return task.progress || ''
|
|
237
333
|
case 'dependsOn':
|
|
238
334
|
return task.dependsOn || ''
|
|
335
|
+
case 'resources':
|
|
336
|
+
return task.resources?.map(res => `${res.type}: ${res.allocated}`).join(', ') || ''
|
|
239
337
|
default:
|
|
240
338
|
return ''
|
|
241
339
|
}
|
|
242
340
|
}
|
|
243
341
|
|
|
244
|
-
mergeTasksBySection(tasks: Task[]): Array<{ task: Task; showSection: boolean; rowSpan: number }> {
|
|
245
|
-
const mergedTasks = [] as Array<{ task: Task; showSection: boolean; rowSpan: number }>
|
|
246
|
-
let currentSection = ''
|
|
247
|
-
let rowSpan = 0
|
|
248
|
-
|
|
249
|
-
;(tasks || []).forEach((task, index) => {
|
|
250
|
-
if (task.section?.name !== currentSection) {
|
|
251
|
-
currentSection = task.section?.name || ''
|
|
252
|
-
rowSpan = 1
|
|
253
|
-
mergedTasks.push({ task, showSection: true, rowSpan: 1 })
|
|
254
|
-
} else {
|
|
255
|
-
mergedTasks[mergedTasks.length - rowSpan].rowSpan = ++rowSpan
|
|
256
|
-
mergedTasks.push({ task, showSection: false, rowSpan: 0 })
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (index === tasks.length - 1 && rowSpan > 0) {
|
|
260
|
-
mergedTasks[mergedTasks.length - rowSpan].rowSpan = rowSpan
|
|
261
|
-
}
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
return mergedTasks
|
|
265
|
-
}
|
|
266
|
-
|
|
267
342
|
selectTask(taskId: string) {
|
|
268
343
|
this.selectedTaskId = taskId
|
|
269
344
|
}
|
|
@@ -273,48 +348,118 @@ export class OxGantt extends LitElement {
|
|
|
273
348
|
}
|
|
274
349
|
|
|
275
350
|
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
|
276
|
-
this.
|
|
351
|
+
this.taskTableContainer.style.width = '254px'
|
|
352
|
+
this.resourceTableContainer.style.width = '254px'
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
updated(changedProperties: PropertyValues<this>) {
|
|
356
|
+
if (changedProperties.has('tasks')) {
|
|
357
|
+
this.resources = this.aggregateResources(this.tasks)
|
|
358
|
+
}
|
|
277
359
|
}
|
|
278
360
|
|
|
279
|
-
|
|
361
|
+
aggregateResources(tasks: Task[]): Resource[] {
|
|
362
|
+
const resourceMap: { [key: string]: number } = {}
|
|
363
|
+
|
|
364
|
+
const traverseTasks = (tasks: Task[]) => {
|
|
365
|
+
tasks.forEach(task => {
|
|
366
|
+
if (task.resources) {
|
|
367
|
+
const startDate = new Date(task.startDate)
|
|
368
|
+
const endDate = new Date(task.endDate)
|
|
369
|
+
const durationDays = d3.timeDay.count(startDate, d3.timeDay.offset(endDate, 1))
|
|
370
|
+
|
|
371
|
+
task.resources.forEach(resource => {
|
|
372
|
+
const totalAllocation = resource.allocated * durationDays
|
|
373
|
+
if (!resourceMap[resource.type]) {
|
|
374
|
+
resourceMap[resource.type] = 0
|
|
375
|
+
}
|
|
376
|
+
resourceMap[resource.type] += totalAllocation
|
|
377
|
+
console.log(resource.type, resource.allocated, durationDays, totalAllocation)
|
|
378
|
+
})
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
if (task.children) {
|
|
382
|
+
traverseTasks(task.children)
|
|
383
|
+
}
|
|
384
|
+
})
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
traverseTasks(tasks)
|
|
388
|
+
|
|
389
|
+
return Object.keys(resourceMap).map(type => ({
|
|
390
|
+
type,
|
|
391
|
+
allocated: resourceMap[type]
|
|
392
|
+
}))
|
|
393
|
+
}
|
|
280
394
|
|
|
281
395
|
syncScroll(e: Event) {
|
|
282
396
|
const target = e.target as HTMLElement
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const newScrollTop = this.
|
|
397
|
+
|
|
398
|
+
if (target === this.taskTableContainer) {
|
|
399
|
+
const newScrollTop = this.taskTableContainer.scrollTop
|
|
286
400
|
this.ganttChart.setVerticalOffset(newScrollTop)
|
|
287
401
|
|
|
288
|
-
// Ensure chart scroll matches table scroll
|
|
289
402
|
if (this.ganttChart.getVerticalOffset() !== newScrollTop) {
|
|
290
403
|
this.ganttChart.setVerticalOffset(newScrollTop)
|
|
291
404
|
}
|
|
292
405
|
} else if (target === this.ganttChart) {
|
|
293
|
-
// Sync table scroll with chart scroll
|
|
294
406
|
const newScrollTop = this.ganttChart.getVerticalOffset()
|
|
295
|
-
this.
|
|
407
|
+
this.taskTableContainer.scrollTop = newScrollTop
|
|
408
|
+
this.ganttChart.setVerticalOffset(this.taskTableContainer.scrollTop)
|
|
409
|
+
|
|
410
|
+
const newScrollLeft = this.ganttChart.getHorizontalOffset()
|
|
411
|
+
this.resourceChart.setHorizontalOffset(newScrollLeft)
|
|
412
|
+
} else if (target === this.resourceChart) {
|
|
413
|
+
const newScrollTop = this.ganttChart.getVerticalOffset()
|
|
414
|
+
this.resourceTableContainer.scrollTop = newScrollTop
|
|
415
|
+
this.resourceChart.setVerticalOffset(this.taskTableContainer.scrollTop)
|
|
296
416
|
|
|
297
|
-
|
|
298
|
-
this.ganttChart.
|
|
417
|
+
const newScrollLeft = this.resourceChart.getHorizontalOffset()
|
|
418
|
+
this.ganttChart.setHorizontalOffset(newScrollLeft)
|
|
419
|
+
} else if (target === this.resourceTableContainer) {
|
|
420
|
+
const newScrollTop = this.taskTableContainer.scrollTop
|
|
421
|
+
this.resourceChart.setVerticalOffset(newScrollTop)
|
|
422
|
+
|
|
423
|
+
if (this.resourceChart.getVerticalOffset() !== newScrollTop) {
|
|
424
|
+
this.resourceChart.setVerticalOffset(newScrollTop)
|
|
425
|
+
}
|
|
299
426
|
}
|
|
300
427
|
}
|
|
301
428
|
|
|
302
|
-
|
|
429
|
+
syncTimeScale(e: CustomEvent) {
|
|
430
|
+
const detail = e.detail
|
|
431
|
+
this.resourceChart.syncTimeScale(detail)
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
resizeHorizontalStart(e: CustomEvent) {
|
|
303
435
|
this._startWidth = ((e.target as HTMLElement)?.previousElementSibling as HTMLElement)?.offsetWidth
|
|
304
436
|
this._isDragging = true
|
|
305
437
|
}
|
|
306
438
|
|
|
307
|
-
|
|
439
|
+
resizeHorizontalDrag(e: CustomEvent) {
|
|
308
440
|
if (!this._isDragging) return
|
|
309
441
|
const delta = e.detail
|
|
310
|
-
|
|
442
|
+
this.taskTableContainer.style.width = `${this._startWidth + delta.x}px`
|
|
443
|
+
this.resourceTableContainer.style.width = `${this._startWidth + delta.x}px`
|
|
444
|
+
}
|
|
311
445
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
446
|
+
resizeHorizontalEnd(e: CustomEvent) {
|
|
447
|
+
this._isDragging = false
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
resizeVerticalStart(e: CustomEvent) {
|
|
451
|
+
this._startHeight = ((e.target as HTMLElement)?.nextElementSibling as HTMLElement)?.offsetHeight
|
|
452
|
+
this._isDragging = true
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
resizeVerticalDrag(e: CustomEvent) {
|
|
456
|
+
if (!this._isDragging) return
|
|
457
|
+
const delta = e.detail
|
|
458
|
+
|
|
459
|
+
this.resourceContainer.style.height = `${this._startHeight - delta.y}px`
|
|
315
460
|
}
|
|
316
461
|
|
|
317
|
-
|
|
462
|
+
resizeVerticalEnd(e: CustomEvent) {
|
|
318
463
|
this._isDragging = false
|
|
319
464
|
}
|
|
320
465
|
}
|