Skip to content

Feat/settings search - #26098

Open
machisuji wants to merge 12 commits into
devfrom
feat/settings-search
Open

machisuji wants to merge 12 commits into
devfrom
feat/settings-search

Conversation

@machisuji

@machisuji machisuji commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Ticket

https://community.openproject.org/projects/SE/work_packages/SE-649/activity

image

What are you trying to accomplish?

The idea is to make our settings in the administration searchable as it can be a hassle to find them.
This PR adds a search bar on top of the admin menu that allows you to find settings and actions throughout the administration.

Results are displayed in a tree view.

Global settings

When clicked, global settings such as the host name will redirect to the setting's page, and the setting itself will be highlighted.

image

Per-entity settings and tabs

Nested per-entity (e.g. work package type) settings will be shown in the tree view and redirect to the respective tab of the first entity. This way the user can find the setting, and then navigate to the desired specific entity to find it again (e.g. the forms tab in a work package type).

image

Actions and links

Settings pages that show a list of entities and otherwise, when empty, only contain an action button, can be found as well. For instance, searching for "Add provider" will find all places that have such a button.
If the button opens a new page, clicking the search result will redirect directly to it, opening the form.

image

Currently the structure of the menus and all settings, tabs, and actions are defined in two new initializers:

  • settings_pages.rb - the main settings menu entries / pages, and their settings are defined here. All referenced global settings have to exist in definition.rb for the settings
  • settings_entity_kinds.rb - this defines existing attributes for various entities, such as color for work package types

When new settings are added, developers have to pay attention to add new settings to these structures as needed.

To make sure the view templates and these structures stay in sync, there are dritft specs (registered_pages_spec.rb, entity_attributes_spec) going through the settings pages and making sure they exist. This does not catch the case when a new setting is added to a template, and forgotten in the settings pages, however.

The new concepts are documented in docs/development/concepts/settings-search/README.md.

Future work

It is extra work to keep everything in sync. But the main idea behind this is not only to have searchable settings.
Ideally we would not have to define new controllers and templates when adding new settings.

All settings views should be automatically rendered based on the settings pages and entity kinds definitions, together with the settings definitions (definition.rb) themselves.

There is a POC PR for this which removes almost 7000 lines of code:

#25859

To make this thing more reviewable, I decided to start with this as the basis for that next step.

Another PR will follow that implements the basic infrastructure for "auto rendering" settings based on their definitions, implementing a hand full as examples. The remaining settings could then be migrated one-by-one.

AI involvement

Collaborative – AI generated a substantial part of the code; I reviewed and understand every line.

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

Settings::Pages records the administration pages global settings are
shown on, so the settings search can find a setting and link to it.
Each page references its admin menu item and lists its settings,
optionally as a tab of the menu item, served by another controller or
behind conditions. Labels and captions default to the setting's
translations and can be given per setting. Engines can register pages
and extend existing ones.
Register all existing settings pages in Settings::Pages, including
tabbed pages and the costs module's pages, so every global setting has
a known place in the admin menu hierarchy. Settings whose page shows a
label or caption other than their default translation get it in the
registry.

A request spec renders each registered page and fails when its
settings fields and the registry drift apart.
Some global settings are changed through toggles, dialogs or model
forms instead of settings form fields: multiple target versions, LLM
features, text transform actions and real-time collaboration. Register
them with `form_field: false` and mark the element representing them
with `data-setting-name`. The drift spec checks for these markers and
renders all pages a second time with optional states enabled.
Settings::SearchTree arranges the registered settings below the admin
menu items and tabs they are shown on, with links highlighting the
setting on its page. Menu items hidden by configuration or not visible
to the current user are left out.
Show a button above the admin side menu opening an overlay with the
tree of global settings. The tree is loaded lazily into a turbo frame
from Admin::SettingsSearchesController when the overlay is first
opened, so admin pages do not build it on every request.

Scope the user search button click in the accents filter spec, as the
settings search button also matches the accessible name "Search".
The filterable tree view loads its tree from an endpoint taking the
query, so that entities such as work package types, which cannot all
be sent to the browser, can be included later. Each word of the query
is matched regardless of order and punctuation, so "self registration"
finds "Self-registration", against a setting, its description or the
menu items and tabs above it. All settings below a matching menu item
or tab stay visible, matching branches are expanded and the query is
highlighted.
The highlight-setting controller scrolls to and highlights the field
named in the `highlight` parameter, or the element marked with its
`data-setting-name`, when a settings page is opened from the search.

A feature spec covers searching settings and opening them highlighted
in the browser.
Move the checks deciding which attributes the custom field details
form shows into their own object, so that the settings search can
list only the attributes that apply to a custom field.
Register the attributes of work package types, statuses, priorities,
roles and custom fields with the settings search. Each kind lists its
attributes below its admin menu entry, leading to the first entity
they apply to. Entities themselves are only listed when their name
matches a word of the query, at most five per kind, so that instances
with many types or custom fields keep a usable tree.

Selecting an attribute highlights its form field on the entity's page,
which may now be given as a field name or as one of several inputs of
a field, such as a single permission of a role.
Admin menu items without registered settings, such as the OpenID, SAML
and LDAP pages, were left out of the settings search tree. List every
visible menu item, resolving menu URLs given as route helpers or
belonging to an engine.

Pages can now register links for their actions, e.g. adding an OpenID
provider for each provider type, a LDAP connection or a storage, each
shown only when its enterprise feature is available. Settings shown in
a field not named "settings[<name>]", such as the keys of the
two-factor authentication, reCAPTCHA, avatars and GitHub/GitLab
plugin settings, name that field, which the highlight falls back to
when no "settings[<name>]" field exists. The departments, project list
and MCP pages register their settings as well.
Register OpenID and SAML providers, LDAP connections, synchronized LDAP
filters and department trees, SCIM clients, OAuth applications, groups,
project phases, Jira imports, webhooks, storages, wiki providers,
document types, cost types and time tracking activities as entity kinds,
so that they are found by name together with their main fields. The
project wikis switch, the announcement and the MCP server are listed as
single records.

Kinds can be hidden by a condition, e.g. without the enterprise feature
required to edit their records.
Describe how the settings search builds its tree from the admin menu and
the registries of settings pages and entity kinds: registering settings,
tabs, links and entity attributes, and the formats understood when
highlighting a setting or field on its page. Point out that the views and
the registries have to be kept in sync and which drift specs ensure it.

Refer to the documentation from the registry initializers.
@github-actions github-actions Bot added the ai: Collaborative 💻 AI generated a substantial part of the code; A human reviewed and understands every line. label Oct 16, 2026
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Deploying openproject with ⚡ PullPreview

Field Value
Latest commit e179f51
Job deploy
Status ✅ Deploy successful
Preview URL https://pr-26098-settings-search-ip-2-28-139-230.my.opf.run:443

View logs

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai: Collaborative 💻 AI generated a substantial part of the code; A human reviewed and understands every line. feature Passion time pullpreview

Development

Successfully merging this pull request may close these issues.

1 participant