aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/issues
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2018-08-13 15:19:24 +0200
committersonartech <sonartech@sonarsource.com>2018-08-16 09:45:57 +0200
commit9ad0e56f42abd45343f16be66edae1f1a4f688b5 (patch)
tree6595a4bd7e841ede2bcfdc266e0e046cf1dbef21 /server/sonar-web/src/main/js/apps/issues
parent38dc0fa7eaa8112b9ca6fec9d3f0c809f83b2b19 (diff)
downloadsonarqube-9ad0e56f42abd45343f16be66edae1f1a4f688b5.tar.gz
sonarqube-9ad0e56f42abd45343f16be66edae1f1a4f688b5.zip
SONAR-11149 Fix loading problems in issues page
Diffstat (limited to 'server/sonar-web/src/main/js/apps/issues')
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/PageActions.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/ReloadButton.tsx54
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.tsx (renamed from server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js)56
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/BackButton.tsx54
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesListHeader.tsx8
5 files changed, 43 insertions, 131 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/components/PageActions.tsx b/server/sonar-web/src/main/js/apps/issues/components/PageActions.tsx
index 330409caa95..1850b50dbda 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/PageActions.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/components/PageActions.tsx
@@ -19,9 +19,9 @@
*/
import * as React from 'react';
import IssuesCounter from './IssuesCounter';
-import ReloadButton from './ReloadButton';
import { HomePageType, Paging } from '../../../app/types';
import HomePageSelect from '../../../components/controls/HomePageSelect';
+import ReloadButton from '../../../components/controls/ReloadButton';
import { translate } from '../../../helpers/l10n';
import { isSonarCloud } from '../../../helpers/system';
diff --git a/server/sonar-web/src/main/js/apps/issues/components/ReloadButton.tsx b/server/sonar-web/src/main/js/apps/issues/components/ReloadButton.tsx
deleted file mode 100644
index 3af99da5480..00000000000
--- a/server/sonar-web/src/main/js/apps/issues/components/ReloadButton.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import * as classNames from 'classnames';
-import Tooltip from '../../../components/controls/Tooltip';
-import { translate } from '../../../helpers/l10n';
-
-interface Props {
- className?: string;
- onClick: () => void;
-}
-
-/* eslint-disable max-len */
-const icon = (
- <svg height="24" viewBox="0 0 18 24" width="18">
- <path d="M16.6454 8.1084c-.3-.5-.9-.7-1.4-.4-.5.3-.7.9-.4 1.4.9 1.6 1.1 3.4.6 5.1-.5 1.7-1.7 3.2-3.2 4-3.3 1.8-7.4.6-9.1-2.7-1.8-3.1-.8-6.9 2.1-8.8v3.3h2v-7h-7v2h3.9c-3.7 2.5-5 7.5-2.8 11.4 1.6 3 4.6 4.6 7.7 4.6 1.4 0 2.8-.3 4.2-1.1 2-1.1 3.5-3 4.2-5.2.6-2.2.3-4.6-.8-6.6z" />
- </svg>
-);
-/* eslint-enable max-len */
-
-export default function ReloadButton(props: Props) {
- const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- props.onClick();
- };
-
- return (
- <Tooltip overlay={translate('reload')}>
- <a
- className={classNames('concise-issues-list-header-button', props.className)}
- href="#"
- onClick={handleClick}>
- {icon}
- </a>
- </Tooltip>
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js b/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.tsx
index dfc109dcb2b..bd16df2c7d1 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.js
+++ b/server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.tsx
@@ -17,19 +17,23 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-// @flow
import * as React from 'react';
-import { shallow, mount } from 'enzyme';
import App from '../App';
import { shallowWithIntl, waitAndUpdate } from '../../../../helpers/testUtils';
+import { Issue } from '../../../../app/types';
const replace = jest.fn();
-const issues = [{ key: 'foo' }, { key: 'bar' }, { key: 'third' }, { key: 'fourth' }];
+const issues = [
+ { key: 'foo' } as Issue,
+ { key: 'bar' } as Issue,
+ { key: 'third' } as Issue,
+ { key: 'fourth' } as Issue
+];
const facets = [{ property: 'severities', values: [{ val: 'MINOR', count: 4 }] }];
-const paging = [{ pageIndex: 1, pageSize: 100, total: 4 }];
+const paging = { pageIndex: 1, pageSize: 100, total: 4 };
-const eventNoShiftKey = { shiftKey: false };
-const eventWithShiftKey = { shiftKey: true };
+const eventNoShiftKey = { shiftKey: false } as MouseEvent;
+const eventWithShiftKey = { shiftKey: true } as MouseEvent;
const PROPS = {
branch: { isMain: true, name: 'master' },
@@ -40,12 +44,22 @@ const PROPS = {
login: 'JohnDoe',
name: 'John Doe'
},
- component: { key: 'foo', name: 'bar', organization: 'John', qualifier: 'Doe' },
+ component: { breadcrumbs: [], key: 'foo', name: 'bar', organization: 'John', qualifier: 'Doe' },
location: { pathname: '/issues', query: {} },
- fetchIssues: () => Promise.resolve({ facets, issues, paging }),
+ fetchIssues: () =>
+ Promise.resolve({
+ components: [],
+ facets,
+ issues,
+ languages: [],
+ paging,
+ rules: [],
+ users: []
+ }),
onBranchesChange: () => {},
onSonarCloud: false,
- organization: { key: 'foo' }
+ organization: { key: 'foo' },
+ userOrganizations: []
};
it('should render a list of issue', async () => {
@@ -65,16 +79,17 @@ it('should be able to check/uncheck a group of issues with the Shift key', async
await waitAndUpdate(wrapper);
expect(wrapper.state().issues.length).toBe(4);
- wrapper.instance().handleIssueCheck('foo', eventNoShiftKey);
+ const instance = wrapper.instance() as App;
+ instance.handleIssueCheck('foo', eventNoShiftKey);
expect(wrapper.state().checked.length).toBe(1);
- wrapper.instance().handleIssueCheck('fourth', eventWithShiftKey);
+ instance.handleIssueCheck('fourth', eventWithShiftKey);
expect(wrapper.state().checked.length).toBe(4);
- wrapper.instance().handleIssueCheck('third', eventNoShiftKey);
+ instance.handleIssueCheck('third', eventNoShiftKey);
expect(wrapper.state().checked.length).toBe(3);
- wrapper.instance().handleIssueCheck('foo', eventWithShiftKey);
+ instance.handleIssueCheck('foo', eventWithShiftKey);
expect(wrapper.state().checked.length).toBe(1);
});
@@ -86,10 +101,11 @@ it('should avoid non-existing keys', async () => {
await waitAndUpdate(wrapper);
expect(wrapper.state().issues.length).toBe(4);
- wrapper.instance().handleIssueCheck('foo', eventNoShiftKey);
+ const instance = wrapper.instance() as App;
+ instance.handleIssueCheck('foo', eventNoShiftKey);
expect(wrapper.state().checked.length).toBe(1);
- wrapper.instance().handleIssueCheck('non-existing-key', eventWithShiftKey);
+ instance.handleIssueCheck('non-existing-key', eventWithShiftKey);
expect(wrapper.state().checked.length).toBe(1);
});
@@ -101,11 +117,12 @@ it('should be able to uncheck all issue with global checkbox', async () => {
await waitAndUpdate(wrapper);
expect(wrapper.state().issues.length).toBe(4);
- wrapper.instance().handleIssueCheck('foo', eventNoShiftKey);
- wrapper.instance().handleIssueCheck('bar', eventNoShiftKey);
+ const instance = wrapper.instance() as App;
+ instance.handleIssueCheck('foo', eventNoShiftKey);
+ instance.handleIssueCheck('bar', eventNoShiftKey);
expect(wrapper.state().checked.length).toBe(2);
- wrapper.instance().onCheckAll(false);
+ instance.onCheckAll(false);
expect(wrapper.state().checked.length).toBe(0);
});
@@ -116,7 +133,8 @@ it('should be able to check all issue with global checkbox', async () => {
await waitAndUpdate(wrapper);
+ const instance = wrapper.instance() as App;
expect(wrapper.state().checked.length).toBe(0);
- wrapper.instance().onCheckAll(true);
+ instance.onCheckAll(true);
expect(wrapper.state().checked.length).toBe(wrapper.state().issues.length);
});
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/BackButton.tsx b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/BackButton.tsx
deleted file mode 100644
index d2a9637e310..00000000000
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/BackButton.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import * as classNames from 'classnames';
-import Tooltip from '../../../components/controls/Tooltip';
-import { translate } from '../../../helpers/l10n';
-
-interface Props {
- className?: string;
- onClick: () => void;
-}
-
-/* eslint-disable max-len */
-const icon = (
- <svg height="24" viewBox="0 0 21 24" width="21">
- <path d="M3.845 12.9992l5.993 5.993.052.056c.049.061.093.122.129.191.082.159.121.339.111.518-.006.102-.028.203-.064.298-.149.39-.537.652-.954.644-.102-.002-.204-.019-.301-.052-.148-.05-.273-.135-.387-.241l-8.407-8.407 8.407-8.407.056-.052c.061-.048.121-.092.19-.128.116-.06.237-.091.366-.108.076-.004.075-.004.153-.003.155.015.3.052.437.129.088.051.169.115.239.19.246.266.33.656.214.999-.051.149-.135.273-.241.387l-5.983 5.984c5.287-.044 10.577-.206 15.859.013.073.009.091.009.163.027.187.047.359.15.49.292.075.081.136.175.18.276.044.101.072.209.081.319.032.391-.175.775-.521.962-.097.052-.202.089-.311.107-.073.012-.091.01-.165.013H3.845z" />
- </svg>
-);
-/* eslint-enable max-len */
-
-export default function BackButton(props: Props) {
- const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- props.onClick();
- };
-
- return (
- <Tooltip overlay={translate('issues.return_to_list')}>
- <a
- className={classNames('concise-issues-list-header-button', props.className)}
- href="#"
- onClick={handleClick}>
- {icon}
- </a>
- </Tooltip>
- );
-}
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesListHeader.tsx b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesListHeader.tsx
index fb50f4f0fec..ffffdeb0a55 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesListHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesListHeader.tsx
@@ -18,8 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import BackButton from './BackButton';
-import ReloadButton from '../components/ReloadButton';
+import BackButton from '../../../components/controls/BackButton';
+import ReloadButton from '../../../components/controls/ReloadButton';
import IssuesCounter from '../components/IssuesCounter';
import { Paging } from '../../../app/types';
@@ -38,7 +38,9 @@ export default function ConciseIssuesListHeader(props: Props) {
return (
<header className="layout-page-header-panel concise-issues-list-header">
<div className="layout-page-header-panel-inner concise-issues-list-header-inner">
- {displayBackButton && <BackButton className="pull-left" onClick={props.onBackClick} />}
+ {displayBackButton && (
+ <BackButton className="pull-left" disabled={props.loading} onClick={props.onBackClick} />
+ )}
{props.loading ? (
<i className="spinner pull-right" />
) : (