Patch #44567 » 0003-Highlight-corresponding-Gantt-rows.patch
| app/assets/stylesheets/gantt.css | ||
|---|---|---|
| 182 | 182 |
} |
| 183 | 183 | |
| 184 | 184 |
[data-gantt-column="subjects"] .gantt-row {
|
| 185 |
inset-inline-start: var(--gantt-row-indent); |
|
| 186 |
inline-size: calc(100% - var(--gantt-row-indent)); |
|
| 185 |
inset-inline-start: 0; |
|
| 186 |
inline-size: 100%; |
|
| 187 |
padding-inline-start: var(--gantt-row-indent); |
|
| 187 | 188 |
line-height: 16px; |
| 188 | 189 |
overflow: hidden; |
| 189 | 190 |
white-space: nowrap; |
| ... | ... | |
| 198 | 199 |
white-space: nowrap; |
| 199 | 200 |
} |
| 200 | 201 | |
| 201 |
[data-gantt-column="subjects"] .gantt-row[data-gantt-row-type="issue"]:hover {
|
|
| 202 |
background-color: var(--oc-yellow-0);
|
|
| 202 |
.gantt-row-hover {
|
|
| 203 |
background-color: rgba(var(--oc-yellow-1-rgb), 0.5);
|
|
| 203 | 204 |
} |
| 204 | 205 | |
| 205 | 206 |
.gantt-timeline-body .gantt-row {
|
| app/helpers/gantt_helper.rb | ||
|---|---|---|
| 201 | 201 |
# Events emitted by child controllers the chart listens to. |
| 202 | 202 |
# - `gantt--options` toggles checkboxes under Options. |
| 203 | 203 |
# - `gantt--subjects` reports tree expand/collapse. |
| 204 |
# - Mouse events synchronize the hovered row across the chart panes. |
|
| 204 | 205 |
# - Window resize triggers a redraw of progress lines and relations. |
| 205 | 206 |
action: %w( |
| 206 | 207 |
gantt--options:toggle-display@document->gantt--chart#handleOptionsDisplay |
| 207 | 208 |
gantt--options:toggle-relations@document->gantt--chart#handleOptionsRelations |
| 208 | 209 |
gantt--options:toggle-progress@document->gantt--chart#handleOptionsProgress |
| 209 | 210 |
gantt--subjects:toggle-tree->gantt--chart#handleSubjectTreeChanged |
| 211 |
mouseover->gantt--chart#highlightRow |
|
| 212 |
mouseout->gantt--chart#unhighlightRow |
|
| 210 | 213 |
resize@window->gantt--chart#handleWindowResize |
| 211 | 214 |
).join(' '),
|
| 212 | 215 |
'gantt--chart-issue-relation-types-value': Redmine::Helpers::Gantt::DRAW_TYPES.to_json, |
| app/javascript/controllers/gantt/chart_controller.js | ||
|---|---|---|
| 31 | 31 |
} |
| 32 | 32 | |
| 33 | 33 |
disconnect() {
|
| 34 |
this.clearRowHighlight() |
|
| 35 | ||
| 34 | 36 |
if (this.#drawPaper) {
|
| 35 | 37 |
this.#drawPaper.remove() |
| 36 | 38 |
this.#drawPaper = null |
| ... | ... | |
| 38 | 40 |
} |
| 39 | 41 |
} |
| 40 | 42 | |
| 43 |
highlightRow(event) {
|
|
| 44 |
const row = event.target.closest(".gantt-row")
|
|
| 45 |
if (!row) return |
|
| 46 | ||
| 47 |
this.#setRowHighlight(row, true) |
|
| 48 |
} |
|
| 49 | ||
| 50 |
unhighlightRow(event) {
|
|
| 51 |
const row = event.target.closest(".gantt-row")
|
|
| 52 |
if (!row) return |
|
| 53 | ||
| 54 |
if (!row.contains(event.relatedTarget)) {
|
|
| 55 |
this.#setRowHighlight(row, false) |
|
| 56 |
} |
|
| 57 |
} |
|
| 58 | ||
| 59 |
clearRowHighlight() {
|
|
| 60 |
this.element.querySelectorAll(".gantt-row-hover").forEach((row) => {
|
|
| 61 |
row.classList.remove("gantt-row-hover")
|
|
| 62 |
}) |
|
| 63 |
} |
|
| 64 | ||
| 41 | 65 |
showSelectedColumnsValueChanged() {
|
| 42 | 66 |
this.#drawSelectedColumns() |
| 43 | 67 |
} |
| ... | ... | |
| 72 | 96 |
this.showProgressValue = !!(event.detail && event.detail.enabled) |
| 73 | 97 |
} |
| 74 | 98 | |
| 99 |
#setRowHighlight(row, highlighted) {
|
|
| 100 |
const rowKey = row.dataset.ganttRowKey |
|
| 101 |
if (!rowKey) return |
|
| 102 | ||
| 103 |
const selector = `.gantt-row[data-gantt-row-key="${CSS.escape(rowKey)}"]`
|
|
| 104 |
this.element.querySelectorAll(selector).forEach((element) => {
|
|
| 105 |
element.classList.toggle("gantt-row-hover", highlighted)
|
|
| 106 |
}) |
|
| 107 |
} |
|
| 108 | ||
| 75 | 109 |
#drawProgressLineAndRelations() {
|
| 76 | 110 |
this.#setupDrawArea() |
| 77 | 111 |
this.#setupDrawPaper() |
| test/system/gantts_test.rb | ||
|---|---|---|
| 48 | 48 |
assert_selector timeline_issue, visible: :visible |
| 49 | 49 |
end |
| 50 | 50 | |
| 51 |
test 'row highlight spans subjects selected columns and timeline' do |
|
| 52 |
visit_gantt |
|
| 53 |
expand_options |
|
| 54 |
find('#draw_selected_columns').check
|
|
| 55 | ||
| 56 |
find('.gantt-timeline-body .gantt-row[data-gantt-row-key="issue-1"] .tooltip').hover
|
|
| 57 | ||
| 58 |
assert_selector '[data-gantt-column="subjects"] .gantt-row.gantt-row-hover[data-gantt-row-key="issue-1"]' |
|
| 59 |
assert_selector '[data-gantt-column="status"] .gantt-row.gantt-row-hover[data-gantt-row-key="issue-1"]' |
|
| 60 |
end |
|
| 61 | ||
| 51 | 62 |
test 'related issues toggle displays and hides relation arrows' do |
| 52 | 63 |
visit_gantt |
| 53 | 64 |
expand_options |
| ... | ... | |
| 62 | 73 | |
| 63 | 74 |
assert_selector '.gantt-relations path', minimum: 1 |
| 64 | 75 | |
| 65 | ||
| 66 | 76 |
# Relation arrows should keep the same position when redrawn after horizontal scrolling. |
| 67 | 77 |
paths_before_scroll = all('.gantt-relations path').pluck(:d)
|
| 68 | 78 |
find('#draw_relations').uncheck
|
| ... | ... | |
| 110 | 120 |
issue_link_text = issue1_subject_row.first('a.issue', visible: :all).text
|
| 111 | 121 |
assert_selector '.tip', text: issue_link_text |
| 112 | 122 |
end |
| 113 | ||
| 114 | 123 |
# Context menu for issue subject |
| 115 | 124 |
issue1_subject_row.right_click |
| 116 | 125 | |