508 Commits

Author SHA1 Message Date
Klaus Zanders 1d91460c84 Extract progress modal form glue into a shared ModalParams concern 2026-06-10 15:40:15 +02:00
Kabiru Mwenja fd22629702 Code Maintenance/STC-462: Tidy the activity-tab paginator and centralise filter modes (#23552)
https://community.openproject.org/wp/STC-462

Two readability passes over the work package activity tab, no behaviour change. The paginator's private methods are reordered to follow their call order so the file reads top-down from `#call`, and the three activity filter modes (`:all`, `:only_comments`, `:only_changes`) — until now bare symbols duplicated across the controller, paginator, journal components and the hidden form — move into a single `WorkPackages::ActivitiesTab::Filters` module so the modes have one source of truth and can't drift apart. The diff reaches beyond the paginator into the controller, several components and a form, since that's where the symbols were scattered.
2026-06-05 16:50:08 +03:00
Kabiru Mwenja 5fdf57df69 Defer activity-tab sequence_version to anchor resolution
The work package activity tab computed a per-journal sequence_version on
every render — a ROW_NUMBER() window function over a LATERAL join — only to
stamp the legacy data-anchor-activity-id that #activity-N deep links rely on.
Nothing mints those links anymore; copy and share links use
#comment-<journal id>, which needs no extra query.

The activity number is now resolved on demand. Only a request carrying
?anchor=activity-N runs the window function, mapping the number to a journal
id the paginator exposes as resolved_anchor. The view hands that to the
client, which rewrites #activity-N to the canonical #comment-<id> and scrolls
using the comment anchor already present in the DOM. Default renders no longer
touch the window function.

References WP #68063.
2026-06-05 14:26:04 +03:00
Tomas Hykel 27397984c2 add a comment 2026-06-03 12:43:46 +02:00
Tomas Hykel 3fbad33ee1 [#74927] Unable to change a parent on bulk edit of work packages with semantic ID
https://community.openproject.org/wp/74927
2026-05-22 19:10:26 +02:00
Kabiru Mwenja 27c6f72cbc Apply S5 review feedback: rename href_id, trim controller comment
- mention_filter.rb: rename local `href_id` to `display_id` to mirror the
  method name and the `data-display-id` wire attribute (the value is the
  user-facing identifier, used for both the href and the data-attribute).
- auto_completes_controller.rb: trim the `displayId` doc comment that
  incorrectly claimed the editor builds the mention's link URL from this
  field. The URL is composed server-side at render time from `data-id` /
  `data-display-id`; the editor only inserts the markdown source.
2026-05-15 10:59:11 +03:00
Kabiru Mwenja 5bf50f3243 Stringify displayId in auto_complete payload for APIv3 parity
The auto_complete endpoint exposed `displayId` as the bare
`work_package.display_id`, which is an Integer in classic mode and a
String in semantic mode. APIv3 already coerces this field on the work
package representer (and on its `:children` and `:ancestors` link
collections), so the auto_complete payload was the lone outlier.

The single CKEditor consumer interpolates the value into a string, so
this change is purely a consistency fix at the JSON boundary; nothing
behavioural depends on the wire type.
2026-05-15 10:59:09 +03:00
Kabiru Mwenja 4286c404aa Drop unused formattedId from auto_complete JSON response
The only consumer of `/work_packages/auto_complete.json` is the CKEditor
mention feed in commonmark-ckeditor-build, which reads `displayId`
(needed to build the markdown source `#PROJ-7` and the link URL) and
`to_s` (used as the dropdown label). `formattedId` was added alongside
`displayId` for symmetry but nothing reads it.
2026-05-15 10:59:08 +03:00
Kabiru Mwenja 745d4f9f5c Expose displayId and formattedId on work-package auto_complete API
The CKEditor mention plugin (in commonmark-ckeditor-build) reads
`displayId` from each search result so the markdown source it inserts
on autocomplete-pick speaks the user-facing identifier — `#PROJ-7` in
semantic mode, `#1234` in classic. The endpoint previously serialised
`work_package.attributes`, which gave the raw `identifier` column but
not the mode-aware `display_id` / `formatted_id` accessors.

Fold both into the JSON response. `displayId` collapses to the numeric
id in classic mode, so the frontend never needs a per-mode branch.
2026-05-15 10:59:08 +03:00
Oliver Günther 3835d71015 Try more back route 2026-04-20 07:34:47 +02:00
Oliver Günther 774e64ca8b Fix back route 2026-04-19 21:10:42 +02:00
Oliver Günther 2898a1d0ff Delete dialog primer 2026-04-19 21:10:41 +02:00
Alexander Brandon Coles ccccead89f Merge branch 'dev' into merge-release/17.3-20260411112919
# Conflicts:
#	config/locales/crowdin/af.yml
#	config/locales/crowdin/ar.yml
#	config/locales/crowdin/az.yml
#	config/locales/crowdin/be.yml
#	config/locales/crowdin/bg.yml
#	config/locales/crowdin/ca.yml
#	config/locales/crowdin/ckb-IR.yml
#	config/locales/crowdin/cs.yml
#	config/locales/crowdin/da.yml
#	config/locales/crowdin/de.yml
#	config/locales/crowdin/el.yml
#	config/locales/crowdin/eo.yml
#	config/locales/crowdin/es.yml
#	config/locales/crowdin/et.yml
#	config/locales/crowdin/eu.yml
#	config/locales/crowdin/fa.yml
#	config/locales/crowdin/fi.yml
#	config/locales/crowdin/fil.yml
#	config/locales/crowdin/fr.yml
#	config/locales/crowdin/he.yml
#	config/locales/crowdin/hi.yml
#	config/locales/crowdin/hr.yml
#	config/locales/crowdin/hu.yml
#	config/locales/crowdin/id.yml
#	config/locales/crowdin/it.yml
#	config/locales/crowdin/ja.yml
#	config/locales/crowdin/js-af.yml
#	config/locales/crowdin/js-ar.yml
#	config/locales/crowdin/js-az.yml
#	config/locales/crowdin/js-be.yml
#	config/locales/crowdin/js-bg.yml
#	config/locales/crowdin/js-ca.yml
#	config/locales/crowdin/js-ckb-IR.yml
#	config/locales/crowdin/js-cs.yml
#	config/locales/crowdin/js-da.yml
#	config/locales/crowdin/js-de.yml
#	config/locales/crowdin/js-el.yml
#	config/locales/crowdin/js-eo.yml
#	config/locales/crowdin/js-es.yml
#	config/locales/crowdin/js-et.yml
#	config/locales/crowdin/js-eu.yml
#	config/locales/crowdin/js-fa.yml
#	config/locales/crowdin/js-fi.yml
#	config/locales/crowdin/js-fil.yml
#	config/locales/crowdin/js-fr.yml
#	config/locales/crowdin/js-he.yml
#	config/locales/crowdin/js-hi.yml
#	config/locales/crowdin/js-hr.yml
#	config/locales/crowdin/js-hu.yml
#	config/locales/crowdin/js-id.yml
#	config/locales/crowdin/js-it.yml
#	config/locales/crowdin/js-ja.yml
#	config/locales/crowdin/js-ka.yml
#	config/locales/crowdin/js-kk.yml
#	config/locales/crowdin/js-ko.yml
#	config/locales/crowdin/js-lt.yml
#	config/locales/crowdin/js-lv.yml
#	config/locales/crowdin/js-mn.yml
#	config/locales/crowdin/js-ms.yml
#	config/locales/crowdin/js-ne.yml
#	config/locales/crowdin/js-nl.yml
#	config/locales/crowdin/js-no.yml
#	config/locales/crowdin/js-pl.yml
#	config/locales/crowdin/js-pt-BR.yml
#	config/locales/crowdin/js-pt-PT.yml
#	config/locales/crowdin/js-ro.yml
#	config/locales/crowdin/js-ru.yml
#	config/locales/crowdin/js-rw.yml
#	config/locales/crowdin/js-si.yml
#	config/locales/crowdin/js-sk.yml
#	config/locales/crowdin/js-sl.yml
#	config/locales/crowdin/js-sr.yml
#	config/locales/crowdin/js-sv.yml
#	config/locales/crowdin/js-th.yml
#	config/locales/crowdin/js-tr.yml
#	config/locales/crowdin/js-uk.yml
#	config/locales/crowdin/js-uz.yml
#	config/locales/crowdin/js-vi.yml
#	config/locales/crowdin/js-zh-CN.yml
#	config/locales/crowdin/js-zh-TW.yml
#	config/locales/crowdin/ka.yml
#	config/locales/crowdin/kk.yml
#	config/locales/crowdin/ko.yml
#	config/locales/crowdin/lt.yml
#	config/locales/crowdin/lv.yml
#	config/locales/crowdin/mn.yml
#	config/locales/crowdin/ms.yml
#	config/locales/crowdin/ne.yml
#	config/locales/crowdin/nl.yml
#	config/locales/crowdin/no.yml
#	config/locales/crowdin/pl.yml
#	config/locales/crowdin/pt-BR.yml
#	config/locales/crowdin/pt-PT.yml
#	config/locales/crowdin/ro.yml
#	config/locales/crowdin/ru.yml
#	config/locales/crowdin/rw.yml
#	config/locales/crowdin/si.yml
#	config/locales/crowdin/sk.yml
#	config/locales/crowdin/sl.yml
#	config/locales/crowdin/sr.yml
#	config/locales/crowdin/sv.yml
#	config/locales/crowdin/th.yml
#	config/locales/crowdin/tr.yml
#	config/locales/crowdin/uk.yml
#	config/locales/crowdin/uz.yml
#	config/locales/crowdin/vi.yml
#	config/locales/crowdin/zh-CN.yml
#	config/locales/crowdin/zh-TW.yml
#	modules/backlogs/config/locales/crowdin/af.yml
#	modules/backlogs/config/locales/crowdin/ar.yml
#	modules/backlogs/config/locales/crowdin/az.yml
#	modules/backlogs/config/locales/crowdin/be.yml
#	modules/backlogs/config/locales/crowdin/bg.yml
#	modules/backlogs/config/locales/crowdin/ca.yml
#	modules/backlogs/config/locales/crowdin/ckb-IR.yml
#	modules/backlogs/config/locales/crowdin/cs.yml
#	modules/backlogs/config/locales/crowdin/da.yml
#	modules/backlogs/config/locales/crowdin/de.yml
#	modules/backlogs/config/locales/crowdin/el.yml
#	modules/backlogs/config/locales/crowdin/eo.yml
#	modules/backlogs/config/locales/crowdin/es.yml
#	modules/backlogs/config/locales/crowdin/et.yml
#	modules/backlogs/config/locales/crowdin/eu.yml
#	modules/backlogs/config/locales/crowdin/fa.yml
#	modules/backlogs/config/locales/crowdin/fi.yml
#	modules/backlogs/config/locales/crowdin/fil.yml
#	modules/backlogs/config/locales/crowdin/fr.yml
#	modules/backlogs/config/locales/crowdin/he.yml
#	modules/backlogs/config/locales/crowdin/hi.yml
#	modules/backlogs/config/locales/crowdin/hr.yml
#	modules/backlogs/config/locales/crowdin/hu.yml
#	modules/backlogs/config/locales/crowdin/id.yml
#	modules/backlogs/config/locales/crowdin/it.yml
#	modules/backlogs/config/locales/crowdin/ja.yml
#	modules/backlogs/config/locales/crowdin/ka.yml
#	modules/backlogs/config/locales/crowdin/kk.yml
#	modules/backlogs/config/locales/crowdin/ko.yml
#	modules/backlogs/config/locales/crowdin/lt.yml
#	modules/backlogs/config/locales/crowdin/lv.yml
#	modules/backlogs/config/locales/crowdin/mn.yml
#	modules/backlogs/config/locales/crowdin/ms.yml
#	modules/backlogs/config/locales/crowdin/ne.yml
#	modules/backlogs/config/locales/crowdin/nl.yml
#	modules/backlogs/config/locales/crowdin/no.yml
#	modules/backlogs/config/locales/crowdin/pl.yml
#	modules/backlogs/config/locales/crowdin/pt-BR.yml
#	modules/backlogs/config/locales/crowdin/pt-PT.yml
#	modules/backlogs/config/locales/crowdin/ro.yml
#	modules/backlogs/config/locales/crowdin/ru.yml
#	modules/backlogs/config/locales/crowdin/rw.yml
#	modules/backlogs/config/locales/crowdin/si.yml
#	modules/backlogs/config/locales/crowdin/sk.yml
#	modules/backlogs/config/locales/crowdin/sl.yml
#	modules/backlogs/config/locales/crowdin/sr.yml
#	modules/backlogs/config/locales/crowdin/sv.yml
#	modules/backlogs/config/locales/crowdin/th.yml
#	modules/backlogs/config/locales/crowdin/tr.yml
#	modules/backlogs/config/locales/crowdin/uk.yml
#	modules/backlogs/config/locales/crowdin/uz.yml
#	modules/backlogs/config/locales/crowdin/vi.yml
#	modules/backlogs/config/locales/crowdin/zh-CN.yml
#	modules/backlogs/config/locales/crowdin/zh-TW.yml
#	modules/bim/config/locales/crowdin/fr.yml
#	modules/budgets/config/locales/crowdin/cs.yml
#	modules/costs/config/locales/crowdin/ja.yml
#	modules/documents/config/locales/crowdin/af.yml
#	modules/documents/config/locales/crowdin/ar.yml
#	modules/documents/config/locales/crowdin/az.yml
#	modules/documents/config/locales/crowdin/be.yml
#	modules/documents/config/locales/crowdin/bg.yml
#	modules/documents/config/locales/crowdin/ca.yml
#	modules/documents/config/locales/crowdin/ckb-IR.yml
#	modules/documents/config/locales/crowdin/cs.yml
#	modules/documents/config/locales/crowdin/da.yml
#	modules/documents/config/locales/crowdin/de.yml
#	modules/documents/config/locales/crowdin/el.yml
#	modules/documents/config/locales/crowdin/eo.yml
#	modules/documents/config/locales/crowdin/es.yml
#	modules/documents/config/locales/crowdin/et.yml
#	modules/documents/config/locales/crowdin/eu.yml
#	modules/documents/config/locales/crowdin/fa.yml
#	modules/documents/config/locales/crowdin/fi.yml
#	modules/documents/config/locales/crowdin/fil.yml
#	modules/documents/config/locales/crowdin/fr.yml
#	modules/documents/config/locales/crowdin/he.yml
#	modules/documents/config/locales/crowdin/hi.yml
#	modules/documents/config/locales/crowdin/hr.yml
#	modules/documents/config/locales/crowdin/hu.yml
#	modules/documents/config/locales/crowdin/id.yml
#	modules/documents/config/locales/crowdin/it.yml
#	modules/documents/config/locales/crowdin/ja.yml
#	modules/documents/config/locales/crowdin/ka.yml
#	modules/documents/config/locales/crowdin/kk.yml
#	modules/documents/config/locales/crowdin/ko.yml
#	modules/documents/config/locales/crowdin/lt.yml
#	modules/documents/config/locales/crowdin/lv.yml
#	modules/documents/config/locales/crowdin/mn.yml
#	modules/documents/config/locales/crowdin/ms.yml
#	modules/documents/config/locales/crowdin/ne.yml
#	modules/documents/config/locales/crowdin/nl.yml
#	modules/documents/config/locales/crowdin/no.yml
#	modules/documents/config/locales/crowdin/pl.yml
#	modules/documents/config/locales/crowdin/pt-BR.yml
#	modules/documents/config/locales/crowdin/pt-PT.yml
#	modules/documents/config/locales/crowdin/ro.yml
#	modules/documents/config/locales/crowdin/ru.yml
#	modules/documents/config/locales/crowdin/rw.yml
#	modules/documents/config/locales/crowdin/si.yml
#	modules/documents/config/locales/crowdin/sk.yml
#	modules/documents/config/locales/crowdin/sl.yml
#	modules/documents/config/locales/crowdin/sr.yml
#	modules/documents/config/locales/crowdin/sv.yml
#	modules/documents/config/locales/crowdin/th.yml
#	modules/documents/config/locales/crowdin/tr.yml
#	modules/documents/config/locales/crowdin/uk.yml
#	modules/documents/config/locales/crowdin/uz.yml
#	modules/documents/config/locales/crowdin/vi.yml
#	modules/documents/config/locales/crowdin/zh-CN.yml
#	modules/documents/config/locales/crowdin/zh-TW.yml
#	modules/gitlab_integration/config/locales/crowdin/af.yml
#	modules/gitlab_integration/config/locales/crowdin/ar.yml
#	modules/gitlab_integration/config/locales/crowdin/az.yml
#	modules/gitlab_integration/config/locales/crowdin/be.yml
#	modules/gitlab_integration/config/locales/crowdin/bg.yml
#	modules/gitlab_integration/config/locales/crowdin/ca.yml
#	modules/gitlab_integration/config/locales/crowdin/ckb-IR.yml
#	modules/gitlab_integration/config/locales/crowdin/cs.yml
#	modules/gitlab_integration/config/locales/crowdin/da.yml
#	modules/gitlab_integration/config/locales/crowdin/de.yml
#	modules/gitlab_integration/config/locales/crowdin/el.yml
#	modules/gitlab_integration/config/locales/crowdin/eo.yml
#	modules/gitlab_integration/config/locales/crowdin/es.yml
#	modules/gitlab_integration/config/locales/crowdin/et.yml
#	modules/gitlab_integration/config/locales/crowdin/eu.yml
#	modules/gitlab_integration/config/locales/crowdin/fa.yml
#	modules/gitlab_integration/config/locales/crowdin/fi.yml
#	modules/gitlab_integration/config/locales/crowdin/fil.yml
#	modules/gitlab_integration/config/locales/crowdin/fr.yml
#	modules/gitlab_integration/config/locales/crowdin/he.yml
#	modules/gitlab_integration/config/locales/crowdin/hi.yml
#	modules/gitlab_integration/config/locales/crowdin/hr.yml
#	modules/gitlab_integration/config/locales/crowdin/hu.yml
#	modules/gitlab_integration/config/locales/crowdin/id.yml
#	modules/gitlab_integration/config/locales/crowdin/it.yml
#	modules/gitlab_integration/config/locales/crowdin/ja.yml
#	modules/gitlab_integration/config/locales/crowdin/ka.yml
#	modules/gitlab_integration/config/locales/crowdin/kk.yml
#	modules/gitlab_integration/config/locales/crowdin/ko.yml
#	modules/gitlab_integration/config/locales/crowdin/lt.yml
#	modules/gitlab_integration/config/locales/crowdin/lv.yml
#	modules/gitlab_integration/config/locales/crowdin/mn.yml
#	modules/gitlab_integration/config/locales/crowdin/ms.yml
#	modules/gitlab_integration/config/locales/crowdin/ne.yml
#	modules/gitlab_integration/config/locales/crowdin/nl.yml
#	modules/gitlab_integration/config/locales/crowdin/no.yml
#	modules/gitlab_integration/config/locales/crowdin/pl.yml
#	modules/gitlab_integration/config/locales/crowdin/pt-BR.yml
#	modules/gitlab_integration/config/locales/crowdin/pt-PT.yml
#	modules/gitlab_integration/config/locales/crowdin/ro.yml
#	modules/gitlab_integration/config/locales/crowdin/ru.yml
#	modules/gitlab_integration/config/locales/crowdin/rw.yml
#	modules/gitlab_integration/config/locales/crowdin/si.yml
#	modules/gitlab_integration/config/locales/crowdin/sk.yml
#	modules/gitlab_integration/config/locales/crowdin/sl.yml
#	modules/gitlab_integration/config/locales/crowdin/sr.yml
#	modules/gitlab_integration/config/locales/crowdin/sv.yml
#	modules/gitlab_integration/config/locales/crowdin/th.yml
#	modules/gitlab_integration/config/locales/crowdin/tr.yml
#	modules/gitlab_integration/config/locales/crowdin/uk.yml
#	modules/gitlab_integration/config/locales/crowdin/uz.yml
#	modules/gitlab_integration/config/locales/crowdin/vi.yml
#	modules/gitlab_integration/config/locales/crowdin/zh-CN.yml
#	modules/gitlab_integration/config/locales/crowdin/zh-TW.yml
#	modules/ldap_groups/config/locales/crowdin/af.yml
#	modules/ldap_groups/config/locales/crowdin/ar.yml
#	modules/ldap_groups/config/locales/crowdin/az.yml
#	modules/ldap_groups/config/locales/crowdin/be.yml
#	modules/ldap_groups/config/locales/crowdin/bg.yml
#	modules/ldap_groups/config/locales/crowdin/ca.yml
#	modules/ldap_groups/config/locales/crowdin/ckb-IR.yml
#	modules/ldap_groups/config/locales/crowdin/cs.yml
#	modules/ldap_groups/config/locales/crowdin/da.yml
#	modules/ldap_groups/config/locales/crowdin/de.yml
#	modules/ldap_groups/config/locales/crowdin/el.yml
#	modules/ldap_groups/config/locales/crowdin/eo.yml
#	modules/ldap_groups/config/locales/crowdin/es.yml
#	modules/ldap_groups/config/locales/crowdin/et.yml
#	modules/ldap_groups/config/locales/crowdin/eu.yml
#	modules/ldap_groups/config/locales/crowdin/fa.yml
#	modules/ldap_groups/config/locales/crowdin/fi.yml
#	modules/ldap_groups/config/locales/crowdin/fil.yml
#	modules/ldap_groups/config/locales/crowdin/fr.yml
#	modules/ldap_groups/config/locales/crowdin/he.yml
#	modules/ldap_groups/config/locales/crowdin/hi.yml
#	modules/ldap_groups/config/locales/crowdin/hr.yml
#	modules/ldap_groups/config/locales/crowdin/hu.yml
#	modules/ldap_groups/config/locales/crowdin/id.yml
#	modules/ldap_groups/config/locales/crowdin/it.yml
#	modules/ldap_groups/config/locales/crowdin/ja.yml
#	modules/ldap_groups/config/locales/crowdin/ka.yml
#	modules/ldap_groups/config/locales/crowdin/kk.yml
#	modules/ldap_groups/config/locales/crowdin/ko.yml
#	modules/ldap_groups/config/locales/crowdin/lt.yml
#	modules/ldap_groups/config/locales/crowdin/lv.yml
#	modules/ldap_groups/config/locales/crowdin/mn.yml
#	modules/ldap_groups/config/locales/crowdin/ms.yml
#	modules/ldap_groups/config/locales/crowdin/ne.yml
#	modules/ldap_groups/config/locales/crowdin/nl.yml
#	modules/ldap_groups/config/locales/crowdin/no.yml
#	modules/ldap_groups/config/locales/crowdin/pl.yml
#	modules/ldap_groups/config/locales/crowdin/pt-BR.yml
#	modules/ldap_groups/config/locales/crowdin/pt-PT.yml
#	modules/ldap_groups/config/locales/crowdin/ro.yml
#	modules/ldap_groups/config/locales/crowdin/ru.yml
#	modules/ldap_groups/config/locales/crowdin/rw.yml
#	modules/ldap_groups/config/locales/crowdin/si.yml
#	modules/ldap_groups/config/locales/crowdin/sk.yml
#	modules/ldap_groups/config/locales/crowdin/sl.yml
#	modules/ldap_groups/config/locales/crowdin/sr.yml
#	modules/ldap_groups/config/locales/crowdin/sv.yml
#	modules/ldap_groups/config/locales/crowdin/th.yml
#	modules/ldap_groups/config/locales/crowdin/tr.yml
#	modules/ldap_groups/config/locales/crowdin/uk.yml
#	modules/ldap_groups/config/locales/crowdin/uz.yml
#	modules/ldap_groups/config/locales/crowdin/vi.yml
#	modules/ldap_groups/config/locales/crowdin/zh-CN.yml
#	modules/ldap_groups/config/locales/crowdin/zh-TW.yml
#	modules/meeting/config/locales/crowdin/af.yml
#	modules/meeting/config/locales/crowdin/ar.yml
#	modules/meeting/config/locales/crowdin/az.yml
#	modules/meeting/config/locales/crowdin/be.yml
#	modules/meeting/config/locales/crowdin/bg.yml
#	modules/meeting/config/locales/crowdin/ca.yml
#	modules/meeting/config/locales/crowdin/ckb-IR.yml
#	modules/meeting/config/locales/crowdin/cs.yml
#	modules/meeting/config/locales/crowdin/da.yml
#	modules/meeting/config/locales/crowdin/de.yml
#	modules/meeting/config/locales/crowdin/el.yml
#	modules/meeting/config/locales/crowdin/eo.yml
#	modules/meeting/config/locales/crowdin/es.yml
#	modules/meeting/config/locales/crowdin/et.yml
#	modules/meeting/config/locales/crowdin/eu.yml
#	modules/meeting/config/locales/crowdin/fa.yml
#	modules/meeting/config/locales/crowdin/fi.yml
#	modules/meeting/config/locales/crowdin/fil.yml
#	modules/meeting/config/locales/crowdin/fr.yml
#	modules/meeting/config/locales/crowdin/he.yml
#	modules/meeting/config/locales/crowdin/hi.yml
#	modules/meeting/config/locales/crowdin/hr.yml
#	modules/meeting/config/locales/crowdin/hu.yml
#	modules/meeting/config/locales/crowdin/id.yml
#	modules/meeting/config/locales/crowdin/it.yml
#	modules/meeting/config/locales/crowdin/ja.yml
#	modules/meeting/config/locales/crowdin/ka.yml
#	modules/meeting/config/locales/crowdin/kk.yml
#	modules/meeting/config/locales/crowdin/ko.yml
#	modules/meeting/config/locales/crowdin/lt.yml
#	modules/meeting/config/locales/crowdin/lv.yml
#	modules/meeting/config/locales/crowdin/mn.yml
#	modules/meeting/config/locales/crowdin/ms.yml
#	modules/meeting/config/locales/crowdin/ne.yml
#	modules/meeting/config/locales/crowdin/nl.yml
#	modules/meeting/config/locales/crowdin/no.yml
#	modules/meeting/config/locales/crowdin/pl.yml
#	modules/meeting/config/locales/crowdin/pt-BR.yml
#	modules/meeting/config/locales/crowdin/pt-PT.yml
#	modules/meeting/config/locales/crowdin/ro.yml
#	modules/meeting/config/locales/crowdin/ru.yml
#	modules/meeting/config/locales/crowdin/rw.yml
#	modules/meeting/config/locales/crowdin/si.yml
#	modules/meeting/config/locales/crowdin/sk.yml
#	modules/meeting/config/locales/crowdin/sl.yml
#	modules/meeting/config/locales/crowdin/sr.yml
#	modules/meeting/config/locales/crowdin/sv.yml
#	modules/meeting/config/locales/crowdin/th.yml
#	modules/meeting/config/locales/crowdin/tr.yml
#	modules/meeting/config/locales/crowdin/uk.yml
#	modules/meeting/config/locales/crowdin/uz.yml
#	modules/meeting/config/locales/crowdin/vi.yml
#	modules/meeting/config/locales/crowdin/zh-CN.yml
#	modules/meeting/config/locales/crowdin/zh-TW.yml
#	modules/openid_connect/config/locales/crowdin/af.yml
#	modules/openid_connect/config/locales/crowdin/ar.yml
#	modules/openid_connect/config/locales/crowdin/az.yml
#	modules/openid_connect/config/locales/crowdin/be.yml
#	modules/openid_connect/config/locales/crowdin/bg.yml
#	modules/openid_connect/config/locales/crowdin/ca.yml
#	modules/openid_connect/config/locales/crowdin/ckb-IR.yml
#	modules/openid_connect/config/locales/crowdin/cs.yml
#	modules/openid_connect/config/locales/crowdin/da.yml
#	modules/openid_connect/config/locales/crowdin/de.yml
#	modules/openid_connect/config/locales/crowdin/el.yml
#	modules/openid_connect/config/locales/crowdin/eo.yml
#	modules/openid_connect/config/locales/crowdin/es.yml
#	modules/openid_connect/config/locales/crowdin/et.yml
#	modules/openid_connect/config/locales/crowdin/eu.yml
#	modules/openid_connect/config/locales/crowdin/fa.yml
#	modules/openid_connect/config/locales/crowdin/fi.yml
#	modules/openid_connect/config/locales/crowdin/fil.yml
#	modules/openid_connect/config/locales/crowdin/fr.yml
#	modules/openid_connect/config/locales/crowdin/he.yml
#	modules/openid_connect/config/locales/crowdin/hi.yml
#	modules/openid_connect/config/locales/crowdin/hr.yml
#	modules/openid_connect/config/locales/crowdin/hu.yml
#	modules/openid_connect/config/locales/crowdin/id.yml
#	modules/openid_connect/config/locales/crowdin/it.yml
#	modules/openid_connect/config/locales/crowdin/ja.yml
#	modules/openid_connect/config/locales/crowdin/ka.yml
#	modules/openid_connect/config/locales/crowdin/kk.yml
#	modules/openid_connect/config/locales/crowdin/ko.yml
#	modules/openid_connect/config/locales/crowdin/lt.yml
#	modules/openid_connect/config/locales/crowdin/lv.yml
#	modules/openid_connect/config/locales/crowdin/mn.yml
#	modules/openid_connect/config/locales/crowdin/ms.yml
#	modules/openid_connect/config/locales/crowdin/ne.yml
#	modules/openid_connect/config/locales/crowdin/nl.yml
#	modules/openid_connect/config/locales/crowdin/no.yml
#	modules/openid_connect/config/locales/crowdin/pl.yml
#	modules/openid_connect/config/locales/crowdin/pt-BR.yml
#	modules/openid_connect/config/locales/crowdin/pt-PT.yml
#	modules/openid_connect/config/locales/crowdin/ro.yml
#	modules/openid_connect/config/locales/crowdin/ru.yml
#	modules/openid_connect/config/locales/crowdin/rw.yml
#	modules/openid_connect/config/locales/crowdin/si.yml
#	modules/openid_connect/config/locales/crowdin/sk.yml
#	modules/openid_connect/config/locales/crowdin/sl.yml
#	modules/openid_connect/config/locales/crowdin/sr.yml
#	modules/openid_connect/config/locales/crowdin/sv.yml
#	modules/openid_connect/config/locales/crowdin/th.yml
#	modules/openid_connect/config/locales/crowdin/tr.yml
#	modules/openid_connect/config/locales/crowdin/uk.yml
#	modules/openid_connect/config/locales/crowdin/uz.yml
#	modules/openid_connect/config/locales/crowdin/vi.yml
#	modules/openid_connect/config/locales/crowdin/zh-CN.yml
#	modules/openid_connect/config/locales/crowdin/zh-TW.yml
#	modules/reporting/config/locales/crowdin/ro.yml
#	modules/reporting/config/locales/crowdin/vi.yml
#	modules/reporting/config/locales/crowdin/zh-TW.yml
#	modules/storages/config/locales/crowdin/ja.yml
#	modules/storages/config/locales/crowdin/js-ja.yml
#	modules/team_planner/config/locales/crowdin/js-fr.yml
#	modules/two_factor_authentication/config/locales/crowdin/af.yml
#	modules/two_factor_authentication/config/locales/crowdin/ar.yml
#	modules/two_factor_authentication/config/locales/crowdin/az.yml
#	modules/two_factor_authentication/config/locales/crowdin/be.yml
#	modules/two_factor_authentication/config/locales/crowdin/bg.yml
#	modules/two_factor_authentication/config/locales/crowdin/ca.yml
#	modules/two_factor_authentication/config/locales/crowdin/ckb-IR.yml
#	modules/two_factor_authentication/config/locales/crowdin/cs.yml
#	modules/two_factor_authentication/config/locales/crowdin/da.yml
#	modules/two_factor_authentication/config/locales/crowdin/de.yml
#	modules/two_factor_authentication/config/locales/crowdin/el.yml
#	modules/two_factor_authentication/config/locales/crowdin/eo.yml
#	modules/two_factor_authentication/config/locales/crowdin/es.yml
#	modules/two_factor_authentication/config/locales/crowdin/et.yml
#	modules/two_factor_authentication/config/locales/crowdin/eu.yml
#	modules/two_factor_authentication/config/locales/crowdin/fa.yml
#	modules/two_factor_authentication/config/locales/crowdin/fi.yml
#	modules/two_factor_authentication/config/locales/crowdin/fil.yml
#	modules/two_factor_authentication/config/locales/crowdin/fr.yml
#	modules/two_factor_authentication/config/locales/crowdin/he.yml
#	modules/two_factor_authentication/config/locales/crowdin/hi.yml
#	modules/two_factor_authentication/config/locales/crowdin/hr.yml
#	modules/two_factor_authentication/config/locales/crowdin/hu.yml
#	modules/two_factor_authentication/config/locales/crowdin/id.yml
#	modules/two_factor_authentication/config/locales/crowdin/it.yml
#	modules/two_factor_authentication/config/locales/crowdin/ja.yml
#	modules/two_factor_authentication/config/locales/crowdin/ka.yml
#	modules/two_factor_authentication/config/locales/crowdin/kk.yml
#	modules/two_factor_authentication/config/locales/crowdin/ko.yml
#	modules/two_factor_authentication/config/locales/crowdin/lt.yml
#	modules/two_factor_authentication/config/locales/crowdin/lv.yml
#	modules/two_factor_authentication/config/locales/crowdin/mn.yml
#	modules/two_factor_authentication/config/locales/crowdin/ms.yml
#	modules/two_factor_authentication/config/locales/crowdin/ne.yml
#	modules/two_factor_authentication/config/locales/crowdin/nl.yml
#	modules/two_factor_authentication/config/locales/crowdin/no.yml
#	modules/two_factor_authentication/config/locales/crowdin/pl.yml
#	modules/two_factor_authentication/config/locales/crowdin/pt-BR.yml
#	modules/two_factor_authentication/config/locales/crowdin/pt-PT.yml
#	modules/two_factor_authentication/config/locales/crowdin/ro.yml
#	modules/two_factor_authentication/config/locales/crowdin/ru.yml
#	modules/two_factor_authentication/config/locales/crowdin/rw.yml
#	modules/two_factor_authentication/config/locales/crowdin/si.yml
#	modules/two_factor_authentication/config/locales/crowdin/sk.yml
#	modules/two_factor_authentication/config/locales/crowdin/sl.yml
#	modules/two_factor_authentication/config/locales/crowdin/sr.yml
#	modules/two_factor_authentication/config/locales/crowdin/sv.yml
#	modules/two_factor_authentication/config/locales/crowdin/th.yml
#	modules/two_factor_authentication/config/locales/crowdin/tr.yml
#	modules/two_factor_authentication/config/locales/crowdin/uk.yml
#	modules/two_factor_authentication/config/locales/crowdin/uz.yml
#	modules/two_factor_authentication/config/locales/crowdin/vi.yml
#	modules/two_factor_authentication/config/locales/crowdin/zh-CN.yml
#	modules/two_factor_authentication/config/locales/crowdin/zh-TW.yml
#	modules/wikis/config/locales/crowdin/af.yml
#	modules/wikis/config/locales/crowdin/ar.yml
#	modules/wikis/config/locales/crowdin/az.yml
#	modules/wikis/config/locales/crowdin/be.yml
#	modules/wikis/config/locales/crowdin/bg.yml
#	modules/wikis/config/locales/crowdin/ca.yml
#	modules/wikis/config/locales/crowdin/ckb-IR.yml
#	modules/wikis/config/locales/crowdin/cs.yml
#	modules/wikis/config/locales/crowdin/da.yml
#	modules/wikis/config/locales/crowdin/de.yml
#	modules/wikis/config/locales/crowdin/el.yml
#	modules/wikis/config/locales/crowdin/eo.yml
#	modules/wikis/config/locales/crowdin/es.yml
#	modules/wikis/config/locales/crowdin/et.yml
#	modules/wikis/config/locales/crowdin/eu.yml
#	modules/wikis/config/locales/crowdin/fa.yml
#	modules/wikis/config/locales/crowdin/fi.yml
#	modules/wikis/config/locales/crowdin/fil.yml
#	modules/wikis/config/locales/crowdin/fr.yml
#	modules/wikis/config/locales/crowdin/he.yml
#	modules/wikis/config/locales/crowdin/hi.yml
#	modules/wikis/config/locales/crowdin/hr.yml
#	modules/wikis/config/locales/crowdin/hu.yml
#	modules/wikis/config/locales/crowdin/id.yml
#	modules/wikis/config/locales/crowdin/it.yml
#	modules/wikis/config/locales/crowdin/ja.yml
#	modules/wikis/config/locales/crowdin/ka.yml
#	modules/wikis/config/locales/crowdin/kk.yml
#	modules/wikis/config/locales/crowdin/ko.yml
#	modules/wikis/config/locales/crowdin/lt.yml
#	modules/wikis/config/locales/crowdin/lv.yml
#	modules/wikis/config/locales/crowdin/mn.yml
#	modules/wikis/config/locales/crowdin/ms.yml
#	modules/wikis/config/locales/crowdin/ne.yml
#	modules/wikis/config/locales/crowdin/nl.yml
#	modules/wikis/config/locales/crowdin/no.yml
#	modules/wikis/config/locales/crowdin/pl.yml
#	modules/wikis/config/locales/crowdin/pt-BR.yml
#	modules/wikis/config/locales/crowdin/pt-PT.yml
#	modules/wikis/config/locales/crowdin/ro.yml
#	modules/wikis/config/locales/crowdin/ru.yml
#	modules/wikis/config/locales/crowdin/rw.yml
#	modules/wikis/config/locales/crowdin/si.yml
#	modules/wikis/config/locales/crowdin/sk.yml
#	modules/wikis/config/locales/crowdin/sl.yml
#	modules/wikis/config/locales/crowdin/sr.yml
#	modules/wikis/config/locales/crowdin/sv.yml
#	modules/wikis/config/locales/crowdin/th.yml
#	modules/wikis/config/locales/crowdin/tr.yml
#	modules/wikis/config/locales/crowdin/uk.yml
#	modules/wikis/config/locales/crowdin/uz.yml
#	modules/wikis/config/locales/crowdin/vi.yml
#	modules/wikis/config/locales/crowdin/zh-CN.yml
#	modules/wikis/config/locales/crowdin/zh-TW.yml
2026-04-11 13:33:28 +02:00
Ivan Kuchin fb0bfb7f6d differentiate message when work package was created not as a child 2026-04-07 19:54:01 +02:00
Oliver Günther f695883e27 Properly authorize bulk actions
https://community.openproject.org/work_packages/73345
2026-03-23 14:33:08 +01:00
Klaus Zanders 33ea76f6c5 Manually add escaping to render json calls 2026-03-23 10:06:43 +01:00
Oliver Günther 4d731dcab6 Replace raw and explicit html_safe calls 2026-03-20 09:49:10 +01:00
Klaus Zanders 1fd5469c33 Merge branch 'dev' into merge-release/17.1-20260223152205 2026-02-23 16:25:43 +01:00
OpenProject Actions CI c779e8fc67 Merge branch 'release/17.0' into release/17.1 2026-02-23 14:29:39 +00:00
Kabiru Mwenja c406e7c5c3 Scope journal lookup to work package in activities tab
https://community.openproject.org/wp/72390
https://community.openproject.org/wp/72393
2026-02-23 16:33:31 +03:00
Klaus Zanders 516c42fcf7 Correctly handle error cases for activity tab controller 2026-02-09 15:08:07 +01:00
Klaus Zanders c2bc836ea1 Consistently load work packages via visible scope 2026-02-09 15:07:49 +01:00
Klaus Zanders 5ffcb63e05 Remove GET route for bulk delete 2026-02-02 11:50:26 +01:00
Kabiru Mwenja 0e5e6e51cf Implementation/71141 remove work package activity tab lazy pagination feature flag (#21817)
https://community.openproject.org/work_packages/71141
2026-01-30 14:06:12 +03:00
Kabiru Mwenja 02b1682559 Set AT limit explicity to 20 items 2025-11-13 13:49:46 +03:00
Henriette Darge 655756631f [67007] Render the WP full view from rails (#20109)
* Create a FullView::CopyComponent for WorkPackages which is routed from rails

* Remove angular splitCopy route and component as it was overwritten by the angular fullCopy route for quite some time already and nobody complained. So we decided to remove the splitCopy completely

* Create FullView::CreateComponent for WorkPackages which is now routed from rails instead of Angular

* First draft of implementing the FullView route for WorkPackages from rails

* Pass correct tab from the URL to the FullView::ShowComponent

* Do a hard reload to "create" route when we are not routed from Angular

* Adapt routing spec to new WorkPackage routes and to some fine-tuning with the WP routes

* Show correct tab in WP Full view and change URL when clicking a tab entry

* Adapt to new rails based routing

* Fix some routes and redirects

* Make sure, the split screen stil renders correctly

* Remove back button from WP full view

* Fix routing issues

* Start fixing specs

* Attempt to override the browser history to be able to use browser back

* Use helper function to build new WP url string

* Adapt spec that now partially renders backend toasts

* Remove ability to move to fullscreen

Theoretically, we can re-add it by posting to some form endpoint, but
not worth it for the first iteration

* Disable cache-control on angular routed pages, so back links work

* Fix double click to fullscreen

* Adapt navigation and title setting

* Let WP breadcrumb to a hard reload instead of Angular transition

* Redirect when the WP route is incomplete (this is the attempt to re-implement an angular functionality)

* Navigate with Turbo when double clicking a card

* Adapt onboarding tour to new hard reload when switching to WP full view

* Fix some specs

* Fix more tests

* Hide Overview tab on FullView

* Correct check for incomplete routes

* Do a hard refresh when coming from slpit screen to full view

* Fix notification navigation

* Adapt attachment spec as the tab switch cannot be done anymore while dragging

* Fix more tests

* Please rubocop and fix more tests

* Attempt to fix navigation_spec

* Add debian_base for pullpreview

---------

Co-authored-by: Oliver Günther <mail@oliverguenther.de>
2025-11-03 09:02:16 +01:00
Kabiru Mwenja 00864f158a bug/66552 Add filter support to activities tab paginator for better page distribution (#20733)
Implements `:only_comments` and `:only_changes` filters to prevent paginating journals that don't match the active filter, reducing unnecessary HTTP requests during lazy loading.

Use SQL-based heuristic to filter journals with changes at database level

  * Include journals with: initial version, attachments, custom fields, file links, cause metadata, or attribute changes
  * Compare work_package_journals columns with immediate predecessor to detect data changes _(handles non-sequential journal versions)_

https://community.openproject.org/wp/66552
2025-10-27 10:41:14 +03:00
Christophe Bliard eae369ec1f [68402] Correctly recompute duration for automatic work packages with children
https://community.openproject.org/wp/68402

There was a bug where when switching to manual mode and clearing the
dates, the controller would also clear the duration and consider it as
being done by the user (touched field). Then when switching to automatic
mode, before calling the SetAttributesService, start date and finish
date would be discarded because the work package is in automatic mode.

The SetAttributesService would then think that the duration being empty
was done by the user, and would then also unset the finish date. That
lead to the incorrect display of the dates and duration in the date
picker: they would appear as empty instead of having the dates inherited
from the child.

Fix is to also discard the duration if the work package is automatically
scheduled and has children.
2025-10-17 15:57:40 +02:00
Kabiru Mwenja 0731145265 Defer loading of emoji (re)actions menu for improved performance (#20580)
https://community.openproject.org/wp/68046
2025-10-10 15:42:04 +03:00
Kabiru Mwenja 22b139c8f4 Merge branch 'dev' into merge-release/16.5-20251010123254 2025-10-10 15:36:38 +03:00
Kabiru Mwenja fe5ced5130 Defer loading of journal items actions menu for improved performance (#20566)
https://community.openproject.org/wp/68046
2025-10-10 10:42:19 +03:00
Kabiru Mwenja 79404866ce Add feature flag for activity tab lazy pagination 2025-10-08 19:10:41 +03:00
Kabiru Mwenja 790f9a44d6 Extract work package activity tab pagination 2025-10-08 15:42:46 +03:00
Kabiru Mwenja 13853fdedd Re-initialize pagination JIT for tab replacement
Pick up any changes to sorting or filtering preferences
2025-10-08 15:42:44 +03:00
Kabiru Mwenja 79673c5a89 Support paginated deep linking of comments 2025-10-08 15:42:43 +03:00
Kabiru Mwenja 2484b48525 Switch from infinite scrolling to managed lazy loaded pages
Akin to lazy frames but with better intersection threshold control
2025-10-08 15:42:42 +03:00
Kabiru Mwenja c1d070ab6f Extract journal_sorting.{asc?,desc?} inquiry 2025-10-08 15:42:40 +03:00
Kabiru Mwenja aabd15be15 Abort infinite scrolling for 1 page collections 2025-10-08 15:42:39 +03:00
Kabiru Mwenja 447a45b575 Add infinite scrolling stimulus controller 2025-10-08 15:42:38 +03:00
Kabiru Mwenja 2468d4d98a Set up POC for infinite scrolling on AT (Messy Commit!) 2025-10-08 15:42:38 +03:00
Alexander Brandon Coles f15be6e07f Freeze string literals in app/controllers
rubocop -A --only Style/FrozenStringLiteralComment,Layout/EmptyLineAfterMagicComment,Style/RedundantFreeze app/controllers
2025-07-18 17:51:00 +01:00
Alexander Brandon Coles 6892ac9d65 Merge branch 'dev' into merge-release/16.2-20250718035236 2025-07-18 08:59:00 +01:00
Kabiru Mwenja 33d3953701 bug/63545 When editing a comment in the activity tab and polling occurs, the form can be force closed (#19507)
The activities tab polling mechanism updates newly updated journals, based on the last update timestamp. In case an attachment is added, or the journal is updated in any other places- the UI item would be updated\ on the next poll, overriding the edit form.

This commit adds an exclusion for any forms that are in "edit" state- it does not yet take into account conflict resolution.

https://community.openproject.org/wp/63545
https://community.openproject.org/wp/65680
2025-07-15 14:46:29 +03:00
Christophe Bliard ab4688e47e [65303] Display non-progress errors in a top banner
https://community.openproject.org/wp/65303

When there are errors on the work package when saving the progress
tracking values, the modal is rendered again with those errors so that
the invalid fields are highlighted and have a validation error message.

When the error is external to the progress modal, for instance a
mandatory custom field or an invalid project phase, it is displayed in a
top banner with a flash message. Before the error was not displayed at
all, leaving users confused as why the progress values could not be
saved.
2025-07-15 08:27:33 +02:00
Christophe Bliard c033715f51 refactor: use more conventional way to render the progress modal
Render it using our component wrapper and
`update_via_turbo_stream(method: "morph")`. Move `<turbo-frame>` of
progress modal from component to the view to avoid double rendering of
the turbo-frame tag.

Inspired by PR #18152 where a similar was done for date picker modal.
2025-07-15 08:27:10 +02:00
Christophe Bliard e8bdff0cbc [65303] Display non-progress errors in a top banner
https://community.openproject.org/wp/65303

When there are errors on the work package when saving the progress
tracking values, the modal is rendered again with those errors so that
the invalid fields are highlighted and have a validation error message.

When the error is external to the progress modal, for instance a
mandatory custom field or an invalid project phase, it is displayed in a
top banner with a flash message. Before the error was not displayed at
all, leaving users confused as why the progress values could not be
saved.
2025-07-03 12:15:13 +02:00
Christophe Bliard 029864a859 refactor: use more conventional way to render the progress modal
Render it using our component wrapper and
`update_via_turbo_stream(method: "morph")`. Move `<turbo-frame>` of
progress modal from component to the view to avoid double rendering of
the turbo-frame tag.

Inspired by PR #18152 where a similar was done for date picker modal.
2025-07-03 11:26:20 +02:00
Dombi Attila 2bb3002748 Use a preview action for the work package datepicker.
This helps differentiating the form when it is initially rendered, or
due to a modification. This distinction is important to decide whether
the live_messages should be rendered or not. Initial rendering of the
dialog should not display live messages, as nothing has changed.
2025-07-02 01:21:19 +03:00
Dombi Attila ef35ec7ca9 Remove unecessary refresh attribute and turbo stream module from date picker controller. 2025-07-02 01:21:14 +03:00
Dombi Attila 8d786d86a7 Replace angular tags instead of ignoring them during the morphing process of the work package dialog. 2025-07-02 01:21:12 +03:00