Skip to content

[AGILE-361] Add batch selection to Backlogs cards - #24525

Merged
myabc merged 22 commits into
devfrom
implementation/AGILE-361-batch-selection
Sep 11, 2026
Merged

myabc merged 22 commits into
devfrom
implementation/AGILE-361-batch-selection

Conversation

@myabc

@myabc myabc commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

Ticket

https://community.openproject.org/wp/AGILE-361

What are you trying to accomplish?

Add batch selection to Backlogs cards so users can select several work packages with the pointer or keyboard before performing a batch action.

Mouse: plain click selects one movable card and opens its details. Ctrl/Cmd+click toggles a card without navigating and makes it the range anchor, including when deselecting it. Shift+click selects a range within the anchor’s list.

Range resizing: independent selections present when a range starts remain selected, including cards in other lists. Repeated Shift gestures extend, shrink, or reverse the range from the same anchor, removing only cards contributed by the previous range. For example, select A and C individually, then Shift to D: A and C–D are selected. Shrink back to C: A and C remain selected.

Keyboard: Space toggles the focused card. Arrows move focus; Shift+Space and Shift+Arrow use the same range rules as the pointer. Home/End move to the first/last movable card in the list; adding Shift extends the range. Ctrl/Cmd+A replaces the selection with all loaded movable cards in the focused card’s list, and a subsequent Shift gesture can narrow that selection. Escape clears selection, while respecting controls and overlays that own the key. Enter retains the card’s existing activation behavior.

Boundaries: without an anchor, Shift starts a single-card selection. Shift into another list starts a new single-card selection and anchor there. Ranges crossing unloaded or non-movable cards are rejected without changing the selection. Individual toggles can build a sparse selection across lists. Broader select-all scopes and alternative cross-list restart behavior remain open decisions in AGILE-181.

Batch movement follows in AGILE-278 / #24778. This PR still moves one card per drag; an existing selection collapses to the dragged card.

Screen recording

This recording predates the latest range-preservation and Select All corrections; the behavior described above is current.

Screen.Recording.2026-08-18.at.23.15.33.mov

Accessibility and follow-ups

Selection changes use the shared Primer live region and the consumer’s vocabulary. Selected cards reference a shared hidden description through aria-describedby. Rejected ranges and cross-list selection restarts receive distinct feedback. There is no persistent visible selection count in this implementation.

The range-selection loss reported in review is addressed here. Two Implementation work packages cover the remaining accessibility work:

What approach did you choose and why?

The framework-independent BatchSelection model stores membership by item type and id, the anchor, and the baseline preserved during range resizing. DOM order and range eligibility are resolved by the sortable-list adapter; the orchestrator routes pointer and keyboard gestures through the shared model.

Selection is opt-in per sortable root. Announcement vocabulary and the shared description id are supplied by the consumer. Modified pointer clicks are handled in the root’s capture phase before card navigation; Escape is handled at the document in the bubble phase so other controls can consume it first.

Movability is an item property. Cards that cannot move still participate in the list’s addressable structure without becoming eligible for batch selection.

Merge checklist

  • Updated AGILE-181 and AGILE-361 behavior descriptions
  • Created accessibility follow-ups AGILE-423 and AGILE-424
  • Explicitly deferred the batch-selection Lookbook guide and selected/current preview to the AGILE-362 / #24779 merge checklist, using the DREAM-774 / #25137 documentation home; the guide is still to be implemented.
  • Reviewer verification of the range-selection correction — Henriette approved the behavior on September 10
  • Carry the range-selection change through the subsequent PRs in the stack and verify their batch behavior

@myabc myabc added this to the 17.8.x milestone Jul 30, 2026
@myabc myabc added javascript Pull requests that update Javascript code feature labels Jul 30, 2026
@github-actions

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./modules/backlogs/spec/features/inbox_column_spec.rb[1:7:1]
  • rspec ./modules/overviews/spec/features/project_description_widget_spec.rb[1:1:1:1:1]
🤖 Ask Copilot to investigate

Copy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer.

@copilot The following spec(s) are flaky in CI (first seen on PR #24525, linked for reference only):

- `rspec ./modules/backlogs/spec/features/inbox_column_spec.rb[1:7:1]`
- `rspec ./modules/overviews/spec/features/project_description_widget_spec.rb[1:1:1:1:1]`

Treat this as a standalone task, unrelated to PR #24525. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24525 or reuse that branch.

Follow the playbook in docs/development/testing/handling-flaky-tests/README.md to find the root cause and fix the underlying race — do not skip, delete, or weaken the spec to make it pass; disabling is a last resort per the playbook, and only with a bug ticket. Verify the fix by running the spec(s) repeatedly (e.g. `script/bulk_run_rspec --run-count 10`).

If you cannot reproduce the flake or are not confident in a fix after reasonable investigation, do not fabricate a change or skip the spec to force CI green. Instead, leave the pull request in draft and document what you tried, the suspected cause, and any leads in its description, then assign @myabc to take over.

Once the fix is verified, title the PR after the spec(s) it fixes, and use the PR description to explain the root cause, how the change resolves it, and the before/after results. Label the PR `flaky-spec`, assign @myabc, and request a review from @myabc.
On every commit, set @myabc as the sole co-author with a `Co-authored-by:` trailer (use their GitHub no-reply email so it links to their account), so it is traceable who dispatched the fix.

Comment thread frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces opt-in batch selection to Backlogs’ sortable lists, including keyboard/mouse interactions, persistent selection count UI, and consistent selection/current-work-package styling across Turbo morphs.

Changes:

  • Add a framework-agnostic BatchSelection model plus a DOM adapter to drive selection behavior in the shared sortable-lists Stimulus controller.
  • Render a persistent Backlogs selection count component (and shared “selected” description element) and wire Backlogs’ root to enable selection + consumer-specific announcements.
  • Update Backlogs item/card DOM contract and styling: movable vs non-movable items, focus target, and selection/current markers preserved across morphs.

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
modules/backlogs/spec/support/pages/backlog.rb Extends Backlogs page object with batch selection helpers and updated drag expectations.
modules/backlogs/spec/requests/backlogs/backlog_spec.rb Adds request spec to ensure selection UI/description is rendered even when inbox is filtered out.
modules/backlogs/spec/features/work_packages/batch_selection_spec.rb New Selenium feature spec covering mouse + keyboard batch selection behavior and accessibility wiring.
modules/backlogs/spec/components/backlogs/work_package_card_list_item_component_spec.rb Updates component specs for movability flag, focus target, and row/card attributes.
modules/backlogs/spec/components/backlogs/work_package_card_list_component_spec.rb Adjusts expectations for updated item target tokens.
modules/backlogs/spec/components/backlogs/sprint_component_spec.rb Aligns sprint rendering expectations with “sortable item always, movable maybe” contract.
modules/backlogs/spec/components/backlogs/selection_count_component_spec.rb New component spec for persistent selection count + shared description rendering.
modules/backlogs/spec/components/backlogs/bucket_component_spec.rb Aligns bucket rendering expectations with updated item contract.
modules/backlogs/config/locales/js-en.yml Adds Backlogs-specific selection announcement/count strings.
modules/backlogs/app/views/backlogs/backlog/show.html.erb Enables selection on Backlogs root and configures announcement scope + description id.
modules/backlogs/app/views/backlogs/backlog/_backlog_list.html.erb Renders selection count component above both planning columns.
modules/backlogs/app/components/backlogs/work_package_card_list_item_component.rb Makes every row a sortable item, adds movable value, and adds a focus item target on the card.
modules/backlogs/app/components/backlogs/selection_count_component.sass Styles persistent selection count and hides it via visibility when empty.
modules/backlogs/app/components/backlogs/selection_count_component.rb Introduces SelectionCount component + shared description id constant.
modules/backlogs/app/components/backlogs/selection_count_component.html.erb Renders persistent count region and shared description element.
modules/backlogs/app/components/_index.sass Registers selection count styles in Backlogs components bundle.
frontend/src/turbo/pragmatic-dnd-morph-attributes.ts Preserves batch selection marker across Turbo morphs to avoid visual flashing.
frontend/src/turbo/pragmatic-dnd-morph-attributes.spec.ts Updates morph preservation test for new selection marker.
frontend/src/stimulus/controllers/dynamic/sortable-lists/selection.ts Adds selection DOM adapter: candidate resolution, range resolution, focus navigation helpers, and presentation wiring.
frontend/src/stimulus/controllers/dynamic/sortable-lists/selection.spec.ts Unit tests for selection adapter behavior.
frontend/src/stimulus/controllers/dynamic/sortable-lists/scrollable.controller.spec.ts Updates fake root interface in tests for new selection capabilities.
frontend/src/stimulus/controllers/dynamic/sortable-lists/preview.ts Removes legacy split-view data-selected stripping; documents batch selection attribute placement.
frontend/src/stimulus/controllers/dynamic/sortable-lists/preview.spec.ts Updates preview sanitization tests accordingly.
frontend/src/stimulus/controllers/dynamic/sortable-lists/list.controller.spec.ts Updates fake root interface in tests for new selection capabilities.
frontend/src/stimulus/controllers/dynamic/sortable-lists/list-dom.ts Adds movable attribute contract and isMovableItem helper.
frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.ts Adds movable value, focus target support, and collapses selection on drag start.
frontend/src/stimulus/controllers/dynamic/sortable-lists/item.controller.spec.ts Adds coverage for movability gating + focus behavior + drag-start selection collapse.
frontend/src/stimulus/controllers/dynamic/sortable-lists/drag-and-drop.ts Extends root interface with selectionEnabled and collapseSelectionForDrag.
frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.ts Implements opt-in batch selection interactions, announcements, morph reconciliation, and selection count rendering.
frontend/src/stimulus/controllers/dynamic/sortable-lists.controller.spec.ts Extensive new test coverage for selection interactions, announcements, and morph reconciliation.
frontend/src/stimulus/controllers/dynamic/backlogs/work-package.controller.ts Removes legacy data-selected handling; keeps only aria-current syncing to URL.
frontend/src/stimulus/controllers/dynamic/backlogs/work-package.controller.spec.ts Updates tests for current-work-package behavior and ensures batch membership is unaffected by URL sync.
frontend/src/global_styles/content/modules/_backlogs.sass Adjusts Backlogs layout to accommodate persistent selection count above scroll columns.
frontend/src/common/batch-selection.ts Adds framework-agnostic batch selection model (ids + anchor + prune).
frontend/src/common/batch-selection.spec.ts Unit tests for batch selection model semantics.
frontend/AGENTS.md Documents sortable-lists batch selection opt-in, vocabulary, and marker placement.
config/locales/js-en.yml Adds default sortable-lists selection announcement strings (generic “item” vocabulary).
app/components/open_project/common/border_box_list_component.sass Updates styling selectors from legacy data-selected to new data-batch-selected + aria-current separation.

@myabc
myabc force-pushed the implementation/AGILE-361-batch-selection branch from 09c5889 to 8a57b46 Compare August 5, 2026 12:11
@github-actions

This comment was marked as outdated.

@myabc myabc changed the title Implementation/agile 361 batch selection [AGILE-361] Add batch selection to Backlogs cards Aug 5, 2026
@myabc
myabc force-pushed the implementation/AGILE-361-batch-selection branch from 8a57b46 to 5273f41 Compare August 5, 2026 14:30
@myabc
myabc requested a lite review from Copilot August 5, 2026 14:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 38 out of 38 changed files in this pull request and generated no new comments.

Suppressed comments (2)

modules/backlogs/app/components/backlogs/selection_count_component.html.erb:55

  • hidden: true renders a literal HTML hidden attribute (i.e., display: none), which commonly removes the element from the accessibility tree. Because this span is referenced via aria-describedby, it should be visually hidden (e.g., sr-only) rather than hidden, otherwise some screen readers may ignore the referenced description.
<%= render(Primer::Box.new(tag: :span, id: DESCRIPTION_ID, hidden: true)) do %>
  <%= I18n.t("js.backlogs.selection.card_state") %>
<% end %>

modules/backlogs/spec/support/pages/backlog.rb:764

  • This comment says the description is permanently hidden and still reachable via aria-describedby. With the HTML hidden attribute that isn’t reliably true; the description should be treated as visually hidden (e.g., sr-only) so assistive tech can still reference it. Updating this wording will prevent future changes from reintroducing hidden and breaking the a11y contract.

Comment thread modules/backlogs/spec/support/pages/backlog.rb Outdated
Comment thread modules/backlogs/spec/support/pages/backlog.rb Outdated
@myabc
myabc force-pushed the implementation/AGILE-361-batch-selection branch 2 times, most recently from 2a7bbac to f3da126 Compare August 5, 2026 16:08
@myabc
myabc force-pushed the implementation/AGILE-361-batch-selection branch from f3da126 to 63d626a Compare August 5, 2026 23:26
@myabc
myabc changed the base branch from dev to implementation/DREAM-786-sortable-lists-admin-project-attributes August 5, 2026 23:27
@myabc
myabc force-pushed the implementation/AGILE-361-batch-selection branch from 63d626a to 6e3c26e Compare August 6, 2026 08:19
@myabc
myabc requested a lite review from Copilot August 6, 2026 08:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 42 out of 42 changed files in this pull request and generated no new comments.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./modules/gantt/spec/features/timeline/timeline_dates_spec.rb[1:3:2:2:1:1]
🤖 Ask Copilot to investigate

Copy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer.

@copilot The following spec(s) are flaky in CI (first seen on PR #24525, linked for reference only):

- `rspec ./modules/gantt/spec/features/timeline/timeline_dates_spec.rb[1:3:2:2:1:1]`

Treat this as a standalone task, unrelated to PR #24525. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24525 or reuse that branch.

Follow the playbook in docs/development/testing/handling-flaky-tests/README.md to find the root cause and fix the underlying race — do not skip, delete, or weaken the spec to make it pass; disabling is a last resort per the playbook, and only with a bug ticket. Verify the fix by running the spec(s) repeatedly (e.g. `script/bulk_run_rspec --run-count 10`).

If you cannot reproduce the flake or are not confident in a fix after reasonable investigation, do not fabricate a change or skip the spec to force CI green. Instead, leave the pull request in draft and document what you tried, the suspected cause, and any leads in its description, then assign @myabc to take over.

Once the fix is verified, title the PR after the spec(s) it fixes, and use the PR description to explain the root cause, how the change resolves it, and the before/after results. Label the PR `flaky-spec`, assign @myabc, and request a review from @myabc.
On every commit, set @myabc as the sole co-author with a `Co-authored-by:` trailer (use their GitHub no-reply email so it links to their account), so it is traceable who dispatched the fix.

@myabc
myabc force-pushed the implementation/AGILE-361-batch-selection branch from ed10ba1 to 554ff16 Compare September 9, 2026 16:48

@HDinger HDinger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behaviour looks fine for me 👍

@github-actions

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./modules/wikis/spec/features/admin/internal_provider_spec.rb[1:1]
  • rspec ./spec/features/roles/report_spec.rb[1:1]
  • rspec ./spec/features/roles/report_spec.rb[1:2]
  • rspec ./spec/features/roles/report_spec.rb[1:3]
🤖 Ask Copilot to investigate

Copy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer.

@copilot The following spec(s) are flaky in CI (first seen on PR #24525, linked for reference only):

- `rspec ./modules/wikis/spec/features/admin/internal_provider_spec.rb[1:1]`
- `rspec ./spec/features/roles/report_spec.rb[1:1]`
- `rspec ./spec/features/roles/report_spec.rb[1:2]`
- `rspec ./spec/features/roles/report_spec.rb[1:3]`

Treat this as a standalone task, unrelated to PR #24525. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24525 or reuse that branch.

Follow the playbook in docs/development/testing/handling-flaky-tests/README.md to find the root cause and fix the underlying race — do not skip, delete, or weaken the spec to make it pass; disabling is a last resort per the playbook, and only with a bug ticket. Verify the fix by running the spec(s) repeatedly (e.g. `script/bulk_run_rspec --run-count 10`).

If you cannot reproduce the flake or are not confident in a fix after reasonable investigation, do not fabricate a change or skip the spec to force CI green. Instead, leave the pull request in draft and document what you tried, the suspected cause, and any leads in its description, then assign @myabc to take over.

Once the fix is verified, title the PR after the spec(s) it fixes, and use the PR description to explain the root cause, how the change resolves it, and the before/after results. Label the PR `flaky-spec`, assign @myabc, and request a review from @myabc.
On every commit, set @myabc as the sole co-author with a `Co-authored-by:` trailer (use their GitHub no-reply email so it links to their account), so it is traceable who dispatched the fix.

@myabc

myabc commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

@ulferts I've added some additional items for discussion to the AGILE-181 description - diff here. Hopefully this list should cover all points that you raised that have yet to be addressed (either in this or other PRs in the stack).

Adds a framework-agnostic anchor/range/toggle model over opaque
(type, id) identities, so card and table views can share one selection
policy without inheriting any view's concepts.

https://community.openproject.org/wp/AGILE-361
Renders every card as a sortable item and replaces presence-based
movability with a mobility value (free, confined or fixed), so a card
the user cannot move still anchors drops and position counting. An
unrecognised value falls closed to fixed.

https://community.openproject.org/wp/AGILE-361
Adds the DOM-facing selection adapter and an orchestrator turning
pointer and keyboard gestures into model changes and announcements.
Ranges and Ctrl/Cmd+A are confined to the focused card's list; Escape
clears the selection from anywhere on the page.

https://community.openproject.org/wp/AGILE-361
Attaches selection opt-in to the sortable root: capture-phase listeners
beat the card's own click handler, a drag collapses the batch onto the
dragged card, and membership survives Turbo morphs and cache restores.

https://community.openproject.org/wp/AGILE-361
Opts the sprint planning page in, speaks "work package" through the
announcement scope, and describes membership through one shared hidden
element every selected card references via aria-describedby.

https://community.openproject.org/wp/AGILE-361
Adds a Selenium feature spec for what units cannot prove: the
capture-phase listeners really beat the card's own click and Enter
handlers in a real page.

https://community.openproject.org/wp/AGILE-361
Restores the change lost in the 2026-08-18 squash: Cmd on Apple
platforms, Ctrl elsewhere, never the other. Meta on Windows or Linux
classifies as an ordinary click again.
Matches the anchor row by (type, id) like every other lookup, bounds
the focus host to the item's own subtree so a nested item's target
cannot stand in, keys lists by their values rather than DOM id, and
keeps range rows to items the list itself owns: the rows-container
boundary bounds only the upward walk, and the downward fallback handed
a structural row the first item of a list nested inside it.
Both specs carried a copy of the production strings and one had
already drifted. A shared fixture of key tokens asserts message
choice and pluralisation without a copy to keep in step. Also covers
a Shift range spanning a fixed card, not only ending on one.
Drops the unread mobility value declaration, makes teardown reset the
model it discards, and has the card controller ignore the same inner
controls the orchestrator does, under a name that says it tracks the
current card rather than a selection.
Accepts the physical A key when the layout prints another script on
it, while still following the key's meaning on Latin layouts such as
AZERTY, where Ctrl+A sits on KeyQ.
Only the Shift range mutation waits for the host; plain navigation
never touched the model and has no reason to stall.
Opening the details pane is feedback enough for the card itself; the
count is worth hearing only once a wider selection is lost.
Focus routinely rests in the details pane or the page header after a
selection. Only an overlay or a field whose widget owns Escape keeps
the key.
The "show more" expander is a frame navigation, not a morph: it swaps
the rows wholesale and no morph event follows, so the fresh rows came
back unmarked while the model and live region still held the batch.
Item outlet churn now schedules the same reconcile a morph does.
A row that wraps a nested list could resolve to the nested list's first
item instead of nothing. resolveItemElement's downward fallback now
checks only the row's own direct children, matching the bound already
applied to its upward climb.
Keeps independently selected items while Shift gestures extend, shrink
or reverse a range. Resets the range baseline on individual selection
changes and removes stale members during reconciliation. Allows Shift
ranges to narrow a selection produced by Select All.

Covers shared state, mouse/keyboard parity, same-list preservation and
baseline pruning after DOM changes. Makes the feature scenario detect
an incorrect anchor after deselection.
Every Selenium spec that visits through a page object warned about the
Cuprite-only helper on each call, since the base class waited without
checking the driver. Selenium's visit already blocks on the load event,
so `visit!` now guards the wait the same way `reload!` does.
The guard only stepped aside for a bare Ctrl-click, so Ctrl+Shift-click
reached the range path although macOS still treats it as the secondary
click. Ctrl now bows out on Apple platforms regardless of the other
modifiers held with it.
The note called selecting across lists a deliberate gap, yet Ctrl/Cmd
click toggles do build a sparse batch across lists; only ranges and
select-all are list-confined. Spelled out so a future consumer does not
remove or work around supported behavior.
Keeps component behavior out of the frontend-wide agent instructions.
Places the durable selection contract beside its implementation and
removes status notes that become stale as the stack progresses.
@github-actions

Copy link
Copy Markdown

Warning

Flaky specs

  • rspec ./modules/meeting/spec/features/recurring_meetings/recurring_meeting_global_create_spec.rb[1:1:2]
  • rspec ./spec/features/notifications/navigation_spec.rb[1:1:1]
🤖 Ask Copilot to investigate

Copy the prompt below into a new comment on this PR to delegate the investigation to GitHub Copilot. It will look into the flakiness and open a separate pull request with you as reviewer.

@copilot The following spec(s) are flaky in CI (first seen on PR #24525, linked for reference only):

- `rspec ./modules/meeting/spec/features/recurring_meetings/recurring_meeting_global_create_spec.rb[1:1:2]`
- `rspec ./spec/features/notifications/navigation_spec.rb[1:1:1]`

Treat this as a standalone task, unrelated to PR #24525. Create a new branch from origin/dev and open a new pull request targeting dev — do not stack it on PR #24525 or reuse that branch.

Follow the playbook in docs/development/testing/handling-flaky-tests/README.md to find the root cause and fix the underlying race — do not skip, delete, or weaken the spec to make it pass; disabling is a last resort per the playbook, and only with a bug ticket. Verify the fix by running the spec(s) repeatedly (e.g. `script/bulk_run_rspec --run-count 10`).

If you cannot reproduce the flake or are not confident in a fix after reasonable investigation, do not fabricate a change or skip the spec to force CI green. Instead, leave the pull request in draft and document what you tried, the suspected cause, and any leads in its description, then assign @myabc to take over.

Once the fix is verified, title the PR after the spec(s) it fixes, and use the PR description to explain the root cause, how the change resolves it, and the before/after results. Label the PR `flaky-spec`, assign @myabc, and request a review from @myabc.
On every commit, set @myabc as the sole co-author with a `Co-authored-by:` trailer (use their GitHub no-reply email so it links to their account), so it is traceable who dispatched the fix.

@myabc
myabc force-pushed the implementation/AGILE-361-batch-selection branch from 8de1e56 to 7f0295c Compare September 10, 2026 17:23

@ulferts ulferts left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a journey but you finished it nicely, @myabc .

@myabc
myabc merged commit 8e9c357 into dev Sep 11, 2026
21 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

feature javascript Pull requests that update Javascript code needs review

Development

Successfully merging this pull request may close these issues.

5 participants