Skip to content

Feature/COMMS-1025: Labels administration - #25394

Merged
akabiru merged 23 commits into
devfrom
implementation/comms-1025-label-admin-listing
Sep 22, 2026
Merged

akabiru merged 23 commits into
devfrom
implementation/comms-1025-label-admin-listing

Conversation

@akabiru

@akabiru akabiru commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

https://community.openproject.org/wp/COMMS-1025
https://community.openproject.org/wp/COMMS-1026

Adds the labels administration page behind the work_package_labels flag: dialogs to create, rename and delete labels.

Deleting a label removes its labelings directly and does not journal the affected work packages; journalling will be handled in #25320. The "Used in" count stays plain text until the label filter from COMMS-1014 exists (tracked in COMMS-1037).

list-with-row-menu create-dialog rename-duplicate-error delete-dialog search-matches search-no-matches

@akabiru akabiru self-assigned this Sep 16, 2026
@akabiru
akabiru added this pull request to stack #25396 September 16, 2026 19:09
@akabiru
akabiru removed this pull request from stack #25396 September 17, 2026 05:49
@akabiru
akabiru force-pushed the implementation/comms-1025-label-admin-listing branch from 3345955 to ed03c50 Compare September 17, 2026 05:52
@akabiru
akabiru changed the base branch from implementation/comms-1025-labels-feature-flag to implementation/comms-1025-labels-services-and-contracts September 17, 2026 05:52
@akabiru
akabiru added this pull request to stack #25402 September 17, 2026 05:52
@akabiru
akabiru force-pushed the implementation/comms-1025-label-admin-listing branch from ed03c50 to 204c1d4 Compare September 17, 2026 06:21
@akabiru
akabiru force-pushed the implementation/comms-1025-label-admin-listing branch from 204c1d4 to 07d5c3b Compare September 17, 2026 07:28
Base automatically changed from implementation/comms-1025-labels-services-and-contracts to dev September 17, 2026 12:26
Admins get a paginated, searchable list of all labels with their usage
and can create, rename and delete labels from dialogs. The page sits
behind the work_package_labels flag and is admin-only.
The list is a BorderBox table as the FND-5 epic specifies, the delete
dialog names how many work packages are affected, name errors read as
full sentences, and creating a label lands on the page that contains it.
Walks through navigation, create, rename, delete, search with
pagination, and the flag-off case in the browser.
Long label names truncate instead of overflowing the row, the page
lookup after creating a label compares case-insensitively in SQL only,
and the dialog, form and delete-failure paths gain specs.
Cuprite in CI did not observe the stream-rendered event within the
wait window; waiting for network idle after typing is what the other
admin search specs do.
@akabiru
akabiru force-pushed the implementation/comms-1025-label-admin-listing branch from dba38fe to 80ce9f7 Compare September 17, 2026 12:26
@akabiru
akabiru marked this pull request as ready for review September 17, 2026 13:10
Component specs now use the test selector helpers, the accessible
role selectors and a new :async_dialog_trigger selector instead of raw
DOM queries, and stop auditing class lists and Stimulus wiring.
Renaming can move a label across an alphabetical page boundary, and
landing back on page one hid the label the admin just renamed. Update
now shares the page computation create already used.
The create and rename dialogs carried a state flag that only ever
mirrored whether the label was persisted, and the form component
accepted it unvalidated. Both now read the record instead. The form
component spec builds an unsaved label for the failed-create render,
since a stubbed one reports itself persisted and rendered the rename
form.
Checking the index body for the word "Labels" passed on the page
title alone. Both flag states now inspect the sidebar anchors.
The name field is required, so the browser blocked the submit before
any request and the assertions passed without exercising the server.
The request spec covers the blank-name rejection.
Cuprite fires no input event when filling a field with an empty
string, so the live search never reloaded and the example failed
deterministically. The clear button dispatches the input event the
filter form listens for.
Authorization, flag gating on mutations, the search pagination link
target, page redirects after create and rename, and the delete failure
branch stay; user flows live in the feature spec.
@akabiru
akabiru requested review from a team and brunopagno September 17, 2026 14:57
@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Deploying openproject with ⚡ PullPreview

Field Value
Latest commit 6c70c00
Job deploy
Status ✅ Deploy successful
Preview URL https://pr-25394-comms-1025-label-ip-157-90-246-145.my.opf.run:443

View logs

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.

🟡 Changes recommended

Address the unsafe HTML interpolation and preserve the selected page size in the index URL.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds feature-flagged administration for work package labels, including listing, searching, pagination, creation, renaming, and deletion.

Changes:

  • Added routes, navigation, feature gating, controllers, forms, and translations.
  • Added label administration components and dialogs.
  • Added request, feature, model, and component coverage.

Review findings:

  • Critical: Escape label.name before interpolating it into the HTML-safe deletion confirmation.
  • Moderate: Preserve per_page in the pushed index URL.
File summaries
File Description
spec/support/finders/test_selector_finders.rb Request-spec selector support
spec/support/capybara/async_dialog_selector.rb Async dialog selectors
spec/requests/admin/labels_spec.rb Request behavior coverage
spec/models/label_spec.rb Pagination coverage
spec/features/admin/labels/manage_spec.rb Label management workflows
spec/components/admin/labels/table_component_spec.rb Table rendering coverage
spec/components/admin/labels/sub_header_component_spec.rb Search and create controls
spec/components/admin/labels/row_component_spec.rb Row actions coverage
spec/components/admin/labels/list_component_spec.rb List and empty states
spec/components/admin/labels/form_component_spec.rb Form coverage
spec/components/admin/labels/dialog_component_spec.rb Create and rename dialogs
spec/components/admin/labels/delete_dialog_component_spec.rb Delete confirmation coverage
config/routes.rb Label administration routes
config/locales/en.yml Label administration translations
config/initializers/menus.rb Feature-flagged admin menu
app/views/admin/labels/index.html.erb Labels administration page
app/models/label.rb Usage counts and pagination
app/forms/admin/labels/form.rb Label form definition
app/controllers/concerns/labels/labels_feature.rb Feature flag enforcement
app/controllers/admin/labels_controller.rb Administration actions
app/components/admin/labels/table_component.rb Labels table
app/components/admin/labels/sub_header_component.rb Subheader behavior
app/components/admin/labels/sub_header_component.html.erb Subheader rendering
app/components/admin/labels/row_component.rb Label row rendering
app/components/admin/labels/list_component.rb List behavior
app/components/admin/labels/list_component.html.erb List and empty states
app/components/admin/labels/form_component.rb Form behavior
app/components/admin/labels/form_component.html.erb Form rendering
app/components/admin/labels/dialog_component.rb Dialog behavior
app/components/admin/labels/dialog_component.html.erb Create and rename dialogs
app/components/admin/labels/delete_dialog_component.rb Delete dialog behavior
app/components/admin/labels/delete_dialog_component.html.erb Delete confirmation rendering
Review details

Suppressed comments (1)

app/controllers/admin/labels_controller.rb:54

  • The pushed index URL drops per_page, even though the search request uses it to render the current page size. After searching, reloading or navigating back to the pushed URL silently resets the user's selected page size to the default. Preserve per_page in the permitted parameters, consistent with the existing index controllers (app/controllers/users_controller.rb:481 and app/controllers/placeholder_users_controller.rb:199).
      turbo_streams << turbo_stream.push_state(url_for(params.permit(:controller, :filters).merge(action: "index")))
  • Files reviewed: 32/32 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/components/admin/labels/delete_dialog_component.html.erb

@brunopagno brunopagno 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.

All good from my side. Played around a bit on pull preview and it's looking quite nice 🎉

Only remark, I find the usage of Arel to obfuscate a bit the code. I'd prefer to avoid it, but I think it's okay in the context it's being used.

The empty and no-matches states stay inside the table so the column headers remain visible.
Drops the single-use Arel scope; the redirect target reads as one comparison against the case-insensitive listing order.
@akabiru akabiru added the ai: Collaborative 💻 AI generated a substantial part of the code; A human reviewed and understands every line. label Sep 22, 2026
@github-actions github-actions Bot removed the ai: Collaborative 💻 AI generated a substantial part of the code; A human reviewed and understands every line. label Sep 22, 2026
@akabiru

akabiru commented Sep 22, 2026 •

Copy link
Copy Markdown
Member Author

🚧 Failing test is a known issue that is fixed in #25519

@akabiru
akabiru merged commit af80783 into dev Sep 22, 2026
18 of 21 checks passed
@akabiru
akabiru deleted the implementation/comms-1025-label-admin-listing branch September 22, 2026 13:51
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants