aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps
diff options
context:
space:
mode:
authorViktor Vorona <viktor.vorona@sonarsource.com>2024-02-15 11:19:17 +0100
committersonartech <sonartech@sonarsource.com>2024-02-15 20:02:34 +0000
commitafa1e65cfbe2f17f39ba73e1fe2dd2a543c5bf9a (patch)
tree357d7a02fff76e99f75170e70722c38950dee09b /server/sonar-web/src/main/js/apps
parent9a1d70adca457f84a6f7da5561328c8d85b1a7bb (diff)
downloadsonarqube-afa1e65cfbe2f17f39ba73e1fe2dd2a543c5bf9a.tar.gz
sonarqube-afa1e65cfbe2f17f39ba73e1fe2dd2a543c5bf9a.zip
SONAR-20510 Always show project name in project facet
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
-rw-r--r--server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/ProjectFacet.tsx114
2 files changed, 80 insertions, 41 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx
index 35501cdd50e..a00e7fe5450 100644
--- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-Filtering-it.tsx
@@ -115,7 +115,12 @@ describe('issues app filtering', () => {
// Project
await user.click(ui.projectFacet.get());
- await user.click(screen.getByRole('checkbox', { name: 'org.project2' }));
+ expect(
+ screen.getByRole('checkbox', { name: 'org.sonarsource.javascript:javascript' }),
+ ).toHaveTextContent('SonarJS');
+ await user.click(
+ screen.getByRole('checkbox', { name: 'org.sonarsource.javascript:javascript' }),
+ );
// Assignee
await user.click(ui.assigneeFacet.get());
diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/ProjectFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/ProjectFacet.tsx
index 0c47345603a..19371524f0d 100644
--- a/server/sonar-web/src/main/js/apps/issues/sidebar/ProjectFacet.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/sidebar/ProjectFacet.tsx
@@ -17,12 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { ProjectIcon } from 'design-system';
+import { ProjectIcon, Spinner } from 'design-system';
import { omit } from 'lodash';
import * as React from 'react';
import { getTree, searchProjects } from '../../../api/components';
import { translate } from '../../../helpers/l10n';
import { highlightTerm } from '../../../helpers/search';
+import { useProjectQuery } from '../../../queries/projects';
import { ComponentQualifier } from '../../../types/component';
import { Facet, ReferencedComponent } from '../../../types/issues';
import { MetricKey } from '../../../types/metrics';
@@ -48,13 +49,23 @@ interface SearchedProject {
name: string;
}
-export class ProjectFacet extends React.PureComponent<Props> {
- handleSearch = (
+export function ProjectFacet(props: Readonly<Props>) {
+ const {
+ component,
+ fetching,
+ onChange,
+ onToggle,
+ open,
+ projects,
+ query,
+ referencedComponents,
+ stats,
+ } = props;
+
+ const handleSearch = (
query: string,
page = 1,
): Promise<{ results: SearchedProject[]; paging: Paging }> => {
- const { component } = this.props;
-
if (
component &&
[
@@ -91,29 +102,27 @@ export class ProjectFacet extends React.PureComponent<Props> {
}));
};
- getProjectName = (project: string) => {
- const { referencedComponents } = this.props;
-
+ const getProjectName = (project: string) => {
return referencedComponents[project] ? referencedComponents[project].name : project;
};
- loadSearchResultCount = (projects: SearchedProject[]) => {
- return this.props.loadSearchResultCount(MetricKey.projects, {
+ const loadSearchResultCount = (projects: SearchedProject[]) => {
+ return props.loadSearchResultCount(MetricKey.projects, {
projects: projects.map((project) => project.key),
});
};
- renderFacetItem = (projectKey: string) => {
+ const renderFacetItem = (projectKey: string) => {
+ const projectName = getProjectName(projectKey);
return (
- <span>
- <ProjectIcon className="sw-mr-1" />
-
- {this.getProjectName(projectKey)}
- </span>
+ <ProjectItem
+ projectKey={projectKey}
+ projectName={projectName === projectKey ? undefined : projectName}
+ />
);
};
- renderSearchResult = (project: Pick<SearchedProject, 'name'>, term: string) => (
+ const renderSearchResult = (project: Pick<SearchedProject, 'name'>, term: string) => (
<>
<ProjectIcon className="sw-mr-1" />
@@ -121,27 +130,52 @@ export class ProjectFacet extends React.PureComponent<Props> {
</>
);
- render() {
- return (
- <ListStyleFacet<SearchedProject>
- facetHeader={translate('issues.facet.projects')}
- fetching={this.props.fetching}
- getFacetItemText={this.getProjectName}
- getSearchResultKey={(project) => project.key}
- getSearchResultText={(project) => project.name}
- loadSearchResultCount={this.loadSearchResultCount}
- onChange={this.props.onChange}
- onSearch={this.handleSearch}
- onToggle={this.props.onToggle}
- open={this.props.open}
- property={MetricKey.projects}
- query={omit(this.props.query, MetricKey.projects)}
- renderFacetItem={this.renderFacetItem}
- renderSearchResult={this.renderSearchResult}
- searchPlaceholder={translate('search.search_for_projects')}
- stats={this.props.stats}
- values={this.props.projects}
- />
- );
- }
+ return (
+ <ListStyleFacet<SearchedProject>
+ facetHeader={translate('issues.facet.projects')}
+ fetching={fetching}
+ getFacetItemText={getProjectName}
+ getSearchResultKey={(project) => project.key}
+ getSearchResultText={(project) => project.name}
+ loadSearchResultCount={loadSearchResultCount}
+ onChange={onChange}
+ onSearch={handleSearch}
+ onToggle={onToggle}
+ open={open}
+ property={MetricKey.projects}
+ query={omit(query, MetricKey.projects)}
+ renderFacetItem={renderFacetItem}
+ renderSearchResult={renderSearchResult}
+ searchPlaceholder={translate('search.search_for_projects')}
+ stats={stats}
+ values={projects}
+ />
+ );
+}
+
+function ProjectItem({
+ projectKey,
+ projectName,
+}: Readonly<{
+ projectKey: string;
+ projectName?: string;
+}>) {
+ const { data, isLoading } = useProjectQuery(projectKey, {
+ enabled: projectName === undefined,
+ select: (data) => data.components.find((el) => el.key === projectKey),
+ });
+
+ const label = projectName ?? (isLoading ? '' : data?.name ?? projectKey);
+
+ return (
+ <div className="sw-flex sw-items-center">
+ <ProjectIcon className="sw-mr-1" />
+
+ <Spinner loading={projectName === undefined && isLoading} />
+
+ <span className="sw-min-w-0 sw-truncate" title={label}>
+ {label}
+ </span>
+ </div>
+ );
}