From 787ab534b45481ec0a08763df322ba358ac231b9 Mon Sep 17 00:00:00 2001 From: Katsuya HIDAKA Date: Thu, 24 Sep 2026 00:47:28 +0900 Subject: Highlight corresponding Gantt rows --- app/assets/stylesheets/gantt.css | 9 ++--- app/helpers/gantt_helper.rb | 3 ++ .../controllers/gantt/chart_controller.js | 34 +++++++++++++++++++ test/system/gantts_test.rb | 13 +++++-- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/gantt.css b/app/assets/stylesheets/gantt.css index 32e280d66..345be731b 100644 --- a/app/assets/stylesheets/gantt.css +++ b/app/assets/stylesheets/gantt.css @@ -182,8 +182,9 @@ } [data-gantt-column="subjects"] .gantt-row { - inset-inline-start: var(--gantt-row-indent); - inline-size: calc(100% - var(--gantt-row-indent)); + inset-inline-start: 0; + inline-size: 100%; + padding-inline-start: var(--gantt-row-indent); line-height: 16px; overflow: hidden; white-space: nowrap; @@ -198,8 +199,8 @@ white-space: nowrap; } -[data-gantt-column="subjects"] .gantt-row[data-gantt-row-type="issue"]:hover { - background-color: var(--oc-yellow-0); +.gantt-row-hover { + background-color: rgba(var(--oc-yellow-1-rgb), 0.5); } .gantt-timeline-body .gantt-row { diff --git a/app/helpers/gantt_helper.rb b/app/helpers/gantt_helper.rb index f482cd316..17a9d5172 100644 --- a/app/helpers/gantt_helper.rb +++ b/app/helpers/gantt_helper.rb @@ -201,12 +201,15 @@ module GanttHelper # Events emitted by child controllers the chart listens to. # - `gantt--options` toggles checkboxes under Options. # - `gantt--subjects` reports tree expand/collapse. + # - Mouse events synchronize the hovered row across the chart panes. # - Window resize triggers a redraw of progress lines and relations. action: %w( gantt--options:toggle-display@document->gantt--chart#handleOptionsDisplay gantt--options:toggle-relations@document->gantt--chart#handleOptionsRelations gantt--options:toggle-progress@document->gantt--chart#handleOptionsProgress gantt--subjects:toggle-tree->gantt--chart#handleSubjectTreeChanged + mouseover->gantt--chart#highlightRow + mouseout->gantt--chart#unhighlightRow resize@window->gantt--chart#handleWindowResize ).join(' '), 'gantt--chart-issue-relation-types-value': Redmine::Helpers::Gantt::DRAW_TYPES.to_json, diff --git a/app/javascript/controllers/gantt/chart_controller.js b/app/javascript/controllers/gantt/chart_controller.js index 1e57c41b7..5ce8fb4d8 100644 --- a/app/javascript/controllers/gantt/chart_controller.js +++ b/app/javascript/controllers/gantt/chart_controller.js @@ -31,6 +31,8 @@ export default class extends Controller { } disconnect() { + this.clearRowHighlight() + if (this.#drawPaper) { this.#drawPaper.remove() this.#drawPaper = null @@ -38,6 +40,28 @@ export default class extends Controller { } } + highlightRow(event) { + const row = event.target.closest(".gantt-row") + if (!row) return + + this.#setRowHighlight(row, true) + } + + unhighlightRow(event) { + const row = event.target.closest(".gantt-row") + if (!row) return + + if (!row.contains(event.relatedTarget)) { + this.#setRowHighlight(row, false) + } + } + + clearRowHighlight() { + this.element.querySelectorAll(".gantt-row-hover").forEach((row) => { + row.classList.remove("gantt-row-hover") + }) + } + showSelectedColumnsValueChanged() { this.#drawSelectedColumns() } @@ -72,6 +96,16 @@ export default class extends Controller { this.showProgressValue = !!(event.detail && event.detail.enabled) } + #setRowHighlight(row, highlighted) { + const rowKey = row.dataset.ganttRowKey + if (!rowKey) return + + const selector = `.gantt-row[data-gantt-row-key="${CSS.escape(rowKey)}"]` + this.element.querySelectorAll(selector).forEach((element) => { + element.classList.toggle("gantt-row-hover", highlighted) + }) + } + #drawProgressLineAndRelations() { this.#setupDrawArea() this.#setupDrawPaper() diff --git a/test/system/gantts_test.rb b/test/system/gantts_test.rb index 1361d0489..2bdc5e37c 100644 --- a/test/system/gantts_test.rb +++ b/test/system/gantts_test.rb @@ -48,6 +48,17 @@ class GanttsTest < ApplicationSystemTestCase assert_selector timeline_issue, visible: :visible end + test 'row highlight spans subjects selected columns and timeline' do + visit_gantt + expand_options + find('#draw_selected_columns').check + + find('.gantt-timeline-body .gantt-row[data-gantt-row-key="issue-1"] .tooltip').hover + + assert_selector '[data-gantt-column="subjects"] .gantt-row.gantt-row-hover[data-gantt-row-key="issue-1"]' + assert_selector '[data-gantt-column="status"] .gantt-row.gantt-row-hover[data-gantt-row-key="issue-1"]' + end + test 'related issues toggle displays and hides relation arrows' do visit_gantt expand_options @@ -62,7 +73,6 @@ class GanttsTest < ApplicationSystemTestCase assert_selector '.gantt-relations path', minimum: 1 - # Relation arrows should keep the same position when redrawn after horizontal scrolling. paths_before_scroll = all('.gantt-relations path').pluck(:d) find('#draw_relations').uncheck @@ -110,7 +120,6 @@ class GanttsTest < ApplicationSystemTestCase issue_link_text = issue1_subject_row.first('a.issue', visible: :all).text assert_selector '.tip', text: issue_link_text end - # Context menu for issue subject issue1_subject_row.right_click -- 2.51.0