diff options
author | Pascal Mugnier <pascal.mugnier@sonarsource.com> | 2018-04-17 12:11:11 +0200 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2018-04-18 20:20:53 +0200 |
commit | d1e95cf62f9b38e7e7df0a5ecc881620298da803 (patch) | |
tree | 085f67ac9d9ac8be315ed3af09398f5f813a804d /server/sonar-web/src/main | |
parent | abcce903fa73b67812b7de04a0414f0ea44b0e58 (diff) | |
download | sonarqube-d1e95cf62f9b38e7e7df0a5ecc881620298da803.tar.gz sonarqube-d1e95cf62f9b38e7e7df0a5ecc881620298da803.zip |
SONAR-10050 Switch Issues/Effort in issues page when data is available
Diffstat (limited to 'server/sonar-web/src/main')
21 files changed, 119 insertions, 20 deletions
diff --git a/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.js.snap b/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.js.snap index aad1591cb67..64c9678aaef 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.js.snap +++ b/server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.js.snap @@ -16,6 +16,7 @@ exports[`should display facet item list 1`] = ` disabled={false} halfWidth={false} key="Reliability" + loading={false} name={ <span id="measure-overview-Reliability-name" @@ -46,6 +47,7 @@ exports[`should display facet item list 1`] = ` disabled={false} halfWidth={false} key="new_bugs" + loading={false} name={ <span className="big-spacer-left" @@ -93,6 +95,7 @@ exports[`should display facet item list 1`] = ` disabled={false} halfWidth={false} key="bugs" + loading={false} name={ <span className="big-spacer-left" @@ -150,6 +153,7 @@ exports[`should display facet item list with bugs selected 1`] = ` disabled={false} halfWidth={false} key="Reliability" + loading={false} name={ <span id="measure-overview-Reliability-name" @@ -180,6 +184,7 @@ exports[`should display facet item list with bugs selected 1`] = ` disabled={false} halfWidth={false} key="new_bugs" + loading={false} name={ <span className="big-spacer-left" @@ -227,6 +232,7 @@ exports[`should display facet item list with bugs selected 1`] = ` disabled={false} halfWidth={false} key="bugs" + loading={false} name={ <span className="big-spacer-left" @@ -280,6 +286,7 @@ exports[`should not display subtitles of new measures if there is none 1`] = ` disabled={false} halfWidth={false} key="Reliability" + loading={false} name={ <span id="measure-overview-Reliability-name" @@ -310,6 +317,7 @@ exports[`should not display subtitles of new measures if there is none 1`] = ` disabled={false} halfWidth={false} key="bugs" + loading={false} name={ <span className="big-spacer-left" @@ -356,6 +364,7 @@ exports[`should not display subtitles of new measures if there is none, even on disabled={false} halfWidth={false} key="Reliability" + loading={false} name={ <span id="measure-overview-Reliability-name" @@ -386,6 +395,7 @@ exports[`should not display subtitles of new measures if there is none, even on disabled={false} halfWidth={false} key="new_bugs" + loading={false} name={ <span className="big-spacer-left" diff --git a/server/sonar-web/src/main/js/apps/issues/components/App.tsx b/server/sonar-web/src/main/js/apps/issues/components/App.tsx index 28a60d965e3..3ab8f9023e8 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/App.tsx @@ -72,22 +72,21 @@ import Checkbox from '../../../components/controls/Checkbox'; import '../styles.css'; +interface FetchIssuesPromise { + components: ReferencedComponent[]; + facets: RawFacet[]; + issues: Issue[]; + languages: ReferencedLanguage[]; + paging: Paging; + rules: { name: string }[]; + users: ReferencedUser[]; +} + interface Props { branchLike?: BranchLike; component?: Component; currentUser: CurrentUser; - fetchIssues: ( - query: RawQuery, - requestOrganizations?: boolean - ) => Promise<{ - components: ReferencedComponent[]; - facets: RawFacet[]; - issues: Issue[]; - languages: ReferencedLanguage[]; - paging: Paging; - rules: { name: string }[]; - users: ReferencedUser[]; - }>; + fetchIssues: (query: RawQuery, requestOrganizations?: boolean) => Promise<FetchIssuesPromise>; location: { pathname: string; query: RawQuery }; myIssues?: boolean; onBranchesChange: () => void; @@ -397,7 +396,11 @@ export default class App extends React.PureComponent<Props, State> { } }; - fetchIssues = (additional: RawQuery, requestFacets = false, requestOrganizations = true) => { + fetchIssues = ( + additional: RawQuery, + requestFacets = false, + requestOrganizations = true + ): Promise<FetchIssuesPromise> => { const { component, organization } = this.props; const { myIssues, openFacets, query } = this.state; @@ -428,7 +431,10 @@ export default class App extends React.PureComponent<Props, State> { Object.assign(parameters, { assignees: '__me__' }); } - return this.props.fetchIssues(parameters, requestOrganizations); + return this.props.fetchIssues(parameters, requestOrganizations).then(reponse => { + this.setState({ loading: false }); + return reponse; + }); }; fetchFirstIssues() { @@ -594,6 +600,7 @@ export default class App extends React.PureComponent<Props, State> { }; handleFilterChange = (changes: Partial<Query>) => { + this.setState({ loading: true }); this.context.router.push({ pathname: this.props.location.pathname, query: { @@ -854,6 +861,7 @@ export default class App extends React.PureComponent<Props, State> { <Sidebar component={component} facets={this.state.facets} + loading={this.state.loading} myIssues={this.state.myIssues} onFacetToggle={this.handleFacetToggle} onFilterChange={this.handleFilterChange} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/AssigneeFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/AssigneeFacet.tsx index 7ad53a950e4..77cae8a2d9c 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/AssigneeFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/AssigneeFacet.tsx @@ -34,6 +34,7 @@ export interface Props { assignees: string[]; component: Component | undefined; facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -164,6 +165,7 @@ export default class AssigneeFacet extends React.PureComponent<Props> { <FacetItem active={this.isAssigneeActive(assignee)} key={assignee} + loading={this.props.loading} name={this.getAssigneeName(assignee)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(assignee), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/AuthorFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/AuthorFacet.tsx index 77398f0c231..a09a7e62a42 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/AuthorFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/AuthorFacet.tsx @@ -28,6 +28,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -78,6 +79,7 @@ export default class AuthorFacet extends React.PureComponent<Props> { <FacetItem active={this.props.authors.includes(author)} key={author} + loading={this.props.loading} name={author} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(author), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.tsx index df6dd15df91..5ba901f92e6 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.tsx @@ -41,6 +41,7 @@ interface Props { createdBefore: Date | undefined; createdInLast: string; facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -171,7 +172,7 @@ export default class CreationDateFacet extends React.PureComponent<Props> { createdBefore: endDate, tooltip, x: index, - y: stats[start] + y: this.props.loading ? 0 : stats[start] }; }); @@ -225,6 +226,7 @@ export default class CreationDateFacet extends React.PureComponent<Props> { <div className="spacer-top issues-predefined-periods"> <FacetItem active={!this.hasValue()} + loading={this.props.loading} name={translate('issues.facet.createdAt.all')} onClick={this.handlePeriodClick} value="" @@ -232,6 +234,7 @@ export default class CreationDateFacet extends React.PureComponent<Props> { {component ? ( <FacetItem active={sinceLeakPeriod} + loading={this.props.loading} name={translate('issues.leak_period')} onClick={this.handleLeakPeriodClick} value="" @@ -240,18 +243,21 @@ export default class CreationDateFacet extends React.PureComponent<Props> { <> <FacetItem active={createdInLast === '1w'} + loading={this.props.loading} name={translate('issues.facet.createdAt.last_week')} onClick={this.handlePeriodClick} value="1w" /> <FacetItem active={createdInLast === '1m'} + loading={this.props.loading} name={translate('issues.facet.createdAt.last_month')} onClick={this.handlePeriodClick} value="1m" /> <FacetItem active={createdInLast === '1y'} + loading={this.props.loading} name={translate('issues.facet.createdAt.last_year')} onClick={this.handlePeriodClick} value="1y" diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/DirectoryFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/DirectoryFacet.tsx index 711b509a235..bff7ef1c391 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/DirectoryFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/DirectoryFacet.tsx @@ -31,6 +31,7 @@ import { collapsePath } from '../../../helpers/path'; interface Props { directories: string[]; facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -92,6 +93,7 @@ export default class DirectoryFacet extends React.PureComponent<Props> { <FacetItem active={this.props.directories.includes(directory)} key={directory} + loading={this.props.loading} name={this.renderName(directory)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(directory), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/FileFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/FileFacet.tsx index c68d4be90c2..cb998d44698 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/FileFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/FileFacet.tsx @@ -31,6 +31,7 @@ import { collapsePath } from '../../../helpers/path'; interface Props { facetMode: string; files: string[]; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -96,6 +97,7 @@ export default class FileFacet extends React.PureComponent<Props> { <FacetItem active={this.props.files.includes(file)} key={file} + loading={this.props.loading} name={this.renderName(file)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(file), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx index 1252b235f29..95d7cae343a 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx @@ -29,12 +29,13 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; + languages: string[]; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; - stats: { [x: string]: number } | undefined; referencedLanguages: { [languageKey: string]: ReferencedLanguage }; - languages: string[]; + stats: { [x: string]: number } | undefined; } export default class LanguageFacet extends React.PureComponent<Props> { @@ -90,6 +91,7 @@ export default class LanguageFacet extends React.PureComponent<Props> { <FacetItem active={this.props.languages.includes(language)} key={language} + loading={this.props.loading} name={this.getLanguageName(language)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(language), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/ModuleFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/ModuleFacet.tsx index 7a48a6d71fe..672678258e6 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/ModuleFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/ModuleFacet.tsx @@ -29,6 +29,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; + loading?: boolean; modules: string[]; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; @@ -94,6 +95,7 @@ export default class ModuleFacet extends React.PureComponent<Props> { <FacetItem active={this.props.modules.includes(module)} key={module} + loading={this.props.loading} name={this.renderName(module)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(module), this.props.facetMode)} 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 6ae7aa5938d..675fdb92fb0 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 @@ -34,6 +34,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { component: Component | undefined; facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -148,6 +149,7 @@ export default class ProjectFacet extends React.PureComponent<Props> { <FacetItem active={this.props.projects.includes(project)} key={project} + loading={this.props.loading} name={this.renderName(project)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(project), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx index 0cf5930502b..911555a6573 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx @@ -28,6 +28,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -90,6 +91,7 @@ export default class ResolutionFacet extends React.PureComponent<Props> { disabled={stat === 0 && !active} halfWidth={true} key={resolution} + loading={this.props.loading} name={this.getFacetItemName(resolution)} onClick={this.handleItemClick} stat={formatFacetStat(stat, this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/RuleFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/RuleFacet.tsx index ff0edeaa406..7cd4be14f75 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/RuleFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/RuleFacet.tsx @@ -31,6 +31,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; languages: string[]; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -105,6 +106,7 @@ export default class RuleFacet extends React.PureComponent<Props> { <FacetItem active={this.props.rules.includes(rule)} key={rule} + loading={this.props.loading} name={this.getRuleName(rule)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(rule), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx index 6c39c35aa76..9b27208e74c 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx @@ -29,6 +29,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -74,6 +75,7 @@ export default class SeverityFacet extends React.PureComponent<Props> { disabled={stat === 0 && !active} halfWidth={true} key={severity} + loading={this.props.loading} name={<SeverityHelper severity={severity} />} onClick={this.handleItemClick} stat={formatFacetStat(stat, this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx index f1853e1337b..c850ffa0750 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx @@ -39,6 +39,7 @@ import { Component } from '../../../app/types'; export interface Props { component: Component | undefined; facets: { [facet: string]: Facet }; + loading?: boolean; myIssues: boolean; onFacetToggle: (property: string) => void; onFilterChange: (changes: Partial<Query>) => void; @@ -67,6 +68,7 @@ export default class Sidebar extends React.PureComponent<Props> { <FacetMode facetMode={query.facetMode} onChange={this.props.onFilterChange} /> <TypeFacet facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.types} @@ -75,6 +77,7 @@ export default class Sidebar extends React.PureComponent<Props> { /> <SeverityFacet facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.severities} @@ -83,6 +86,7 @@ export default class Sidebar extends React.PureComponent<Props> { /> <ResolutionFacet facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.resolutions} @@ -92,6 +96,7 @@ export default class Sidebar extends React.PureComponent<Props> { /> <StatusFacet facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.statuses} @@ -105,6 +110,7 @@ export default class Sidebar extends React.PureComponent<Props> { createdBefore={query.createdBefore} createdInLast={query.createdInLast} facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.createdAt} @@ -114,6 +120,7 @@ export default class Sidebar extends React.PureComponent<Props> { <RuleFacet facetMode={query.facetMode} languages={query.languages} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.rules} @@ -125,6 +132,7 @@ export default class Sidebar extends React.PureComponent<Props> { <TagFacet component={component} facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.tags} @@ -136,6 +144,7 @@ export default class Sidebar extends React.PureComponent<Props> { <ProjectFacet component={component} facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.projects} @@ -148,6 +157,7 @@ export default class Sidebar extends React.PureComponent<Props> { {displayModulesFacet && ( <ModuleFacet facetMode={query.facetMode} + loading={this.props.loading} modules={query.modules} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} @@ -160,6 +170,7 @@ export default class Sidebar extends React.PureComponent<Props> { <DirectoryFacet directories={query.directories} facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.directories} @@ -171,6 +182,7 @@ export default class Sidebar extends React.PureComponent<Props> { <FileFacet facetMode={query.facetMode} files={query.files} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.files} @@ -184,6 +196,7 @@ export default class Sidebar extends React.PureComponent<Props> { assignees={query.assignees} component={component} facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.assignees} @@ -196,6 +209,7 @@ export default class Sidebar extends React.PureComponent<Props> { <AuthorFacet authors={query.authors} facetMode={query.facetMode} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.authors} @@ -205,6 +219,7 @@ export default class Sidebar extends React.PureComponent<Props> { <LanguageFacet facetMode={query.facetMode} languages={query.languages} + loading={this.props.loading} onChange={this.props.onFilterChange} onToggle={this.props.onFacetToggle} open={!!openFacets.languages} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx index 5985afc6334..86e876d11c5 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx @@ -28,6 +28,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -81,6 +82,7 @@ export default class StatusFacet extends React.PureComponent<Props> { disabled={stat === 0 && !active} halfWidth={true} key={status} + loading={this.props.loading} name={this.renderStatus(status)} onClick={this.handleItemClick} stat={formatFacetStat(stat, this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/TagFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/TagFacet.tsx index 2fc0c14ab66..ba44ec51a29 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/TagFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/TagFacet.tsx @@ -32,6 +32,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { component: Component | undefined; facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -107,6 +108,7 @@ export default class TagFacet extends React.PureComponent<Props> { <FacetItem active={this.props.tags.includes(tag)} key={tag} + loading={this.props.loading} name={this.renderTag(tag)} onClick={this.handleItemClick} stat={formatFacetStat(this.getStat(tag), this.props.facetMode)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/TypeFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/TypeFacet.tsx index b026c0af92d..146a6dbe634 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/TypeFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/TypeFacet.tsx @@ -29,6 +29,7 @@ import { translate } from '../../../helpers/l10n'; interface Props { facetMode: string; + loading?: boolean; onChange: (changes: Partial<Query>) => void; onToggle: (property: string) => void; open: boolean; @@ -73,6 +74,7 @@ export default class TypeFacet extends React.PureComponent<Props> { active={active} disabled={stat === 0 && !active} key={type} + loading={this.props.loading} name={ <span> <IssueTypeIcon query={type} /> {translate('issue.type', type)} diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/AssigneeFacet-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/AssigneeFacet-test.tsx.snap index a0afcc2cf9a..1d183049d3d 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/AssigneeFacet-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/AssigneeFacet-test.tsx.snap @@ -16,6 +16,7 @@ exports[`should render 1`] = ` active={false} disabled={false} halfWidth={false} + loading={false} name="unassigned" onClick={[Function]} stat="5" @@ -26,6 +27,7 @@ exports[`should render 1`] = ` disabled={false} halfWidth={false} key="foo" + loading={false} name={ <span> <Connect(Avatar) @@ -46,6 +48,7 @@ exports[`should render 1`] = ` disabled={false} halfWidth={false} key="bar" + loading={false} name="bar" onClick={[Function]} stat="7" @@ -106,6 +109,7 @@ exports[`should select unassigned 1`] = ` active={true} disabled={false} halfWidth={false} + loading={false} name="unassigned" onClick={[Function]} stat="5" @@ -116,6 +120,7 @@ exports[`should select unassigned 1`] = ` disabled={false} halfWidth={false} key="foo" + loading={false} name={ <span> <Connect(Avatar) @@ -136,6 +141,7 @@ exports[`should select unassigned 1`] = ` disabled={false} halfWidth={false} key="bar" + loading={false} name="bar" onClick={[Function]} stat="7" @@ -170,6 +176,7 @@ exports[`should select user 1`] = ` active={false} disabled={false} halfWidth={false} + loading={false} name="unassigned" onClick={[Function]} stat="5" @@ -180,6 +187,7 @@ exports[`should select user 1`] = ` disabled={false} halfWidth={false} key="foo" + loading={false} name={ <span> <Connect(Avatar) @@ -200,6 +208,7 @@ exports[`should select user 1`] = ` disabled={false} halfWidth={false} key="bar" + loading={false} name="bar" onClick={[Function]} stat="7" diff --git a/server/sonar-web/src/main/js/components/facet/FacetItem.tsx b/server/sonar-web/src/main/js/components/facet/FacetItem.tsx index a960cb8af0e..17f9a3c4b16 100644 --- a/server/sonar-web/src/main/js/components/facet/FacetItem.tsx +++ b/server/sonar-web/src/main/js/components/facet/FacetItem.tsx @@ -25,6 +25,7 @@ export interface Props { className?: string; disabled?: boolean; halfWidth?: boolean; + loading?: boolean; name: React.ReactNode; onClick: (x: string) => void; stat?: React.ReactNode; @@ -34,7 +35,8 @@ export interface Props { export default class FacetItem extends React.PureComponent<Props> { static defaultProps = { disabled: false, - halfWidth: false + halfWidth: false, + loading: false }; handleClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => { @@ -52,12 +54,16 @@ export default class FacetItem extends React.PureComponent<Props> { return this.props.disabled ? ( <span className={className} data-facet={this.props.value}> <span className="facet-name">{this.props.name}</span> - {this.props.stat != null && <span className="facet-stat">{this.props.stat}</span>} + {this.props.stat != null && ( + <span className="facet-stat">{this.props.loading ? '' : this.props.stat}</span> + )} </span> ) : ( <a className={className} data-facet={this.props.value} href="#" onClick={this.handleClick}> <span className="facet-name">{this.props.name}</span> - {this.props.stat != null && <span className="facet-stat">{this.props.stat}</span>} + {this.props.stat != null && ( + <span className="facet-stat">{this.props.loading ? '' : this.props.stat}</span> + )} </a> ); } diff --git a/server/sonar-web/src/main/js/components/facet/__tests__/FacetItem-test.tsx b/server/sonar-web/src/main/js/components/facet/__tests__/FacetItem-test.tsx index e16c5020383..95c822c8eb3 100644 --- a/server/sonar-web/src/main/js/components/facet/__tests__/FacetItem-test.tsx +++ b/server/sonar-web/src/main/js/components/facet/__tests__/FacetItem-test.tsx @@ -34,6 +34,10 @@ it('should render stat', () => { expect(renderFacetItem({ stat: '13' })).toMatchSnapshot(); }); +it('should loading stat', () => { + expect(renderFacetItem({ loading: true })).toMatchSnapshot(); +}); + it('should render disabled', () => { expect(renderFacetItem({ disabled: true })).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetItem-test.tsx.snap b/server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetItem-test.tsx.snap index c0cf80746aa..3044d7ddbbd 100644 --- a/server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetItem-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetItem-test.tsx.snap @@ -1,5 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should loading stat 1`] = ` +<a + className="facet search-navigator-facet" + data-facet="bar" + href="#" + onClick={[Function]} +> + <span + className="facet-name" + > + foo + </span> +</a> +`; + exports[`should render active 1`] = ` <a className="facet search-navigator-facet active" |