aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main
diff options
context:
space:
mode:
authorPascal Mugnier <pascal.mugnier@sonarsource.com>2018-04-17 12:11:11 +0200
committerSonarTech <sonartech@sonarsource.com>2018-04-18 20:20:53 +0200
commitd1e95cf62f9b38e7e7df0a5ecc881620298da803 (patch)
tree085f67ac9d9ac8be315ed3af09398f5f813a804d /server/sonar-web/src/main
parentabcce903fa73b67812b7de04a0414f0ea44b0e58 (diff)
downloadsonarqube-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')
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/sidebar/__tests__/__snapshots__/DomainFacet-test.js.snap10
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/App.tsx36
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/AssigneeFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/AuthorFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/DirectoryFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/FileFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/ModuleFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/ProjectFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/ResolutionFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/RuleFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/SeverityFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/Sidebar.tsx15
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/StatusFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/TagFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/TypeFacet.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/__tests__/__snapshots__/AssigneeFacet-test.tsx.snap9
-rw-r--r--server/sonar-web/src/main/js/components/facet/FacetItem.tsx12
-rw-r--r--server/sonar-web/src/main/js/components/facet/__tests__/FacetItem-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetItem-test.tsx.snap15
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"