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]

Reply via email to