@progress/kendo-angular-gantt 21.1.1-develop.2 → 21.2.0-develop.2

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.
@@ -12,7 +12,7 @@ import { isPresent } from '../utils';
12
12
  import { CurrentTimeMarkerService } from './current-time-marker.service';
13
13
  import { GanttDependencyDirective } from '../dependencies/gantt-dependency.directive';
14
14
  import { GanttTasksTableBodyComponent } from '../rendering/gantt-tasks-table-body.component';
15
- import { NgFor, NgIf, NgTemplateOutlet } from '@angular/common';
15
+ import { NgTemplateOutlet } from '@angular/common';
16
16
  import { TimelineScrollableDirective } from '../scrolling/timeline-scroll.directive';
17
17
  import { GanttHeaderTableBodyComponent } from '../rendering/gantt-header-table-body.component';
18
18
  import { TaskDragService } from '../dragging/task-drag.service';
@@ -192,6 +192,11 @@ export class GanttTimelineComponent {
192
192
  this.createTimeMarker();
193
193
  }
194
194
  }
195
+ trackBySlotIndex(index, item) {
196
+ // Combine index with timestamp to ensure uniqueness
197
+ // even when multiple slots have the same start time
198
+ return `${index}-${item.start.getTime()}`;
199
+ }
195
200
  ngAfterViewInit() {
196
201
  this.currentTimeMarkerService.slots = this.slots;
197
202
  this.currentTimeMarkerService.rows = this.rows;
@@ -227,149 +232,157 @@ export class GanttTimelineComponent {
227
232
  });
228
233
  }
229
234
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GanttTimelineComponent, deps: [{ token: i1.ScrollSyncService }, { token: i2.DependencyDomService }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i3.CurrentTimeMarkerService }, { token: i4.GanttLocalizationService }, { token: i5.TaskDragService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
230
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: GanttTimelineComponent, isStandalone: true, selector: "kendo-gantt-timeline", inputs: { rows: "rows", slots: "slots", groupSlots: "groupSlots", tableWidth: "tableWidth", activeView: "activeView", taskContentTemplate: "taskContentTemplate", taskTemplate: "taskTemplate", summaryTaskTemplate: "summaryTaskTemplate", taskClass: "taskClass", renderDependencyDragClues: "renderDependencyDragClues", dragScrollSettings: "dragScrollSettings", currentTimeMarker: "currentTimeMarker", customTooltipTemplate: "customTooltipTemplate", tooltipOptions: "tooltipOptions", selectable: "selectable", isTaskSelected: "isTaskSelected", isExpanded: "isExpanded", dependencies: "dependencies" }, outputs: { timelineContainerPress: "timelineContainerPress", timelineContainerDrag: "timelineContainerDrag", timelineContainerRelease: "timelineContainerRelease" }, viewQueries: [{ propertyName: "timelineContent", first: true, predicate: ["timelineContent"], descendants: true, static: true }, { propertyName: "timelineColumns", first: true, predicate: ["timelineColumns"], descendants: true, static: true }, { propertyName: "timelineHeaderWrap", first: true, predicate: ["timelineHeaderWrap"], descendants: true, static: true }, { propertyName: "tasksContainer", first: true, predicate: ["tasksContainer"], descendants: true, static: true }, { propertyName: "tooltip", first: true, predicate: TooltipDirective, descendants: true }, { propertyName: "dragPopupContainer", first: true, predicate: ["dragPopupContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "dependencyDragCreatePolyline", first: true, predicate: ["dependencyDragCreatePolyline"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
235
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: GanttTimelineComponent, isStandalone: true, selector: "kendo-gantt-timeline", inputs: { rows: "rows", slots: "slots", groupSlots: "groupSlots", tableWidth: "tableWidth", activeView: "activeView", taskContentTemplate: "taskContentTemplate", taskTemplate: "taskTemplate", summaryTaskTemplate: "summaryTaskTemplate", taskClass: "taskClass", renderDependencyDragClues: "renderDependencyDragClues", dragScrollSettings: "dragScrollSettings", currentTimeMarker: "currentTimeMarker", customTooltipTemplate: "customTooltipTemplate", tooltipOptions: "tooltipOptions", selectable: "selectable", isTaskSelected: "isTaskSelected", isExpanded: "isExpanded", dependencies: "dependencies" }, outputs: { timelineContainerPress: "timelineContainerPress", timelineContainerDrag: "timelineContainerDrag", timelineContainerRelease: "timelineContainerRelease" }, viewQueries: [{ propertyName: "timelineContent", first: true, predicate: ["timelineContent"], descendants: true, static: true }, { propertyName: "timelineColumns", first: true, predicate: ["timelineColumns"], descendants: true, static: true }, { propertyName: "timelineHeaderWrap", first: true, predicate: ["timelineHeaderWrap"], descendants: true, static: true }, { propertyName: "tasksContainer", first: true, predicate: ["tasksContainer"], descendants: true, static: true }, { propertyName: "tooltip", first: true, predicate: TooltipDirective, descendants: true }, { propertyName: "dragPopupContainer", first: true, predicate: ["dragPopupContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "dependencyDragCreatePolyline", first: true, predicate: ["dependencyDragCreatePolyline"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
231
236
  <div class="k-gantt-timeline k-grid k-grid-md">
232
- <div class="k-grid-header">
233
- <div #timelineHeaderWrap class="k-grid-header-wrap">
234
- <table
235
- class="k-table k-table-md k-grid-header-table"
236
- role="presentation"
237
- [style.width.px]="tableWidth"
238
- >
239
- <tbody
240
- kendoGanttHeaderTableBody
241
- [groupSlots]="groupSlots"
242
- [slots]="slots">
243
- </tbody>
244
- </table>
245
- </div>
237
+ <div class="k-grid-header">
238
+ <div #timelineHeaderWrap class="k-grid-header-wrap">
239
+ <table
240
+ class="k-table k-table-md k-grid-header-table"
241
+ role="presentation"
242
+ [style.width.px]="tableWidth"
243
+ >
244
+ <tbody
245
+ kendoGanttHeaderTableBody
246
+ [groupSlots]="groupSlots"
247
+ [slots]="slots">
248
+ </tbody>
249
+ </table>
246
250
  </div>
247
- <!-- tabindex="-1" required for https://bugzilla.mozilla.org/show_bug.cgi?id=1069739 -->
248
- <div
249
- #timelineContent
250
- class="k-grid-content"
251
- tabindex="-1"
252
- role="tree"
253
- aria-roledescription="Timeline"
254
- kendoGanttTimelineScrollable
255
- [scrollSettings]="dragScrollSettings"
256
- kendoDraggable
257
- [enableDrag]="draggableEnabled"
258
- (kendoPress)="timelineContainerPress.emit($event)"
259
- (kendoDrag)="timelineContainerDrag.emit($event)"
260
- (kendoRelease)="timelineContainerRelease.emit($event)"
251
+ </div>
252
+ <!-- tabindex="-1" required for https://bugzilla.mozilla.org/show_bug.cgi?id=1069739 -->
253
+ <div
254
+ #timelineContent
255
+ class="k-grid-content"
256
+ tabindex="-1"
257
+ role="tree"
258
+ aria-roledescription="Timeline"
259
+ kendoGanttTimelineScrollable
260
+ [scrollSettings]="dragScrollSettings"
261
+ kendoDraggable
262
+ [enableDrag]="draggableEnabled"
263
+ (kendoPress)="timelineContainerPress.emit($event)"
264
+ (kendoDrag)="timelineContainerDrag.emit($event)"
265
+ (kendoRelease)="timelineContainerRelease.emit($event)"
261
266
  >
262
- <div class="k-gantt-tables">
263
- <table
264
- class="k-table k-table-md k-grid-table k-gantt-rows"
265
- [style.width.px]="tableWidth"
266
- role="presentation"
267
- >
268
- <tbody class="k-table-tbody">
269
- <tr
270
- *ngFor="let item of rows; let i = index;"
271
- class="k-table-row{{i % 2 ? ' k-table-alt-row' : ''}}">
272
- <td class="k-table-td"></td>
273
- </tr>
274
- </tbody>
275
- </table>
267
+ <div class="k-gantt-tables">
268
+ <table
269
+ class="k-table k-table-md k-grid-table k-gantt-rows"
270
+ [style.width.px]="tableWidth"
271
+ role="presentation"
272
+ >
273
+ <tbody class="k-table-tbody">
274
+ @for (item of rows; track $index; let i = $index) {
275
+ <tr
276
+ class="k-table-row{{i % 2 ? ' k-table-alt-row' : ''}}">
277
+ <td class="k-table-td"></td>
278
+ </tr>
279
+ }
280
+ </tbody>
281
+ </table>
276
282
 
277
- <table
278
- #timelineColumns
279
- class="k-table k-table-md k-gantt-columns"
280
- role="presentation"
281
- [style.width.px]="tableWidth"
282
- >
283
- <colgroup>
284
- <col *ngFor="let item of slots">
285
- </colgroup>
283
+ <table
284
+ #timelineColumns
285
+ class="k-table k-table-md k-gantt-columns"
286
+ role="presentation"
287
+ [style.width.px]="tableWidth"
288
+ >
289
+ <colgroup>
290
+ @for (item of slots; track trackBySlotIndex($index, item)) {
291
+ <col>
292
+ }
293
+ </colgroup>
286
294
 
287
- <tbody class="k-table-tbody">
288
- <tr class="k-table-row">
289
- <td *ngFor="let item of slots"
290
- class="k-table-td"
291
- [class.k-nonwork-hour]="isNonWorking(item)"></td>
292
- </tr>
293
- </tbody>
294
- </table>
295
+ <tbody class="k-table-tbody">
296
+ <tr class="k-table-row">
297
+ @for (item of slots; track trackBySlotIndex($index, item)) {
298
+ <td
299
+ class="k-table-td"
300
+ [class.k-nonwork-hour]="isNonWorking(item)"></td>
301
+ }
302
+ </tr>
303
+ </tbody>
304
+ </table>
295
305
 
296
- <table kendoTooltip
297
- #tooltip="kendoTooltip"
298
- [tooltipTemplate]="completion ? completionRatioTooltip : dragging ? resizingTooltip : customTooltipTemplate ? customTooltip : tooltipTemplate"
299
- [position]="tooltipOptions.position"
300
- [callout]="!dragging"
301
- [tooltipClass]="dragging ? 'k-gantt-resize-hint' : undefined"
302
- filter=".k-task"
303
- [showOn]="dragging || completion ? 'none' : 'hover'"
304
- #tasksContainer
305
- class="k-table k-table-md k-gantt-tasks"
306
- role="presentation"
307
- [style.border-collapse]="'collapse'"
308
- [style.width.px]="tableWidth"
309
- >
310
- <tbody
311
- class="k-table-tbody"
312
- kendoGanttTasksTableBody
313
- [rows]="rows"
314
- [activeView]="activeView"
315
- [taskContentTemplate]="taskContentTemplate"
316
- [taskTemplate]="taskTemplate"
317
- [summaryTaskTemplate]="summaryTaskTemplate"
318
- [taskClass]="taskClass"
319
- [isExpanded]="isExpanded"
320
- [selectable]="selectable"
321
- [isTaskSelected]="isTaskSelected"
322
- [renderDependencyDragClues]="renderDependencyDragClues"
323
- (taskPointerEnter)="task = $event"
324
- (taskPointerLeave)="task = null"
325
- >
326
- </tbody>
327
- </table>
328
- </div>
329
- <ng-template #tooltipTemplate>
330
- <div class="k-task-content">
331
- <div class="k-task-details">
332
- <strong>{{task?.title}}</strong>
333
- <div class="k-task-pct">{{task?.completionRatio | kendoNumber: 'p'}}</div>
334
- <ul class="k-reset">
335
- <li>{{messageFor('tooltipStartDateText')}}: {{task?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
336
- <li>{{messageFor('tooltipEndDateText')}}: {{task?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
337
- </ul>
338
- </div>
339
- </div>
340
- </ng-template>
341
- <ng-template #customTooltip>
342
- <ng-container *ngTemplateOutlet="customTooltipTemplate.templateRef; context: { $implicit: task, task }"></ng-container>
343
- </ng-template>
344
- <ng-template #resizingTooltip>
345
- <div class="k-tooltip-content">
346
- <div>{{messageFor('tooltipStartDateText')}}: {{dragResult?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
347
- <div>{{messageFor('tooltipEndDateText')}}: {{dragResult?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
348
- </div>
349
- </ng-template>
350
- <ng-template #completionRatioTooltip>
351
- <div class="k-tooltip-content">
352
- <div>{{dragResult?.completionRatio | kendoNumber: 'p'}}</div>
353
- </div>
354
- </ng-template>
355
-
356
- <svg class="k-gantt-dependencies-svg">
357
- <polyline
358
- *ngFor="let dependency of dependencies"
359
- kendoGanttDependency
360
- [dependency]="dependency"
361
- />
362
- <polyline #dependencyDragCreatePolyline />
363
- </svg>
364
- <div class="k-marquee k-gantt-marquee" *ngIf="marquee.show" style="top: 0px; height: {{tasksContainer.offsetHeight}}px; left: {{marquee.left}}px; width: {{marquee.width}}px;">
365
- <div class="k-marquee-color"></div>
366
- </div>
367
- <!-- placeholder for the dependency drag popup; its position is not arbitrary - the popup is intended to be absolutely positioned inside the .k-grid-content element -->
368
- <ng-container #dragPopupContainer></ng-container>
306
+ <table kendoTooltip
307
+ #tooltip="kendoTooltip"
308
+ [tooltipTemplate]="completion ? completionRatioTooltip : dragging ? resizingTooltip : customTooltipTemplate ? customTooltip : tooltipTemplate"
309
+ [position]="tooltipOptions.position"
310
+ [callout]="!dragging"
311
+ [tooltipClass]="dragging ? 'k-gantt-resize-hint' : undefined"
312
+ filter=".k-task"
313
+ [showOn]="dragging || completion ? 'none' : 'hover'"
314
+ #tasksContainer
315
+ class="k-table k-table-md k-gantt-tasks"
316
+ role="presentation"
317
+ [style.border-collapse]="'collapse'"
318
+ [style.width.px]="tableWidth"
319
+ >
320
+ <tbody
321
+ class="k-table-tbody"
322
+ kendoGanttTasksTableBody
323
+ [rows]="rows"
324
+ [activeView]="activeView"
325
+ [taskContentTemplate]="taskContentTemplate"
326
+ [taskTemplate]="taskTemplate"
327
+ [summaryTaskTemplate]="summaryTaskTemplate"
328
+ [taskClass]="taskClass"
329
+ [isExpanded]="isExpanded"
330
+ [selectable]="selectable"
331
+ [isTaskSelected]="isTaskSelected"
332
+ [renderDependencyDragClues]="renderDependencyDragClues"
333
+ (taskPointerEnter)="task = $event"
334
+ (taskPointerLeave)="task = null"
335
+ >
336
+ </tbody>
337
+ </table>
369
338
  </div>
339
+ <ng-template #tooltipTemplate>
340
+ <div class="k-task-content">
341
+ <div class="k-task-details">
342
+ <strong>{{task?.title}}</strong>
343
+ <div class="k-task-pct">{{task?.completionRatio | kendoNumber: 'p'}}</div>
344
+ <ul class="k-reset">
345
+ <li>{{messageFor('tooltipStartDateText')}}: {{task?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
346
+ <li>{{messageFor('tooltipEndDateText')}}: {{task?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
347
+ </ul>
348
+ </div>
349
+ </div>
350
+ </ng-template>
351
+ <ng-template #customTooltip>
352
+ <ng-container *ngTemplateOutlet="customTooltipTemplate.templateRef; context: { $implicit: task, task }"></ng-container>
353
+ </ng-template>
354
+ <ng-template #resizingTooltip>
355
+ <div class="k-tooltip-content">
356
+ <div>{{messageFor('tooltipStartDateText')}}: {{dragResult?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
357
+ <div>{{messageFor('tooltipEndDateText')}}: {{dragResult?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
358
+ </div>
359
+ </ng-template>
360
+ <ng-template #completionRatioTooltip>
361
+ <div class="k-tooltip-content">
362
+ <div>{{dragResult?.completionRatio | kendoNumber: 'p'}}</div>
363
+ </div>
364
+ </ng-template>
365
+
366
+ <svg class="k-gantt-dependencies-svg">
367
+ @for (dependency of dependencies; track dependency.id) {
368
+ <polyline
369
+ kendoGanttDependency
370
+ [dependency]="dependency"
371
+ />
372
+ }
373
+ <polyline #dependencyDragCreatePolyline />
374
+ </svg>
375
+ @if (marquee.show) {
376
+ <div class="k-marquee k-gantt-marquee" style="top: 0px; height: {{tasksContainer.offsetHeight}}px; left: {{marquee.left}}px; width: {{marquee.width}}px;">
377
+ <div class="k-marquee-color"></div>
378
+ </div>
379
+ }
380
+ <!-- placeholder for the dependency drag popup; its position is not arbitrary - the popup is intended to be absolutely positioned inside the .k-grid-content element -->
381
+ <ng-container #dragPopupContainer></ng-container>
382
+ </div>
370
383
  </div>
371
384
 
372
- `, isInline: true, dependencies: [{ kind: "component", type: GanttHeaderTableBodyComponent, selector: "[kendoGanttHeaderTableBody]", inputs: ["groupSlots", "slots"] }, { kind: "directive", type: TimelineScrollableDirective, selector: "[kendoGanttTimelineScrollable]", inputs: ["scrollSettings"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: GanttTasksTableBodyComponent, selector: "[kendoGanttTasksTableBody]", inputs: ["selectable", "rows", "activeView", "taskContentTemplate", "taskTemplate", "summaryTaskTemplate", "taskClass", "isExpanded", "isTaskSelected", "renderDependencyDragClues"], outputs: ["taskPointerEnter", "taskPointerLeave"] }, { kind: "directive", type: GanttDependencyDirective, selector: "[kendoGanttDependency]", inputs: ["dependency"] }, { kind: "directive", type: i6.TooltipDirective, selector: "[kendoTooltip]", inputs: ["filter", "position", "titleTemplate", "showOn", "showAfter", "callout", "closable", "offset", "tooltipWidth", "tooltipHeight", "tooltipClass", "tooltipContentClass", "collision", "closeTitle", "tooltipTemplate"], exportAs: ["kendoTooltip"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: DatePipe, name: "kendoDate" }, { kind: "pipe", type: NumberPipe, name: "kendoNumber" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
385
+ `, isInline: true, dependencies: [{ kind: "component", type: GanttHeaderTableBodyComponent, selector: "[kendoGanttHeaderTableBody]", inputs: ["groupSlots", "slots"] }, { kind: "directive", type: TimelineScrollableDirective, selector: "[kendoGanttTimelineScrollable]", inputs: ["scrollSettings"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["enableDrag"], outputs: ["kendoPress", "kendoDrag", "kendoRelease"] }, { kind: "component", type: GanttTasksTableBodyComponent, selector: "[kendoGanttTasksTableBody]", inputs: ["selectable", "rows", "activeView", "taskContentTemplate", "taskTemplate", "summaryTaskTemplate", "taskClass", "isExpanded", "isTaskSelected", "renderDependencyDragClues"], outputs: ["taskPointerEnter", "taskPointerLeave"] }, { kind: "directive", type: GanttDependencyDirective, selector: "[kendoGanttDependency]", inputs: ["dependency"] }, { kind: "directive", type: i6.TooltipDirective, selector: "[kendoTooltip]", inputs: ["filter", "position", "titleTemplate", "showOn", "showAfter", "callout", "closable", "offset", "tooltipWidth", "tooltipHeight", "tooltipClass", "tooltipContentClass", "collision", "closeTitle", "tooltipTemplate"], exportAs: ["kendoTooltip"] }, { kind: "pipe", type: DatePipe, name: "kendoDate" }, { kind: "pipe", type: NumberPipe, name: "kendoNumber" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None });
373
386
  }
374
387
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GanttTimelineComponent, decorators: [{
375
388
  type: Component,
@@ -377,151 +390,158 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
377
390
  selector: 'kendo-gantt-timeline',
378
391
  template: `
379
392
  <div class="k-gantt-timeline k-grid k-grid-md">
380
- <div class="k-grid-header">
381
- <div #timelineHeaderWrap class="k-grid-header-wrap">
382
- <table
383
- class="k-table k-table-md k-grid-header-table"
384
- role="presentation"
385
- [style.width.px]="tableWidth"
386
- >
387
- <tbody
388
- kendoGanttHeaderTableBody
389
- [groupSlots]="groupSlots"
390
- [slots]="slots">
391
- </tbody>
392
- </table>
393
- </div>
393
+ <div class="k-grid-header">
394
+ <div #timelineHeaderWrap class="k-grid-header-wrap">
395
+ <table
396
+ class="k-table k-table-md k-grid-header-table"
397
+ role="presentation"
398
+ [style.width.px]="tableWidth"
399
+ >
400
+ <tbody
401
+ kendoGanttHeaderTableBody
402
+ [groupSlots]="groupSlots"
403
+ [slots]="slots">
404
+ </tbody>
405
+ </table>
394
406
  </div>
395
- <!-- tabindex="-1" required for https://bugzilla.mozilla.org/show_bug.cgi?id=1069739 -->
396
- <div
397
- #timelineContent
398
- class="k-grid-content"
399
- tabindex="-1"
400
- role="tree"
401
- aria-roledescription="Timeline"
402
- kendoGanttTimelineScrollable
403
- [scrollSettings]="dragScrollSettings"
404
- kendoDraggable
405
- [enableDrag]="draggableEnabled"
406
- (kendoPress)="timelineContainerPress.emit($event)"
407
- (kendoDrag)="timelineContainerDrag.emit($event)"
408
- (kendoRelease)="timelineContainerRelease.emit($event)"
407
+ </div>
408
+ <!-- tabindex="-1" required for https://bugzilla.mozilla.org/show_bug.cgi?id=1069739 -->
409
+ <div
410
+ #timelineContent
411
+ class="k-grid-content"
412
+ tabindex="-1"
413
+ role="tree"
414
+ aria-roledescription="Timeline"
415
+ kendoGanttTimelineScrollable
416
+ [scrollSettings]="dragScrollSettings"
417
+ kendoDraggable
418
+ [enableDrag]="draggableEnabled"
419
+ (kendoPress)="timelineContainerPress.emit($event)"
420
+ (kendoDrag)="timelineContainerDrag.emit($event)"
421
+ (kendoRelease)="timelineContainerRelease.emit($event)"
409
422
  >
410
- <div class="k-gantt-tables">
411
- <table
412
- class="k-table k-table-md k-grid-table k-gantt-rows"
413
- [style.width.px]="tableWidth"
414
- role="presentation"
415
- >
416
- <tbody class="k-table-tbody">
417
- <tr
418
- *ngFor="let item of rows; let i = index;"
419
- class="k-table-row{{i % 2 ? ' k-table-alt-row' : ''}}">
420
- <td class="k-table-td"></td>
421
- </tr>
422
- </tbody>
423
- </table>
423
+ <div class="k-gantt-tables">
424
+ <table
425
+ class="k-table k-table-md k-grid-table k-gantt-rows"
426
+ [style.width.px]="tableWidth"
427
+ role="presentation"
428
+ >
429
+ <tbody class="k-table-tbody">
430
+ @for (item of rows; track $index; let i = $index) {
431
+ <tr
432
+ class="k-table-row{{i % 2 ? ' k-table-alt-row' : ''}}">
433
+ <td class="k-table-td"></td>
434
+ </tr>
435
+ }
436
+ </tbody>
437
+ </table>
424
438
 
425
- <table
426
- #timelineColumns
427
- class="k-table k-table-md k-gantt-columns"
428
- role="presentation"
429
- [style.width.px]="tableWidth"
430
- >
431
- <colgroup>
432
- <col *ngFor="let item of slots">
433
- </colgroup>
439
+ <table
440
+ #timelineColumns
441
+ class="k-table k-table-md k-gantt-columns"
442
+ role="presentation"
443
+ [style.width.px]="tableWidth"
444
+ >
445
+ <colgroup>
446
+ @for (item of slots; track trackBySlotIndex($index, item)) {
447
+ <col>
448
+ }
449
+ </colgroup>
434
450
 
435
- <tbody class="k-table-tbody">
436
- <tr class="k-table-row">
437
- <td *ngFor="let item of slots"
438
- class="k-table-td"
439
- [class.k-nonwork-hour]="isNonWorking(item)"></td>
440
- </tr>
441
- </tbody>
442
- </table>
451
+ <tbody class="k-table-tbody">
452
+ <tr class="k-table-row">
453
+ @for (item of slots; track trackBySlotIndex($index, item)) {
454
+ <td
455
+ class="k-table-td"
456
+ [class.k-nonwork-hour]="isNonWorking(item)"></td>
457
+ }
458
+ </tr>
459
+ </tbody>
460
+ </table>
443
461
 
444
- <table kendoTooltip
445
- #tooltip="kendoTooltip"
446
- [tooltipTemplate]="completion ? completionRatioTooltip : dragging ? resizingTooltip : customTooltipTemplate ? customTooltip : tooltipTemplate"
447
- [position]="tooltipOptions.position"
448
- [callout]="!dragging"
449
- [tooltipClass]="dragging ? 'k-gantt-resize-hint' : undefined"
450
- filter=".k-task"
451
- [showOn]="dragging || completion ? 'none' : 'hover'"
452
- #tasksContainer
453
- class="k-table k-table-md k-gantt-tasks"
454
- role="presentation"
455
- [style.border-collapse]="'collapse'"
456
- [style.width.px]="tableWidth"
457
- >
458
- <tbody
459
- class="k-table-tbody"
460
- kendoGanttTasksTableBody
461
- [rows]="rows"
462
- [activeView]="activeView"
463
- [taskContentTemplate]="taskContentTemplate"
464
- [taskTemplate]="taskTemplate"
465
- [summaryTaskTemplate]="summaryTaskTemplate"
466
- [taskClass]="taskClass"
467
- [isExpanded]="isExpanded"
468
- [selectable]="selectable"
469
- [isTaskSelected]="isTaskSelected"
470
- [renderDependencyDragClues]="renderDependencyDragClues"
471
- (taskPointerEnter)="task = $event"
472
- (taskPointerLeave)="task = null"
473
- >
474
- </tbody>
475
- </table>
476
- </div>
477
- <ng-template #tooltipTemplate>
478
- <div class="k-task-content">
479
- <div class="k-task-details">
480
- <strong>{{task?.title}}</strong>
481
- <div class="k-task-pct">{{task?.completionRatio | kendoNumber: 'p'}}</div>
482
- <ul class="k-reset">
483
- <li>{{messageFor('tooltipStartDateText')}}: {{task?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
484
- <li>{{messageFor('tooltipEndDateText')}}: {{task?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
485
- </ul>
486
- </div>
487
- </div>
488
- </ng-template>
489
- <ng-template #customTooltip>
490
- <ng-container *ngTemplateOutlet="customTooltipTemplate.templateRef; context: { $implicit: task, task }"></ng-container>
491
- </ng-template>
492
- <ng-template #resizingTooltip>
493
- <div class="k-tooltip-content">
494
- <div>{{messageFor('tooltipStartDateText')}}: {{dragResult?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
495
- <div>{{messageFor('tooltipEndDateText')}}: {{dragResult?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
496
- </div>
497
- </ng-template>
498
- <ng-template #completionRatioTooltip>
499
- <div class="k-tooltip-content">
500
- <div>{{dragResult?.completionRatio | kendoNumber: 'p'}}</div>
501
- </div>
502
- </ng-template>
503
-
504
- <svg class="k-gantt-dependencies-svg">
505
- <polyline
506
- *ngFor="let dependency of dependencies"
507
- kendoGanttDependency
508
- [dependency]="dependency"
509
- />
510
- <polyline #dependencyDragCreatePolyline />
511
- </svg>
512
- <div class="k-marquee k-gantt-marquee" *ngIf="marquee.show" style="top: 0px; height: {{tasksContainer.offsetHeight}}px; left: {{marquee.left}}px; width: {{marquee.width}}px;">
513
- <div class="k-marquee-color"></div>
514
- </div>
515
- <!-- placeholder for the dependency drag popup; its position is not arbitrary - the popup is intended to be absolutely positioned inside the .k-grid-content element -->
516
- <ng-container #dragPopupContainer></ng-container>
462
+ <table kendoTooltip
463
+ #tooltip="kendoTooltip"
464
+ [tooltipTemplate]="completion ? completionRatioTooltip : dragging ? resizingTooltip : customTooltipTemplate ? customTooltip : tooltipTemplate"
465
+ [position]="tooltipOptions.position"
466
+ [callout]="!dragging"
467
+ [tooltipClass]="dragging ? 'k-gantt-resize-hint' : undefined"
468
+ filter=".k-task"
469
+ [showOn]="dragging || completion ? 'none' : 'hover'"
470
+ #tasksContainer
471
+ class="k-table k-table-md k-gantt-tasks"
472
+ role="presentation"
473
+ [style.border-collapse]="'collapse'"
474
+ [style.width.px]="tableWidth"
475
+ >
476
+ <tbody
477
+ class="k-table-tbody"
478
+ kendoGanttTasksTableBody
479
+ [rows]="rows"
480
+ [activeView]="activeView"
481
+ [taskContentTemplate]="taskContentTemplate"
482
+ [taskTemplate]="taskTemplate"
483
+ [summaryTaskTemplate]="summaryTaskTemplate"
484
+ [taskClass]="taskClass"
485
+ [isExpanded]="isExpanded"
486
+ [selectable]="selectable"
487
+ [isTaskSelected]="isTaskSelected"
488
+ [renderDependencyDragClues]="renderDependencyDragClues"
489
+ (taskPointerEnter)="task = $event"
490
+ (taskPointerLeave)="task = null"
491
+ >
492
+ </tbody>
493
+ </table>
517
494
  </div>
495
+ <ng-template #tooltipTemplate>
496
+ <div class="k-task-content">
497
+ <div class="k-task-details">
498
+ <strong>{{task?.title}}</strong>
499
+ <div class="k-task-pct">{{task?.completionRatio | kendoNumber: 'p'}}</div>
500
+ <ul class="k-reset">
501
+ <li>{{messageFor('tooltipStartDateText')}}: {{task?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
502
+ <li>{{messageFor('tooltipEndDateText')}}: {{task?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</li>
503
+ </ul>
504
+ </div>
505
+ </div>
506
+ </ng-template>
507
+ <ng-template #customTooltip>
508
+ <ng-container *ngTemplateOutlet="customTooltipTemplate.templateRef; context: { $implicit: task, task }"></ng-container>
509
+ </ng-template>
510
+ <ng-template #resizingTooltip>
511
+ <div class="k-tooltip-content">
512
+ <div>{{messageFor('tooltipStartDateText')}}: {{dragResult?.start | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
513
+ <div>{{messageFor('tooltipEndDateText')}}: {{dragResult?.end | kendoDate: 'HH:mm a EEE, MMM d'}}</div>
514
+ </div>
515
+ </ng-template>
516
+ <ng-template #completionRatioTooltip>
517
+ <div class="k-tooltip-content">
518
+ <div>{{dragResult?.completionRatio | kendoNumber: 'p'}}</div>
519
+ </div>
520
+ </ng-template>
521
+
522
+ <svg class="k-gantt-dependencies-svg">
523
+ @for (dependency of dependencies; track dependency.id) {
524
+ <polyline
525
+ kendoGanttDependency
526
+ [dependency]="dependency"
527
+ />
528
+ }
529
+ <polyline #dependencyDragCreatePolyline />
530
+ </svg>
531
+ @if (marquee.show) {
532
+ <div class="k-marquee k-gantt-marquee" style="top: 0px; height: {{tasksContainer.offsetHeight}}px; left: {{marquee.left}}px; width: {{marquee.width}}px;">
533
+ <div class="k-marquee-color"></div>
534
+ </div>
535
+ }
536
+ <!-- placeholder for the dependency drag popup; its position is not arbitrary - the popup is intended to be absolutely positioned inside the .k-grid-content element -->
537
+ <ng-container #dragPopupContainer></ng-container>
538
+ </div>
518
539
  </div>
519
540
 
520
- `,
541
+ `,
521
542
  standalone: true,
522
543
  encapsulation: ViewEncapsulation.None,
523
- imports: [GanttHeaderTableBodyComponent, TimelineScrollableDirective, DraggableDirective, NgFor, GanttTasksTableBodyComponent,
524
- GanttDependencyDirective, KENDO_TOOLTIP, NgIf, DatePipe, NumberPipe, NgTemplateOutlet],
544
+ imports: [GanttHeaderTableBodyComponent, TimelineScrollableDirective, DraggableDirective, GanttTasksTableBodyComponent, GanttDependencyDirective, KENDO_TOOLTIP, DatePipe, NumberPipe, NgTemplateOutlet],
525
545
  }]
526
546
  }], ctorParameters: () => [{ type: i1.ScrollSyncService }, { type: i2.DependencyDomService }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i3.CurrentTimeMarkerService }, { type: i4.GanttLocalizationService }, { type: i5.TaskDragService, decorators: [{
527
547
  type: Optional