From 9d5f9c6bb4beff1cd29dc836c9960ced17f4e67f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Fri, 10 Aug 2018 15:01:30 +0200 Subject: [PATCH] SONAR-11123 Avoid duplicate API call to api/organizations/search in org projects page --- .../sonar-web/src/main/js/api/components.ts | 7 +++- .../src/main/js/app/styles/init/icons.css | 1 + .../apps/projects/components/AllProjects.tsx | 32 ++++++++----------- .../src/main/js/apps/projects/utils.ts | 28 ++++++++++------ 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/server/sonar-web/src/main/js/api/components.ts b/server/sonar-web/src/main/js/api/components.ts index c917f8a4460..f6e83e322b9 100644 --- a/server/sonar-web/src/main/js/api/components.ts +++ b/server/sonar-web/src/main/js/api/components.ts @@ -174,7 +174,12 @@ export interface Facet { export function searchProjects( data: RequestData -): Promise<{ components: Component[]; facets: Facet[]; paging: Paging }> { +): Promise<{ + components: Component[]; + facets: Facet[]; + organizations: Array<{ key: string; name: string }>; + paging: Paging; +}> { const url = '/api/components/search_projects'; return getJSON(url, data); } diff --git a/server/sonar-web/src/main/js/app/styles/init/icons.css b/server/sonar-web/src/main/js/app/styles/init/icons.css index 38d782a3a8a..8acdf0079e1 100644 --- a/server/sonar-web/src/main/js/app/styles/init/icons.css +++ b/server/sonar-web/src/main/js/app/styles/init/icons.css @@ -68,6 +68,7 @@ a[class*=' icon-'] { box-shadow 0.4s ease; } +.icon-checkbox:focus:before, .link-checkbox:focus:focus .icon-checkbox:before { box-shadow: 0 0 0 3px rgba(35, 106, 151, 0.25); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx index e0b234e235d..2bf13b590b5 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx @@ -118,11 +118,7 @@ export default class AllProjects extends React.PureComponent { fetchProjects = (query: any) => { this.setState({ loading: true, query }); - fetchProjects( - query, - this.props.isFavorite, - this.props.organization && this.props.organization.key - ).then(response => { + fetchProjects(query, this.props.isFavorite, this.props.organization).then(response => { if (this.mounted) { this.setState({ facets: response.facets, @@ -139,20 +135,18 @@ export default class AllProjects extends React.PureComponent { const { pageIndex, projects, query } = this.state; if (pageIndex && projects && query) { this.setState({ loading: true }); - fetchProjects( - query, - this.props.isFavorite, - this.props.organization && this.props.organization.key, - pageIndex + 1 - ).then(response => { - if (this.mounted) { - this.setState({ - loading: false, - pageIndex: pageIndex + 1, - projects: [...projects, ...response.projects] - }); - } - }, this.stopLoading); + fetchProjects(query, this.props.isFavorite, this.props.organization, pageIndex + 1).then( + response => { + if (this.mounted) { + this.setState({ + loading: false, + pageIndex: pageIndex + 1, + projects: [...projects, ...response.projects] + }); + } + }, + this.stopLoading + ); } }; diff --git a/server/sonar-web/src/main/js/apps/projects/utils.ts b/server/sonar-web/src/main/js/apps/projects/utils.ts index 474b8d89e8e..61ea473403f 100644 --- a/server/sonar-web/src/main/js/apps/projects/utils.ts +++ b/server/sonar-web/src/main/js/apps/projects/utils.ts @@ -26,6 +26,7 @@ import { getOrganizations } from '../../api/organizations'; import { searchProjects, Facet } from '../../api/components'; import { getMeasuresForProjects } from '../../api/measures'; import { isDiffMetric, getPeriodValue } from '../../helpers/measures'; +import { Organization } from '../../app/types'; interface SortingOption { class?: string; @@ -164,21 +165,25 @@ export function parseSorting(sort: string): { sortValue: string; sortDesc: boole export function fetchProjects( query: Query, isFavorite: boolean, - organization?: string, + organization: Organization | undefined, pageIndex = 1 ) { const ps = query.view === 'visualizations' ? PAGE_SIZE_VISUALIZATIONS : PAGE_SIZE; - const data = convertToQueryData(query, isFavorite, organization, { + const data = convertToQueryData(query, isFavorite, organization && organization.key, { p: pageIndex > 1 ? pageIndex : undefined, ps, facets: defineFacets(query).join(), f: 'analysisDate,leakPeriodDate' }); - return searchProjects(data).then(({ components, facets, paging }) => { - return Promise.all([ - fetchProjectMeasures(components, query), - fetchProjectOrganizations(components) - ]).then(([measures, organizations]) => { + return searchProjects(data) + .then(response => + Promise.all([ + fetchProjectMeasures(response.components, query), + fetchProjectOrganizations(response.components, organization), + Promise.resolve(response) + ]) + ) + .then(([measures, organizations, { components, facets, paging }]) => { return { facets: getFacetsMap(facets), projects: components @@ -201,7 +206,6 @@ export function fetchProjects( total: paging.total }; }); - }); } function defineMetrics(query: Query): string[] { @@ -254,7 +258,13 @@ function fetchProjectMeasures(projects: Array<{ key: string }>, query: Query) { return getMeasuresForProjects(projectKeys, metrics); } -function fetchProjectOrganizations(projects: Array<{ organization: string }>) { +function fetchProjectOrganizations( + projects: Array<{ organization: string }>, + organization: Organization | undefined +) { + if (organization) { + return Promise.resolve([organization]); + } if (!projects.length) { return Promise.resolve([]); } -- 2.39.5