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.
@@ -3385,7 +3385,7 @@ if (typeof window !== 'undefined') {
3385
3385
  // Indicate to webpack that this file can be concatenated
3386
3386
  /* harmony default export */ var setPublicPath = (null);
3387
3387
 
3388
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3388
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3389
3389
  var render = function render() {
3390
3390
  var _vm = this,
3391
3391
  _c = _vm._self._c;
@@ -3393,7 +3393,11 @@ var render = function render() {
3393
3393
  attrs: {
3394
3394
  "tasks": _vm.tasks,
3395
3395
  "options": _vm.options,
3396
- "dynamicStyle": _vm.dynamicStyle
3396
+ "dynamicStyle": _vm.dynamicStyle,
3397
+ "isHeaderVisible": _vm.isHeaderVisible,
3398
+ "projectName": _vm.projectName,
3399
+ "headerLeftSideLabels": _vm.headerLeftSideLabels,
3400
+ "headerLegendConfig": _vm.headerLegendConfig
3397
3401
  },
3398
3402
  on: {
3399
3403
  "task-updated": function ($event) {
@@ -3417,8 +3421,35 @@ var render = function render() {
3417
3421
  "dynamic-style-changed": function ($event) {
3418
3422
  return _vm.$emit('dynamic-style-changed', $event);
3419
3423
  },
3424
+ "action-button-clicked": function ($event) {
3425
+ return _vm.$emit('action-button-clicked', $event);
3426
+ },
3427
+ "calendar-recalculate": function ($event) {
3428
+ return _vm.$emit('calendar-recalculate', $event);
3429
+ },
3430
+ "created": function ($event) {
3431
+ return _vm.$emit('created', $event);
3432
+ },
3433
+ "before-mount": function ($event) {
3434
+ return _vm.$emit('before-mount', $event);
3435
+ },
3436
+ "ready": function ($event) {
3437
+ return _vm.$emit('ready', $event);
3438
+ },
3420
3439
  "mounted": function ($event) {
3421
3440
  return _vm.$emit('mounted', $event);
3441
+ },
3442
+ "before-update": function ($event) {
3443
+ return _vm.$emit('before-update', $event);
3444
+ },
3445
+ "updated": function ($event) {
3446
+ return _vm.$emit('updated', $event);
3447
+ },
3448
+ "before-destroy": function ($event) {
3449
+ return _vm.$emit('before-destroy', $event);
3450
+ },
3451
+ "destroyed": function ($event) {
3452
+ return _vm.$emit('destroyed', $event);
3422
3453
  }
3423
3454
  }
3424
3455
  }, [_vm.components.header ? _c(_vm.components.header, {
@@ -3437,8 +3468,8 @@ var render = function render() {
3437
3468
  };
3438
3469
  var staticRenderFns = [];
3439
3470
 
3440
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3441
- var GanttElasticvue_type_template_id_95091692_render = function render() {
3471
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3472
+ var GanttElasticvue_type_template_id_2e042034_render = function render() {
3442
3473
  var _vm = this,
3443
3474
  _c = _vm._self._c,
3444
3475
  _setup = _vm._self._setupProxy;
@@ -3454,7 +3485,9 @@ var GanttElasticvue_type_template_id_95091692_render = function render() {
3454
3485
  slot: "header"
3455
3486
  }) : _vm._e(), _c('gantt-view-filter', {
3456
3487
  attrs: {
3457
- "slot": "header"
3488
+ "slot": "header",
3489
+ "left-side-labels": _vm.headerLeftSideLabels,
3490
+ "legend-config": _vm.headerLegendConfig
3458
3491
  },
3459
3492
  on: {
3460
3493
  "view-mode-changed": _vm.onViewModeChanged
@@ -3467,7 +3500,7 @@ var GanttElasticvue_type_template_id_95091692_render = function render() {
3467
3500
  }
3468
3501
  }), _vm._t("footer")], 2);
3469
3502
  };
3470
- var GanttElasticvue_type_template_id_95091692_staticRenderFns = [];
3503
+ var GanttElasticvue_type_template_id_2e042034_staticRenderFns = [];
3471
3504
 
3472
3505
  // EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.push.js
3473
3506
  var es_array_push = __webpack_require__(4114);
@@ -3498,14 +3531,37 @@ var esnext_iterator_reduce = __webpack_require__(8872);
3498
3531
  // EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js
3499
3532
  var dayjs_min = __webpack_require__(4353);
3500
3533
  var dayjs_min_default = /*#__PURE__*/__webpack_require__.n(dayjs_min);
3501
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3502
- var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function render() {
3534
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3535
+ var GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_render = function render() {
3503
3536
  var _vm = this,
3504
3537
  _c = _vm._self._c;
3505
3538
  return _c('div', {
3506
3539
  staticClass: "gantt-view-filter"
3507
3540
  }, [_c('div', {
3508
3541
  staticClass: "view-toggle-group"
3542
+ }, [_c('div', {
3543
+ staticClass: "left-side-labels"
3544
+ }, _vm._l(_vm.leftSideLabels, function (label, index) {
3545
+ return _c('span', {
3546
+ key: index,
3547
+ staticClass: "left-label-item"
3548
+ }, [_vm._v(" " + _vm._s(label) + " ")]);
3549
+ }), 0), _c('div', {
3550
+ staticClass: "legend-section"
3551
+ }, _vm._l(_vm.legendItems, function (legendItem) {
3552
+ return _c('span', {
3553
+ key: legendItem.type,
3554
+ staticClass: "legend-item-wrapper"
3555
+ }, [_c('span', {
3556
+ staticClass: "colorboxsquare",
3557
+ style: {
3558
+ backgroundColor: legendItem.color
3559
+ }
3560
+ }), _c('span', {
3561
+ staticClass: "legend-label"
3562
+ }, [_vm._v(_vm._s(legendItem.label))])]);
3563
+ }), 0), _c('div', {
3564
+ staticClass: "view-toggle-buttons"
3509
3565
  }, [_c('button', {
3510
3566
  staticClass: "view-toggle-btn",
3511
3567
  class: {
@@ -3518,7 +3574,7 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3518
3574
  }
3519
3575
  }, [_c('span', {
3520
3576
  staticClass: "view-icon"
3521
- }, [_vm._v("📅")]), _c('span', {
3577
+ }), _c('span', {
3522
3578
  staticClass: "view-label"
3523
3579
  }, [_vm._v("Day")])]), _c('button', {
3524
3580
  staticClass: "view-toggle-btn",
@@ -3532,7 +3588,7 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3532
3588
  }
3533
3589
  }, [_c('span', {
3534
3590
  staticClass: "view-icon"
3535
- }, [_vm._v("📊")]), _c('span', {
3591
+ }), _c('span', {
3536
3592
  staticClass: "view-label"
3537
3593
  }, [_vm._v("Week")])]), _c('button', {
3538
3594
  staticClass: "view-toggle-btn",
@@ -3546,7 +3602,7 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3546
3602
  }
3547
3603
  }, [_c('span', {
3548
3604
  staticClass: "view-icon"
3549
- }, [_vm._v("🗓️")]), _c('span', {
3605
+ }), _c('span', {
3550
3606
  staticClass: "view-label"
3551
3607
  }, [_vm._v("Month")])]), _c('button', {
3552
3608
  staticClass: "view-toggle-btn",
@@ -3560,36 +3616,139 @@ var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render = function r
3560
3616
  }
3561
3617
  }, [_c('span', {
3562
3618
  staticClass: "view-icon"
3563
- }, [_vm._v("📈")]), _c('span', {
3619
+ }), _c('span', {
3564
3620
  staticClass: "view-label"
3565
- }, [_vm._v("Quarter")])])])]);
3621
+ }, [_vm._v("Quarter")])])])])]);
3566
3622
  };
3567
- var GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_staticRenderFns = [];
3623
+ var GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_staticRenderFns = [];
3568
3624
 
3569
3625
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/Header/GanttViewFilter.vue?vue&type=script&lang=js
3626
+
3627
+
3628
+
3629
+
3630
+
3631
+
3632
+
3633
+
3634
+
3635
+
3570
3636
  /* harmony default export */ var GanttViewFiltervue_type_script_lang_js = ({
3571
3637
  name: 'GanttViewFilter',
3638
+ inject: ['root'],
3639
+ props: {
3640
+ leftSideLabels: {
3641
+ type: Array,
3642
+ default: () => ['Timeline', 'Epic', 'Task Story']
3643
+ },
3644
+ legendConfig: {
3645
+ type: Array,
3646
+ default: () => null // If null, will be computed from tasks
3647
+ }
3648
+ },
3572
3649
  data() {
3573
3650
  return {
3574
3651
  viewMode: 'day' // default view mode
3575
3652
  };
3576
3653
  },
3654
+ computed: {
3655
+ /**
3656
+ * Get unique task types from tasks
3657
+ */
3658
+ uniqueTaskTypes() {
3659
+ if (!this.root || !this.root.state || !this.root.state.tasks) {
3660
+ return [];
3661
+ }
3662
+ const taskTypes = new Set();
3663
+ this.root.state.tasks.forEach(task => {
3664
+ if (task.type) {
3665
+ taskTypes.add(task.type);
3666
+ }
3667
+ });
3668
+ return Array.from(taskTypes);
3669
+ },
3670
+ /**
3671
+ * Color map for task types - matches chart colors
3672
+ */
3673
+ taskTypeColors() {
3674
+ return {
3675
+ 'milestone': '#CD5C5C',
3676
+ 'task': '#3B82F6',
3677
+ 'project': '#8B5CF6',
3678
+ 'sprint': '#F59E0B',
3679
+ 'flag': '#10B981',
3680
+ 'check': '#3B82F6',
3681
+ 'epic': '#8B5CF6',
3682
+ 'story': '#86EFAC',
3683
+ 'subtask': '#3B82F6'
3684
+ };
3685
+ },
3686
+ /**
3687
+ * Task type labels (capitalized, human-readable)
3688
+ */
3689
+ taskTypeLabels() {
3690
+ return {
3691
+ 'milestone': 'Milestone',
3692
+ 'task': 'Task',
3693
+ 'project': 'Project',
3694
+ 'sprint': 'Sprint',
3695
+ 'flag': 'Flag',
3696
+ 'check': 'Check',
3697
+ 'epic': 'Epic',
3698
+ 'story': 'Story',
3699
+ 'subtask': 'Subtask'
3700
+ };
3701
+ },
3702
+ /**
3703
+ * Generate legend items dynamically from tasks or use provided config
3704
+ */
3705
+ legendItems() {
3706
+ // If custom config provided, use it
3707
+ if (this.legendConfig && Array.isArray(this.legendConfig)) {
3708
+ return this.legendConfig;
3709
+ }
3710
+
3711
+ // Otherwise, generate from unique task types
3712
+ const items = [];
3713
+ this.uniqueTaskTypes.forEach(type => {
3714
+ items.push({
3715
+ type: type,
3716
+ label: this.taskTypeLabels[type] || this.capitalizeFirst(type),
3717
+ color: this.taskTypeColors[type] || '#6B7280'
3718
+ });
3719
+ });
3720
+
3721
+ // Sort items in a consistent order (epic, story, task, milestone, etc.)
3722
+ const order = ['epic', 'story', 'task', 'subtask', 'milestone', 'project', 'sprint'];
3723
+ items.sort((a, b) => {
3724
+ const indexA = order.indexOf(a.type);
3725
+ const indexB = order.indexOf(b.type);
3726
+ if (indexA === -1 && indexB === -1) return 0;
3727
+ if (indexA === -1) return 1;
3728
+ if (indexB === -1) return -1;
3729
+ return indexA - indexB;
3730
+ });
3731
+ return items;
3732
+ }
3733
+ },
3577
3734
  methods: {
3578
3735
  changeViewMode(mode) {
3579
- // eslint-disable-next-line no-debugger
3580
- debugger;
3581
3736
  this.viewMode = mode;
3582
3737
  // Emit an event to the parent component (App.vue) so it can update the Gantt chart
3583
3738
  this.$emit('view-mode-changed', mode);
3739
+ },
3740
+ capitalizeFirst(str) {
3741
+ if (!str) return '';
3742
+ return str.charAt(0).toUpperCase() + str.slice(1);
3584
3743
  }
3585
3744
  }
3586
3745
  });
3587
3746
  ;// ./src/components/Header/GanttViewFilter.vue?vue&type=script&lang=js
3588
3747
  /* harmony default export */ var Header_GanttViewFiltervue_type_script_lang_js = (GanttViewFiltervue_type_script_lang_js);
3589
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-55.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-55.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-55.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
3748
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-55.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-55.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-55.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
3590
3749
  // extracted by mini-css-extract-plugin
3591
3750
 
3592
- ;// ./src/components/Header/GanttViewFilter.vue?vue&type=style&index=0&id=f4bb58fc&prod&scoped=true&lang=css
3751
+ ;// ./src/components/Header/GanttViewFilter.vue?vue&type=style&index=0&id=eb2e1196&prod&scoped=true&lang=css
3593
3752
 
3594
3753
  ;// ./node_modules/@vue/vue-loader-v15/lib/runtime/componentNormalizer.js
3595
3754
  /* globals __VUE_SSR_CONTEXT__ */
@@ -3700,11 +3859,11 @@ function normalizeComponent(
3700
3859
 
3701
3860
  var component = normalizeComponent(
3702
3861
  Header_GanttViewFiltervue_type_script_lang_js,
3703
- GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_render,
3704
- GanttViewFiltervue_type_template_id_f4bb58fc_scoped_true_staticRenderFns,
3862
+ GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_render,
3863
+ GanttViewFiltervue_type_template_id_eb2e1196_scoped_true_staticRenderFns,
3705
3864
  false,
3706
3865
  null,
3707
- "f4bb58fc",
3866
+ "eb2e1196",
3708
3867
  null
3709
3868
 
3710
3869
  )
@@ -3883,8 +4042,8 @@ var TaskListvue_type_template_id_b705a4ea_render = function render() {
3883
4042
  };
3884
4043
  var TaskListvue_type_template_id_b705a4ea_staticRenderFns = [];
3885
4044
 
3886
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3887
- var TaskListHeadervue_type_template_id_2ecc0032_render = function render() {
4045
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
4046
+ var TaskListHeadervue_type_template_id_92de7fea_render = function render() {
3888
4047
  var _vm = this,
3889
4048
  _c = _vm._self._c;
3890
4049
  return _c('div', {
@@ -3904,7 +4063,8 @@ var TaskListHeadervue_type_template_id_2ecc0032_render = function render() {
3904
4063
  staticClass: "gantt-elastic__task-list-header-label",
3905
4064
  style: _vm.headerLabelStyle(column),
3906
4065
  attrs: {
3907
- "column": column
4066
+ "column": column,
4067
+ "title": _vm.getTooltipText(column)
3908
4068
  },
3909
4069
  on: {
3910
4070
  "mouseup": _vm.resizerMouseUp
@@ -3932,7 +4092,7 @@ var TaskListHeadervue_type_template_id_2ecc0032_render = function render() {
3932
4092
  }), 0)])], 1);
3933
4093
  }), 0);
3934
4094
  };
3935
- var TaskListHeadervue_type_template_id_2ecc0032_staticRenderFns = [];
4095
+ var TaskListHeadervue_type_template_id_92de7fea_staticRenderFns = [];
3936
4096
 
3937
4097
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
3938
4098
  var Expandervue_type_template_id_4831d194_render = function render() {
@@ -4120,6 +4280,17 @@ var Expander_component = normalizeComponent(
4120
4280
  }
4121
4281
  },
4122
4282
  methods: {
4283
+ getTooltipText(column) {
4284
+ // Return descriptive tooltips for each column
4285
+ const tooltips = {
4286
+ 'ID': 'Task identifier number',
4287
+ 'Description': 'Task name and description',
4288
+ 'Assigned to': 'Person or role responsible for this task',
4289
+ 'Start': 'Task start date and time',
4290
+ 'Progress': 'Task completion percentage (0-100%)'
4291
+ };
4292
+ return tooltips[column.label] || column.label;
4293
+ },
4123
4294
  columnStyle(column) {
4124
4295
  return {
4125
4296
  ...this.root.style['task-list-header-column'],
@@ -4201,8 +4372,8 @@ var Expander_component = normalizeComponent(
4201
4372
  ;
4202
4373
  var TaskListHeader_component = normalizeComponent(
4203
4374
  TaskList_TaskListHeadervue_type_script_lang_js,
4204
- TaskListHeadervue_type_template_id_2ecc0032_render,
4205
- TaskListHeadervue_type_template_id_2ecc0032_staticRenderFns,
4375
+ TaskListHeadervue_type_template_id_92de7fea_render,
4376
+ TaskListHeadervue_type_template_id_92de7fea_staticRenderFns,
4206
4377
  false,
4207
4378
  null,
4208
4379
  null,
@@ -4238,8 +4409,8 @@ var TaskListItemvue_type_template_id_b99d1d94_render = function render() {
4238
4409
  };
4239
4410
  var TaskListItemvue_type_template_id_b99d1d94_staticRenderFns = [];
4240
4411
 
4241
- ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
4242
- var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4412
+ ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.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
4413
+ var ItemColumnvue_type_template_id_6a863d80_render = function render() {
4243
4414
  var _vm = this,
4244
4415
  _c = _vm._self._c;
4245
4416
  return _c('div', {
@@ -4254,6 +4425,9 @@ var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4254
4425
  }, [!_vm.html ? _c('div', {
4255
4426
  staticClass: "gantt-elastic__task-list-item-value",
4256
4427
  style: _vm.valueStyle,
4428
+ attrs: {
4429
+ "title": _vm.tooltipText
4430
+ },
4257
4431
  on: {
4258
4432
  "click": function ($event) {
4259
4433
  return _vm.emitEvent('click', $event);
@@ -4311,6 +4485,9 @@ var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4311
4485
  }, [_vm._v(_vm._s(_vm.value))])]) : _c('div', {
4312
4486
  staticClass: "gantt-elastic__task-list-item-value",
4313
4487
  style: _vm.valueStyle,
4488
+ attrs: {
4489
+ "title": _vm.tooltipText
4490
+ },
4314
4491
  on: {
4315
4492
  "click": function ($event) {
4316
4493
  return _vm.emitEvent('click', $event);
@@ -4370,9 +4547,10 @@ var ItemColumnvue_type_template_id_f410efbc_render = function render() {
4370
4547
  }
4371
4548
  })])])], 2)]);
4372
4549
  };
4373
- var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4550
+ var ItemColumnvue_type_template_id_6a863d80_staticRenderFns = [];
4374
4551
 
4375
4552
  ;// ./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib/index.js??clonedRuleSet-83.use[1]!./node_modules/@vue/vue-loader-v15/lib/index.js??vue-loader-options!./src/components/TaskList/ItemColumn.vue?vue&type=script&lang=js
4553
+
4376
4554
  /* harmony default export */ var ItemColumnvue_type_script_lang_js = ({
4377
4555
  name: 'ItemColumn',
4378
4556
  inject: ['root'],
@@ -4388,6 +4566,29 @@ var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4388
4566
  * @param {Event} event
4389
4567
  */
4390
4568
  emitEvent(eventName, event) {
4569
+ // Handle action button clicks from dynamically generated HTML buttons
4570
+ if (eventName === 'click' && event && event.target) {
4571
+ const button = event.target.closest('.action-btn');
4572
+ if (button) {
4573
+ event.preventDefault();
4574
+ event.stopPropagation();
4575
+ const action = button.getAttribute('data-action');
4576
+ const buttonId = button.getAttribute('data-button-id');
4577
+ const taskId = button.getAttribute('data-task-id');
4578
+
4579
+ // Emit action button click event
4580
+ this.root.$emit('action-button-clicked', {
4581
+ action: action,
4582
+ buttonId: buttonId,
4583
+ taskId: taskId ? isNaN(taskId) ? taskId : parseFloat(taskId) : this.task.id,
4584
+ task: this.task,
4585
+ column: this.column
4586
+ });
4587
+ return;
4588
+ }
4589
+ }
4590
+
4591
+ // Normal column event handling
4391
4592
  if (typeof this.column.events !== 'undefined' && typeof this.column.events[eventName] === 'function') {
4392
4593
  this.column.events[eventName]({
4393
4594
  event,
@@ -4420,10 +4621,109 @@ var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4420
4621
  * @returns {any|string}
4421
4622
  */
4422
4623
  value() {
4624
+ // Handle function-based column values
4423
4625
  if (typeof this.column.value === 'function') {
4424
- return this.column.value(this.task);
4626
+ try {
4627
+ const result = this.column.value(this.task);
4628
+ // For Start column: Always use fallback if result is empty/null/undefined
4629
+ // This ensures Start column always displays even if the function fails due to closure issues
4630
+ if (this.column.label === 'Start') {
4631
+ if (result === null || result === undefined || result === '') {
4632
+ return this.formatStartDate();
4633
+ }
4634
+ // If result is valid, return it
4635
+ return result;
4636
+ }
4637
+ // For other columns: return result as is
4638
+ if (result !== null && result !== undefined && result !== '') {
4639
+ return result;
4640
+ }
4641
+ return result || '';
4642
+ } catch (error) {
4643
+ console.error('Error executing column value function:', error, this.column, this.task);
4644
+ // For Start column: Always use fallback on error
4645
+ if (this.column.label === 'Start' && this.task) {
4646
+ return this.formatStartDate();
4647
+ }
4648
+ return '';
4649
+ }
4650
+ }
4651
+ // If column value is a string and it's "start", format it
4652
+ if (this.column.value === 'start' && this.column.label === 'Start') {
4653
+ return this.formatStartDate();
4654
+ }
4655
+ // Handle string-based column values
4656
+ if (typeof this.column.value === 'string') {
4657
+ const taskValue = this.task[this.column.value];
4658
+ return taskValue !== null && taskValue !== undefined ? taskValue : '';
4659
+ }
4660
+ return '';
4661
+ },
4662
+ /**
4663
+ * Format start date for Start column
4664
+ */
4665
+ formatStartDate() {
4666
+ if (!this.task) return '';
4667
+ try {
4668
+ // Try to get start value from different possible properties
4669
+ const startValue = this.task.startTime || this.task.start;
4670
+ if (!startValue) return '';
4671
+
4672
+ // Ensure dayjs is imported and available
4673
+ if (typeof (dayjs_min_default()) === 'undefined') {
4674
+ console.warn('dayjs is not available in ItemColumn, returning raw value');
4675
+ return String(startValue);
4676
+ }
4677
+
4678
+ // Parse with dayjs
4679
+ const date = dayjs_min_default()(startValue);
4680
+
4681
+ // Return formatted date if valid
4682
+ if (date && date.isValid()) {
4683
+ return date.format("YYYY-MM-DD HH:mm A");
4684
+ }
4685
+
4686
+ // Fallback: return as string if date is invalid
4687
+ return String(startValue);
4688
+ } catch (error) {
4689
+ console.error('Error formatting start date in ItemColumn:', error, this.task);
4690
+ // Last resort: return the raw value as string
4691
+ const startValue = this.task.startTime || this.task.start;
4692
+ return startValue ? String(startValue) : '';
4425
4693
  }
4426
- return this.task[this.column.value];
4694
+ },
4695
+ /**
4696
+ * Get tooltip text for the column value
4697
+ *
4698
+ * @returns {string}
4699
+ */
4700
+ tooltipText() {
4701
+ let tooltipValue = this.value;
4702
+
4703
+ // If value is HTML, strip HTML tags for tooltip
4704
+ if (this.html && typeof tooltipValue === 'string') {
4705
+ // Strip HTML tags using regex (simple approach)
4706
+ tooltipValue = tooltipValue.replace(/<[^>]*>/g, '').trim();
4707
+ }
4708
+
4709
+ // Convert to string if not already
4710
+ const stringValue = String(tooltipValue || '').trim();
4711
+
4712
+ // Format tooltip based on column type
4713
+ if (this.column.label === 'Progress') {
4714
+ return stringValue ? `${stringValue}% complete` : 'Progress not set';
4715
+ } else if (this.column.label === 'Start') {
4716
+ return stringValue ? `Start: ${stringValue}` : 'Start date not set';
4717
+ } else if (this.column.label === 'ID') {
4718
+ return stringValue ? `Task ID: ${stringValue}` : 'No ID';
4719
+ } else if (this.column.label === 'Assigned to') {
4720
+ return stringValue ? `Assigned to: ${stringValue}` : 'Not assigned';
4721
+ } else if (this.column.label === 'Description') {
4722
+ return stringValue || 'No description';
4723
+ }
4724
+
4725
+ // Default: return the value as string
4726
+ return stringValue || '';
4427
4727
  },
4428
4728
  itemColumnStyle() {
4429
4729
  return {
@@ -4554,8 +4854,8 @@ var ItemColumnvue_type_template_id_f410efbc_staticRenderFns = [];
4554
4854
  ;
4555
4855
  var ItemColumn_component = normalizeComponent(
4556
4856
  TaskList_ItemColumnvue_type_script_lang_js,
4557
- ItemColumnvue_type_template_id_f410efbc_render,
4558
- ItemColumnvue_type_template_id_f410efbc_staticRenderFns,
4857
+ ItemColumnvue_type_template_id_6a863d80_render,
4858
+ ItemColumnvue_type_template_id_6a863d80_staticRenderFns,
4559
4859
  false,
4560
4860
  null,
4561
4861
  null,
@@ -7156,7 +7456,7 @@ var ProgressBar_component = normalizeComponent(
7156
7456
  document.removeEventListener('click', this.hideContextMenu);
7157
7457
 
7158
7458
  // Clean up context menu
7159
- this.hideContextMenu();
7459
+ //this.hideContextMenu();
7160
7460
 
7161
7461
  // Clean up date tooltip
7162
7462
  this.removeDateTooltip();
@@ -11340,6 +11640,11 @@ function mergeDeep(target, ...sources) {
11340
11640
  const source = sources.shift();
11341
11641
  if (isObject(target) && isObject(source)) {
11342
11642
  for (const key in source) {
11643
+ // Preserve functions - don't deep merge them
11644
+ if (typeof source[key] === 'function') {
11645
+ target[key] = source[key];
11646
+ continue;
11647
+ }
11343
11648
  if (isObject(source[key])) {
11344
11649
  if (typeof target[key] === 'undefined') {
11345
11650
  target[key] = {};
@@ -11349,7 +11654,15 @@ function mergeDeep(target, ...sources) {
11349
11654
  target[key] = [];
11350
11655
  for (let item of source[key]) {
11351
11656
  if (isObject(item)) {
11352
- target[key].push(mergeDeep({}, item));
11657
+ // Preserve functions in array items (like column.value functions)
11658
+ const mergedItem = mergeDeep({}, item);
11659
+ // Ensure functions are preserved
11660
+ for (const itemKey in item) {
11661
+ if (typeof item[itemKey] === 'function') {
11662
+ mergedItem[itemKey] = item[itemKey];
11663
+ }
11664
+ }
11665
+ target[key].push(mergedItem);
11353
11666
  continue;
11354
11667
  }
11355
11668
  target[key].push(item);
@@ -11497,7 +11810,7 @@ const GanttElastic = {
11497
11810
  'gantt-header': Header,
11498
11811
  'gantt-view-filter': GanttViewFilter
11499
11812
  },
11500
- props: ['tasks', 'options', 'dynamicStyle', 'isHeaderVisible', 'projectName'],
11813
+ props: ['tasks', 'options', 'dynamicStyle', 'isHeaderVisible', 'projectName', 'headerLeftSideLabels', 'headerLegendConfig'],
11501
11814
  provide() {
11502
11815
  const provider = {};
11503
11816
  const self = this;
@@ -11816,17 +12129,39 @@ const GanttElastic = {
11816
12129
  options.taskList = {};
11817
12130
  }
11818
12131
  options.taskList.columns = options.taskList.columns.map((column, index) => {
11819
- column.thresholdPercent = 100;
11820
- column.widthFromPercentage = 0;
11821
- column.finalWidth = 0;
11822
- if (typeof column.height === 'undefined') {
11823
- column.height = 0;
12132
+ // Create a new column object to avoid mutating the original
12133
+ const newColumn = {
12134
+ ...column,
12135
+ thresholdPercent: 100,
12136
+ widthFromPercentage: 0,
12137
+ finalWidth: 0,
12138
+ height: typeof column.height !== 'undefined' ? column.height : 0,
12139
+ style: typeof column.style !== 'undefined' ? column.style : {},
12140
+ _id: `${index}-${column.label}`
12141
+ };
12142
+
12143
+ // Preserve the value function reference if it exists
12144
+ // This is critical to prevent closure issues when columns are cloned
12145
+ if (typeof column.value === 'function') {
12146
+ // If column has buttons array, bind the function to access this.buttons
12147
+ if (column.buttons && Array.isArray(column.buttons)) {
12148
+ newColumn.buttons = column.buttons;
12149
+ newColumn.value = column.value.bind(newColumn);
12150
+ } else {
12151
+ newColumn.value = column.value;
12152
+ }
11824
12153
  }
11825
- if (typeof column.style === 'undefined') {
11826
- column.style = {};
12154
+
12155
+ // Preserve buttons array if it exists (for action columns)
12156
+ if (column.buttons && Array.isArray(column.buttons)) {
12157
+ newColumn.buttons = column.buttons;
12158
+ }
12159
+
12160
+ // Preserve events if they exist
12161
+ if (column.events) {
12162
+ newColumn.events = column.events;
11827
12163
  }
11828
- column._id = `${index}-${column.label}`;
11829
- return column;
12164
+ return newColumn;
11830
12165
  });
11831
12166
  this.state.options = options;
11832
12167
  tasks = this.fillTasks(tasks);
@@ -12294,6 +12629,10 @@ const GanttElastic = {
12294
12629
  this.$on('scope-change', this.onScopeChange);
12295
12630
  this.$on('taskList-width-change', this.onTaskListWidthChange);
12296
12631
  this.$on('taskList-column-width-change', this.onTaskListColumnWidthChange);
12632
+ // Forward action button click events to parent
12633
+ this.$on('action-button-clicked', payload => {
12634
+ this.$emit('action-button-clicked', payload);
12635
+ });
12297
12636
  },
12298
12637
  /**
12299
12638
  * Get responsive step widths based on screen size
@@ -13115,10 +13454,10 @@ const GanttElastic = {
13115
13454
  /* harmony default export */ var GanttElasticvue_type_script_lang_js = (GanttElastic);
13116
13455
  ;// ./src/GanttElastic.vue?vue&type=script&lang=js
13117
13456
  /* harmony default export */ var src_GanttElasticvue_type_script_lang_js = (GanttElasticvue_type_script_lang_js);
13118
- ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-55.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-55.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-55.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
13457
+ ;// ./node_modules/mini-css-extract-plugin/dist/loader.js??clonedRuleSet-55.use[0]!./node_modules/@vue/cli-service/node_modules/css-loader/dist/cjs.js??clonedRuleSet-55.use[1]!./node_modules/@vue/vue-loader-v15/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-55.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
13119
13458
  // extracted by mini-css-extract-plugin
13120
13459
 
13121
- ;// ./src/GanttElastic.vue?vue&type=style&index=0&id=95091692&prod&lang=css
13460
+ ;// ./src/GanttElastic.vue?vue&type=style&index=0&id=2e042034&prod&lang=css
13122
13461
 
13123
13462
  ;// ./src/GanttElastic.vue
13124
13463
 
@@ -13131,8 +13470,8 @@ const GanttElastic = {
13131
13470
 
13132
13471
  var GanttElastic_component = normalizeComponent(
13133
13472
  src_GanttElasticvue_type_script_lang_js,
13134
- GanttElasticvue_type_template_id_95091692_render,
13135
- GanttElasticvue_type_template_id_95091692_staticRenderFns,
13473
+ GanttElasticvue_type_template_id_2e042034_render,
13474
+ GanttElasticvue_type_template_id_2e042034_staticRenderFns,
13136
13475
  false,
13137
13476
  null,
13138
13477
  null,
@@ -13162,6 +13501,22 @@ var GanttElastic_component = normalizeComponent(
13162
13501
  type: Object,
13163
13502
  default: () => ({})
13164
13503
  },
13504
+ isHeaderVisible: {
13505
+ type: Boolean,
13506
+ default: true
13507
+ },
13508
+ projectName: {
13509
+ type: String,
13510
+ default: ''
13511
+ },
13512
+ headerLeftSideLabels: {
13513
+ type: Array,
13514
+ default: () => []
13515
+ },
13516
+ headerLegendConfig: {
13517
+ type: Object,
13518
+ default: () => ({})
13519
+ },
13165
13520
  header: {
13166
13521
  type: Object,
13167
13522
  default: () => ({})