DoDiODev opened a new pull request, #9282:
URL: https://github.com/apache/devlake/pull/9282
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
### Summary
When adding data scopes to a SonarQube connection (Connection → *Add Data
Scope*), the search box only lets you pick the matching projects one by one.
With a few hundred projects sharing a prefix this is tedious.
This PR adds an **"ALL"** checkbox as the first entry of the search result
list. It selects or deselects **all** projects matching the search term, not
only the page that is currently loaded. The feature is opt-in per plugin and
is only switched on for SonarQube.
#### Backend (`feat(sonarqube): return total count from
search-remote-scopes`)
- `DsRemoteApiScopeSearchHelper` can now return the total number of matches
as `count` in the `search-remote-scopes` response.
- New function type `DsSearchRemoteScopesWithCount` and constructor
`NewDsRemoteApiScopeSearchHelperWithCount`.
- The existing `NewDsRemoteApiScopeSearchHelper` wraps its function and
reports the total as unknown (`-1`). In that case `count` is omitted from
the response. **No other plugin changes; the response of all other
plugins is unchanged.**
- `DsRemoteApiScopeList` documents the optional `count` field (Swagger).
- SonarQube: `querySonarqubeProjects` also returns `paging.total` from
`api/components/search_projects`, and the search endpoint uses the new
constructor.
#### config-ui (`feat(config-ui): add "ALL" toggle to the SonarQube remote
scope search`)
- New optional plugin config flag `dataScope.searchSelectAll`, set to `true`
for SonarQube only.
- The "ALL" row is rendered via `renderTitle` of `MillerColumnsSelect`, so it
sits inside the list, before the first item, and looks like a list item.
The built-in `showSelectAll` of `miller-columns-select` is not used: it
only
covers the already loaded items and replaces the whole selection.
- Behaviour of the checkbox:
- Label shows the number of matches, e.g. `ALL (237)` (from `count`, or the
list length once the whole result is loaded).
- Tri-state: checked / indeterminate / unchecked. Scopes that already exist
(disabled entries) are ignored.
- If not all pages are loaded yet, a click loads the remaining pages first
(spinner shown). With `count` the loop stops exactly at the last page;
without it, it stops at the first short page. Limit: 100 pages × 100.
If the limit is hit, a warning asks to refine the search.
- Selection outside the current filter is always kept. Clicking again only
removes the filtered entries.
- If the search term changes while loading, the stale result is discarded.
- Small fixes in `search-remote.tsx`: results are de-duplicated when the next
page is appended, and the memoised `disabledIds` is reused.
- `API.scope.searchRemote`: `count` is now typed as optional.
### Question for reviewers
The new behaviour is opt-in and currently enabled for SonarQube only. Should
it become the **default for all plugins** with a remote search? That covers:
1. **Showing the number of matches** behind the checkbox (`ALL (n)`), and
2. **Loading all pages of the search result** when "ALL" is clicked, instead
of acting only on the loaded items.
The helper extension is already generic. Each plugin would only need to
return the total from its search function (many remote APIs report it, for
example GitHub search `total_count` or Jira `total`; this would need to be
checked per plugin). Without a
total, the UI falls back to "load until a short page" and shows the count
only after everything is loaded. Plugins that use
`NewDsRemoteApiScopeSearchHelper`
today: azuredevops_go, bamboo, bitbucket, bitbucket_server, circleci,
gh-copilot, github, gitlab, grafana_irm, incidentio, jira, pagerduty, rootly,
slack, sonarqube, tapd, teambition, tempo, testmo, trello.
If you agree, I would prefer a follow-up PR: drop the `searchSelectAll` flag
(or flip its default) and add `count` plugin by plugin. That keeps this PR
small. I'm also happy to change it here if you prefer.
### Does this close any open issues?
N/A
### Screenshots
_Will be added shortly._
### Other Information
- Backwards compatible: `count` is only added to the response when a plugin
reports it; existing clients ignore unknown fields.
- Tests:
- Go: new unit tests for the helper (`count` present / omitted, legacy
wrapper) and for `querySonarqubeProjects` (mocked `ApiClient`; checks
`paging.total`, `filter`, `p`, `ps`).
- config-ui: Vitest unit tests for the select-all helpers and component
tests for the "ALL" row (15/15). `tsc` and `eslint` pass.
- Fork CI on the same change (golangci-lint, unit-test, e2e on MySQL,
config-ui, license header, Grafana check; 14/14 jobs green):
https://github.com/DoDiODev/devlake/actions/runs/40840628487
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]