tg-ganttchart 0.0.14 → 0.0.16

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.
@@ -3375,7 +3375,7 @@ if (typeof window !== 'undefined') {
3375
3375
  // Indicate to webpack that this file can be concatenated
3376
3376
  /* harmony default export */ var setPublicPath = (null);
3377
3377
 
3378
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/GanttElastic.standalone.vue?vue&type=template&id=ba4781dc
3378
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/GanttElastic.standalone.vue?vue&type=template&id=6d043e84
3379
3379
  var render = function render() {
3380
3380
  var _vm = this,
3381
3381
  _c = _vm._self._c;
@@ -3383,7 +3383,11 @@ var render = function render() {
3383
3383
  attrs: {
3384
3384
  "tasks": _vm.tasks,
3385
3385
  "options": _vm.options,
3386
- "dynamicStyle": _vm.dynamicStyle
3386
+ "dynamicStyle": _vm.dynamicStyle,
3387
+ "isHeaderVisible": _vm.isHeaderVisible,
3388
+ "projectName": _vm.projectName,
3389
+ "headerLeftSideLabels": _vm.headerLeftSideLabels,
3390
+ "headerLegendConfig": _vm.headerLegendConfig
3387
3391
  },
3388
3392
  on: {
3389
3393
  "task-updated": function ($event) {
@@ -3407,8 +3411,35 @@ var render = function render() {
3407
3411
  "dynamic-style-changed": function ($event) {
3408
3412
  return _vm.$emit('dynamic-style-changed', $event);
3409
3413
  },
3414
+ "action-button-clicked": function ($event) {
3415
+ return _vm.$emit('action-button-clicked', $event);
3416
+ },
3417
+ "calendar-recalculate": function ($event) {
3418
+ return _vm.$emit('calendar-recalculate', $event);
3419
+ },
3420
+ "created": function ($event) {
3421
+ return _vm.$emit('created', $event);
3422
+ },
3423
+ "before-mount": function ($event) {
3424
+ return _vm.$emit('before-mount', $event);
3425
+ },
3426
+ "ready": function ($event) {
3427
+ return _vm.$emit('ready', $event);
3428
+ },
3410
3429
  "mounted": function ($event) {
3411
3430
  return _vm.$emit('mounted', $event);
3431
+ },
3432
+ "before-update": function ($event) {
3433
+ return _vm.$emit('before-update', $event);
3434
+ },
3435
+ "updated": function ($event) {
3436
+ return _vm.$emit('updated', $event);
3437
+ },
3438
+ "before-destroy": function ($event) {
3439
+ return _vm.$emit('before-destroy', $event);
3440
+ },
3441
+ "destroyed": function ($event) {
3442
+ return _vm.$emit('destroyed', $event);
3412
3443
  }
3413
3444
  }
3414
3445
  }, [_vm.components.header ? _c(_vm.components.header, {
@@ -3427,8 +3458,8 @@ var render = function render() {
3427
3458
  };
3428
3459
  var staticRenderFns = [];
3429
3460
 
3430
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/GanttElastic.vue?vue&type=template&id=95091692
3431
- var GanttElasticvue_type_template_id_95091692_render = function render() {
3461
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/GanttElastic.vue?vue&type=template&id=2e042034
3462
+ var GanttElasticvue_type_template_id_2e042034_render = function render() {
3432
3463
  var _vm = this,
3433
3464
  _c = _vm._self._c,
3434
3465
  _setup = _vm._self._setupProxy;
@@ -3444,7 +3475,9 @@ var GanttElasticvue_type_template_id_95091692_render = function render() {
3444
3475
  slot: "header"
3445
3476
  }) : _vm._e(), _c('gantt-view-filter', {
3446
3477
  attrs: {
3447
- "slot": "header"
3478
+ "slot": "header",
3479
+ "left-side-labels": _vm.headerLeftSideLabels,
3480
+ "legend-config": _vm.headerLegendConfig
3448
3481
  },
3449
3482
  on: {
3450
3483
  "view-mode-changed": _vm.onViewModeChanged
@@ -3457,7 +3490,7 @@ var GanttElasticvue_type_template_id_95091692_render = function render() {
3457
3490
  }
3458
3491
  }), _vm._t("footer")], 2);
3459
3492
  };
3460
- var GanttElasticvue_type_template_id_95091692_staticRenderFns = [];
3493
+ var GanttElasticvue_type_template_id_2e042034_staticRenderFns = [];
3461
3494
 
3462
3495
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.push.js
3463
3496
  var es_array_push = __webpack_require__(4114);
@@ -3488,14 +3521,37 @@ var esnext_iterator_reduce = __webpack_require__(8872);
3488
3521
  // EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js
3489
3522
  var dayjs_min = __webpack_require__(4353);
3490
3523
  var dayjs_min_default = /*#__PURE__*/__webpack_require__.n(dayjs_min);
3491
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/Header/GanttViewFilter.vue?vue&type=template&id=f4bb58fc&scoped=true
3492
- var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function render() {
3524
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/Header/GanttViewFilter.vue?vue&type=template&id=eb2e1196&scoped=true
3525
+ var GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_render = function render() {
3493
3526
  var _vm = this,
3494
3527
  _c = _vm._self._c;
3495
3528
  return _c('div', {
3496
3529
  staticClass: "gantt-view-filter"
3497
3530
  }, [_c('div', {
3498
3531
  staticClass: "view-toggle-group"
3532
+ }, [_c('div', {
3533
+ staticClass: "left-side-labels"
3534
+ }, _vm._l(_vm.leftSideLabels, function (label, index) {
3535
+ return _c('span', {
3536
+ key: index,
3537
+ staticClass: "left-label-item"
3538
+ }, [_vm._v(" " + _vm._s(label) + " ")]);
3539
+ }), 0), _c('div', {
3540
+ staticClass: "legend-section"
3541
+ }, _vm._l(_vm.legendItems, function (legendItem) {
3542
+ return _c('span', {
3543
+ key: legendItem.type,
3544
+ staticClass: "legend-item-wrapper"
3545
+ }, [_c('span', {
3546
+ staticClass: "colorboxsquare",
3547
+ style: {
3548
+ backgroundColor: legendItem.color
3549
+ }
3550
+ }), _c('span', {
3551
+ staticClass: "legend-label"
3552
+ }, [_vm._v(_vm._s(legendItem.label))])]);
3553
+ }), 0), _c('div', {
3554
+ staticClass: "view-toggle-buttons"
3499
3555
  }, [_c('button', {
3500
3556
  staticClass: "view-toggle-btn",
3501
3557
  class: {
@@ -3508,7 +3564,7 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3508
3564
  }
3509
3565
  }, [_c('span', {
3510
3566
  staticClass: "view-icon"
3511
- }, [_vm._v("📅")]), _c('span', {
3567
+ }), _c('span', {
3512
3568
  staticClass: "view-label"
3513
3569
  }, [_vm._v("Day")])]), _c('button', {
3514
3570
  staticClass: "view-toggle-btn",
@@ -3522,7 +3578,7 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3522
3578
  }
3523
3579
  }, [_c('span', {
3524
3580
  staticClass: "view-icon"
3525
- }, [_vm._v("📊")]), _c('span', {
3581
+ }), _c('span', {
3526
3582
  staticClass: "view-label"
3527
3583
  }, [_vm._v("Week")])]), _c('button', {
3528
3584
  staticClass: "view-toggle-btn",
@@ -3536,7 +3592,7 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3536
3592
  }
3537
3593
  }, [_c('span', {
3538
3594
  staticClass: "view-icon"
3539
- }, [_vm._v("🗓️")]), _c('span', {
3595
+ }), _c('span', {
3540
3596
  staticClass: "view-label"
3541
3597
  }, [_vm._v("Month")])]), _c('button', {
3542
3598
  staticClass: "view-toggle-btn",
@@ -3550,36 +3606,139 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3550
3606
  }
3551
3607
  }, [_c('span', {
3552
3608
  staticClass: "view-icon"
3553
- }, [_vm._v("📈")]), _c('span', {
3609
+ }), _c('span', {
3554
3610
  staticClass: "view-label"
3555
- }, [_vm._v("Quarter")])])])]);
3611
+ }, [_vm._v("Quarter")])])])])]);
3556
3612
  };
3557
- var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_staticRenderFns = [];
3613
+ var GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_staticRenderFns = [];
3558
3614
 
3559
3615
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/Header/GanttViewFilter.vue?vue&type=script&lang=js
3616
+
3617
+
3618
+
3619
+
3620
+
3621
+
3622
+
3623
+
3624
+
3625
+
3560
3626
  /* harmony default export */ var GanttViewFiltervue_type_script_lang_js = ({
3561
3627
  name: 'GanttViewFilter',
3628
+ inject: ['root'],
3629
+ props: {
3630
+ leftSideLabels: {
3631
+ type: Array,
3632
+ default: () => ['Timeline', 'Epic', 'Task Story']
3633
+ },
3634
+ legendConfig: {
3635
+ type: Array,
3636
+ default: () => null // If null, will be computed from tasks
3637
+ }
3638
+ },
3562
3639
  data() {
3563
3640
  return {
3564
3641
  viewMode: 'day' // default view mode
3565
3642
  };
3566
3643
  },
3644
+ computed: {
3645
+ /**
3646
+ * Get unique task types from tasks
3647
+ */
3648
+ uniqueTaskTypes() {
3649
+ if (!this.root || !this.root.state || !this.root.state.tasks) {
3650
+ return [];
3651
+ }
3652
+ const taskTypes = new Set();
3653
+ this.root.state.tasks.forEach(task => {
3654
+ if (task.type) {
3655
+ taskTypes.add(task.type);
3656
+ }
3657
+ });
3658
+ return Array.from(taskTypes);
3659
+ },
3660
+ /**
3661
+ * Color map for task types - matches chart colors
3662
+ */
3663
+ taskTypeColors() {
3664
+ return {
3665
+ 'milestone': '#CD5C5C',
3666
+ 'task': '#3B82F6',
3667
+ 'project': '#8B5CF6',
3668
+ 'sprint': '#F59E0B',
3669
+ 'flag': '#10B981',
3670
+ 'check': '#3B82F6',
3671
+ 'epic': '#8B5CF6',
3672
+ 'story': '#86EFAC',
3673
+ 'subtask': '#3B82F6'
3674
+ };
3675
+ },
3676
+ /**
3677
+ * Task type labels (capitalized, human-readable)
3678
+ */
3679
+ taskTypeLabels() {
3680
+ return {
3681
+ 'milestone': 'Milestone',
3682
+ 'task': 'Task',
3683
+ 'project': 'Project',
3684
+ 'sprint': 'Sprint',
3685
+ 'flag': 'Flag',
3686
+ 'check': 'Check',
3687
+ 'epic': 'Epic',
3688
+ 'story': 'Story',
3689
+ 'subtask': 'Subtask'
3690
+ };
3691
+ },
3692
+ /**
3693
+ * Generate legend items dynamically from tasks or use provided config
3694
+ */
3695
+ legendItems() {
3696
+ // If custom config provided, use it
3697
+ if (this.legendConfig && Array.isArray(this.legendConfig)) {
3698
+ return this.legendConfig;
3699
+ }
3700
+
3701
+ // Otherwise, generate from unique task types
3702
+ const items = [];
3703
+ this.uniqueTaskTypes.forEach(type => {
3704
+ items.push({
3705
+ type: type,
3706
+ label: this.taskTypeLabels[type] || this.capitalizeFirst(type),
3707
+ color: this.taskTypeColors[type] || '#6B7280'
3708
+ });
3709
+ });
3710
+
3711
+ // Sort items in a consistent order (epic, story, task, milestone, etc.)
3712
+ const order = ['epic', 'story', 'task', 'subtask', 'milestone', 'project', 'sprint'];
3713
+ items.sort((a, b) => {
3714
+ const indexA = order.indexOf(a.type);
3715
+ const indexB = order.indexOf(b.type);
3716
+ if (indexA === -1 && indexB === -1) return 0;
3717
+ if (indexA === -1) return 1;
3718
+ if (indexB === -1) return -1;
3719
+ return indexA - indexB;
3720
+ });
3721
+ return items;
3722
+ }
3723
+ },
3567
3724
  methods: {
3568
3725
  changeViewMode(mode) {
3569
- // eslint-disable-next-line no-debugger
3570
- debugger;
3571
3726
  this.viewMode = mode;
3572
3727
  // Emit an event to the parent component (App.vue) so it can update the Gantt chart
3573
3728
  this.$emit('view-mode-changed', mode);
3729
+ },
3730
+ capitalizeFirst(str) {
3731
+ if (!str) return '';
3732
+ return str.charAt(0).toUpperCase() + str.slice(1);
3574
3733
  }
3575
3734
  }
3576
3735
  });
3577
3736
  ;// ./src/components/Header/GanttViewFilter.vue?vue&type=script&lang=js
3578
3737
  /* harmony default export */ var Header_GanttViewFiltervue_type_script_lang_js = (GanttViewFiltervue_type_script_lang_js);
3579
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/Header/GanttViewFilter.vue?vue&type=style&index=0&id=f4bb58fc&prod&scoped=true&lang=css
3738
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/Header/GanttViewFilter.vue?vue&type=style&index=0&id=eb2e1196&prod&scoped=true&lang=css
3580
3739
  // extracted by mini-css-extract-plugin
3581
3740
 
3582
- ;// ./src/components/Header/GanttViewFilter.vue?vue&type=style&index=0&id=f4bb58fc&prod&scoped=true&lang=css
3741
+ ;// ./src/components/Header/GanttViewFilter.vue?vue&type=style&index=0&id=eb2e1196&prod&scoped=true&lang=css
3583
3742
 
3584
3743
  ;// ./node_modules/@vue/vue-loader-v15/lib/runtime/componentNormalizer.js
3585
3744
  /* globals __VUE_SSR_CONTEXT__ */
@@ -3690,11 +3849,11 @@ function normalizeComponent(
3690
3849
 
3691
3850
  var component = normalizeComponent(
3692
3851
  Header_GanttViewFiltervue_type_script_lang_js,
3693
- GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render,
3694
- GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_staticRenderFns,
3852
+ GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_render,
3853
+ GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_staticRenderFns,
3695
3854
  false,
3696
3855
  null,
3697
- "f4bb58fc",
3856
+ "eb2e1196",
3698
3857
  null
3699
3858
 
3700
3859
  )
@@ -3873,8 +4032,8 @@ var TaskListvue_type_template_id_b705a4ea_render = function render() {
3873
4032
  };
3874
4033
  var TaskListvue_type_template_id_b705a4ea_staticRenderFns = [];
3875
4034
 
3876
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/TaskList/TaskListHeader.vue?vue&type=template&id=2ecc0032
3877
- var TaskListHeadervue_type_template_id_2ecc0032_render = function render() {
4035
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/TaskList/TaskListHeader.vue?vue&type=template&id=92de7fea
4036
+ var TaskListHeadervue_type_template_id_92de7fea_render = function render() {
3878
4037
  var _vm = this,
3879
4038
  _c = _vm._self._c;
3880
4039
  return _c('div', {
@@ -3894,7 +4053,8 @@ var TaskListHeadervue_type_template_id_2ecc0032_render = function render() {
3894
4053
  staticClass: "gantt-elastic__task-list-header-label",
3895
4054
  style: _vm.headerLabelStyle(column),
3896
4055
  attrs: {
3897
- "column": column
4056
+ "column": column,
4057
+ "title": _vm.getTooltipText(column)
3898
4058
  },
3899
4059
  on: {
3900
4060
  "mouseup": _vm.resizerMouseUp
@@ -3922,7 +4082,7 @@ var TaskListHeadervue_type_template_id_2ecc0032_render = function render() {
3922
4082
  }), 0)])], 1);
3923
4083
  }), 0);
3924
4084
  };
3925
- var TaskListHeadervue_type_template_id_2ecc0032_staticRenderFns = [];
4085
+ var TaskListHeadervue_type_template_id_92de7fea_staticRenderFns = [];
3926
4086
 
3927
4087
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/Expander.vue?vue&type=template&id=4831d194
3928
4088
  var Expandervue_type_template_id_4831d194_render = function render() {
@@ -4110,6 +4270,17 @@ var Expander_component = normalizeComponent(
4110
4270
  }
4111
4271
  },
4112
4272
  methods: {
4273
+ getTooltipText(column) {
4274
+ // Return descriptive tooltips for each column
4275
+ const tooltips = {
4276
+ 'ID': 'Task identifier number',
4277
+ 'Description': 'Task name and description',
4278
+ 'Assigned to': 'Person or role responsible for this task',
4279
+ 'Start': 'Task start date and time',
4280
+ 'Progress': 'Task completion percentage (0-100%)'
4281
+ };
4282
+ return tooltips[column.label] || column.label;
4283
+ },
4113
4284
  columnStyle(column) {
4114
4285
  return {
4115
4286
  ...this.root.style['task-list-header-column'],
@@ -4191,8 +4362,8 @@ var Expander_component = normalizeComponent(
4191
4362
  ;
4192
4363
  var TaskListHeader_component = normalizeComponent(
4193
4364
  TaskList_TaskListHeadervue_type_script_lang_js,
4194
- TaskListHeadervue_type_template_id_2ecc0032_render,
4195
- TaskListHeadervue_type_template_id_2ecc0032_staticRenderFns,
4365
+ TaskListHeadervue_type_template_id_92de7fea_render,
4366
+ TaskListHeadervue_type_template_id_92de7fea_staticRenderFns,
4196
4367
  false,
4197
4368
  null,
4198
4369
  null,
@@ -4228,8 +4399,8 @@ var TaskListItemvue_type_template_id_b99d1d94_render = function render() {
4228
4399
  };
4229
4400
  var TaskListItemvue_type_template_id_b99d1d94_staticRenderFns = [];
4230
4401
 
4231
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/TaskList/ItemColumn.vue?vue&type=template&id=f410efbc
4232
- var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4402
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/templateLoader.js??ruleSet[1].rules[3]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/TaskList/ItemColumn.vue?vue&type=template&id=6a863d80
4403
+ var ItemColumnvue_type_template_id_6a863d80_render = function render() {
4233
4404
  var _vm = this,
4234
4405
  _c = _vm._self._c;
4235
4406
  return _c('div', {
@@ -4244,6 +4415,9 @@ var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4244
4415
  }, [!_vm.html ? _c('div', {
4245
4416
  staticClass: "gantt-elastic__task-list-item-value",
4246
4417
  style: _vm.valueStyle,
4418
+ attrs: {
4419
+ "title": _vm.tooltipText
4420
+ },
4247
4421
  on: {
4248
4422
  "click": function ($event) {
4249
4423
  return _vm.emitEvent('click', $event);
@@ -4301,6 +4475,9 @@ var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4301
4475
  }, [_vm._v(_vm._s(_vm.value))])]) : _c('div', {
4302
4476
  staticClass: "gantt-elastic__task-list-item-value",
4303
4477
  style: _vm.valueStyle,
4478
+ attrs: {
4479
+ "title": _vm.tooltipText
4480
+ },
4304
4481
  on: {
4305
4482
  "click": function ($event) {
4306
4483
  return _vm.emitEvent('click', $event);
@@ -4360,9 +4537,10 @@ var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4360
4537
  }
4361
4538
  })])])], 2)]);
4362
4539
  };
4363
- var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4540
+ var ItemColumnvue_type_template_id_6a863d80_staticRenderFns = [];
4364
4541
 
4365
4542
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/TaskList/ItemColumn.vue?vue&type=script&lang=js
4543
+
4366
4544
  /* harmony default export */ var ItemColumnvue_type_script_lang_js = ({
4367
4545
  name: 'ItemColumn',
4368
4546
  inject: ['root'],
@@ -4378,6 +4556,29 @@ var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4378
4556
  * @param {Event} event
4379
4557
  */
4380
4558
  emitEvent(eventName, event) {
4559
+ // Handle action button clicks from dynamically generated HTML buttons
4560
+ if (eventName === 'click' && event && event.target) {
4561
+ const button = event.target.closest('.action-btn');
4562
+ if (button) {
4563
+ event.preventDefault();
4564
+ event.stopPropagation();
4565
+ const action = button.getAttribute('data-action');
4566
+ const buttonId = button.getAttribute('data-button-id');
4567
+ const taskId = button.getAttribute('data-task-id');
4568
+
4569
+ // Emit action button click event
4570
+ this.root.$emit('action-button-clicked', {
4571
+ action: action,
4572
+ buttonId: buttonId,
4573
+ taskId: taskId ? isNaN(taskId) ? taskId : parseFloat(taskId) : this.task.id,
4574
+ task: this.task,
4575
+ column: this.column
4576
+ });
4577
+ return;
4578
+ }
4579
+ }
4580
+
4581
+ // Normal column event handling
4381
4582
  if (typeof this.column.events !== 'undefined' && typeof this.column.events[eventName] === 'function') {
4382
4583
  this.column.events[eventName]({
4383
4584
  event,
@@ -4410,10 +4611,109 @@ var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4410
4611
  * @returns {any|string}
4411
4612
  */
4412
4613
  value() {
4614
+ // Handle function-based column values
4413
4615
  if (typeof this.column.value === 'function') {
4414
- return this.column.value(this.task);
4616
+ try {
4617
+ const result = this.column.value(this.task);
4618
+ // For Start column: Always use fallback if result is empty/null/undefined
4619
+ // This ensures Start column always displays even if the function fails due to closure issues
4620
+ if (this.column.label === 'Start') {
4621
+ if (result === null || result === undefined || result === '') {
4622
+ return this.formatStartDate();
4623
+ }
4624
+ // If result is valid, return it
4625
+ return result;
4626
+ }
4627
+ // For other columns: return result as is
4628
+ if (result !== null && result !== undefined && result !== '') {
4629
+ return result;
4630
+ }
4631
+ return result || '';
4632
+ } catch (error) {
4633
+ console.error('Error executing column value function:', error, this.column, this.task);
4634
+ // For Start column: Always use fallback on error
4635
+ if (this.column.label === 'Start' && this.task) {
4636
+ return this.formatStartDate();
4637
+ }
4638
+ return '';
4639
+ }
4640
+ }
4641
+ // If column value is a string and it's "start", format it
4642
+ if (this.column.value === 'start' && this.column.label === 'Start') {
4643
+ return this.formatStartDate();
4644
+ }
4645
+ // Handle string-based column values
4646
+ if (typeof this.column.value === 'string') {
4647
+ const taskValue = this.task[this.column.value];
4648
+ return taskValue !== null && taskValue !== undefined ? taskValue : '';
4649
+ }
4650
+ return '';
4651
+ },
4652
+ /**
4653
+ * Format start date for Start column
4654
+ */
4655
+ formatStartDate() {
4656
+ if (!this.task) return '';
4657
+ try {
4658
+ // Try to get start value from different possible properties
4659
+ const startValue = this.task.startTime || this.task.start;
4660
+ if (!startValue) return '';
4661
+
4662
+ // Ensure dayjs is imported and available
4663
+ if (typeof (dayjs_min_default()) === 'undefined') {
4664
+ console.warn('dayjs is not available in ItemColumn, returning raw value');
4665
+ return String(startValue);
4666
+ }
4667
+
4668
+ // Parse with dayjs
4669
+ const date = dayjs_min_default()(startValue);
4670
+
4671
+ // Return formatted date if valid
4672
+ if (date && date.isValid()) {
4673
+ return date.format("YYYY-MM-DD HH:mm A");
4674
+ }
4675
+
4676
+ // Fallback: return as string if date is invalid
4677
+ return String(startValue);
4678
+ } catch (error) {
4679
+ console.error('Error formatting start date in ItemColumn:', error, this.task);
4680
+ // Last resort: return the raw value as string
4681
+ const startValue = this.task.startTime || this.task.start;
4682
+ return startValue ? String(startValue) : '';
4415
4683
  }
4416
- return this.task[this.column.value];
4684
+ },
4685
+ /**
4686
+ * Get tooltip text for the column value
4687
+ *
4688
+ * @returns {string}
4689
+ */
4690
+ tooltipText() {
4691
+ let tooltipValue = this.value;
4692
+
4693
+ // If value is HTML, strip HTML tags for tooltip
4694
+ if (this.html && typeof tooltipValue === 'string') {
4695
+ // Strip HTML tags using regex (simple approach)
4696
+ tooltipValue = tooltipValue.replace(/<[^>]*>/g, '').trim();
4697
+ }
4698
+
4699
+ // Convert to string if not already
4700
+ const stringValue = String(tooltipValue || '').trim();
4701
+
4702
+ // Format tooltip based on column type
4703
+ if (this.column.label === 'Progress') {
4704
+ return stringValue ? `${stringValue}% complete` : 'Progress not set';
4705
+ } else if (this.column.label === 'Start') {
4706
+ return stringValue ? `Start: ${stringValue}` : 'Start date not set';
4707
+ } else if (this.column.label === 'ID') {
4708
+ return stringValue ? `Task ID: ${stringValue}` : 'No ID';
4709
+ } else if (this.column.label === 'Assigned to') {
4710
+ return stringValue ? `Assigned to: ${stringValue}` : 'Not assigned';
4711
+ } else if (this.column.label === 'Description') {
4712
+ return stringValue || 'No description';
4713
+ }
4714
+
4715
+ // Default: return the value as string
4716
+ return stringValue || '';
4417
4717
  },
4418
4718
  itemColumnStyle() {
4419
4719
  return {
@@ -4544,8 +4844,8 @@ var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4544
4844
  ;
4545
4845
  var ItemColumn_component = normalizeComponent(
4546
4846
  TaskList_ItemColumnvue_type_script_lang_js,
4547
- ItemColumnvue_type_template_id_f410efbc_render,
4548
- ItemColumnvue_type_template_id_f410efbc_staticRenderFns,
4847
+ ItemColumnvue_type_template_id_6a863d80_render,
4848
+ ItemColumnvue_type_template_id_6a863d80_staticRenderFns,
4549
4849
  false,
4550
4850
  null,
4551
4851
  null,
@@ -7146,7 +7446,7 @@ var ProgressBar_component = normalizeComponent(
7146
7446
  document.removeEventListener('click', this.hideContextMenu);
7147
7447
 
7148
7448
  // Clean up context menu
7149
- this.hideContextMenu();
7449
+ //this.hideContextMenu();
7150
7450
 
7151
7451
  // Clean up date tooltip
7152
7452
  this.removeDateTooltip();
@@ -11330,6 +11630,11 @@ function mergeDeep(target, ...sources) {
11330
11630
  const source = sources.shift();
11331
11631
  if (isObject(target) && isObject(source)) {
11332
11632
  for (const key in source) {
11633
+ // Preserve functions - don't deep merge them
11634
+ if (typeof source[key] === 'function') {
11635
+ target[key] = source[key];
11636
+ continue;
11637
+ }
11333
11638
  if (isObject(source[key])) {
11334
11639
  if (typeof target[key] === 'undefined') {
11335
11640
  target[key] = {};
@@ -11339,7 +11644,15 @@ function mergeDeep(target, ...sources) {
11339
11644
  target[key] = [];
11340
11645
  for (let item of source[key]) {
11341
11646
  if (isObject(item)) {
11342
- target[key].push(mergeDeep({}, item));
11647
+ // Preserve functions in array items (like column.value functions)
11648
+ const mergedItem = mergeDeep({}, item);
11649
+ // Ensure functions are preserved
11650
+ for (const itemKey in item) {
11651
+ if (typeof item[itemKey] === 'function') {
11652
+ mergedItem[itemKey] = item[itemKey];
11653
+ }
11654
+ }
11655
+ target[key].push(mergedItem);
11343
11656
  continue;
11344
11657
  }
11345
11658
  target[key].push(item);
@@ -11487,7 +11800,7 @@ const GanttElastic = {
11487
11800
  'gantt-header': Header,
11488
11801
  'gantt-view-filter': GanttViewFilter
11489
11802
  },
11490
- props: ['tasks', 'options', 'dynamicStyle', 'isHeaderVisible', 'projectName'],
11803
+ props: ['tasks', 'options', 'dynamicStyle', 'isHeaderVisible', 'projectName', 'headerLeftSideLabels', 'headerLegendConfig'],
11491
11804
  provide() {
11492
11805
  const provider = {};
11493
11806
  const self = this;
@@ -11806,17 +12119,39 @@ const GanttElastic = {
11806
12119
  options.taskList = {};
11807
12120
  }
11808
12121
  options.taskList.columns = options.taskList.columns.map((column, index) => {
11809
- column.thresholdPercent = 100;
11810
- column.widthFromPercentage = 0;
11811
- column.finalWidth = 0;
11812
- if (typeof column.height === 'undefined') {
11813
- column.height = 0;
12122
+ // Create a new column object to avoid mutating the original
12123
+ const newColumn = {
12124
+ ...column,
12125
+ thresholdPercent: 100,
12126
+ widthFromPercentage: 0,
12127
+ finalWidth: 0,
12128
+ height: typeof column.height !== 'undefined' ? column.height : 0,
12129
+ style: typeof column.style !== 'undefined' ? column.style : {},
12130
+ _id: `${index}-${column.label}`
12131
+ };
12132
+
12133
+ // Preserve the value function reference if it exists
12134
+ // This is critical to prevent closure issues when columns are cloned
12135
+ if (typeof column.value === 'function') {
12136
+ // If column has buttons array, bind the function to access this.buttons
12137
+ if (column.buttons && Array.isArray(column.buttons)) {
12138
+ newColumn.buttons = column.buttons;
12139
+ newColumn.value = column.value.bind(newColumn);
12140
+ } else {
12141
+ newColumn.value = column.value;
12142
+ }
11814
12143
  }
11815
- if (typeof column.style === 'undefined') {
11816
- column.style = {};
12144
+
12145
+ // Preserve buttons array if it exists (for action columns)
12146
+ if (column.buttons && Array.isArray(column.buttons)) {
12147
+ newColumn.buttons = column.buttons;
12148
+ }
12149
+
12150
+ // Preserve events if they exist
12151
+ if (column.events) {
12152
+ newColumn.events = column.events;
11817
12153
  }
11818
- column._id = `${index}-${column.label}`;
11819
- return column;
12154
+ return newColumn;
11820
12155
  });
11821
12156
  this.state.options = options;
11822
12157
  tasks = this.fillTasks(tasks);
@@ -12284,6 +12619,10 @@ const GanttElastic = {
12284
12619
  this.$on('scope-change', this.onScopeChange);
12285
12620
  this.$on('taskList-width-change', this.onTaskListWidthChange);
12286
12621
  this.$on('taskList-column-width-change', this.onTaskListColumnWidthChange);
12622
+ // Forward action button click events to parent
12623
+ this.$on('action-button-clicked', payload => {
12624
+ this.$emit('action-button-clicked', payload);
12625
+ });
12287
12626
  },
12288
12627
  /**
12289
12628
  * Get responsive step widths based on screen size
@@ -13105,10 +13444,10 @@ const GanttElastic = {
13105
13444
  /* harmony default export */ var GanttElasticvue_type_script_lang_js = (GanttElastic);
13106
13445
  ;// ./src/GanttElastic.vue?vue&type=script&lang=js
13107
13446
  /* harmony default export */ var src_GanttElasticvue_type_script_lang_js = (GanttElasticvue_type_script_lang_js);
13108
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/GanttElastic.vue?vue&type=style&index=0&id=95091692&prod&lang=css
13447
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-12.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/GanttElastic.vue?vue&type=style&index=0&id=2e042034&prod&lang=css
13109
13448
  // extracted by mini-css-extract-plugin
13110
13449
 
13111
- ;// ./src/GanttElastic.vue?vue&type=style&index=0&id=95091692&prod&lang=css
13450
+ ;// ./src/GanttElastic.vue?vue&type=style&index=0&id=2e042034&prod&lang=css
13112
13451
 
13113
13452
  ;// ./src/GanttElastic.vue
13114
13453
 
@@ -13121,8 +13460,8 @@ const GanttElastic = {
13121
13460
 
13122
13461
  var GanttElastic_component = normalizeComponent(
13123
13462
  src_GanttElasticvue_type_script_lang_js,
13124
- GanttElasticvue_type_template_id_95091692_render,
13125
- GanttElasticvue_type_template_id_95091692_staticRenderFns,
13463
+ GanttElasticvue_type_template_id_2e042034_render,
13464
+ GanttElasticvue_type_template_id_2e042034_staticRenderFns,
13126
13465
  false,
13127
13466
  null,
13128
13467
  null,
@@ -13152,6 +13491,22 @@ var GanttElastic_component = normalizeComponent(
13152
13491
  type: Object,
13153
13492
  default: () => ({})
13154
13493
  },
13494
+ isHeaderVisible: {
13495
+ type: Boolean,
13496
+ default: true
13497
+ },
13498
+ projectName: {
13499
+ type: String,
13500
+ default: ''
13501
+ },
13502
+ headerLeftSideLabels: {
13503
+ type: Array,
13504
+ default: () => []
13505
+ },
13506
+ headerLegendConfig: {
13507
+ type: Object,
13508
+ default: () => ({})
13509
+ },
13155
13510
  header: {
13156
13511
  type: Object,
13157
13512
  default: () => ({})