diff options
author | Viktor Vorona <viktor.vorona@sonarsource.com> | 2024-02-15 11:19:17 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-02-15 20:02:34 +0000 |
commit | afa1e65cfbe2f17f39ba73e1fe2dd2a543c5bf9a (patch) | |
tree | 357d7a02fff76e99f75170e70722c38950dee09b /server/sonar-web/src/main/js/apps | |
parent | 9a1d70adca457f84a6f7da5561328c8d85b1a7bb (diff) | |
download | sonarqube-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.tsx | 7 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/issues/sidebar/ProjectFacet.tsx | 114 |
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> + ); } |