2312 Commits

Author SHA1 Message Date
Alexander Brandon Coles 86e40ffffe Adapt specs to capybara_accessible_selectors 0.16
Refactors the custom `:list`/`:list_item` selectors onto CAS's
`add_role_selector` and drops the now-native `Capybara::Node::Simple#role`
hack. `:list_item` resolves the listitem role, so specs matching
non-listitem `<li>` are updated (`have_row` for the custom field table,
presentation dividers via CSS).

CAS 0.16 also resolves role selectors by computed role and accessible
name, which our CSS-styled tables and Primer menus do not expose through
plain markup. Affected feature specs switch to robust locators:
Capybara's `:table_row`, the FullCalendar `data-date`, and the action
menu's real accessible name ("Edit status").

The `:columnheader` `colindex` filter lost its off-by-one offset and now
uses the true 1-based `th` position. Also fixes Webhooks `RowComponent`
spec capitalization.
2026-05-29 20:41:25 +02:00
Ivan Kuchin f6e073f0a1 [#74769] Remove portfolio_models feature flag
https://community.openproject.org/wp/74769
2026-05-28 13:53:08 +02:00
Alexander Brandon Coles 2935a9386f Stabilize cancel editing home navigation
Wait for the Turbo visit to finish before the Selenium example resets.
2026-05-27 00:33:13 +02:00
Alexander Brandon Coles c776be17cc Make WP query history filter checks idempotent
Turbo can restore the query filter pane as either open or closed during
browser history traversal. Use an idempotent helper before asserting
restored filters so the spec checks the query state instead of depending
on the current pane visibility.
2026-05-26 23:17:42 +02:00
Alexander Brandon Coles ab3b74dbf2 Patch Puma socket timeout failure 2026-05-26 17:18:05 +02:00
Tomas Hykel 948fa43321 chore: Remove feature flag for project-based work package identifiers 2026-05-25 17:45:06 +02:00
Oliver Günther 5bf27bb868 Merge remote-tracking branch 'origin/release/17.4' into dev 2026-05-05 12:29:43 +02:00
ulferts 222639f8d4 include filter working with portfolios and programs 2026-04-30 10:18:09 +02:00
Kabiru Mwenja 4dfdd6ec5d Drop numeric pins on auxilary links 2026-04-30 11:08:48 +03:00
Kabiru Mwenja 2f25a7c69f Merge pull request #22902 from opf/implementation/74308-use-displayid-in-work-package-context-menus-and-list
Use displayId in WP context menus, list toolbar, row click, cards
2026-04-29 16:51:46 +03:00
Kabiru Mwenja 41b57c0b2b Add :semantic project factory trait, tighten WP context menu spec (#22977)
Add :semantic project factory trait and tighten WP context menu spec

Follow-up to PR #22975. The reviewer correctly observed that
upcasing the factory-default identifier (e.g. "MYPROJECT_NO_17") puts
the project into a state Projects::Identifier validators would reject:
14 chars exceeds SEMANTIC_IDENTIFIER_MAX_LENGTH = 10.

Two improvements:

1. Project factory gains a :semantic trait that yields a deterministic
   uppercase identifier matching the semantic format constraints
   (\\A[A-Z][A-Z0-9_]*\\z, max 10 chars). Future specs that create their
   own project per example in semantic mode can use this trait directly
   instead of mutating identifiers post hoc.

2. Tighten the WP context menu shared example: replace
   identifier.upcase with "P#{project.id}".first(10), which satisfies
   both the route constraint and the production length constraint.
   The shared example still mutates the existing project rather than
   using the trait because consumers use shared_let(:project),
   evaluated once at suite setup before per-example with_settings:
   activates semantic mode. A comment documents this and points new
   readers at the trait.
2026-04-29 09:22:10 +03:00
Kabiru Mwenja 8e86ce0f2f Fix context menu spec to use uppercase project identifier in semantic mode
In semantic mode, project identifiers are uppercase (e.g. PROJ-42).
The shared example created a project via factory which generates a
lowercase slug, causing the WP semantic identifier to be lowercase and
fail the ID_ROUTE_CONSTRAINT (/\d+|[A-Z][A-Z0-9_]*-\d+/).

- Upcase the project identifier before allocating the semantic WP id
- Assert that semantic mode is actually active (via with_settings +
  with_flag metadata) so misconfigured test contexts fail clearly
- Revert tab_component_spec back to uppercase MYPROJ (correct for
  semantic mode) after an earlier incorrect attempt to go lowercase

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 21:47:30 +03:00
Kabiru Mwenja fd83913475 Sync on row -checked class before clicking toolbar info icon
Capybara's .click returns before the JS click handler has finished
writing wpTableFocus.focusedWorkPackage and propagating the selection
state to the DOM. Asserting the row carries the -checked class first
guarantees both pieces of state are settled before the toolbar click,
which avoids a race where the toolbar reads a stale focus.
2026-04-28 15:58:15 +03:00
Kabiru Mwenja 993e7dd492 Drop redundant allocate_and_register_semantic_id calls in semantic-nav specs
The after_create hook on WorkPackage (semantic_identifier.rb:63) already
allocates the semantic identifier when Setting::WorkPackageIdentifier.semantic?
is true. with_settings: stubs the setting before let materialization, so
creating the WP via the lazy let is enough — the explicit call was burning
a second sequence and inserting orphaned alias rows.

Also covers spec/features/work_packages/table/semantic_id_navigation_spec.rb
which had the same redundancy from PR 22733.
2026-04-28 15:58:02 +03:00
Kabiru Mwenja a16e899189 Use retry_block for clipboard spy poll in nav follow-ups spec
Replaces the hand-rolled Timeout.timeout + sleep loop with the project's
idiomatic retry_block helper. Drops the dead `expect(page).to have_css("body")`
sync line. Adds a comment explaining why we keep the navigator.clipboard
spy rather than reusing have_message_copied_to_clipboard (the matcher
only inspects the flash DOM and can't distinguish numeric vs semantic ids).
2026-04-28 15:52:38 +03:00
Kabiru Mwenja 058c344a90 Fix "null" href on row's Open details view anchor
The split-view branch of `UiStateLinkBuilder.build` was passing the tab
under the param name `tab`, but the underlying ui-router state declares
the parameter as `:tabIdentifier` (split-view-routes.template.ts).
Without a matching parameter, `$state.href(...)` returns null, which
gets coerced to the literal string "null" when assigned to `a.href`.

Click navigation worked because `WorkPackageStateLinksHandler` reads
the data attributes and routes via the state machine, ignoring the
href entirely. But middle-click, "Open in new tab", and the browser
status-bar URL on hover all surface the broken href.

Add a feature spec asserting the row's "Open details view" anchor
href contains the semantic identifier and is not "null".
2026-04-28 14:41:04 +03:00
Oliver Günther f4da89af8b Add stable condition to ensure work package has updated 2026-04-28 10:18:34 +02:00
Kabiru Mwenja 678eeb285c Fix rubocop findings in navigation follow-ups spec 2026-04-28 09:21:46 +03:00
Kabiru Mwenja 49a82738b0 Use displayId in WP context menu, list toolbar, row click, and cards
Covers #74308 (context menus — "Open fullscreen" link and Copy link),
#73982 (Copy link to clipboard), #74309 (list toolbar info icon),
#74310 (plain row click while split view is open), and #74312 (card ID
link href). Each site previously passed the numeric primary key into URL
construction or routing state transitions; switched to the semantic
displayId via direct reference (wp.displayId) or the resolveRoutingId
helper where only a numeric id was in scope.

Feature specs cover the semantic-mode behaviour for every site. Classic
mode is a behavioural no-op in each case (displayId collapses to id) so
those contexts are intentionally omitted.
2026-04-28 09:21:45 +03:00
Kabiru Mwenja d1dfa8e92e Merge branch 'dev' into implementation/73797-use-displayid-in-work-package-urls
Integrates PR 22674 (remove ui-router from Calendars and TeamPlanner).
Four files had navigation-call conflicts between the ui-router removal
and this branch's displayId-in-URL work.

Resolution strategy: take dev's ui-router-free structure (Turbo navigation
via window.location / Turbo.visit, URL-path gates, hasUiRouterContext
branching) and apply the displayId invariant wherever a work-package URL
segment is constructed.

- op-work-packages-calendar.service.ts: openSplitView/openFullView now
  funnel through dev's visitSplitViewLink + pathHelper.workPackagePath,
  wrapping the incoming id with resolveRoutingId at the service boundary.
- wp-calendar.component.ts: eventClick uses the HAL resource already in
  scope; split-view call passes wp.id! (service resolves), full-view href
  uses wp.displayId directly.
- wp-single-card.component.ts: selection regex widened from /(\d+)/ to
  /([^/?#]+)/ to match semantic identifiers; both uiRouter and URL
  comparisons check id OR displayId.
- wp-view-context-menu.directive.ts: 'relations' case + buildItems()
  splitViewHref both use this.workPackage.displayId for URL segments.
2026-04-23 13:36:10 +03:00
Henriette Darge bfa4c782c6 Merge branch 'dev' into code-maintenance/73671-remove-ui-router-from-calendars 2026-04-22 10:36:18 +02:00
Henriette Darge 5f98ee2f36 Merge pull request #22814 from opf/bug/59732-list-is-scrollable-even-if-there-is-only-1-item
[59732] List is scrollable even if there is only 1 item
2026-04-22 10:20:39 +02:00
Henriette Darge 3dd3d91081 Adapt filter component to new ngSelect syntax 2026-04-22 08:01:45 +02:00
Kabiru Mwenja 491f936138 Merge branch 'dev' into implementation/73797-use-displayid-in-work-package-urls 2026-04-21 18:08:01 +03:00
Kabiru Mwenja e9ab79dcfe Merge branch 'feature/73717-adapt-work-package-lists-for-project-based-semantic-work-package-identifiers' into implementation/73797-use-displayid-in-work-package-urls
# Conflicts:
#	frontend/src/app/shared/components/fields/display/field-types/work-package-display-field.module.ts
2026-04-21 17:51:10 +03:00
Tobias Dillmann a2847a00e8 [#73104] Use correct expectation for empty, but settable field 2026-04-21 13:55:12 +02:00
Kabiru Mwenja 234a870060 Merge pull request #22704 from opf/feature/73716-adapt-work-package-show-view-for-project-based-semantic-work-package-identifiers
Adapt work package show view for semantic identifiers
2026-04-21 13:52:23 +03:00
Henriette Darge 1225a30fca Adapt tests to removed uiRouter 2026-04-21 09:15:05 +02:00
Oliver Günther 2898a1d0ff Delete dialog primer 2026-04-19 21:10:41 +02:00
Kabiru Mwenja 89c4191038 Fix WP table click navigation to use semantic ID in URL
Clicking a semantic ID link (e.g. PROJ-42) in the work package table
navigated to the numeric ID URL (/work_packages/42) instead of the
semantic one (/work_packages/PROJ-42). The href was correct but the
click handler (WorkPackageStateLinksHandler) read data-work-package-id
(the numeric PK) and used it for navigation.

Add data-routing-id to link elements carrying the semantic identifier.
The click handler now reads this attribute and flows it through the
stateLinkClicked event so wp-list-view uses it for URL construction
while keeping the numeric PK for selection and focus state.
2026-04-16 11:21:54 +03:00
Kabiru Mwenja 9c757cf194 Keep parent_id route constraint numeric-only
parent_id is consumed by parseInt() in wp-create.component.ts, which
returns NaN for semantic identifiers like "PROJ-42". This silently
breaks parent assignment when creating child work packages.

Revert the route constraint back to [0-9]+ since parent_id is a
machine-level concern used in API calls, not a display identifier.

Add a feature spec with semantic mode enabled to verify the URL uses
the numeric PK and the parent relationship is set correctly.
2026-04-15 18:59:43 +03: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 3c3ccb06e1 add flash message expectation when adding child work packages 2026-04-07 20:23:52 +02:00
Alexander Brandon Coles 88a9d798ad Merge pull request #22219 from opf/code-maintenance/remove-zone.js
[#72834] Migrate Angular frontend to Zoneless
2026-04-06 15:26:25 +01:00
Alexander Brandon Coles 4ad434ff8d Fix inline-edit portal CD in zoneless mode
Adds an `errorsChanged$` subject to `HalResourceEditFieldHandler` and
subscribes in `EditFormPortalComponent` to call `detectChanges()` when
errors change. Forces `detectChanges()` after portal initialisation in
`EditingPortalService` and after error field activation in `EditForm`.
Overrides `focusOnFirstError()` in `EditFormComponent` to call
`detectChanges()` before querying the DOM for the first error field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 14:20:27 +01:00
Mir Bhatia 18ae3b1ca6 Update specs to use new field name 2026-04-01 17:08:54 +02:00
Henriette Darge d288a61b83 Make the user a member, otherwise they will not be allowed to log time in that project 2026-03-31 10:09:08 +02:00
Klaus Zanders b66b6ddf87 Fix flaky spec when activating switching WP type 2026-03-22 17:35:03 +01:00
ulferts a847296c8a Merge remote-tracking branch 'origin/dev' into feature/72227-sprints-included-in-api-get-sprint-and-sprint-on-work-package-resource 2026-03-18 22:03:40 +01:00
ulferts 1240b066c3 work package creation and update including backlogs properties 2026-03-11 13:24:32 +01:00
Alexander Brandon Coles 2c3b50cfa0 Stabilize reminders spec 2026-03-10 15:26:39 -03:00
Alexander Brandon Coles 0a32be066b Stabilize additional out-of-hours feature specs 2026-03-10 15:26:39 -03:00
Alexander Brandon Coles 801984e8b9 Stabilize time-sensitive feature specs
Use shared_let for frozen feature spec times
2026-03-10 15:26:39 -03:00
Dombi Attila 60e747be2b Apply manage_sprint_items permissions on the work packages model and update specs.
- Do not remove the assign_versions permission anymore, it still has
purpose in the context of updating work packages.
- Update backlog related specs.
2026-03-03 15:40:36 +02:00
Henriette Darge 356c4f9bca Merge pull request #22082 from opf/bug/72262-replace-eur-with-in-seed-data-and-harmonize-widgets
[72262] Replace EUR with € in cost currency setting default and harmonize widgets
2026-02-25 14:17:21 +01:00
Henriette Darge 614f8ecc8d Apply negative currency format and change default from "EUR" to "€" 2026-02-25 09:54:56 +01:00
Henriette Darge 2b31d05f0a Merge pull request #21612 from opf/code-maintenance/68481-remove-new-project-overview-feature-flag
[#68481] Remove new project overview feature flag
2026-02-24 12:20:13 +01:00
Henriette Darge 9409fa9730 Adapt tests to new project overview title 2026-02-24 11:46:50 +01:00
Henriette Darge 0fbb221c33 Merge remote-tracking branch 'origin/dev' into code-maintenance/68481-remove-new-project-overview-feature-flag 2026-02-24 10:39:21 +01:00
Alexander Brandon Coles a6ae097715 Merge branch 'dev' into merge-release/17.1-20260223125632 2026-02-23 11:45:18 -03:00