Ver código fonte

SONAR-12285 Load issues until opened one is found

tags/8.0
Wouter Admiraal 4 anos atrás
pai
commit
f1ba685b86

+ 43
- 23
server/sonar-web/src/main/js/apps/issues/components/App.tsx Ver arquivo

@@ -116,6 +116,7 @@ interface Props {

export interface State {
bulkChangeModal: boolean;
cannotShowOpenIssue?: boolean;
checkAll?: boolean;
checked: string[];
effortTotal?: number;
@@ -142,6 +143,7 @@ export interface State {
}

const DEFAULT_QUERY = { resolved: 'false' };
const MAX_INITAL_FETCH = 1000;

export class App extends React.PureComponent<Props, State> {
mounted = false;
@@ -459,8 +461,25 @@ export class App extends React.PureComponent<Props, State> {

fetchFirstIssues() {
const prevQuery = this.props.location.query;
const openIssueKey = getOpen(this.props.location.query);
let fetchPromise;

this.setState({ checked: [], loading: true });
return this.fetchIssues({}, true).then(
if (openIssueKey !== undefined) {
fetchPromise = this.fetchIssuesUntil(1, (pageIssues: T.Issue[], paging: T.Paging) => {
if (
paging.total <= paging.pageIndex * paging.pageSize ||
paging.pageIndex * paging.pageSize >= MAX_INITAL_FETCH
) {
return true;
}
return pageIssues.some(issue => issue.key === openIssueKey);
});
} else {
fetchPromise = this.fetchIssues({}, true);
}

return fetchPromise.then(
({ effortTotal, facets, issues, paging, ...other }) => {
if (this.mounted && areQueriesEqual(prevQuery, this.props.location.query)) {
const openIssue = this.getOpenIssue(this.props, issues);
@@ -469,6 +488,7 @@ export class App extends React.PureComponent<Props, State> {
selected = openIssue ? openIssue.key : issues[0].key;
}
this.setState(state => ({
cannotShowOpenIssue: Boolean(openIssueKey && !openIssue),
effortTotal,
facets: { ...state.facets, ...parseFacets(facets) },
loading: false,
@@ -502,24 +522,15 @@ export class App extends React.PureComponent<Props, State> {

fetchIssuesUntil = (
p: number,
done: (lastIssue: T.Issue, paging: T.Paging) => boolean
): Promise<{ issues: T.Issue[]; paging: T.Paging }> => {
const recursiveFetch = (
p: number,
issues: T.Issue[]
): Promise<{ issues: T.Issue[]; paging: T.Paging }> => {
return this.fetchIssuesPage(p)
.then(response => {
return {
issues: [...issues, ...response.issues],
paging: response.paging
};
})
.then(({ issues, paging }) => {
return done(issues[issues.length - 1], paging)
? { issues, paging }
: recursiveFetch(p + 1, issues);
});
done: (pageIssues: T.Issue[], paging: T.Paging) => boolean
): Promise<FetchIssuesPromise> => {
const recursiveFetch = (p: number, prevIssues: T.Issue[]): Promise<FetchIssuesPromise> => {
return this.fetchIssuesPage(p).then(({ issues: pageIssues, paging, ...other }) => {
const issues = [...prevIssues, ...pageIssues];
return done(pageIssues, paging)
? { issues, paging, ...other }
: recursiveFetch(p + 1, issues);
});
};

return recursiveFetch(p, []);
@@ -562,7 +573,8 @@ export class App extends React.PureComponent<Props, State> {

const isSameComponent = (issue: T.Issue) => issue.component === openIssue.component;

const done = (lastIssue: T.Issue, paging: T.Paging) => {
const done = (pageIssues: T.Issue[], paging: T.Paging) => {
const lastIssue = pageIssues[pageIssues.length - 1];
if (paging.total <= paging.pageIndex * paging.pageSize) {
return true;
}
@@ -572,7 +584,7 @@ export class App extends React.PureComponent<Props, State> {
return lastIssue.textRange !== undefined && lastIssue.textRange.endLine > to;
};

if (done(issues[issues.length - 1], paging)) {
if (done(issues, paging)) {
return Promise.resolve(issues.filter(isSameComponent));
}

@@ -820,7 +832,7 @@ export class App extends React.PureComponent<Props, State> {

handleReloadAndOpenFirst = () => {
this.fetchFirstIssues().then(
issues => {
(issues: T.Issue[]) => {
if (issues.length > 0) {
this.openIssue(issues[0].key);
}
@@ -1107,7 +1119,7 @@ export class App extends React.PureComponent<Props, State> {
}

renderPage() {
const { checkAll, issues, loading, openIssue, paging } = this.state;
const { cannotShowOpenIssue, checkAll, issues, loading, openIssue, paging } = this.state;
return (
<div className="layout-page-main-inner">
{openIssue ? (
@@ -1134,6 +1146,14 @@ export class App extends React.PureComponent<Props, State> {
/>
</Alert>
)}
{cannotShowOpenIssue && (
<Alert className="big-spacer-bottom" variant="warning">
{translateWithParameters(
'issues.cannot_open_issue_max_initial_X_fetched',
MAX_INITAL_FETCH
)}
</Alert>
)}
{this.renderList()}
</DeferredSpinner>
)}

+ 1
- 1
server/sonar-web/src/main/js/apps/issues/components/__tests__/App-test.tsx Ver arquivo

@@ -304,7 +304,7 @@ it('should correctly handle filter changes', () => {
});

it('should fetch issues until defined', async () => {
const mockDone = (_lastIssue: T.Issue, paging: T.Paging) =>
const mockDone = (_: T.Issue[], paging: T.Paging) =>
paging.total <= paging.pageIndex * paging.pageSize;

const wrapper = shallowRender({

+ 1
- 1
server/sonar-web/src/main/js/apps/issues/utils.ts Ver arquivo

@@ -106,7 +106,7 @@ export function parseQuery(query: T.RawQuery): Query {
};
}

export function getOpen(query: T.RawQuery): string {
export function getOpen(query: T.RawQuery): string | undefined {
return query.open;
}


+ 1
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties Ver arquivo

@@ -667,6 +667,7 @@ issue.filter_similar_issues=Filter Similar Issues
issue.this_issue_involves_x_code_locations=This issue involves {0} code location(s)
issue.from_external_rule_engine=Issue detected by an external rule engine: {0}
issue.external_issue_description=This is external rule {0}. No details are available.
issues.cannot_open_issue_max_initial_X_fetched=Cannot open selected issue, as it's not part of the initial {0} loaded issues.
issues.return_to_list=Return to List
issues.bulk_change_X_issues=Bulk Change {0} Issue(s)
issues.select_all_issues=Select all Issues

Carregando…
Cancelar
Salvar