From 8861af45d573781699afbe2f3f586b8e2ea48661 Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Fri, 23 Jan 2026 19:00:19 +0900 Subject: [PATCH 3/4] Update Gantt collapse/expand handler to use CSS logical properties --- .../controllers/gantt/subjects_controller.js | 45 ++++++++++++++----- lib/redmine/helpers/gantt.rb | 2 +- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/app/javascript/controllers/gantt/subjects_controller.js b/app/javascript/controllers/gantt/subjects_controller.js index 8fdbb0954..760cf8dac 100644 --- a/app/javascript/controllers/gantt/subjects_controller.js +++ b/app/javascript/controllers/gantt/subjects_controller.js @@ -17,8 +17,8 @@ export default class extends Controller { handleEntryClick(event) { const iconExpander = event.currentTarget const $subject = this.$(iconExpander.parentElement) - const subjectLeft = - parseInt($subject.css("left"), 10) + parseInt(iconExpander.offsetWidth, 10) + const subjectInlineStart = + this.#readInlineStart($subject) + parseInt(iconExpander.offsetWidth, 10) let targetShown = null let targetTop = 0 @@ -36,16 +36,16 @@ export default class extends Controller { const barsSelector = `#gantt_area form > div[data-collapse-expand='${json.obj_id}'][data-number-of-rows='${numberOfRows}']` const selectedColumnsSelector = `td.gantt_selected_column div[data-collapse-expand='${json.obj_id}'][data-number-of-rows='${numberOfRows}']` - if (outOfHierarchy || parseInt($element.css("left"), 10) <= subjectLeft) { + if (outOfHierarchy || this.#readInlineStart($element) <= subjectInlineStart) { outOfHierarchy = true if (targetShown === null) return false - const newTopVal = parseInt($element.css("top"), 10) + totalHeight * (targetShown ? -1 : 1) + const newTopVal = this.#readBlockStart($element) + totalHeight * (targetShown ? -1 : 1) - $element.css("top", newTopVal) + this.#setBlockStart($element, newTopVal) this.$([barsSelector, selectedColumnsSelector].join()).each((__, el) => { - this.$(el).css("top", newTopVal) + this.#setBlockStart(this.$(el), newTopVal) }) return true @@ -55,7 +55,7 @@ export default class extends Controller { if (targetShown === null) { targetShown = isShown - targetTop = parseInt($element.css("top"), 10) + targetTop = this.#readBlockStart($element) totalHeight = 0 } @@ -64,7 +64,7 @@ export default class extends Controller { const $task = this.$(task) if (!isShown && willOpen) { - $task.css("top", targetTop + totalHeight) + this.#setBlockStart($task, targetTop + totalHeight) } if (!$task.hasClass("tooltip")) { $task.toggle(willOpen) @@ -75,13 +75,13 @@ export default class extends Controller { const $attr = this.$(attr) if (!isShown && willOpen) { - $attr.css("top", targetTop + totalHeight) + this.#setBlockStart($attr, targetTop + totalHeight) } $attr.toggle(willOpen) }) if (!isShown && willOpen) { - $element.css("top", targetTop + totalHeight) + this.#setBlockStart($element, targetTop + totalHeight) } this.#setIconState($element, willOpen) @@ -93,6 +93,31 @@ export default class extends Controller { this.dispatch("toggle-tree", { bubbles: true }) } + #getComputedPx(el, property) { + const node = el.jquery ? el[0] : el + const styles = window.getComputedStyle(node) + const val = styles.getPropertyValue(property) + if (val) { + const num = parseFloat(val) + if (!Number.isNaN(num)) return num + } + return NaN + } + + #readInlineStart(el) { + return this.#getComputedPx(el, "inset-inline-start") + } + + #readBlockStart(el) { + return this.#getComputedPx(el, "inset-block-start") + } + + #setBlockStart(el, value) { + const node = el.jquery ? el[0] : el + const px = typeof value === "number" ? `${value}px` : value + node.style.setProperty("inset-block-start", px) + } + #setIconState(element, open) { const $element = element.jquery ? element : this.$(element) const expander = $element.find(".expander") diff --git a/lib/redmine/helpers/gantt.rb b/lib/redmine/helpers/gantt.rb index 50864fb7d..0753c3209 100644 --- a/lib/redmine/helpers/gantt.rb +++ b/lib/redmine/helpers/gantt.rb @@ -817,7 +817,7 @@ module Redmine end if has_children content = view.content_tag(:span, - view.sprite_icon('angle-down').html_safe, + view.sprite_icon('angle-down', rtl: true).html_safe, :class => 'icon icon-expanded expander', :data => {:action => 'click->gantt--subjects#handleEntryClick'}) + content tag_options[:class] += ' open' -- 2.50.1