Sfoglia il codice sorgente

apply feedback on issues page (part 2) (#1991)

tags/6.4-RC1
Stas Vilchik 7 anni fa
parent
commit
c370fe8bd9

+ 0
- 3
server/sonar-web/src/main/js/apps/issues/components/App.js Vedi File

@@ -433,9 +433,6 @@ export default class App extends React.PureComponent {
): Promise<Array<Issue>> => {
const { issues, openIssue, paging } = this.state;

/* eslint-disable no-console */
console.log(`loadin issues from line ${from} to line ${to}`);

if (!openIssue || !paging) {
return Promise.reject();
}

+ 14
- 10
server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.js Vedi File

@@ -160,16 +160,20 @@ export default class BulkChangeModal extends React.PureComponent {

handleSubmit = (e: Event) => {
e.preventDefault();
const query = pickBy({
assign: this.state.assignee,
set_type: this.state.type,
set_severity: this.state.severity,
add_tags: this.state.addTags && this.state.addTags.join(),
remove_tags: this.state.removeTags && this.state.removeTags.join(),
do_transition: this.state.transition,
comment: this.state.comment,
sendNotifications: this.state.notifications
});
const query = pickBy(
{
assign: this.state.assignee,
set_type: this.state.type,
set_severity: this.state.severity,
add_tags: this.state.addTags && this.state.addTags.join(),
remove_tags: this.state.removeTags && this.state.removeTags.join(),
do_transition: this.state.transition,
comment: this.state.comment,
sendNotifications: this.state.notifications
},
// remove null, but keep empty string
x => x != null
);
const issueKeys = this.state.issues.map(issue => issue.key);

this.setState({ submitting: true });

+ 5
- 3
server/sonar-web/src/main/js/apps/issues/components/ComponentBreadcrumbs.js Vedi File

@@ -47,7 +47,7 @@ export default class ComponentBreadcrumbs extends React.PureComponent {
<Organization linkClassName="link-no-underline" organizationKey={issue.organization} />}

{displayProject &&
<span>
<span title={issue.projectName}>
<Link to={getProjectUrl(issue.project)} className="link-no-underline">
{limitComponentName(issue.projectName)}
</Link>
@@ -56,7 +56,7 @@ export default class ComponentBreadcrumbs extends React.PureComponent {

{displaySubProject &&
issue.subProject != null &&
<span>
<span title={issue.subProjectName}>
<Link to={getProjectUrl(issue.subProject)} className="link-no-underline">
{limitComponentName(issue.subProjectName)}
</Link>
@@ -64,7 +64,9 @@ export default class ComponentBreadcrumbs extends React.PureComponent {
</span>}

<Link to={getProjectUrl(issue.component)} className="link-no-underline">
{collapsePath(issue.componentLongName)}
<span title={issue.componentLongName}>
{collapsePath(issue.componentLongName)}
</span>
</Link>
</div>
);

+ 1
- 1
server/sonar-web/src/main/js/apps/issues/components/IssuesCounter.js Vedi File

@@ -30,7 +30,7 @@ type Props = {
const IssuesCounter = (props: Props) => (
<span>
<strong>
{props.current != null && <span>{props.current + 1} / </span>}
{props.current != null && <span>{formatMeasure(props.current + 1, 'INT')} / </span>}
{formatMeasure(props.total, 'INT')}
</strong>
{' '}

+ 31
- 0
server/sonar-web/src/main/js/apps/issues/components/__tests__/IssuesContainer-test.js Vedi File

@@ -0,0 +1,31 @@
/*
* SonarQube
* Copyright (C) 2009-2017 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.
*/
// @flow
import React from 'react';
import { shallow } from 'enzyme';
import IssuesCounter from '../IssuesCounter';

it('formats numbers', () => {
expect(shallow(<IssuesCounter current={1234} total={987654321} />)).toMatchSnapshot();
});

it('does not show current', () => {
expect(shallow(<IssuesCounter current={null} total={987654321} />)).toMatchSnapshot();
});

+ 25
- 0
server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesContainer-test.js.snap Vedi File

@@ -0,0 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`does not show current 1`] = `
<span>
<strong>
987,654,321
</strong>
issues.issues
</span>
`;

exports[`formats numbers 1`] = `
<span>
<strong>
<span>
1,235
/
</span>
987,654,321
</strong>
issues.issues
</span>
`;

+ 52
- 44
server/sonar-web/src/main/js/apps/issues/sidebar/CreationDateFacet.js Vedi File

@@ -19,11 +19,11 @@
*/
// @flow
import React from 'react';
import classNames from 'classnames';
import moment from 'moment';
import { max } from 'lodash';
import FacetBox from './components/FacetBox';
import FacetHeader from './components/FacetHeader';
import FacetItem from './components/FacetItem';
import { BarChart } from '../../../components/charts/bar-chart';
import DateInput from '../../../components/controls/DateInput';
import { translate } from '../../../helpers/l10n';
@@ -55,6 +55,13 @@ export default class CreationDateFacet extends React.PureComponent {

property = 'createdAt';

hasValue = (): boolean =>
this.props.createdAfter.length > 0 ||
this.props.createdAt.length > 0 ||
this.props.createdBefore.length > 0 ||
this.props.createdInLast.length > 0 ||
this.props.sinceLeakPeriod;

handleHeaderClick = () => {
this.props.onToggle(this.property);
};
@@ -93,15 +100,11 @@ export default class CreationDateFacet extends React.PureComponent {
});
};

handlePeriodClick = (period?: string) => (e: Event & { target: HTMLElement }) => {
e.preventDefault();
e.target.blur;
handlePeriodClick = (period: string) => {
this.resetTo({ createdInLast: period });
};

handleLeakPeriodClick = () => (e: Event & { target: HTMLElement }) => {
e.preventDefault();
e.target.blur;
handleLeakPeriodClick = () => {
this.resetTo({ sinceLeakPeriod: true });
};

@@ -200,39 +203,51 @@ export default class CreationDateFacet extends React.PureComponent {
renderPrefefinedPeriods() {
const { component, createdInLast, sinceLeakPeriod } = this.props;
return (
<div className="spacer-top">
<span className="spacer-right">{translate('issues.facet.createdAt.or')}</span>
<a className="spacer-right" href="#" onClick={this.handlePeriodClick()}>
{translate('issues.facet.createdAt.all')}
</a>
<div className="spacer-top issues-predefined-periods">
<FacetItem
active={!this.hasValue()}
facetMode=""
name={translate('issues.facet.createdAt.all')}
onClick={this.handlePeriodClick}
stat={null}
value=""
/>
{component == null &&
<a
className={classNames('spacer-right', { 'active-link': createdInLast === '1w' })}
href="#"
onClick={this.handlePeriodClick('1w')}>
{translate('issues.facet.createdAt.last_week')}
</a>}
<FacetItem
active={createdInLast === '1w'}
facetMode=""
name={translate('issues.facet.createdAt.last_week')}
onClick={this.handlePeriodClick}
stat={null}
value="1w"
/>}
{component == null &&
<a
className={classNames('spacer-right', { 'active-link': createdInLast === '1m' })}
href="#"
onClick={this.handlePeriodClick('1m')}>
{translate('issues.facet.createdAt.last_month')}
</a>}
<FacetItem
active={createdInLast === '1m'}
facetMode=""
name={translate('issues.facet.createdAt.last_month')}
onClick={this.handlePeriodClick}
stat={null}
value="1m"
/>}
{component == null &&
<a
className={classNames('spacer-right', { 'active-link': createdInLast === '1y' })}
href="#"
onClick={this.handlePeriodClick('1y')}>
{translate('issues.facet.createdAt.last_year')}
</a>}
<FacetItem
active={createdInLast === '1y'}
facetMode=""
name={translate('issues.facet.createdAt.last_year')}
onClick={this.handlePeriodClick}
stat={null}
value="1y"
/>}
{component != null &&
<a
className={classNames('spacer-right', { 'active-link': sinceLeakPeriod })}
href="#"
onClick={this.handleLeakPeriodClick()}>
{translate('issues.leak_period')}
</a>}
<FacetItem
active={sinceLeakPeriod}
facetMode=""
name={translate('issues.leak_period')}
onClick={this.handleLeakPeriodClick}
stat={null}
value=""
/>}
</div>
);
}
@@ -249,13 +264,6 @@ export default class CreationDateFacet extends React.PureComponent {
}

render() {
const hasValue =
this.props.createdAfter.length > 0 ||
this.props.createdAt.length > 0 ||
this.props.createdBefore.length > 0 ||
this.props.createdInLast.length > 0 ||
this.props.sinceLeakPeriod;

return (
<FacetBox property={this.property}>
<FacetHeader
@@ -263,7 +271,7 @@ export default class CreationDateFacet extends React.PureComponent {
onClear={this.handleClear}
onClick={this.handleHeaderClick}
open={this.props.open}
values={hasValue ? 1 : 0}
values={this.hasValue() ? 1 : 0}
/>

{this.props.open && this.renderInner()}

+ 9
- 0
server/sonar-web/src/main/js/apps/issues/styles.css Vedi File

@@ -216,3 +216,12 @@
.issues-workspace-list-component + .issues-workspace-list-item {
margin-top: 0;
}

.issues-predefined-periods {
display: flex;
}

.issues-predefined-periods .search-navigator-facet {
width: auto;
margin-right: 4px;
}

+ 1
- 0
server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js Vedi File

@@ -158,6 +158,7 @@ export default class SourceViewerCode extends React.PureComponent {
issueLocations={this.getIssueLocationsForLine(line)}
issues={issuesForLine}
key={line.line}
last={index === this.props.sources.length - 1 && !this.props.hasSourcesAfter}
line={line}
loadDuplications={this.props.loadDuplications}
onClick={this.props.onLineClick}

+ 3
- 1
server/sonar-web/src/main/js/components/SourceViewer/components/Line.js Vedi File

@@ -46,6 +46,7 @@ type Props = {|
highlightedSymbols?: Array<string>,
issueLocations: Array<LinearIssueLocation>,
issues: Array<Issue>,
last: boolean,
line: SourceLine,
loadDuplications: (SourceLine, HTMLElement) => void,
onClick: (SourceLine, HTMLElement) => void,
@@ -94,7 +95,8 @@ export default class Line extends React.PureComponent {
const className = classNames('source-line', {
'source-line-highlighted': this.props.highlighted,
'source-line-shadowed': filtered === false,
'source-line-filtered': filtered === true
'source-line-filtered': filtered === true,
'source-line-last': this.props.last
});

return (

+ 5
- 0
server/sonar-web/src/main/less/components/issues.less Vedi File

@@ -366,4 +366,9 @@ input.issue-action-options-search {

.issue:not(.selected) .location-index {
background-color: #ccc;
}

.issue .menu {
max-height: 120px;
overflow: auto;
}

+ 4
- 0
server/sonar-web/src/main/less/components/source.less Vedi File

@@ -89,6 +89,10 @@
}
}

.source-line-last .source-line-code-inner {
padding-bottom: 80px;
}

.source-viewer pre {
height: @source-line-height;
padding: 0;

+ 0
- 1
sonar-core/src/main/resources/org/sonar/l10n/core.properties Vedi File

@@ -797,7 +797,6 @@ issues.facet.rules=Rule
issues.facet.resolutions=Resolution
issues.facet.languages=Language
issues.facet.createdAt=Creation Date
issues.facet.createdAt.or=Or:
issues.facet.createdAt.all=All
issues.facet.createdAt.last_week=Last week
issues.facet.createdAt.last_month=Last month

Loading…
Annulla
Salva