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

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