diff options
author | Stas Vilchik <stas-vilchik@users.noreply.github.com> | 2017-03-17 09:10:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-17 09:10:48 +0100 |
commit | de4365079bad2df3bdee2133576dc913ffbf1ab2 (patch) | |
tree | a522ccb952f0d37f454e8188e13b3dec3f731912 /server/sonar-web/src/main | |
parent | 6a03df65cc0c91a26150ea172a2c480e07326ea1 (diff) | |
download | sonarqube-de4365079bad2df3bdee2133576dc913ffbf1ab2.tar.gz sonarqube-de4365079bad2df3bdee2133576dc913ffbf1ab2.zip |
format code using prettier (#1774)
Diffstat (limited to 'server/sonar-web/src/main')
1054 files changed, 15585 insertions, 15664 deletions
diff --git a/server/sonar-web/src/main/js/api/auth.js b/server/sonar-web/src/main/js/api/auth.js index 6efcfa3fb87..801e37189af 100644 --- a/server/sonar-web/src/main/js/api/auth.js +++ b/server/sonar-web/src/main/js/api/auth.js @@ -29,17 +29,12 @@ const basicCheckStatus = response => { } }; -export const login = (login, password) => ( - request('/api/authentication/login') - .setMethod('POST') - .setData({ login, password }) - .submit() - .then(basicCheckStatus) -); +export const login = (login, password) => + request('/api/authentication/login') + .setMethod('POST') + .setData({ login, password }) + .submit() + .then(basicCheckStatus); -export const logout = () => ( - request('/api/authentication/logout') - .setMethod('POST') - .submit() - .then(basicCheckStatus) -); +export const logout = () => + request('/api/authentication/logout').setMethod('POST').submit().then(basicCheckStatus); diff --git a/server/sonar-web/src/main/js/api/ce.js b/server/sonar-web/src/main/js/api/ce.js index c673cb7e40a..4f73f4cc948 100644 --- a/server/sonar-web/src/main/js/api/ce.js +++ b/server/sonar-web/src/main/js/api/ce.js @@ -20,9 +20,7 @@ // @flow import { getJSON, post } from '../helpers/request'; -export const getActivity = (data?: Object): Promise<*> => ( - getJSON('/api/ce/activity', data) -); +export const getActivity = (data?: Object): Promise<*> => getJSON('/api/ce/activity', data); export const getStatus = (componentId?: string): Promise<*> => { const data = {}; @@ -32,22 +30,15 @@ export const getStatus = (componentId?: string): Promise<*> => { return getJSON('/api/ce/activity_status', data); }; -export const getTask = (id: string, additionalFields?: Array<string>): Promise<*> => ( - getJSON('/api/ce/task', { id, additionalFields }).then(r => r.task) -); +export const getTask = (id: string, additionalFields?: Array<string>): Promise<*> => + getJSON('/api/ce/task', { id, additionalFields }).then(r => r.task); -export const cancelTask = (id: string): Promise<*> => ( - post('/api/ce/cancel', { id }).then(() => getTask(id), () => getTask(id)) -); +export const cancelTask = (id: string): Promise<*> => + post('/api/ce/cancel', { id }).then(() => getTask(id), () => getTask(id)); -export const cancelAllTasks = (): Promise<*> => ( - post('/api/ce/cancel_all') -); +export const cancelAllTasks = (): Promise<*> => post('/api/ce/cancel_all'); -export const getTasksForComponent = (componentId: string): Promise<*> => ( - getJSON('/api/ce/component', { componentId }) -); +export const getTasksForComponent = (componentId: string): Promise<*> => + getJSON('/api/ce/component', { componentId }); -export const getTypes = (): Promise<*> => ( - getJSON('/api/ce/task_types').then(r => r.taskTypes) -); +export const getTypes = (): Promise<*> => getJSON('/api/ce/task_types').then(r => r.taskTypes); diff --git a/server/sonar-web/src/main/js/api/components.js b/server/sonar-web/src/main/js/api/components.js index f0469af18ec..c2ec0a454f5 100644 --- a/server/sonar-web/src/main/js/api/components.js +++ b/server/sonar-web/src/main/js/api/components.js @@ -20,57 +20,59 @@ // @flow import { getJSON, postJSON, post } from '../helpers/request'; -export function getComponents (data?: Object) { +export function getComponents(data?: Object) { const url = '/api/projects/search'; return getJSON(url, data); } -export function getProvisioned (data?: Object) { +export function getProvisioned(data?: Object) { const url = '/api/projects/provisioned'; return getJSON(url, data); } -export function getGhosts (data?: Object) { +export function getGhosts(data?: Object) { const url = '/api/projects/ghosts'; return getJSON(url, data); } -export function deleteComponents (data: { projects: string, organization?: string }) { +export function deleteComponents(data: { projects: string, organization?: string }) { const url = '/api/projects/bulk_delete'; return post(url, data); } -export function deleteProject (project: string) { +export function deleteProject(project: string) { const url = '/api/projects/delete'; const data = { project }; return post(url, data); } -export function createProject (data: { - branch?: string, - name: string, - project: string, - organization?: string -}) { +export function createProject( + data: { + branch?: string, + name: string, + project: string, + organization?: string + } +) { const url = '/api/projects/create'; return postJSON(url, data); } -export function searchProjectTags (data?: { ps?: number, q?: string }) { +export function searchProjectTags(data?: { ps?: number, q?: string }) { const url = '/api/project_tags/search'; return getJSON(url, data); } -export function setProjectTags (data: { project: string, tags: string }) { +export function setProjectTags(data: { project: string, tags: string }) { const url = '/api/project_tags/set'; return postJSON(url, data); } -export function getComponentTree ( - strategy: string, - componentKey: string, - metrics: Array<string> = [], - additional?: Object = {} +export function getComponentTree( + strategy: string, + componentKey: string, + metrics: Array<string> = [], + additional?: Object = {} ) { const url = '/api/measures/component_tree'; const data = Object.assign({}, additional, { @@ -81,33 +83,37 @@ export function getComponentTree ( return getJSON(url, data); } -export function getChildren (componentKey: string, metrics?: Array<string>, additional?: Object) { +export function getChildren(componentKey: string, metrics?: Array<string>, additional?: Object) { return getComponentTree('children', componentKey, metrics, additional); } -export function getComponentLeaves (componentKey: string, metrics?: Array<string>, additional?: Object) { +export function getComponentLeaves( + componentKey: string, + metrics?: Array<string>, + additional?: Object +) { return getComponentTree('leaves', componentKey, metrics, additional); } -export function getComponent (componentKey: string, metrics: Array<string> = []) { +export function getComponent(componentKey: string, metrics: Array<string> = []) { const url = '/api/measures/component'; const data = { componentKey, metricKeys: metrics.join(',') }; return getJSON(url, data).then(r => r.component); } -export function getTree (component: string, options?: Object = {}) { +export function getTree(component: string, options?: Object = {}) { const url = '/api/components/tree'; const data = { ...options, component }; return getJSON(url, data); } -export function getParents ({ id, key }: { id: string, key: string }) { +export function getParents({ id, key }: { id: string, key: string }) { const url = '/api/components/show'; const data = id ? { id } : { key }; return getJSON(url, data).then(r => r.ancestors); } -export function getBreadcrumbs (component: string) { +export function getBreadcrumbs(component: string) { const url = '/api/components/show'; return getJSON(url, { component }).then(r => { const reversedAncestors = [...r.ancestors].reverse(); @@ -115,12 +121,12 @@ export function getBreadcrumbs (component: string) { }); } -export function getMyProjects (data?: Object) { +export function getMyProjects(data?: Object) { const url = '/api/projects/search_my_projects'; return getJSON(url, data); } -export function searchProjects (data?: Object) { +export function searchProjects(data?: Object) { const url = '/api/components/search_projects'; return getJSON(url, data); } @@ -131,7 +137,7 @@ export function searchProjects (data?: Object) { * @param {string} to * @returns {Promise} */ -export function changeKey (from: string, to: string) { +export function changeKey(from: string, to: string) { const url = '/api/projects/update_key'; const data = { from, to }; return post(url, data); @@ -145,19 +151,17 @@ export function changeKey (from: string, to: string) { * @param {boolean} dryRun * @returns {Promise} */ -export function bulkChangeKey (project: string, from: string, to: string, dryRun?: boolean = false) { +export function bulkChangeKey(project: string, from: string, to: string, dryRun?: boolean = false) { const url = '/api/projects/bulk_update_key'; const data = { project, from, to, dryRun }; return postJSON(url, data); } -export const getSuggestions = (query: string): Promise<Object> => ( - getJSON('/api/components/suggestions', { s: query }) -); +export const getSuggestions = (query: string): Promise<Object> => + getJSON('/api/components/suggestions', { s: query }); -export const getComponentForSourceViewer = (component: string): Promise<*> => ( - getJSON('/api/components/app', { component }) -); +export const getComponentForSourceViewer = (component: string): Promise<*> => + getJSON('/api/components/app', { component }); export const getSources = (component: string, from?: number, to?: number): Promise<Array<*>> => { const data: Object = { key: component }; @@ -170,10 +174,10 @@ export const getSources = (component: string, from?: number, to?: number): Promi return getJSON('/api/sources/lines', data).then(r => r.sources); }; -export const getDuplications = (component: string): Promise<*> => ( - getJSON('/api/duplications/show', { key: component }) -); +export const getDuplications = (component: string): Promise<*> => + getJSON('/api/duplications/show', { key: component }); -export const getTests = (component: string, line: number | string): Promise<*> => ( - getJSON('/api/tests/list', { sourceFileKey: component, sourceFileLineNumber: line }).then(r => r.tests) -); +export const getTests = (component: string, line: number | string): Promise<*> => + getJSON('/api/tests/list', { sourceFileKey: component, sourceFileLineNumber: line }).then( + r => r.tests + ); diff --git a/server/sonar-web/src/main/js/api/favorites.js b/server/sonar-web/src/main/js/api/favorites.js index 5c855447bfe..77cef860c49 100644 --- a/server/sonar-web/src/main/js/api/favorites.js +++ b/server/sonar-web/src/main/js/api/favorites.js @@ -20,14 +20,12 @@ /* @flow */ import { post, getJSON } from '../helpers/request'; -export const getFavorites = (): Promise<Object> => ( - getJSON('/api/favorites/search') -); +export const getFavorites = (): Promise<Object> => getJSON('/api/favorites/search'); -export function addFavorite (component: string) { +export function addFavorite(component: string) { return post('/api/favorites/add', { component }); } -export function removeFavorite (component: string) { +export function removeFavorite(component: string) { return post('/api/favorites/remove', { component }); } diff --git a/server/sonar-web/src/main/js/api/issue-filters.js b/server/sonar-web/src/main/js/api/issue-filters.js index 3a0eff2736e..a5336c2dbe2 100644 --- a/server/sonar-web/src/main/js/api/issue-filters.js +++ b/server/sonar-web/src/main/js/api/issue-filters.js @@ -19,7 +19,7 @@ */ import { post } from '../helpers/request'; -export function toggleIssueFilter (id) { +export function toggleIssueFilter(id) { const url = '/issues/toggle_fav'; const data = { id }; return post(url, data); diff --git a/server/sonar-web/src/main/js/api/issues.js b/server/sonar-web/src/main/js/api/issues.js index 75cbdec6e2d..cb5bfeb951e 100644 --- a/server/sonar-web/src/main/js/api/issues.js +++ b/server/sonar-web/src/main/js/api/issues.js @@ -34,11 +34,10 @@ type IssuesResponse = { users?: Array<*> }; -export const searchIssues = (query: {}): Promise<IssuesResponse> => ( - getJSON('/api/issues/search', query) -); +export const searchIssues = (query: {}): Promise<IssuesResponse> => + getJSON('/api/issues/search', query); -export function getFacets (query: {}, facets: Array<string>): Promise<*> { +export function getFacets(query: {}, facets: Array<string>): Promise<*> { const data = { ...query, facets: facets.join(), @@ -50,53 +49,47 @@ export function getFacets (query: {}, facets: Array<string>): Promise<*> { }); } -export function getFacet (query: {}, facet: string): Promise<*> { +export function getFacet(query: {}, facet: string): Promise<*> { return getFacets(query, [facet]).then(r => { return { facet: r.facets[0].values, response: r.response }; }); } -export function getSeverities (query: {}): Promise<*> { +export function getSeverities(query: {}): Promise<*> { return getFacet(query, 'severities').then(r => r.facet); } -export function getTags (query: {}): Promise<*> { +export function getTags(query: {}): Promise<*> { return getFacet(query, 'tags').then(r => r.facet); } -export function extractAssignees ( - facet: Array<{ val: string }>, - response: IssuesResponse -) { +export function extractAssignees(facet: Array<{ val: string }>, response: IssuesResponse) { return facet.map(item => { const user = response.users ? response.users.find(user => user.login = item.val) : null; return { ...item, user }; }); } -export function getAssignees (query: {}): Promise<*> { +export function getAssignees(query: {}): Promise<*> { return getFacet(query, 'assignees').then(r => extractAssignees(r.facet, r.response)); } -export function getIssuesCount (query: {}): Promise<*> { +export function getIssuesCount(query: {}): Promise<*> { const data = { ...query, ps: 1, facetMode: 'effort' }; return searchIssues(data).then(r => { return { issues: r.paging.total, debt: r.debtTotal }; }); } -export const searchIssueTags = (ps: number = 500) => ( - getJSON('/api/issues/tags', { ps }) -); +export const searchIssueTags = (ps: number = 500) => getJSON('/api/issues/tags', { ps }); -export function getIssueFilters () { +export function getIssueFilters() { const url = '/api/issue_filters/search'; return getJSON(url).then(r => r.issueFilters); } -export const bulkChangeIssues = (issueKeys: Array<string>, query: {}) => ( - post('/api/issues/bulk_change', { - issues: issueKeys.join(), - ...query - }) -); +export const bulkChangeIssues = (issueKeys: Array<string>, query: {}) => + post('/api/issues/bulk_change', { + issues: issueKeys.join(), + ...query + }); diff --git a/server/sonar-web/src/main/js/api/languages.js b/server/sonar-web/src/main/js/api/languages.js index 151f53e4616..5f58849b1ed 100644 --- a/server/sonar-web/src/main/js/api/languages.js +++ b/server/sonar-web/src/main/js/api/languages.js @@ -19,7 +19,7 @@ */ import { getJSON } from '../helpers/request'; -export function getLanguages () { +export function getLanguages() { const url = '/api/languages/list'; return getJSON(url).then(r => r.languages); } diff --git a/server/sonar-web/src/main/js/api/licenses.js b/server/sonar-web/src/main/js/api/licenses.js index 43b6b01e06a..49c8df01978 100644 --- a/server/sonar-web/src/main/js/api/licenses.js +++ b/server/sonar-web/src/main/js/api/licenses.js @@ -19,8 +19,7 @@ */ import { getJSON, post } from '../helpers/request'; -export const getLicenses = () => - getJSON('/api/licenses/list').then(r => r.licenses); +export const getLicenses = () => getJSON('/api/licenses/list').then(r => r.licenses); export const setLicense = (key, value) => { const url = '/api/settings/set'; diff --git a/server/sonar-web/src/main/js/api/measures.js b/server/sonar-web/src/main/js/api/measures.js index 6c853cee9a5..2ad2f9643c2 100644 --- a/server/sonar-web/src/main/js/api/measures.js +++ b/server/sonar-web/src/main/js/api/measures.js @@ -19,13 +19,13 @@ */ import { getJSON } from '../helpers/request'; -export function getMeasures (componentKey, metrics) { +export function getMeasures(componentKey, metrics) { const url = '/api/measures/component'; const data = { componentKey, metricKeys: metrics.join(',') }; return getJSON(url, data).then(r => r.component.measures); } -export function getMeasuresAndMeta (componentKey, metrics, additional = {}) { +export function getMeasuresAndMeta(componentKey, metrics, additional = {}) { const url = '/api/measures/component'; const data = Object.assign({}, additional, { componentKey, @@ -34,9 +34,8 @@ export function getMeasuresAndMeta (componentKey, metrics, additional = {}) { return getJSON(url, data); } -export const getMeasuresForProjects = (projectKeys, metricKeys) => ( - getJSON('/api/measures/search', { - projectKeys: projectKeys.join(), - metricKeys: metricKeys.join() - }) -); +export const getMeasuresForProjects = (projectKeys, metricKeys) => + getJSON('/api/measures/search', { + projectKeys: projectKeys.join(), + metricKeys: metricKeys.join() + }); diff --git a/server/sonar-web/src/main/js/api/metrics.js b/server/sonar-web/src/main/js/api/metrics.js index 2f9129a8c1d..b48abd7ed2e 100644 --- a/server/sonar-web/src/main/js/api/metrics.js +++ b/server/sonar-web/src/main/js/api/metrics.js @@ -19,7 +19,7 @@ */ import { getJSON } from '../helpers/request'; -export function getMetrics () { +export function getMetrics() { const url = '/api/metrics/search'; const data = { ps: 9999 }; return getJSON(url, data).then(r => r.metrics); diff --git a/server/sonar-web/src/main/js/api/nav.js b/server/sonar-web/src/main/js/api/nav.js index 6838cbd79ab..eacb2faa4f2 100644 --- a/server/sonar-web/src/main/js/api/nav.js +++ b/server/sonar-web/src/main/js/api/nav.js @@ -19,18 +19,18 @@ */ import { getJSON } from '../helpers/request'; -export function getGlobalNavigation () { +export function getGlobalNavigation() { const url = '/api/navigation/global'; return getJSON(url); } -export function getComponentNavigation (componentKey) { +export function getComponentNavigation(componentKey) { const url = '/api/navigation/component'; const data = { componentKey }; return getJSON(url, data); } -export function getSettingsNavigation () { +export function getSettingsNavigation() { const url = '/api/navigation/settings'; return getJSON(url); } diff --git a/server/sonar-web/src/main/js/api/notifications.js b/server/sonar-web/src/main/js/api/notifications.js index c4d2b35fb91..10c8749f59e 100644 --- a/server/sonar-web/src/main/js/api/notifications.js +++ b/server/sonar-web/src/main/js/api/notifications.js @@ -33,9 +33,8 @@ export type GetNotificationsResponse = { perProjectTypes: Array<string> }; -export const getNotifications = (): Promise<GetNotificationsResponse> => ( - getJSON('/api/notifications/list') -); +export const getNotifications = (): Promise<GetNotificationsResponse> => + getJSON('/api/notifications/list'); export const addNotification = (channel: string, type: string, project?: string): Promise<*> => { const data: Object = { channel, type }; diff --git a/server/sonar-web/src/main/js/api/organizations.js b/server/sonar-web/src/main/js/api/organizations.js index f56432e79c7..95de53bb6d9 100644 --- a/server/sonar-web/src/main/js/api/organizations.js +++ b/server/sonar-web/src/main/js/api/organizations.js @@ -29,9 +29,8 @@ export const getOrganizations = (organizations?: Array<string>) => { return getJSON('/api/organizations/search', data); }; -export const getMyOrganizations = () => ( - getJSON('/api/organizations/search_my_organizations').then(r => r.organizations) -); +export const getMyOrganizations = () => + getJSON('/api/organizations/search_my_organizations').then(r => r.organizations); type GetOrganizationType = null | Organization; @@ -48,14 +47,10 @@ export const getOrganizationNavigation = (key: string): Promise<GetOrganizationN return getJSON('/api/navigation/organization', { organization: key }).then(r => r.organization); }; -export const createOrganization = (fields: {}): Promise<Organization> => ( - postJSON('/api/organizations/create', fields).then(r => r.organization) -); +export const createOrganization = (fields: {}): Promise<Organization> => + postJSON('/api/organizations/create', fields).then(r => r.organization); -export const updateOrganization = (key: string, changes: {}) => ( - post('/api/organizations/update', { key, ...changes }) -); +export const updateOrganization = (key: string, changes: {}) => + post('/api/organizations/update', { key, ...changes }); -export const deleteOrganization = (key: string) => ( - post('/api/organizations/delete', { key }) -); +export const deleteOrganization = (key: string) => post('/api/organizations/delete', { key }); diff --git a/server/sonar-web/src/main/js/api/permissions.js b/server/sonar-web/src/main/js/api/permissions.js index 215143f92b9..2487ec4b1b6 100644 --- a/server/sonar-web/src/main/js/api/permissions.js +++ b/server/sonar-web/src/main/js/api/permissions.js @@ -17,16 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - // @flow +// @flow import { getJSON, post, postJSON } from '../helpers/request'; const PAGE_SIZE = 100; -export function grantPermissionToUser ( - projectKey: string | null, - login: string, - permission: string, - organization?: string +export function grantPermissionToUser( + projectKey: string | null, + login: string, + permission: string, + organization?: string ) { const url = '/api/permissions/add_user'; const data: Object = { login, permission }; @@ -39,11 +39,11 @@ export function grantPermissionToUser ( return post(url, data); } -export function revokePermissionFromUser ( - projectKey: string | null, - login: string, - permission: string, - organization?: string +export function revokePermissionFromUser( + projectKey: string | null, + login: string, + permission: string, + organization?: string ) { const url = '/api/permissions/remove_user'; const data: Object = { login, permission }; @@ -56,11 +56,11 @@ export function revokePermissionFromUser ( return post(url, data); } -export function grantPermissionToGroup ( - projectKey: string | null, - groupName: string, - permission: string, - organization?: string +export function grantPermissionToGroup( + projectKey: string | null, + groupName: string, + permission: string, + organization?: string ) { const url = '/api/permissions/add_group'; const data: Object = { groupName, permission }; @@ -73,11 +73,11 @@ export function grantPermissionToGroup ( return post(url, data); } -export function revokePermissionFromGroup ( - projectKey: string | null, - groupName: string, - permission: string, - organization?: string +export function revokePermissionFromGroup( + projectKey: string | null, + groupName: string, + permission: string, + organization?: string ) { const url = '/api/permissions/remove_group'; const data: Object = { groupName, permission }; @@ -94,22 +94,19 @@ export function revokePermissionFromGroup ( * Get list of permission templates * @returns {Promise} */ -export function getPermissionTemplates (organization?: string) { +export function getPermissionTemplates(organization?: string) { const url = '/api/permissions/search_templates'; return organization ? getJSON(url, { organization }) : getJSON(url); } -export const createPermissionTemplate = (data: Object) => ( - postJSON('/api/permissions/create_template', data) -); +export const createPermissionTemplate = (data: Object) => + postJSON('/api/permissions/create_template', data); -export const updatePermissionTemplate = (data: Object) => ( - post('/api/permissions/update_template', data) -); +export const updatePermissionTemplate = (data: Object) => + post('/api/permissions/update_template', data); -export const deletePermissionTemplate = (data: Object) => ( - post('/api/permissions/delete_template', data) -); +export const deletePermissionTemplate = (data: Object) => + post('/api/permissions/delete_template', data); /** * Set default permission template for a given qualifier @@ -117,61 +114,69 @@ export const deletePermissionTemplate = (data: Object) => ( * @param {string} qualifier * @returns {Promise} */ -export function setDefaultPermissionTemplate (templateId: string, qualifier: string) { +export function setDefaultPermissionTemplate(templateId: string, qualifier: string) { const url = '/api/permissions/set_default_template'; const data = { templateId, qualifier }; return post(url, data); } -export function applyTemplateToProject (data: Object) { +export function applyTemplateToProject(data: Object) { const url = '/api/permissions/apply_template'; return post(url, data); } -export function bulkApplyTemplate (data: Object) { +export function bulkApplyTemplate(data: Object) { const url = '/api/permissions/bulk_apply_template'; return post(url, data); } -export function grantTemplatePermissionToUser (templateId: string, login: string, permission: string) { +export function grantTemplatePermissionToUser( + templateId: string, + login: string, + permission: string +) { const url = '/api/permissions/add_user_to_template'; const data = { templateId, login, permission }; return post(url, data); } -export function revokeTemplatePermissionFromUser (templateId: string, login: string, permission: string) { +export function revokeTemplatePermissionFromUser( + templateId: string, + login: string, + permission: string +) { const url = '/api/permissions/remove_user_from_template'; const data = { templateId, login, permission }; return post(url, data); } -export function grantTemplatePermissionToGroup (data: Object) { +export function grantTemplatePermissionToGroup(data: Object) { const url = '/api/permissions/add_group_to_template'; return post(url, data); } -export function revokeTemplatePermissionFromGroup (data: Object) { +export function revokeTemplatePermissionFromGroup(data: Object) { const url = '/api/permissions/remove_group_from_template'; return post(url, data); } -export function addProjectCreatorToTemplate (templateId: string, permission: string) { +export function addProjectCreatorToTemplate(templateId: string, permission: string) { const url = '/api/permissions/add_project_creator_to_template'; const data = { templateId, permission }; return post(url, data); } -export function removeProjectCreatorFromTemplate (templateId: string, permission: string) { +export function removeProjectCreatorFromTemplate(templateId: string, permission: string) { const url = '/api/permissions/remove_project_creator_from_template'; const data = { templateId, permission }; return post(url, data); } -export function getPermissionsUsersForComponent ( - projectKey: string, - query?: string, - permission?: string, - organization?: string +export function getPermissionsUsersForComponent( + projectKey: string, + query?: string, + permission?: string, + organization?: string ) { const url = '/api/permissions/users'; const data: Object = { projectKey, ps: PAGE_SIZE }; @@ -187,11 +192,11 @@ export function getPermissionsUsersForComponent ( return getJSON(url, data).then(r => r.users); } -export function getPermissionsGroupsForComponent ( - projectKey: string, - query: string = '', - permission?: string, - organization?: string +export function getPermissionsGroupsForComponent( + projectKey: string, + query: string = '', + permission?: string, + organization?: string ) { const url = '/api/permissions/groups'; const data: Object = { projectKey, ps: PAGE_SIZE }; @@ -207,10 +212,10 @@ export function getPermissionsGroupsForComponent ( return getJSON(url, data).then(r => r.groups); } -export function getGlobalPermissionsUsers ( - query?: string, - permission?: string, - organization?: string +export function getGlobalPermissionsUsers( + query?: string, + permission?: string, + organization?: string ) { const url = '/api/permissions/users'; const data: Object = { ps: PAGE_SIZE }; @@ -226,10 +231,10 @@ export function getGlobalPermissionsUsers ( return getJSON(url, data).then(r => r.users); } -export function getGlobalPermissionsGroups ( - query?: string, - permission?: string, - organization?: string +export function getGlobalPermissionsGroups( + query?: string, + permission?: string, + organization?: string ) { const url = '/api/permissions/groups'; const data: Object = { ps: PAGE_SIZE }; @@ -245,11 +250,11 @@ export function getGlobalPermissionsGroups ( return getJSON(url, data).then(r => r.groups); } -export function getPermissionTemplateUsers ( - templateId: string, - query?: string, - permission?: string, - organization?: string +export function getPermissionTemplateUsers( + templateId: string, + query?: string, + permission?: string, + organization?: string ) { const url = '/api/permissions/template_users'; const data: Object = { templateId, ps: PAGE_SIZE }; @@ -265,11 +270,11 @@ export function getPermissionTemplateUsers ( return getJSON(url, data).then(r => r.users); } -export function getPermissionTemplateGroups ( - templateId: string, - query?: string, - permission?: string, - organization?: string +export function getPermissionTemplateGroups( + templateId: string, + query?: string, + permission?: string, + organization?: string ) { const url = '/api/permissions/template_groups'; const data: Object = { templateId, ps: PAGE_SIZE }; diff --git a/server/sonar-web/src/main/js/api/projectActivity.js b/server/sonar-web/src/main/js/api/projectActivity.js index c49aac032ea..131256b0696 100644 --- a/server/sonar-web/src/main/js/api/projectActivity.js +++ b/server/sonar-web/src/main/js/api/projectActivity.js @@ -36,8 +36,8 @@ type GetProjectActivityOptions = { }; export const getProjectActivity = ( - project: string, - options?: GetProjectActivityOptions + project: string, + options?: GetProjectActivityOptions ): Promise<GetProjectActivityResponse> => { const data: Object = { project }; if (options) { @@ -64,10 +64,10 @@ type CreateEventResponse = { }; export const createEvent = ( - analysis: string, - name: string, - category?: string, - description?: string + analysis: string, + name: string, + category?: string, + description?: string ): Promise<CreateEventResponse> => { const data: Object = { analysis, name }; if (category) { @@ -79,11 +79,14 @@ export const createEvent = ( return postJSON('/api/project_analyses/create_event', data).then(r => r.event); }; -export const deleteEvent = (event: string): Promise<*> => ( - post('/api/project_analyses/delete_event', { event }) -); +export const deleteEvent = (event: string): Promise<*> => + post('/api/project_analyses/delete_event', { event }); -export const changeEvent = (event: string, name: ?string, description: ?string): Promise<CreateEventResponse> => { +export const changeEvent = ( + event: string, + name: ?string, + description: ?string +): Promise<CreateEventResponse> => { const data: Object = { event }; if (name) { data.name = name; @@ -94,6 +97,5 @@ export const changeEvent = (event: string, name: ?string, description: ?string): return postJSON('/api/project_analyses/update_event', data).then(r => r.event); }; -export const deleteAnalysis = (analysis: string): Promise<*> => ( - post('/api/project_analyses/delete', { analysis }) -); +export const deleteAnalysis = (analysis: string): Promise<*> => + post('/api/project_analyses/delete', { analysis }); diff --git a/server/sonar-web/src/main/js/api/projectLinks.js b/server/sonar-web/src/main/js/api/projectLinks.js index d5413e73fc0..5982fbf365e 100644 --- a/server/sonar-web/src/main/js/api/projectLinks.js +++ b/server/sonar-web/src/main/js/api/projectLinks.js @@ -19,19 +19,19 @@ */ import { getJSON, post, postJSON } from '../helpers/request'; -export function getProjectLinks (projectKey) { +export function getProjectLinks(projectKey) { const url = '/api/project_links/search'; const data = { projectKey }; return getJSON(url, data).then(r => r.links); } -export function deleteLink (linkId) { +export function deleteLink(linkId) { const url = '/api/project_links/delete'; const data = { id: linkId }; return post(url, data); } -export function createLink (projectKey, name, url) { +export function createLink(projectKey, name, url) { const apiURL = '/api/project_links/create'; const data = { projectKey, name, url }; return postJSON(apiURL, data).then(r => r.link); diff --git a/server/sonar-web/src/main/js/api/quality-gates.js b/server/sonar-web/src/main/js/api/quality-gates.js index a9cdc5df417..ca20a0f97d0 100644 --- a/server/sonar-web/src/main/js/api/quality-gates.js +++ b/server/sonar-web/src/main/js/api/quality-gates.js @@ -19,86 +19,87 @@ */ import { getJSON, post, postJSON } from '../helpers/request'; -export function fetchQualityGatesAppDetails () { +export function fetchQualityGatesAppDetails() { const url = '/api/qualitygates/app'; return getJSON(url); } -export function fetchQualityGates () { +export function fetchQualityGates() { const url = '/api/qualitygates/list'; - return getJSON(url).then(r => r.qualitygates.map(qualityGate => { - return { - ...qualityGate, - isDefault: qualityGate.id === r.default - }; - })); + return getJSON(url).then(r => + r.qualitygates.map(qualityGate => { + return { + ...qualityGate, + isDefault: qualityGate.id === r.default + }; + })); } -export function fetchQualityGate (id) { +export function fetchQualityGate(id) { const url = '/api/qualitygates/show'; return getJSON(url, { id }); } -export function createQualityGate (name) { +export function createQualityGate(name) { const url = '/api/qualitygates/create'; return postJSON(url, { name }); } -export function deleteQualityGate (id) { +export function deleteQualityGate(id) { const url = '/api/qualitygates/destroy'; return post(url, { id }); } -export function renameQualityGate (id, name) { +export function renameQualityGate(id, name) { const url = '/api/qualitygates/rename'; return post(url, { id, name }); } -export function copyQualityGate (id, name) { +export function copyQualityGate(id, name) { const url = '/api/qualitygates/copy'; return postJSON(url, { id, name }); } -export function setQualityGateAsDefault (id) { +export function setQualityGateAsDefault(id) { const url = '/api/qualitygates/set_as_default'; return post(url, { id }); } -export function unsetQualityGateAsDefault (id) { +export function unsetQualityGateAsDefault(id) { const url = '/api/qualitygates/unset_default'; return post(url, { id }); } -export function createCondition (gateId, condition) { +export function createCondition(gateId, condition) { const url = '/api/qualitygates/create_condition'; return postJSON(url, { ...condition, gateId }); } -export function updateCondition (condition) { +export function updateCondition(condition) { const url = '/api/qualitygates/update_condition'; return postJSON(url, { ...condition }); } -export function deleteCondition (id) { +export function deleteCondition(id) { const url = '/api/qualitygates/delete_condition'; return post(url, { id }); } -export function getGateForProject (projectKey) { +export function getGateForProject(projectKey) { const url = '/api/qualitygates/get_by_project'; const data = { projectKey }; return getJSON(url, data).then(r => r.qualityGate); } -export function associateGateWithProject (gateId, projectKey) { +export function associateGateWithProject(gateId, projectKey) { const url = '/api/qualitygates/select'; const data = { gateId, projectKey }; return post(url, data); } -export function dissociateGateWithProject (gateId, projectKey) { +export function dissociateGateWithProject(gateId, projectKey) { const url = '/api/qualitygates/deselect'; const data = { gateId, projectKey }; return post(url, data); diff --git a/server/sonar-web/src/main/js/api/quality-profiles.js b/server/sonar-web/src/main/js/api/quality-profiles.js index 64cd30b0566..6f482bd3a9a 100644 --- a/server/sonar-web/src/main/js/api/quality-profiles.js +++ b/server/sonar-web/src/main/js/api/quality-profiles.js @@ -17,50 +17,43 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { - request, - checkStatus, - parseJSON, - getJSON, - post, - postJSON -} from '../helpers/request'; - -export function getQualityProfiles (data) { +import { request, checkStatus, parseJSON, getJSON, post, postJSON } from '../helpers/request'; + +export function getQualityProfiles(data) { const url = '/api/qualityprofiles/search'; return getJSON(url, data).then(r => r.profiles); } -export function createQualityProfile (data) { +export function createQualityProfile(data) { return request('/api/qualityprofiles/create') - .setMethod('post') - .setData(data) - .submit() - .then(checkStatus) - .then(parseJSON); + .setMethod('post') + .setData(data) + .submit() + .then(checkStatus) + .then(parseJSON); } -export function restoreQualityProfile (data) { +export function restoreQualityProfile(data) { return request('/api/qualityprofiles/restore') - .setMethod('post') - .setData(data) - .submit() - .then(checkStatus) - .then(parseJSON); + .setMethod('post') + .setData(data) + .submit() + .then(checkStatus) + .then(parseJSON); } -export function getProfileProjects (data) { +export function getProfileProjects(data) { const url = '/api/qualityprofiles/projects'; return getJSON(url, data); } -export function getProfileInheritance (profileKey) { +export function getProfileInheritance(profileKey) { const url = '/api/qualityprofiles/inheritance'; const data = { profileKey }; return getJSON(url, data); } -export function setDefaultProfile (profileKey) { +export function setDefaultProfile(profileKey) { const url = '/api/qualityprofiles/set_default'; const data = { profileKey }; return post(url, data); @@ -72,7 +65,7 @@ export function setDefaultProfile (profileKey) { * @param {string} name * @returns {Promise} */ -export function renameProfile (key, name) { +export function renameProfile(key, name) { const url = '/api/qualityprofiles/rename'; const data = { key, name }; return post(url, data); @@ -84,7 +77,7 @@ export function renameProfile (key, name) { * @param {string} toName * @returns {Promise} */ -export function copyProfile (fromKey, toName) { +export function copyProfile(fromKey, toName) { const url = '/api/qualityprofiles/copy'; const data = { fromKey, toName }; return postJSON(url, data); @@ -95,7 +88,7 @@ export function copyProfile (fromKey, toName) { * @param {string} profileKey * @returns {Promise} */ -export function deleteProfile (profileKey) { +export function deleteProfile(profileKey) { const url = '/api/qualityprofiles/delete'; const data = { profileKey }; return post(url, data); @@ -107,7 +100,7 @@ export function deleteProfile (profileKey) { * @param {string} parentKey * @returns {Promise} */ -export function changeProfileParent (profileKey, parentKey) { +export function changeProfileParent(profileKey, parentKey) { const url = '/api/qualityprofiles/change_parent'; const data = { profileKey, parentKey }; return post(url, data); @@ -117,7 +110,7 @@ export function changeProfileParent (profileKey, parentKey) { * Get list of available importers * @returns {Promise} */ -export function getImporters () { +export function getImporters() { const url = '/api/qualityprofiles/importers'; return getJSON(url).then(r => r.importers); } @@ -126,7 +119,7 @@ export function getImporters () { * Get list of available exporters * @returns {Promise} */ -export function getExporters () { +export function getExporters() { const url = '/api/qualityprofiles/exporters'; return getJSON(url).then(r => r.exporters); } @@ -136,7 +129,7 @@ export function getExporters () { * @param {string} languageKey * @returns {Promise} */ -export function restoreBuiltInProfiles (languageKey) { +export function restoreBuiltInProfiles(languageKey) { const url = '/api/qualityprofiles/restore_built_in'; const data = { language: languageKey }; return post(url, data); @@ -147,7 +140,7 @@ export function restoreBuiltInProfiles (languageKey) { * @param {Object} data API parameters * @returns {Promise} */ -export function getProfileChangelog (data) { +export function getProfileChangelog(data) { const url = '/api/qualityprofiles/changelog'; return getJSON(url, data); } @@ -158,19 +151,19 @@ export function getProfileChangelog (data) { * @param {string} rightKey * @returns {Promise} */ -export function compareProfiles (leftKey, rightKey) { +export function compareProfiles(leftKey, rightKey) { const url = '/api/qualityprofiles/compare'; const data = { leftKey, rightKey }; return getJSON(url, data); } -export function associateProject (profileKey, projectKey) { +export function associateProject(profileKey, projectKey) { const url = '/api/qualityprofiles/add_project'; const data = { profileKey, projectKey }; return post(url, data); } -export function dissociateProject (profileKey, projectKey) { +export function dissociateProject(profileKey, projectKey) { const url = '/api/qualityprofiles/remove_project'; const data = { profileKey, projectKey }; return post(url, data); diff --git a/server/sonar-web/src/main/js/api/rules.js b/server/sonar-web/src/main/js/api/rules.js index 220bf039f34..194b7514574 100644 --- a/server/sonar-web/src/main/js/api/rules.js +++ b/server/sonar-web/src/main/js/api/rules.js @@ -19,12 +19,12 @@ */ import { getJSON } from '../helpers/request'; -export function searchRules (data) { +export function searchRules(data) { const url = '/api/rules/search'; return getJSON(url, data); } -export function takeFacet (response, property) { +export function takeFacet(response, property) { const facet = response.facets.find(facet => facet.property === property); return facet ? facet.values : []; } diff --git a/server/sonar-web/src/main/js/api/settings.js b/server/sonar-web/src/main/js/api/settings.js index 4b8dbb9d527..a5212c18453 100644 --- a/server/sonar-web/src/main/js/api/settings.js +++ b/server/sonar-web/src/main/js/api/settings.js @@ -21,16 +21,16 @@ import omitBy from 'lodash/omitBy'; import { getJSON, post, postJSON } from '../helpers/request'; import { TYPE_PROPERTY_SET } from '../apps/settings/constants'; -export function getDefinitions (componentKey) { +export function getDefinitions(componentKey) { const url = '/api/settings/list_definitions'; - const data = { }; + const data = {}; if (componentKey) { data.component = componentKey; } return getJSON(url, data).then(r => r.definitions); } -export function getValues (keys, componentKey) { +export function getValues(keys, componentKey) { const url = '/api/settings/values'; const data = { keys }; if (componentKey) { @@ -39,7 +39,7 @@ export function getValues (keys, componentKey) { return getJSON(url, data).then(r => r.settings); } -export function setSettingValue (definition, value, componentKey) { +export function setSettingValue(definition, value, componentKey) { const url = '/api/settings/set'; const { key } = definition; @@ -49,8 +49,8 @@ export function setSettingValue (definition, value, componentKey) { data.values = value; } else if (definition.type === TYPE_PROPERTY_SET) { data.fieldValues = value - .map(fields => omitBy(fields, value => value == null)) - .map(JSON.stringify); + .map(fields => omitBy(fields, value => value == null)) + .map(JSON.stringify); } else { data.value = value; } @@ -62,7 +62,7 @@ export function setSettingValue (definition, value, componentKey) { return post(url, data); } -export function resetSettingValue (key, componentKey) { +export function resetSettingValue(key, componentKey) { const url = '/api/settings/reset'; const data = { keys: key }; if (componentKey) { @@ -71,28 +71,28 @@ export function resetSettingValue (key, componentKey) { return post(url, data); } -export function sendTestEmail (to, subject, message) { +export function sendTestEmail(to, subject, message) { const url = '/api/emails/send'; const data = { to, subject, message }; return post(url, data); } -export function checkSecretKey () { +export function checkSecretKey() { return getJSON('/api/settings/check_secret_key'); } -export function generateSecretKey () { +export function generateSecretKey() { return postJSON('/api/settings/generate_secret_key'); } -export function encryptValue (value) { +export function encryptValue(value) { return postJSON('/api/settings/encrypt', { value }); } -export function getServerId () { +export function getServerId() { return getJSON('/api/server_id/show'); } -export function generateServerId (organization, ip) { +export function generateServerId(organization, ip) { return postJSON('/api/server_id/generate', { organization, ip }); } diff --git a/server/sonar-web/src/main/js/api/system.js b/server/sonar-web/src/main/js/api/system.js index 43659183efb..dc02de9b717 100644 --- a/server/sonar-web/src/main/js/api/system.js +++ b/server/sonar-web/src/main/js/api/system.js @@ -19,32 +19,33 @@ */ import { getJSON, post } from '../helpers/request'; -export function setLogLevel (level) { +export function setLogLevel(level) { const url = '/api/system/change_log_level'; const data = { level }; return post(url, data); } -export function getSystemInfo () { +export function getSystemInfo() { const url = '/api/system/info'; return getJSON(url); } -export function getSystemStatus () { +export function getSystemStatus() { const url = '/api/system/status'; return getJSON(url); } -export function restart () { +export function restart() { const url = '/api/system/restart'; return post(url); } const POLLING_INTERVAL = 2000; -function pollStatus (cb) { - setTimeout(() => { - getSystemStatus() +function pollStatus(cb) { + setTimeout( + () => { + getSystemStatus() .then(r => { if (r.status === 'UP') { cb(); @@ -53,13 +54,15 @@ function pollStatus (cb) { } }) .catch(() => pollStatus(cb)); - }, POLLING_INTERVAL); + }, + POLLING_INTERVAL + ); } -function promiseStatus () { +function promiseStatus() { return new Promise(resolve => pollStatus(resolve)); } -export function restartAndWait () { +export function restartAndWait() { return restart().then(promiseStatus); } diff --git a/server/sonar-web/src/main/js/api/time-machine.js b/server/sonar-web/src/main/js/api/time-machine.js index deb17e5d21d..9104ec1d391 100644 --- a/server/sonar-web/src/main/js/api/time-machine.js +++ b/server/sonar-web/src/main/js/api/time-machine.js @@ -35,11 +35,14 @@ type Response = { } }; -export const getTimeMachineData = (component: string, metrics: Array<string>, other?: {}): Promise<Response> => ( - getJSON('/api/measures/search_history', { - component, - metrics: metrics.join(), - ps: 1000, - ...other - }) -); +export const getTimeMachineData = ( + component: string, + metrics: Array<string>, + other?: {} +): Promise<Response> => + getJSON('/api/measures/search_history', { + component, + metrics: metrics.join(), + ps: 1000, + ...other + }); diff --git a/server/sonar-web/src/main/js/api/user-tokens.js b/server/sonar-web/src/main/js/api/user-tokens.js index de20c7bbfcd..4b3b97e2bba 100644 --- a/server/sonar-web/src/main/js/api/user-tokens.js +++ b/server/sonar-web/src/main/js/api/user-tokens.js @@ -24,7 +24,7 @@ import { getJSON, postJSON, post } from '../helpers/request'; * @param {string} login * @returns {Promise} */ -export function getTokens (login) { +export function getTokens(login) { const url = '/api/user_tokens/search'; const data = { login }; return getJSON(url, data).then(r => r.userTokens); @@ -36,7 +36,7 @@ export function getTokens (login) { * @param {string} tokenName * @returns {Promise} */ -export function generateToken (userLogin, tokenName) { +export function generateToken(userLogin, tokenName) { const url = '/api/user_tokens/generate'; const data = { login: userLogin, name: tokenName }; return postJSON(url, data); @@ -48,7 +48,7 @@ export function generateToken (userLogin, tokenName) { * @param {string} tokenName * @returns {Promise} */ -export function revokeToken (userLogin, tokenName) { +export function revokeToken(userLogin, tokenName) { const url = '/api/user_tokens/revoke'; const data = { login: userLogin, name: tokenName }; return post(url, data); diff --git a/server/sonar-web/src/main/js/api/users.js b/server/sonar-web/src/main/js/api/users.js index a7b629041f7..a661bcace4e 100644 --- a/server/sonar-web/src/main/js/api/users.js +++ b/server/sonar-web/src/main/js/api/users.js @@ -19,12 +19,12 @@ */ import { getJSON, post } from '../helpers/request'; -export function getCurrentUser () { +export function getCurrentUser() { const url = '/api/users/current'; return getJSON(url); } -export function changePassword (login, password, previousPassword) { +export function changePassword(login, password, previousPassword) { const url = '/api/users/change_password'; const data = { login, password }; @@ -35,12 +35,12 @@ export function changePassword (login, password, previousPassword) { return post(url, data); } -export function getIdentityProviders () { +export function getIdentityProviders() { const url = '/api/users/identity_providers'; return getJSON(url); } -export function searchUsers (query) { +export function searchUsers(query) { const url = '/api/users/search'; const data = { q: query }; return getJSON(url, data); diff --git a/server/sonar-web/src/main/js/api/web-api.js b/server/sonar-web/src/main/js/api/web-api.js index bd4803322fd..73299248b18 100644 --- a/server/sonar-web/src/main/js/api/web-api.js +++ b/server/sonar-web/src/main/js/api/web-api.js @@ -56,19 +56,20 @@ export type Domain = { path: string }; -export function fetchWebApi (showInternal: boolean = true): Promise<Array<Domain>> { +export function fetchWebApi(showInternal: boolean = true): Promise<Array<Domain>> { const url = '/api/webservices/list'; const data = { include_internals: showInternal }; - return getJSON(url, data).then(r => r.webServices.map(domain => { - const deprecated = !domain.actions.find(action => !action.deprecatedSince); - const internal = !domain.actions.find(action => !action.internal); + return getJSON(url, data).then(r => + r.webServices.map(domain => { + const deprecated = !domain.actions.find(action => !action.deprecatedSince); + const internal = !domain.actions.find(action => !action.internal); - return { ...domain, deprecated, internal }; - })); + return { ...domain, deprecated, internal }; + })); } -export function fetchResponseExample (domain: string, action: string): Promise<{ example: string }> { +export function fetchResponseExample(domain: string, action: string): Promise<{ example: string }> { const url = '/api/webservices/response_example'; const data = { controller: domain, action }; diff --git a/server/sonar-web/src/main/js/app/components/AdminContainer.js b/server/sonar-web/src/main/js/app/components/AdminContainer.js index f0830c3b9a3..84ca940e53a 100644 --- a/server/sonar-web/src/main/js/app/components/AdminContainer.js +++ b/server/sonar-web/src/main/js/app/components/AdminContainer.js @@ -27,7 +27,7 @@ import { getSettingsNavigation } from '../../api/nav'; import { setAdminPages } from '../../store/appState/duck'; class AdminContainer extends React.Component { - componentDidMount () { + componentDidMount() { if (!isUserAdmin(this.props.currentUser)) { // workaround cyclic dependencies const handleRequiredAuthorization = require('../utils/handleRequiredAuthorization').default; @@ -36,23 +36,23 @@ class AdminContainer extends React.Component { this.loadData(); } - loadData () { + loadData() { getSettingsNavigation().then( r => this.props.setAdminPages(r.extensions), onFail(this.props.dispatch) ); } - render () { + render() { if (!isUserAdmin(this.props.currentUser) || !this.props.adminPages) { return null; } return ( - <div> - <SettingsNav location={this.props.location} extensions={this.props.adminPages}/> - {this.props.children} - </div> + <div> + <SettingsNav location={this.props.location} extensions={this.props.adminPages} /> + {this.props.children} + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/App.js b/server/sonar-web/src/main/js/app/components/App.js index db7f3aecaa2..647acffd144 100644 --- a/server/sonar-web/src/main/js/app/components/App.js +++ b/server/sonar-web/src/main/js/app/components/App.js @@ -45,32 +45,36 @@ class App extends React.Component { } }; - componentDidMount () { + componentDidMount() { this.mounted = true; - this.props.fetchCurrentUser() - .then(() => Promise.all([ + this.props + .fetchCurrentUser() + .then(() => + Promise.all([ this.props.fetchAppState(), this.props.fetchOrganizations(), this.props.fetchLanguages() ])) - .then(this.finishLoading, this.finishLoading); + .then(this.finishLoading, this.finishLoading); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - render () { + render() { if (this.state.loading) { - return <GlobalLoading/>; + return <GlobalLoading />; } return this.props.children; } } -export default connect( - null, - { fetchAppState, fetchCurrentUser, fetchLanguages, fetchOrganizations } -)(App); +export default connect(null, { + fetchAppState, + fetchCurrentUser, + fetchLanguages, + fetchOrganizations +})(App); diff --git a/server/sonar-web/src/main/js/app/components/GlobalContainer.js b/server/sonar-web/src/main/js/app/components/GlobalContainer.js index 05219392c0e..e59fd05b2c6 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalContainer.js +++ b/server/sonar-web/src/main/js/app/components/GlobalContainer.js @@ -24,20 +24,20 @@ import GlobalFooter from './GlobalFooter'; import GlobalMessagesContainer from './GlobalMessagesContainer'; export default class GlobalContainer extends React.Component { - render () { + render() { // it is important to pass `location` down to `GlobalNav` to trigger render on url change return ( - <div className="global-container"> - <div className="page-wrapper page-wrapper-global" id="container"> - <div className="page-container"> - <GlobalNav location={this.props.location}/> - <GlobalMessagesContainer/> - {this.props.children} - </div> + <div className="global-container"> + <div className="page-wrapper page-wrapper-global" id="container"> + <div className="page-container"> + <GlobalNav location={this.props.location} /> + <GlobalMessagesContainer /> + {this.props.children} </div> - <GlobalFooter/> </div> + <GlobalFooter /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooter.js b/server/sonar-web/src/main/js/app/components/GlobalFooter.js index f28d36ac5f0..886de879bab 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalFooter.js +++ b/server/sonar-web/src/main/js/app/components/GlobalFooter.js @@ -25,43 +25,42 @@ import { getAppState } from '../../store/rootReducer'; import GlobalFooterBranding from './GlobalFooterBranding'; class GlobalFooter extends React.Component { - render () { + render() { const { sonarqubeVersion, productionDatabase } = this.props; return ( - <div id="footer" className="page-footer page-container"> - {productionDatabase === false && ( - <div className="alert alert-danger"> - <p className="big" id="evaluation_warning"> - Embedded database should be used for evaluation purpose only - </p> - <p> - The embedded database will not scale, it will not support upgrading to newer versions of SonarQube, - and there is no support for migrating your data out of it into a different database engine. - </p> - </div> - )} + <div id="footer" className="page-footer page-container"> + {productionDatabase === false && + <div className="alert alert-danger"> + <p className="big" id="evaluation_warning"> + Embedded database should be used for evaluation purpose only + </p> + <p> + The embedded database will not scale, it will not support upgrading to newer versions of SonarQube, + and there is no support for migrating your data out of it into a different database engine. + </p> + </div>} - <GlobalFooterBranding/> + <GlobalFooterBranding /> - <div> - Version {sonarqubeVersion} - {' - '} - <a href="http://www.gnu.org/licenses/lgpl-3.0.txt">LGPL v3</a> - {' - '} - <a href="http://www.sonarqube.org">Community</a> - {' - '} - <a href="https://redirect.sonarsource.com/doc/home.html">Documentation</a> - {' - '} - <a href="https://redirect.sonarsource.com/doc/community.html">Get Support</a> - {' - '} - <a href="https://redirect.sonarsource.com/doc/plugin-library.html">Plugins</a> - {' - '} - <Link to="/web_api">Web API</Link> - {' - '} - <Link to="/about">About</Link> - </div> + <div> + Version {sonarqubeVersion} + {' - '} + <a href="http://www.gnu.org/licenses/lgpl-3.0.txt">LGPL v3</a> + {' - '} + <a href="http://www.sonarqube.org">Community</a> + {' - '} + <a href="https://redirect.sonarsource.com/doc/home.html">Documentation</a> + {' - '} + <a href="https://redirect.sonarsource.com/doc/community.html">Get Support</a> + {' - '} + <a href="https://redirect.sonarsource.com/doc/plugin-library.html">Plugins</a> + {' - '} + <Link to="/web_api">Web API</Link> + {' - '} + <Link to="/about">About</Link> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.js b/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.js index 1d80c194eaa..1ca8a72c20a 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.js +++ b/server/sonar-web/src/main/js/app/components/GlobalFooterBranding.js @@ -21,17 +21,17 @@ import React from 'react'; export default class GlobalFooterBranding extends React.Component { - render () { + render() { return ( - <div> - This application is based on - {' '} - <a href="http://www.sonarqube.org/" title="SonarQube™">SonarQube™</a> - {' '} - but is <strong>not</strong> an official version provided by - {' '} - <a href="http://www.sonarsource.com" title="SonarSource SA">SonarSource SA</a>. - </div> + <div> + This application is based on + {' '} + <a href="http://www.sonarqube.org/" title="SonarQubeâ„¢">SonarQube™</a> + {' '} + but is <strong>not</strong> an official version provided by + {' '} + <a href="http://www.sonarsource.com" title="SonarSource SA">SonarSource SA</a>. + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/GlobalLoading.js b/server/sonar-web/src/main/js/app/components/GlobalLoading.js index 67d707e52ca..b5e45197357 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalLoading.js +++ b/server/sonar-web/src/main/js/app/components/GlobalLoading.js @@ -22,12 +22,12 @@ import React from 'react'; import './GlobalLoading.css'; export default class GlobalLoading extends React.Component { - render () { + render() { return ( - <div className="global-loading"> - <i className="spinner global-loading-spinner"/> - <span className="global-loading-text">Loading...</span> - </div> + <div className="global-loading"> + <i className="spinner global-loading-spinner" /> + <span className="global-loading-text">Loading...</span> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/Landing.js b/server/sonar-web/src/main/js/app/components/Landing.js index 7b4ba1721dc..5239df6f93b 100644 --- a/server/sonar-web/src/main/js/app/components/Landing.js +++ b/server/sonar-web/src/main/js/app/components/Landing.js @@ -25,10 +25,13 @@ import { getCurrentUser } from '../../store/rootReducer'; class Landing extends React.Component { static propTypes = { - currentUser: React.PropTypes.oneOfType([React.PropTypes.bool, React.PropTypes.object]).isRequired + currentUser: React.PropTypes.oneOfType([ + React.PropTypes.bool, + React.PropTypes.object + ]).isRequired }; - componentDidMount () { + componentDidMount() { const { currentUser, router } = this.props; if (currentUser.isLoggedIn) { router.replace('/projects'); @@ -37,7 +40,7 @@ class Landing extends React.Component { } } - render () { + render() { return null; } } diff --git a/server/sonar-web/src/main/js/app/components/LocalizationContainer.js b/server/sonar-web/src/main/js/app/components/LocalizationContainer.js index 21bd6c1a57b..8cbbec134be 100644 --- a/server/sonar-web/src/main/js/app/components/LocalizationContainer.js +++ b/server/sonar-web/src/main/js/app/components/LocalizationContainer.js @@ -34,16 +34,16 @@ export default class LocalizationContainer extends React.Component { } }; - componentDidMount () { + componentDidMount() { this.mounted = true; requestMessages().then(this.finishLoading, this.finishLoading); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - render () { + render() { return this.state.loading ? null : this.props.children; } } diff --git a/server/sonar-web/src/main/js/app/components/MarkdownHelp.js b/server/sonar-web/src/main/js/app/components/MarkdownHelp.js index 70263175f0a..4502435d47e 100644 --- a/server/sonar-web/src/main/js/app/components/MarkdownHelp.js +++ b/server/sonar-web/src/main/js/app/components/MarkdownHelp.js @@ -21,7 +21,7 @@ import React from 'react'; export default class MarkdownHelp extends React.Component { - render () { + render() { return ( <div className="page page-limited"> <h2 className="spacer-bottom">Markdown Syntax</h2> @@ -50,7 +50,7 @@ export default class MarkdownHelp extends React.Component { </td> </tr> <tr> - <td className="text-top">* first item<br/> + <td className="text-top">* first item<br /> * second item </td> <td className="markdown"> @@ -61,7 +61,7 @@ export default class MarkdownHelp extends React.Component { </td> </tr> <tr> - <td className="text-top">1. first item<br/> + <td className="text-top">1. first item<br /> 1. second item </td> <td className="markdown text-top"> @@ -73,12 +73,12 @@ export default class MarkdownHelp extends React.Component { </tr> <tr> <td className="text-top"> - = Heading Level 1<br/> - == Heading Level 2<br/> - === Heading Level 3<br/> - ==== Heading Level 4<br/> - ===== Heading Level 5<br/> - ====== Heading Level 6<br/> + = Heading Level 1<br /> + == Heading Level 2<br /> + === Heading Level 3<br /> + ==== Heading Level 4<br /> + ===== Heading Level 5<br /> + ====== Heading Level 6<br /> </td> <td className="markdown text-top"> <h1>Heading Level 1</h1> @@ -95,11 +95,11 @@ export default class MarkdownHelp extends React.Component { </tr> <tr> <td className="text-top"> - ``<br/> - // code on multiple lines<br/> - {'public void foo() {'}<br/> - {'// do some logic here'}<br/> - {'}'}<br/> + ``<br /> + // code on multiple lines<br /> + {'public void foo() {'}<br /> + {'// do some logic here'}<br /> + {'}'}<br /> `` </td> <td className="markdown text-top"> @@ -113,14 +113,14 @@ export default class MarkdownHelp extends React.Component { </tr> <tr> <td className="text-top"> - Standard text<br/> - > Blockquoted text<br/> - > that spans multiple lines<br/> + Standard text<br /> + > Blockquoted text<br /> + > that spans multiple lines<br /> </td> <td className="markdown text-top"> <p>Standard text</p> - <blockquote>Blockquoted text<br/> - that spans multiple lines<br/></blockquote> + <blockquote>Blockquoted text<br /> + that spans multiple lines<br /></blockquote> </td> </tr> </tbody> diff --git a/server/sonar-web/src/main/js/app/components/MigrationContainer.js b/server/sonar-web/src/main/js/app/components/MigrationContainer.js index 46ed174a8c9..4441e3e8373 100644 --- a/server/sonar-web/src/main/js/app/components/MigrationContainer.js +++ b/server/sonar-web/src/main/js/app/components/MigrationContainer.js @@ -32,7 +32,7 @@ class MigrationContainer extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { getSystemStatus().then(r => { if (r.status === 'UP') { this.setState({ loading: false }); @@ -42,7 +42,7 @@ class MigrationContainer extends React.Component { }); } - render () { + render() { if (this.state.loading) { return null; } diff --git a/server/sonar-web/src/main/js/app/components/NotFound.js b/server/sonar-web/src/main/js/app/components/NotFound.js index 98e1e55aca4..2692a72a90d 100644 --- a/server/sonar-web/src/main/js/app/components/NotFound.js +++ b/server/sonar-web/src/main/js/app/components/NotFound.js @@ -22,13 +22,15 @@ import { Link } from 'react-router'; import SimpleContainer from './SimpleContainer'; export default class NotFound extends React.Component { - render () { + render() { return ( - <SimpleContainer> - <h2 className="big-spacer-bottom">The page you were looking for does not exist.</h2> - <p className="spacer-bottom">You may have mistyped the address or the page may have moved.</p> - <p><Link to="/">Go back to the homepage</Link></p> - </SimpleContainer> + <SimpleContainer> + <h2 className="big-spacer-bottom">The page you were looking for does not exist.</h2> + <p className="spacer-bottom"> + You may have mistyped the address or the page may have moved. + </p> + <p><Link to="/">Go back to the homepage</Link></p> + </SimpleContainer> ); } } diff --git a/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js b/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js index 6c8f4418520..79c773e10af 100644 --- a/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js +++ b/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js @@ -31,26 +31,26 @@ class ProjectAdminContainer extends React.Component { } }; - componentDidMount () { + componentDidMount() { this.checkPermissions(); } - componentDidUpdate () { + componentDidUpdate() { this.checkPermissions(); } - isProjectAdmin () { + isProjectAdmin() { const { configuration } = this.props.project; return configuration != null && configuration.showSettings; } - checkPermissions () { + checkPermissions() { if (!this.isProjectAdmin()) { handleRequiredAuthorization(); } } - render () { + render() { if (!this.isProjectAdmin()) { return null; } diff --git a/server/sonar-web/src/main/js/app/components/ProjectContainer.js b/server/sonar-web/src/main/js/app/components/ProjectContainer.js index 5e8c5e3738c..4dd98290d38 100644 --- a/server/sonar-web/src/main/js/app/components/ProjectContainer.js +++ b/server/sonar-web/src/main/js/app/components/ProjectContainer.js @@ -39,19 +39,18 @@ class ProjectContainer extends React.Component { qualifier: string }, fetchProject: (string) => Promise<*> - } - - componentDidMount () { + }; + componentDidMount() { this.fetchProject(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.location.query.id !== this.props.location.query.id) { this.fetchProject(); } } - fetchProject () { + fetchProject() { this.props.fetchProject(this.props.location.query.id).catch(e => { if (e.response.status === 403) { handleRequiredAuthorization(); @@ -61,7 +60,7 @@ class ProjectContainer extends React.Component { }); } - render () { + render() { // check `breadcrumbs` to be sure that /api/navigation/component has been already called if (!this.props.project || this.props.project.breadcrumbs == null) { return null; @@ -73,12 +72,10 @@ class ProjectContainer extends React.Component { const configuration = this.props.project.configuration || {}; return ( - <div> - {!isFile && ( - <ComponentNav component={this.props.project} conf={configuration}/> - )} - {this.props.children} - </div> + <div> + {!isFile && <ComponentNav component={this.props.project} conf={configuration} />} + {this.props.children} + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/SimpleContainer.js b/server/sonar-web/src/main/js/app/components/SimpleContainer.js index 106a948c7a3..7fd30d02596 100644 --- a/server/sonar-web/src/main/js/app/components/SimpleContainer.js +++ b/server/sonar-web/src/main/js/app/components/SimpleContainer.js @@ -29,30 +29,30 @@ export default class SimpleContainer extends React.Component { ]) }; - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } - render () { + render() { return ( - <div className="global-container"> - <div className="page-wrapper page-wrapper-global" id="container"> - <nav className="navbar navbar-global page-container" id="global-navigation"> - <div className="navbar-header"/> - </nav> + <div className="global-container"> + <div className="page-wrapper page-wrapper-global" id="container"> + <nav className="navbar navbar-global page-container" id="global-navigation"> + <div className="navbar-header" /> + </nav> - <div id="bd" className="page-wrapper-simple"> - <div id="nonav" className="page-simple"> - {this.props.children} - </div> + <div id="bd" className="page-wrapper-simple"> + <div id="nonav" className="page-simple"> + {this.props.children} </div> </div> - <GlobalFooter/> </div> + <GlobalFooter /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/Extension.js b/server/sonar-web/src/main/js/app/components/extensions/Extension.js index 1011c4bea2c..3889e58612d 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/Extension.js +++ b/server/sonar-web/src/main/js/app/components/extensions/Extension.js @@ -42,18 +42,18 @@ class Extension extends React.Component { props: Props; stop: ?Function; - componentDidMount () { + componentDidMount() { this.startExtension(); } - componentDidUpdate (prevProps: Props) { + componentDidUpdate(prevProps: Props) { if (prevProps.extension !== this.props.extension) { this.stopExtension(); this.startExtension(); } } - componentWillUnmount () { + componentWillUnmount() { this.stopExtension(); } @@ -70,21 +70,21 @@ class Extension extends React.Component { this.props.onFail(translate('page_extension_failed')); }; - startExtension () { + startExtension() { const { extension } = this.props; getExtensionStart(extension.key).then(this.handleStart, this.handleFailure); } - stopExtension () { + stopExtension() { this.stop && this.stop(); this.stop = null; } - render () { + render() { return ( - <div> - <div ref={container => this.container = container}/> - </div> + <div> + <div ref={container => this.container = container} /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/ExtensionNotFound.js b/server/sonar-web/src/main/js/app/components/extensions/ExtensionNotFound.js index 5ad30878ae3..077cd721366 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/ExtensionNotFound.js +++ b/server/sonar-web/src/main/js/app/components/extensions/ExtensionNotFound.js @@ -22,23 +22,25 @@ import React from 'react'; import { Link } from 'react-router'; export default class ExtensionNotFound extends React.Component { - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } - render () { + render() { return ( - <div id="bd" className="page-wrapper-simple"> - <div id="nonav" className="page-simple"> - <h2 className="big-spacer-bottom">The page you were looking for does not exist.</h2> - <p className="spacer-bottom">You may have mistyped the address or the page may have moved.</p> - <p><Link to="/">Go back to the homepage</Link></p> - </div> + <div id="bd" className="page-wrapper-simple"> + <div id="nonav" className="page-simple"> + <h2 className="big-spacer-bottom">The page you were looking for does not exist.</h2> + <p className="spacer-bottom"> + You may have mistyped the address or the page may have moved. + </p> + <p><Link to="/">Go back to the homepage</Link></p> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/GlobalAdminPageExtension.js b/server/sonar-web/src/main/js/app/components/extensions/GlobalAdminPageExtension.js index 4b8b26976a0..54f9f231b36 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/GlobalAdminPageExtension.js +++ b/server/sonar-web/src/main/js/app/components/extensions/GlobalAdminPageExtension.js @@ -31,16 +31,11 @@ class GlobalAdminPageExtension extends React.Component { extensionKey: string, pluginKey: string } - } - - render () { + }; + render() { const { extensionKey, pluginKey } = this.props.params; const extension = this.props.adminPages.find(p => p.key === `${pluginKey}/${extensionKey}`); - return extension ? ( - <Extension extension={extension}/> - ) : ( - <ExtensionNotFound/> - ); + return extension ? <Extension extension={extension} /> : <ExtensionNotFound />; } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/GlobalPageExtension.js b/server/sonar-web/src/main/js/app/components/extensions/GlobalPageExtension.js index df0e56d3dbc..147564cf34a 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/GlobalPageExtension.js +++ b/server/sonar-web/src/main/js/app/components/extensions/GlobalPageExtension.js @@ -31,16 +31,11 @@ class GlobalPageExtension extends React.Component { extensionKey: string, pluginKey: string } - } - - render () { + }; + render() { const { extensionKey, pluginKey } = this.props.params; const extension = this.props.globalPages.find(p => p.key === `${pluginKey}/${extensionKey}`); - return extension ? ( - <Extension extension={extension}/> - ) : ( - <ExtensionNotFound/> - ); + return extension ? <Extension extension={extension} /> : <ExtensionNotFound />; } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/ProjectAdminPageExtension.js b/server/sonar-web/src/main/js/app/components/extensions/ProjectAdminPageExtension.js index 385c396ee05..4e753ae6459 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/ProjectAdminPageExtension.js +++ b/server/sonar-web/src/main/js/app/components/extensions/ProjectAdminPageExtension.js @@ -41,16 +41,14 @@ type Props = { class ProjectAdminPageExtension extends React.Component { props: Props; - render () { + render() { const { extensionKey, pluginKey } = this.props.params; const { component } = this.props; const extension = component.configuration && - component.configuration.extensions.find(p => p.key === `${pluginKey}/${extensionKey}`); - return extension ? ( - <Extension extension={extension} options={{ component }}/> - ) : ( - <ExtensionNotFound/> - ); + component.configuration.extensions.find(p => p.key === `${pluginKey}/${extensionKey}`); + return extension + ? <Extension extension={extension} options={{ component }} /> + : <ExtensionNotFound />; } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/ProjectPageExtension.js b/server/sonar-web/src/main/js/app/components/extensions/ProjectPageExtension.js index b13d06a8029..3f2d684c04f 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/ProjectPageExtension.js +++ b/server/sonar-web/src/main/js/app/components/extensions/ProjectPageExtension.js @@ -39,15 +39,13 @@ type Props = { class ProjectPageExtension extends React.Component { props: Props; - render () { + render() { const { extensionKey, pluginKey } = this.props.params; const { component } = this.props; const extension = component.extensions.find(p => p.key === `${pluginKey}/${extensionKey}`); - return extension ? ( - <Extension extension={extension} options={{ component }}/> - ) : ( - <ExtensionNotFound/> - ); + return extension + ? <Extension extension={extension} options={{ component }} /> + : <ExtensionNotFound />; } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/ViewDashboard.js b/server/sonar-web/src/main/js/app/components/extensions/ViewDashboard.js index 38041bdab3c..eb38960ee66 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/ViewDashboard.js +++ b/server/sonar-web/src/main/js/app/components/extensions/ViewDashboard.js @@ -22,11 +22,12 @@ import React from 'react'; import ProjectPageExtension from './ProjectPageExtension'; export default class ViewDashboard extends React.Component { - render () { + render() { return ( - <ProjectPageExtension - location={this.props.location} - params={{ pluginKey: 'governance', extensionKey: 'governance' }}/> + <ProjectPageExtension + location={this.props.location} + params={{ pluginKey: 'governance', extensionKey: 'governance' }} + /> ); } } diff --git a/server/sonar-web/src/main/js/app/components/extensions/utils.js b/server/sonar-web/src/main/js/app/components/extensions/utils.js index 6bd8058fa85..7294bea0c83 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/utils.js +++ b/server/sonar-web/src/main/js/app/components/extensions/utils.js @@ -29,20 +29,19 @@ const installScript = (key: string) => { }); }; -export const getExtensionStart = (key: string) => ( - new Promise((resolve, reject) => { - const fromCache = getExtensionFromCache(key); - if (fromCache) { - return resolve(fromCache); - } +export const getExtensionStart = (key: string) => + new Promise((resolve, reject) => { + const fromCache = getExtensionFromCache(key); + if (fromCache) { + return resolve(fromCache); + } - installScript(key).then(() => { - const start = getExtensionFromCache(key); - if (start) { - resolve(start); - } else { - reject(); - } - }); - }) -); + installScript(key).then(() => { + const start = getExtensionFromCache(key); + if (start) { + resolve(start); + } else { + reject(); + } + }); + }); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.js b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.js index d0e02dcbae8..ed484f8453f 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.js @@ -28,18 +28,18 @@ import { getTasksForComponent } from '../../../../api/ce'; import { STATUSES } from '../../../../apps/background-tasks/constants'; export default React.createClass({ - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadStatus(); this.populateRecentHistory(); }, - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; }, - loadStatus () { + loadStatus() { getTasksForComponent(this.props.component.id).then(r => { if (this.mounted) { this.setState({ @@ -51,7 +51,7 @@ export default React.createClass({ }); }, - populateRecentHistory () { + populateRecentHistory() { const { breadcrumbs } = this.props.component; const { qualifier } = breadcrumbs[breadcrumbs.length - 1]; if (['TRK', 'VW', 'DEV'].indexOf(qualifier) !== -1) { @@ -64,33 +64,34 @@ export default React.createClass({ } }, - render () { + render() { return ( - <nav className="navbar navbar-context page-container" id="context-navigation"> - <div className="navbar-context-inner"> - <div className="container"> - <ComponentNavFavorite - component={this.props.component.key} - favorite={this.props.component.isFavorite}/> + <nav className="navbar navbar-context page-container" id="context-navigation"> + <div className="navbar-context-inner"> + <div className="container"> + <ComponentNavFavorite + component={this.props.component.key} + favorite={this.props.component.isFavorite} + /> - <ComponentNavBreadcrumbs - component={this.props.component} - breadcrumbs={this.props.component.breadcrumbs}/> + <ComponentNavBreadcrumbs + component={this.props.component} + breadcrumbs={this.props.component.breadcrumbs} + /> - <TooltipsContainer options={{ delay: { show: 0, hide: 2000 } }}> - <ComponentNavMeta - {...this.props} - {...this.state} - version={this.props.component.version} - snapshotDate={this.props.component.snapshotDate}/> - </TooltipsContainer> + <TooltipsContainer options={{ delay: { show: 0, hide: 2000 } }}> + <ComponentNavMeta + {...this.props} + {...this.state} + version={this.props.component.version} + snapshotDate={this.props.component.snapshotDate} + /> + </TooltipsContainer> - <ComponentNavMenu - component={this.props.component} - conf={this.props.conf}/> - </div> + <ComponentNavMenu component={this.props.component} conf={this.props.conf} /> </div> - </nav> + </div> + </nav> ); } }); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js index 1915257f6c4..05648e1bec5 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js @@ -29,7 +29,7 @@ class ComponentNavBreadcrumbs extends React.Component { breadcrumbs: React.PropTypes.array }; - render () { + render() { const { breadcrumbs, organization, shouldOrganizationBeDisplayed } = this.props; if (!breadcrumbs) { @@ -42,47 +42,46 @@ class ComponentNavBreadcrumbs extends React.Component { const items = breadcrumbs.map((item, index) => { return ( - <span key={item.key}> - {!displayOrganization && index === 0 && ( - <span className="navbar-context-title-qualifier little-spacer-right"> - <QualifierIcon qualifier={lastItem.qualifier}/> - </span> - )} - <Link to={{ pathname: '/dashboard', query: { id: item.key } }} className="link-base-color"> - {index === breadcrumbs.length - 1 ? ( - <strong>{item.name}</strong> - ) : ( - <span>{item.name}</span> - )} - </Link> - {index < breadcrumbs.length - 1 && ( - <span className="slash-separator"/> - )} - </span> + <span key={item.key}> + {!displayOrganization && + index === 0 && + <span className="navbar-context-title-qualifier little-spacer-right"> + <QualifierIcon qualifier={lastItem.qualifier} /> + </span>} + <Link + to={{ pathname: '/dashboard', query: { id: item.key } }} + className="link-base-color" + > + {index === breadcrumbs.length - 1 + ? <strong>{item.name}</strong> + : <span>{item.name}</span>} + </Link> + {index < breadcrumbs.length - 1 && <span className="slash-separator" />} + </span> ); }); return ( - <h2 className="navbar-context-title"> - {displayOrganization && ( - <span> - <span className="navbar-context-title-qualifier little-spacer-right"> - <QualifierIcon qualifier={lastItem.qualifier}/> - </span> - <OrganizationLink organization={organization} className="link-base-color"> - {organization.name} - </OrganizationLink> - <span className="slash-separator"/> - </span> - )} - {items} - </h2> + <h2 className="navbar-context-title"> + {displayOrganization && + <span> + <span className="navbar-context-title-qualifier little-spacer-right"> + <QualifierIcon qualifier={lastItem.qualifier} /> + </span> + <OrganizationLink organization={organization} className="link-base-color"> + {organization.name} + </OrganizationLink> + <span className="slash-separator" /> + </span>} + {items} + </h2> ); } } const mapStateToProps = (state, ownProps) => ({ - organization: ownProps.component.organization && getOrganizationByKey(state, ownProps.component.organization), + organization: ownProps.component.organization && + getOrganizationByKey(state, ownProps.component.organization), shouldOrganizationBeDisplayed: areThereCustomOrganizations(state) }); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavFavorite.js b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavFavorite.js index 20a96f79203..4ae31ef1fb7 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavFavorite.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavFavorite.js @@ -27,17 +27,15 @@ class ComponentNavFavorite extends React.Component { currentUser: React.PropTypes.object.isRequired }; - render () { + render() { if (!this.props.currentUser.isLoggedIn) { return null; } return ( - <div className="navbar-context-favorite"> - <Favorite - component={this.props.component} - favorite={this.props.favorite}/> - </div> + <div className="navbar-context-favorite"> + <Favorite component={this.props.component} favorite={this.props.favorite} /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.js b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.js index c6203fb9017..6d3cc006dc3 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.js @@ -41,241 +41,256 @@ export default class ComponentNavMenu extends React.Component { conf: React.PropTypes.object.isRequired }; - isProject () { + isProject() { return this.props.component.qualifier === 'TRK'; } - isDeveloper () { + isDeveloper() { return this.props.component.qualifier === 'DEV'; } - isView () { + isView() { const { qualifier } = this.props.component; return qualifier === 'VW' || qualifier === 'SVW'; } - shouldShowAdministration () { + shouldShowAdministration() { return Object.keys(this.props.conf).some(key => this.props.conf[key]); } - renderDashboardLink () { + renderDashboardLink() { const pathname = this.isView() ? '/view' : '/dashboard'; return ( - <li> - <Link - to={{ pathname, query: { id: this.props.component.key } }} - activeClassName="active"> - <i className="icon-home"/> - </Link> - </li> + <li> + <Link to={{ pathname, query: { id: this.props.component.key } }} activeClassName="active"> + <i className="icon-home" /> + </Link> + </li> ); } - renderCodeLink () { + renderCodeLink() { if (this.isDeveloper()) { return null; } return ( - <li> - <Link - to={{ pathname: '/code', query: { id: this.props.component.key } }} - activeClassName="active"> - {this.isView() ? translate('view_projects.page') : translate('code.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/code', query: { id: this.props.component.key } }} + activeClassName="active" + > + {this.isView() ? translate('view_projects.page') : translate('code.page')} + </Link> + </li> ); } - renderActivityLink () { + renderActivityLink() { if (!this.isProject()) { return null; } return ( - <li> - <Link to={{ pathname: '/project/activity', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('project_activity.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/activity', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('project_activity.page')} + </Link> + </li> ); } - renderComponentIssuesLink () { + renderComponentIssuesLink() { return ( - <li> - <Link - to={{ pathname: '/component_issues', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('issues.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/component_issues', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('issues.page')} + </Link> + </li> ); } - renderComponentMeasuresLink () { + renderComponentMeasuresLink() { return ( - <li> - <Link - to={{ pathname: '/component_measures', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('layout.measures')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/component_measures', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('layout.measures')} + </Link> + </li> ); } - renderAdministration () { + renderAdministration() { if (!this.shouldShowAdministration()) { return null; } const isSettingsActive = SETTINGS_URLS.some(url => window.location.href.indexOf(url) !== -1); const className = 'dropdown' + (isSettingsActive ? ' active' : ''); return ( - <li className={className}> - <a className="dropdown-toggle navbar-admin-link" - id="component-navigation-admin" data-toggle="dropdown" href="#"> - {translate('layout.settings')} - <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - {this.renderSettingsLink()} - {this.renderProfilesLink()} - {this.renderQualityGateLink()} - {this.renderCustomMeasuresLink()} - {this.renderLinksLink()} - {this.renderPermissionsLink()} - {this.renderBackgroundTasksLink()} - {this.renderUpdateKeyLink()} - {this.renderAdminExtensions()} - {this.renderDeletionLink()} - </ul> - </li> + <li className={className}> + <a + className="dropdown-toggle navbar-admin-link" + id="component-navigation-admin" + data-toggle="dropdown" + href="#" + > + {translate('layout.settings')} + <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + {this.renderSettingsLink()} + {this.renderProfilesLink()} + {this.renderQualityGateLink()} + {this.renderCustomMeasuresLink()} + {this.renderLinksLink()} + {this.renderPermissionsLink()} + {this.renderBackgroundTasksLink()} + {this.renderUpdateKeyLink()} + {this.renderAdminExtensions()} + {this.renderDeletionLink()} + </ul> + </li> ); } - renderSettingsLink () { + renderSettingsLink() { if (!this.props.conf.showSettings) { return null; } return ( - <li> - <Link - to={{ pathname: '/project/settings', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('project_settings.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/settings', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('project_settings.page')} + </Link> + </li> ); } - renderProfilesLink () { + renderProfilesLink() { if (!this.props.conf.showQualityProfiles) { return null; } return ( - <li> - <Link - to={{ pathname: '/project/quality_profiles', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('project_quality_profiles.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/quality_profiles', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('project_quality_profiles.page')} + </Link> + </li> ); } - renderQualityGateLink () { + renderQualityGateLink() { if (!this.props.conf.showQualityGates) { return null; } return ( - <li> - <Link - to={{ pathname: '/project/quality_gate', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('project_quality_gate.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/quality_gate', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('project_quality_gate.page')} + </Link> + </li> ); } - renderCustomMeasuresLink () { + renderCustomMeasuresLink() { if (!this.props.conf.showManualMeasures) { return null; } return ( - <li> - <Link - to={{ pathname: '/custom_measures', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('custom_measures.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/custom_measures', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('custom_measures.page')} + </Link> + </li> ); } - renderLinksLink () { + renderLinksLink() { if (!this.props.conf.showLinks) { return null; } return ( - <li> - <Link - to={{ pathname: '/project/links', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('project_links.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/links', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('project_links.page')} + </Link> + </li> ); } - renderPermissionsLink () { + renderPermissionsLink() { if (!this.props.conf.showPermissions) { return null; } return ( - <li> - <Link - to={{ pathname: '/project_roles', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('permissions.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project_roles', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('permissions.page')} + </Link> + </li> ); } - renderBackgroundTasksLink () { + renderBackgroundTasksLink() { if (!this.props.conf.showBackgroundTasks) { return null; } return ( - <li> - <Link - to={{ pathname: '/project/background_tasks', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('background_tasks.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/background_tasks', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('background_tasks.page')} + </Link> + </li> ); } - renderUpdateKeyLink () { + renderUpdateKeyLink() { if (!this.props.conf.showUpdateKey) { return null; } return ( - <li> - <Link - to={{ pathname: '/project/key', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('update_key.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/key', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('update_key.page')} + </Link> + </li> ); } - renderDeletionLink () { + renderDeletionLink() { const { qualifier } = this.props.component; if (!this.props.conf.showSettings) { @@ -287,33 +302,34 @@ export default class ComponentNavMenu extends React.Component { } return ( - <li> - <Link - to={{ pathname: '/project/deletion', query: { id: this.props.component.key } }} - activeClassName="active"> - {translate('deletion.page')} - </Link> - </li> + <li> + <Link + to={{ pathname: '/project/deletion', query: { id: this.props.component.key } }} + activeClassName="active" + > + {translate('deletion.page')} + </Link> + </li> ); } renderExtension = ({ key, name }, isAdmin = false) => { const pathname = isAdmin ? `/project/admin/extension/${key}` : `/project/extension/${key}`; return ( - <li key={key}> - <Link to={{ pathname, query: { id: this.props.component.key } }} activeClassName="active"> - {name} - </Link> - </li> + <li key={key}> + <Link to={{ pathname, query: { id: this.props.component.key } }} activeClassName="active"> + {name} + </Link> + </li> ); }; - renderAdminExtensions () { + renderAdminExtensions() { const extensions = this.props.conf.extensions || []; return extensions.map(e => this.renderExtension(e, true)); } - renderExtensions () { + renderExtensions() { const extensions = this.props.component.extensions || []; const withoutGovernance = extensions.filter(ext => ext.name !== 'Governance'); if (!withoutGovernance.length) { @@ -321,29 +337,34 @@ export default class ComponentNavMenu extends React.Component { } return ( - <li className="dropdown"> - <a className="dropdown-toggle" id="component-navigation-more" data-toggle="dropdown" href="#"> - {translate('more')} - <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - {withoutGovernance.map(this.renderExtension)} - </ul> - </li> + <li className="dropdown"> + <a + className="dropdown-toggle" + id="component-navigation-more" + data-toggle="dropdown" + href="#" + > + {translate('more')} + <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + {withoutGovernance.map(this.renderExtension)} + </ul> + </li> ); } - render () { + render() { return ( - <ul className="nav navbar-nav nav-tabs"> - {this.renderDashboardLink()} - {this.renderComponentIssuesLink()} - {this.renderComponentMeasuresLink()} - {this.renderCodeLink()} - {this.renderActivityLink()} - {this.renderAdministration()} - {this.renderExtensions()} - </ul> + <ul className="nav navbar-nav nav-tabs"> + {this.renderDashboardLink()} + {this.renderComponentIssuesLink()} + {this.renderComponentMeasuresLink()} + {this.renderCodeLink()} + {this.renderActivityLink()} + {this.renderAdministration()} + {this.renderExtensions()} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.js b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.js index bd2273f9662..21fc78a5de4 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.js @@ -23,40 +23,43 @@ import PendingIcon from '../../../../components/shared/pending-icon'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; export default React.createClass({ - render () { + render() { const metaList = []; const canSeeBackgroundTasks = this.props.conf.showBackgroundTasks; - const backgroundTasksUrl = - `${window.baseUrl}/project/background_tasks?id=${encodeURIComponent(this.props.component.key)}`; + const backgroundTasksUrl = window.baseUrl + + `/project/background_tasks?id=${encodeURIComponent(this.props.component.key)}`; if (this.props.isInProgress) { - const tooltip = canSeeBackgroundTasks ? - translateWithParameters('component_navigation.status.in_progress.admin', backgroundTasksUrl) : - translate('component_navigation.status.in_progress'); + const tooltip = canSeeBackgroundTasks + ? translateWithParameters( + 'component_navigation.status.in_progress.admin', + backgroundTasksUrl + ) + : translate('component_navigation.status.in_progress'); metaList.push( <li key="isInProgress" data-toggle="tooltip" title={tooltip}> - <i className="spinner" style={{ marginTop: '-1px' }}/> - {' '} - <span className="text-info">{translate('background_task.status.IN_PROGRESS')}</span> - </li> + <i className="spinner" style={{ marginTop: '-1px' }} /> + {' '} + <span className="text-info">{translate('background_task.status.IN_PROGRESS')}</span> + </li> ); } else if (this.props.isPending) { - const tooltip = canSeeBackgroundTasks ? - translateWithParameters('component_navigation.status.pending.admin', backgroundTasksUrl) : - translate('component_navigation.status.pending'); + const tooltip = canSeeBackgroundTasks + ? translateWithParameters('component_navigation.status.pending.admin', backgroundTasksUrl) + : translate('component_navigation.status.pending'); metaList.push( <li key="isPending" data-toggle="tooltip" title={tooltip}> - <PendingIcon/> <span>{translate('background_task.status.PENDING')}</span> - </li> + <PendingIcon /> <span>{translate('background_task.status.PENDING')}</span> + </li> ); } else if (this.props.isFailed) { - const tooltip = canSeeBackgroundTasks ? - translateWithParameters('component_navigation.status.failed.admin', backgroundTasksUrl) : - translate('component_navigation.status.failed'); + const tooltip = canSeeBackgroundTasks + ? translateWithParameters('component_navigation.status.failed.admin', backgroundTasksUrl) + : translate('component_navigation.status.failed'); metaList.push( <li key="isFailed" data-toggle="tooltip" title={tooltip}> - <span className="badge badge-danger">{translate('background_task.status.FAILED')}</span> - </li> + <span className="badge badge-danger">{translate('background_task.status.FAILED')}</span> + </li> ); } @@ -69,9 +72,9 @@ export default React.createClass({ } return ( - <div className="navbar-context-meta"> - <ul className="list-inline">{metaList}</ul> - </div> + <div className="navbar-context-meta"> + <ul className="list-inline">{metaList}</ul> + </div> ); } }); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/RecentHistory.js b/server/sonar-web/src/main/js/app/components/nav/component/RecentHistory.js index a783c0344ff..6cd25ac4072 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/RecentHistory.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/RecentHistory.js @@ -29,7 +29,7 @@ type History = Array<{ }>; export default class RecentHistory { - static get (): History { + static get(): History { let history = localStorage.getItem(STORAGE_KEY); if (history == null) { history = []; @@ -44,15 +44,20 @@ export default class RecentHistory { return history; } - static set (newHistory: History): void { + static set(newHistory: History): void { localStorage.setItem(STORAGE_KEY, JSON.stringify(newHistory)); } - static clear (): void { + static clear(): void { localStorage.removeItem(STORAGE_KEY); } - static add (componentKey: string, componentName: string, icon: string, organization?: string): void { + static add( + componentKey: string, + componentName: string, + icon: string, + organization?: string + ): void { const sonarHistory = RecentHistory.get(); const newEntry = { key: componentKey, name: componentName, icon, organization }; let newHistory = sonarHistory.filter(entry => entry.key !== newEntry.key); @@ -61,7 +66,7 @@ export default class RecentHistory { RecentHistory.set(newHistory); } - static remove (componentKey: string): void { + static remove(componentKey: string): void { const history = RecentHistory.get(); const newHistory = history.filter(entry => entry.key !== componentKey); RecentHistory.set(newHistory); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js index e8c6e930bd0..6fce85f2d97 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js @@ -23,7 +23,7 @@ import { Unconnected } from '../ComponentNavBreadcrumbs'; it('should not render breadcrumbs with one element', () => { const breadcrumbs = [{ key: 'my-project', name: 'My Project', qualifier: 'TRK' }]; - const result = shallow(<Unconnected breadcrumbs={breadcrumbs}/>); + const result = shallow(<Unconnected breadcrumbs={breadcrumbs} />); expect(result).toMatchSnapshot(); }); @@ -32,8 +32,10 @@ it('should render organization', () => { const organization = { key: 'foo', name: 'The Foo Organization' }; const result = shallow( <Unconnected - breadcrumbs={breadcrumbs} - organization={organization} - shouldOrganizationBeDisplayed={true}/>); + breadcrumbs={breadcrumbs} + organization={organization} + shouldOrganizationBeDisplayed={true} + /> + ); expect(result).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavMenu-test.js b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavMenu-test.js index 257d3c9f02e..024f2a4a7a0 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavMenu-test.js +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavMenu-test.js @@ -30,6 +30,6 @@ it('should work with extensions', () => { showSettings: true, extensions: [{ key: 'foo', name: 'Foo' }] }; - const wrapper = shallow(<ComponentNavMenu component={component} conf={conf}/>); + const wrapper = shallow(<ComponentNavMenu component={component} conf={conf} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js index d4a04a25860..ef83aed3921 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.js @@ -27,11 +27,11 @@ import ShortcutsHelpView from './ShortcutsHelpView'; import { getCurrentUser, getAppState } from '../../../../store/rootReducer'; class GlobalNav extends React.Component { - componentDidMount () { + componentDidMount() { window.addEventListener('keypress', this.onKeyPress); } - componentWillUnmount () { + componentWillUnmount() { window.removeEventListener('keypress', this.onKeyPress); } @@ -53,25 +53,25 @@ class GlobalNav extends React.Component { new ShortcutsHelpView().render(); }; - render () { + render() { return ( - <nav className="navbar navbar-global page-container" id="global-navigation"> - <div className="container"> - <GlobalNavBranding/> + <nav className="navbar navbar-global page-container" id="global-navigation"> + <div className="container"> + <GlobalNavBranding /> - <GlobalNavMenu {...this.props}/> + <GlobalNavMenu {...this.props} /> - <ul className="nav navbar-nav navbar-right"> - <GlobalNavUser {...this.props}/> - <GlobalNavSearch {...this.props}/> - <li> - <a onClick={this.openHelp} href="#"> - <i className="icon-help navbar-icon"/> - </a> - </li> - </ul> - </div> - </nav> + <ul className="nav navbar-nav navbar-right"> + <GlobalNavUser {...this.props} /> + <GlobalNavSearch {...this.props} /> + <li> + <a onClick={this.openHelp} href="#"> + <i className="icon-help navbar-icon" /> + </a> + </li> + </ul> + </div> + </nav> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js index a1f73443ea2..8e6dd891305 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.js @@ -29,23 +29,22 @@ class GlobalNavBranding extends React.Component { customLogoWidth: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]) }; - renderLogo () { + renderLogo() { const url = this.props.customLogoUrl || `${window.baseUrl}/images/logo.svg`; const width = this.props.customLogoWidth || 100; const height = 30; const title = translate('layout.sonar.slogan'); - return ( - <img src={url} width={width} height={height} alt={title} title={title}/> - ); + return <img src={url} width={width} height={height} alt={title} title={title} />; } - render () { + render() { const homeController = this.props.currentUser.isLoggedIn ? '/projects' : '/about'; - const homeLinkClassName = 'navbar-brand' + (this.props.customLogoUrl ? ' navbar-brand-custom' : ''); + const homeLinkClassName = 'navbar-brand' + + (this.props.customLogoUrl ? ' navbar-brand-custom' : ''); return ( - <div className="navbar-header"> - <Link to={homeController} className={homeLinkClassName}>{this.renderLogo()}</Link> - </div> + <div className="navbar-header"> + <Link to={homeController} className={homeLinkClassName}>{this.renderLogo()}</Link> + </div> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js index 3693e493fcf..b1e556af9d0 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.js @@ -33,112 +33,114 @@ export default class GlobalNavMenu extends React.Component { globalPages: [] }; - activeLink (url) { + activeLink(url) { return window.location.pathname.indexOf(window.baseUrl + url) === 0 ? 'active' : null; } - renderProjects () { + renderProjects() { return ( - <li> - <Link to="/projects" activeClassName="active"> - {translate('projects.page')} - </Link> - </li> + <li> + <Link to="/projects" activeClassName="active"> + {translate('projects.page')} + </Link> + </li> ); } - renderIssuesLink () { - const query = this.props.currentUser.isLoggedIn ? '#resolved=false|assigned_to_me=true' : '#resolved=false'; + renderIssuesLink() { + const query = this.props.currentUser.isLoggedIn + ? '#resolved=false|assigned_to_me=true' + : '#resolved=false'; const url = '/issues' + query; return ( - <li> - <Link to={url} className={this.activeLink('/issues')}> - {translate('issues.page')} - </Link> - </li> + <li> + <Link to={url} className={this.activeLink('/issues')}> + {translate('issues.page')} + </Link> + </li> ); } - renderRulesLink () { + renderRulesLink() { return ( - <li> - <Link to="/coding_rules" className={this.activeLink('/coding_rules')}> - {translate('coding_rules.page')} - </Link> - </li> + <li> + <Link to="/coding_rules" className={this.activeLink('/coding_rules')}> + {translate('coding_rules.page')} + </Link> + </li> ); } - renderProfilesLink () { + renderProfilesLink() { return ( - <li> - <Link to="/profiles" activeClassName="active"> - {translate('quality_profiles.page')} - </Link> - </li> + <li> + <Link to="/profiles" activeClassName="active"> + {translate('quality_profiles.page')} + </Link> + </li> ); } - renderQualityGatesLink () { + renderQualityGatesLink() { return ( - <li> - <Link to="/quality_gates" activeClassName="active"> - {translate('quality_gates.page')} - </Link> - </li> + <li> + <Link to="/quality_gates" activeClassName="active"> + {translate('quality_gates.page')} + </Link> + </li> ); } - renderAdministrationLink () { + renderAdministrationLink() { if (!isUserAdmin(this.props.currentUser)) { return null; } return ( - <li> - <Link to="/settings" className="navbar-admin-link" activeClassName="active"> - {translate('layout.settings')} - </Link> - </li> + <li> + <Link to="/settings" className="navbar-admin-link" activeClassName="active"> + {translate('layout.settings')} + </Link> + </li> ); } renderGlobalPageLink = ({ key, name }) => { return ( - <li key={key}> - <Link to={`/extension/${key}`}>{name}</Link> - </li> + <li key={key}> + <Link to={`/extension/${key}`}>{name}</Link> + </li> ); }; - renderMore () { + renderMore() { const { globalPages } = this.props.appState; if (globalPages.length === 0) { return null; } return ( - <li className="dropdown"> - <a className="dropdown-toggle" id="global-navigation-more" data-toggle="dropdown" href="#"> - {translate('more')} - <span className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - {globalPages.map(this.renderGlobalPageLink)} - </ul> - </li> + <li className="dropdown"> + <a className="dropdown-toggle" id="global-navigation-more" data-toggle="dropdown" href="#"> + {translate('more')} + <span className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + {globalPages.map(this.renderGlobalPageLink)} + </ul> + </li> ); } - render () { + render() { return ( - <ul className="nav navbar-nav"> - {this.renderProjects()} - {this.renderIssuesLink()} - {this.renderRulesLink()} - {this.renderProfilesLink()} - {this.renderQualityGatesLink()} - {this.renderAdministrationLink()} - {this.renderMore()} - </ul> + <ul className="nav navbar-nav"> + {this.renderProjects()} + {this.renderIssuesLink()} + {this.renderRulesLink()} + {this.renderProfilesLink()} + {this.renderQualityGatesLink()} + {this.renderAdministrationLink()} + {this.renderMore()} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js index fdcb24c2881..2b5aa6ccf63 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavSearch.js @@ -23,7 +23,7 @@ import { connect } from 'react-redux'; import SearchView from './SearchView'; import { getCurrentUser } from '../../../../store/rootReducer'; -function contains (root, node) { +function contains(root, node) { while (node) { if (node === root) { return true; @@ -36,7 +36,7 @@ function contains (root, node) { class GlobalNavSearch extends React.Component { state = { open: false }; - componentDidMount () { + componentDidMount() { key('s', () => { const isModalOpen = document.querySelector('html').classList.contains('modal-open'); if (!isModalOpen) { @@ -46,7 +46,7 @@ class GlobalNavSearch extends React.Component { }); } - componentWillUnmount () { + componentWillUnmount() { this.closeSearch(); key.unbind('s'); } @@ -92,15 +92,18 @@ class GlobalNavSearch extends React.Component { } }; - render () { + render() { const dropdownClassName = 'dropdown' + (this.state.open ? ' open' : ''); return ( - <li ref="dropdown" className={dropdownClassName}> - <a className="navbar-search-dropdown" href="#" onClick={this.onClick}> - <i className="icon-search navbar-icon"/> <i className="icon-dropdown"/> - </a> - <div ref="container" className="dropdown-menu dropdown-menu-right global-navbar-search-dropdown"/> - </li> + <li ref="dropdown" className={dropdownClassName}> + <a className="navbar-search-dropdown" href="#" onClick={this.onClick}> + <i className="icon-search navbar-icon" /> <i className="icon-dropdown" /> + </a> + <div + ref="container" + className="dropdown-menu dropdown-menu-right global-navbar-search-dropdown" + /> + </li> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js index b8a5fe7c1df..57fda1a1492 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUser.js @@ -49,35 +49,35 @@ class GlobalNavUser extends React.Component { this.props.router.push('/sessions/logout'); }; - renderAuthenticated () { + renderAuthenticated() { const { currentUser } = this.props; return ( - <li className="dropdown js-user-authenticated"> - <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - <Avatar email={currentUser.email} size={20}/> - {currentUser.name} <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu dropdown-menu-right"> - <li> - <Link to="/account">{translate('my_account.page')}</Link> - </li> - <li> - <a onClick={this.handleLogout} href="#">{translate('layout.logout')}</a> - </li> - </ul> - </li> + <li className="dropdown js-user-authenticated"> + <a className="dropdown-toggle" data-toggle="dropdown" href="#"> + <Avatar email={currentUser.email} size={20} /> + {currentUser.name} <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu dropdown-menu-right"> + <li> + <Link to="/account">{translate('my_account.page')}</Link> + </li> + <li> + <a onClick={this.handleLogout} href="#">{translate('layout.logout')}</a> + </li> + </ul> + </li> ); } - renderAnonymous () { + renderAnonymous() { return ( - <li> - <a onClick={this.handleLogin} href="#">{translate('layout.login')}</a> - </li> + <li> + <a onClick={this.handleLogin} href="#">{translate('layout.login')}</a> + </li> ); } - render () { + render() { return this.props.currentUser.isLoggedIn ? this.renderAuthenticated() : this.renderAnonymous(); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js b/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js index cf711c889e8..e98a0397a3a 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/SearchView.js @@ -31,7 +31,10 @@ import { translate } from '../../../../helpers/l10n'; import { isUserAdmin } from '../../../../helpers/users'; import { getFavorites } from '../../../../api/favorites'; import { getSuggestions } from '../../../../api/components'; -import { getOrganization, areThereCustomOrganizations } from '../../../../store/organizations/utils'; +import { + getOrganization, + areThereCustomOrganizations +} from '../../../../store/organizations/utils'; type Finding = { name: string, @@ -45,19 +48,19 @@ const SearchItemView = Marionette.ItemView.extend({ tagName: 'li', template: SearchItemTemplate, - select () { + select() { this.$el.addClass('active'); }, - deselect () { + deselect() { this.$el.removeClass('active'); }, - submit () { + submit() { this.$('a')[0].click(); }, - onRender () { + onRender() { this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', html: true, @@ -66,11 +69,11 @@ const SearchItemView = Marionette.ItemView.extend({ }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), index: this.options.index @@ -105,7 +108,7 @@ export default Marionette.LayoutView.extend({ 'keyup .js-search-input': 'onKeyUp' }, - initialize () { + initialize() { this.results = new Backbone.Collection(); this.favorite = []; if (this.model.get('currentUser').isLoggedIn) { @@ -121,15 +124,18 @@ export default Marionette.LayoutView.extend({ this._bufferedValue = ''; }, - onRender () { + onRender() { const that = this; this.resultsRegion.show(this.resultsView); - setTimeout(() => { - that.$('.js-search-input').focus(); - }, 0); + setTimeout( + () => { + that.$('.js-search-input').focus(); + }, + 0 + ); }, - onKeyDown (e) { + onKeyDown(e) { if (e.keyCode === 38) { this.resultsView.selectPrev(); return false; @@ -149,7 +155,7 @@ export default Marionette.LayoutView.extend({ } }, - onKeyUp () { + onKeyUp() { const value = this.$('.js-search-input').val(); if (value === this._bufferedValue) { return; @@ -158,18 +164,21 @@ export default Marionette.LayoutView.extend({ this.searchRequest = this.debouncedSearch(value); }, - onSubmit () { + onSubmit() { return false; }, - fetchFavorite (): Promise<*> { + fetchFavorite(): Promise<*> { const customOrganizations = areThereCustomOrganizations(); return getFavorites().then(r => { this.favorite = r.favorites.map(f => { const showOrganization = customOrganizations && f.organization != null; const organization = showOrganization ? getOrganization(f.organization) : null; return { - url: window.baseUrl + '/dashboard/index?id=' + encodeURIComponent(f.key) + window.dashboardParameters(true), + url: window.baseUrl + + '/dashboard/index?id=' + + encodeURIComponent(f.key) + + window.dashboardParameters(true), name: f.name, icon: 'favorite', organization @@ -179,12 +188,14 @@ export default Marionette.LayoutView.extend({ }); }, - resetResultsToDefault () { + resetResultsToDefault() { const recentHistory = RecentHistory.get(); const customOrganizations = areThereCustomOrganizations(); const history = recentHistory.map((historyItem, index) => { - const url = window.baseUrl + '/dashboard/index?id=' + encodeURIComponent(historyItem.key) + - window.dashboardParameters(true); + const url = window.baseUrl + + '/dashboard/index?id=' + + encodeURIComponent(historyItem.key) + + window.dashboardParameters(true); const showOrganization = customOrganizations && historyItem.organization != null; // $FlowFixMe flow doesn't check the above condition on `historyItem.organization != null` const organization = showOrganization ? getOrganization(historyItem.organization) : null; @@ -202,7 +213,7 @@ export default Marionette.LayoutView.extend({ this.results.reset([].concat(history, favorite)); }, - search (q) { + search(q) { if (q.length < 2) { this.resetResultsToDefault(); return; @@ -219,8 +230,9 @@ export default Marionette.LayoutView.extend({ const collection = []; r.results.forEach(({ items, q }) => { items.forEach((item, index) => { - const showOrganization = customOrganizations && item.organization != null && - SHOW_ORGANIZATION_FOR_QUALIFIERS.includes(q); + const showOrganization = customOrganizations && + item.organization != null && + SHOW_ORGANIZATION_FOR_QUALIFIERS.includes(q); const organization = showOrganization ? getOrganization(item.organization) : null; collection.push({ ...item, @@ -240,10 +252,13 @@ export default Marionette.LayoutView.extend({ }); }, - getNavigationFindings (q) { + getNavigationFindings(q) { const DEFAULT_ITEMS = [ { name: translate('issues.page'), url: window.baseUrl + '/issues/search' }, - { name: translate('layout.measures'), url: window.baseUrl + '/measures/search?qualifiers[]=TRK' }, + { + name: translate('layout.measures'), + url: window.baseUrl + '/measures/search?qualifiers[]=TRK' + }, { name: translate('coding_rules.page'), url: window.baseUrl + '/coding_rules' }, { name: translate('quality_profiles.page'), url: window.baseUrl + '/profiles' }, { name: translate('quality_gates.page'), url: window.baseUrl + '/quality_gates' } @@ -261,10 +276,13 @@ export default Marionette.LayoutView.extend({ return findings.slice(0, 6); }, - getGlobalDashboardFindings (q) { + getGlobalDashboardFindings(q) { const dashboards = this.model.get('globalDashboards') || []; const items = dashboards.map(d => { - return { name: d.name, url: window.baseUrl + '/dashboard/index?did=' + encodeURIComponent(d.key) }; + return { + name: d.name, + url: window.baseUrl + '/dashboard/index?did=' + encodeURIComponent(d.key) + }; }); const findings = items.filter(f => { return f.name.match(new RegExp(q, 'i')); @@ -275,7 +293,7 @@ export default Marionette.LayoutView.extend({ return findings.slice(0, 6); }, - getFavoriteFindings (q) { + getFavoriteFindings(q) { const findings = this.favorite.filter(f => { return f.name.match(new RegExp(q, 'i')); }); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js b/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js index 6c9f8cbc4b1..893e4930ad6 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/ShortcutsHelpView.js @@ -24,4 +24,3 @@ export default ModalView.extend({ className: 'modal modal-large', template: ShortcutsHelpTemplate }); - diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js index 43e5359b962..8631913e07f 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavMenu-test.js @@ -29,6 +29,6 @@ it('should work with extensions', () => { isLoggedIn: false, permissions: { global: [] } }; - const wrapper = shallow(<GlobalNavMenu appState={appState} currentUser={currentUser}/>); + const wrapper = shallow(<GlobalNavMenu appState={appState} currentUser={currentUser} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js index 38ee2cef480..b82a5e22a60 100644 --- a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js +++ b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js @@ -29,35 +29,35 @@ class SettingsNav extends React.Component { extensions: [] }; - isSomethingActive (urls) { + isSomethingActive(urls) { const path = window.location.pathname; return urls.some(url => path.indexOf(window.baseUrl + url) === 0); } - isSecurityActive () { + isSecurityActive() { const urls = ['/users', '/groups', '/roles/global', '/permission_templates']; return this.isSomethingActive(urls); } - isProjectsActive () { + isProjectsActive() { const urls = ['/projects_admin', '/background_tasks']; return this.isSomethingActive(urls); } - isSystemActive () { + isSystemActive() { const urls = ['/updatecenter', '/system']; return this.isSomethingActive(urls); } renderExtension = ({ key, name }) => { return ( - <li key={key}> - <Link to={`/admin/extension/${key}`} activeClassName="active">{name}</Link> - </li> + <li key={key}> + <Link to={`/admin/extension/${key}`} activeClassName="active">{name}</Link> + </li> ); }; - render () { + render() { const isSecurity = this.isSecurityActive(); const isProjects = this.isProjectsActive(); const isSystem = this.isSystemActive(); @@ -70,127 +70,128 @@ class SettingsNav extends React.Component { }); return ( - <nav className="navbar navbar-context page-container" id="context-navigation"> - <div className="navbar-context-inner"> - <div className="container"> - <ul className="nav navbar-nav nav-crumbs"> - <li> - <IndexLink to="/settings"> - {translate('layout.settings')} - </IndexLink> - </li> - </ul> - - <ul className="nav navbar-nav nav-tabs"> - <li className={configurationClassNames}> - <a className="dropdown-toggle" data-toggle="dropdown" id="settings-navigation-configuration" href="#"> - {translate('sidebar.project_settings')} <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> + <nav className="navbar navbar-context page-container" id="context-navigation"> + <div className="navbar-context-inner"> + <div className="container"> + <ul className="nav navbar-nav nav-crumbs"> + <li> + <IndexLink to="/settings"> + {translate('layout.settings')} + </IndexLink> + </li> + </ul> + + <ul className="nav navbar-nav nav-tabs"> + <li className={configurationClassNames}> + <a + className="dropdown-toggle" + data-toggle="dropdown" + id="settings-navigation-configuration" + href="#" + > + {translate('sidebar.project_settings')} <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + <li> + <IndexLink to="/settings" activeClassName="active"> + {translate('settings.page')} + </IndexLink> + </li> + <li> + <IndexLink to="/settings/licenses" activeClassName="active"> + {translate('property.category.licenses')} + </IndexLink> + </li> + <li> + <IndexLink to="/settings/encryption" activeClassName="active"> + {translate('property.category.security.encryption')} + </IndexLink> + </li> + <li> + <IndexLink to="/settings/server_id" activeClassName="active"> + {translate('property.category.server_id')} + </IndexLink> + </li> + <li> + <IndexLink to="/metrics" activeClassName="active"> + Custom Metrics + </IndexLink> + </li> + {this.props.extensions.map(this.renderExtension)} + </ul> + </li> + + <li className={securityClassName}> + <a className="dropdown-toggle" data-toggle="dropdown" href="#"> + {translate('sidebar.security')} <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + <li> + <IndexLink to="/users" activeClassName="active"> + {translate('users.page')} + </IndexLink> + </li> + {!this.props.customOrganizations && <li> - <IndexLink to="/settings" activeClassName="active"> - {translate('settings.page')} + <IndexLink to="/groups" activeClassName="active"> + {translate('user_groups.page')} </IndexLink> - </li> + </li>} + {!this.props.customOrganizations && <li> - <IndexLink to="/settings/licenses" activeClassName="active"> - {translate('property.category.licenses')} + <IndexLink to="/roles/global" activeClassName="active"> + {translate('global_permissions.page')} </IndexLink> - </li> + </li>} + {!this.props.customOrganizations && <li> - <IndexLink to="/settings/encryption" activeClassName="active"> - {translate('property.category.security.encryption')} + <IndexLink to="/permission_templates" activeClassName="active"> + {translate('permission_templates')} </IndexLink> - </li> + </li>} + </ul> + </li> + + <li className={projectsClassName}> + <a className="dropdown-toggle" data-toggle="dropdown" href="#"> + {translate('sidebar.projects')} <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + {!this.props.customOrganizations && <li> - <IndexLink to="/settings/server_id" activeClassName="active"> - {translate('property.category.server_id')} + <IndexLink to="/projects_admin" activeClassName="active"> + Management </IndexLink> - </li> - <li> - <IndexLink to="/metrics" activeClassName="active"> - Custom Metrics - </IndexLink> - </li> - {this.props.extensions.map(this.renderExtension)} - </ul> - </li> - - <li className={securityClassName}> - <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {translate('sidebar.security')} <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - <li> - <IndexLink to="/users" activeClassName="active"> - {translate('users.page')} - </IndexLink> - </li> - {!this.props.customOrganizations && ( - <li> - <IndexLink to="/groups" activeClassName="active"> - {translate('user_groups.page')} - </IndexLink> - </li> - )} - {!this.props.customOrganizations && ( - <li> - <IndexLink to="/roles/global" activeClassName="active"> - {translate('global_permissions.page')} - </IndexLink> - </li> - )} - {!this.props.customOrganizations && ( - <li> - <IndexLink to="/permission_templates" activeClassName="active"> - {translate('permission_templates')} - </IndexLink> - </li> - )} - </ul> - </li> - - <li className={projectsClassName}> - <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {translate('sidebar.projects')} <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - {!this.props.customOrganizations && ( - <li> - <IndexLink to="/projects_admin" activeClassName="active"> - Management - </IndexLink> - </li> - )} - <li> - <IndexLink to="/background_tasks" activeClassName="active"> - {translate('background_tasks.page')} - </IndexLink> - </li> - </ul> - </li> - - <li className={systemClassName}> - <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {translate('sidebar.system')} <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - <li> - <IndexLink to="/updatecenter" activeClassName="active"> - {translate('update_center.page')} - </IndexLink> - </li> - <li> - <IndexLink to="/system" activeClassName="active"> - {translate('system_info.page')} - </IndexLink> - </li> - </ul> - </li> - </ul> - </div> + </li>} + <li> + <IndexLink to="/background_tasks" activeClassName="active"> + {translate('background_tasks.page')} + </IndexLink> + </li> + </ul> + </li> + + <li className={systemClassName}> + <a className="dropdown-toggle" data-toggle="dropdown" href="#"> + {translate('sidebar.system')} <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + <li> + <IndexLink to="/updatecenter" activeClassName="active"> + {translate('update_center.page')} + </IndexLink> + </li> + <li> + <IndexLink to="/system" activeClassName="active"> + {translate('system_info.page')} + </IndexLink> + </li> + </ul> + </li> + </ul> </div> - </nav> + </div> + </nav> ); } } diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js index 2477ccb58a4..48f8539f415 100644 --- a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js +++ b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/SettingsNav-test.js @@ -23,6 +23,6 @@ import { UnconnectedSettingsNav } from '../SettingsNav'; it('should work with extensions', () => { const extensions = [{ key: 'foo', name: 'Foo' }]; - const wrapper = shallow(<UnconnectedSettingsNav extensions={extensions}/>); + const wrapper = shallow(<UnconnectedSettingsNav extensions={extensions} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/app/utils/configureLocale.js b/server/sonar-web/src/main/js/app/utils/configureLocale.js index 077a768d108..3b5346d2c59 100644 --- a/server/sonar-web/src/main/js/app/utils/configureLocale.js +++ b/server/sonar-web/src/main/js/app/utils/configureLocale.js @@ -19,9 +19,8 @@ */ import moment from 'moment'; -const getPreferredLanguage = () => ( - window.navigator.languages ? window.navigator.languages[0] : window.navigator.language -); +const getPreferredLanguage = () => + window.navigator.languages ? window.navigator.languages[0] : window.navigator.language; const configureLocale = () => { moment.locale(getPreferredLanguage()); diff --git a/server/sonar-web/src/main/js/app/utils/getHistory.js b/server/sonar-web/src/main/js/app/utils/getHistory.js index 263245a61b0..3a0f42b0d5d 100644 --- a/server/sonar-web/src/main/js/app/utils/getHistory.js +++ b/server/sonar-web/src/main/js/app/utils/getHistory.js @@ -30,6 +30,4 @@ const ensureHistory = () => { return history; }; -export default () => ( - history ? history : ensureHistory() -); +export default () => history ? history : ensureHistory(); diff --git a/server/sonar-web/src/main/js/app/utils/getStore.js b/server/sonar-web/src/main/js/app/utils/getStore.js index 03596f06dab..16796124e8f 100644 --- a/server/sonar-web/src/main/js/app/utils/getStore.js +++ b/server/sonar-web/src/main/js/app/utils/getStore.js @@ -28,6 +28,4 @@ const createStore = () => { return store; }; -export default () => ( - store ? store : createStore() -); +export default () => store ? store : createStore(); diff --git a/server/sonar-web/src/main/js/app/utils/handleRequiredAuthentication.js b/server/sonar-web/src/main/js/app/utils/handleRequiredAuthentication.js index 80771d448c4..ccd6899e88e 100644 --- a/server/sonar-web/src/main/js/app/utils/handleRequiredAuthentication.js +++ b/server/sonar-web/src/main/js/app/utils/handleRequiredAuthentication.js @@ -25,6 +25,6 @@ export default () => { const returnTo = window.location.pathname + window.location.search + window.location.hash; history.replace({ pathname: '/sessions/new', - query: { 'return_to': returnTo } + query: { return_to: returnTo } }); }; diff --git a/server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js b/server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js index 8637db51dc1..efb0deaecbd 100644 --- a/server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js +++ b/server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js @@ -31,6 +31,6 @@ export default () => { store.dispatch(requireAuthorization()); history.replace({ pathname: '/sessions/new', - query: { 'return_to': returnTo } + query: { return_to: returnTo } }); }; diff --git a/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js b/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js index 5b08fa4fc51..c60f3bca742 100644 --- a/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js +++ b/server/sonar-web/src/main/js/app/utils/startAjaxMonitoring.js @@ -36,27 +36,27 @@ const Process = Backbone.Model.extend({ state: 'ok' }, - timeout () { + timeout() { this.set({ state: 'timeout', message: 'Still Working...' }); }, - finish (options) { + finish(options) { const finalOptions = { force: false, ...options }; if (this.get('state') !== 'failed' || finalOptions.force) { this.trigger('destroy', this, this.collection, finalOptions); } }, - fail (message) { + fail(message) { const that = this; let msg = message || translate('process.fail'); if (msg === 'process.fail') { // no translation msg = 'An error happened, some parts of the page might not render correctly. ' + - 'Please contact the administrator if you keep on experiencing this error.'; + 'Please contact the administrator if you keep on experiencing this error.'; } clearInterval(this.get('timer')); this.set({ @@ -64,9 +64,12 @@ const Process = Backbone.Model.extend({ message: msg }); this.set('state', 'failed'); - setTimeout(() => { - that.finish({ force: true }); - }, 5000); + setTimeout( + () => { + that.finish({ force: true }); + }, + 5000 + ); } }); @@ -79,28 +82,28 @@ const ProcessesView = Marionette.ItemView.extend({ className: 'processes-container', collectionEvents: { - 'all': 'render' + all: 'render' }, - render () { + render() { const failed = this.collection.findWhere({ state: 'failed' }); const timeout = this.collection.findWhere({ state: 'timeout' }); let el; this.$el.empty(); if (failed != null) { el = $('<li></li>') - .html(failed.get('message')) - .addClass('process-spinner process-spinner-failed shown'); - const close = $('<button></button>').html('<i class="icon-close"></i>').addClass('process-spinner-close'); + .html(failed.get('message')) + .addClass('process-spinner process-spinner-failed shown'); + const close = $('<button></button>') + .html('<i class="icon-close"></i>') + .addClass('process-spinner-close'); close.appendTo(el); close.on('click', () => { failed.finish({ force: true }); }); el.appendTo(this.$el); } else if (timeout != null) { - el = $('<li></li>') - .html(timeout.get('message')) - .addClass('process-spinner shown'); + el = $('<li></li>').html(timeout.get('message')).addClass('process-spinner shown'); el.appendTo(this.$el); } return this; @@ -116,13 +119,16 @@ const processesView = new ProcessesView({ * Add background process * @returns {number} */ -function addBackgroundProcess () { +function addBackgroundProcess() { const uid = uniqueId('process'); const process = new Process({ id: uid, - timer: setTimeout(() => { - process.timeout(); - }, defaults.timeout) + timer: setTimeout( + () => { + process.timeout(); + }, + defaults.timeout + ) }); processes.add(process); return uid; @@ -132,7 +138,7 @@ function addBackgroundProcess () { * Finish background process * @param {number} uid */ -function finishBackgroundProcess (uid) { +function finishBackgroundProcess(uid) { const process = processes.get(uid); if (process != null) { process.finish(); @@ -144,7 +150,7 @@ function finishBackgroundProcess (uid) { * @param {number} uid * @param {string} message */ -function failBackgroundProcess (uid, message) { +function failBackgroundProcess(uid, message) { const process = processes.get(uid); if (process != null) { process.fail(message); @@ -155,7 +161,7 @@ function failBackgroundProcess (uid, message) { * Handle ajax error * @param jqXHR */ -function handleAjaxError (jqXHR) { +function handleAjaxError(jqXHR) { if (jqXHR != null && jqXHR.processId != null) { let message = null; if (jqXHR.responseJSON != null && jqXHR.responseJSON.errors != null) { @@ -165,18 +171,18 @@ function handleAjaxError (jqXHR) { } } -function handleNotAuthenticatedError () { +function handleNotAuthenticatedError() { // workaround cyclic dependencies const handleRequiredAuthentication = require('./handleRequiredAuthentication').default; handleRequiredAuthentication(); } $.ajaxSetup({ - beforeSend (jqXHR) { + beforeSend(jqXHR) { jqXHR.setRequestHeader(getCSRFTokenName(), getCSRFTokenValue()); jqXHR.processId = addBackgroundProcess(); }, - complete (jqXHR) { + complete(jqXHR) { if (jqXHR.processId != null) { finishBackgroundProcess(jqXHR.processId); } diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.js b/server/sonar-web/src/main/js/app/utils/startReactApp.js index 594e906ff12..71f53ddfe0f 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.js +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.js @@ -69,7 +69,7 @@ import { globalPermissionsRoutes, projectPermissionsRoutes } from '../../apps/pe import getStore from './getStore'; import getHistory from './getHistory'; -function handleUpdate () { +function handleUpdate() { const { action } = this.state.location; if (action === 'PUSH') { @@ -83,14 +83,17 @@ const startReactApp = () => { const history = getHistory(); const store = getStore(); - render(( + render( <Provider store={store}> <Router history={history} onUpdate={handleUpdate}> - <Route path="/dashboard/index/:key" onEnter={(nextState, replace) => { - replace({ pathname: '/dashboard', query: { id: nextState.params.key } }); - }}/> + <Route + path="/dashboard/index/:key" + onEnter={(nextState, replace) => { + replace({ pathname: '/dashboard', query: { id: nextState.params.key } }); + }} + /> - <Route path="markdown/help" component={MarkdownHelp}/> + <Route path="markdown/help" component={MarkdownHelp} /> <Route component={LocalizationContainer}> <Route component={SimpleContainer}> @@ -105,17 +108,20 @@ const startReactApp = () => { <Route path="/" component={App}> - <IndexRoute component={Landing}/> + <IndexRoute component={Landing} /> <Route component={GlobalContainer}> <Route path="about">{aboutRoutes}</Route> <Route path="account">{accountRoutes}</Route> - <Route path="codingrules" onEnter={(nextState, replace) => { - replace('/coding_rules' + window.location.hash); - }}/> + <Route + path="codingrules" + onEnter={(nextState, replace) => { + replace('/coding_rules' + window.location.hash); + }} + /> <Route path="coding_rules">{codingRulesRoutes}</Route> <Route path="component">{componentRoutes}</Route> - <Route path="extension/:pluginKey/:extensionKey" component={GlobalPageExtension}/> + <Route path="extension/:pluginKey/:extensionKey" component={GlobalPageExtension} /> <Route path="issues">{issuesRoutes}</Route> <Route path="organizations">{organizationsRouters}</Route> <Route path="projects">{projectsRoutes}</Route> @@ -129,24 +135,33 @@ const startReactApp = () => { <Route path="component_measures">{componentMeasuresRoutes}</Route> <Route path="custom_measures">{customMeasuresRoutes}</Route> <Route path="dashboard">{overviewRoutes}</Route> - <Redirect from="governance" to="/view"/> + <Redirect from="governance" to="/view" /> <Route path="project"> <Route path="activity">{projectActivityRoutes}</Route> <Route path="admin" component={ProjectAdminContainer}> - <Route path="extension/:pluginKey/:extensionKey" component={ProjectAdminPageExtension}/> + <Route + path="extension/:pluginKey/:extensionKey" + component={ProjectAdminPageExtension} + /> </Route> - <Redirect from="extension/governance/governance" to="/view"/> - <Route path="extension/:pluginKey/:extensionKey" component={ProjectPageExtension}/> + <Redirect from="extension/governance/governance" to="/view" /> + <Route + path="extension/:pluginKey/:extensionKey" + component={ProjectPageExtension} + /> <Route path="background_tasks">{backgroundTasksRoutes}</Route> <Route path="settings">{settingsRoutes}</Route> {projectAdminRoutes} </Route> <Route path="project_roles">{projectPermissionsRoutes}</Route> - <Route path="view" component={ViewDashboard}/> + <Route path="view" component={ViewDashboard} /> </Route> <Route component={AdminContainer}> - <Route path="admin/extension/:pluginKey/:extensionKey" component={GlobalAdminPageExtension}/> + <Route + path="admin/extension/:pluginKey/:extensionKey" + component={GlobalAdminPageExtension} + /> <Route path="background_tasks">{backgroundTasksRoutes}</Route> <Route path="groups">{groupsRoutes}</Route> <Route path="metrics">{metricsRoutes}</Route> @@ -160,14 +175,15 @@ const startReactApp = () => { </Route> </Route> - <Route path="not_found" component={NotFound}/> - <Route path="*" component={NotFound}/> + <Route path="not_found" component={NotFound} /> + <Route path="*" component={NotFound} /> </Route> </Route> </Route> </Router> - </Provider> - ), el); + </Provider>, + el + ); }; export default startReactApp; diff --git a/server/sonar-web/src/main/js/apps/about/actions.js b/server/sonar-web/src/main/js/apps/about/actions.js index 18f1d88f09d..279c6f46c49 100644 --- a/server/sonar-web/src/main/js/apps/about/actions.js +++ b/server/sonar-web/src/main/js/apps/about/actions.js @@ -21,10 +21,11 @@ import { getValues } from '../../api/settings'; import { receiveValues } from '../settings/store/values/actions'; -export const fetchAboutPageSettings = (): Function => (dispatch: Function): Promise<*> => { - const keys = ['sonar.lf.aboutText']; +export const fetchAboutPageSettings = (): Function => + (dispatch: Function): Promise<*> => { + const keys = ['sonar.lf.aboutText']; - return getValues(keys.join()).then(values => { - dispatch(receiveValues(values)); - }); -}; + return getValues(keys.join()).then(values => { + dispatch(receiveValues(values)); + }); + }; diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutApp.js b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js index 743e8ed3afd..6efe4c891d0 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutApp.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutApp.js @@ -63,33 +63,29 @@ class AboutApp extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadData(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadProjects () { + loadProjects() { return searchProjects({ ps: 1 }).then(r => r.paging.total); } - loadIssues () { + loadIssues() { return getFacet({ resolved: false }, 'types'); } - loadCustomText () { + loadCustomText() { return this.props.fetchAboutPageSettings(); } - loadData () { - Promise.all([ - this.loadProjects(), - this.loadIssues(), - this.loadCustomText() - ]).then(responses => { + loadData() { + Promise.all([this.loadProjects(), this.loadIssues(), this.loadCustomText()]).then(responses => { if (this.mounted) { const [projectsCount, issues] = responses; const issueTypes = keyBy(issues.facet, 'val'); @@ -102,7 +98,7 @@ class AboutApp extends React.Component { }); } - render () { + render() { if (this.state.loading) { return null; } @@ -118,69 +114,80 @@ class AboutApp extends React.Component { if (sonarqubeDotCom && sonarqubeDotCom.value === 'true') { return ( - <AboutAppForSonarQubeDotCom - bugs={bugs} - codeSmells={codeSmells} - currentUser={this.props.currentUser} - customText={customText} - projectsCount={this.state.projectsCount} - vulnerabilities={vulnerabilities}/> + <AboutAppForSonarQubeDotCom + bugs={bugs} + codeSmells={codeSmells} + currentUser={this.props.currentUser} + customText={customText} + projectsCount={this.state.projectsCount} + vulnerabilities={vulnerabilities} + /> ); } return ( - <div id="about-page" className="about-page"> - <div className="about-page-container"> - <div className="about-page-entry"> - <div className="about-page-intro"> - <h1 className="big-spacer-bottom"> - {translate('layout.sonar.slogan')} - </h1> - {!this.props.currentUser.isLoggedIn && ( - <Link to="/sessions/new" className="button button-active big-spacer-right"> - {translate('layout.login')} - </Link> - )} - <a className="button" href="https://redirect.sonarsource.com/doc/home.html" target="_blank"> - {translate('about_page.read_documentation')} - </a> - </div> - - <div className="about-page-instance"> - <AboutProjects count={this.state.projectsCount}/> - <EntryIssueTypes bugs={bugs} vulnerabilities={vulnerabilities} codeSmells={codeSmells}/> - </div> + <div id="about-page" className="about-page"> + <div className="about-page-container"> + <div className="about-page-entry"> + <div className="about-page-intro"> + <h1 className="big-spacer-bottom"> + {translate('layout.sonar.slogan')} + </h1> + {!this.props.currentUser.isLoggedIn && + <Link to="/sessions/new" className="button button-active big-spacer-right"> + {translate('layout.login')} + </Link>} + <a + className="button" + href="https://redirect.sonarsource.com/doc/home.html" + target="_blank" + > + {translate('about_page.read_documentation')} + </a> </div> - {customText != null && customText.value && ( - <div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText.value }}/> - )} + <div className="about-page-instance"> + <AboutProjects count={this.state.projectsCount} /> + <EntryIssueTypes + bugs={bugs} + vulnerabilities={vulnerabilities} + codeSmells={codeSmells} + /> + </div> + </div> - <AboutLanguages/> + {customText != null && + customText.value && + <div + className="about-page-section" + dangerouslySetInnerHTML={{ __html: customText.value }} + />} - <AboutQualityModel/> + <AboutLanguages /> - <div className="flex-columns"> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutCleanCode/> - </div> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutLeakPeriod/> - </div> - </div> + <AboutQualityModel /> - <div className="flex-columns"> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutQualityGates/> - </div> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutStandards/> - </div> + <div className="flex-columns"> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutCleanCode /> + </div> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutLeakPeriod /> </div> + </div> - <AboutScanners/> + <div className="flex-columns"> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutQualityGates /> + </div> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutStandards /> + </div> </div> + + <AboutScanners /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js index 2a42ace6915..36fb27aea43 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutAppForSonarQubeDotCom.js @@ -39,71 +39,77 @@ export default class AboutAppForSonarQubeDotCom extends React.Component { currentUser: { isLoggedIn: boolean }, customText?: string, projectsCount: number, - vulnerabilities: number, + vulnerabilities: number }; - render () { + render() { const { customText } = this.props; - return ( - <div id="about-page" className="about-page sqcom-about-page"> - <div className="sqcom-about-page-entry"> - <div className="about-page-container"> - <div className="sqcom-about-page-intro"> - <h1 className="big-spacer-bottom"> - Continuous Code Quality<br/>as a Service - </h1> - <a className="button button-active" href="https://about.sonarqube.com/get-started/" target="_blank"> - Get Started - </a> - {!this.props.currentUser.isLoggedIn && ( - <Link to="/sessions/new" className="button big-spacer-left"> - {translate('layout.login')} - </Link> - )} - </div> + <div id="about-page" className="about-page sqcom-about-page"> + <div className="sqcom-about-page-entry"> + <div className="about-page-container"> + <div className="sqcom-about-page-intro"> + <h1 className="big-spacer-bottom"> + Continuous Code Quality<br />as a Service + </h1> + <a + className="button button-active" + href="https://about.sonarqube.com/get-started/" + target="_blank" + > + Get Started + </a> + {!this.props.currentUser.isLoggedIn && + <Link to="/sessions/new" className="button big-spacer-left"> + {translate('layout.login')} + </Link>} + </div> - <div className="sqcom-about-page-instance"> - <AboutProjects count={this.props.projectsCount}/> - <EntryIssueTypesForSonarQubeDotCom - bugs={this.props.bugs} - vulnerabilities={this.props.vulnerabilities} - codeSmells={this.props.codeSmells}/> - </div> + <div className="sqcom-about-page-instance"> + <AboutProjects count={this.props.projectsCount} /> + <EntryIssueTypesForSonarQubeDotCom + bugs={this.props.bugs} + vulnerabilities={this.props.vulnerabilities} + codeSmells={this.props.codeSmells} + /> </div> </div> + </div> - <AboutRulesForSonarQubeDotCom/> + <AboutRulesForSonarQubeDotCom /> - <div className="about-page-container"> - {customText != null && customText.value && ( - <div className="about-page-section" dangerouslySetInnerHTML={{ __html: customText.value }}/> - )} + <div className="about-page-container"> + {customText != null && + customText.value && + <div + className="about-page-section" + dangerouslySetInnerHTML={{ __html: customText.value }} + />} - <AboutQualityModelForSonarQubeDotCom/> + <AboutQualityModelForSonarQubeDotCom /> - <div className="flex-columns"> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutCleanCode/> - </div> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutLeakPeriod/> - </div> + <div className="flex-columns"> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutCleanCode /> </div> - - <div className="flex-columns"> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutQualityGates/> - </div> - <div className="flex-column flex-column-half about-page-group-boxes"> - <AboutStandards/> - </div> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutLeakPeriod /> </div> + </div> - <AboutScanners/> + <div className="flex-columns"> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutQualityGates /> + </div> + <div className="flex-column flex-column-half about-page-group-boxes"> + <AboutStandards /> + </div> </div> + + <AboutScanners /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js index 216a6888166..0100b0fbe1b 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutCleanCode.js @@ -24,15 +24,15 @@ import { translate } from '../../../helpers/l10n'; const link = 'https://redirect.sonarsource.com/doc/issues.html'; export default class AboutCleanCode extends React.Component { - render () { + render() { return ( - <div className="boxed-group"> - <h2>{translate('about_page.clean_code')}</h2> - <div className="boxed-group-inner"> - <p className="about-page-text">{translate('about_page.clean_code.text')}</p> - <ReadMore link={link}/> - </div> + <div className="boxed-group"> + <h2>{translate('about_page.clean_code')}</h2> + <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.clean_code.text')}</p> + <ReadMore link={link} /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js b/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js index 632cf692877..0876d2078d2 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutLanguages.js @@ -46,25 +46,24 @@ const languages = [ const half = (languages.length + 1) / 2; export default class AboutLanguages extends React.Component { - render () { + render() { return ( - <div className="boxed-group"> - <h2>{translate('about_page.languages')}</h2> - <div className="boxed-group-inner"> - <p className="about-page-text">{translate('about_page.languages.text')}</p> - <ul className="about-page-languages"> - {languages.slice(0, half).map((language, index) => ( - <li key={index}> - <a href={languages[index].url}>{languages[index].name}</a> - <br/> - {index + half < languages.length && ( - <a href={languages[index + half].url}>{languages[index + half].name}</a> - )} - </li> - ))} - </ul> - </div> + <div className="boxed-group"> + <h2>{translate('about_page.languages')}</h2> + <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.languages.text')}</p> + <ul className="about-page-languages"> + {languages.slice(0, half).map((language, index) => ( + <li key={index}> + <a href={languages[index].url}>{languages[index].name}</a> + <br /> + {index + half < languages.length && + <a href={languages[index + half].url}>{languages[index + half].name}</a>} + </li> + ))} + </ul> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js index ac3691aca72..edf09b00582 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutLeakPeriod.js @@ -24,15 +24,15 @@ import { translate } from '../../../helpers/l10n'; const link = 'https://redirect.sonarsource.com/doc/fix-the-leak.html'; export default class AboutLeakPeriod extends React.Component { - render () { + render() { return ( - <div className="boxed-group"> - <h2>{translate('about_page.fix_the_leak')}</h2> - <div className="boxed-group-inner"> - <p className="about-page-text">{translate('about_page.fix_the_leak.text')}</p> - <ReadMore link={link}/> - </div> + <div className="boxed-group"> + <h2>{translate('about_page.fix_the_leak')}</h2> + <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.fix_the_leak.text')}</p> + <ReadMore link={link} /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js index 3710e115b04..785214d854b 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutProjects.js @@ -27,20 +27,20 @@ export default class AboutProjects extends React.Component { count: React.PropTypes.number.isRequired }; - render () { + render() { return ( - <div className="about-page-projects"> + <div className="about-page-projects"> + <div> <div> - <div> - <Link to="/projects" className="about-page-projects-link"> - {formatMeasure(this.props.count, 'INT')} - </Link> - </div> - <div> - {translate('about_page.projects_analyzed')} - </div> + <Link to="/projects" className="about-page-projects-link"> + {formatMeasure(this.props.count, 'INT')} + </Link> + </div> + <div> + {translate('about_page.projects_analyzed')} </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js index a564b428f69..6e49863472a 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutQualityGates.js @@ -24,15 +24,15 @@ import { translate } from '../../../helpers/l10n'; const link = 'https://redirect.sonarsource.com/doc/quality-gates.html'; export default class AboutQualityGates extends React.Component { - render () { + render() { return ( - <div className="boxed-group"> - <h2>{translate('about_page.quality_gates')}</h2> - <div className="boxed-group-inner"> - <p className="about-page-text">{translate('about_page.quality_gates.text')}</p> - <ReadMore link={link}/> - </div> + <div className="boxed-group"> + <h2>{translate('about_page.quality_gates')}</h2> + <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.quality_gates.text')}</p> + <ReadMore link={link} /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js index fe8566c72e3..f107c0d2195 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModel.js @@ -24,42 +24,42 @@ import VulnerabilityIcon from '../../../components/ui/VulnerabilityIcon'; import CodeSmellIcon from '../../../components/ui/CodeSmellIcon'; export default class AboutQualityModel extends React.Component { - render () { + render() { return ( - <div className="boxed-group about-quality-model"> - <h2>{translate('about_page.quality_model')}</h2> + <div className="boxed-group about-quality-model"> + <h2>{translate('about_page.quality_model')}</h2> - <div className="boxed-group-inner clearfix"> - <div className="flex-columns"> - <div className="flex-column flex-column-third"> - <div className="pull-left little-spacer-right"><BugIcon/></div> - <p className="about-page-text overflow-hidden"> - <strong>{translate('issue.type.BUG.plural')}</strong> - {' '} - {translate('about_page.quality_model.bugs')} - </p> - </div> + <div className="boxed-group-inner clearfix"> + <div className="flex-columns"> + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"><BugIcon /></div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.BUG.plural')}</strong> + {' '} + {translate('about_page.quality_model.bugs')} + </p> + </div> - <div className="flex-column flex-column-third"> - <div className="pull-left little-spacer-right"><VulnerabilityIcon/></div> - <p className="about-page-text overflow-hidden"> - <strong>{translate('issue.type.VULNERABILITY.plural')}</strong> - {' '} - {translate('about_page.quality_model.vulnerabilities')} - </p> - </div> + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"><VulnerabilityIcon /></div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.VULNERABILITY.plural')}</strong> + {' '} + {translate('about_page.quality_model.vulnerabilities')} + </p> + </div> - <div className="flex-column flex-column-third"> - <div className="pull-left little-spacer-right"><CodeSmellIcon/></div> - <p className="about-page-text overflow-hidden"> - <strong>{translate('issue.type.CODE_SMELL.plural')}</strong> - {' '} - {translate('about_page.quality_model.code_smells')} - </p> - </div> + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"><CodeSmellIcon /></div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.CODE_SMELL.plural')}</strong> + {' '} + {translate('about_page.quality_model.code_smells')} + </p> </div> </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModelForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModelForSonarQubeDotCom.js index 7208fa3a82f..077d9b8c736 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutQualityModelForSonarQubeDotCom.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutQualityModelForSonarQubeDotCom.js @@ -24,42 +24,46 @@ import VulnerabilityIconForSonarQubeDotCom from './VulnerabilityIconForSonarQube import CodeSmellIconForSonarQubeDotCom from './CodeSmellIconForSonarQubeDotCom'; export default class AboutQualityModelForSonarQubeDotCom extends React.Component { - render () { + render() { return ( - <div className="boxed-group about-quality-model sqcom-about-quality-model"> - <h2>{translate('about_page.quality_model')}</h2> + <div className="boxed-group about-quality-model sqcom-about-quality-model"> + <h2>{translate('about_page.quality_model')}</h2> - <div className="boxed-group-inner clearfix"> - <div className="flex-columns"> - <div className="flex-column flex-column-third"> - <div className="pull-left little-spacer-right"><BugIconForSonarQubeDotCom/></div> - <p className="about-page-text overflow-hidden"> - <strong>{translate('issue.type.BUG.plural')}</strong> - {' '} - {translate('about_page.quality_model.bugs')} - </p> - </div> + <div className="boxed-group-inner clearfix"> + <div className="flex-columns"> + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"><BugIconForSonarQubeDotCom /></div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.BUG.plural')}</strong> + {' '} + {translate('about_page.quality_model.bugs')} + </p> + </div> - <div className="flex-column flex-column-third"> - <div className="pull-left little-spacer-right"><VulnerabilityIconForSonarQubeDotCom/></div> - <p className="about-page-text overflow-hidden"> - <strong>{translate('issue.type.VULNERABILITY.plural')}</strong> - {' '} - {translate('about_page.quality_model.vulnerabilities')} - </p> + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"> + <VulnerabilityIconForSonarQubeDotCom /> </div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.VULNERABILITY.plural')}</strong> + {' '} + {translate('about_page.quality_model.vulnerabilities')} + </p> + </div> - <div className="flex-column flex-column-third"> - <div className="pull-left little-spacer-right"><CodeSmellIconForSonarQubeDotCom/></div> - <p className="about-page-text overflow-hidden"> - <strong>{translate('issue.type.CODE_SMELL.plural')}</strong> - {' '} - {translate('about_page.quality_model.code_smells')} - </p> + <div className="flex-column flex-column-third"> + <div className="pull-left little-spacer-right"> + <CodeSmellIconForSonarQubeDotCom /> </div> + <p className="about-page-text overflow-hidden"> + <strong>{translate('issue.type.CODE_SMELL.plural')}</strong> + {' '} + {translate('about_page.quality_model.code_smells')} + </p> </div> </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutRulesForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/AboutRulesForSonarQubeDotCom.js index 75a869c1225..140ab0444d0 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutRulesForSonarQubeDotCom.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutRulesForSonarQubeDotCom.js @@ -23,27 +23,36 @@ import { Link } from 'react-router'; import { getRulesUrl } from '../../../helpers/urls'; export default class AboutRulesForSonarQubeDotCom extends React.Component { - render () { + render() { return ( - <div className="sqcom-about-rules"> - <div className="about-page-container"> - <Link to={getRulesUrl()} className="sqcom-about-rules-link"> - +3,000 rules - <span className="spacer-left"> - <svg width="15" height="36" viewBox="0 0 15 36"> - <g transform="matrix(1,0,0,1,-267,-362)"> - <path d="M268,363L281,380L269,397" style={{ fill: 'none', stroke: '#c1d9ea', strokeWidth: 1 }}/> - </g> - </svg> - </span> - </Link> - <Link to={getRulesUrl({ languages: 'js' })} className="sqcom-about-rules-link">JavaScript</Link> - <Link to={getRulesUrl({ languages: 'java' })} className="sqcom-about-rules-link">Java</Link> - <Link to={getRulesUrl({ languages: 'c,cpp' })} className="sqcom-about-rules-link">C/C++</Link> - <Link to={getRulesUrl({ languages: 'cs' })} className="sqcom-about-rules-link">C#</Link> - <Link to={getRulesUrl()} className="button">And More</Link> - </div> + <div className="sqcom-about-rules"> + <div className="about-page-container"> + <Link to={getRulesUrl()} className="sqcom-about-rules-link"> + +3,000 rules + <span className="spacer-left"> + <svg width="15" height="36" viewBox="0 0 15 36"> + <g transform="matrix(1,0,0,1,-267,-362)"> + <path + d="M268,363L281,380L269,397" + style={{ fill: 'none', stroke: '#c1d9ea', strokeWidth: 1 }} + /> + </g> + </svg> + </span> + </Link> + <Link to={getRulesUrl({ languages: 'js' })} className="sqcom-about-rules-link"> + JavaScript + </Link> + <Link to={getRulesUrl({ languages: 'java' })} className="sqcom-about-rules-link"> + Java + </Link> + <Link to={getRulesUrl({ languages: 'c,cpp' })} className="sqcom-about-rules-link"> + C/C++ + </Link> + <Link to={getRulesUrl({ languages: 'cs' })} className="sqcom-about-rules-link">C#</Link> + <Link to={getRulesUrl()} className="button">And More</Link> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js index 77490fabb90..981e8c90a3b 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutScanners.js @@ -24,41 +24,49 @@ const scanners = [ { key: 'sonarqube', link: 'https://redirect.sonarsource.com/doc/install-configure-scanner.html' - }, { + }, + { key: 'msbuild', link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html' - }, { + }, + { key: 'maven', link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-maven.html' - }, { + }, + { key: 'gradle', link: 'https://redirect.sonarsource.com/doc/gradle.html' - }, { + }, + { key: 'jenkins', link: 'https://redirect.sonarsource.com/plugins/jenkins.html' - }, { + }, + { key: 'ant', link: 'https://redirect.sonarsource.com/doc/install-configure-scanner-ant.html' } ]; export default class AboutScanners extends React.Component { - render () { + render() { return ( - <div className="boxed-group"> - <h2>{translate('about_page.scanners')}</h2> - <div className="boxed-group-inner"> - <p className="about-page-text">{translate('about_page.scanners.text')}</p> - <div className="about-page-analyzers"> - {scanners.map(scanner => ( - <a key={scanner.key} className="about-page-analyzer-box" href={scanner.link}> - <img src={`${window.baseUrl}/images/scanner-logos/${scanner.key}.svg`} height={60} - alt={translate('about_page.scanners', scanner.key)}/> - </a> - ))} - </div> + <div className="boxed-group"> + <h2>{translate('about_page.scanners')}</h2> + <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.scanners.text')}</p> + <div className="about-page-analyzers"> + {scanners.map(scanner => ( + <a key={scanner.key} className="about-page-analyzer-box" href={scanner.link}> + <img + src={`${window.baseUrl}/images/scanner-logos/${scanner.key}.svg`} + height={60} + alt={translate('about_page.scanners', scanner.key)} + /> + </a> + ))} </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js b/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js index 816627d9d5a..c1065f5058e 100644 --- a/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js +++ b/server/sonar-web/src/main/js/apps/about/components/AboutStandards.js @@ -28,52 +28,56 @@ const link = 'https://redirect.sonarsource.com/doc/rules.html'; const owaspTags = 'owasp-a1,owasp-a2,owasp-a3,owasp-a4,owasp-a5,owasp-a6,owasp-a7,owasp-a8,owasp-a9,owasp-a10'; export default class AboutStandards extends React.Component { - render () { + render() { return ( - <div className="boxed-group"> - <h2>{translate('about_page.standards')}</h2> - <div className="boxed-group-inner"> - <p className="about-page-text">{translate('about_page.standards.text')}</p> + <div className="boxed-group"> + <h2>{translate('about_page.standards')}</h2> + <div className="boxed-group-inner"> + <p className="about-page-text">{translate('about_page.standards.text')}</p> - <div className="spacer-top"> - <ul className="list-inline"> - <li> - <Link to={getRulesUrl({ tags: 'misra' })} className="link-with-icon"> - <i className="icon-tags"/> - <span className="little-spacer-left">MISRA</span> - </Link> - </li> - <li> - <Link to={getRulesUrl({ tags: 'cert' })} className="link-with-icon"> - <i className="icon-tags"/> - <span className="little-spacer-left">CERT</span> - </Link> - </li> - <li> - <Link to={getRulesUrl({ tags: 'cwe' })} className="link-with-icon"> - <i className="icon-tags"/> - <span className="little-spacer-left">CWE</span> - </Link> - </li> - <li> - <Link to={getRulesUrl({ tags: owaspTags })} className="link-with-icon"> - <i className="icon-tags"/> - <span className="little-spacer-left">OWASP Top 10</span> - </Link> - </li> - <li> - <Link to={getRulesUrl({ tags: 'sans-top25-porous,sans-top25-risky,sans-top25-insecure' })} - className="link-with-icon"> - <i className="icon-tags"/> - <span className="little-spacer-left">SANS Top 25</span> - </Link> - </li> - </ul> - </div> - - <ReadMore link={link}/> + <div className="spacer-top"> + <ul className="list-inline"> + <li> + <Link to={getRulesUrl({ tags: 'misra' })} className="link-with-icon"> + <i className="icon-tags" /> + <span className="little-spacer-left">MISRA</span> + </Link> + </li> + <li> + <Link to={getRulesUrl({ tags: 'cert' })} className="link-with-icon"> + <i className="icon-tags" /> + <span className="little-spacer-left">CERT</span> + </Link> + </li> + <li> + <Link to={getRulesUrl({ tags: 'cwe' })} className="link-with-icon"> + <i className="icon-tags" /> + <span className="little-spacer-left">CWE</span> + </Link> + </li> + <li> + <Link to={getRulesUrl({ tags: owaspTags })} className="link-with-icon"> + <i className="icon-tags" /> + <span className="little-spacer-left">OWASP Top 10</span> + </Link> + </li> + <li> + <Link + to={getRulesUrl({ + tags: 'sans-top25-porous,sans-top25-risky,sans-top25-insecure' + })} + className="link-with-icon" + > + <i className="icon-tags" /> + <span className="little-spacer-left">SANS Top 25</span> + </Link> + </li> + </ul> </div> + + <ReadMore link={link} /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/BugIconForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/BugIconForSonarQubeDotCom.js index 03427f7d952..a116f7331e6 100644 --- a/server/sonar-web/src/main/js/apps/about/components/BugIconForSonarQubeDotCom.js +++ b/server/sonar-web/src/main/js/apps/about/components/BugIconForSonarQubeDotCom.js @@ -21,12 +21,15 @@ import React from 'react'; export default class BugIconForSonarQubeDotCom extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg viewBox="0 0 26 26" width="26" height="26"> - <path style={{ fill: 'currentcolor' }} d="M23.737 15.91l-2.298-2.297a.797.797 0 0 0-.542-.232h-2.18v-1.588l2.722-2.723a.773.773 0 0 0 .233-.542V4.243a.777.777 0 0 0-.775-.775.777.777 0 0 0-.774.775v3.962l-1.407 1.407v-.633a.777.777 0 0 0-.774-.774h-.517a4.51 4.51 0 0 0-2.852-3.446l2.698-2.698a.787.787 0 0 0 0-1.097.787.787 0 0 0-1.098 0L12.985 4.14 9.823.99a.787.787 0 0 0-1.097 0 .787.787 0 0 0 0 1.097l2.672 2.672a4.51 4.51 0 0 0-2.853 3.446H7.99a.777.777 0 0 0-.774.774v.633L5.81 8.192v-3.95a.777.777 0 0 0-.774-.774.777.777 0 0 0-.775.775v4.272c0 .206.078.4.233.542l2.723 2.723v1.6H5.035c-.207 0-.4.078-.542.233L2.195 15.91a.787.787 0 0 0 0 1.098.764.764 0 0 0 .542.232c.194 0 .4-.078.542-.232l2.078-2.078h1.86v.761l-2.789 3.64a.783.783 0 0 0-.155.477v4.505c0 .426.349.774.775.774a.777.777 0 0 0 .774-.774v-4.247l1.433-1.884a5.77 5.77 0 0 0 2.788 4.298l.077.039c.84.49 1.82.761 2.853.761a5.825 5.825 0 0 0 2.865-.761c.013-.013.039-.013.051-.026a5.75 5.75 0 0 0 2.801-4.31l1.446 1.883v4.247c0 .426.348.774.774.774a.777.777 0 0 0 .775-.774v-4.505a.811.811 0 0 0-.155-.477l-2.788-3.64v-.761H20.6l2.078 2.078a.764.764 0 0 0 .542.232c.193 0 .4-.078.542-.232a.787.787 0 0 0-.026-1.098zm-10.752-9.9c1.369 0 2.517.93 2.853 2.182h-5.705a2.954 2.954 0 0 1 2.852-2.181zm-4.22 11.527V9.754h3.433v9.254l-1.82 1.82a4.172 4.172 0 0 1-1.613-3.291zm3.046 4.04l1.149-1.15 1.148 1.15a4.188 4.188 0 0 1-1.148.167c-.388 0-.775-.064-1.15-.167zm5.356-4.04c0 1.342-.632 2.53-1.6 3.304l-1.82-1.82V9.754h3.433v7.783h-.013z"/> - </svg> + <svg viewBox="0 0 26 26" width="26" height="26"> + <path + style={{ fill: 'currentcolor' }} + d="M23.737 15.91l-2.298-2.297a.797.797 0 0 0-.542-.232h-2.18v-1.588l2.722-2.723a.773.773 0 0 0 .233-.542V4.243a.777.777 0 0 0-.775-.775.777.777 0 0 0-.774.775v3.962l-1.407 1.407v-.633a.777.777 0 0 0-.774-.774h-.517a4.51 4.51 0 0 0-2.852-3.446l2.698-2.698a.787.787 0 0 0 0-1.097.787.787 0 0 0-1.098 0L12.985 4.14 9.823.99a.787.787 0 0 0-1.097 0 .787.787 0 0 0 0 1.097l2.672 2.672a4.51 4.51 0 0 0-2.853 3.446H7.99a.777.777 0 0 0-.774.774v.633L5.81 8.192v-3.95a.777.777 0 0 0-.774-.774.777.777 0 0 0-.775.775v4.272c0 .206.078.4.233.542l2.723 2.723v1.6H5.035c-.207 0-.4.078-.542.233L2.195 15.91a.787.787 0 0 0 0 1.098.764.764 0 0 0 .542.232c.194 0 .4-.078.542-.232l2.078-2.078h1.86v.761l-2.789 3.64a.783.783 0 0 0-.155.477v4.505c0 .426.349.774.775.774a.777.777 0 0 0 .774-.774v-4.247l1.433-1.884a5.77 5.77 0 0 0 2.788 4.298l.077.039c.84.49 1.82.761 2.853.761a5.825 5.825 0 0 0 2.865-.761c.013-.013.039-.013.051-.026a5.75 5.75 0 0 0 2.801-4.31l1.446 1.883v4.247c0 .426.348.774.774.774a.777.777 0 0 0 .775-.774v-4.505a.811.811 0 0 0-.155-.477l-2.788-3.64v-.761H20.6l2.078 2.078a.764.764 0 0 0 .542.232c.193 0 .4-.078.542-.232a.787.787 0 0 0-.026-1.098zm-10.752-9.9c1.369 0 2.517.93 2.853 2.182h-5.705a2.954 2.954 0 0 1 2.852-2.181zm-4.22 11.527V9.754h3.433v9.254l-1.82 1.82a4.172 4.172 0 0 1-1.613-3.291zm3.046 4.04l1.149-1.15 1.148 1.15a4.188 4.188 0 0 1-1.148.167c-.388 0-.775-.064-1.15-.167zm5.356-4.04c0 1.342-.632 2.53-1.6 3.304l-1.82-1.82V9.754h3.433v7.783h-.013z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/CodeSmellIconForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/CodeSmellIconForSonarQubeDotCom.js index ad38f5556c3..1b951e1d3fe 100644 --- a/server/sonar-web/src/main/js/apps/about/components/CodeSmellIconForSonarQubeDotCom.js +++ b/server/sonar-web/src/main/js/apps/about/components/CodeSmellIconForSonarQubeDotCom.js @@ -21,12 +21,15 @@ import React from 'react'; export default class CodeSmellIconForSonarQubeDotCom extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg viewBox="0 0 26 26" width="26" height="26"> - <path style={{ fill: 'currentcolor' }} d="M19.957 5.099a10.455 10.455 0 0 0-7.424-3.077c-1.42 0-2.792.278-4.087.825a10.426 10.426 0 0 0-3.338 2.249 10.462 10.462 0 0 0-3.076 7.427c0 1.418.279 2.791.826 4.087a10.497 10.497 0 0 0 2.25 3.338 10.426 10.426 0 0 0 3.338 2.25c1.295.546 2.67.825 4.086.825 1.419 0 2.791-.279 4.087-.826a10.426 10.426 0 0 0 3.338-2.249 10.465 10.465 0 0 0 3.075-7.425c0-1.417-.278-2.793-.823-4.086a10.396 10.396 0 0 0-2.252-3.338zm.393 10.725a8.436 8.436 0 0 1-1.818 2.695 8.452 8.452 0 0 1-5.996 2.486 8.442 8.442 0 0 1-5.997-2.486 8.455 8.455 0 0 1-2.486-5.996 8.43 8.43 0 0 1 2.486-5.995 8.452 8.452 0 0 1 5.996-2.486 8.445 8.445 0 0 1 5.997 2.486 8.452 8.452 0 0 1 2.485 5.995 8.35 8.35 0 0 1-.667 3.3zm-7.794 4.202h-.037a7.767 7.767 0 0 1-3.426-.835.317.317 0 0 1-.13-.44l2.25-3.923a.32.32 0 0 1 .403-.132c.284.119.595.189.92.189.326 0 .639-.067.92-.19a.32.32 0 0 1 .404.133l2.255 3.922c.09.157.03.36-.133.441a7.896 7.896 0 0 1-3.426.835zm-1.58-7.457c0-.003 0-.009-.003-.013a1.56 1.56 0 0 1 2.337-1.35c.468.269.781.77.781 1.35v.013a1.557 1.557 0 0 1-3.115 0zm-1.068.015H5.384a.318.318 0 0 1-.32-.334c.03-.614.19-1.992.981-3.391l.008-.016.007-.016a7.806 7.806 0 0 1 2.428-2.554.317.317 0 0 1 .448.106l2.282 3.903a.316.316 0 0 1-.082.414 2.371 2.371 0 0 0-.914 1.605.325.325 0 0 1-.314.283zm9.776-.007h-4.526a.32.32 0 0 1-.316-.282 2.371 2.371 0 0 0-.913-1.604.322.322 0 0 1-.082-.414l2.284-3.904a.317.317 0 0 1 .449-.106 7.787 7.787 0 0 1 2.426 2.554l.016.033a7.74 7.74 0 0 1 .98 3.387.319.319 0 0 1-.318.336z"/> - </svg> + <svg viewBox="0 0 26 26" width="26" height="26"> + <path + style={{ fill: 'currentcolor' }} + d="M19.957 5.099a10.455 10.455 0 0 0-7.424-3.077c-1.42 0-2.792.278-4.087.825a10.426 10.426 0 0 0-3.338 2.249 10.462 10.462 0 0 0-3.076 7.427c0 1.418.279 2.791.826 4.087a10.497 10.497 0 0 0 2.25 3.338 10.426 10.426 0 0 0 3.338 2.25c1.295.546 2.67.825 4.086.825 1.419 0 2.791-.279 4.087-.826a10.426 10.426 0 0 0 3.338-2.249 10.465 10.465 0 0 0 3.075-7.425c0-1.417-.278-2.793-.823-4.086a10.396 10.396 0 0 0-2.252-3.338zm.393 10.725a8.436 8.436 0 0 1-1.818 2.695 8.452 8.452 0 0 1-5.996 2.486 8.442 8.442 0 0 1-5.997-2.486 8.455 8.455 0 0 1-2.486-5.996 8.43 8.43 0 0 1 2.486-5.995 8.452 8.452 0 0 1 5.996-2.486 8.445 8.445 0 0 1 5.997 2.486 8.452 8.452 0 0 1 2.485 5.995 8.35 8.35 0 0 1-.667 3.3zm-7.794 4.202h-.037a7.767 7.767 0 0 1-3.426-.835.317.317 0 0 1-.13-.44l2.25-3.923a.32.32 0 0 1 .403-.132c.284.119.595.189.92.189.326 0 .639-.067.92-.19a.32.32 0 0 1 .404.133l2.255 3.922c.09.157.03.36-.133.441a7.896 7.896 0 0 1-3.426.835zm-1.58-7.457c0-.003 0-.009-.003-.013a1.56 1.56 0 0 1 2.337-1.35c.468.269.781.77.781 1.35v.013a1.557 1.557 0 0 1-3.115 0zm-1.068.015H5.384a.318.318 0 0 1-.32-.334c.03-.614.19-1.992.981-3.391l.008-.016.007-.016a7.806 7.806 0 0 1 2.428-2.554.317.317 0 0 1 .448.106l2.282 3.903a.316.316 0 0 1-.082.414 2.371 2.371 0 0 0-.914 1.605.325.325 0 0 1-.314.283zm9.776-.007h-4.526a.32.32 0 0 1-.316-.282 2.371 2.371 0 0 0-.913-1.604.322.322 0 0 1-.082-.414l2.284-3.904a.317.317 0 0 1 .449-.106 7.787 7.787 0 0 1 2.426 2.554l.016.033a7.74 7.74 0 0 1 .98 3.387.319.319 0 0 1-.318.336z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js b/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js index 648f93be3dd..712dc253293 100644 --- a/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js +++ b/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypes.js @@ -33,52 +33,58 @@ export default class EntryIssueTypes extends React.Component { codeSmells: React.PropTypes.number.isRequired }; - render () { + render() { const { bugs, vulnerabilities, codeSmells } = this.props; return ( - <div className="about-page-projects"> - <table className="about-page-issue-types"> - <tbody> - <tr> - <td className="about-page-issue-type-number"> - <Link to={getIssuesUrl({ resolved: false, types: 'BUG' })} - className="about-page-issue-type-link"> - {formatMeasure(bugs, 'SHORT_INT')} - </Link> - </td> - <td> - <span className="little-spacer-right"><BugIcon/></span> - {translate('issue.type.BUG.plural')} - </td> - </tr> - <tr> - <td className="about-page-issue-type-number"> - <Link to={getIssuesUrl({ resolved: false, types: 'VULNERABILITY' })} - className="about-page-issue-type-link"> - {formatMeasure(vulnerabilities, 'SHORT_INT')} - </Link> - </td> - <td> - <span className="little-spacer-right"><VulnerabilityIcon/></span> - {translate('issue.type.VULNERABILITY.plural')} - </td> - </tr> - <tr> - <td className="about-page-issue-type-number"> - <Link to={getIssuesUrl({ resolved: false, types: 'CODE_SMELL' })} - className="about-page-issue-type-link"> - {formatMeasure(codeSmells, 'SHORT_INT')} - </Link> - </td> - <td> - <span className="little-spacer-right"><CodeSmellIcon/></span> - {translate('issue.type.CODE_SMELL.plural')} - </td> - </tr> - </tbody> - </table> - </div> + <div className="about-page-projects"> + <table className="about-page-issue-types"> + <tbody> + <tr> + <td className="about-page-issue-type-number"> + <Link + to={getIssuesUrl({ resolved: false, types: 'BUG' })} + className="about-page-issue-type-link" + > + {formatMeasure(bugs, 'SHORT_INT')} + </Link> + </td> + <td> + <span className="little-spacer-right"><BugIcon /></span> + {translate('issue.type.BUG.plural')} + </td> + </tr> + <tr> + <td className="about-page-issue-type-number"> + <Link + to={getIssuesUrl({ resolved: false, types: 'VULNERABILITY' })} + className="about-page-issue-type-link" + > + {formatMeasure(vulnerabilities, 'SHORT_INT')} + </Link> + </td> + <td> + <span className="little-spacer-right"><VulnerabilityIcon /></span> + {translate('issue.type.VULNERABILITY.plural')} + </td> + </tr> + <tr> + <td className="about-page-issue-type-number"> + <Link + to={getIssuesUrl({ resolved: false, types: 'CODE_SMELL' })} + className="about-page-issue-type-link" + > + {formatMeasure(codeSmells, 'SHORT_INT')} + </Link> + </td> + <td> + <span className="little-spacer-right"><CodeSmellIcon /></span> + {translate('issue.type.CODE_SMELL.plural')} + </td> + </tr> + </tbody> + </table> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypesForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypesForSonarQubeDotCom.js index 1450efde801..8ec4c383d79 100644 --- a/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypesForSonarQubeDotCom.js +++ b/server/sonar-web/src/main/js/apps/about/components/EntryIssueTypesForSonarQubeDotCom.js @@ -33,52 +33,58 @@ export default class EntryIssueTypesForSonarQubeDotCom extends React.Component { codeSmells: React.PropTypes.number.isRequired }; - render () { + render() { const { bugs, vulnerabilities, codeSmells } = this.props; return ( - <div className="about-page-projects"> - <table className="about-page-issue-types"> - <tbody> - <tr> - <td className="about-page-issue-type-number"> - <Link to={getIssuesUrl({ resolved: false, types: 'BUG' })} - className="about-page-issue-type-link"> - {formatMeasure(bugs, 'SHORT_INT')} - </Link> - </td> - <td> - <span className="little-spacer-right"><BugIconForSonarQubeDotCom/></span> - {translate('issue.type.BUG.plural')} - </td> - </tr> - <tr> - <td className="about-page-issue-type-number"> - <Link to={getIssuesUrl({ resolved: false, types: 'VULNERABILITY' })} - className="about-page-issue-type-link"> - {formatMeasure(vulnerabilities, 'SHORT_INT')} - </Link> - </td> - <td> - <span className="little-spacer-right"><VulnerabilityIconForSonarQubeDotCom/></span> - {translate('issue.type.VULNERABILITY.plural')} - </td> - </tr> - <tr> - <td className="about-page-issue-type-number"> - <Link to={getIssuesUrl({ resolved: false, types: 'CODE_SMELL' })} - className="about-page-issue-type-link"> - {formatMeasure(codeSmells, 'SHORT_INT')} - </Link> - </td> - <td> - <span className="little-spacer-right"><CodeSmellIconForSonarQubeDotCom/></span> - {translate('issue.type.CODE_SMELL.plural')} - </td> - </tr> - </tbody> - </table> - </div> + <div className="about-page-projects"> + <table className="about-page-issue-types"> + <tbody> + <tr> + <td className="about-page-issue-type-number"> + <Link + to={getIssuesUrl({ resolved: false, types: 'BUG' })} + className="about-page-issue-type-link" + > + {formatMeasure(bugs, 'SHORT_INT')} + </Link> + </td> + <td> + <span className="little-spacer-right"><BugIconForSonarQubeDotCom /></span> + {translate('issue.type.BUG.plural')} + </td> + </tr> + <tr> + <td className="about-page-issue-type-number"> + <Link + to={getIssuesUrl({ resolved: false, types: 'VULNERABILITY' })} + className="about-page-issue-type-link" + > + {formatMeasure(vulnerabilities, 'SHORT_INT')} + </Link> + </td> + <td> + <span className="little-spacer-right"><VulnerabilityIconForSonarQubeDotCom /></span> + {translate('issue.type.VULNERABILITY.plural')} + </td> + </tr> + <tr> + <td className="about-page-issue-type-number"> + <Link + to={getIssuesUrl({ resolved: false, types: 'CODE_SMELL' })} + className="about-page-issue-type-link" + > + {formatMeasure(codeSmells, 'SHORT_INT')} + </Link> + </td> + <td> + <span className="little-spacer-right"><CodeSmellIconForSonarQubeDotCom /></span> + {translate('issue.type.CODE_SMELL.plural')} + </td> + </tr> + </tbody> + </table> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/ReadMore.js b/server/sonar-web/src/main/js/apps/about/components/ReadMore.js index 50eb2685021..2f9c515b713 100644 --- a/server/sonar-web/src/main/js/apps/about/components/ReadMore.js +++ b/server/sonar-web/src/main/js/apps/about/components/ReadMore.js @@ -25,13 +25,13 @@ export default class ReadMore extends React.Component { link: React.PropTypes.string.isRequired }; - render () { + render() { return ( - <div className="big-spacer-top"> - <a className="about-page-link-more" href={this.props.link} target="_blank"> - <span>{translate('about_page.read_more')}</span> - </a> - </div> + <div className="big-spacer-top"> + <a className="about-page-link-more" href={this.props.link} target="_blank"> + <span>{translate('about_page.read_more')}</span> + </a> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/components/VulnerabilityIconForSonarQubeDotCom.js b/server/sonar-web/src/main/js/apps/about/components/VulnerabilityIconForSonarQubeDotCom.js index b088564b296..2576a3d5cd5 100644 --- a/server/sonar-web/src/main/js/apps/about/components/VulnerabilityIconForSonarQubeDotCom.js +++ b/server/sonar-web/src/main/js/apps/about/components/VulnerabilityIconForSonarQubeDotCom.js @@ -21,12 +21,15 @@ import React from 'react'; export default class VulnerabilityIconForSonarQubeDotCom extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg viewBox="0 0 26 26" width="26" height="26"> - <path style={{ fill: 'currentcolor' }} d="M7.688 9.224V5.818c0-2.622 2.16-4.756 4.813-4.756 2.654 0 4.802 2.134 4.813 4.756v.931c0 .5-.413.909-.919.909a.916.916 0 0 1-.919-.909v-.93c0-1.624-1.332-2.94-2.975-2.94s-2.975 1.316-2.975 2.94v3.405h7.892c1.401 0 2.539 1.124 2.539 2.509v9.706c0 1.442-1.195 2.623-2.654 2.623H7.688c-1.46 0-2.654-1.18-2.654-2.623v-9.706c0-1.385 1.137-2.509 2.539-2.509h.115zm9.615 13.033a.814.814 0 0 0 .816-.806v-9.718a.692.692 0 0 0-.701-.692H7.573c-.39 0-.7.306-.7.692v9.718c0 .442.367.806.815.806h9.615zm-4.802-8.98c-1.045 0-1.907.84-1.907 1.884 0 .704.402 1.329.988 1.647v2.304c0 .5.414.908.92.908a.916.916 0 0 0 .918-.908v-2.316c.586-.318.988-.942.988-1.646a1.904 1.904 0 0 0-1.907-1.873zM22.99 8.804l-1.7-.681c-.47-.182-1.01.034-1.194.5a.904.904 0 0 0 .505 1.18l1.712.681c.115.046.23.068.344.068a.908.908 0 0 0 .85-.567.91.91 0 0 0-.517-1.18zm-2.837-1.703a.939.939 0 0 0 1.206.488l1.689-.715a.9.9 0 0 0 .482-1.192c-.195-.465-.735-.67-1.206-.477l-1.689.716a.876.876 0 0 0-.482 1.18zm-1.068-1.124c-.471-.181-.69-.715-.506-1.192l.69-1.68c.183-.465.723-.681 1.194-.5.471.182.69.716.506 1.181l-.69 1.692a.908.908 0 0 1-.85.567.932.932 0 0 1-.344-.068z"/> - </svg> + <svg viewBox="0 0 26 26" width="26" height="26"> + <path + style={{ fill: 'currentcolor' }} + d="M7.688 9.224V5.818c0-2.622 2.16-4.756 4.813-4.756 2.654 0 4.802 2.134 4.813 4.756v.931c0 .5-.413.909-.919.909a.916.916 0 0 1-.919-.909v-.93c0-1.624-1.332-2.94-2.975-2.94s-2.975 1.316-2.975 2.94v3.405h7.892c1.401 0 2.539 1.124 2.539 2.509v9.706c0 1.442-1.195 2.623-2.654 2.623H7.688c-1.46 0-2.654-1.18-2.654-2.623v-9.706c0-1.385 1.137-2.509 2.539-2.509h.115zm9.615 13.033a.814.814 0 0 0 .816-.806v-9.718a.692.692 0 0 0-.701-.692H7.573c-.39 0-.7.306-.7.692v9.718c0 .442.367.806.815.806h9.615zm-4.802-8.98c-1.045 0-1.907.84-1.907 1.884 0 .704.402 1.329.988 1.647v2.304c0 .5.414.908.92.908a.916.916 0 0 0 .918-.908v-2.316c.586-.318.988-.942.988-1.646a1.904 1.904 0 0 0-1.907-1.873zM22.99 8.804l-1.7-.681c-.47-.182-1.01.034-1.194.5a.904.904 0 0 0 .505 1.18l1.712.681c.115.046.23.068.344.068a.908.908 0 0 0 .85-.567.91.91 0 0 0-.517-1.18zm-2.837-1.703a.939.939 0 0 0 1.206.488l1.689-.715a.9.9 0 0 0 .482-1.192c-.195-.465-.735-.67-1.206-.477l-1.689.716a.876.876 0 0 0-.482 1.18zm-1.068-1.124c-.471-.181-.69-.715-.506-1.192l.69-1.68c.183-.465.723-.681 1.194-.5.471.182.69.716.506 1.181l-.69 1.692a.908.908 0 0 1-.85.567.932.932 0 0 1-.344-.068z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/apps/about/routes.js b/server/sonar-web/src/main/js/apps/about/routes.js index 9b1d3ec370d..a8d72cc6e72 100644 --- a/server/sonar-web/src/main/js/apps/about/routes.js +++ b/server/sonar-web/src/main/js/apps/about/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import AboutApp from './components/AboutApp'; -export default ( - <IndexRoute component={AboutApp}/> -); +export default <IndexRoute component={AboutApp} />; diff --git a/server/sonar-web/src/main/js/apps/account/components/Account.js b/server/sonar-web/src/main/js/apps/account/components/Account.js index d91725574a1..2240231a9e9 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Account.js +++ b/server/sonar-web/src/main/js/apps/account/components/Account.js @@ -26,13 +26,13 @@ import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthe import '../account.css'; class Account extends React.Component { - componentDidMount () { + componentDidMount() { if (!this.props.currentUser.isLoggedIn) { handleRequiredAuthentication(); } } - render () { + render() { const { currentUser, children } = this.props; if (!currentUser.isLoggedIn) { @@ -40,16 +40,16 @@ class Account extends React.Component { } return ( - <div id="account-page"> - <header className="account-header"> - <div className="account-container clearfix"> - <UserCard user={currentUser}/> - <Nav user={currentUser} customOrganizations={this.props.customOrganizations}/> - </div> - </header> + <div id="account-page"> + <header className="account-header"> + <div className="account-container clearfix"> + <UserCard user={currentUser} /> + <Nav user={currentUser} customOrganizations={this.props.customOrganizations} /> + </div> + </header> - {children} - </div> + {children} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/components/Nav.js b/server/sonar-web/src/main/js/apps/account/components/Nav.js index ae2b85cb1e1..c2770721d8a 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Nav.js +++ b/server/sonar-web/src/main/js/apps/account/components/Nav.js @@ -27,39 +27,37 @@ type Props = { }; const Nav = ({ customOrganizations }: Props) => ( - <nav className="account-nav clearfix"> - <ul className="nav navbar-nav nav-tabs"> + <nav className="account-nav clearfix"> + <ul className="nav navbar-nav nav-tabs"> + <li> + <IndexLink to="/account/" activeClassName="active"> + {translate('my_account.profile')} + </IndexLink> + </li> + <li> + <Link to="/account/security/" activeClassName="active"> + {translate('my_account.security')} + </Link> + </li> + <li> + <Link to="/account/notifications" activeClassName="active"> + {translate('my_account.notifications')} + </Link> + </li> + {!customOrganizations && <li> - <IndexLink to="/account/" activeClassName="active"> - {translate('my_account.profile')} - </IndexLink> - </li> - <li> - <Link to="/account/security/" activeClassName="active"> - {translate('my_account.security')} + <Link to="/account/projects/" activeClassName="active"> + {translate('my_account.projects')} </Link> - </li> + </li>} + {customOrganizations && <li> - <Link to="/account/notifications" activeClassName="active"> - {translate('my_account.notifications')} + <Link to="/account/organizations" activeClassName="active"> + {translate('my_account.organizations')} </Link> - </li> - {!customOrganizations && ( - <li> - <Link to="/account/projects/" activeClassName="active"> - {translate('my_account.projects')} - </Link> - </li> - )} - {customOrganizations && ( - <li> - <Link to="/account/organizations" activeClassName="active"> - {translate('my_account.organizations')} - </Link> - </li> - )} - </ul> - </nav> + </li>} + </ul> + </nav> ); export default Nav; diff --git a/server/sonar-web/src/main/js/apps/account/components/Password.js b/server/sonar-web/src/main/js/apps/account/components/Password.js index 907b4700ad0..925fc4ce901 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Password.js +++ b/server/sonar-web/src/main/js/apps/account/components/Password.js @@ -27,28 +27,28 @@ export default class Password extends Component { errors: null }; - handleSuccessfulChange () { + handleSuccessfulChange() { this.refs.oldPassword.value = ''; this.refs.password.value = ''; this.refs.passwordConfirmation.value = ''; this.setState({ success: true, errors: null }); } - handleFailedChange (e) { + handleFailedChange(e) { e.response.json().then(r => { this.refs.oldPassword.focus(); this.setErrors(r.errors.map(e => e.msg)); }); } - setErrors (errors) { + setErrors(errors) { this.setState({ success: false, errors }); } - handleChangePassword (e) { + handleChangePassword(e) { e.preventDefault(); const { user } = this.props; @@ -61,77 +61,77 @@ export default class Password extends Component { this.setErrors([translate('user.password_doesnt_match_confirmation')]); } else { changePassword(user.login, password, oldPassword) - .then(this.handleSuccessfulChange.bind(this)) - .catch(this.handleFailedChange.bind(this)); + .then(this.handleSuccessfulChange.bind(this)) + .catch(this.handleFailedChange.bind(this)); } } - render () { + render() { const { success, errors } = this.state; return ( - <section> - <h2 className="spacer-bottom"> - {translate('my_profile.password.title')} - </h2> + <section> + <h2 className="spacer-bottom"> + {translate('my_profile.password.title')} + </h2> - <form onSubmit={this.handleChangePassword.bind(this)}> - {success && ( - <div className="alert alert-success"> - {translate('my_profile.password.changed')} - </div> - )} + <form onSubmit={this.handleChangePassword.bind(this)}> + {success && + <div className="alert alert-success"> + {translate('my_profile.password.changed')} + </div>} - {errors && errors.map((e, i) => ( - <div key={i} className="alert alert-danger">{e}</div> - ))} + {errors && errors.map((e, i) => <div key={i} className="alert alert-danger">{e}</div>)} - <div className="modal-field"> - <label htmlFor="old_password"> - {translate('my_profile.password.old')} - <em className="mandatory">*</em> - </label> - <input - ref="oldPassword" - autoComplete="off" - id="old_password" - name="old_password" - required={true} - type="password"/> - </div> - <div className="modal-field"> - <label htmlFor="password"> - {translate('my_profile.password.new')} - <em className="mandatory">*</em> - </label> - <input - ref="password" - autoComplete="off" - id="password" - name="password" - required={true} - type="password"/> - </div> - <div className="modal-field"> - <label htmlFor="password_confirmation"> - {translate('my_profile.password.confirm')} - <em className="mandatory">*</em> - </label> - <input - ref="passwordConfirmation" - autoComplete="off" - id="password_confirmation" - name="password_confirmation" - required={true} - type="password"/> - </div> - <div className="modal-field"> - <button id="change-password" type="submit"> - {translate('my_profile.password.submit')} - </button> - </div> - </form> - </section> + <div className="modal-field"> + <label htmlFor="old_password"> + {translate('my_profile.password.old')} + <em className="mandatory">*</em> + </label> + <input + ref="oldPassword" + autoComplete="off" + id="old_password" + name="old_password" + required={true} + type="password" + /> + </div> + <div className="modal-field"> + <label htmlFor="password"> + {translate('my_profile.password.new')} + <em className="mandatory">*</em> + </label> + <input + ref="password" + autoComplete="off" + id="password" + name="password" + required={true} + type="password" + /> + </div> + <div className="modal-field"> + <label htmlFor="password_confirmation"> + {translate('my_profile.password.confirm')} + <em className="mandatory">*</em> + </label> + <input + ref="passwordConfirmation" + autoComplete="off" + id="password_confirmation" + name="password_confirmation" + required={true} + type="password" + /> + </div> + <div className="modal-field"> + <button id="change-password" type="submit"> + {translate('my_profile.password.submit')} + </button> + </div> + </form> + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/components/Security.js b/server/sonar-web/src/main/js/apps/account/components/Security.js index f4f05a1a3c5..6e4a670d143 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Security.js +++ b/server/sonar-web/src/main/js/apps/account/components/Security.js @@ -26,32 +26,23 @@ import { translate } from '../../../helpers/l10n'; import { getCurrentUser } from '../../../store/rootReducer'; class Security extends React.Component { - render () { + render() { const { user } = this.props; - const title = translate('my_account.page') + ' - ' + - translate('my_account.security'); + const title = translate('my_account.page') + ' - ' + translate('my_account.security'); return ( - <div className="account-body account-container"> - <Helmet - title={title} - titleTemplate="SonarQube - %s"/> + <div className="account-body account-container"> + <Helmet title={title} titleTemplate="SonarQube - %s" /> - <Tokens user={user}/> + <Tokens user={user} /> - {user.local && ( - <hr className="account-separator"/> - )} + {user.local && <hr className="account-separator" />} - {user.local && ( - <Password user={user}/> - )} - </div> + {user.local && <Password user={user} />} + </div> ); } } -export default connect( - state => ({ user: getCurrentUser(state) }) -)(Security); +export default connect(state => ({ user: getCurrentUser(state) }))(Security); diff --git a/server/sonar-web/src/main/js/apps/account/components/Tokens.js b/server/sonar-web/src/main/js/apps/account/components/Tokens.js index bf1e272a9b5..284f0fd9f9d 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Tokens.js +++ b/server/sonar-web/src/main/js/apps/account/components/Tokens.js @@ -22,15 +22,15 @@ import React, { Component } from 'react'; import TokensView from '../tokens-view'; export default class Tokens extends Component { - componentDidMount () { + componentDidMount() { this.renderView(); } - componentWillUnmount () { + componentWillUnmount() { this.destroyView(); } - renderView () { + renderView() { const account = new Backbone.Model({ id: this.props.user.login }); @@ -41,13 +41,13 @@ export default class Tokens extends Component { }).render(); } - destroyView () { + destroyView() { if (this.destroyView) { this.tokensView.destroy(); } } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/account/components/UserCard.js b/server/sonar-web/src/main/js/apps/account/components/UserCard.js index 55bcad4dada..5635f828279 100644 --- a/server/sonar-web/src/main/js/apps/account/components/UserCard.js +++ b/server/sonar-web/src/main/js/apps/account/components/UserCard.js @@ -25,16 +25,16 @@ export default class UserCard extends React.Component { user: React.PropTypes.object.isRequired }; - render () { + render() { const { user } = this.props; return ( - <div className="account-user"> - <div id="avatar" className="pull-left account-user-avatar"> - <Avatar email={user.email} size={60}/> - </div> - <h1 id="name" className="pull-left">{user.name}</h1> + <div className="account-user"> + <div id="avatar" className="pull-left account-user-avatar"> + <Avatar email={user.email} size={60} /> </div> + <h1 id="name" className="pull-left">{user.name}</h1> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.js b/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.js index c3ba81c4a37..46cf99ccb4b 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/GlobalNotifications.js @@ -43,34 +43,35 @@ class GlobalNotifications extends React.Component { removeNotification: (n: Notification) => void }; - render () { + render() { return ( - <section> - <h2 className="spacer-bottom"> - {translate('my_profile.overall_notifications.title')} - </h2> + <section> + <h2 className="spacer-bottom"> + {translate('my_profile.overall_notifications.title')} + </h2> - <table className="form"> - <thead> - <tr> - <th/> - {this.props.channels.map(channel => ( - <th key={channel} className="text-center"> - <h4>{translate('notification.channel', channel)}</h4> - </th> - ))} - </tr> - </thead> + <table className="form"> + <thead> + <tr> + <th /> + {this.props.channels.map(channel => ( + <th key={channel} className="text-center"> + <h4>{translate('notification.channel', channel)}</h4> + </th> + ))} + </tr> + </thead> - <NotificationsList - notifications={this.props.notifications} - channels={this.props.channels} - types={this.props.types} - checkboxId={(d, c) => `global-notification-${d}-${c}`} - onAdd={this.props.addNotification} - onRemove={this.props.removeNotification}/> - </table> - </section> + <NotificationsList + notifications={this.props.notifications} + channels={this.props.channels} + types={this.props.types} + checkboxId={(d, c) => `global-notification-${d}-${c}`} + onAdd={this.props.addNotification} + onRemove={this.props.removeNotification} + /> + </table> + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/notifications/Notifications.js b/server/sonar-web/src/main/js/apps/account/notifications/Notifications.js index 8e145bdb7d3..8d852e2b567 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/Notifications.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/Notifications.js @@ -31,27 +31,27 @@ class Notifications extends React.Component { fetchNotifications: () => void }; - componentDidMount () { + componentDidMount() { this.props.fetchNotifications(); } - render () { + render() { const title = translate('my_account.page') + ' - ' + translate('my_account.notifications'); return ( - <div className="account-body account-container"> - <Helmet title={title} titleTemplate="SonarQube - %s"/> + <div className="account-body account-container"> + <Helmet title={title} titleTemplate="SonarQube - %s" /> - <p className="big-spacer-bottom"> - {translate('notification.dispatcher.information')} - </p> + <p className="big-spacer-bottom"> + {translate('notification.dispatcher.information')} + </p> - <GlobalNotifications/> + <GlobalNotifications /> - <hr className="account-separator"/> + <hr className="account-separator" /> - <Projects/> - </div> + <Projects /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/notifications/NotificationsList.js b/server/sonar-web/src/main/js/apps/account/notifications/NotificationsList.js index 31d52d45759..193381d9110 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/NotificationsList.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/NotificationsList.js @@ -20,7 +20,12 @@ import React from 'react'; import Checkbox from '../../../components/controls/Checkbox'; import { translate } from '../../../helpers/l10n'; -import { Notification, NotificationsState, ChannelsState, TypesState } from '../../../store/notifications/duck'; +import { + Notification, + NotificationsState, + ChannelsState, + TypesState +} from '../../../store/notifications/duck'; export default class NotificationsList extends React.Component { props: { @@ -32,13 +37,13 @@ export default class NotificationsList extends React.Component { notifications: NotificationsState }; - isEnabled (type: string, channel: string): boolean { - return !!this.props.notifications.find(notification => ( - notification.type === type && notification.channel === channel - )); + isEnabled(type: string, channel: string): boolean { + return !!this.props.notifications.find( + notification => notification.type === type && notification.channel === channel + ); } - handleCheck (type: string, channel: string, checked: boolean) { + handleCheck(type: string, channel: string, checked: boolean) { if (checked) { this.props.onAdd({ type, channel }); } else { @@ -46,25 +51,26 @@ export default class NotificationsList extends React.Component { } } - render () { + render() { const { channels, checkboxId, types } = this.props; return ( - <tbody> - {types.map(type => ( - <tr key={type}> - <td>{translate('notification.dispatcher', type)}</td> - {channels.map(channel => ( - <td key={channel} className="text-center"> - <Checkbox - checked={this.isEnabled(type, channel)} - id={checkboxId(type, channel)} - onCheck={checked => this.handleCheck(type, channel, checked)}/> - </td> - ))} - </tr> - ))} - </tbody> + <tbody> + {types.map(type => ( + <tr key={type}> + <td>{translate('notification.dispatcher', type)}</td> + {channels.map(channel => ( + <td key={channel} className="text-center"> + <Checkbox + checked={this.isEnabled(type, channel)} + id={checkboxId(type, channel)} + onCheck={checked => this.handleCheck(type, channel, checked)} + /> + </td> + ))} + </tr> + ))} + </tbody> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/notifications/ProjectNotifications.js b/server/sonar-web/src/main/js/apps/account/notifications/ProjectNotifications.js index be7f0dfb21d..1f2359717c4 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/ProjectNotifications.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/ProjectNotifications.js @@ -51,7 +51,7 @@ class ProjectNotifications extends React.Component { removeNotification: (n: Notification) => void }; - handleAddNotification ({ channel, type }) { + handleAddNotification({ channel, type }) { this.props.addNotification({ channel, type, @@ -61,7 +61,7 @@ class ProjectNotifications extends React.Component { }); } - handleRemoveNotification ({ channel, type }) { + handleRemoveNotification({ channel, type }) { this.props.removeNotification({ channel, type, @@ -69,34 +69,37 @@ class ProjectNotifications extends React.Component { }); } - render () { + render() { const { project, channels } = this.props; return ( - <table key={project.key} className="form big-spacer-bottom"> - <thead> - <tr> - <th> - <span className="text-normal"><Organization organizationKey={project.organization}/></span> - <h4 className="display-inline-block"> - <Link to={getProjectUrl(project.key)}>{project.name}</Link> - </h4> + <table key={project.key} className="form big-spacer-bottom"> + <thead> + <tr> + <th> + <span className="text-normal"> + <Organization organizationKey={project.organization} /> + </span> + <h4 className="display-inline-block"> + <Link to={getProjectUrl(project.key)}>{project.name}</Link> + </h4> + </th> + {channels.map(channel => ( + <th key={channel} className="text-center"> + <h4>{translate('notification.channel', channel)}</h4> </th> - {channels.map(channel => ( - <th key={channel} className="text-center"> - <h4>{translate('notification.channel', channel)}</h4> - </th> - ))} - </tr> - </thead> - <NotificationsList - notifications={this.props.notifications} - channels={this.props.channels} - types={this.props.types} - checkboxId={(d, c) => `project-notification-${project.key}-${d}-${c}`} - onAdd={n => this.handleAddNotification(n)} - onRemove={n => this.handleRemoveNotification(n)}/> - </table> + ))} + </tr> + </thead> + <NotificationsList + notifications={this.props.notifications} + channels={this.props.channels} + types={this.props.types} + checkboxId={(d, c) => `project-notification-${project.key}-${d}-${c}`} + onAdd={n => this.handleAddNotification(n)} + onRemove={n => this.handleRemoveNotification(n)} + /> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/notifications/Projects.js b/server/sonar-web/src/main/js/apps/account/notifications/Projects.js index cf2796cf022..ccc704ab397 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/Projects.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/Projects.js @@ -48,7 +48,7 @@ class Projects extends React.Component { addedProjects: [] }; - componentWillReceiveProps (nextProps: Props) { + componentWillReceiveProps(nextProps: Props) { // remove all projects from `this.state.addedProjects` that already exist in `nextProps.projects` const nextAddedProjects = differenceBy( this.state.addedProjects, @@ -63,13 +63,12 @@ class Projects extends React.Component { renderOption = option => { return ( - <span> - <Organization organizationKey={option.organization} link={false}/> - <strong>{option.label}</strong> - </span> + <span> + <Organization organizationKey={option.organization} link={false} /> + <strong>{option.label}</strong> + </span> ); - } - + }; loadOptions = (query, cb) => { if (query.length < 2) { cb(null, { options: [] }); @@ -77,62 +76,65 @@ class Projects extends React.Component { } getSuggestions(query) - .then(r => { - const projects = r.results.find(domain => domain.q === 'TRK'); - return projects ? projects.items : []; - }) - .then(projects => projects.map(project => ({ + .then(r => { + const projects = r.results.find(domain => domain.q === 'TRK'); + return projects ? projects.items : []; + }) + .then(projects => + projects.map(project => ({ value: project.key, label: project.name, organization: project.organization }))) - .then(options => { - cb(null, { options }); - }); + .then(options => { + cb(null, { options }); + }); }; handleAddProject = selected => { - const project = { key: selected.value, name: selected.label, organization: selected.organization }; + const project = { + key: selected.value, + name: selected.label, + organization: selected.organization + }; this.setState({ addedProjects: [...this.state.addedProjects, project] }); }; - render () { + render() { const allProjects = [...this.props.projects, ...this.state.addedProjects]; return ( - <section> - <h2 className="spacer-bottom"> - {translate('my_profile.per_project_notifications.title')} - </h2> - - {allProjects.length === 0 && ( - <div className="note"> - {translate('my_account.no_project_notifications')} - </div> - )} - - {allProjects.map(project => ( - <ProjectNotifications key={project.key} project={project}/> - ))} - - <div className="spacer-top panel bg-muted"> - <span className="text-middle spacer-right"> - Set notifications for: - </span> - <Select.Async - autoload={false} - cache={false} - name="new_project" - style={{ width: '300px' }} - loadOptions={this.loadOptions} - minimumInput={2} - optionRenderer={this.renderOption} - onChange={this.handleAddProject} - placeholder="Search Project"/> - </div> - </section> + <section> + <h2 className="spacer-bottom"> + {translate('my_profile.per_project_notifications.title')} + </h2> + + {allProjects.length === 0 && + <div className="note"> + {translate('my_account.no_project_notifications')} + </div>} + + {allProjects.map(project => <ProjectNotifications key={project.key} project={project} />)} + + <div className="spacer-top panel bg-muted"> + <span className="text-middle spacer-right"> + Set notifications for: + </span> + <Select.Async + autoload={false} + cache={false} + name="new_project" + style={{ width: '300px' }} + loadOptions={this.loadOptions} + minimumInput={2} + optionRenderer={this.renderOption} + onChange={this.handleAddProject} + placeholder="Search Project" + /> + </div> + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/GlobalNotifications-test.js b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/GlobalNotifications-test.js index 764a499eec8..7a844312170 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/GlobalNotifications-test.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/GlobalNotifications-test.js @@ -30,12 +30,15 @@ it('should match snapshot', () => { { channel: 'channel2', type: 'type2' } ]; - expect(shallow( - <UnconnectedGlobalNotifications - notifications={notifications} - channels={channels} - types={types} - addNotification={jest.fn()} - removeNotification={jest.fn()}/> - )).toMatchSnapshot(); + expect( + shallow( + <UnconnectedGlobalNotifications + notifications={notifications} + channels={channels} + types={types} + addNotification={jest.fn()} + removeNotification={jest.fn()} + /> + ) + ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Notifications-test.js b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Notifications-test.js index 69ccb43e7f0..d3e14c28d28 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Notifications-test.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Notifications-test.js @@ -22,7 +22,5 @@ import { shallow } from 'enzyme'; import { UnconnectedNotifications } from '../Notifications'; it('should match snapshot', () => { - expect(shallow( - <UnconnectedNotifications fetchNotifications={jest.fn()}/> - )).toMatchSnapshot(); + expect(shallow(<UnconnectedNotifications fetchNotifications={jest.fn()} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/NotificationsList-test.js b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/NotificationsList-test.js index 2fafd101315..6ad339b88eb 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/NotificationsList-test.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/NotificationsList-test.js @@ -32,15 +32,18 @@ const notifications = [ const checkboxId = (t, c) => `checkbox-io-${t}-${c}`; it('should match snapshot', () => { - expect(shallow( - <NotificationsList - onAdd={jest.fn()} - onRemove={jest.fn()} - channels={channels} - checkboxId={checkboxId} - types={types} - notifications={notifications}/> - )).toMatchSnapshot(); + expect( + shallow( + <NotificationsList + onAdd={jest.fn()} + onRemove={jest.fn()} + channels={channels} + checkboxId={checkboxId} + types={types} + notifications={notifications} + /> + ) + ).toMatchSnapshot(); }); it('should call `onAdd` and `onRemove`', () => { @@ -48,12 +51,13 @@ it('should call `onAdd` and `onRemove`', () => { const onRemove = jest.fn(); const wrapper = shallow( <NotificationsList - onAdd={onAdd} - onRemove={onRemove} - channels={channels} - checkboxId={checkboxId} - types={types} - notifications={notifications}/> + onAdd={onAdd} + onRemove={onRemove} + channels={channels} + checkboxId={checkboxId} + types={types} + notifications={notifications} + /> ); const checkbox = wrapper.find(Checkbox).first(); diff --git a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/ProjectNotifications-test.js b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/ProjectNotifications-test.js index 300e6bd2e74..a28c27fa621 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/ProjectNotifications-test.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/ProjectNotifications-test.js @@ -31,15 +31,18 @@ const notifications = [ ]; it('should match snapshot', () => { - expect(shallow( - <UnconnectedProjectNotifications - project={{ key: 'foo', name: 'Foo' }} - notifications={notifications} - channels={channels} - types={types} - addNotification={jest.fn()} - removeNotification={jest.fn()}/> - )).toMatchSnapshot(); + expect( + shallow( + <UnconnectedProjectNotifications + project={{ key: 'foo', name: 'Foo' }} + notifications={notifications} + channels={channels} + types={types} + addNotification={jest.fn()} + removeNotification={jest.fn()} + /> + ) + ).toMatchSnapshot(); }); it('should call `addNotification` and `removeNotification`', () => { @@ -47,12 +50,13 @@ it('should call `addNotification` and `removeNotification`', () => { const removeNotification = jest.fn(); const wrapper = shallow( <UnconnectedProjectNotifications - project={{ key: 'foo', name: 'Foo' }} - notifications={notifications} - channels={channels} - types={types} - addNotification={addNotification} - removeNotification={removeNotification}/> + project={{ key: 'foo', name: 'Foo' }} + notifications={notifications} + channels={channels} + types={types} + addNotification={addNotification} + removeNotification={removeNotification} + /> ); const notificationsList = wrapper.find(NotificationsList); diff --git a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Projects-test.js b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Projects-test.js index eb9d5b4c3b3..facedde8c03 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Projects-test.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/__tests__/Projects-test.js @@ -21,17 +21,12 @@ import React from 'react'; import { shallow } from 'enzyme'; import { UnconnectedProjects } from '../Projects'; -const projects = [ - { key: 'foo', name: 'Foo' }, - { key: 'bar', name: 'Bar' } -]; +const projects = [{ key: 'foo', name: 'Foo' }, { key: 'bar', name: 'Bar' }]; const newProject = { key: 'qux', name: 'Qux' }; it('should render projects', () => { - const wrapper = shallow( - <UnconnectedProjects projects={projects}/> - ); + const wrapper = shallow(<UnconnectedProjects projects={projects} />); expect(wrapper).toMatchSnapshot(); // let's add a new project diff --git a/server/sonar-web/src/main/js/apps/account/notifications/actions.js b/server/sonar-web/src/main/js/apps/account/notifications/actions.js index 053a7aab6c4..85e4821d73c 100644 --- a/server/sonar-web/src/main/js/apps/account/notifications/actions.js +++ b/server/sonar-web/src/main/js/apps/account/notifications/actions.js @@ -28,35 +28,36 @@ import { } from '../../../store/notifications/duck'; import type { Notification } from '../../../store/notifications/duck'; -export const fetchNotifications = () => (dispatch: Function) => { - const onFulfil = (response: GetNotificationsResponse) => { - const organizations = response.notifications +export const fetchNotifications = () => + (dispatch: Function) => { + const onFulfil = (response: GetNotificationsResponse) => { + const organizations = response.notifications .filter(n => n.organization) .map(n => n.organization); - dispatch(fetchOrganizations(organizations)).then(() => { - dispatch(receiveNotifications( - response.notifications, - response.channels, - response.globalTypes, - response.perProjectTypes - )); - }); - }; + dispatch(fetchOrganizations(organizations)).then(() => { + dispatch( + receiveNotifications( + response.notifications, + response.channels, + response.globalTypes, + response.perProjectTypes + ) + ); + }); + }; - return api.getNotifications().then(onFulfil, onFail(dispatch)); -}; + return api.getNotifications().then(onFulfil, onFail(dispatch)); + }; -export const addNotification = (n: Notification) => (dispatch: Function) => ( - api.addNotification(n.channel, n.type, n.project).then( - () => dispatch(addNotificationAction(n)), - onFail(dispatch) - ) -); +export const addNotification = (n: Notification) => + (dispatch: Function) => + api + .addNotification(n.channel, n.type, n.project) + .then(() => dispatch(addNotificationAction(n)), onFail(dispatch)); -export const removeNotification = (n: Notification) => (dispatch: Function) => ( - api.removeNotification(n.channel, n.type, n.project).then( - () => dispatch(removeNotificationAction(n)), - onFail(dispatch) - ) -); +export const removeNotification = (n: Notification) => + (dispatch: Function) => + api + .removeNotification(n.channel, n.type, n.project) + .then(() => dispatch(removeNotificationAction(n)), onFail(dispatch)); diff --git a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js index 9a0c10de08c..34baf4aa21f 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js +++ b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.js @@ -54,16 +54,16 @@ class CreateOrganizationForm extends React.Component { url: '' }; - constructor (props) { + constructor(props) { super(props); this.changeAvatarImage = debounce(this.changeAvatarImage, 500); } - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -110,127 +110,138 @@ class CreateOrganizationForm extends React.Component { Object.assign(organization, { url: this.state.url }); } this.setState({ loading: true }); - this.props.createOrganization(organization).then(this.stopProcessingAndClose, this.stopProcessing); + this.props + .createOrganization(organization) + .then(this.stopProcessingAndClose, this.stopProcessing); }; - render () { + render() { return ( - <Modal isOpen={true} - contentLabel="modal form" - className="modal" - overlayClassName="modal-overlay" - onRequestClose={this.closeForm}> - <header className="modal-head"> - <h2>{translate('my_account.create_organization')}</h2> - </header> - - <form onSubmit={this.handleSubmit}> - <div className="modal-body"> - <div className="modal-field"> - <label htmlFor="organization-name"> - {translate('organization.name')} - <em className="mandatory">*</em> - </label> - <input id="organization-name" - autoFocus={true} - name="name" - required={true} - type="text" - minLength="2" - maxLength="64" - value={this.state.name} - disabled={this.state.loading} - onChange={e => this.setState({ name: e.target.value })}/> - <div className="modal-field-description"> - {translate('organization.name.description')} - </div> + <Modal + isOpen={true} + contentLabel="modal form" + className="modal" + overlayClassName="modal-overlay" + onRequestClose={this.closeForm} + > + <header className="modal-head"> + <h2>{translate('my_account.create_organization')}</h2> + </header> + + <form onSubmit={this.handleSubmit}> + <div className="modal-body"> + <div className="modal-field"> + <label htmlFor="organization-name"> + {translate('organization.name')} + <em className="mandatory">*</em> + </label> + <input + id="organization-name" + autoFocus={true} + name="name" + required={true} + type="text" + minLength="2" + maxLength="64" + value={this.state.name} + disabled={this.state.loading} + onChange={e => this.setState({ name: e.target.value })} + /> + <div className="modal-field-description"> + {translate('organization.name.description')} </div> - <div className="modal-field"> - <label htmlFor="organization-key"> - {translate('organization.key')} - </label> - <input id="organization-key" - name="key" - type="text" - minLength="2" - maxLength="64" - value={this.state.key} - disabled={this.state.loading} - onChange={e => this.setState({ key: e.target.value })}/> - <div className="modal-field-description"> - {translate('organization.key.description')} - </div> + </div> + <div className="modal-field"> + <label htmlFor="organization-key"> + {translate('organization.key')} + </label> + <input + id="organization-key" + name="key" + type="text" + minLength="2" + maxLength="64" + value={this.state.key} + disabled={this.state.loading} + onChange={e => this.setState({ key: e.target.value })} + /> + <div className="modal-field-description"> + {translate('organization.key.description')} </div> - <div className="modal-field"> - <label htmlFor="organization-avatar"> - {translate('organization.avatar')} - </label> - <input id="organization-avatar" - name="avatar" - type="text" - maxLength="256" - value={this.state.avatar} - disabled={this.state.loading} - onChange={this.handleAvatarInputChange}/> - <div className="modal-field-description"> - {translate('organization.avatar.description')} - </div> - {!!this.state.avatarImage && ( - <div className="spacer-top spacer-bottom"> - <div className="little-spacer-bottom"> - {translate('organization.avatar.preview')} - {':'} - </div> - <img src={this.state.avatarImage} alt="" height={30}/> - </div> - )} + </div> + <div className="modal-field"> + <label htmlFor="organization-avatar"> + {translate('organization.avatar')} + </label> + <input + id="organization-avatar" + name="avatar" + type="text" + maxLength="256" + value={this.state.avatar} + disabled={this.state.loading} + onChange={this.handleAvatarInputChange} + /> + <div className="modal-field-description"> + {translate('organization.avatar.description')} </div> - <div className="modal-field"> - <label htmlFor="organization-description"> - {translate('description')} - </label> - <textarea id="organization-description" - name="description" - rows="3" - maxLength="256" - value={this.state.description} - disabled={this.state.loading} - onChange={e => this.setState({ description: e.target.value })}/> - <div className="modal-field-description"> - {translate('organization.description.description')} - </div> + {!!this.state.avatarImage && + <div className="spacer-top spacer-bottom"> + <div className="little-spacer-bottom"> + {translate('organization.avatar.preview')} + {':'} + </div> + <img src={this.state.avatarImage} alt="" height={30} /> + </div>} + </div> + <div className="modal-field"> + <label htmlFor="organization-description"> + {translate('description')} + </label> + <textarea + id="organization-description" + name="description" + rows="3" + maxLength="256" + value={this.state.description} + disabled={this.state.loading} + onChange={e => this.setState({ description: e.target.value })} + /> + <div className="modal-field-description"> + {translate('organization.description.description')} </div> - <div className="modal-field"> - <label htmlFor="organization-url"> - {translate('organization.url')} - </label> - <input id="organization-url" - name="url" - type="text" - maxLength="256" - value={this.state.url} - disabled={this.state.loading} - onChange={e => this.setState({ url: e.target.value })}/> - <div className="modal-field-description"> - {translate('organization.url.description')} - </div> + </div> + <div className="modal-field"> + <label htmlFor="organization-url"> + {translate('organization.url')} + </label> + <input + id="organization-url" + name="url" + type="text" + maxLength="256" + value={this.state.url} + disabled={this.state.loading} + onChange={e => this.setState({ url: e.target.value })} + /> + <div className="modal-field-description"> + {translate('organization.url.description')} </div> </div> - - <footer className="modal-foot"> - {this.state.processing ? ( - <i className="spinner"/> - ) : ( - <div> - <button type="submit">{translate('create')}</button> - <button type="reset" className="button-link" onClick={this.closeForm}> - {translate('cancel')} - </button> - </div> - )} - </footer> - </form> - </Modal> + </div> + + <footer className="modal-foot"> + {this.state.processing + ? <i className="spinner" /> + : <div> + <button type="submit">{translate('create')}</button> + <button type="reset" className="button-link" onClick={this.closeForm}> + {translate('cancel')} + </button> + </div>} + </footer> + </form> + </Modal> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/organizations/OrganizationCard.js b/server/sonar-web/src/main/js/apps/account/organizations/OrganizationCard.js index 9108615aab7..e3adb69a2d8 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/OrganizationCard.js +++ b/server/sonar-web/src/main/js/apps/account/organizations/OrganizationCard.js @@ -27,40 +27,37 @@ export default class OrganizationCard extends React.Component { organization: Organization }; - render () { + render() { const { organization } = this.props; return ( - <div className="account-project-card clearfix"> - <aside className="account-project-side"> - {!!organization.avatar && ( - <div className="spacer-bottom"> - <img src={organization.avatar} height={30} alt={organization.name}/> - </div> - )} - {!!organization.url && ( - <div className="text-limited text-top spacer-bottom"> - <a className="small" href={organization.url} title={organization.url} rel="nofollow"> - {organization.url} - </a> - </div> - )} - </aside> + <div className="account-project-card clearfix"> + <aside className="account-project-side"> + {!!organization.avatar && + <div className="spacer-bottom"> + <img src={organization.avatar} height={30} alt={organization.name} /> + </div>} + {!!organization.url && + <div className="text-limited text-top spacer-bottom"> + <a className="small" href={organization.url} title={organization.url} rel="nofollow"> + {organization.url} + </a> + </div>} + </aside> - <h3 className="account-project-name"> - <OrganizationLink organization={organization}> - {organization.name} - </OrganizationLink> - </h3> + <h3 className="account-project-name"> + <OrganizationLink organization={organization}> + {organization.name} + </OrganizationLink> + </h3> - <div className="account-project-key">{organization.key}</div> + <div className="account-project-key">{organization.key}</div> - {!!organization.description && ( - <div className="account-project-description"> - {organization.description} - </div> - )} - </div> + {!!organization.description && + <div className="account-project-description"> + {organization.description} + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/organizations/OrganizationsList.js b/server/sonar-web/src/main/js/apps/account/organizations/OrganizationsList.js index 291c273c58e..a41bf9b2bef 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/OrganizationsList.js +++ b/server/sonar-web/src/main/js/apps/account/organizations/OrganizationsList.js @@ -27,15 +27,15 @@ export default class OrganizationsList extends React.Component { organizations: Array<Organization> }; - render () { + render() { return ( - <ul className="account-projects-list"> - {this.props.organizations.map(organization => ( - <li key={organization.key}> - <OrganizationCard organization={organization}/> - </li> - ))} - </ul> + <ul className="account-projects-list"> + {this.props.organizations.map(organization => ( + <li key={organization.key}> + <OrganizationCard organization={organization} /> + </li> + ))} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js b/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js index 87872f45004..00cf8d9b1fe 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js +++ b/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.js @@ -45,56 +45,58 @@ class UserOrganizations extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; - Promise.all([this.props.fetchMyOrganizations(), this.props.fetchIfAnyoneCanCreateOrganizations()]).then(() => { + Promise.all([ + this.props.fetchMyOrganizations(), + this.props.fetchIfAnyoneCanCreateOrganizations() + ]).then(() => { if (this.mounted) { this.setState({ loading: false }); } }); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - render () { + render() { const title = translate('my_account.organizations') + ' - ' + translate('my_account.page'); - const anyoneCanCreate = this.props.anyoneCanCreate != null && this.props.anyoneCanCreate.value === 'true'; + const anyoneCanCreate = this.props.anyoneCanCreate != null && + this.props.anyoneCanCreate.value === 'true'; - const canCreateOrganizations = !this.state.loading && (anyoneCanCreate || isUserAdmin(this.props.currentUser)); + const canCreateOrganizations = !this.state.loading && + (anyoneCanCreate || isUserAdmin(this.props.currentUser)); return ( - <div className="account-body account-container"> - <Helmet title={title} titleTemplate="%s - SonarQube"/> + <div className="account-body account-container"> + <Helmet title={title} titleTemplate="%s - SonarQube" /> - <header className="page-header"> - <h2 className="page-title">{translate('my_account.organizations')}</h2> - {canCreateOrganizations && ( - <div className="page-actions"> - <Link to="/account/organizations/create" className="button">{translate('create')}</Link> - </div> - )} - {this.props.organizations.length > 0 ? ( - <div className="page-description"> - {translate('my_account.organizations.description')} - </div> - ) : ( - <div className="page-description"> - {translate('my_account.organizations.no_results')} - </div> - )} - </header> + <header className="page-header"> + <h2 className="page-title">{translate('my_account.organizations')}</h2> + {canCreateOrganizations && + <div className="page-actions"> + <Link to="/account/organizations/create" className="button"> + {translate('create')} + </Link> + </div>} + {this.props.organizations.length > 0 + ? <div className="page-description"> + {translate('my_account.organizations.description')} + </div> + : <div className="page-description"> + {translate('my_account.organizations.no_results')} + </div>} + </header> - {this.state.loading ? ( - <i className="spinner"/> - ) : ( - <OrganizationsList organizations={this.props.organizations}/> - )} + {this.state.loading + ? <i className="spinner" /> + : <OrganizationsList organizations={this.props.organizations} />} - {this.props.children} - </div> + {this.props.children} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/organizations/actions.js b/server/sonar-web/src/main/js/apps/account/organizations/actions.js index 16e1c6dbe05..9731c4dec15 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/actions.js +++ b/server/sonar-web/src/main/js/apps/account/organizations/actions.js @@ -23,20 +23,22 @@ import { receiveMyOrganizations } from '../../../store/organizations/duck'; import { getValues } from '../../../api/settings'; import { receiveValues } from '../../settings/store/values/actions'; -export const fetchMyOrganizations = (): Function => (dispatch: Function): Promise<*> => { - return api.getMyOrganizations().then(keys => { - if (keys.length > 0) { - return api.getOrganizations(keys).then(({ organizations }) => { - return dispatch(receiveMyOrganizations(organizations)); - }); - } else { - return dispatch(receiveMyOrganizations([])); - } - }); -}; +export const fetchMyOrganizations = (): Function => + (dispatch: Function): Promise<*> => { + return api.getMyOrganizations().then(keys => { + if (keys.length > 0) { + return api.getOrganizations(keys).then(({ organizations }) => { + return dispatch(receiveMyOrganizations(organizations)); + }); + } else { + return dispatch(receiveMyOrganizations([])); + } + }); + }; -export const fetchIfAnyoneCanCreateOrganizations = (): Function => (dispatch: Function): Promise<*> => { - return getValues('sonar.organizations.anyoneCanCreate').then(values => { - dispatch(receiveValues(values)); - }); -}; +export const fetchIfAnyoneCanCreateOrganizations = (): Function => + (dispatch: Function): Promise<*> => { + return getValues('sonar.organizations.anyoneCanCreate').then(values => { + dispatch(receiveValues(values)); + }); + }; diff --git a/server/sonar-web/src/main/js/apps/account/profile/Profile.js b/server/sonar-web/src/main/js/apps/account/profile/Profile.js index e2c2bde6f65..ebcbf0d8a07 100644 --- a/server/sonar-web/src/main/js/apps/account/profile/Profile.js +++ b/server/sonar-web/src/main/js/apps/account/profile/Profile.js @@ -38,38 +38,33 @@ class Profile extends React.Component { } }; - render () { + render() { const { customOrganizations, user } = this.props; return ( - <div className="account-body account-container"> - <div className="spacer-bottom"> - Login: <strong id="login">{user.login}</strong> - </div> + <div className="account-body account-container"> + <div className="spacer-bottom"> + Login: <strong id="login">{user.login}</strong> + </div> - {!user.local && user.externalProvider !== 'sonarqube' && ( - <div id="identity-provider" className="spacer-bottom"> - <UserExternalIdentity user={user}/> - </div> - )} + {!user.local && + user.externalProvider !== 'sonarqube' && + <div id="identity-provider" className="spacer-bottom"> + <UserExternalIdentity user={user} /> + </div>} - {!!user.email && ( - <div className="spacer-bottom"> - Email: <strong id="email">{user.email}</strong> - </div> - )} + {!!user.email && + <div className="spacer-bottom"> + Email: <strong id="email">{user.email}</strong> + </div>} - {!customOrganizations && ( - <hr className="account-separator"/> - )} - {!customOrganizations && ( - <UserGroups groups={user.groups}/> - )} + {!customOrganizations && <hr className="account-separator" />} + {!customOrganizations && <UserGroups groups={user.groups} />} - <hr className="account-separator"/> + <hr className="account-separator" /> - <UserScmAccounts user={user} scmAccounts={user.scmAccounts}/> - </div> + <UserScmAccounts user={user} scmAccounts={user.scmAccounts} /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/profile/UserExternalIdentity.js b/server/sonar-web/src/main/js/apps/account/profile/UserExternalIdentity.js index 39c2c39e673..3bf647a6693 100644 --- a/server/sonar-web/src/main/js/apps/account/profile/UserExternalIdentity.js +++ b/server/sonar-web/src/main/js/apps/account/profile/UserExternalIdentity.js @@ -25,40 +25,41 @@ export default class UserExternalIdentity extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.fetchIdentityProviders(); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.user !== this.props.user) { this.this.fetchIdentityProviders(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - fetchIdentityProviders () { + fetchIdentityProviders() { this.setState({ loading: true }); getIdentityProviders() - .then(r => r.identityProviders) - .then(providers => { - if (this.mounted) { - const identityProvider = providers - .find(provider => provider.key === this.props.user.externalProvider); - this.setState({ loading: false, identityProvider }); - } - }) - .catch(() => { - if (this.mounted) { - this.setState({ loading: false }); - } - }); + .then(r => r.identityProviders) + .then(providers => { + if (this.mounted) { + const identityProvider = providers.find( + provider => provider.key === this.props.user.externalProvider + ); + this.setState({ loading: false, identityProvider }); + } + }) + .catch(() => { + if (this.mounted) { + this.setState({ loading: false }); + } + }); } - render () { + render() { const { user } = this.props; const { loading, identityProvider } = this.state; @@ -68,19 +69,26 @@ export default class UserExternalIdentity extends React.Component { if (!identityProvider) { return ( - <div> - {user.externalProvider}{': '}{user.externalIdentity} - </div> + <div> + {user.externalProvider}{': '}{user.externalIdentity} + </div> ); } return ( - <div className="identity-provider" - style={{ backgroundColor: identityProvider.backgroundColor }}> - <img src={window.baseUrl + identityProvider.iconPath} width="14" height="14" alt={identityProvider.name}/> - {' '} - {user.externalIdentity} - </div> + <div + className="identity-provider" + style={{ backgroundColor: identityProvider.backgroundColor }} + > + <img + src={window.baseUrl + identityProvider.iconPath} + width="14" + height="14" + alt={identityProvider.name} + /> + {' '} + {user.externalIdentity} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/profile/UserGroups.js b/server/sonar-web/src/main/js/apps/account/profile/UserGroups.js index c731c97c751..f71360cdb1c 100644 --- a/server/sonar-web/src/main/js/apps/account/profile/UserGroups.js +++ b/server/sonar-web/src/main/js/apps/account/profile/UserGroups.js @@ -25,20 +25,20 @@ export default class UserGroups extends React.Component { groups: React.PropTypes.arrayOf(React.PropTypes.string).isRequired }; - render () { + render() { const { groups } = this.props; return ( - <div> - <h2 className="spacer-bottom">{translate('my_profile.groups')}</h2> - <ul id="groups"> - {groups.map(group => ( - <li key={group} className="little-spacer-bottom" title={group}> - {group} - </li> - ))} - </ul> - </div> + <div> + <h2 className="spacer-bottom">{translate('my_profile.groups')}</h2> + <ul id="groups"> + {groups.map(group => ( + <li key={group} className="little-spacer-bottom" title={group}> + {group} + </li> + ))} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/profile/UserScmAccounts.js b/server/sonar-web/src/main/js/apps/account/profile/UserScmAccounts.js index bfabf2e5fd9..fa42ae4262a 100644 --- a/server/sonar-web/src/main/js/apps/account/profile/UserScmAccounts.js +++ b/server/sonar-web/src/main/js/apps/account/profile/UserScmAccounts.js @@ -26,30 +26,29 @@ export default class UserScmAccounts extends React.Component { scmAccounts: React.PropTypes.arrayOf(React.PropTypes.string).isRequired }; - render () { + render() { const { user, scmAccounts } = this.props; return ( - <div> - <h2 className="spacer-bottom">{translate('my_profile.scm_accounts')}</h2> - <ul id="scm-accounts"> - <li className="little-spacer-bottom text-ellipsis" title={user.login}> - {user.login} - </li> + <div> + <h2 className="spacer-bottom">{translate('my_profile.scm_accounts')}</h2> + <ul id="scm-accounts"> + <li className="little-spacer-bottom text-ellipsis" title={user.login}> + {user.login} + </li> - {user.email && ( - <li className="little-spacer-bottom text-ellipsis" title={user.email}> - {user.email} - </li> - )} + {user.email && + <li className="little-spacer-bottom text-ellipsis" title={user.email}> + {user.email} + </li>} - {scmAccounts.map(scmAccount => ( - <li key={scmAccount} className="little-spacer-bottom" title={scmAccount}> - {scmAccount} - </li> - ))} - </ul> - </div> + {scmAccounts.map(scmAccount => ( + <li key={scmAccount} className="little-spacer-bottom" title={scmAccount}> + {scmAccount} + </li> + ))} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js index ad0fb0caf15..6464f3edeeb 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js +++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectCard.js @@ -30,69 +30,64 @@ export default class ProjectCard extends React.Component { project: projectType.isRequired }; - render () { + render() { const { project } = this.props; const isAnalyzed = project.lastAnalysisDate != null; const analysisMoment = isAnalyzed && moment(project.lastAnalysisDate); const links = sortBy(project.links, 'type'); return ( - <div className="account-project-card clearfix"> - <aside className="account-project-side"> - {isAnalyzed ? ( - <div className="account-project-analysis" - title={analysisMoment.format('LLL')}> - {translateWithParameters( - 'my_account.projects.analyzed_x', - analysisMoment.fromNow() - )} - </div> - ) : ( - <div className="account-project-analysis"> - {translate('my_account.projects.never_analyzed')} - </div> - )} + <div className="account-project-card clearfix"> + <aside className="account-project-side"> + {isAnalyzed + ? <div className="account-project-analysis" title={analysisMoment.format('LLL')}> + {translateWithParameters( + 'my_account.projects.analyzed_x', + analysisMoment.fromNow() + )} + </div> + : <div className="account-project-analysis"> + {translate('my_account.projects.never_analyzed')} + </div>} - {project.qualityGate != null && ( - <div className="account-project-quality-gate"> - <Level level={project.qualityGate}/> - </div> - )} - </aside> + {project.qualityGate != null && + <div className="account-project-quality-gate"> + <Level level={project.qualityGate} /> + </div>} + </aside> - <h3 className="account-project-name"> - <Link to={{ pathname: '/dashboard', query: { id: project.key } }}> - {project.name} - </Link> - </h3> + <h3 className="account-project-name"> + <Link to={{ pathname: '/dashboard', query: { id: project.key } }}> + {project.name} + </Link> + </h3> - {links.length > 0 && ( - <div className="account-project-links"> - <ul className="list-inline"> - {links.map(link => ( - <li key={link.type}> - <a - className="link-with-icon" - href={link.href} - title={link.name} - target="_blank" - rel="nofollow"> - <i className={`icon-color-link icon-${link.type}`}/> - </a> - </li> - ))} - </ul> - </div> - )} + {links.length > 0 && + <div className="account-project-links"> + <ul className="list-inline"> + {links.map(link => ( + <li key={link.type}> + <a + className="link-with-icon" + href={link.href} + title={link.name} + target="_blank" + rel="nofollow" + > + <i className={`icon-color-link icon-${link.type}`} /> + </a> + </li> + ))} + </ul> + </div>} - <div className="account-project-key">{project.key}</div> + <div className="account-project-key">{project.key}</div> - {!!project.description && ( - <div className="account-project-description"> - {project.description} - </div> - )} - </div> + {!!project.description && + <div className="account-project-description"> + {project.description} + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/projects/Projects.js b/server/sonar-web/src/main/js/apps/account/projects/Projects.js index 6ed39db6e44..6fe13a1e67a 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/Projects.js +++ b/server/sonar-web/src/main/js/apps/account/projects/Projects.js @@ -31,39 +31,36 @@ export default class Projects extends React.Component { loadMore: React.PropTypes.func.isRequired }; - render () { + render() { const { projects } = this.props; return ( - <div id="account-projects"> - {projects.length === 0 ? ( - <div className="js-no-results"> - {translate('my_account.projects.no_results')} - </div> - ) : ( - <p> - {translate('my_account.projects.description')} - </p> - )} + <div id="account-projects"> + {projects.length === 0 + ? <div className="js-no-results"> + {translate('my_account.projects.no_results')} + </div> + : <p> + {translate('my_account.projects.description')} + </p>} - {projects.length > 0 && ( - <ul className="account-projects-list"> - {projects.map(project => ( - <li key={project.key}> - <ProjectCard project={project}/> - </li> - ))} - </ul> - )} + {projects.length > 0 && + <ul className="account-projects-list"> + {projects.map(project => ( + <li key={project.key}> + <ProjectCard project={project} /> + </li> + ))} + </ul>} - {projects.length > 0 && ( - <ListFooter - count={projects.length} - total={this.props.total} - ready={!this.props.loading} - loadMore={this.props.loadMore}/> - )} - </div> + {projects.length > 0 && + <ListFooter + count={projects.length} + total={this.props.total} + ready={!this.props.loading} + loadMore={this.props.loadMore} + />} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js index 292d9d95488..240815f2602 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js +++ b/server/sonar-web/src/main/js/apps/account/projects/ProjectsContainer.js @@ -30,21 +30,21 @@ export default class ProjectsContainer extends React.Component { query: '' }; - componentWillMount () { + componentWillMount() { this.loadMore = this.loadMore.bind(this); this.search = this.search.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadProjects(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadProjects (page = this.state.page, query = this.state.query) { + loadProjects(page = this.state.page, query = this.state.query) { this.setState({ loading: true }); const data = { ps: 100 }; if (page > 1) { @@ -54,8 +54,7 @@ export default class ProjectsContainer extends React.Component { data.q = query; } return getMyProjects(data).then(r => { - const projects = page > 1 ? - [...this.state.projects, ...r.projects] : r.projects; + const projects = page > 1 ? [...this.state.projects, ...r.projects] : r.projects; this.setState({ projects, query, @@ -66,39 +65,37 @@ export default class ProjectsContainer extends React.Component { }); } - loadMore () { + loadMore() { return this.loadProjects(this.state.page + 1); } - search (query) { + search(query) { return this.loadProjects(1, query); } - render () { + render() { if (this.state.projects == null) { return ( - <div className="text-center"> - <i className="spinner spinner-margin"/> - </div> + <div className="text-center"> + <i className="spinner spinner-margin" /> + </div> ); } - const title = translate('my_account.page') + ' - ' + - translate('my_account.projects'); + const title = translate('my_account.page') + ' - ' + translate('my_account.projects'); return ( - <div className="account-body account-container"> - <Helmet - title={title} - titleTemplate="SonarQube - %s"/> + <div className="account-body account-container"> + <Helmet title={title} titleTemplate="SonarQube - %s" /> - <Projects - projects={this.state.projects} - total={this.state.total} - loading={this.state.loading} - loadMore={this.loadMore} - search={this.search}/> - </div> + <Projects + projects={this.state.projects} + total={this.state.total} + loading={this.state.loading} + loadMore={this.loadMore} + search={this.search} + /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js b/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js index 9378a023f7a..f681f8af62f 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js +++ b/server/sonar-web/src/main/js/apps/account/projects/__tests__/ProjectCard-test.js @@ -27,20 +27,20 @@ const BASE = { id: 'id', key: 'key', name: 'name', links: [] }; it('should render key and name', () => { const project = { ...BASE }; - const output = shallow(<ProjectCard project={project}/>); + const output = shallow(<ProjectCard project={project} />); expect(output.find('.account-project-key').text()).toBe('key'); expect(output.find('.account-project-name').find(Link).prop('children')).toBe('name'); }); it('should render description', () => { const project = { ...BASE, description: 'bla' }; - const output = shallow(<ProjectCard project={project}/>); + const output = shallow(<ProjectCard project={project} />); expect(output.find('.account-project-description').text()).toBe('bla'); }); it('should not render optional fields', () => { const project = { ...BASE }; - const output = shallow(<ProjectCard project={project}/>); + const output = shallow(<ProjectCard project={project} />); expect(output.find('.account-project-description').length).toBe(0); expect(output.find('.account-project-quality-gate').length).toBe(0); expect(output.find('.account-project-links').length).toBe(0); @@ -48,21 +48,23 @@ it('should not render optional fields', () => { it('should render analysis date', () => { const project = { ...BASE, lastAnalysisDate: '2016-05-17' }; - const output = shallow(<ProjectCard project={project}/>); - expect(output.find('.account-project-analysis').text()).toContain('my_account.projects.analyzed_x'); + const output = shallow(<ProjectCard project={project} />); + expect(output.find('.account-project-analysis').text()).toContain( + 'my_account.projects.analyzed_x' + ); }); it('should not render analysis date', () => { const project = { ...BASE }; - const output = shallow(<ProjectCard project={project}/>); - expect(output.find('.account-project-analysis').text()).toContain('my_account.projects.never_analyzed'); + const output = shallow(<ProjectCard project={project} />); + expect(output.find('.account-project-analysis').text()).toContain( + 'my_account.projects.never_analyzed' + ); }); it('should render quality gate status', () => { const project = { ...BASE, qualityGate: 'ERROR' }; - const output = shallow( - <ProjectCard project={project}/> - ); + const output = shallow(<ProjectCard project={project} />); expect(output.find('.account-project-quality-gate').find(Level).prop('level')).toBe('ERROR'); }); @@ -71,6 +73,6 @@ it('should render links', () => { ...BASE, links: [{ name: 'n', type: 't', href: 'h' }] }; - const output = shallow(<ProjectCard project={project}/>); + const output = shallow(<ProjectCard project={project} />); expect(output.find('.account-project-links').find('li').length).toBe(1); }); diff --git a/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js b/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js index 470050668ca..06329efad3e 100644 --- a/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js +++ b/server/sonar-web/src/main/js/apps/account/projects/__tests__/Projects-test.js @@ -31,11 +31,12 @@ it('should render list of ProjectCards', () => { const output = shallow( <Projects - projects={projects} - total={5} - loading={false} - search={() => true} - loadMore={() => true}/> + projects={projects} + total={5} + loading={false} + search={() => true} + loadMore={() => true} + /> ); expect(output.find(ProjectCard).length).toBe(2); @@ -50,11 +51,12 @@ it('should render ListFooter', () => { const footer = shallow( <Projects - projects={projects} - total={5} - loading={false} - search={() => true} - loadMore={loadMore}/> + projects={projects} + total={5} + loading={false} + search={() => true} + loadMore={loadMore} + /> ).find(ListFooter); expect(footer.length).toBe(1); @@ -65,12 +67,7 @@ it('should render ListFooter', () => { it('should render when no results', () => { const output = shallow( - <Projects - projects={[]} - total={0} - loading={false} - search={() => true} - loadMore={() => true}/> + <Projects projects={[]} total={0} loading={false} search={() => true} loadMore={() => true} /> ); expect(output.find('.js-no-results').length).toBe(1); diff --git a/server/sonar-web/src/main/js/apps/account/routes.js b/server/sonar-web/src/main/js/apps/account/routes.js index c89b032f839..daeea0fbb33 100644 --- a/server/sonar-web/src/main/js/apps/account/routes.js +++ b/server/sonar-web/src/main/js/apps/account/routes.js @@ -28,17 +28,23 @@ import UserOrganizations from './organizations/UserOrganizations'; import CreateOrganizationForm from './organizations/CreateOrganizationForm'; export default ( - <Route component={Account}> - <IndexRoute component={Profile}/> - <Route path="security" component={Security}/> - <Route path="projects" component={ProjectsContainer}/> - <Route path="notifications" component={Notifications}/> - <Route path="organizations" component={UserOrganizations}> - <Route path="create" component={CreateOrganizationForm}/> - </Route> - - <Route path="issues" onEnter={() => { - window.location = window.baseUrl + '/issues' + window.location.hash + '|assigned_to_me=true'; - }}/> + <Route component={Account}> + <IndexRoute component={Profile} /> + <Route path="security" component={Security} /> + <Route path="projects" component={ProjectsContainer} /> + <Route path="notifications" component={Notifications} /> + <Route path="organizations" component={UserOrganizations}> + <Route path="create" component={CreateOrganizationForm} /> </Route> + + <Route + path="issues" + onEnter={() => { + window.location = window.baseUrl + + '/issues' + + window.location.hash + + '|assigned_to_me=true'; + }} + /> + </Route> ); diff --git a/server/sonar-web/src/main/js/apps/account/tokens-view.js b/server/sonar-web/src/main/js/apps/account/tokens-view.js index 1e8a9054645..62c6f8f9143 100644 --- a/server/sonar-web/src/main/js/apps/account/tokens-view.js +++ b/server/sonar-web/src/main/js/apps/account/tokens-view.js @@ -26,46 +26,46 @@ import { getTokens, generateToken, revokeToken } from '../../api/user-tokens'; export default Marionette.ItemView.extend({ template: Template, - events () { + events() { return { 'submit .js-generate-token-form': 'onGenerateTokenFormSubmit', 'submit .js-revoke-token-form': 'onRevokeTokenFormSubmit' }; }, - initialize () { + initialize() { this.tokens = null; this.newToken = null; this.errors = []; this.requestTokens(); }, - requestTokens () { + requestTokens() { return getTokens(this.model.id).then(tokens => { this.tokens = tokens; this.render(); }); }, - onGenerateTokenFormSubmit (e) { + onGenerateTokenFormSubmit(e) { e.preventDefault(); this.errors = []; this.newToken = null; const tokenName = this.$('.js-generate-token-form input').val(); generateToken(this.model.id, tokenName) - .then(response => { - this.newToken = response; - this.requestTokens(); - }) - .catch(error => { - error.response.json().then(response => { - this.errors = response.errors; - this.render(); - }); + .then(response => { + this.newToken = response; + this.requestTokens(); + }) + .catch(error => { + error.response.json().then(response => { + this.errors = response.errors; + this.render(); }); + }); }, - onRevokeTokenFormSubmit (e) { + onRevokeTokenFormSubmit(e) { e.preventDefault(); const tokenName = $(e.currentTarget).data('token'); const token = this.tokens.find(token => token.name === `${tokenName}`); @@ -79,19 +79,21 @@ export default Marionette.ItemView.extend({ } }, - onRender () { + onRender() { const copyButton = this.$('.js-copy-to-clipboard'); if (copyButton.length) { const clipboard = new Clipboard(copyButton.get(0)); clipboard.on('success', () => { - copyButton.tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' }).tooltip('show'); + copyButton + .tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' }) + .tooltip('show'); setTimeout(() => copyButton.tooltip('hide'), 1000); }); } this.newToken = null; }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), tokens: this.tokens, @@ -99,5 +101,4 @@ export default Marionette.ItemView.extend({ errors: this.errors }; } - }); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/__tests__/background-tasks-test.js b/server/sonar-web/src/main/js/apps/background-tasks/__tests__/background-tasks-test.js index 71ebab17170..b34ba6668ab 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/__tests__/background-tasks-test.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/__tests__/background-tasks-test.js @@ -47,29 +47,32 @@ describe('Search', () => { }; it('should render search form', () => { - const component = shallow(<Search {...defaultProps}/>); + const component = shallow(<Search {...defaultProps} />); expect(component.find('.js-search').length).toBe(1); }); it('should not render search form', () => { - const component = shallow(<Search {...defaultProps} component={{ id: 'ABCD' }}/>); + const component = shallow(<Search {...defaultProps} component={{ id: 'ABCD' }} />); expect(component.find('.js-search').length).toBe(0); }); it('should search', done => { const searchSpy = jest.fn(); - const component = shallow(<Search {...defaultProps} onFilterUpdate={searchSpy}/>); + const component = shallow(<Search {...defaultProps} onFilterUpdate={searchSpy} />); const searchInput = component.find('.js-search'); change(searchInput, 'some search query'); - setTimeout(() => { - expect(searchSpy).toBeCalledWith({ query: 'some search query' }); - done(); - }, DEBOUNCE_DELAY); + setTimeout( + () => { + expect(searchSpy).toBeCalledWith({ query: 'some search query' }); + done(); + }, + DEBOUNCE_DELAY + ); }); it('should reload', () => { const reloadSpy = jest.fn(); - const component = shallow(<Search {...defaultProps} onReload={reloadSpy}/>); + const component = shallow(<Search {...defaultProps} onReload={reloadSpy} />); const reloadButton = component.find('.js-reload'); expect(reloadSpy).not.toBeCalled(); click(reloadButton); @@ -80,28 +83,38 @@ describe('Search', () => { describe('Stats', () => { describe('Pending', () => { it('should show zero pending', () => { - const result = shallow(<Stats pendingCount={0} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats pendingCount={0} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-pending-count').text()).toContain('0'); }); it('should show 5 pending', () => { - const result = shallow(<Stats pendingCount={5} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats pendingCount={5} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-pending-count').text()).toContain('5'); }); it('should not show cancel pending button', () => { - const result = shallow(<Stats pendingCount={0} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats pendingCount={0} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-cancel-pending').length).toBe(0); }); it('should show cancel pending button', () => { - const result = shallow(<Stats pendingCount={5} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats pendingCount={5} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-cancel-pending').length).toBe(1); }); it('should trigger cancelling pending', () => { const spy = jest.fn(); - const result = shallow(<Stats pendingCount={5} onCancelAllPending={spy} onShowFailing={stub}/>); + const result = shallow( + <Stats pendingCount={5} onCancelAllPending={spy} onShowFailing={stub} /> + ); expect(spy).not.toBeCalled(); click(result.find('.js-cancel-pending')); expect(spy).toBeCalled(); @@ -110,28 +123,38 @@ describe('Stats', () => { describe('Failures', () => { it('should show zero failures', () => { - const result = shallow(<Stats failingCount={0} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats failingCount={0} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-failures-count').text()).toContain('0'); }); it('should show 5 failures', () => { - const result = shallow(<Stats failingCount={5} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats failingCount={5} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-failures-count').text()).toContain('5'); }); it('should not show link to failures', () => { - const result = shallow(<Stats failingCount={0} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats failingCount={0} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-failures-count').is('a')).toBeFalsy(); }); it('should show link to failures', () => { - const result = shallow(<Stats failingCount={5} onCancelAllPending={stub} onShowFailing={stub}/>); + const result = shallow( + <Stats failingCount={5} onCancelAllPending={stub} onShowFailing={stub} /> + ); expect(result.find('.js-failures-count').is('a')).toBeTruthy(); }); it('should trigger filtering failures', () => { const spy = jest.fn(); - const result = shallow(<Stats failingCount={5} onCancelAllPending={stub} onShowFailing={spy}/>); + const result = shallow( + <Stats failingCount={5} onCancelAllPending={stub} onShowFailing={spy} /> + ); expect(spy).not.toBeCalled(); click(result.find('.js-failures-count')); expect(spy).toBeCalled(); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js index 10349a820e2..ed7d23a657d 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/BackgroundTasksApp.js @@ -29,7 +29,13 @@ import Footer from './Footer'; import Stats from '../components/Stats'; import Search from '../components/Search'; import Tasks from '../components/Tasks'; -import { getTypes, getActivity, getStatus, cancelAllTasks, cancelTask as cancelTaskAPI } from '../../../api/ce'; +import { + getTypes, + getActivity, + getStatus, + cancelAllTasks, + cancelTask as cancelTaskAPI +} from '../../../api/ce'; import { updateTask, mapFiltersToParameters } from '../utils'; import { Task } from '../types'; import { getComponent } from '../../../store/rootReducer'; @@ -48,7 +54,7 @@ type State = { types?: Array<*>, query: string, pendingCount: number, - failingCount: number, + failingCount: number }; class BackgroundTasksApp extends React.Component { @@ -72,11 +78,11 @@ class BackgroundTasksApp extends React.Component { failingCount: 0 }; - componentWillMount () { + componentWillMount() { this.loadTasksDebounced = debounce(this.loadTasks.bind(this), DEBOUNCE_DELAY); } - componentDidMount () { + componentDidMount() { this.mounted = true; getTypes().then(types => { @@ -85,28 +91,30 @@ class BackgroundTasksApp extends React.Component { }); } - shouldComponentUpdate (nextProps: Props, nextState: State) { + shouldComponentUpdate(nextProps: Props, nextState: State) { return shallowCompare(this, nextProps, nextState); } - componentDidUpdate (prevProps: Props) { - if (prevProps.component !== this.props.component || - prevProps.location !== this.props.location) { + componentDidUpdate(prevProps: Props) { + if ( + prevProps.component !== this.props.component || prevProps.location !== this.props.location + ) { this.loadTasksDebounced(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadTasks () { + loadTasks() { this.setState({ loading: true }); const status = this.props.location.query.status || DEFAULT_FILTERS.status; const taskType = this.props.location.query.taskType || DEFAULT_FILTERS.taskType; const currents = this.props.location.query.currents || DEFAULT_FILTERS.currents; - const minSubmittedAt = this.props.location.query.minSubmittedAt || DEFAULT_FILTERS.minSubmittedAt; + const minSubmittedAt = this.props.location.query.minSubmittedAt || + DEFAULT_FILTERS.minSubmittedAt; const maxExecutedAt = this.props.location.query.maxExecutedAt || DEFAULT_FILTERS.maxExecutedAt; const query = this.props.location.query.query || DEFAULT_FILTERS.query; @@ -117,10 +125,7 @@ class BackgroundTasksApp extends React.Component { parameters.componentId = this.props.component.id; } - Promise.all([ - getActivity(parameters), - getStatus(parameters.componentId) - ]).then(responses => { + Promise.all([getActivity(parameters), getStatus(parameters.componentId)]).then(responses => { if (this.mounted) { const [activity, status] = responses; const tasks = activity.tasks; @@ -141,7 +146,7 @@ class BackgroundTasksApp extends React.Component { }); } - handleFilterUpdate (nextState: Object) { + handleFilterUpdate(nextState: Object) { const nextQuery = { ...this.props.location.query, ...nextState }; // remove defaults @@ -157,7 +162,7 @@ class BackgroundTasksApp extends React.Component { }); } - handleCancelTask (task: Task) { + handleCancelTask(task: Task) { this.setState({ loading: true }); cancelTaskAPI(task.id).then(nextTask => { @@ -168,11 +173,11 @@ class BackgroundTasksApp extends React.Component { }); } - handleFilterTask (task: Task) { + handleFilterTask(task: Task) { this.handleFilterUpdate({ query: task.componentKey }); } - handleShowFailing () { + handleShowFailing() { this.handleFilterUpdate({ ...DEFAULT_FILTERS, status: STATUSES.FAILED, @@ -180,7 +185,7 @@ class BackgroundTasksApp extends React.Component { }); } - handleCancelAllPending () { + handleCancelAllPending() { this.setState({ loading: true }); cancelAllTasks().then(() => { @@ -190,15 +195,15 @@ class BackgroundTasksApp extends React.Component { }); } - render () { + render() { const { component } = this.props; const { loading, types, tasks, pendingCount, failingCount } = this.state; if (!types) { return ( - <div className="page"> - <i className="spinner"/> - </div> + <div className="page"> + <i className="spinner" /> + </div> ); } @@ -210,45 +215,50 @@ class BackgroundTasksApp extends React.Component { const query = this.props.location.query.query || ''; return ( - <div className="page page-limited"> - <Header/> - - <Stats - component={component} - pendingCount={pendingCount} - failingCount={failingCount} - onShowFailing={this.handleShowFailing.bind(this)} - onCancelAllPending={this.handleCancelAllPending.bind(this)}/> - - <Search - loading={loading} - component={component} - status={status} - currents={currents} - minSubmittedAt={minSubmittedAt} - maxExecutedAt={maxExecutedAt} - query={query} - taskType={taskType} - types={types} - onFilterUpdate={this.handleFilterUpdate.bind(this)} - onReload={this.loadTasksDebounced}/> - - <Tasks - loading={loading} - component={component} - types={types} - tasks={tasks} - onCancelTask={this.handleCancelTask.bind(this)} - onFilterTask={this.handleFilterTask.bind(this)}/> - - <Footer tasks={tasks}/> - </div> + <div className="page page-limited"> + <Header /> + + <Stats + component={component} + pendingCount={pendingCount} + failingCount={failingCount} + onShowFailing={this.handleShowFailing.bind(this)} + onCancelAllPending={this.handleCancelAllPending.bind(this)} + /> + + <Search + loading={loading} + component={component} + status={status} + currents={currents} + minSubmittedAt={minSubmittedAt} + maxExecutedAt={maxExecutedAt} + query={query} + taskType={taskType} + types={types} + onFilterUpdate={this.handleFilterUpdate.bind(this)} + onReload={this.loadTasksDebounced} + /> + + <Tasks + loading={loading} + component={component} + types={types} + tasks={tasks} + onCancelTask={this.handleCancelTask.bind(this)} + onFilterTask={this.handleFilterTask.bind(this)} + /> + + <Footer tasks={tasks} /> + </div> ); } } const mapStateToProps = (state, ownProps) => ({ - component: ownProps.location.query.id ? getComponent(state, ownProps.location.query.id) : undefined + component: ownProps.location.query.id + ? getComponent(state, ownProps.location.query.id) + : undefined }); const mapDispatchToProps = { fetchOrganizations }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.js b/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.js index 5fec14c598c..b91f872b82c 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.js @@ -23,12 +23,12 @@ import Checkbox from '../../../components/controls/Checkbox'; import { CURRENTS } from '../constants'; const CurrentsFilter = ({ value, onChange }: { value: ?string, onChange: (string) => void }) => { - function handleChange (value) { + function handleChange(value) { const newValue = value ? CURRENTS.ONLY_CURRENTS : CURRENTS.ALL; onChange(newValue); } - function handleLabelClick (e) { + function handleLabelClick(e) { const newValue = value === CURRENTS.ALL ? CURRENTS.ONLY_CURRENTS : CURRENTS.ALL; e.preventDefault(); @@ -38,18 +38,19 @@ const CurrentsFilter = ({ value, onChange }: { value: ?string, onChange: (string const checked = value === CURRENTS.ONLY_CURRENTS; return ( - <div className="bt-search-form-field"> - <Checkbox checked={checked} onCheck={handleChange}/> - - <label - style={{ cursor: 'pointer' }} - role="checkbox" - tabIndex="0" - aria-checked={checked ? 'true' : 'false'} - onClick={handleLabelClick}> - Yes - </label> - </div> + <div className="bt-search-form-field"> + <Checkbox checked={checked} onCheck={handleChange} /> + + <label + style={{ cursor: 'pointer' }} + role="checkbox" + tabIndex="0" + aria-checked={checked ? 'true' : 'false'} + onClick={handleLabelClick} + > + Yes + </label> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/DateFilter.js b/server/sonar-web/src/main/js/apps/background-tasks/components/DateFilter.js index bf503cff53c..1d811180649 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/DateFilter.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/DateFilter.js @@ -17,22 +17,22 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import $ from 'jquery'; import moment from 'moment'; import React, { Component } from 'react'; import { DATE_FORMAT } from '../constants'; export default class DateFilter extends Component { - componentDidMount () { + componentDidMount() { this.attachDatePicker(); } - componentDidUpdate () { + componentDidUpdate() { this.attachDatePicker(); } - attachDatePicker () { + attachDatePicker() { const opts = { dateFormat: 'yy-mm-dd', changeMonth: true, @@ -45,7 +45,7 @@ export default class DateFilter extends Component { } } - handleChange () { + handleChange() { const date = {}; const minDateRaw = this.refs.minDate.value; const maxDateRaw = this.refs.maxDate.value; @@ -63,27 +63,29 @@ export default class DateFilter extends Component { this.props.onChange(date); } - render () { + render() { const { minSubmittedAt, maxExecutedAt } = this.props; return ( - <div> - <input - className="input-small" - value={minSubmittedAt} - onChange={() => true} - ref="minDate" - type="text" - placeholder="From"/> - {' '} - <input - className="input-small" - value={maxExecutedAt} - onChange={() => true} - ref="maxDate" - type="text" - placeholder="To"/> - </div> + <div> + <input + className="input-small" + value={minSubmittedAt} + onChange={() => true} + ref="minDate" + type="text" + placeholder="From" + /> + {' '} + <input + className="input-small" + value={maxExecutedAt} + onChange={() => true} + ref="maxDate" + type="text" + placeholder="To" + /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Footer.js b/server/sonar-web/src/main/js/apps/background-tasks/components/Footer.js index 2135b74b581..ced62322f91 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Footer.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Footer.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import { Task } from '../types'; import { translateWithParameters } from '../../../helpers/l10n'; @@ -30,9 +30,9 @@ const Footer = ({ tasks }: { tasks: Task[] }) => { } return ( - <footer className="spacer-top note text-center"> - {translateWithParameters('max_results_reached', LIMIT)} - </footer> + <footer className="spacer-top note text-center"> + {translateWithParameters('max_results_reached', LIMIT)} + </footer> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Header.js b/server/sonar-web/src/main/js/apps/background-tasks/components/Header.js index 61d973c9fb8..c775e76f17a 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Header.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Header.js @@ -17,20 +17,20 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import { translate } from '../../../helpers/l10n'; const Header = () => { return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('background_tasks.page')} - </h1> - <p className="page-description"> - {translate('background_tasks.page.description')} - </p> - </header> + <header className="page-header"> + <h1 className="page-title"> + {translate('background_tasks.page')} + </h1> + <p className="page-description"> + {translate('background_tasks.page.description')} + </p> + </header> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Search.js b/server/sonar-web/src/main/js/apps/background-tasks/components/Search.js index ddb33c7f619..58d8fd12cff 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Search.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Search.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import StatusFilter from './StatusFilter'; import TypesFilter from './TypesFilter'; @@ -37,38 +37,38 @@ export default class Search extends React.Component { onReload: React.PropTypes.func.isRequired }; - handleStatusChange (status: string) { + handleStatusChange(status: string) { this.props.onFilterUpdate({ status }); } - handleTypeChange (taskType: string) { + handleTypeChange(taskType: string) { this.props.onFilterUpdate({ taskType }); } - handleCurrentsChange (currents: string) { + handleCurrentsChange(currents: string) { this.props.onFilterUpdate({ currents }); } - handleDateChange (date: string) { + handleDateChange(date: string) { this.props.onFilterUpdate(date); } - handleQueryChange (query: string) { + handleQueryChange(query: string) { this.props.onFilterUpdate({ query }); } - handleReload (e: Object) { + handleReload(e: Object) { e.target.blur(); this.props.onReload(); } - handleReset (e: Object) { + handleReset(e: Object) { e.preventDefault(); e.target.blur(); this.props.onFilterUpdate(DEFAULT_FILTERS); } - renderSearchBox () { + renderSearchBox() { const { component, query } = this.props; if (component) { @@ -77,95 +77,86 @@ export default class Search extends React.Component { } return ( - <li> - <h6 className="bt-search-form-label"> - Search by Task or Component - </h6> - - <input - onChange={e => this.handleQueryChange(e.target.value)} - value={query} - ref="searchInput" - className="js-search input-large" - type="search" - placeholder="Search"/> - </li> + <li> + <h6 className="bt-search-form-label"> + Search by Task or Component + </h6> + + <input + onChange={e => this.handleQueryChange(e.target.value)} + value={query} + ref="searchInput" + className="js-search input-large" + type="search" + placeholder="Search" + /> + </li> ); } - render () { + render() { const { - loading, - component, - types, - status, - taskType, - currents, - minSubmittedAt, - maxExecutedAt + loading, + component, + types, + status, + taskType, + currents, + minSubmittedAt, + maxExecutedAt } = this.props; return ( - <section className="big-spacer-top big-spacer-bottom"> - <ul className="bt-search-form"> + <section className="big-spacer-top big-spacer-bottom"> + <ul className="bt-search-form"> + <li> + <h6 className="bt-search-form-label"> + Status + </h6> + <StatusFilter value={status} onChange={this.handleStatusChange.bind(this)} /> + </li> + {types.length > 1 && <li> <h6 className="bt-search-form-label"> - Status + Type </h6> - <StatusFilter - value={status} - onChange={this.handleStatusChange.bind(this)}/> - </li> - {types.length > 1 && ( - <li> - <h6 className="bt-search-form-label"> - Type - </h6> - <TypesFilter - value={taskType} - types={types} - onChange={this.handleTypeChange.bind(this)}/> - </li> - )} - {!component && ( - <li> - <h6 className="bt-search-form-label"> - Only Latest Analysis - </h6> - <CurrentsFilter - value={currents} - onChange={this.handleCurrentsChange.bind(this)}/> - </li> - )} + <TypesFilter + value={taskType} + types={types} + onChange={this.handleTypeChange.bind(this)} + /> + </li>} + {!component && <li> <h6 className="bt-search-form-label"> - Date + Only Latest Analysis </h6> - <DateFilter - minSubmittedAt={minSubmittedAt} - maxExecutedAt={maxExecutedAt} - onChange={this.handleDateChange.bind(this)}/> - </li> - - {this.renderSearchBox()} - - <li className="bt-search-form-right"> - <button - className="js-reload" - onClick={this.handleReload.bind(this)} - disabled={loading}> - {translate('reload')} - </button> - {' '} - <button - ref="resetButton" - onClick={this.handleReset.bind(this)} - disabled={loading}> - {translate('reset_verb')} - </button> - </li> - </ul> - </section> + <CurrentsFilter value={currents} onChange={this.handleCurrentsChange.bind(this)} /> + </li>} + <li> + <h6 className="bt-search-form-label"> + Date + </h6> + <DateFilter + minSubmittedAt={minSubmittedAt} + maxExecutedAt={maxExecutedAt} + onChange={this.handleDateChange.bind(this)} + /> + </li> + + {this.renderSearchBox()} + + <li className="bt-search-form-right"> + <button className="js-reload" onClick={this.handleReload.bind(this)} disabled={loading}> + {translate('reload')} + </button> + {' '} + <button ref="resetButton" onClick={this.handleReset.bind(this)} disabled={loading}> + {translate('reset_verb')} + </button> + </li> + </ul> + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Stats.js b/server/sonar-web/src/main/js/apps/background-tasks/components/Stats.js index 99a8493fbc6..8d9da1719ef 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Stats.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Stats.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; import { translate } from '../../../helpers/l10n'; @@ -35,52 +35,53 @@ export default class Stats extends React.Component { props: Props; state: State; - shouldComponentUpdate (nextProps: Props, nextState: State) { + shouldComponentUpdate(nextProps: Props, nextState: State) { return shallowCompare(this, nextProps, nextState); } - handleCancelAllPending (e: Object) { + handleCancelAllPending(e: Object) { e.preventDefault(); e.target.blur(); this.props.onCancelAllPending(); } - handleShowFailing (e: Object) { + handleShowFailing(e: Object) { e.preventDefault(); e.target.blur(); this.props.onShowFailing(); } - renderPending () { + renderPending() { if (this.props.pendingCount == null) { return null; } if (this.props.pendingCount > 0) { return ( - <span> - <span className="js-pending-count emphasised-measure">{this.props.pendingCount}</span> - - {translate('background_tasks.pending')} - <a - onClick={this.handleCancelAllPending.bind(this)} - className="js-cancel-pending icon-delete spacer-left" - title={translate('background_tasks.cancel_all_tasks')} - data-toggle="tooltip" - href="#"/> - </span> + <span> + <span className="js-pending-count emphasised-measure">{this.props.pendingCount}</span> + + {translate('background_tasks.pending')} + <a + onClick={this.handleCancelAllPending.bind(this)} + className="js-cancel-pending icon-delete spacer-left" + title={translate('background_tasks.cancel_all_tasks')} + data-toggle="tooltip" + href="#" + /> + </span> ); } else { return ( - <span> - <span className="js-pending-count emphasised-measure">{this.props.pendingCount}</span> - - {translate('background_tasks.pending')} - </span> + <span> + <span className="js-pending-count emphasised-measure">{this.props.pendingCount}</span> + + {translate('background_tasks.pending')} + </span> ); } } - renderFailures () { + renderFailures() { if (this.props.failingCount == null) { return null; } @@ -91,41 +92,47 @@ export default class Stats extends React.Component { if (this.props.failingCount > 0) { return ( - <span> - <a onClick={this.handleShowFailing.bind(this)} - className="js-failures-count emphasised-measure" - data-toggle="tooltip" - title="Count of projects where processing of most recent analysis report failed" - href="#">{this.props.failingCount}</a> - - {translate('background_tasks.failures')} - </span> + <span> + <a + onClick={this.handleShowFailing.bind(this)} + className="js-failures-count emphasised-measure" + data-toggle="tooltip" + title="Count of projects where processing of most recent analysis report failed" + href="#" + > + {this.props.failingCount} + </a> + + {translate('background_tasks.failures')} + </span> ); } else { return ( - <span> - <span className="js-failures-count emphasised-measure" data-toggle="tooltip" - title="Count of projects where processing of most recent analysis report failed"> - {this.props.failingCount} - </span> - - {translate('background_tasks.failures')} + <span> + <span + className="js-failures-count emphasised-measure" + data-toggle="tooltip" + title="Count of projects where processing of most recent analysis report failed" + > + {this.props.failingCount} </span> + + {translate('background_tasks.failures')} + </span> ); } } - render () { + render() { return ( - <section className="big-spacer-top big-spacer-bottom"> - <span> - {this.renderPending()} - </span> - <span className="huge-spacer-left"> - {this.renderFailures()} - </span> - </section> - + <section className="big-spacer-top big-spacer-bottom"> + <span> + {this.renderPending()} + </span> + <span className="huge-spacer-left"> + {this.renderFailures()} + </span> + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.js b/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.js index 6d81f1819d1..ac88dff66ae 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import Select from 'react-select'; import { STATUSES } from '../constants'; @@ -26,7 +26,10 @@ import { translate } from '../../../helpers/l10n'; const StatusFilter = ({ value, onChange }: { value: ?string, onChange: Function }) => { const options = [ { value: STATUSES.ALL, label: translate('background_task.status.ALL') }, - { value: STATUSES.ALL_EXCEPT_PENDING, label: translate('background_task.status.ALL_EXCEPT_PENDING') }, + { + value: STATUSES.ALL_EXCEPT_PENDING, + label: translate('background_task.status.ALL_EXCEPT_PENDING') + }, { value: STATUSES.PENDING, label: translate('background_task.status.PENDING') }, { value: STATUSES.IN_PROGRESS, label: translate('background_task.status.IN_PROGRESS') }, { value: STATUSES.SUCCESS, label: translate('background_task.status.SUCCESS') }, @@ -35,13 +38,14 @@ const StatusFilter = ({ value, onChange }: { value: ?string, onChange: Function ]; return ( - <Select - value={value} - onChange={option => onChange(option.value)} - className="input-medium" - options={options} - clearable={false} - searchable={false}/> + <Select + value={value} + onChange={option => onChange(option.value)} + className="input-medium" + options={options} + clearable={false} + searchable={false} + /> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Task.js b/server/sonar-web/src/main/js/apps/background-tasks/components/Task.js index 2fdb7ed9970..3caf3566f24 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Task.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Task.js @@ -38,31 +38,32 @@ export default class Task extends React.Component { onFilterTask: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - render () { + render() { const { task, index, tasks, component, types, onCancelTask, onFilterTask } = this.props; const prevTask = index > 0 ? tasks[index - 1] : null; return ( - <tr> - <TaskStatus task={task}/> - <TaskComponent task={task} types={types}/> - <TaskId task={task}/> - <TaskDay task={task} prevTask={prevTask}/> - <TaskDate date={task.submittedAt} baseDate={task.submittedAt} format="LTS"/> - <TaskDate date={task.startedAt} baseDate={task.submittedAt} format="LTS"/> - <TaskDate date={task.executedAt} baseDate={task.submittedAt} format="LTS"/> - <TaskExecutionTime task={task}/> - <TaskActions - component={component} - task={task} - onFilterTask={onFilterTask} - onCancelTask={onCancelTask}/> - </tr> + <tr> + <TaskStatus task={task} /> + <TaskComponent task={task} types={types} /> + <TaskId task={task} /> + <TaskDay task={task} prevTask={prevTask} /> + <TaskDate date={task.submittedAt} baseDate={task.submittedAt} format="LTS" /> + <TaskDate date={task.startedAt} baseDate={task.submittedAt} format="LTS" /> + <TaskDate date={task.executedAt} baseDate={task.submittedAt} format="LTS" /> + <TaskExecutionTime task={task} /> + <TaskActions + component={component} + task={task} + onFilterTask={onFilterTask} + onCancelTask={onCancelTask} + /> + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js index 877399d13c2..96daac4cb13 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskActions.js @@ -25,31 +25,31 @@ import { STATUSES } from './../constants'; import { translate, translateWithParameters } from '../../../helpers/l10n'; export default class TaskActions extends React.Component { - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleFilterClick (e) { + handleFilterClick(e) { e.preventDefault(); this.props.onFilterTask(this.props.task); } - handleCancelClick (e) { + handleCancelClick(e) { e.preventDefault(); this.props.onCancelTask(this.props.task); } - handleShowScannerContextClick (e) { + handleShowScannerContextClick(e) { e.preventDefault(); new ScannerContextView({ task: this.props.task }).render(); } - handleShowStacktraceClick (e) { + handleShowStacktraceClick(e) { e.preventDefault(); new StacktraceView({ task: this.props.task }).render(); } - render () { + render() { const { component, task } = this.props; const canFilter = component == null; @@ -62,51 +62,54 @@ export default class TaskActions extends React.Component { } return ( - <td className="thin nowrap"> - <div className="dropdown js-task-action"> - <button className="dropdown-toggle" data-toggle="dropdown"> - <i className="icon-dropdown"/> - </button> - <ul className="dropdown-menu dropdown-menu-right"> - {canFilter && ( - <li> - <a className="js-task-filter" href="#" onClick={this.handleFilterClick.bind(this)}> - <i className="spacer-right icon-filter icon-gray"/> - {translateWithParameters('background_tasks.filter_by_component_x', task.componentName)} - </a> - </li> - )} - {canCancel && ( - <li> - <a className="js-task-cancel" href="#" onClick={this.handleCancelClick.bind(this)}> - <i className="spacer-right icon-delete"/> - {translate('background_tasks.cancel_task')} - </a> - </li> - )} - {task.hasScannerContext && ( - <li> - <a className="js-task-show-scanner-context" - href="#" - onClick={this.handleShowScannerContextClick.bind(this)}> - <i className="spacer-right icon-list icon-gray"/> - {translate('background_tasks.show_scanner_context')} - </a> - </li> - )} - {canShowStacktrace && ( - <li> - <a className="js-task-show-stacktrace" - href="#" - onClick={this.handleShowStacktraceClick.bind(this)}> - <i className="spacer-right icon-list icon-red"/> - {translate('background_tasks.show_stacktrace')} - </a> - </li> - )} - </ul> - </div> - </td> + <td className="thin nowrap"> + <div className="dropdown js-task-action"> + <button className="dropdown-toggle" data-toggle="dropdown"> + <i className="icon-dropdown" /> + </button> + <ul className="dropdown-menu dropdown-menu-right"> + {canFilter && + <li> + <a className="js-task-filter" href="#" onClick={this.handleFilterClick.bind(this)}> + <i className="spacer-right icon-filter icon-gray" /> + {translateWithParameters( + 'background_tasks.filter_by_component_x', + task.componentName + )} + </a> + </li>} + {canCancel && + <li> + <a className="js-task-cancel" href="#" onClick={this.handleCancelClick.bind(this)}> + <i className="spacer-right icon-delete" /> + {translate('background_tasks.cancel_task')} + </a> + </li>} + {task.hasScannerContext && + <li> + <a + className="js-task-show-scanner-context" + href="#" + onClick={this.handleShowScannerContextClick.bind(this)} + > + <i className="spacer-right icon-list icon-gray" /> + {translate('background_tasks.show_scanner_context')} + </a> + </li>} + {canShowStacktrace && + <li> + <a + className="js-task-show-stacktrace" + href="#" + onClick={this.handleShowStacktraceClick.bind(this)} + > + <i className="spacer-right icon-list icon-red" /> + {translate('background_tasks.show_stacktrace')} + </a> + </li>} + </ul> + </div> + </td> ); } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.js index c572f6bd921..6c7d13c15b7 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskComponent.js @@ -31,38 +31,32 @@ export default class TaskComponent extends React.Component { types: Array<string> }; - render () { + render() { const { task, types } = this.props; if (!task.componentKey) { return ( - <td> - <span className="note">{task.id}</span> - {types.length > 1 && ( - <TaskType task={task}/> - )} - </td> + <td> + <span className="note">{task.id}</span> + {types.length > 1 && <TaskType task={task} />} + </td> ); } return ( - <td> - <span className="little-spacer-right"> - <QualifierIcon qualifier={task.componentQualifier}/> - </span> + <td> + <span className="little-spacer-right"> + <QualifierIcon qualifier={task.componentQualifier} /> + </span> - {task.organization != null && ( - <Organization organizationKey={task.organization}/> - )} + {task.organization != null && <Organization organizationKey={task.organization} />} - <Link to={{ pathname: '/dashboard', query: { id: task.componentKey } }}> - {task.componentName} - </Link> + <Link to={{ pathname: '/dashboard', query: { id: task.componentKey } }}> + {task.componentName} + </Link> - {types.length > 1 && ( - <TaskType task={task}/> - )} - </td> + {types.length > 1 && <TaskType task={task} />} + </td> ); } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDate.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDate.js index 4978cd4b7c0..856e93da7c6 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDate.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDate.js @@ -17,23 +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 */ +/* @flow */ import moment from 'moment'; import React from 'react'; -const TaskDate = ({ date, baseDate, format }: { date: string, baseDate: string, format: string }) => { +const TaskDate = ( + { date, baseDate, format }: { date: string, baseDate: string, format: string } +) => { const m = moment(date); const baseM = moment(baseDate); - const diff = (date && baseDate) ? m.diff(baseM, 'days') : 0; + const diff = date && baseDate ? m.diff(baseM, 'days') : 0; return ( - <td className="thin nowrap text-right"> - {diff > 0 && ( - <span className="text-warning little-spacer-right">{`(+${diff}d)`}</span> - )} + <td className="thin nowrap text-right"> + {diff > 0 && <span className="text-warning little-spacer-right">{`(+${diff}d)`}</span>} - {date ? moment(date).format(format) : ''} - </td> + {date ? moment(date).format(format) : ''} + </td> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDay.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDay.js index 4eadbdd9a09..bfb5ff53cd9 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDay.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskDay.js @@ -17,12 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import moment from 'moment'; import React from 'react'; import { Task } from '../types'; -function isAnotherDay (a, b) { +function isAnotherDay(a, b) { return !moment(a).isSame(moment(b), 'day'); } @@ -30,9 +30,9 @@ const TaskDay = ({ task, prevTask }: { task: Task, prevTask: ?Task }) => { const shouldDisplay = !prevTask || isAnotherDay(task.submittedAt, prevTask.submittedAt); return ( - <td className="thin nowrap text-right"> - {shouldDisplay ? moment(task.submittedAt).format('LL') : ''} - </td> + <td className="thin nowrap text-right"> + {shouldDisplay ? moment(task.submittedAt).format('LL') : ''} + </td> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskExecutionTime.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskExecutionTime.js index 3e0fefeb870..594be8d2208 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskExecutionTime.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskExecutionTime.js @@ -17,16 +17,16 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import { formatDuration } from '../utils'; import { Task } from '../types'; const TaskExecutionTime = ({ task }: { task: Task }) => { return ( - <td className="thin nowrap text-right"> - {formatDuration(task.executionTimeMs)} - </td> + <td className="thin nowrap text-right"> + {formatDuration(task.executionTimeMs)} + </td> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskId.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskId.js index a96faa321f0..b4e705d4f54 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskId.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskId.js @@ -21,11 +21,11 @@ import React from 'react'; const TaskId = ({ task }) => { return ( - <td className="thin nowrap"> - <div className="note"> - {task.id} - </div> - </td> + <td className="thin nowrap"> + <div className="note"> + {task.id} + </div> + </td> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js index 835406e278f..471b7de04de 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskStatus.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import { STATUSES } from './../constants'; import PendingIcon from '../../../components/shared/pending-icon'; @@ -29,19 +29,25 @@ const TaskStatus = ({ task }: { task: Task }) => { switch (task.status) { case STATUSES.PENDING: - inner = <PendingIcon/>; + inner = <PendingIcon />; break; case STATUSES.IN_PROGRESS: - inner = <i className="spinner"/>; + inner = <i className="spinner" />; break; case STATUSES.SUCCESS: - inner = <span className="badge badge-success">{translate('background_task.status.SUCCESS')}</span>; + inner = ( + <span className="badge badge-success">{translate('background_task.status.SUCCESS')}</span> + ); break; case STATUSES.FAILED: - inner = <span className="badge badge-danger">{translate('background_task.status.FAILED')}</span>; + inner = ( + <span className="badge badge-danger">{translate('background_task.status.FAILED')}</span> + ); break; case STATUSES.CANCELED: - inner = <span className="badge badge-muted">{translate('background_task.status.CANCELED')}</span>; + inner = ( + <span className="badge badge-muted">{translate('background_task.status.CANCELED')}</span> + ); break; default: inner = ''; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskType.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskType.js index 9d16c52fc12..11957d7dcf2 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TaskType.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TaskType.js @@ -17,18 +17,18 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import { Task } from '../types'; import { translate } from '../../../helpers/l10n'; const TaskType = ({ task }: { task: Task }) => { return ( - <span className="note nowrap spacer-left"> - {'['} - {translate('background_task.type', task.type)} - {']'} - </span> + <span className="note nowrap spacer-left"> + {'['} + {translate('background_task.type', task.type)} + {']'} + </span> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Tasks.js b/server/sonar-web/src/main/js/apps/background-tasks/components/Tasks.js index 4fe24aed9c6..1fa5cf0aee4 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/Tasks.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Tasks.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import shallowCompare from 'react-addons-shallow-compare'; import classNames from 'classnames'; @@ -39,11 +39,11 @@ export default class Tasks extends React.Component { props: Props; state: State; - shouldComponentUpdate (nextProps: Props, nextState: State) { + shouldComponentUpdate(nextProps: Props, nextState: State) { return shallowCompare(this, nextProps, nextState); } - render () { + render() { const { tasks, component, types, loading, onCancelTask, onFilterTask } = this.props; const className = classNames('data zebra zebra-hover background-tasks', { @@ -51,8 +51,8 @@ export default class Tasks extends React.Component { }); return ( - <table className={className}> - <thead> + <table className={className}> + <thead> <tr> <th>{translate('background_tasks.table.status')}</th> <th>{translate('background_tasks.table.task')}</th> @@ -64,21 +64,22 @@ export default class Tasks extends React.Component { <th className="text-right">{translate('background_tasks.table.duration')}</th> <th> </th> </tr> - </thead> - <tbody> + </thead> + <tbody> {tasks.map((task, index, tasks) => ( - <Task - key={task.id} - task={task} - index={index} - tasks={tasks} - component={component} - types={types} - onCancelTask={onCancelTask} - onFilterTask={onFilterTask}/> + <Task + key={task.id} + task={task} + index={index} + tasks={tasks} + component={component} + types={types} + onCancelTask={onCancelTask} + onFilterTask={onFilterTask} + /> ))} - </tbody> - </table> + </tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.js b/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.js index ae1923ec497..2a0268be408 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.js @@ -17,13 +17,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import React from 'react'; import Select from 'react-select'; import { ALL_TYPES } from '../constants'; import { translate } from '../../../helpers/l10n'; -const TypesFilter = ({ value, onChange, types }: { value: string, onChange: Function, types: string[] }) => { +const TypesFilter = ( + { value, onChange, types }: { value: string, onChange: Function, types: string[] } +) => { const options = types.map(t => { return { value: t, @@ -37,13 +39,14 @@ const TypesFilter = ({ value, onChange, types }: { value: string, onChange: Func ]; return ( - <Select - value={value} - onChange={option => onChange(option.value)} - className="input-medium" - options={allOptions} - clearable={false} - searchable={false}/> + <Select + value={value} + onChange={option => onChange(option.value)} + className="input-medium" + options={allOptions} + clearable={false} + searchable={false} + /> ); }; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/constants.js b/server/sonar-web/src/main/js/apps/background-tasks/constants.js index 71233754bcc..83fd4a4fb07 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/constants.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/constants.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ export const STATUSES = { ALL: '__ALL__', ALL_EXCEPT_PENDING: '__ALL_EXCEPT_PENDING__', diff --git a/server/sonar-web/src/main/js/apps/background-tasks/routes.js b/server/sonar-web/src/main/js/apps/background-tasks/routes.js index d3a01f5e1d8..895734d05ef 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/routes.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import BackgroundTasksApp from './components/BackgroundTasksApp'; -export default ( - <IndexRoute component={BackgroundTasksApp}/> -); +export default <IndexRoute component={BackgroundTasksApp} />; diff --git a/server/sonar-web/src/main/js/apps/background-tasks/utils.js b/server/sonar-web/src/main/js/apps/background-tasks/utils.js index d3ca6caee42..adb942dacd9 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/utils.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/utils.js @@ -17,15 +17,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - /* @flow */ +/* @flow */ import { STATUSES, ALL_TYPES, CURRENTS } from './constants'; import { Task } from './types'; -export function updateTask (tasks: Task[], newTask: Task) { +export function updateTask(tasks: Task[], newTask: Task) { return tasks.map(task => task.id === newTask.id ? newTask : task); } -export function mapFiltersToParameters (filters: Object = {}) { +export function mapFiltersToParameters(filters: Object = {}) { const parameters = {}; if (filters.status === STATUSES.ALL) { @@ -77,11 +77,11 @@ export function mapFiltersToParameters (filters: Object = {}) { const ONE_SECOND = 1000; const ONE_MINUTE = 60 * ONE_SECOND; -function format (int, suffix) { +function format(int, suffix) { return `${int}${suffix}`; } -export function formatDuration (value: ?number) { +export function formatDuration(value: ?number) { if (!value) { return ''; } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/views/ScannerContextView.js b/server/sonar-web/src/main/js/apps/background-tasks/views/ScannerContextView.js index ad74e17f4b7..ef35cf57125 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/views/ScannerContextView.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/views/ScannerContextView.js @@ -25,23 +25,22 @@ export default Modal.extend({ template: Template, className: 'modal modal-large', - initialize () { + initialize() { this.scannerContext = null; this.loadScannerContext(); }, - loadScannerContext () { + loadScannerContext() { getTask(this.options.task.id, ['scannerContext']).then(task => { this.scannerContext = task.scannerContext; this.render(); }); }, - serializeData () { + serializeData() { return { task: this.options.task, scannerContext: this.scannerContext }; } }); - diff --git a/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js index 495fe78191a..866d9a487eb 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/views/StacktraceView.js @@ -25,13 +25,13 @@ export default Modal.extend({ template: Template, className: 'modal modal-large', - initialize () { + initialize() { this.loaded = false; this.stacktrace = null; this.loadStacktrace(); }, - loadStacktrace () { + loadStacktrace() { getTask(this.options.task.id, ['stacktrace']).then(task => { this.loaded = true; this.stacktrace = task.errorStacktrace; @@ -39,7 +39,7 @@ export default Modal.extend({ }); }, - serializeData () { + serializeData() { return { task: this.options.task, stacktrace: this.stacktrace, @@ -47,4 +47,3 @@ export default Modal.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/code/bucket.js b/server/sonar-web/src/main/js/apps/code/bucket.js index 6b1a972b4ce..7b235e0f14b 100644 --- a/server/sonar-web/src/main/js/apps/code/bucket.js +++ b/server/sonar-web/src/main/js/apps/code/bucket.js @@ -21,31 +21,31 @@ let bucket = {}; let childrenBucket = {}; let breadcrumbsBucket = {}; -export function addComponent (component) { +export function addComponent(component) { bucket[component.key] = component; } -export function getComponent (componentKey) { +export function getComponent(componentKey) { return bucket[componentKey]; } -export function addComponentChildren (componentKey, children, total, page) { +export function addComponentChildren(componentKey, children, total, page) { childrenBucket[componentKey] = { children, total, page }; } -export function getComponentChildren (componentKey) { +export function getComponentChildren(componentKey) { return childrenBucket[componentKey]; } -export function addComponentBreadcrumbs (componentKey, breadcrumbs) { +export function addComponentBreadcrumbs(componentKey, breadcrumbs) { breadcrumbsBucket[componentKey] = breadcrumbs; } -export function getComponentBreadcrumbs (componentKey) { +export function getComponentBreadcrumbs(componentKey) { return breadcrumbsBucket[componentKey]; } -export function clearBucket () { +export function clearBucket() { bucket = {}; childrenBucket = {}; breadcrumbsBucket = {}; diff --git a/server/sonar-web/src/main/js/apps/code/components/App.js b/server/sonar-web/src/main/js/apps/code/components/App.js index 8e75483c1da..a8a8fd02a51 100644 --- a/server/sonar-web/src/main/js/apps/code/components/App.js +++ b/server/sonar-web/src/main/js/apps/code/components/App.js @@ -25,7 +25,12 @@ import Breadcrumbs from './Breadcrumbs'; import SourceViewer from './../../../components/SourceViewer/SourceViewer'; import Search from './Search'; import ListFooter from '../../../components/controls/ListFooter'; -import { retrieveComponentChildren, retrieveComponent, loadMoreChildren, parseError } from '../utils'; +import { + retrieveComponentChildren, + retrieveComponent, + loadMoreChildren, + parseError +} from '../utils'; import { addComponent, addComponentBreadcrumbs, clearBucket } from '../bucket'; import { getComponent } from '../../../store/rootReducer'; import '../code.css'; @@ -42,12 +47,12 @@ class App extends React.Component { error: null }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.handleComponentChange(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.component !== this.props.component) { this.handleComponentChange(); } else if (prevProps.location !== this.props.location) { @@ -55,12 +60,12 @@ class App extends React.Component { } } - componentWillUnmount () { + componentWillUnmount() { clearBucket(); this.mounted = false; } - handleComponentChange () { + handleComponentChange() { const { component } = this.props; // we already know component's breadcrumbs, @@ -68,52 +73,57 @@ class App extends React.Component { this.setState({ loading: true }); const isView = component.qualifier === 'VW' || component.qualifier === 'SVW'; - retrieveComponentChildren(component.key, isView).then(r => { - addComponent(r.baseComponent); - this.handleUpdate(); - }).catch(e => { - if (this.mounted) { - this.setState({ loading: false }); - parseError(e).then(this.handleError.bind(this)); - } - }); + retrieveComponentChildren(component.key, isView) + .then(r => { + addComponent(r.baseComponent); + this.handleUpdate(); + }) + .catch(e => { + if (this.mounted) { + this.setState({ loading: false }); + parseError(e).then(this.handleError.bind(this)); + } + }); } - loadComponent (componentKey) { + loadComponent(componentKey) { this.setState({ loading: true }); - const isView = this.props.component.qualifier === 'VW' || this.props.component.qualifier === 'SVW'; - retrieveComponent(componentKey, isView).then(r => { - if (this.mounted) { - if (['FIL', 'UTS'].includes(r.component.qualifier)) { - this.setState({ - loading: false, - sourceViewer: r.component, - breadcrumbs: r.breadcrumbs, - searchResults: null - }); - } else { - this.setState({ - loading: false, - baseComponent: r.component, - components: r.components, - breadcrumbs: r.breadcrumbs, - total: r.total, - page: r.page, - sourceViewer: null, - searchResults: null - }); + const isView = this.props.component.qualifier === 'VW' || + this.props.component.qualifier === 'SVW'; + retrieveComponent(componentKey, isView) + .then(r => { + if (this.mounted) { + if (['FIL', 'UTS'].includes(r.component.qualifier)) { + this.setState({ + loading: false, + sourceViewer: r.component, + breadcrumbs: r.breadcrumbs, + searchResults: null + }); + } else { + this.setState({ + loading: false, + baseComponent: r.component, + components: r.components, + breadcrumbs: r.breadcrumbs, + total: r.total, + page: r.page, + sourceViewer: null, + searchResults: null + }); + } } - } - }).catch(e => { - if (this.mounted) { - this.setState({ loading: false }); - parseError(e).then(this.handleError.bind(this)); - } - }); + }) + .catch(e => { + if (this.mounted) { + this.setState({ loading: false }); + parseError(e).then(this.handleError.bind(this)); + } + }); } - handleUpdate () { + handleUpdate() { const { component, location } = this.props; const { selected } = location.query; const finalKey = selected || component.key; @@ -121,41 +131,44 @@ class App extends React.Component { this.loadComponent(finalKey); } - handleLoadMore () { + handleLoadMore() { const { baseComponent, page } = this.state; - const isView = this.props.component.qualifier === 'VW' || this.props.component.qualifier === 'SVW'; - loadMoreChildren(baseComponent.key, page + 1, isView).then(r => { - if (this.mounted) { - this.setState({ - components: [...this.state.components, ...r.components], - page: r.page, - total: r.total - }); - } - }).catch(e => { - if (this.mounted) { - this.setState({ loading: false }); - parseError(e).then(this.handleError.bind(this)); - } - }); + const isView = this.props.component.qualifier === 'VW' || + this.props.component.qualifier === 'SVW'; + loadMoreChildren(baseComponent.key, page + 1, isView) + .then(r => { + if (this.mounted) { + this.setState({ + components: [...this.state.components, ...r.components], + page: r.page, + total: r.total + }); + } + }) + .catch(e => { + if (this.mounted) { + this.setState({ loading: false }); + parseError(e).then(this.handleError.bind(this)); + } + }); } - handleError (error) { + handleError(error) { if (this.mounted) { this.setState({ error }); } } - render () { + render() { const { component, location } = this.props; const { - loading, - error, - baseComponent, - components, - breadcrumbs, - total, - sourceViewer + loading, + error, + baseComponent, + components, + breadcrumbs, + total, + sourceViewer } = this.state; const shouldShowSourceViewer = !!sourceViewer; @@ -165,49 +178,40 @@ class App extends React.Component { const componentsClassName = classNames('spacer-top', { 'new-loading': loading }); return ( - <div className="page page-limited"> - {error && ( - <div className="alert alert-danger"> - {error} - </div> - )} - - <Search - location={location} - component={component} - onError={this.handleError.bind(this)}/> - - - <div className="code-components"> - {shouldShowBreadcrumbs && ( - <Breadcrumbs - rootComponent={component} - breadcrumbs={breadcrumbs}/> - )} - - {shouldShowComponents && ( - <div className={componentsClassName}> - <Components - rootComponent={component} - baseComponent={baseComponent} - components={components}/> - </div> - )} - - {shouldShowComponents && ( - <ListFooter - count={components.length} - total={total} - loadMore={this.handleLoadMore.bind(this)}/> - )} - - {shouldShowSourceViewer && ( - <div className="spacer-top"> - <SourceViewer component={sourceViewer.key}/> - </div> - )} - </div> + <div className="page page-limited"> + {error && + <div className="alert alert-danger"> + {error} + </div>} + + <Search location={location} component={component} onError={this.handleError.bind(this)} /> + + <div className="code-components"> + {shouldShowBreadcrumbs && + <Breadcrumbs rootComponent={component} breadcrumbs={breadcrumbs} />} + + {shouldShowComponents && + <div className={componentsClassName}> + <Components + rootComponent={component} + baseComponent={baseComponent} + components={components} + /> + </div>} + + {shouldShowComponents && + <ListFooter + count={components.length} + total={total} + loadMore={this.handleLoadMore.bind(this)} + />} + + {shouldShowSourceViewer && + <div className="spacer-top"> + <SourceViewer component={sourceViewer.key} /> + </div>} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/code/components/Breadcrumb.js b/server/sonar-web/src/main/js/apps/code/components/Breadcrumb.js index c2c49928649..99dc00ab670 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Breadcrumb.js +++ b/server/sonar-web/src/main/js/apps/code/components/Breadcrumb.js @@ -21,10 +21,7 @@ import React from 'react'; import ComponentName from './ComponentName'; const Breadcrumb = ({ rootComponent, component, canBrowse }) => ( - <ComponentName - rootComponent={rootComponent} - component={component} - canBrowse={canBrowse}/> + <ComponentName rootComponent={rootComponent} component={component} canBrowse={canBrowse} /> ); export default Breadcrumb; diff --git a/server/sonar-web/src/main/js/apps/code/components/Breadcrumbs.js b/server/sonar-web/src/main/js/apps/code/components/Breadcrumbs.js index d42d47f6a57..fe9116f7cfc 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Breadcrumbs.js +++ b/server/sonar-web/src/main/js/apps/code/components/Breadcrumbs.js @@ -21,16 +21,17 @@ import React from 'react'; import Breadcrumb from './Breadcrumb'; const Breadcrumbs = ({ rootComponent, breadcrumbs }) => ( - <ul className="code-breadcrumbs"> - {breadcrumbs.map((component, index) => ( - <li key={component.key}> - <Breadcrumb - rootComponent={rootComponent} - component={component} - canBrowse={index < breadcrumbs.length - 1}/> - </li> - ))} - </ul> + <ul className="code-breadcrumbs"> + {breadcrumbs.map((component, index) => ( + <li key={component.key}> + <Breadcrumb + rootComponent={rootComponent} + component={component} + canBrowse={index < breadcrumbs.length - 1} + /> + </li> + ))} + </ul> ); export default Breadcrumbs; diff --git a/server/sonar-web/src/main/js/apps/code/components/Component.js b/server/sonar-web/src/main/js/apps/code/components/Component.js index d2deccf4376..9166c570e7a 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Component.js +++ b/server/sonar-web/src/main/js/apps/code/components/Component.js @@ -30,30 +30,33 @@ const TOP_OFFSET = 200; const BOTTOM_OFFSET = 10; export default class Component extends React.Component { - componentDidMount () { + componentDidMount() { this.handleUpdate(); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentDidUpdate () { + componentDidUpdate() { this.handleUpdate(); } - handleUpdate () { + handleUpdate() { const { selected } = this.props; // scroll viewport so the current selected component is visible if (selected) { - setTimeout(() => { - this.handleScroll(); - }, 0); + setTimeout( + () => { + this.handleScroll(); + }, + 0 + ); } } - handleScroll () { + handleScroll() { const node = ReactDOM.findDOMNode(this); const position = node.getBoundingClientRect(); const { top, bottom } = position; @@ -64,7 +67,7 @@ export default class Component extends React.Component { } } - render () { + render() { const { component, rootComponent, selected, previous, canBrowse } = this.props; const isView = ['VW', 'SVW'].includes(rootComponent.qualifier); @@ -74,54 +77,58 @@ export default class Component extends React.Component { switch (component.qualifier) { case 'FIL': case 'UTS': - componentAction = <ComponentPin component={component}/>; + componentAction = <ComponentPin component={component} />; break; default: - componentAction = <ComponentDetach component={component}/>; + componentAction = <ComponentDetach component={component} />; } } - const columns = isView ? [ - { metric: 'releasability_rating', type: 'RATING' }, - { metric: 'reliability_rating', type: 'RATING' }, - { metric: 'security_rating', type: 'RATING' }, - { metric: 'sqale_rating', type: 'RATING' }, - { metric: 'ncloc', type: 'SHORT_INT' } - ] : [ - { metric: 'ncloc', type: 'SHORT_INT' }, - { metric: 'bugs', type: 'SHORT_INT' }, - { metric: 'vulnerabilities', type: 'SHORT_INT' }, - { metric: 'code_smells', type: 'SHORT_INT' }, - { metric: 'coverage', type: 'PERCENT' }, - { metric: 'duplicated_lines_density', type: 'PERCENT' } - ]; + const columns = isView + ? [ + { metric: 'releasability_rating', type: 'RATING' }, + { metric: 'reliability_rating', type: 'RATING' }, + { metric: 'security_rating', type: 'RATING' }, + { metric: 'sqale_rating', type: 'RATING' }, + { metric: 'ncloc', type: 'SHORT_INT' } + ] + : [ + { metric: 'ncloc', type: 'SHORT_INT' }, + { metric: 'bugs', type: 'SHORT_INT' }, + { metric: 'vulnerabilities', type: 'SHORT_INT' }, + { metric: 'code_smells', type: 'SHORT_INT' }, + { metric: 'coverage', type: 'PERCENT' }, + { metric: 'duplicated_lines_density', type: 'PERCENT' } + ]; return ( - <tr className={classNames({ selected })}> - <td className="thin nowrap"> - <span className="spacer-right"> - {componentAction} - </span> - </td> - <td className="code-name-cell"> - <ComponentName + <tr className={classNames({ selected })}> + <td className="thin nowrap"> + <span className="spacer-right"> + {componentAction} + </span> + </td> + <td className="code-name-cell"> + <ComponentName + component={component} + rootComponent={rootComponent} + previous={previous} + canBrowse={canBrowse} + /> + </td> + + {columns.map(column => ( + <td key={column.metric} className="thin nowrap text-right"> + <div className="code-components-cell"> + <ComponentMeasure component={component} - rootComponent={rootComponent} - previous={previous} - canBrowse={canBrowse}/> + metricKey={column.metric} + metricType={column.type} + /> + </div> </td> - - {columns.map(column => ( - <td key={column.metric} className="thin nowrap text-right"> - <div className="code-components-cell"> - <ComponentMeasure - component={component} - metricKey={column.metric} - metricType={column.type}/> - </div> - </td> - ))} - </tr> + ))} + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js index da85d25d9be..69e1aafd253 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js @@ -22,9 +22,11 @@ import { Link } from 'react-router'; import { translate } from '../../../helpers/l10n'; const ComponentDetach = ({ component }) => ( - <Link to={{ pathname: '/dashboard', query: { id: component.refKey || component.key } }} - className="icon-detach" - title={translate('code.open_component_page')}/> + <Link + to={{ pathname: '/dashboard', query: { id: component.refKey || component.key } }} + className="icon-detach" + title={translate('code.open_component_page')} + /> ); export default ComponentDetach; diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js b/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js index 58928392896..bfb5a4b8e40 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentMeasure.js @@ -24,19 +24,17 @@ const ComponentMeasure = ({ component, metricKey, metricType }) => { const isProject = component.qualifier === 'TRK'; const isReleasability = metricKey === 'releasability_rating'; - const finalMetricKey = (isProject && isReleasability) ? 'alert_status' : metricKey; - const finalMetricType = (isProject && isReleasability) ? 'LEVEL' : metricType; + const finalMetricKey = isProject && isReleasability ? 'alert_status' : metricKey; + const finalMetricType = isProject && isReleasability ? 'LEVEL' : metricType; const measure = Array.isArray(component.measures) && - component.measures.find(measure => measure.metric === finalMetricKey); + component.measures.find(measure => measure.metric === finalMetricKey); if (!measure) { - return <span/>; + return <span />; } - return ( - <Measure measure={measure} metric={{ key: finalMetricKey, type: finalMetricType }}/> - ); + return <Measure measure={measure} metric={{ key: finalMetricKey, type: finalMetricType }} />; }; export default ComponentMeasure; diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentName.js b/server/sonar-web/src/main/js/apps/code/components/ComponentName.js index 74ee0565e0f..d3c7efa4578 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentName.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentName.js @@ -22,7 +22,7 @@ import { Link } from 'react-router'; import Truncated from './Truncated'; import QualifierIcon from '../../../components/shared/qualifier-icon'; -function getTooltip (component) { +function getTooltip(component) { const isFile = component.qualifier === 'FIL' || component.qualifier === 'UTS'; if (isFile && component.path) { return component.path + '\n\n' + component.key; @@ -31,7 +31,7 @@ function getTooltip (component) { } } -function mostCommitPrefix (strings) { +function mostCommitPrefix(strings) { const sortedStrings = strings.slice(0).sort(); const firstString = sortedStrings[0]; const firstStringLength = firstString.length; @@ -49,22 +49,25 @@ function mostCommitPrefix (strings) { const ComponentName = ({ component, rootComponent, previous, canBrowse }) => { const areBothDirs = component.qualifier === 'DIR' && previous && previous.qualifier === 'DIR'; const prefix = areBothDirs ? mostCommitPrefix([component.name + '/', previous.name + '/']) : ''; - const name = prefix ? ( - <span> + const name = prefix + ? <span> <span style={{ color: '#777' }}>{prefix}</span> <span>{component.name.substr(prefix.length)}</span> </span> - ) : component.name; + : component.name; let inner = null; if (component.refKey && component.qualifier !== 'SVW') { inner = ( - <Link to={{ pathname: '/dashboard', query: { id: component.refKey } }} className="link-with-icon"> - <QualifierIcon qualifier={component.qualifier}/> - {' '} - <span>{name}</span> - </Link> + <Link + to={{ pathname: '/dashboard', query: { id: component.refKey } }} + className="link-with-icon" + > + <QualifierIcon qualifier={component.qualifier} /> + {' '} + <span>{name}</span> + </Link> ); } else if (canBrowse) { const query = { id: rootComponent.key }; @@ -72,26 +75,26 @@ const ComponentName = ({ component, rootComponent, previous, canBrowse }) => { Object.assign(query, { selected: component.key }); } inner = ( - <Link to={{ pathname: '/code', query }} className="link-with-icon"> - <QualifierIcon qualifier={component.qualifier}/> - {' '} - <span>{name}</span> - </Link> + <Link to={{ pathname: '/code', query }} className="link-with-icon"> + <QualifierIcon qualifier={component.qualifier} /> + {' '} + <span>{name}</span> + </Link> ); } else { inner = ( - <span> - <QualifierIcon qualifier={component.qualifier}/> - {' '} - {name} - </span> + <span> + <QualifierIcon qualifier={component.qualifier} /> + {' '} + {name} + </span> ); } return ( - <Truncated title={getTooltip(component)}> - {inner} - </Truncated> + <Truncated title={getTooltip(component)}> + {inner} + </Truncated> ); }; diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js b/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js index 20670ac9bcb..5ab8c75959a 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js @@ -29,13 +29,14 @@ const ComponentPin = ({ component }) => { }; return ( - <a - className="link-no-underline" - onClick={handleClick} - title={translate('component_viewer.open_in_workspace')} - href="#"> - <PinIcon/> - </a> + <a + className="link-no-underline" + onClick={handleClick} + title={translate('component_viewer.open_in_workspace')} + href="#" + > + <PinIcon /> + </a> ); }; diff --git a/server/sonar-web/src/main/js/apps/code/components/Components.js b/server/sonar-web/src/main/js/apps/code/components/Components.js index c106cd180da..62d653d3543 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Components.js +++ b/server/sonar-web/src/main/js/apps/code/components/Components.js @@ -23,35 +23,34 @@ import ComponentsEmpty from './ComponentsEmpty'; import ComponentsHeader from './ComponentsHeader'; const Components = ({ rootComponent, baseComponent, components, selected }) => ( - <table className="data zebra"> - <ComponentsHeader baseComponent={baseComponent} rootComponent={rootComponent}/> - {baseComponent && ( - <tbody> - <Component - key={baseComponent.key} - rootComponent={rootComponent} - component={baseComponent}/> - <tr className="blank"> - <td colSpan="8"> </td> - </tr> - </tbody> - )} + <table className="data zebra"> + <ComponentsHeader baseComponent={baseComponent} rootComponent={rootComponent} /> + {baseComponent && <tbody> - {components.length ? ( - components.map((component, index, list) => ( - <Component - key={component.key} - rootComponent={rootComponent} - component={component} - selected={component === selected} - previous={index > 0 ? list[index - 1] : null} - canBrowse={true}/> - )) - ) : ( - <ComponentsEmpty/> - )} - </tbody> - </table> + <Component + key={baseComponent.key} + rootComponent={rootComponent} + component={baseComponent} + /> + <tr className="blank"> + <td colSpan="8"> </td> + </tr> + </tbody>} + <tbody> + {components.length + ? components.map((component, index, list) => ( + <Component + key={component.key} + rootComponent={rootComponent} + component={component} + selected={component === selected} + previous={index > 0 ? list[index - 1] : null} + canBrowse={true} + /> + )) + : <ComponentsEmpty />} + </tbody> + </table> ); export default Components; diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js b/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js index e254cd99d60..ea40873c8db 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js @@ -21,14 +21,12 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; const ComponentsEmpty = () => ( - <tr> - <td colSpan="2"> - {translate('no_results')} - </td> - <td colSpan="6"> - - </td> - </tr> + <tr> + <td colSpan="2"> + {translate('no_results')} + </td> + <td colSpan="6" /> + </tr> ); export default ComponentsEmpty; diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js b/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js index 92290dda6a6..ec63a912732 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentsHeader.js @@ -23,33 +23,35 @@ import { translate } from '../../../helpers/l10n'; const ComponentsHeader = ({ baseComponent, rootComponent }) => { const isView = rootComponent.qualifier === 'VW' || rootComponent.qualifier === 'SVW'; - const columns = isView ? [ - translate('metric_domain.Releasability'), - translate('metric_domain.Reliability'), - translate('metric_domain.Security'), - translate('metric_domain.Maintainability'), - translate('metric', 'ncloc', 'name') - ] : [ - translate('metric', 'ncloc', 'name'), - translate('metric', 'bugs', 'name'), - translate('metric', 'vulnerabilities', 'name'), - translate('metric', 'code_smells', 'name'), - translate('metric', 'coverage', 'name'), - translate('metric', 'duplicated_lines_density', 'short_name') - ]; + const columns = isView + ? [ + translate('metric_domain.Releasability'), + translate('metric_domain.Reliability'), + translate('metric_domain.Security'), + translate('metric_domain.Maintainability'), + translate('metric', 'ncloc', 'name') + ] + : [ + translate('metric', 'ncloc', 'name'), + translate('metric', 'bugs', 'name'), + translate('metric', 'vulnerabilities', 'name'), + translate('metric', 'code_smells', 'name'), + translate('metric', 'coverage', 'name'), + translate('metric', 'duplicated_lines_density', 'short_name') + ]; return ( - <thead> - <tr className="code-components-header"> - <th className="thin nowrap"> </th> - <th> </th> - {columns.map(column => ( - <th key={column} className="thin nowrap text-right code-components-cell"> - {baseComponent && column} - </th> - ))} - </tr> - </thead> + <thead> + <tr className="code-components-header"> + <th className="thin nowrap"> </th> + <th> </th> + {columns.map(column => ( + <th key={column} className="thin nowrap text-right code-components-cell"> + {baseComponent && column} + </th> + ))} + </tr> + </thead> ); }; diff --git a/server/sonar-web/src/main/js/apps/code/components/Search.js b/server/sonar-web/src/main/js/apps/code/components/Search.js index 818e28083dc..93315434b45 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Search.js +++ b/server/sonar-web/src/main/js/apps/code/components/Search.js @@ -45,16 +45,16 @@ export default class Search extends React.Component { selectedIndex: null }; - componentWillMount () { + componentWillMount() { this.handleSearch = debounce(this.handleSearch.bind(this), 250); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.refs.input.focus(); } - componentWillReceiveProps (nextProps) { + componentWillReceiveProps(nextProps) { // if the url has change, reset the current state if (nextProps.location !== this.props.location) { this.setState({ @@ -66,33 +66,33 @@ export default class Search extends React.Component { } } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - checkInputValue (query) { + checkInputValue(query) { return this.refs.input.value === query; } - handleSelectNext () { + handleSelectNext() { const { selectedIndex, results } = this.state; if (results != null && selectedIndex != null && selectedIndex < results.length - 1) { this.setState({ selectedIndex: selectedIndex + 1 }); } } - handleSelectPrevious () { + handleSelectPrevious() { const { selectedIndex, results } = this.state; if (results != null && selectedIndex != null && selectedIndex > 0) { this.setState({ selectedIndex: selectedIndex - 1 }); } } - handleSelectCurrent () { + handleSelectCurrent() { const { component } = this.props; const { results, selectedIndex } = this.state; if (results != null && selectedIndex != null) { @@ -112,7 +112,7 @@ export default class Search extends React.Component { } } - handleKeyDown (e) { + handleKeyDown(e) { switch (e.keyCode) { case 13: e.preventDefault(); @@ -130,7 +130,7 @@ export default class Search extends React.Component { } } - handleSearch (query) { + handleSearch(query) { // first time check if value has changed due to debounce if (this.mounted && this.checkInputValue(query)) { const { component, onError } = this.props; @@ -140,27 +140,27 @@ export default class Search extends React.Component { const qualifiers = isView ? 'SVW,TRK' : 'BRC,UTS,FIL'; getTree(component.key, { q: query, s: 'qualifier,name', qualifiers }) - .then(r => { - // second time check if value has change due to api request - if (this.mounted && this.checkInputValue(query)) { - this.setState({ - results: r.components, - selectedIndex: r.components.length > 0 ? 0 : null, - loading: false - }); - } - }) - .catch(e => { - // second time check if value has change due to api request - if (this.mounted && this.checkInputValue(query)) { - this.setState({ loading: false }); - parseError(e).then(onError); - } - }); + .then(r => { + // second time check if value has change due to api request + if (this.mounted && this.checkInputValue(query)) { + this.setState({ + results: r.components, + selectedIndex: r.components.length > 0 ? 0 : null, + loading: false + }); + } + }) + .catch(e => { + // second time check if value has change due to api request + if (this.mounted && this.checkInputValue(query)) { + this.setState({ loading: false }); + parseError(e).then(onError); + } + }); } } - handleQueryChange (query) { + handleQueryChange(query) { this.setState({ query }); if (query.length < 3) { this.setState({ results: null }); @@ -169,18 +169,18 @@ export default class Search extends React.Component { } } - handleInputChange (e) { + handleInputChange(e) { const query = e.target.value; this.handleQueryChange(query); } - handleSubmit (e) { + handleSubmit(e) { e.preventDefault(); const query = this.refs.input.value; this.handleQueryChange(query); } - render () { + render() { const { component } = this.props; const { query, loading, selectedIndex, results } = this.state; const selected = selectedIndex != null && results != null ? results[selectedIndex] : null; @@ -188,44 +188,39 @@ export default class Search extends React.Component { 'code-search-with-results': results != null }); const inputClassName = classNames('search-box-input', { - 'touched': query.length > 0 && query.length < 3 + touched: query.length > 0 && query.length < 3 }); return ( - <div id="code-search" className={containerClassName}> - <form className="search-box" onSubmit={this.handleSubmit.bind(this)}> - <button className="search-box-submit button-clean"> - <i className="icon-search"/> - </button> - - <input - ref="input" - onKeyDown={this.handleKeyDown.bind(this)} - onChange={this.handleInputChange.bind(this)} - value={query} - className={inputClassName} - type="search" - name="q" - placeholder={translate('search_verb')} - maxLength="100" - autoComplete="off"/> - - {loading && ( - <i className="spinner spacer-left"/> - )} - - <span className="note spacer-left"> - {translateWithParameters('select2.tooShort', 3)} - </span> - </form> - - {results != null && ( - <Components - rootComponent={component} - components={results} - selected={selected}/> - )} - </div> + <div id="code-search" className={containerClassName}> + <form className="search-box" onSubmit={this.handleSubmit.bind(this)}> + <button className="search-box-submit button-clean"> + <i className="icon-search" /> + </button> + + <input + ref="input" + onKeyDown={this.handleKeyDown.bind(this)} + onChange={this.handleInputChange.bind(this)} + value={query} + className={inputClassName} + type="search" + name="q" + placeholder={translate('search_verb')} + maxLength="100" + autoComplete="off" + /> + + {loading && <i className="spinner spacer-left" />} + + <span className="note spacer-left"> + {translateWithParameters('select2.tooShort', 3)} + </span> + </form> + + {results != null && + <Components rootComponent={component} components={results} selected={selected} />} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/code/components/Truncated.js b/server/sonar-web/src/main/js/apps/code/components/Truncated.js index ce0c488ffa8..82c6cd14fdd 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Truncated.js +++ b/server/sonar-web/src/main/js/apps/code/components/Truncated.js @@ -20,11 +20,9 @@ import React from 'react'; const Truncated = ({ children, title }) => ( - <span - className="code-truncated" - title={title}> - {children} - </span> + <span className="code-truncated" title={title}> + {children} + </span> ); export default Truncated; diff --git a/server/sonar-web/src/main/js/apps/code/routes.js b/server/sonar-web/src/main/js/apps/code/routes.js index e7f4a836853..07bb9e8a918 100644 --- a/server/sonar-web/src/main/js/apps/code/routes.js +++ b/server/sonar-web/src/main/js/apps/code/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import App from './components/App'; -export default ( - <IndexRoute component={App}/> -); +export default <IndexRoute component={App} />; diff --git a/server/sonar-web/src/main/js/apps/code/utils.js b/server/sonar-web/src/main/js/apps/code/utils.js index c6999204de8..c5451d4a89e 100644 --- a/server/sonar-web/src/main/js/apps/code/utils.js +++ b/server/sonar-web/src/main/js/apps/code/utils.js @@ -50,7 +50,7 @@ const VIEW_METRICS = [ const PAGE_SIZE = 100; -function requestChildren (componentKey, metrics, page) { +function requestChildren(componentKey, metrics, page) { return getChildren(componentKey, metrics, { p: page, ps: PAGE_SIZE }).then(r => { if (r.paging.total > r.paging.pageSize * r.paging.pageIndex) { return requestChildren(componentKey, metrics, page + 1).then(moreComponents => { @@ -61,13 +61,15 @@ function requestChildren (componentKey, metrics, page) { }); } -function requestAllChildren (componentKey, metrics) { +function requestAllChildren(componentKey, metrics) { return requestChildren(componentKey, metrics, 1); } -function expandRootDir (metrics) { - return function ({ components, total, ...other }) { - const rootDir = components.find(component => component.qualifier === 'DIR' && component.name === '/'); +function expandRootDir(metrics) { + return function({ components, total, ...other }) { + const rootDir = components.find( + component => component.qualifier === 'DIR' && component.name === '/' + ); if (rootDir) { return requestAllChildren(rootDir.key, metrics).then(rootDirComponents => { const nextComponents = without([...rootDirComponents, ...components], rootDir); @@ -80,7 +82,7 @@ function expandRootDir (metrics) { }; } -function prepareChildren (r) { +function prepareChildren(r) { return { components: r.components, total: r.paging.total, @@ -89,17 +91,17 @@ function prepareChildren (r) { }; } -function skipRootDir (breadcrumbs) { +function skipRootDir(breadcrumbs) { return breadcrumbs.filter(component => { return !(component.qualifier === 'DIR' && component.name === '/'); }); } -function storeChildrenBase (children) { +function storeChildrenBase(children) { children.forEach(addComponent); } -function storeChildrenBreadcrumbs (parentComponentKey, children) { +function storeChildrenBreadcrumbs(parentComponentKey, children) { const parentBreadcrumbs = getComponentBreadcrumbs(parentComponentKey); if (parentBreadcrumbs) { children.forEach(child => { @@ -109,7 +111,7 @@ function storeChildrenBreadcrumbs (parentComponentKey, children) { } } -function getMetrics (isView) { +function getMetrics(isView) { return isView ? VIEW_METRICS : METRICS; } @@ -118,7 +120,7 @@ function getMetrics (isView) { * @param {boolean} isView * @returns {Promise} */ -function retrieveComponentBase (componentKey, isView) { +function retrieveComponentBase(componentKey, isView) { const existing = getComponentFromBucket(componentKey); if (existing) { return Promise.resolve(existing); @@ -137,7 +139,7 @@ function retrieveComponentBase (componentKey, isView) { * @param {boolean} isView * @returns {Promise} */ -export function retrieveComponentChildren (componentKey, isView) { +export function retrieveComponentChildren(componentKey, isView) { const existing = getComponentChildren(componentKey); if (existing) { return Promise.resolve({ @@ -150,28 +152,26 @@ export function retrieveComponentChildren (componentKey, isView) { const metrics = getMetrics(isView); return getChildren(componentKey, metrics, { ps: PAGE_SIZE, s: 'qualifier,name' }) - .then(prepareChildren) - .then(expandRootDir(metrics)) - .then(r => { - addComponentChildren(componentKey, r.components, r.total, r.page); - storeChildrenBase(r.components); - storeChildrenBreadcrumbs(componentKey, r.components); - return r; - }); + .then(prepareChildren) + .then(expandRootDir(metrics)) + .then(r => { + addComponentChildren(componentKey, r.components, r.total, r.page); + storeChildrenBase(r.components); + storeChildrenBreadcrumbs(componentKey, r.components); + return r; + }); } -function retrieveComponentBreadcrumbs (componentKey) { +function retrieveComponentBreadcrumbs(componentKey) { const existing = getComponentBreadcrumbs(componentKey); if (existing) { return Promise.resolve(existing); } - return getBreadcrumbs(componentKey) - .then(skipRootDir) - .then(breadcrumbs => { - addComponentBreadcrumbs(componentKey, breadcrumbs); - return breadcrumbs; - }); + return getBreadcrumbs(componentKey).then(skipRootDir).then(breadcrumbs => { + addComponentBreadcrumbs(componentKey, breadcrumbs); + return breadcrumbs; + }); } /** @@ -179,7 +179,7 @@ function retrieveComponentBreadcrumbs (componentKey) { * @param {boolean} isView * @returns {Promise} */ -export function retrieveComponent (componentKey, isView) { +export function retrieveComponent(componentKey, isView) { return Promise.all([ retrieveComponentBase(componentKey, isView), retrieveComponentChildren(componentKey, isView), @@ -195,18 +195,18 @@ export function retrieveComponent (componentKey, isView) { }); } -export function loadMoreChildren (componentKey, page, isView) { +export function loadMoreChildren(componentKey, page, isView) { const metrics = getMetrics(isView); return getChildren(componentKey, metrics, { ps: PAGE_SIZE, p: page }) - .then(prepareChildren) - .then(expandRootDir(metrics)) - .then(r => { - addComponentChildren(componentKey, r.components, r.total, r.page); - storeChildrenBase(r.components); - storeChildrenBreadcrumbs(componentKey, r.components); - return r; - }); + .then(prepareChildren) + .then(expandRootDir(metrics)) + .then(r => { + addComponentChildren(componentKey, r.components, r.total, r.page); + storeChildrenBase(r.components); + storeChildrenBreadcrumbs(componentKey, r.components); + return r; + }); } /** @@ -214,13 +214,14 @@ export function loadMoreChildren (componentKey, page, isView) { * @param {Error} error * @returns {Promise} */ -export function parseError (error) { +export function parseError(error) { const DEFAULT_MESSAGE = translate('default_error_message'); try { - return error.response.json() - .then(r => r.errors.map(error => error.msg).join('. ')) - .catch(() => DEFAULT_MESSAGE); + return error.response + .json() + .then(r => r.errors.map(error => error.msg).join('. ')) + .catch(() => DEFAULT_MESSAGE); } catch (ex) { return Promise.resolve(DEFAULT_MESSAGE); } diff --git a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js index 3611d044d44..777364a49fa 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js @@ -25,28 +25,37 @@ import { translateWithParameters } from '../../helpers/l10n'; export default ModalFormView.extend({ template: Template, - ui () { + ui() { return { ...ModalFormView.prototype.ui.apply(this, arguments), codingRulesSubmitBulkChange: '#coding-rules-submit-bulk-change' }; }, - showSuccessMessage (profile, succeeded) { + showSuccessMessage(profile, succeeded) { const profileBase = this.options.app.qualityProfiles.find(p => p.key === profile); - const message = translateWithParameters('coding_rules.bulk_change.success', - profileBase.name, profileBase.language, succeeded); + const message = translateWithParameters( + 'coding_rules.bulk_change.success', + profileBase.name, + profileBase.language, + succeeded + ); this.ui.messagesContainer.append(`<div class="alert alert-success">${message}</div>`); }, - showWarnMessage (profile, succeeded, failed) { + showWarnMessage(profile, succeeded, failed) { const profileBase = this.options.app.qualityProfiles.find(p => p.key === profile); - const message = translateWithParameters('coding_rules.bulk_change.warning', - profileBase.name, profileBase.language, succeeded, failed); + const message = translateWithParameters( + 'coding_rules.bulk_change.warning', + profileBase.name, + profileBase.language, + succeeded, + failed + ); this.ui.messagesContainer.append(`<div class="alert alert-warning">${message}</div>`); }, - onRender () { + onRender() { ModalFormView.prototype.onRender.apply(this, arguments); this.$('#coding-rules-bulk-change-profile').select2({ width: '250px', @@ -55,7 +64,7 @@ export default ModalFormView.extend({ }); }, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); const url = `${window.baseUrl}/api/qualityprofiles/${this.options.action}_rules`; const options = { ...this.options.app.state.get('query'), wsAction: this.options.action }; @@ -64,7 +73,7 @@ export default ModalFormView.extend({ this.sendRequests(url, options, profiles); }, - sendRequests (url, options, profiles) { + sendRequests(url, options, profiles) { const that = this; let looper = $.Deferred().resolve(); this.disableForm(); @@ -93,7 +102,7 @@ export default ModalFormView.extend({ }); }, - getAvailableQualityProfiles () { + getAvailableQualityProfiles() { const queryLanguages = this.options.app.state.get('query').languages; const languages = queryLanguages && queryLanguages.length > 0 ? queryLanguages.split(',') : []; let profiles = this.options.app.qualityProfiles; @@ -103,7 +112,7 @@ export default ModalFormView.extend({ return profiles; }, - serializeData () { + serializeData() { const profile = this.options.app.qualityProfiles.find(p => p.key === this.options.param); return { ...ModalFormView.prototype.serializeData.apply(this, arguments), diff --git a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js index c39db0fdce2..b38546304fa 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-popup-view.js @@ -29,7 +29,7 @@ export default PopupView.extend({ 'click .js-bulk-change': 'doAction' }, - doAction (e) { + doAction(e) { const action = $(e.currentTarget).data('action'); const param = $(e.currentTarget).data('param'); new BulkChangeModalView({ @@ -39,7 +39,7 @@ export default PopupView.extend({ }).render(); }, - serializeData () { + serializeData() { const query = this.options.app.state.get('query'); const profileKey = query.qprofile; const profile = this.options.app.qualityProfiles.find(p => p.key === profileKey); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js b/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js index 62c4459d1a4..91b561597b9 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/CodingRulesAppContainer.js @@ -21,23 +21,23 @@ import React from 'react'; import init from '../init'; export default class CodingRulesAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { this.stop = init(this.refs.container); } - componentWillUnmount () { + componentWillUnmount() { this.stop(); } - render () { + render() { // placing container inside div is required, // because when backbone.marionette's layout is destroyed, // it also destroys the root element, // but react wants it to be there to unmount it return ( - <div> - <div ref="container"/> - </div> + <div> + <div ref="container" /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js b/server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js index 698377be307..54404543657 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/confirm-dialog.js @@ -24,22 +24,30 @@ const DEFAULTS = { html: '', yesLabel: 'Yes', noLabel: 'Cancel', - yesHandler () { + yesHandler() { // no op }, - noHandler () { + noHandler() { // no op }, - always () { + always() { // no op } }; -export default function (options) { +export default function(options) { const settings = { ...DEFAULTS, ...options }; - const dialog = $('<div><div class="modal-head"><h2>' + settings.title + '</h2></div><div class="modal-body">' + - settings.html + '</div><div class="modal-foot"><button data-confirm="yes">' + settings.yesLabel + - '</button> <a data-confirm="no" class="action">' + settings.noLabel + '</a></div></div>'); + const dialog = $( + '<div><div class="modal-head"><h2>' + + settings.title + + '</h2></div><div class="modal-body">' + + settings.html + + '</div><div class="modal-foot"><button data-confirm="yes">' + + settings.yesLabel + + '</button> <a data-confirm="no" class="action">' + + settings.noLabel + + '</a></div></div>' + ); $('[data-confirm=yes]', dialog).on('click', () => { dialog.dialog('close'); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/controller.js b/server/sonar-web/src/main/js/apps/coding-rules/controller.js index 7b819c3e07b..01943b685bf 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/controller.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/controller.js @@ -24,11 +24,9 @@ import RuleDetailsView from './rule-details-view'; export default Controller.extend({ pageSize: 200, - ruleFields: [ - 'name', 'lang', 'langName', 'sysTags', 'tags', 'status', 'severity' - ], + ruleFields: ['name', 'lang', 'langName', 'sysTags', 'tags', 'status', 'severity'], - _searchParameters () { + _searchParameters() { const fields = this.ruleFields.slice(); const profile = this.app.state.get('query').qprofile; if (profile != null) { @@ -49,7 +47,7 @@ export default Controller.extend({ return params; }, - fetchList (firstPage) { + fetchList(firstPage) { firstPage = firstPage == null ? true : firstPage; if (firstPage) { this.app.state.set({ selectedIndex: 0, page: 1 }, { silent: true }); @@ -84,12 +82,12 @@ export default Controller.extend({ }); }, - isRulePermalink () { + isRulePermalink() { const query = this.app.state.get('query'); return query.rule_key != null && this.app.list.length === 1; }, - requestFacet (id) { + requestFacet(id) { const url = window.baseUrl + '/api/rules/search'; const facet = this.app.facets.get(id); const options = { facets: id, ps: 1, ...this.app.state.get('query') }; @@ -101,14 +99,14 @@ export default Controller.extend({ }); }, - parseQuery () { + parseQuery() { const q = Controller.prototype.parseQuery.apply(this, arguments); delete q.asc; delete q.s; return q; }, - getRuleDetails (rule) { + getRuleDetails(rule) { const that = this; const url = window.baseUrl + '/api/rules/show'; const options = { @@ -121,7 +119,7 @@ export default Controller.extend({ }); }, - showDetails (rule) { + showDetails(rule) { const that = this; const ruleModel = typeof rule === 'string' ? new Rule({ key: rule }) : rule; this.app.layout.workspaceDetailsRegion.reset(); @@ -139,12 +137,12 @@ export default Controller.extend({ }); }, - showDetailsForSelected () { + showDetailsForSelected() { const rule = this.app.list.at(this.app.state.get('selectedIndex')); this.showDetails(rule); }, - hideDetails (firstPage) { + hideDetails(firstPage) { key.setScope('list'); this.app.state.unset('rule'); this.app.layout.workspaceDetailsRegion.reset(); @@ -155,7 +153,7 @@ export default Controller.extend({ } }, - activateCurrent () { + activateCurrent() { if (this.app.layout.detailsShow()) { this.app.workspaceDetailsView.$('#coding-rules-quality-profile-activate').click(); } else { @@ -165,12 +163,11 @@ export default Controller.extend({ } }, - deactivateCurrent () { + deactivateCurrent() { if (!this.app.layout.detailsShow()) { const rule = this.app.list.at(this.app.state.get('selectedIndex')); const ruleView = this.app.workspaceListView.children.findByModel(rule); ruleView.$('.coding-rules-detail-quality-profile-deactivate').click(); } } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js b/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js index 1bd752777ec..6343b01109f 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets-view.js @@ -50,10 +50,8 @@ const viewsMapping = { }; export default FacetsView.extend({ - - getChildView (model) { + getChildView(model) { const view = viewsMapping[model.get('property')]; return view ? view : BaseFacet; } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js index fcb312861bd..0bda9b9fada 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js @@ -26,11 +26,11 @@ export default BaseFacet.extend({ template: Template, severities: ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR'], - initialize (options) { + initialize(options) { this.listenTo(options.app.state, 'change:query', this.onQueryChange); }, - onQueryChange () { + onQueryChange() { const query = this.options.app.state.get('query'); const isProfileSelected = query.qprofile != null; const isActiveShown = '' + query.activation === 'true'; @@ -39,22 +39,22 @@ export default BaseFacet.extend({ } }, - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); this.onQueryChange(); }, - forbid () { + forbid() { BaseFacet.prototype.forbid.apply(this, arguments); this.$el.prop('title', translate('coding_rules.filters.active_severity.inactive')); }, - allow () { + allow() { BaseFacet.prototype.allow.apply(this, arguments); this.$el.prop('title', null); }, - sortValues (values) { + sortValues(values) { const order = this.severities; return sortBy(values, v => order.indexOf(v.val)); } diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js index f280adf2a07..a736dde41c2 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/available-since-facet.js @@ -23,14 +23,14 @@ import Template from '../templates/facets/coding-rules-available-since-facet.hbs export default BaseFacet.extend({ template: Template, - events () { + events() { return { ...BaseFacet.prototype.events.apply(this, arguments), 'change input': 'applyFacet' }; }, - onRender () { + onRender() { this.$el.toggleClass('search-navigator-facet-box-collapsed', !this.model.get('enabled')); this.$el.attr('data-property', this.model.get('property')); this.$('input').datepicker({ @@ -44,15 +44,14 @@ export default BaseFacet.extend({ } }, - applyFacet () { + applyFacet() { const obj = {}; const property = this.model.get('property'); obj[property] = this.$('input').val(); this.options.app.state.updateFilter(obj); }, - getLabelsSource () { + getLabelsSource() { return this.options.app.languages; } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-labels-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-labels-facet.js index 9b35342bab9..de33bc62f79 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-labels-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-labels-facet.js @@ -20,12 +20,11 @@ import BaseFacet from './base-facet'; export default BaseFacet.extend({ - - getLabelsSource () { + getLabelsSource() { return []; }, - getValues () { + getValues() { const that = this; const labels = that.getLabelsSource(); return this.model.getValues().map(item => { @@ -33,7 +32,7 @@ export default BaseFacet.extend({ }); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), values: this.getValues() diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js index e69778c3630..27acd7145e3 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js @@ -24,34 +24,34 @@ import { translate, translateWithParameters } from '../../../helpers/l10n'; export default BaseFacet.extend({ template: Template, - events () { + events() { return { ...BaseFacet.prototype.events.apply(this, arguments), 'change .js-custom-value': 'addCustomValue' }; }, - getUrl () { + getUrl() { return window.baseUrl; }, - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); this.prepareSearch(); }, - prepareSearch () { + prepareSearch() { this.$('.js-custom-value').select2({ placeholder: translate('search_verb'), minimumInputLength: 1, allowClear: false, - formatNoMatches () { + formatNoMatches() { return translate('select2.noMatches'); }, - formatSearching () { + formatSearching() { return translate('select2.searching'); }, - formatInputTooShort () { + formatInputTooShort() { return translateWithParameters('select2.tooShort', 1); }, width: '100%', @@ -59,20 +59,20 @@ export default BaseFacet.extend({ }); }, - prepareAjaxSearch () { + prepareAjaxSearch() { return { quietMillis: 300, url: this.getUrl(), - data (term, page) { + data(term, page) { return { s: term, p: page }; }, - results (data) { + results(data) { return { more: data.more, results: data.results }; } }; }, - addCustomValue () { + addCustomValue() { const property = this.model.get('property'); const customValue = this.$('.js-custom-value').select2('val'); let value = this.getValue(); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js index 6352dccb04b..4bd314e19aa 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js @@ -25,11 +25,11 @@ import { translate } from '../../../helpers/l10n'; export default BaseFacet.extend({ template: Template, - initialize (options) { + initialize(options) { this.listenTo(options.app.state, 'change:query', this.onQueryChange); }, - onQueryChange () { + onQueryChange() { const query = this.options.app.state.get('query'); const isProfileSelected = query.qprofile != null; if (isProfileSelected) { @@ -42,22 +42,22 @@ export default BaseFacet.extend({ } }, - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); this.onQueryChange(); }, - forbid () { + forbid() { BaseFacet.prototype.forbid.apply(this, arguments); this.$el.prop('title', translate('coding_rules.filters.inheritance.inactive')); }, - allow () { + allow() { BaseFacet.prototype.allow.apply(this, arguments); this.$el.prop('title', null); }, - getValues () { + getValues() { const values = ['NONE', 'INHERITED', 'OVERRIDES']; return values.map(key => { return { @@ -67,7 +67,7 @@ export default BaseFacet.extend({ }); }, - toggleFacet (e) { + toggleFacet(e) { const obj = {}; const property = this.model.get('property'); if ($(e.currentTarget).is('.active')) { @@ -78,7 +78,7 @@ export default BaseFacet.extend({ this.options.app.state.updateFilter(obj); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), values: this.getValues() diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js index 7fccd421c2e..b075edfe363 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/key-facet.js @@ -23,15 +23,15 @@ import Template from '../templates/facets/coding-rules-key-facet.hbs'; export default BaseFacet.extend({ template: Template, - onRender () { + onRender() { this.$el.toggleClass('hidden', !this.options.app.state.get('query').rule_key); }, - disable () { + disable() { this.options.app.state.updateFilter({ rule_key: null }); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), key: this.options.app.state.get('query').rule_key diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/language-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/language-facet.js index 18beae465ed..35d82b58801 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/language-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/language-facet.js @@ -20,19 +20,18 @@ import CustomValuesFacet from './custom-values-facet'; export default CustomValuesFacet.extend({ - - getUrl () { + getUrl() { return window.baseUrl + '/api/languages/list'; }, - prepareAjaxSearch () { + prepareAjaxSearch() { return { quietMillis: 300, url: this.getUrl(), - data (term) { + data(term) { return { q: term, ps: 10000 }; }, - results (data) { + results(data) { return { more: false, results: data.languages.map(lang => { @@ -43,11 +42,11 @@ export default CustomValuesFacet.extend({ }; }, - getLabelsSource () { + getLabelsSource() { return this.options.app.languages; }, - getValues () { + getValues() { const that = this; const labels = that.getLabelsSource(); return this.model.getValues().map(item => { @@ -55,11 +54,10 @@ export default CustomValuesFacet.extend({ }); }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValues()) }; } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js index 236232f0aa6..f2568f2109c 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/quality-profile-facet.js @@ -25,7 +25,7 @@ import Template from '../templates/facets/coding-rules-quality-profile-facet.hbs export default BaseFacet.extend({ template: Template, - events () { + events() { return { ...BaseFacet.prototype.events.apply(this, arguments), 'click .js-active': 'setActivation', @@ -33,24 +33,22 @@ export default BaseFacet.extend({ }; }, - getValues () { + getValues() { const that = this; const languagesQuery = this.options.app.state.get('query').languages; const languages = languagesQuery != null ? languagesQuery.split(',') : []; const lang = languages.length === 1 ? languages[0] : null; const values = this.options.app.qualityProfiles - .filter(profile => ( - lang != null ? profile.lang === lang : true - )) - .map(profile => ({ - label: profile.name, - extra: that.options.app.languages[profile.lang], - val: profile.key - })); + .filter(profile => lang != null ? profile.lang === lang : true) + .map(profile => ({ + label: profile.name, + extra: that.options.app.languages[profile.lang], + val: profile.key + })); return sortBy(values, 'label'); }, - toggleFacet (e) { + toggleFacet(e) { const obj = {}; const property = this.model.get('property'); if ($(e.currentTarget).is('.active')) { @@ -63,29 +61,29 @@ export default BaseFacet.extend({ this.options.app.state.updateFilter(obj); }, - setActivation (e) { + setActivation(e) { e.stopPropagation(); this.options.app.state.updateFilter({ activation: 'true' }); }, - unsetActivation (e) { + unsetActivation(e) { e.stopPropagation(); this.options.app.state.updateFilter({ activation: 'false', active_severities: null }); }, - getToggled () { + getToggled() { const activation = this.options.app.state.get('query').activation; return activation === 'true' || activation === true; }, - disable () { + disable() { const obj = { activation: null }; const property = this.model.get('property'); obj[property] = null; this.options.app.state.updateFilter(obj); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), values: this.getValues(), diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js index 9f236e9f328..3198f422809 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/query-facet.js @@ -23,7 +23,7 @@ import Template from '../templates/facets/coding-rules-query-facet.hbs'; export default BaseFacet.extend({ template: Template, - events () { + events() { return { ...BaseFacet.prototype.events.apply(this, arguments), 'submit form': 'onFormSubmit', @@ -31,7 +31,7 @@ export default BaseFacet.extend({ }; }, - onRender () { + onRender() { this.$el.attr('data-property', this.model.get('property')); const query = this.options.app.state.get('query'); const value = query.q; @@ -40,16 +40,16 @@ export default BaseFacet.extend({ } }, - onFormSubmit (e) { + onFormSubmit(e) { e.preventDefault(); this.applyFacet(); }, - onInputSearch () { + onInputSearch() { this.applyFacet(); }, - applyFacet () { + applyFacet() { const obj = {}; const property = this.model.get('property'); const value = this.$('input').val(); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js index 784f8268918..379c9b8fbdc 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/repository-facet.js @@ -17,23 +17,22 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import {} from 'lodash/object'; +import 'lodash/object'; import CustomValuesFacet from './custom-values-facet'; export default CustomValuesFacet.extend({ - - getUrl () { + getUrl() { return window.baseUrl + '/api/rules/repositories'; }, - prepareAjaxSearch () { + prepareAjaxSearch() { return { quietMillis: 300, url: this.getUrl(), - data (term) { + data(term) { return { q: term, ps: 10000 }; }, - results (data) { + results(data) { return { more: false, results: data.repositories.map(repo => { @@ -44,13 +43,13 @@ export default CustomValuesFacet.extend({ }; }, - getLabelsSource () { + getLabelsSource() { const source = {}; this.options.app.repositories.forEach(repo => source[repo.key] = repo.name); return source; }, - getValues () { + getValues() { const that = this; const labels = that.getLabelsSource(); return this.model.getValues().map(value => { @@ -63,11 +62,10 @@ export default CustomValuesFacet.extend({ }); }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.getValues() }; } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js index 1c292ec337a..cc0afc62ce3 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/severity-facet.js @@ -25,7 +25,7 @@ export default BaseFacet.extend({ template: Template, severities: ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR'], - sortValues (values) { + sortValues(values) { const order = this.severities; return sortBy(values, v => order.indexOf(v.val)); } diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js index 5ae3bd422dd..49645fe82bb 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js @@ -24,7 +24,7 @@ import { translate } from '../../../helpers/l10n'; export default BaseFacet.extend({ statuses: ['READY', 'DEPRECATED', 'BETA'], - getValues () { + getValues() { const values = this.model.getValues(); return values.map(value => ({ ...value, @@ -32,12 +32,12 @@ export default BaseFacet.extend({ })); }, - sortValues (values) { + sortValues(values) { const order = this.statuses; return sortBy(values, v => order.indexOf(v.val)); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValues()) diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/tag-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/tag-facet.js index 6e879ba6d95..c6260da607c 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/tag-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/tag-facet.js @@ -20,19 +20,18 @@ import CustomValuesFacet from './custom-values-facet'; export default CustomValuesFacet.extend({ - - getUrl () { + getUrl() { return window.baseUrl + '/api/rules/tags'; }, - prepareAjaxSearch () { + prepareAjaxSearch() { return { quietMillis: 300, url: this.getUrl(), - data (term) { + data(term) { return { q: term, ps: 10000 }; }, - results (data) { + results(data) { return { more: false, results: data.tags.map(tag => { @@ -42,5 +41,4 @@ export default CustomValuesFacet.extend({ } }; } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js index 65ea3319f77..810dfe29eee 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/template-facet.js @@ -24,7 +24,7 @@ import Template from '../templates/facets/coding-rules-template-facet.hbs'; export default BaseFacet.extend({ template: Template, - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); const value = this.options.app.state.get('query').is_template; if (value != null) { @@ -32,7 +32,7 @@ export default BaseFacet.extend({ } }, - toggleFacet (e) { + toggleFacet(e) { $(e.currentTarget).toggleClass('active'); const property = this.model.get('property'); const obj = {}; @@ -43,5 +43,4 @@ export default BaseFacet.extend({ } this.options.app.state.updateFilter(obj); } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js index ba090dd4ea5..7e940f0ff7b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/type-facet.js @@ -24,9 +24,8 @@ import Template from '../templates/facets/coding-rules-type-facet.hbs'; export default BaseFacet.extend({ template: Template, - sortValues (values) { + sortValues(values) { const order = ['BUG', 'VULNERABILITY', 'CODE_SMELL']; return sortBy(values, v => order.indexOf(v.val)); } }); - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/init.js b/server/sonar-web/src/main/js/apps/coding-rules/init.js index a1d63d23901..bd3eeebda96 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/init.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/init.js @@ -34,60 +34,62 @@ import FiltersView from './filters-view'; const App = new Marionette.Application(); -App.on('start', function (el) { - $.get(window.baseUrl + '/api/rules/app').done(r => { - App.canWrite = r.canWrite; - App.qualityProfiles = sortBy(r.qualityprofiles, ['name', 'lang']); - App.languages = { ...r.languages, none: 'None' }; - App.qualityProfiles.forEach(profile => { - profile.language = App.languages[profile.lang]; - }); - App.repositories = r.repositories; - App.statuses = r.statuses; - }).done(() => { - this.layout = new Layout({ el }); - this.layout.render(); - $('#footer').addClass('search-navigator-footer'); +App.on('start', function(el) { + $.get(window.baseUrl + '/api/rules/app') + .done(r => { + App.canWrite = r.canWrite; + App.qualityProfiles = sortBy(r.qualityprofiles, ['name', 'lang']); + App.languages = { ...r.languages, none: 'None' }; + App.qualityProfiles.forEach(profile => { + profile.language = App.languages[profile.lang]; + }); + App.repositories = r.repositories; + App.statuses = r.statuses; + }) + .done(() => { + this.layout = new Layout({ el }); + this.layout.render(); + $('#footer').addClass('search-navigator-footer'); - this.state = new State(); - this.list = new Rules(); - this.facets = new Facets(); + this.state = new State(); + this.list = new Rules(); + this.facets = new Facets(); - this.controller = new Controller({ app: this }); + this.controller = new Controller({ app: this }); - this.workspaceListView = new WorkspaceListView({ - app: this, - collection: this.list - }); - this.layout.workspaceListRegion.show(this.workspaceListView); - this.workspaceListView.bindScrollEvents(); + this.workspaceListView = new WorkspaceListView({ + app: this, + collection: this.list + }); + this.layout.workspaceListRegion.show(this.workspaceListView); + this.workspaceListView.bindScrollEvents(); - this.workspaceHeaderView = new WorkspaceHeaderView({ - app: this, - collection: this.list - }); - this.layout.workspaceHeaderRegion.show(this.workspaceHeaderView); + this.workspaceHeaderView = new WorkspaceHeaderView({ + app: this, + collection: this.list + }); + this.layout.workspaceHeaderRegion.show(this.workspaceHeaderView); - this.facetsView = new FacetsView({ - app: this, - collection: this.facets - }); - this.layout.facetsRegion.show(this.facetsView); + this.facetsView = new FacetsView({ + app: this, + collection: this.facets + }); + this.layout.facetsRegion.show(this.facetsView); - this.filtersView = new FiltersView({ - app: this - }); - this.layout.filtersRegion.show(this.filtersView); + this.filtersView = new FiltersView({ + app: this + }); + this.layout.filtersRegion.show(this.filtersView); - key.setScope('list'); - this.router = new Router({ - app: this + key.setScope('list'); + this.router = new Router({ + app: this + }); + Backbone.history.start(); }); - Backbone.history.start(); - }); }); -export default function (el) { +export default function(el) { App.start(el); return () => { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/layout.js b/server/sonar-web/src/main/js/apps/coding-rules/layout.js index 9e9dba4672b..ba874e70120 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/layout.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/layout.js @@ -32,27 +32,26 @@ export default Marionette.LayoutView.extend({ workspaceDetailsRegion: '.search-navigator-workspace-details' }, - onRender () { + onRender() { const navigator = this.$('.search-navigator'); const top = navigator.offset().top; this.$('.search-navigator-workspace-header').css({ top }); this.$('.search-navigator-side').css({ top }).isolatedScroll(); }, - showDetails () { + showDetails() { this.scroll = $(window).scrollTop(); this.$('.search-navigator').addClass('search-navigator-extended-view'); }, - hideDetails () { + hideDetails() { this.$('.search-navigator').removeClass('search-navigator-extended-view'); if (this.scroll != null) { $(window).scrollTop(this.scroll); } }, - detailsShow () { + detailsShow() { return this.$('.search-navigator').is('.search-navigator-extended-view'); } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/models/rule.js b/server/sonar-web/src/main/js/apps/coding-rules/models/rule.js index 654b858c908..4b0d2a9723c 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/models/rule.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/models/rule.js @@ -22,19 +22,22 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ idAttribute: 'key', - addExtraAttributes (repositories) { + addExtraAttributes(repositories) { const repo = repositories.find(repo => repo.key === this.get('repo')) || this.get('repo'); const repoName = repo != null ? repo.name : repo; const isManual = this.get('repo') === 'manual'; const isCustom = this.has('templateKey'); - this.set({ - repoName, - isManual, - isCustom - }, { silent: true }); + this.set( + { + repoName, + isManual, + isCustom + }, + { silent: true } + ); }, - getInactiveProfiles (actives, profiles) { + getInactiveProfiles(actives, profiles) { return actives.map(profile => { const profileBase = profiles.find(p => p.key === profile.qProfile); if (profileBase != null) { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/models/rules.js b/server/sonar-web/src/main/js/apps/coding-rules/models/rules.js index 5458ef686c2..6698900c496 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/models/rules.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/models/rules.js @@ -23,7 +23,7 @@ import Rule from './rule'; export default Backbone.Collection.extend({ model: Rule, - parseRules (r) { + parseRules(r) { let rules = r.rules; const profiles = r.qProfiles || []; @@ -45,13 +45,13 @@ export default Backbone.Collection.extend({ return rules; }, - setIndex () { + setIndex() { this.forEach((rule, index) => { rule.set({ index }); }); }, - addExtraAttributes (repositories) { + addExtraAttributes(repositories) { this.models.forEach(model => { model.addExtraAttributes(repositories); }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/models/state.js b/server/sonar-web/src/main/js/apps/coding-rules/models/state.js index 8eec95a0b6f..301401f84c2 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/models/state.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/models/state.js @@ -24,10 +24,7 @@ export default State.extend({ page: 1, maxResultsReached: false, query: {}, - facets: [ - 'types', - 'languages' - ], + facets: ['types', 'languages'], allFacets: [ 'q', 'rule_key', diff --git a/server/sonar-web/src/main/js/apps/coding-rules/routes.js b/server/sonar-web/src/main/js/apps/coding-rules/routes.js index e0807b45982..651cc6aeaec 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/routes.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import CodingRulesAppContainer from './components/CodingRulesAppContainer'; -export default ( - <IndexRoute component={CodingRulesAppContainer}/> -); +export default <IndexRoute component={CodingRulesAppContainer} />; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js index 394436553dd..c83af70b66b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js @@ -50,7 +50,7 @@ export default Marionette.LayoutView.extend({ 'click .js-delete': 'deleteRule' }, - initialize () { + initialize() { this.bindShortcuts(); this.customRules = new Rules(); if (this.model.get('isTemplate')) { @@ -59,41 +59,53 @@ export default Marionette.LayoutView.extend({ this.listenTo(this.options.app.state, 'change:selectedIndex', this.select); }, - onRender () { - this.metaRegion.show(new MetaView({ - app: this.options.app, - model: this.model - })); - this.descRegion.show(new DescView({ - app: this.options.app, - model: this.model - })); - this.paramRegion.show(new ParamView({ - app: this.options.app, - model: this.model - })); - this.profilesRegion.show(new ProfilesView({ - app: this.options.app, - model: this.model, - collection: new Backbone.Collection(this.getQualityProfiles()) - })); - this.customRulesRegion.show(new CustomRulesView({ - app: this.options.app, - model: this.model, - collection: this.customRules - })); - this.issuesRegion.show(new IssuesView({ - app: this.options.app, - model: this.model - })); + onRender() { + this.metaRegion.show( + new MetaView({ + app: this.options.app, + model: this.model + }) + ); + this.descRegion.show( + new DescView({ + app: this.options.app, + model: this.model + }) + ); + this.paramRegion.show( + new ParamView({ + app: this.options.app, + model: this.model + }) + ); + this.profilesRegion.show( + new ProfilesView({ + app: this.options.app, + model: this.model, + collection: new Backbone.Collection(this.getQualityProfiles()) + }) + ); + this.customRulesRegion.show( + new CustomRulesView({ + app: this.options.app, + model: this.model, + collection: this.customRules + }) + ); + this.issuesRegion.show( + new IssuesView({ + app: this.options.app, + model: this.model + }) + ); this.$el.scrollParent().scrollTop(0); }, - onDestroy () { + onDestroy() { this.unbindShortcuts(); }, - fetchCustomRules () { + fetchCustomRules() { const that = this; const url = window.baseUrl + '/api/rules/search'; const options = { @@ -105,11 +117,11 @@ export default Marionette.LayoutView.extend({ }); }, - getQualityProfiles () { + getQualityProfiles() { return this.model.getInactiveProfiles(this.options.actives, this.options.app.qualityProfiles); }, - bindShortcuts () { + bindShortcuts() { const that = this; key('up', 'details', () => { that.options.app.controller.selectPrev(); @@ -125,18 +137,18 @@ export default Marionette.LayoutView.extend({ }); }, - unbindShortcuts () { + unbindShortcuts() { key.deleteScope('details'); }, - editCustomRule () { + editCustomRule() { new CustomRuleCreationView({ app: this.options.app, model: this.model }).render(); }, - deleteRule () { + deleteRule() { const deleteRuleView = new DeleteRuleView({ model: this.model }).render(); @@ -151,13 +163,13 @@ export default Marionette.LayoutView.extend({ }); }, - select () { + select() { const selected = this.options.app.state.get('selectedIndex'); const selectedRule = this.options.app.list.at(selected); this.options.app.controller.showDetails(selectedRule); }, - serializeData () { + serializeData() { const isCustom = this.model.has('templateKey'); const isEditable = this.options.app.canWrite && isCustom; let qualityProfilesVisible = true; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js index ec3c67b93b1..98e7529af5c 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-filter-view.js @@ -25,18 +25,17 @@ import Template from './templates/coding-rules-rule-filter-form.hbs'; export default ActionOptionsView.extend({ template: Template, - selectOption (e) { + selectOption(e) { const property = $(e.currentTarget).data('property'); const value = $(e.currentTarget).data('value'); this.trigger('select', property, value); return ActionOptionsView.prototype.selectOption.apply(this, arguments); }, - serializeData () { + serializeData() { return { ...ActionOptionsView.prototype.serializeData.apply(this, arguments), tags: union(this.model.get('sysTags'), this.model.get('tags')) }; } - }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js index 083cc5423b0..5ce696aa43c 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js @@ -27,7 +27,7 @@ import { translate } from '../../../helpers/l10n'; export default ModalFormView.extend({ template: Template, - ui () { + ui() { return { ...ModalFormView.prototype.ui.apply(this, arguments), customRuleCreationKey: '#coding-rules-custom-rule-creation-key', @@ -42,7 +42,7 @@ export default ModalFormView.extend({ }; }, - events () { + events() { return { ...ModalFormView.prototype.events.apply(this, arguments), 'input @ui.customRuleCreationName': 'generateKey', @@ -59,31 +59,36 @@ export default ModalFormView.extend({ }; }, - generateKey () { + generateKey() { if (!this.keyModifiedByUser && this.ui.customRuleCreationKey) { - const generatedKey = latinize(this.ui.customRuleCreationName.val()).replace(/[^A-Za-z0-9]/g, '_'); + const generatedKey = latinize(this.ui.customRuleCreationName.val()).replace( + /[^A-Za-z0-9]/g, + '_' + ); this.ui.customRuleCreationKey.val(generatedKey); } }, - flagKey () { + flagKey() { this.keyModifiedByUser = true; }, - onRender () { + onRender() { ModalFormView.prototype.onRender.apply(this, arguments); this.keyModifiedByUser = false; - const format = function (state) { + const format = function(state) { if (!state.id) { return state.text; } else { return `<i class="icon-severity-${state.id.toLowerCase()}"></i> ${state.text}`; } }; - const severity = (this.model && this.model.get('severity')) || this.options.templateRule.get('severity'); - const status = (this.model && this.model.get('status')) || this.options.templateRule.get('status'); + const severity = (this.model && this.model.get('severity')) || + this.options.templateRule.get('severity'); + const status = (this.model && this.model.get('status')) || + this.options.templateRule.get('status'); this.ui.customRuleCreationSeverity.val(severity); this.ui.customRuleCreationSeverity.select2({ @@ -100,9 +105,9 @@ export default ModalFormView.extend({ }); }, - create (e) { + create(e) { e.preventDefault(); - const action = (this.model && this.model.has('key')) ? 'update' : 'create'; + const action = this.model && this.model.has('key') ? 'update' : 'create'; const options = { name: this.ui.customRuleCreationName.val(), markdown_description: this.ui.customRuleCreationHtmlDescription.val(), @@ -118,22 +123,24 @@ export default ModalFormView.extend({ prevent_reactivation: true }); } - const params = this.ui.customRuleCreationParameters.map(function () { - const node = $(this); - let value = node.val(); - if (!value && action === 'create') { - value = node.prop('placeholder') || ''; - } - return { - key: node.prop('name'), - value - }; - }).get(); + const params = this.ui.customRuleCreationParameters + .map(function() { + const node = $(this); + let value = node.val(); + if (!value && action === 'create') { + value = node.prop('placeholder') || ''; + } + return { + key: node.prop('name'), + value + }; + }) + .get(); options.params = params.map(param => param.key + '=' + csvEscape(param.value)).join(';'); this.sendRequest(action, options); }, - reactivate () { + reactivate() { const options = { name: this.existingRule.name, markdown_description: this.existingRule.mdDesc, @@ -148,7 +155,7 @@ export default ModalFormView.extend({ this.sendRequest('create', options); }, - sendRequest (action, options) { + sendRequest(action, options) { this.$('.alert').addClass('hidden'); const that = this; const url = window.baseUrl + '/api/rules/' + action; @@ -160,26 +167,28 @@ export default ModalFormView.extend({ // do not show global error 400: null } - }).done(() => { - if (that.options.templateRule) { - that.options.app.controller.showDetails(that.options.templateRule); - } else { - that.options.app.controller.showDetails(that.model); - } - that.destroy(); - }).fail(jqXHR => { - if (jqXHR.status === 409) { - that.existingRule = jqXHR.responseJSON.rule; - that.showErrors([], [{ msg: translate('coding_rules.reactivate.help') }]); - that.ui.customRuleCreationCreate.addClass('hidden'); - that.ui.customRuleCreationReactivate.removeClass('hidden'); - } else { - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - } - }); + }) + .done(() => { + if (that.options.templateRule) { + that.options.app.controller.showDetails(that.options.templateRule); + } else { + that.options.app.controller.showDetails(that.model); + } + that.destroy(); + }) + .fail(jqXHR => { + if (jqXHR.status === 409) { + that.existingRule = jqXHR.responseJSON.rule; + that.showErrors([], [{ msg: translate('coding_rules.reactivate.help') }]); + that.ui.customRuleCreationCreate.addClass('hidden'); + that.ui.customRuleCreationReactivate.removeClass('hidden'); + } else { + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + } + }); }, - serializeData () { + serializeData() { let params = {}; if (this.options.templateRule) { params = this.options.templateRule.get('params'); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js index a236cc1e617..1a5ff0ccdfe 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js @@ -26,14 +26,14 @@ export default Marionette.ItemView.extend({ template: Template, modelEvents: { - 'change': 'render' + change: 'render' }, events: { 'click .js-delete-custom-rule': 'deleteRule' }, - deleteRule () { + deleteRule() { const deleteRuleView = new DeleteRuleView({ model: this.model }).render(); @@ -44,7 +44,7 @@ export default Marionette.ItemView.extend({ }); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), canWrite: this.options.app.canWrite, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js index 499a14b9195..e8f9c0752c1 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rules-view.js @@ -27,7 +27,7 @@ export default Marionette.CompositeView.extend({ childView: CustomRuleView, childViewContainer: '#coding-rules-detail-custom-rules', - childViewOptions () { + childViewOptions() { return { app: this.options.app, templateRule: this.model @@ -35,25 +35,25 @@ export default Marionette.CompositeView.extend({ }, modelEvents: { - 'change': 'render' + change: 'render' }, events: { 'click .js-create-custom-rule': 'createCustomRule' }, - onRender () { + onRender() { this.$el.toggleClass('hidden', !this.model.get('isTemplate')); }, - createCustomRule () { + createCustomRule() { new CustomRuleCreationView({ app: this.options.app, templateRule: this.model }).render(); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), canWrite: this.options.app.canWrite diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/delete-rule-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/delete-rule-view.js index 3fb97ab2760..ba33cd5a0a5 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/delete-rule-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/delete-rule-view.js @@ -24,7 +24,7 @@ import Template from '../templates/rule/coding-rules-delete-rule.hbs'; export default ModalFormView.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); const url = window.baseUrl + '/api/rules/delete'; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js index 6cf664d9ee2..7ad2466241d 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/profile-activation-view.js @@ -27,7 +27,7 @@ import { sortProfiles } from '../../quality-profiles/utils'; export default ModalForm.extend({ template: Template, - ui () { + ui() { return { ...ModalForm.prototype.ui.apply(this, arguments), qualityProfileSelect: '#coding-rules-quality-profile-activation-select', @@ -37,14 +37,14 @@ export default ModalForm.extend({ }; }, - events () { + events() { return { ...ModalForm.prototype.events.apply(this, arguments), 'click @ui.qualityProfileActivate': 'activate' }; }, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.ui.qualityProfileSelect.select2({ @@ -53,14 +53,15 @@ export default ModalForm.extend({ }); const that = this; - const format = function (state) { + const format = function(state) { if (!state.id) { return state.text; } else { return `<i class="icon-severity-${state.id.toLowerCase()}"></i> ${state.text}`; } }; - const severity = (this.model && this.model.get('severity')) || this.options.rule.get('severity'); + const severity = (this.model && this.model.get('severity')) || + this.options.rule.get('severity'); this.ui.qualityProfileSeverity.val(severity); this.ui.qualityProfileSeverity.select2({ width: '250px', @@ -68,22 +69,27 @@ export default ModalForm.extend({ formatResult: format, formatSelection: format }); - setTimeout(() => { - that.$('a').first().focus(); - }, 0); + setTimeout( + () => { + that.$('a').first().focus(); + }, + 0 + ); }, - activate (e) { + activate(e) { e.preventDefault(); const that = this; let profileKey = this.ui.qualityProfileSelect.val(); - const params = this.ui.qualityProfileParameters.map(function () { - return { - key: $(this).prop('name'), - value: $(this).val() || $(this).prop('placeholder') || '' - }; - }).get(); - const paramsHash = (params.map(param => param.key + '=' + csvEscape(param.value))).join(';'); + const params = this.ui.qualityProfileParameters + .map(function() { + return { + key: $(this).prop('name'), + value: $(this).val() || $(this).prop('placeholder') || '' + }; + }) + .get(); + const paramsHash = params.map(param => param.key + '=' + csvEscape(param.value)).join(';'); if (this.model) { profileKey = this.model.get('qProfile'); @@ -110,24 +116,26 @@ export default ModalForm.extend({ // do not show global error 400: null } - }).done(() => { - that.destroy(); - that.trigger('profileActivated', severity, params, profileKey); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + }) + .done(() => { + that.destroy(); + that.trigger('profileActivated', severity, params, profileKey); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); }, - getAvailableQualityProfiles (lang) { + getAvailableQualityProfiles(lang) { const activeQualityProfiles = this.collection || new Backbone.Collection(); - const inactiveProfiles = this.options.app.qualityProfiles.filter(profile => ( - !activeQualityProfiles.findWhere({ key: profile.key }) - )); + const inactiveProfiles = this.options.app.qualityProfiles.filter( + profile => !activeQualityProfiles.findWhere({ key: profile.key }) + ); return inactiveProfiles.filter(profile => profile.lang === lang); }, - serializeData () { + serializeData() { let params = this.options.rule.get('params'); if (this.model != null) { const modelParams = this.model.get('params'); @@ -159,7 +167,8 @@ export default ModalForm.extend({ qualityProfiles: profilesWithDepth, severities: ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'], saveEnabled: availableProfiles.length > 0 || (this.model && this.model.get('qProfile')), - isCustomRule: (this.model && this.model.has('templateKey')) || this.options.rule.has('templateKey') + isCustomRule: (this.model && this.model.has('templateKey')) || + this.options.rule.has('templateKey') }; } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js index 5ae069e0bd3..62d516c543d 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js @@ -27,7 +27,7 @@ export default Marionette.ItemView.extend({ template: Template, modelEvents: { - 'change': 'render' + change: 'render' }, ui: { @@ -47,18 +47,18 @@ export default Marionette.ItemView.extend({ 'click @ui.extendDescriptionRemove': 'removeExtendedDescription' }, - showExtendDescriptionForm () { + showExtendDescriptionForm() { this.ui.descriptionExtra.addClass('hidden'); this.ui.extendDescriptionForm.removeClass('hidden'); this.ui.extendDescriptionText.focus(); }, - hideExtendDescriptionForm () { + hideExtendDescriptionForm() { this.ui.descriptionExtra.removeClass('hidden'); this.ui.extendDescriptionForm.addClass('hidden'); }, - submitExtendDescription () { + submitExtendDescription() { const that = this; this.ui.extendDescriptionForm.addClass('hidden'); return $.ajax({ @@ -69,29 +69,31 @@ export default Marionette.ItemView.extend({ key: this.model.get('key'), markdown_note: this.ui.extendDescriptionText.val() } - }).done(r => { - that.model.set({ - htmlNote: r.rule.htmlNote, - mdNote: r.rule.mdNote + }) + .done(r => { + that.model.set({ + htmlNote: r.rule.htmlNote, + mdNote: r.rule.mdNote + }); + that.render(); + }) + .fail(() => { + that.render(); }); - that.render(); - }).fail(() => { - that.render(); - }); }, - removeExtendedDescription () { + removeExtendedDescription() { const that = this; confirmDialog({ html: translate('coding_rules.remove_extended_description.confirm'), - yesHandler () { + yesHandler() { that.ui.extendDescriptionText.val(''); that.submitExtendDescription(); } }); }, - serializeData () { + serializeData() { const isEditable = this.options.app.canWrite && this.model.get('isCustom'); return { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-filter-mixin.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-filter-mixin.js index 0276bf24e6e..a0ad4f2006e 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-filter-mixin.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-filter-mixin.js @@ -21,7 +21,7 @@ import $ from 'jquery'; import RuleFilterView from '../rule-filter-view'; export default { - onRuleFilterClick (e) { + onRuleFilterClick(e) { e.preventDefault(); e.stopPropagation(); $('body').click(); @@ -40,4 +40,3 @@ export default { popup.render(); } }; - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js index 330e802a151..d13deae57e0 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-issues-view.js @@ -24,7 +24,7 @@ import Template from '../templates/rule/coding-rules-rule-issues.hbs'; export default Marionette.ItemView.extend({ template: Template, - initialize () { + initialize() { const that = this; this.total = null; this.projects = []; @@ -33,7 +33,7 @@ export default Marionette.ItemView.extend({ }); }, - requestIssues () { + requestIssues() { const that = this; const url = window.baseUrl + '/api/issues/search'; const options = { @@ -57,13 +57,14 @@ export default Marionette.ItemView.extend({ }); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), total: this.total, projects: this.projects, - baseSearchUrl: window.baseUrl + '/issues/search#resolved=false|rules=' + encodeURIComponent(this.model.id) + baseSearchUrl: window.baseUrl + + '/issues/search#resolved=false|rules=' + + encodeURIComponent(this.model.id) }; } }); - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js index 1cc0f98939b..b7fdf7d3c33 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-meta-view.js @@ -28,7 +28,7 @@ export default Marionette.ItemView.extend(RuleFilterMixin).extend({ template: Template, modelEvents: { - 'change': 'render' + change: 'render' }, ui: { @@ -47,22 +47,22 @@ export default Marionette.ItemView.extend(RuleFilterMixin).extend({ 'click .js-rule-filter': 'onRuleFilterClick' }, - onRender () { + onRender() { this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - requestTags () { + requestTags() { const url = window.baseUrl + '/api/rules/tags'; return $.get(url); }, - changeTags () { + changeTags() { const that = this; this.requestTags().done(r => { that.ui.tagInput.select2({ @@ -77,7 +77,7 @@ export default Marionette.ItemView.extend(RuleFilterMixin).extend({ }); }, - cancelEdit () { + cancelEdit() { this.ui.tagsList.removeClass('hidden'); this.ui.tagsEdit.addClass('hidden'); if (this.ui.tagInput.select2) { @@ -86,7 +86,7 @@ export default Marionette.ItemView.extend(RuleFilterMixin).extend({ } }, - editDone () { + editDone() { const that = this; const tags = this.ui.tagInput.val(); return $.ajax({ @@ -96,15 +96,17 @@ export default Marionette.ItemView.extend(RuleFilterMixin).extend({ key: this.model.get('key'), tags } - }).done(r => { - that.model.set('tags', r.rule.tags); - that.cancelEdit(); - }).always(() => { - that.cancelEdit(); - }); + }) + .done(r => { + that.model.set('tags', r.rule.tags); + that.cancelEdit(); + }) + .always(() => { + that.cancelEdit(); + }); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), canWrite: this.options.app.canWrite, @@ -113,4 +115,3 @@ export default Marionette.ItemView.extend(RuleFilterMixin).extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js index 43d69b5c2c9..8923b74d374 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-parameters-view.js @@ -24,15 +24,15 @@ export default Marionette.ItemView.extend({ template: Template, modelEvents: { - 'change': 'render' + change: 'render' }, - onRender () { + onRender() { const params = this.model.get('params'); this.$el.toggleClass('hidden', params == null || params.length === 0); }, - serializeData () { + serializeData() { const isEditable = this.options.app.canWrite && this.model.get('isCustom'); return { @@ -42,4 +42,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js index 4cefddcac1e..7265d718b25 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js @@ -31,7 +31,7 @@ export default Marionette.ItemView.extend({ template: Template, modelEvents: { - 'change': 'render' + change: 'render' }, ui: { @@ -46,13 +46,13 @@ export default Marionette.ItemView.extend({ 'click @ui.deactivate': 'deactivate' }, - onRender () { + onRender() { this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' }); }, - change () { + change() { const that = this; const activationView = new ProfileActivationView({ model: this.model, @@ -66,13 +66,16 @@ export default Marionette.ItemView.extend({ activationView.render(); }, - revert () { + revert() { const that = this; const ruleKey = this.options.rule.get('key'); confirmDialog({ title: translate('coding_rules.revert_to_parent_definition'), - html: translateWithParameters('coding_rules.revert_to_parent_definition.confirm', this.getParent().name), - yesHandler () { + html: translateWithParameters( + 'coding_rules.revert_to_parent_definition.confirm', + this.getParent().name + ), + yesHandler() { return $.ajax({ type: 'POST', url: window.baseUrl + '/api/qualityprofiles/activate_rule', @@ -88,13 +91,13 @@ export default Marionette.ItemView.extend({ }); }, - deactivate () { + deactivate() { const that = this; const ruleKey = this.options.rule.get('key'); confirmDialog({ title: translate('coding_rules.deactivate'), html: translateWithParameters('coding_rules.deactivate.confirm'), - yesHandler () { + yesHandler() { return $.ajax({ type: 'POST', url: window.baseUrl + '/api/qualityprofiles/deactivate_rule', @@ -109,23 +112,26 @@ export default Marionette.ItemView.extend({ }); }, - enableUpdate () { + enableUpdate() { return this.ui.update.prop('disabled', false); }, - getParent () { + getParent() { if (!(this.model.get('inherit') && this.model.get('inherit') !== 'NONE')) { return null; } - const myProfile = this.options.app.qualityProfiles.find(p => p.key === this.model.get('qProfile')); + const myProfile = this.options.app.qualityProfiles.find( + p => p.key === this.model.get('qProfile') + ); const parentKey = myProfile.parentKey; const parent = { ...this.options.app.qualityProfiles.find(p => p.key === parentKey) }; - const parentActiveInfo = this.model.collection.findWhere({ qProfile: parentKey }) || new Backbone.Model(); + const parentActiveInfo = this.model.collection.findWhere({ qProfile: parentKey }) || + new Backbone.Model(); Object.assign(parent, parentActiveInfo.toJSON()); return parent; }, - enhanceParameters () { + enhanceParameters() { const parent = this.getParent(); const params = sortBy(this.model.get('params'), 'key'); if (!parent) { @@ -141,7 +147,7 @@ export default Marionette.ItemView.extend({ }); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), canWrite: this.options.app.canWrite, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js index 670a4f543cf..dadabe8ea18 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profiles-view.js @@ -27,7 +27,7 @@ export default Marionette.CompositeView.extend({ childView: ProfileView, childViewContainer: '#coding-rules-detail-quality-profiles', - childViewOptions () { + childViewOptions() { return { app: this.options.app, rule: this.model, @@ -36,14 +36,14 @@ export default Marionette.CompositeView.extend({ }, modelEvents: { - 'change': 'render' + change: 'render' }, events: { 'click #coding-rules-quality-profile-activate': 'activate' }, - onRender () { + onRender() { let qualityProfilesVisible = true; if (this.model.get('isTemplate')) { @@ -53,7 +53,7 @@ export default Marionette.CompositeView.extend({ this.$el.toggleClass('hidden', !qualityProfilesVisible); }, - activate () { + activate() { const that = this; const activationView = new ProfileActivationView({ rule: this.model, @@ -75,14 +75,16 @@ export default Marionette.CompositeView.extend({ activationView.render(); }, - refreshActives () { + refreshActives() { const that = this; this.options.app.controller.getRuleDetails(this.model).done(data => { - that.collection.reset(that.model.getInactiveProfiles(data.actives, that.options.app.qualityProfiles)); + that.collection.reset( + that.model.getInactiveProfiles(data.actives, that.options.app.qualityProfiles) + ); }); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), canWrite: this.options.app.canWrite diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js index b6df2291f16..a5ac0165f28 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-header-view.js @@ -25,7 +25,7 @@ import Template from './templates/coding-rules-workspace-header.hbs'; export default WorkspaceHeaderView.extend({ template: Template, - events () { + events() { return { ...WorkspaceHeaderView.prototype.events.apply(this, arguments), 'click .js-back': 'onBackClick', @@ -35,11 +35,11 @@ export default WorkspaceHeaderView.extend({ }; }, - onBackClick () { + onBackClick() { this.options.app.controller.hideDetails(); }, - onBulkChangeClick (e) { + onBulkChangeClick(e) { e.stopPropagation(); $('body').click(); new BulkChangePopup({ @@ -49,19 +49,18 @@ export default WorkspaceHeaderView.extend({ }).render(); }, - reload () { + reload() { this.options.app.controller.fetchList(true); }, - newSearch () { + newSearch() { this.options.app.controller.newSearch(); }, - serializeData () { + serializeData() { return { ...WorkspaceHeaderView.prototype.serializeData.apply(this, arguments), canWrite: this.options.app.canWrite }; } }); - diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js index c82efaf9927..dc8cbf4b994 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js @@ -23,7 +23,7 @@ import { translate } from '../../helpers/l10n'; export default Marionette.ItemView.extend({ className: 'search-navigator-no-results', - template () { + template() { return translate('coding_rules.no_results'); } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js index a338d44a29b..b64ee68739d 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js @@ -32,7 +32,7 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ template: Template, modelEvents: { - 'change': 'render' + change: 'render' }, events: { @@ -46,30 +46,32 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ 'click .coding-rules-detail-quality-profile-deactivate': 'deactivate' }, - onRender () { + onRender() { WorkspaceListItemView.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - selectCurrent () { + selectCurrent() { this.options.app.state.set({ selectedIndex: this.model.get('index') }); }, - openRule () { + openRule() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); this.options.app.controller.showDetails(this.model); }, - activate () { + activate() { const that = this; const selectedProfile = this.options.app.state.get('query').qprofile; - const othersQualityProfiles = this.options.app.qualityProfiles.filter(profile => profile.key !== selectedProfile); + const othersQualityProfiles = this.options.app.qualityProfiles.filter( + profile => profile.key !== selectedProfile + ); const activationView = new ProfileActivationView({ rule: this.model, collection: new Backbone.Collection(othersQualityProfiles), @@ -87,14 +89,14 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ activationView.render(); }, - deactivate () { + deactivate() { const that = this; const ruleKey = this.model.get('key'); const activation = this.model.get('activation'); confirmDialog({ title: translate('coding_rules.deactivate'), html: translateWithParameters('coding_rules.deactivate.confirm'), - yesHandler () { + yesHandler() { return $.ajax({ type: 'POST', url: window.baseUrl + '/api/qualityprofiles/deactivate_rule', @@ -109,7 +111,7 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ }); }, - serializeData () { + serializeData() { return { ...WorkspaceListItemView.prototype.serializeData.apply(this, arguments), tags: union(this.model.get('sysTags'), this.model.get('tags')), diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js index b7ea0ac3b86..1e32a633a9a 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-view.js @@ -28,7 +28,7 @@ export default WorkspaceListView.extend({ childViewContainer: '.js-list', emptyView: WorkspaceListEmptyView, - bindShortcuts () { + bindShortcuts() { WorkspaceListView.prototype.bindShortcuts.apply(this, arguments); const that = this; key('right', 'list', () => { @@ -45,4 +45,3 @@ export default WorkspaceListView.extend({ }); } }); - diff --git a/server/sonar-web/src/main/js/apps/component-issues/components/ComponentIssuesAppContainer.js b/server/sonar-web/src/main/js/apps/component-issues/components/ComponentIssuesAppContainer.js index 7d7f478dcd1..061b3e8f8c6 100644 --- a/server/sonar-web/src/main/js/apps/component-issues/components/ComponentIssuesAppContainer.js +++ b/server/sonar-web/src/main/js/apps/component-issues/components/ComponentIssuesAppContainer.js @@ -23,23 +23,23 @@ import init from '../init'; import { getComponent, getCurrentUser } from '../../../store/rootReducer'; class ComponentIssuesAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { this.stop = init(this.refs.container, this.props.component, this.props.currentUser); } - componentWillUnmount () { + componentWillUnmount() { this.stop(); } - render () { + render() { // placing container inside div is required, // because when backbone.marionette's layout is destroyed, // it also destroys the root element, // but react wants it to be there to unmount it return ( - <div> - <div ref="container"/> - </div> + <div> + <div ref="container" /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-issues/init.js b/server/sonar-web/src/main/js/apps/component-issues/init.js index 37bf91c5d19..65721263cc7 100644 --- a/server/sonar-web/src/main/js/apps/component-issues/init.js +++ b/server/sonar-web/src/main/js/apps/component-issues/init.js @@ -33,7 +33,7 @@ import FacetsView from './../issues/facets-view'; import HeaderView from './../issues/HeaderView'; const App = new Marionette.Application(); -const init = function ({ el, component, currentUser }) { +const init = function({ el, component, currentUser }) { this.config = { resource: component.id, resourceName: component.name, @@ -86,28 +86,31 @@ const init = function ({ el, component, currentUser }) { Backbone.history.start(); }; -App.getContextQuery = function () { +App.getContextQuery = function() { return { componentUuids: this.config.resource }; }; -App.getRestrictedFacets = function () { +App.getRestrictedFacets = function() { return { - 'TRK': ['projectUuids'], - 'BRC': ['projectUuids'], - 'DIR': ['projectUuids', 'moduleUuids', 'directories'], - 'DEV': ['authors'], - 'DEV_PRJ': ['projectUuids', 'authors'] + TRK: ['projectUuids'], + BRC: ['projectUuids'], + DIR: ['projectUuids', 'moduleUuids', 'directories'], + DEV: ['authors'], + DEV_PRJ: ['projectUuids', 'authors'] }; }; -App.updateContextFacets = function () { +App.updateContextFacets = function() { const facets = this.state.get('facets'); const allFacets = this.state.get('allFacets'); const facetsFromServer = this.state.get('facetsFromServer'); return this.state.set({ facets, allFacets: difference(allFacets, this.getRestrictedFacets()[this.config.resourceQualifier]), - facetsFromServer: difference(facetsFromServer, this.getRestrictedFacets()[this.config.resourceQualifier]) + facetsFromServer: difference( + facetsFromServer, + this.getRestrictedFacets()[this.config.resourceQualifier] + ) }); }; @@ -115,7 +118,7 @@ App.on('start', options => { init.call(App, options); }); -export default function (el, component, currentUser) { +export default function(el, component, currentUser) { App.start({ el, component, currentUser }); return () => { diff --git a/server/sonar-web/src/main/js/apps/component-issues/routes.js b/server/sonar-web/src/main/js/apps/component-issues/routes.js index 40d8ac8975e..0b64f94952f 100644 --- a/server/sonar-web/src/main/js/apps/component-issues/routes.js +++ b/server/sonar-web/src/main/js/apps/component-issues/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import ComponentIssuesAppContainer from './components/ComponentIssuesAppContainer'; -export default ( - <IndexRoute component={ComponentIssuesAppContainer}/> -); +export default <IndexRoute component={ComponentIssuesAppContainer} />; diff --git a/server/sonar-web/src/main/js/apps/component-measures/app/App.js b/server/sonar-web/src/main/js/apps/component-measures/app/App.js index 2381ba36011..29aa89ae573 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/app/App.js +++ b/server/sonar-web/src/main/js/apps/component-measures/app/App.js @@ -23,21 +23,21 @@ import Spinner from './../components/Spinner'; export default class App extends React.Component { state = { componentSet: false }; - componentDidMount () { + componentDidMount() { this.props.setComponent(this.props.component); this.props.fetchMetrics(); this.setState({ componentSet: true }); } - render () { + render() { if (this.props.metrics == null || !this.state.componentSet) { - return <Spinner/>; + return <Spinner />; } return ( - <main id="component-measures"> - {this.props.children} - </main> + <main id="component-measures"> + {this.props.children} + </main> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/app/AppContainer.js b/server/sonar-web/src/main/js/apps/component-measures/app/AppContainer.js index 316314122fa..dca2e1eb935 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/app/AppContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/app/AppContainer.js @@ -34,7 +34,4 @@ const mapDispatchToProps = dispatch => { }; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(App); +export default connect(mapStateToProps, mapDispatchToProps)(App); diff --git a/server/sonar-web/src/main/js/apps/component-measures/app/actions.js b/server/sonar-web/src/main/js/apps/component-measures/app/actions.js index 36f8559b61a..7cfb8acbe6f 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/app/actions.js +++ b/server/sonar-web/src/main/js/apps/component-measures/app/actions.js @@ -31,15 +31,15 @@ export const SET_COMPONENT = 'measuresApp/app/SET_COMPONENT'; * Action Creators */ -export function displayHome () { +export function displayHome() { return { type: DISPLAY_HOME }; } -function receiveMetrics (metrics) { +function receiveMetrics(metrics) { return { type: RECEIVE_METRICS, metrics }; } -export function setComponent (component) { +export function setComponent(component) { return { type: SET_COMPONENT, component }; } @@ -47,7 +47,7 @@ export function setComponent (component) { * Workflow */ -export function fetchMetrics () { +export function fetchMetrics() { return dispatch => { getMetrics().then(metrics => { dispatch(receiveMetrics(metrics)); diff --git a/server/sonar-web/src/main/js/apps/component-measures/app/reducer.js b/server/sonar-web/src/main/js/apps/component-measures/app/reducer.js index c0fac17c757..165b79c524b 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/app/reducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/app/reducer.js @@ -23,7 +23,7 @@ const initialState = { metrics: undefined }; -export default function appReducer (state = initialState, action = {}) { +export default function appReducer(state = initialState, action = {}) { switch (action.type) { case RECEIVE_METRICS: return { ...state, metrics: action.metrics }; @@ -33,4 +33,3 @@ export default function appReducer (state = initialState, action = {}) { return state; } } - diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/IconBubbles.js b/server/sonar-web/src/main/js/apps/component-measures/components/IconBubbles.js index dd446d46b5b..e2776c7538a 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/IconBubbles.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/IconBubbles.js @@ -19,17 +19,18 @@ */ import React from 'react'; -export default function IconBubbles () { +export default function IconBubbles() { /* eslint max-len: 0 */ return ( - <svg className="measure-tab-icon" - viewBox="0 0 512 448" - fillRule="evenodd" - clipRule="evenodd" - strokeLinejoin="round" - strokeMiterlimit="1.414"> - <path - d="M352 256c52.984 0 96 43.016 96 96s-43.016 96-96 96-96-43.016-96-96 43.016-96 96-96zM128 96c70.645 0 128 57.355 128 128 0 70.645-57.355 128-128 128C57.355 352 0 294.645 0 224 0 153.355 57.355 96 128 96zM352 0c52.984 0 96 43.016 96 96s-43.016 96-96 96-96-43.016-96-96 43.016-96 96-96z"/> - </svg> + <svg + className="measure-tab-icon" + viewBox="0 0 512 448" + fillRule="evenodd" + clipRule="evenodd" + strokeLinejoin="round" + strokeMiterlimit="1.414" + > + <path d="M352 256c52.984 0 96 43.016 96 96s-43.016 96-96 96-96-43.016-96-96 43.016-96 96-96zM128 96c70.645 0 128 57.355 128 128 0 70.645-57.355 128-128 128C57.355 352 0 294.645 0 224 0 153.355 57.355 96 128 96zM352 0c52.984 0 96 43.016 96 96s-43.016 96-96 96-96-43.016-96-96 43.016-96 96-96z" /> + </svg> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/IconHistory.js b/server/sonar-web/src/main/js/apps/component-measures/components/IconHistory.js index 0e2abcf2ded..ae09eda5adc 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/IconHistory.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/IconHistory.js @@ -19,17 +19,18 @@ */ import React from 'react'; -export default function IconHistory () { +export default function IconHistory() { /* eslint max-len: 0 */ return ( - <svg className="measure-tab-icon" - viewBox="0 0 512 448" - fillRule="evenodd" - clipRule="evenodd" - strokeLinejoin="round" - strokeMiterlimit="1.414"> - <path - d="M512 384v32H0V32h32v352h480zM480 72v108.75q0 5.25-4.875 7.375t-8.875-1.875L436 156 277.75 314.25q-2.5 2.5-5.75 2.5t-5.75-2.5L208 256 104 360l-48-48 146.25-146.25q2.5-2.5 5.75-2.5t5.75 2.5L272 224l116-116-30.25-30.25q-4-4-1.875-8.875T363.25 64H472q3.5 0 5.75 2.25T480 72z"/> - </svg> + <svg + className="measure-tab-icon" + viewBox="0 0 512 448" + fillRule="evenodd" + clipRule="evenodd" + strokeLinejoin="round" + strokeMiterlimit="1.414" + > + <path d="M512 384v32H0V32h32v352h480zM480 72v108.75q0 5.25-4.875 7.375t-8.875-1.875L436 156 277.75 314.25q-2.5 2.5-5.75 2.5t-5.75-2.5L208 256 104 360l-48-48 146.25-146.25q2.5-2.5 5.75-2.5t5.75 2.5L272 224l116-116-30.25-30.25q-4-4-1.875-8.875T363.25 64H472q3.5 0 5.75 2.25T480 72z" /> + </svg> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/IconList.js b/server/sonar-web/src/main/js/apps/component-measures/components/IconList.js index 6a37c1f3f77..973f0521938 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/IconList.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/IconList.js @@ -19,17 +19,18 @@ */ import React from 'react'; -export default function ListIcon () { +export default function ListIcon() { /* eslint max-len: 0 */ return ( - <svg className="measure-tab-icon" - viewBox="0 0 448 448" - fillRule="evenodd" - clipRule="evenodd" - strokeLinejoin="round" - strokeMiterlimit="1.414"> - <path - d="M448 48c0-8.83-7.17-16-16-16H16C7.17 32 0 39.17 0 48v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16V48zM448 144c0-8.83-7.17-16-16-16H16c-8.83 0-16 7.17-16 16v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16v-32zM448 240c0-8.83-7.17-16-16-16H16c-8.83 0-16 7.17-16 16v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16v-32zM448 336.03c0-8.83-7.17-16-16-16H16c-8.83 0-16 7.17-16 16v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16v-32z"/> - </svg> + <svg + className="measure-tab-icon" + viewBox="0 0 448 448" + fillRule="evenodd" + clipRule="evenodd" + strokeLinejoin="round" + strokeMiterlimit="1.414" + > + <path d="M448 48c0-8.83-7.17-16-16-16H16C7.17 32 0 39.17 0 48v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16V48zM448 144c0-8.83-7.17-16-16-16H16c-8.83 0-16 7.17-16 16v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16v-32zM448 240c0-8.83-7.17-16-16-16H16c-8.83 0-16 7.17-16 16v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16v-32zM448 336.03c0-8.83-7.17-16-16-16H16c-8.83 0-16 7.17-16 16v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16v-32z" /> + </svg> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/IconTree.js b/server/sonar-web/src/main/js/apps/component-measures/components/IconTree.js index 3401c56b158..3a3a1ca95ab 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/IconTree.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/IconTree.js @@ -19,17 +19,18 @@ */ import React from 'react'; -export default function IconTree () { +export default function IconTree() { /* eslint max-len: 0 */ return ( - <svg className="measure-tab-icon" - viewBox="0 0 448 448" - fillRule="evenodd" - clipRule="evenodd" - strokeLinejoin="round" - strokeMiterlimit="1.414"> - <path - d="M448 48c0-8.83-7.17-16-16-16H16C7.17 32 0 39.17 0 48v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16V48zM448 144c0-8.83-6.146-16-13.714-16H77.714C70.144 128 64 135.17 64 144v32c0 8.83 6.145 16 13.714 16h356.572c7.568 0 13.714-7.17 13.714-16v-32zM448 240c0-8.83-5.12-16-11.428-16H139.428C133.12 224 128 231.17 128 240v32c0 8.83 5.12 16 11.428 16h297.144c6.307 0 11.428-7.17 11.428-16v-32zM448 336.03c0-8.83-4.097-16-9.142-16H201.143c-5.046 0-9.143 7.17-9.143 16v32c0 8.83 4.097 16 9.143 16h237.715c5.045 0 9.142-7.17 9.142-16v-32z"/> - </svg> + <svg + className="measure-tab-icon" + viewBox="0 0 448 448" + fillRule="evenodd" + clipRule="evenodd" + strokeLinejoin="round" + strokeMiterlimit="1.414" + > + <path d="M448 48c0-8.83-7.17-16-16-16H16C7.17 32 0 39.17 0 48v32c0 8.83 7.17 16 16 16h416c8.83 0 16-7.17 16-16V48zM448 144c0-8.83-6.146-16-13.714-16H77.714C70.144 128 64 135.17 64 144v32c0 8.83 6.145 16 13.714 16h356.572c7.568 0 13.714-7.17 13.714-16v-32zM448 240c0-8.83-5.12-16-11.428-16H139.428C133.12 224 128 231.17 128 240v32c0 8.83 5.12 16 11.428 16h297.144c6.307 0 11.428-7.17 11.428-16v-32zM448 336.03c0-8.83-4.097-16-9.142-16H201.143c-5.046 0-9.143 7.17-9.143 16v32c0 8.83 4.097 16 9.143 16h237.715c5.045 0 9.142-7.17 9.142-16v-32z" /> + </svg> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/IconTreemap.js b/server/sonar-web/src/main/js/apps/component-measures/components/IconTreemap.js index 52a015602b9..9e7ee089dfd 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/IconTreemap.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/IconTreemap.js @@ -19,15 +19,17 @@ */ import React from 'react'; -export default function IconTreemap () { +export default function IconTreemap() { return ( - <svg className="measure-tab-icon" - viewBox="0 0 448 448" - fillRule="evenodd" - clipRule="evenodd" - strokeLinejoin="round" - strokeMiterlimit="1.414"> - <path d="M0 0h224v448H0zM256 0h192v256H256zM256 288h192v160H256z"/> - </svg> + <svg + className="measure-tab-icon" + viewBox="0 0 448 448" + fillRule="evenodd" + clipRule="evenodd" + strokeLinejoin="round" + strokeMiterlimit="1.414" + > + <path d="M0 0h224v448H0zM256 0h192v256H256zM256 288h192v160H256z" /> + </svg> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.js b/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.js index 9de244b9797..c437c474e93 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.js @@ -30,13 +30,13 @@ const LeakPeriodLegend = ({ period }) => { const tooltip = fromNow + ', ' + moment(date).format('LL'); return ( - <TooltipsContainer> - <div className="measures-domains-leak-header"> - <div title={tooltip} data-toggle="tooltip"> - {translateWithParameters('overview.leak_period_x', label)} - </div> + <TooltipsContainer> + <div className="measures-domains-leak-header"> + <div title={tooltip} data-toggle="tooltip"> + {translateWithParameters('overview.leak_period_x', label)} </div> - </TooltipsContainer> + </div> + </TooltipsContainer> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/Measure.js b/server/sonar-web/src/main/js/apps/component-measures/components/Measure.js index c19f3aa3508..31f66a71fdb 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/Measure.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/Measure.js @@ -30,27 +30,27 @@ export default class Measure extends React.Component { metric: React.PropTypes.object }; - renderRating (measure, metric) { + renderRating(measure, metric) { const value = isDiffMetric(metric) ? measure.leak : measure.value; const tooltip = getRatingTooltip(metric.key, value); - const rating = <Rating value={value}/>; + const rating = <Rating value={value} />; if (tooltip) { return ( - <TooltipsContainer> - <span> - <span title={tooltip} data-toggle="tooltip"> - {rating} - </span> + <TooltipsContainer> + <span> + <span title={tooltip} data-toggle="tooltip"> + {rating} </span> - </TooltipsContainer> + </span> + </TooltipsContainer> ); } return rating; } - render () { + render() { const { measure, metric } = this.props; const finalMetric = metric || measure.metric; @@ -59,17 +59,17 @@ export default class Measure extends React.Component { } if (finalMetric.type === 'LEVEL') { - return <Level level={measure.value}/>; + return <Level level={measure.value} />; } - const formattedValue = isDiffMetric(finalMetric) ? - formatLeak(measure.leak, finalMetric) : - formatMeasure(measure.value, finalMetric.type); + const formattedValue = isDiffMetric(finalMetric) + ? formatLeak(measure.leak, finalMetric) + : formatMeasure(measure.value, finalMetric.type); return ( - <span> - {formattedValue != null ? formattedValue : '–'} - </span> + <span> + {formattedValue != null ? formattedValue : '–'} + </span> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/Spinner.js b/server/sonar-web/src/main/js/apps/component-measures/components/Spinner.js index 0cd810447bf..3f899ac3b4f 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/Spinner.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/Spinner.js @@ -19,8 +19,6 @@ */ import React from 'react'; -export default function Spinner () { - return ( - <i className="spinner spinner-margin"/> - ); +export default function Spinner() { + return <i className="spinner spinner-margin" />; } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/BubbleChart.js b/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/BubbleChart.js index 4cd674b7c1f..edf1b0def09 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/BubbleChart.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/BubbleChart.js @@ -30,7 +30,7 @@ import { getLocalizedMetricName, translateWithParameters } from '../../../../hel const HEIGHT = 500; const BUBBLES_LIMIT = 500; -function getMeasure (component, metric) { +function getMeasure(component, metric) { return Number(component.measures[metric]) || 0; } @@ -40,30 +40,30 @@ export default class BubbleChart extends React.Component { files: [] }; - componentWillMount () { + componentWillMount() { this.updateMetrics(this.props); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.fetchFiles(); } - componentWillUpdate (nextProps) { + componentWillUpdate(nextProps) { this.updateMetrics(nextProps); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.domainName !== this.props.domainName) { this.fetchFiles(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - updateMetrics (props) { + updateMetrics(props) { const { metrics, domainName } = props; const conf = bubbles[domainName]; this.xMetric = metrics.find(m => m.key === conf.x); @@ -71,7 +71,7 @@ export default class BubbleChart extends React.Component { this.sizeMetric = metrics.find(m => m.key === conf.size); } - fetchFiles () { + fetchFiles() { const { component } = this.props; const metrics = [this.xMetric.key, this.yMetric.key, this.sizeMetric.key]; const options = { @@ -105,7 +105,7 @@ export default class BubbleChart extends React.Component { }); } - getTooltip (component) { + getTooltip(component) { const inner = [ component.name, `${this.xMetric.name}: ${formatMeasure(getMeasure(component, this.xMetric.key), this.xMetric.type)}`, @@ -116,7 +116,7 @@ export default class BubbleChart extends React.Component { return `<div class="text-left">${inner}</div>`; } - handleBubbleClick (component) { + handleBubbleClick(component) { if (['FIL', 'UTS'].includes(component.qualifier)) { Workspace.openComponent({ key: component.key }); } else { @@ -124,7 +124,7 @@ export default class BubbleChart extends React.Component { } } - renderBubbleChart () { + renderBubbleChart() { const items = this.state.files.map(file => { return { x: getMeasure(file, this.xMetric.key), @@ -139,45 +139,49 @@ export default class BubbleChart extends React.Component { const formatYTick = tick => formatMeasure(tick, this.yMetric.type); return ( - <OriginalBubbleChart - items={items} - height={HEIGHT} - padding={[25, 60, 50, 60]} - formatXTick={formatXTick} - formatYTick={formatYTick} - onBubbleClick={this.handleBubbleClick.bind(this)}/> + <OriginalBubbleChart + items={items} + height={HEIGHT} + padding={[25, 60, 50, 60]} + formatXTick={formatXTick} + formatYTick={formatYTick} + onBubbleClick={this.handleBubbleClick.bind(this)} + /> ); } - render () { + render() { const { fetching } = this.state; if (fetching) { return ( - <div className="measure-details-bubble-chart"> - <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> - <Spinner/> - </div> + <div className="measure-details-bubble-chart"> + <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> + <Spinner /> </div> + </div> ); } return ( - <div className="measure-details-bubble-chart"> - <div> - {this.renderBubbleChart()} - </div> + <div className="measure-details-bubble-chart"> + <div> + {this.renderBubbleChart()} + </div> - <div className="measure-details-bubble-chart-axis x"> - {getLocalizedMetricName(this.xMetric)} - </div> - <div className="measure-details-bubble-chart-axis y"> - {getLocalizedMetricName(this.yMetric)} - </div> - <div className="measure-details-bubble-chart-axis size"> - {translateWithParameters('component_measures.legend.size_x', getLocalizedMetricName(this.sizeMetric))} - </div> + <div className="measure-details-bubble-chart-axis x"> + {getLocalizedMetricName(this.xMetric)} + </div> + <div className="measure-details-bubble-chart-axis y"> + {getLocalizedMetricName(this.yMetric)} + </div> + <div className="measure-details-bubble-chart-axis size"> + {translateWithParameters( + 'component_measures.legend.size_x', + getLocalizedMetricName(this.sizeMetric) + )} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/MeasureBubbleChartContainer.js b/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/MeasureBubbleChartContainer.js index edaea8a2855..bc9741bed87 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/MeasureBubbleChartContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/bubbleChart/MeasureBubbleChartContainer.js @@ -32,7 +32,4 @@ const mapDispatchToProps = () => { return {}; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(MeasureBubbleChart); +export default connect(mapStateToProps, mapDispatchToProps)(MeasureBubbleChart); diff --git a/server/sonar-web/src/main/js/apps/component-measures/config/bubbles.js b/server/sonar-web/src/main/js/apps/component-measures/config/bubbles.js index c69c6798776..28407f56dc5 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/config/bubbles.js +++ b/server/sonar-web/src/main/js/apps/component-measures/config/bubbles.js @@ -18,11 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ const bubblesConfig = { - 'Reliability': { x: 'ncloc', y: 'reliability_remediation_effort', size: 'bugs' }, - 'Security': { x: 'ncloc', y: 'security_remediation_effort', size: 'vulnerabilities' }, - 'Maintainability': { x: 'ncloc', y: 'sqale_index', size: 'code_smells' }, - 'Coverage': { x: 'complexity', y: 'coverage', size: 'uncovered_lines' }, - 'Duplications': { x: 'ncloc', y: 'duplicated_lines', size: 'duplicated_blocks' } + Reliability: { x: 'ncloc', y: 'reliability_remediation_effort', size: 'bugs' }, + Security: { x: 'ncloc', y: 'security_remediation_effort', size: 'vulnerabilities' }, + Maintainability: { x: 'ncloc', y: 'sqale_index', size: 'code_smells' }, + Coverage: { x: 'complexity', y: 'coverage', size: 'uncovered_lines' }, + Duplications: { x: 'ncloc', y: 'duplicated_lines', size: 'duplicated_blocks' } }; export default bubblesConfig; diff --git a/server/sonar-web/src/main/js/apps/component-measures/config/complementary.js b/server/sonar-web/src/main/js/apps/component-measures/config/complementary.js index 30af2c252d8..46340a2cd23 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/config/complementary.js +++ b/server/sonar-web/src/main/js/apps/component-measures/config/complementary.js @@ -18,20 +18,20 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ export default { - 'coverage': ['uncovered_lines', 'uncovered_conditions'], - 'line_coverage': ['uncovered_lines'], - 'branch_coverage': ['uncovered_conditions'], - 'uncovered_lines': ['line_coverage'], - 'uncovered_conditions': ['branch_coverage'], + coverage: ['uncovered_lines', 'uncovered_conditions'], + line_coverage: ['uncovered_lines'], + branch_coverage: ['uncovered_conditions'], + uncovered_lines: ['line_coverage'], + uncovered_conditions: ['branch_coverage'], - 'new_coverage': ['new_uncovered_lines', 'new_uncovered_conditions'], - 'new_line_coverage': ['new_uncovered_lines'], - 'new_branch_coverage': ['new_uncovered_conditions'], - 'new_uncovered_lines': ['new_line_coverage'], - 'new_uncovered_conditions': ['new_branch_coverage'], + new_coverage: ['new_uncovered_lines', 'new_uncovered_conditions'], + new_line_coverage: ['new_uncovered_lines'], + new_branch_coverage: ['new_uncovered_conditions'], + new_uncovered_lines: ['new_line_coverage'], + new_uncovered_conditions: ['new_branch_coverage'], - 'duplicated_lines_density': ['duplicated_lines'], - 'new_duplicated_lines_density': ['new_duplicated_lines'], - 'duplicated_lines': ['duplicated_lines_density'], - 'new_duplicated_lines': ['new_duplicated_lines_density'] + duplicated_lines_density: ['duplicated_lines'], + new_duplicated_lines_density: ['new_duplicated_lines'], + duplicated_lines: ['duplicated_lines_density'], + new_duplicated_lines: ['new_duplicated_lines_density'] }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/config/domains.js b/server/sonar-web/src/main/js/apps/component-measures/config/domains.js index 26a5a589df4..6ac6a6975c2 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/config/domains.js +++ b/server/sonar-web/src/main/js/apps/component-measures/config/domains.js @@ -18,12 +18,8 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ export const domains = { - 'Reliability': { - main: [ - 'bugs', - 'new_bugs', - 'reliability_rating' - ], + Reliability: { + main: ['bugs', 'new_bugs', 'reliability_rating'], order: [ 'bugs', 'new_bugs', @@ -33,12 +29,8 @@ export const domains = { ] }, - 'Security': { - main: [ - 'vulnerabilities', - 'new_vulnerabilities', - 'security_rating' - ], + Security: { + main: ['vulnerabilities', 'new_vulnerabilities', 'security_rating'], order: [ 'vulnerabilities', 'new_vulnerabilities', @@ -48,12 +40,8 @@ export const domains = { ] }, - 'Maintainability': { - main: [ - 'code_smells', - 'new_code_smells', - 'sqale_rating' - ], + Maintainability: { + main: ['code_smells', 'new_code_smells', 'sqale_rating'], order: [ 'code_smells', 'new_code_smells', @@ -66,12 +54,8 @@ export const domains = { ] }, - 'Coverage': { - main: [ - 'coverage', - 'new_coverage', - 'tests' - ], + Coverage: { + main: ['coverage', 'new_coverage', 'tests'], order: [ 'coverage', 'new_coverage', @@ -97,11 +81,8 @@ export const domains = { ] }, - 'Duplications': { - main: [ - 'duplicated_lines_density', - 'new_duplicated_lines_density' - ], + Duplications: { + main: ['duplicated_lines_density', 'new_duplicated_lines_density'], order: [ 'duplicated_lines_density', 'new_duplicated_lines_density', @@ -113,10 +94,8 @@ export const domains = { ] }, - 'Size': { - main: [ - 'ncloc' - ], + Size: { + main: ['ncloc'], order: [ 'ncloc', 'lines', @@ -129,33 +108,18 @@ export const domains = { ] }, - 'Complexity': { - main: [ - 'complexity' - ], - order: [ - 'complexity', - 'function_complexity', - 'file_complexity', - 'class_complexity' - ] + Complexity: { + main: ['complexity'], + order: ['complexity', 'function_complexity', 'file_complexity', 'class_complexity'] }, - 'Releasability': { - main: [ - 'alert_status', - 'releasability_rating' - ], - order: [ - 'alert_status' - ] + Releasability: { + main: ['alert_status', 'releasability_rating'], + order: ['alert_status'] }, - 'Issues': { - main: [ - 'violations', - 'new_violations' - ], + Issues: { + main: ['violations', 'new_violations'], order: [ 'violations', 'new_violations', diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetails.js b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetails.js index 53309e403b1..41855bcc6db 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetails.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetails.js @@ -33,50 +33,52 @@ export default class MeasureDetails extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadData(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.params.metricKey !== this.props.params.metricKey) { this.loadData(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - metricExists (): boolean { + metricExists(): boolean { const { metrics } = this.props; const { metricKey } = this.props.params; const metric = metrics.find(metric => metric.key === metricKey); return !!metric; } - loadData () { + loadData() { if (this.metricExists()) { this.setState({ loading: true }); const periodIndex = this.props.location.query.period || 1; const onLoaded = () => this.mounted && this.setState({ loading: false }); - this.props.fetchMeasure(this.props.params.metricKey, Number(periodIndex)).then(onLoaded, onLoaded); + this.props + .fetchMeasure(this.props.params.metricKey, Number(periodIndex)) + .then(onLoaded, onLoaded); } } - render () { + render() { if (!this.metricExists()) { - return <MetricNotFound/>; + return <MetricNotFound />; } if (this.state.loading) { - return <Spinner/>; + return <Spinner />; } const { component, metric, secondaryMeasure, measure, periods, children } = this.props; if (!measure) { - return <MetricNotFound/>; + return <MetricNotFound />; } const { tab } = this.props.params; @@ -85,43 +87,48 @@ export default class MeasureDetails extends React.Component { const periodDate = getPeriodDate(period); return ( - <section id="component-measures-details" className="page page-container page-limited"> - <div className="note"> - <IndexLink - to={{ pathname: '/component_measures', query: { id: component.key } }} - id="component-measures-back-to-all-measures" - className="text-muted"> - {translate('component_measures.all_measures')} - </IndexLink> - {!!metric.domain && ( - <span> - {' / '} - <Link - to={{ pathname: `/component_measures/domain/${metric.domain}`, query: { id: component.key } }} - className="text-muted"> - {translateWithParameters('component_measures.domain_measures', metric.domain)} - </Link> - </span> - )} - </div> + <section id="component-measures-details" className="page page-container page-limited"> + <div className="note"> + <IndexLink + to={{ pathname: '/component_measures', query: { id: component.key } }} + id="component-measures-back-to-all-measures" + className="text-muted" + > + {translate('component_measures.all_measures')} + </IndexLink> + {!!metric.domain && + <span> + {' / '} + <Link + to={{ + pathname: `/component_measures/domain/${metric.domain}`, + query: { id: component.key } + }} + className="text-muted" + > + {translateWithParameters('component_measures.domain_measures', metric.domain)} + </Link> + </span>} + </div> - <MeasureDetailsHeader - measure={measure} - metric={metric} - secondaryMeasure={secondaryMeasure} - leakPeriod={period}/> + <MeasureDetailsHeader + measure={measure} + metric={metric} + secondaryMeasure={secondaryMeasure} + leakPeriod={period} + /> - {measure && ( - <MeasureDrilldown - component={component} - metric={metric} - tab={tab} - leakPeriod={period} - leakPeriodDate={periodDate}> - {children} - </MeasureDrilldown> - )} - </section> + {measure && + <MeasureDrilldown + component={component} + metric={metric} + tab={tab} + leakPeriod={period} + leakPeriodDate={periodDate} + > + {children} + </MeasureDrilldown>} + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsContainer.js b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsContainer.js index 604aa4c3c6d..7ae39057181 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsContainer.js @@ -42,7 +42,4 @@ const mapStateToProps = state => { const mapDispatchToProps = { fetchMeasure }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(MeasureDetails); +export default connect(mapStateToProps, mapDispatchToProps)(MeasureDetails); diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js index 0009c3dcfcb..d3cdb27ff1a 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js @@ -27,52 +27,49 @@ import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin'; import { getLocalizedMetricName } from '../../../helpers/l10n'; import IssueTypeIcon from '../../../components/ui/IssueTypeIcon'; -export default function MeasureDetailsHeader ({ measure, metric, secondaryMeasure, leakPeriod }) { +export default function MeasureDetailsHeader({ measure, metric, secondaryMeasure, leakPeriod }) { return ( - <header className="measure-details-header"> - <h2 className="measure-details-metric"> - <IssueTypeIcon query={metric.key} className="little-spacer-right"/> - {getLocalizedMetricName(metric)} - </h2> + <header className="measure-details-header"> + <h2 className="measure-details-metric"> + <IssueTypeIcon query={metric.key} className="little-spacer-right" /> + {getLocalizedMetricName(metric)} + </h2> - {isDiffMetric(metric) && ( - <div className="pull-right"> - <LeakPeriodLegend period={leakPeriod}/> - </div> - )} + {isDiffMetric(metric) && + <div className="pull-right"> + <LeakPeriodLegend period={leakPeriod} /> + </div>} - <TooltipsContainer options={{ html: false }}> - <div className="measure-details-value"> + <TooltipsContainer options={{ html: false }}> + <div className="measure-details-value"> - {isDiffMetric(metric) ? ( - <div className="measure-details-value-leak"> - <Measure measure={measure} metric={metric}/> - </div> - ) : ( - <div className="measure-details-value-absolute"> - <Measure measure={measure} metric={metric}/> - </div> - )} + {isDiffMetric(metric) + ? <div className="measure-details-value-leak"> + <Measure measure={measure} metric={metric} /> + </div> + : <div className="measure-details-value-absolute"> + <Measure measure={measure} metric={metric} /> + </div>} - {secondaryMeasure && secondaryMeasure.metric === 'ncloc_language_distribution' && ( - <div className="measure-details-secondary"> - <LanguageDistribution distribution={secondaryMeasure.value}/> - </div> - )} + {secondaryMeasure && + secondaryMeasure.metric === 'ncloc_language_distribution' && + <div className="measure-details-secondary"> + <LanguageDistribution distribution={secondaryMeasure.value} /> + </div>} - {secondaryMeasure && secondaryMeasure.metric === 'function_complexity_distribution' && ( - <div className="measure-details-secondary"> - <ComplexityDistribution distribution={secondaryMeasure.value} of="function"/> - </div> - )} + {secondaryMeasure && + secondaryMeasure.metric === 'function_complexity_distribution' && + <div className="measure-details-secondary"> + <ComplexityDistribution distribution={secondaryMeasure.value} of="function" /> + </div>} - {secondaryMeasure && secondaryMeasure.metric === 'file_complexity_distribution' && ( - <div className="measure-details-secondary"> - <ComplexityDistribution distribution={secondaryMeasure.value} of="file"/> - </div> - )} - </div> - </TooltipsContainer> - </header> + {secondaryMeasure && + secondaryMeasure.metric === 'file_complexity_distribution' && + <div className="measure-details-secondary"> + <ComplexityDistribution distribution={secondaryMeasure.value} of="file" /> + </div>} + </div> + </TooltipsContainer> + </header> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/MetricNotFound.js b/server/sonar-web/src/main/js/apps/component-measures/details/MetricNotFound.js index f9ab4446a9e..f16edc1f4d5 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/MetricNotFound.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/MetricNotFound.js @@ -22,13 +22,13 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class MetricNotFound extends React.Component { - render () { + render() { return ( - <div className="page page-limited"> - <div className="alert alert-danger"> - {translate('component_measures.not_found')} - </div> + <div className="page page-limited"> + <div className="alert alert-danger"> + {translate('component_measures.not_found')} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/actions.js b/server/sonar-web/src/main/js/apps/component-measures/details/actions.js index 8c858bad657..55579349c01 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/actions.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/actions.js @@ -32,11 +32,11 @@ export const RECEIVE_MEASURE = 'measuresApp/details/RECEIVE_MEASURE'; * Action Creators */ -function requestMeasure (metric) { +function requestMeasure(metric) { return { type: REQUEST_MEASURE, metric }; } -function receiveMeasure (measure, secondaryMeasure, periods) { +function receiveMeasure(measure, secondaryMeasure, periods) { return { type: RECEIVE_MEASURE, measure, secondaryMeasure, periods }; } @@ -44,7 +44,7 @@ function receiveMeasure (measure, secondaryMeasure, periods) { * Workflow */ -export function fetchMeasure (metricKey, periodIndex = 1) { +export function fetchMeasure(metricKey, periodIndex = 1) { return (dispatch, getState) => { const state = getState(); const component = getMeasuresAppComponent(state); @@ -64,11 +64,9 @@ export function fetchMeasure (metricKey, periodIndex = 1) { const metric = metrics.find(m => m.key === metricKey); dispatch(requestMeasure(metric)); - return getMeasuresAndMeta( - component.key, - metricsToRequest, - { additionalFields: 'periods' } - ).then(r => { + return getMeasuresAndMeta(component.key, metricsToRequest, { + additionalFields: 'periods' + }).then(r => { const measures = enhanceWithLeak(r.component.measures, periodIndex); const measure = measures.find(m => m.metric === metricKey); const secondaryMeasure = measures.find(m => m.metric !== metricKey); diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumb.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumb.js index 0b01b71baeb..03d857462bf 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumb.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumb.js @@ -32,30 +32,25 @@ const Breadcrumb = ({ component, metric, onBrowse }) => { let inner; if (onBrowse) { inner = ( - <a - id={'component-measures-breadcrumb-' + component.key} - href="#" - onClick={handleClick}> - {component.name} - </a> + <a id={'component-measures-breadcrumb-' + component.key} href="#" onClick={handleClick}> + {component.name} + </a> ); } else { inner = <span>{component.name}</span>; } - const value = isDiffMetric(metric) ? - formatLeak(component.leak, metric) : - formatMeasure(component.value, metric.type); + const value = isDiffMetric(metric) + ? formatLeak(component.leak, metric) + : formatMeasure(component.value, metric.type); return ( - <span> - <QualifierIcon qualifier={component.qualifier}/> - - {inner} - {value != null && ( - <span>{' (' + value + ')'}</span> - )} - </span> + <span> + <QualifierIcon qualifier={component.qualifier} /> + + {inner} + {value != null && <span>{' (' + value + ')'}</span>} + </span> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumbs.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumbs.js index eddfe8d319b..7bc20340cd4 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumbs.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/Breadcrumbs.js @@ -21,16 +21,17 @@ import React from 'react'; import Breadcrumb from './Breadcrumb'; const Breadcrumbs = ({ breadcrumbs, metric, onBrowse }) => ( - <ul className="component-measures-breadcrumbs"> - {breadcrumbs.map((component, index) => ( - <li key={component.key}> - <Breadcrumb - component={component} - metric={metric} - onBrowse={index + 1 < breadcrumbs.length ? onBrowse : null}/> - </li> - ))} - </ul> + <ul className="component-measures-breadcrumbs"> + {breadcrumbs.map((component, index) => ( + <li key={component.key}> + <Breadcrumb + component={component} + metric={metric} + onBrowse={index + 1 < breadcrumbs.length ? onBrowse : null} + /> + </li> + ))} + </ul> ); export default Breadcrumbs; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentCell.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentCell.js index b2446c30e55..e3e7969da17 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentCell.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentCell.js @@ -25,7 +25,7 @@ import { getComponentUrl } from '../../../../helpers/urls'; const ComponentCell = ({ component, isSelected, onClick }) => { const linkClassName = classNames('link-no-underline', { - 'selected': isSelected + selected: isSelected }); const handleClick = e => { @@ -48,41 +48,46 @@ const ComponentCell = ({ component, isSelected, onClick }) => { } const inner = ( - <span title={component.refKey || component.key}> - <QualifierIcon qualifier={component.qualifier}/> - - {head.length > 0 && ( - <span className="note">{head}/</span> - )} - <span>{tail}</span> - </span> + <span title={component.refKey || component.key}> + <QualifierIcon qualifier={component.qualifier} /> + + {head.length > 0 && <span className="note">{head}/</span>} + <span>{tail}</span> + </span> ); return ( - <td style={{ maxWidth: 0 }}> - <div style={{ maxWidth: '100%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}> - {(component.refId == null || component.qualifier === 'DEV_PRJ') ? ( - <a - id={'component-measures-component-link-' + component.key} - className={linkClassName} - href={getComponentUrl(component.key)} - onClick={handleClick}> - {inner} - </a> - ) : ( - <a - id={'component-measures-component-link-' + component.key} - className={linkClassName} - href={getComponentUrl(component.refKey || component.key)}> - <span className="big-spacer-right"> - <i className="icon-detach"/> - </span> + <td style={{ maxWidth: 0 }}> + <div + style={{ + maxWidth: '100%', + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis' + }} + > + {component.refId == null || component.qualifier === 'DEV_PRJ' + ? <a + id={'component-measures-component-link-' + component.key} + className={linkClassName} + href={getComponentUrl(component.key)} + onClick={handleClick} + > + {inner} + </a> + : <a + id={'component-measures-component-link-' + component.key} + className={linkClassName} + href={getComponentUrl(component.refKey || component.key)} + > + <span className="big-spacer-right"> + <i className="icon-detach" /> + </span> - {inner} - </a> - )} - </div> - </td> + {inner} + </a>} + </div> + </td> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsList.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsList.js index 71a6ddf5e9d..7acaeb62890 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsList.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsList.js @@ -25,7 +25,7 @@ import { getLocalizedMetricName } from '../../../../helpers/l10n'; const ComponentsList = ({ components, metrics, selected, metric, onClick }) => { if (!components.length) { - return <EmptyComponentsList/>; + return <EmptyComponentsList />; } const otherMetrics = (complementary[metric.key] || []).map(metric => { @@ -33,35 +33,35 @@ const ComponentsList = ({ components, metrics, selected, metric, onClick }) => { }); return ( - <table className="data zebra zebra-hover"> - {otherMetrics.length > 0 && ( - <thead> - <tr> - <th> </th> - <th className="text-right"> - <span className="small">{getLocalizedMetricName(metric)}</span> - </th> - {otherMetrics.map(metric => ( - <th key={metric.key} className="text-right"> - <span className="small">{getLocalizedMetricName(metric)}</span> - </th> - ))} - </tr> - </thead> - )} + <table className="data zebra zebra-hover"> + {otherMetrics.length > 0 && + <thead> + <tr> + <th> </th> + <th className="text-right"> + <span className="small">{getLocalizedMetricName(metric)}</span> + </th> + {otherMetrics.map(metric => ( + <th key={metric.key} className="text-right"> + <span className="small">{getLocalizedMetricName(metric)}</span> + </th> + ))} + </tr> + </thead>} - <tbody> - {components.map(component => ( - <ComponentsListRow - key={component.id} - component={component} - otherMetrics={otherMetrics} - isSelected={component === selected} - metric={metric} - onClick={onClick}/> - ))} - </tbody> - </table> + <tbody> + {components.map(component => ( + <ComponentsListRow + key={component.id} + component={component} + otherMetrics={otherMetrics} + isSelected={component === selected} + metric={metric} + onClick={onClick} + /> + ))} + </tbody> + </table> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsListRow.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsListRow.js index 4c4afc18b01..ca2f51c96a4 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsListRow.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ComponentsListRow.js @@ -40,23 +40,23 @@ const ComponentsListRow = ({ component, otherMetrics, isSelected, metric, onClic }); return ( - <tr> - <ComponentCell - component={component} - isSelected={isSelected} - onClick={handleClick.bind(this, component)}/> + <tr> + <ComponentCell + component={component} + isSelected={isSelected} + onClick={handleClick.bind(this, component)} + /> - <MeasureCell - component={component} - metric={metric}/> + <MeasureCell component={component} metric={metric} /> - {otherMeasures.map(measure => ( - <MeasureCell - key={measure.metric.key} - component={replaceMeasure(component, measure)} - metric={measure.metric}/> - ))} - </tr> + {otherMeasures.map(measure => ( + <MeasureCell + key={measure.metric.key} + component={replaceMeasure(component, measure)} + metric={measure.metric} + /> + ))} + </tr> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/EmptyComponentsList.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/EmptyComponentsList.js index 4045cb3eb19..be032c05ce0 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/EmptyComponentsList.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/EmptyComponentsList.js @@ -22,9 +22,9 @@ import { translate } from '../../../../helpers/l10n'; const EmptyComponentsList = () => { return ( - <div className="note"> - {translate('no_results')} - </div> + <div className="note"> + {translate('no_results')} + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListHeader.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListHeader.js index 226f18bd30b..b929bac5d9a 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListHeader.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListHeader.js @@ -34,33 +34,30 @@ const ListHeader = props => { }; return ( - <header className="measure-details-viewer-header"> - {breadcrumbs != null && breadcrumbs.length > 1 && ( - <div className="measure-details-header-container"> - <Breadcrumbs - breadcrumbs={breadcrumbs} - metric={metric} - onBrowse={onBrowse}/> - </div> - )} + <header className="measure-details-viewer-header"> + {breadcrumbs != null && + breadcrumbs.length > 1 && + <div className="measure-details-header-container"> + <Breadcrumbs breadcrumbs={breadcrumbs} metric={metric} onBrowse={onBrowse} /> + </div>} - {selectedIndex != null && selectedIndex !== -1 && ( - <div className="pull-right"> - <span className="note spacer-right"> - {translateWithParameters('component_measures.x_of_y', selectedIndex + 1, componentsCount)} - </span> + {selectedIndex != null && + selectedIndex !== -1 && + <div className="pull-right"> + <span className="note spacer-right"> + {translateWithParameters( + 'component_measures.x_of_y', + selectedIndex + 1, + componentsCount + )} + </span> - <div className="button-group"> - {hasPrevious && ( - <button onClick={blur(onSelectPrevious)}><</button> - )} - {hasNext && ( - <button onClick={blur(onSelectNext)}>></button> - )} - </div> - </div> - )} - </header> + <div className="button-group"> + {hasPrevious && <button onClick={blur(onSelectPrevious)}><</button>} + {hasNext && <button onClick={blur(onSelectNext)}>></button>} + </div> + </div>} + </header> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListView.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListView.js index 6f52f65713e..b6d5f03ca38 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListView.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListView.js @@ -31,7 +31,7 @@ export default class ListView extends React.Component { router: React.PropTypes.object.isRequired }; - componentDidMount () { + componentDidMount() { const { component, metric } = this.props; if (component.qualifier === 'DEV') { const { router } = this.context; @@ -40,7 +40,7 @@ export default class ListView extends React.Component { this.handleChangeBaseComponent(component); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.metric !== this.props.metric) { this.handleChangeBaseComponent(this.props.component); } @@ -52,7 +52,7 @@ export default class ListView extends React.Component { } } - scrollToViewer () { + scrollToViewer() { const { container } = this.refs; const top = container.getBoundingClientRect().top + window.scrollY - 95 - 10; @@ -62,41 +62,50 @@ export default class ListView extends React.Component { } } - scrollToStoredPosition () { + scrollToStoredPosition() { window.scrollTo(0, this.scrollTop); this.scrollTop = null; } - storeScrollPosition () { + storeScrollPosition() { this.scrollTop = window.scrollY; } - handleChangeBaseComponent (baseComponent) { + handleChangeBaseComponent(baseComponent) { const { metric, onFetchList } = this.props; const periodIndex = this.props.location.query.period || 1; onFetchList(baseComponent, metric, Number(periodIndex)); } - handleFetchMore () { + handleFetchMore() { const periodIndex = this.props.location.query.period || 1; this.props.onFetchMore(Number(periodIndex)); } - changeSelected (selected) { + changeSelected(selected) { this.props.onSelect(selected); } - handleClick (selected) { + handleClick(selected) { this.storeScrollPosition(); this.props.onSelect(selected); } - handleBreadcrumbClick () { + handleBreadcrumbClick() { this.props.onSelect(undefined); } - render () { - const { component, components, metrics, metric, leakPeriod, selected, total, fetching } = this.props; + render() { + const { + component, + components, + metrics, + metric, + leakPeriod, + selected, + total, + fetching + } = this.props; const { onSelectNext, onSelectPrevious } = this.props; const breadcrumbs = [component]; @@ -105,57 +114,58 @@ export default class ListView extends React.Component { } const selectedIndex = components.indexOf(selected); const sourceViewerPeriod = metric.key.indexOf('new_') === 0 && !!leakPeriod ? leakPeriod : null; - const sourceViewerPeriodDate = sourceViewerPeriod != null ? moment(sourceViewerPeriod.date).toDate() : null; - - const filterLine = sourceViewerPeriodDate != null ? line => { - if (line.scmDate) { - const scmDate = moment(line.scmDate).toDate(); - return scmDate >= sourceViewerPeriodDate; - } else { - return false; - } - } : undefined; + const sourceViewerPeriodDate = sourceViewerPeriod != null + ? moment(sourceViewerPeriod.date).toDate() + : null; + + const filterLine = sourceViewerPeriodDate != null + ? line => { + if (line.scmDate) { + const scmDate = moment(line.scmDate).toDate(); + return scmDate >= sourceViewerPeriodDate; + } else { + return false; + } + } + : undefined; return ( - <div ref="container" className="measure-details-plain-list"> - <ListHeader - metric={metric} - breadcrumbs={breadcrumbs} - componentsCount={components.length} - selectedIndex={selectedIndex} - onSelectPrevious={onSelectPrevious} - onSelectNext={onSelectNext} - onBrowse={this.handleBreadcrumbClick.bind(this)}/> - - {!selected && ( - <div className={classNames({ 'new-loading': fetching })}> - {(!fetching || components.length !== 0) ? ( - <div> - <ComponentsList - components={components} - metrics={metrics} - selected={selected} - metric={metric} - onClick={this.handleClick.bind(this)}/> - <ListFooter - count={components.length} - total={total} - loadMore={this.handleFetchMore.bind(this)}/> - </div> - ) : ( - <Spinner/> - )} - </div> - )} - - {!!selected && ( - <div className="measure-details-viewer"> - <SourceViewer - component={selected.key} - filterLine={filterLine}/> - </div> - )} - </div> + <div ref="container" className="measure-details-plain-list"> + <ListHeader + metric={metric} + breadcrumbs={breadcrumbs} + componentsCount={components.length} + selectedIndex={selectedIndex} + onSelectPrevious={onSelectPrevious} + onSelectNext={onSelectNext} + onBrowse={this.handleBreadcrumbClick.bind(this)} + /> + + {!selected && + <div className={classNames({ 'new-loading': fetching })}> + {!fetching || components.length !== 0 + ? <div> + <ComponentsList + components={components} + metrics={metrics} + selected={selected} + metric={metric} + onClick={this.handleClick.bind(this)} + /> + <ListFooter + count={components.length} + total={total} + loadMore={this.handleFetchMore.bind(this)} + /> + </div> + : <Spinner />} + </div>} + + {!!selected && + <div className="measure-details-viewer"> + <SourceViewer component={selected.key} filterLine={filterLine} /> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListViewContainer.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListViewContainer.js index 3304447f550..bf6b3fc106a 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListViewContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/ListViewContainer.js @@ -19,7 +19,13 @@ */ import { connect } from 'react-redux'; import ListView from './ListView'; -import { fetchList, fetchMore, selectComponent, selectNext, selectPrevious } from '../../store/listViewActions'; +import { + fetchList, + fetchMore, + selectComponent, + selectNext, + selectPrevious +} from '../../store/listViewActions'; import { getMeasuresAppListComponents, getMeasuresAppListSelected, @@ -46,7 +52,8 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { return { - onFetchList: (baseComponent, metric, periodIndex) => dispatch(fetchList(baseComponent, metric, periodIndex)), + onFetchList: (baseComponent, metric, periodIndex) => + dispatch(fetchList(baseComponent, metric, periodIndex)), onFetchMore: periodIndex => dispatch(fetchMore(periodIndex)), onSelect: component => dispatch(selectComponent(component)), onSelectNext: component => dispatch(selectNext(component)), @@ -54,7 +61,4 @@ const mapDispatchToProps = dispatch => { }; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(ListView); +export default connect(mapStateToProps, mapDispatchToProps)(ListView); diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureCell.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureCell.js index db8f608723a..ee236adbb74 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureCell.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureCell.js @@ -22,11 +22,11 @@ import Measure from '../../components/Measure'; const MeasureCell = ({ component, metric }) => { return ( - <td className="thin nowrap text-right"> - <span id={'component-measures-component-measure-' + component.key + '-' + metric.key}> - <Measure measure={{ value: component.value, leak: component.leak }} metric={metric}/> - </span> - </td> + <td className="thin nowrap text-right"> + <span id={'component-measures-component-measure-' + component.key + '-' + metric.key}> + <Measure measure={{ value: component.value, leak: component.leak }} metric={metric} /> + </span> + </td> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureDrilldown.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureDrilldown.js index b3065d65c0f..f934eebd193 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureDrilldown.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/MeasureDrilldown.js @@ -28,79 +28,86 @@ import { hasHistory, hasBubbleChart, hasTreemap } from '../../utils'; import { translate } from '../../../../helpers/l10n'; export default class MeasureDrilldown extends React.Component { - render () { + render() { const { children, component, metric, ...other } = this.props; const child = React.cloneElement(children, { ...other }); return ( - <div className="measure-details-drilldown"> - <ul className="measure-details-drilldown-mode"> - {component.qualifier !== 'DEV' && ( - <li> - <Link - activeClassName="active" - to={{ pathname: `/component_measures/metric/${metric.key}/list`, query: { id: component.key } }}> - <IconList/> - {translate('component_measures.tab.list')} - </Link> - </li> - )} - + <div className="measure-details-drilldown"> + <ul className="measure-details-drilldown-mode"> + {component.qualifier !== 'DEV' && <li> <Link - activeClassName="active" - to={{ pathname: `/component_measures/metric/${metric.key}/tree`, query: { id: component.key } }}> - <IconTree/> - {translate('component_measures.tab.tree')} + activeClassName="active" + to={{ + pathname: `/component_measures/metric/${metric.key}/list`, + query: { id: component.key } + }} + > + <IconList /> + {translate('component_measures.tab.list')} </Link> - </li> + </li>} - {hasBubbleChart(metric.key) && ( - <li> - <Link - activeClassName="active" - to={{ - pathname: `/component_measures/metric/${metric.key}/bubbles`, - query: { id: component.key } - }}> - <IconBubbles/> - {translate('component_measures.tab.bubbles')} - </Link> - </li> - )} + <li> + <Link + activeClassName="active" + to={{ + pathname: `/component_measures/metric/${metric.key}/tree`, + query: { id: component.key } + }} + > + <IconTree /> + {translate('component_measures.tab.tree')} + </Link> + </li> - {hasTreemap(metric) && ( - <li> - <Link - activeClassName="active" - to={{ - pathname: `/component_measures/metric/${metric.key}/treemap`, - query: { id: component.key } - }}> - <IconTreemap/> - {translate('component_measures.tab.treemap')} - </Link> - </li> - )} + {hasBubbleChart(metric.key) && + <li> + <Link + activeClassName="active" + to={{ + pathname: `/component_measures/metric/${metric.key}/bubbles`, + query: { id: component.key } + }} + > + <IconBubbles /> + {translate('component_measures.tab.bubbles')} + </Link> + </li>} - {hasHistory(metric.key) && ( - <li> - <Link - activeClassName="active" - to={{ - pathname: `/component_measures/metric/${metric.key}/history`, - query: { id: component.key } - }}> - <IconHistory/> - {translate('component_measures.tab.history')} - </Link> - </li> - )} - </ul> + {hasTreemap(metric) && + <li> + <Link + activeClassName="active" + to={{ + pathname: `/component_measures/metric/${metric.key}/treemap`, + query: { id: component.key } + }} + > + <IconTreemap /> + {translate('component_measures.tab.treemap')} + </Link> + </li>} + + {hasHistory(metric.key) && + <li> + <Link + activeClassName="active" + to={{ + pathname: `/component_measures/metric/${metric.key}/history`, + query: { id: component.key } + }} + > + <IconHistory /> + {translate('component_measures.tab.history')} + </Link> + </li>} + </ul> - {child} - </div> + {child} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeView.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeView.js index 4c6e64c94e4..5a038da60e8 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeView.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeView.js @@ -26,11 +26,11 @@ import SourceViewer from '../../../../components/SourceViewer/SourceViewer'; import ListFooter from '../../../../components/controls/ListFooter'; export default class TreeView extends React.Component { - componentDidMount () { + componentDidMount() { this.handleChangeBaseComponent(this.props.component); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.metric !== this.props.metric) { this.handleChangeBaseComponent(this.props.component); } @@ -42,7 +42,7 @@ export default class TreeView extends React.Component { } } - scrollToViewer () { + scrollToViewer() { const { container } = this.refs; const top = container.getBoundingClientRect().top + window.scrollY - 95 - 10; @@ -52,34 +52,34 @@ export default class TreeView extends React.Component { } } - scrollToStoredPosition () { + scrollToStoredPosition() { window.scrollTo(0, this.scrollTop); this.scrollTop = null; } - storeScrollPosition () { + storeScrollPosition() { this.scrollTop = window.scrollY; } - handleChangeBaseComponent (baseComponent) { + handleChangeBaseComponent(baseComponent) { const { metric, onStart } = this.props; const periodIndex = this.props.location.query.period || 1; onStart(baseComponent, metric, Number(periodIndex)); } - handleFetchMore () { + handleFetchMore() { this.props.onFetchMore(); } - changeSelected (selected) { + changeSelected(selected) { this.props.onSelect(selected); } - canDrilldown (component) { + canDrilldown(component) { return !['FIL', 'UTS'].includes(component.qualifier); } - handleClick (selected) { + handleClick(selected) { if (this.canDrilldown(selected)) { this.props.onDrilldown(selected); } else { @@ -88,67 +88,77 @@ export default class TreeView extends React.Component { } } - handleBreadcrumbClick (component) { + handleBreadcrumbClick(component) { this.props.onUseBreadcrumbs(component, this.props.metric); } - render () { - const { components, metrics, breadcrumbs, metric, leakPeriod, selected, total, fetching } = this.props; + render() { + const { + components, + metrics, + breadcrumbs, + metric, + leakPeriod, + selected, + total, + fetching + } = this.props; const { onSelectNext, onSelectPrevious } = this.props; const selectedIndex = components.indexOf(selected); const sourceViewerPeriod = metric.key.indexOf('new_') === 0 && !!leakPeriod ? leakPeriod : null; - const sourceViewerPeriodDate = sourceViewerPeriod != null ? moment(sourceViewerPeriod.date).toDate() : null; - - const filterLine = sourceViewerPeriodDate != null ? line => { - if (line.scmDate) { - const scmDate = moment(line.scmDate).toDate(); - return scmDate >= sourceViewerPeriodDate; - } else { - return false; - } - } : undefined; + const sourceViewerPeriodDate = sourceViewerPeriod != null + ? moment(sourceViewerPeriod.date).toDate() + : null; + + const filterLine = sourceViewerPeriodDate != null + ? line => { + if (line.scmDate) { + const scmDate = moment(line.scmDate).toDate(); + return scmDate >= sourceViewerPeriodDate; + } else { + return false; + } + } + : undefined; return ( - <div ref="container" className="measure-details-plain-list"> - <ListHeader - metric={metric} - breadcrumbs={breadcrumbs} - componentsCount={components.length} - selectedIndex={selectedIndex} - onSelectPrevious={onSelectPrevious} - onSelectNext={onSelectNext} - onBrowse={this.handleBreadcrumbClick.bind(this)}/> - - {!selected && ( - <div> - {(!fetching || components.length !== 0) ? ( - <div> - <ComponentsList - components={components} - metrics={metrics} - selected={selected} - metric={metric} - onClick={this.handleClick.bind(this)}/> - <ListFooter - count={components.length} - total={total} - loadMore={this.handleFetchMore.bind(this)}/> - </div> - ) : ( - <Spinner/> - )} - </div> - )} - - {!!selected && ( - <div className="measure-details-viewer"> - <SourceViewer - component={selected.key} - filterLine={filterLine}/> - </div> - )} - </div> + <div ref="container" className="measure-details-plain-list"> + <ListHeader + metric={metric} + breadcrumbs={breadcrumbs} + componentsCount={components.length} + selectedIndex={selectedIndex} + onSelectPrevious={onSelectPrevious} + onSelectNext={onSelectNext} + onBrowse={this.handleBreadcrumbClick.bind(this)} + /> + + {!selected && + <div> + {!fetching || components.length !== 0 + ? <div> + <ComponentsList + components={components} + metrics={metrics} + selected={selected} + metric={metric} + onClick={this.handleClick.bind(this)} + /> + <ListFooter + count={components.length} + total={total} + loadMore={this.handleFetchMore.bind(this)} + /> + </div> + : <Spinner />} + </div>} + + {!!selected && + <div className="measure-details-viewer"> + <SourceViewer component={selected.key} filterLine={filterLine} /> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeViewContainer.js b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeViewContainer.js index 1111d3c3afc..a7ae418251f 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeViewContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/drilldown/TreeViewContainer.js @@ -56,7 +56,8 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { return { - onStart: (rootComponent, metric, periodIndex) => dispatch(start(rootComponent, metric, periodIndex)), + onStart: (rootComponent, metric, periodIndex) => + dispatch(start(rootComponent, metric, periodIndex)), onDrilldown: component => dispatch(drilldown(component)), onUseBreadcrumbs: component => dispatch(useBreadcrumbs(component)), onFetchMore: () => dispatch(fetchMore()), @@ -66,7 +67,4 @@ const mapDispatchToProps = dispatch => { }; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(TreeView); +export default connect(mapStateToProps, mapDispatchToProps)(TreeView); diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js index 21ee19cdd82..833043b8c9e 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js @@ -36,28 +36,25 @@ export default class MeasureHistory extends React.Component { fetching: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.fetchHistory(); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.metric !== this.props.metric) { this.fetchHistory(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - fetchHistory () { + fetchHistory() { const { metric } = this.props; - Promise.all([ - this.fetchTimeMachineData(metric.key), - this.fetchEvents() - ]).then(responses => { + Promise.all([this.fetchTimeMachineData(metric.key), this.fetchEvents()]).then(responses => { if (this.mounted) { this.setState({ snapshots: responses[0], @@ -68,7 +65,7 @@ export default class MeasureHistory extends React.Component { }); } - fetchTimeMachineData (currentMetric, comparisonMetric) { + fetchTimeMachineData(currentMetric, comparisonMetric) { const metricsToRequest = [currentMetric]; if (comparisonMetric) { @@ -86,12 +83,14 @@ export default class MeasureHistory extends React.Component { }); } - fetchEvents () { + fetchEvents() { if (this.props.component.qualifier !== 'TRK') { return Promise.resolve([]); } - return getProjectActivity(this.props.component.key, { category: 'VERSION' }).then(({ analyses }) => { + return getProjectActivity(this.props.component.key, { category: 'VERSION' }).then(({ + analyses + }) => { const events = analyses.map(analysis => { const version = analysis.events.find(event => event.category === 'VERSION'); return { version: version.name, date: moment(analysis.date).toDate() }; @@ -101,7 +100,7 @@ export default class MeasureHistory extends React.Component { }); } - renderLineChart (snapshots, metric) { + renderLineChart(snapshots, metric) { if (!metric) { return null; } @@ -121,48 +120,50 @@ export default class MeasureHistory extends React.Component { const formatYTick = tick => formatMeasure(tick, getShortType(metric.type)); return ( - <div style={{ height: HEIGHT }}> - <Timeline key={metric.key} - data={data} - metricType={metric.type} - events={this.state.events} - height={HEIGHT} - interpolate="linear" - formatValue={formatValue} - formatYTick={formatYTick} - leakPeriodDate={this.props.leakPeriodDate} - padding={[25, 25, 25, 60]}/> - </div> + <div style={{ height: HEIGHT }}> + <Timeline + key={metric.key} + data={data} + metricType={metric.type} + events={this.state.events} + height={HEIGHT} + interpolate="linear" + formatValue={formatValue} + formatYTick={formatYTick} + leakPeriodDate={this.props.leakPeriodDate} + padding={[25, 25, 25, 60]} + /> + </div> ); } - render () { + render() { const { fetching, snapshots } = this.state; if (fetching) { return ( - <div className="measure-details-history"> - <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> - <Spinner/> - </div> + <div className="measure-details-history"> + <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> + <Spinner /> </div> + </div> ); } if (!snapshots || snapshots.length < 2) { return ( - <div className="measure-details-history"> - <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> - {translate('component_measures.no_history')} - </div> + <div className="measure-details-history"> + <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> + {translate('component_measures.no_history')} </div> + </div> ); } return ( - <div className="measure-details-history"> - {this.renderLineChart(this.state.snapshots, this.props.metric)} - </div> + <div className="measure-details-history"> + {this.renderLineChart(this.state.snapshots, this.props.metric)} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js index 2da90ca76d4..72fe0385a2c 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js @@ -19,7 +19,10 @@ */ import { connect } from 'react-redux'; import MeasureHistory from './MeasureHistory'; -import { getMeasuresAppDetailsMetric, getMeasuresAppComponent } from '../../../../store/rootReducer'; +import { + getMeasuresAppDetailsMetric, + getMeasuresAppComponent +} from '../../../../store/rootReducer'; const mapStateToProps = state => { return { @@ -32,7 +35,4 @@ const mapDispatchToProps = () => { return {}; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(MeasureHistory); +export default connect(mapStateToProps, mapDispatchToProps)(MeasureHistory); diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/reducer.js b/server/sonar-web/src/main/js/apps/component-measures/details/reducer.js index ca725f764b0..ea68685093f 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/reducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/reducer.js @@ -27,16 +27,20 @@ const initialState = { periods: undefined }; -export default function appReducer (state = initialState, action = {}) { +export default function appReducer(state = initialState, action = {}) { switch (action.type) { case DISPLAY_HOME: return initialState; case REQUEST_MEASURE: return { ...state, metric: action.metric }; case RECEIVE_MEASURE: - return { ...state, measure: action.measure, secondaryMeasure: action.secondaryMeasure, periods: action.periods }; + return { + ...state, + measure: action.measure, + secondaryMeasure: action.secondaryMeasure, + periods: action.periods + }; default: return state; } } - diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js index b599af3cd2b..74f0cc9975d 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemap.js @@ -23,7 +23,11 @@ import { getLeakValue } from '../../utils'; import { Treemap } from '../../../../components/charts/treemap'; import { getChildren } from '../../../../api/components'; import { formatMeasure } from '../../../../helpers/measures'; -import { translate, translateWithParameters, getLocalizedMetricName } from '../../../../helpers/l10n'; +import { + translate, + translateWithParameters, + getLocalizedMetricName +} from '../../../../helpers/l10n'; import { getComponentUrl } from '../../../../helpers/urls'; import Workspace from '../../../../components/workspace/main'; @@ -36,24 +40,24 @@ export default class MeasureTreemap extends React.Component { breadcrumbs: [] }; - componentDidMount () { + componentDidMount() { const { component } = this.props; this.mounted = true; this.fetchComponents(component.key); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.metric !== this.props.metric) { this.fetchComponents(this.props.component.key); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - fetchComponents (componentKey) { + fetchComponents(componentKey) { const { metric } = this.props; const metrics = ['ncloc', metric.key]; const options = { @@ -81,7 +85,7 @@ export default class MeasureTreemap extends React.Component { }); } - getTooltip (component) { + getTooltip(component) { const { metric } = this.props; let inner = [ @@ -91,36 +95,33 @@ export default class MeasureTreemap extends React.Component { const colorMeasure = component.measures[metric.key]; const formatted = colorMeasure != null ? formatMeasure(colorMeasure, metric.type) : '—'; - inner.push(`${getLocalizedMetricName(metric)}: ${formatted}`); inner = inner.join('<br>'); - return `<div class="text-left">${inner}</div>`; } - - getPercentColorScale (metric) { + getPercentColorScale(metric) { const color = d3.scale.linear().domain([0, 25, 50, 75, 100]); - color.range(metric.direction === 1 ? - ['#d4333f', '#ed7d20', '#eabe06', '#b0d513', '#00aa00'] : - ['#00aa00', '#b0d513', '#eabe06', '#ed7d20', '#d4333f']); + color.range( + metric.direction === 1 + ? ['#d4333f', '#ed7d20', '#eabe06', '#b0d513', '#00aa00'] + : ['#00aa00', '#b0d513', '#eabe06', '#ed7d20', '#d4333f'] + ); return color; } - - getRatingColorScale () { - return d3.scale.linear() - .domain([1, 2, 3, 4, 5]) - .range(['#00aa00', '#b0d513', '#eabe06', '#ed7d20', '#d4333f']); + getRatingColorScale() { + return d3.scale + .linear() + .domain([1, 2, 3, 4, 5]) + .range(['#00aa00', '#b0d513', '#eabe06', '#ed7d20', '#d4333f']); } - - getLevelColorScale () { - return d3.scale.ordinal() - .domain(['ERROR', 'WARN', 'OK', 'NONE']) - .range(['#d4333f', '#ed7d20', '#00aa00', '#b4b4b4']); + getLevelColorScale() { + return d3.scale + .ordinal() + .domain(['ERROR', 'WARN', 'OK', 'NONE']) + .range(['#d4333f', '#ed7d20', '#00aa00', '#b4b4b4']); } - - getScale () { + getScale() { const { metric } = this.props; - if (metric.type === 'LEVEL') { return this.getLevelColorScale(); } @@ -129,98 +130,95 @@ export default class MeasureTreemap extends React.Component { } return this.getPercentColorScale(metric); } - - handleRectangleClick (node) { + handleRectangleClick(node) { const isFile = node.qualifier === 'FIL' || node.qualifier === 'UTS'; - if (isFile) { Workspace.openComponent({ key: node.key }); return; } - this.fetchComponents(node.key).then(() => { let nextBreadcrumbs = [...this.state.breadcrumbs]; const index = this.state.breadcrumbs.findIndex(b => b.key === node.key); - if (index !== -1) { nextBreadcrumbs = nextBreadcrumbs.slice(0, index); } - - nextBreadcrumbs = [...nextBreadcrumbs, { - key: node.key, - name: node.name, - qualifier: node.qualifier - }]; - + nextBreadcrumbs = [ + ...nextBreadcrumbs, + { + key: node.key, + name: node.name, + qualifier: node.qualifier + } + ]; this.setState({ breadcrumbs: nextBreadcrumbs }); }); } - - handleReset () { + handleReset() { const { component } = this.props; this.fetchComponents(component.key).then(() => { this.setState({ breadcrumbs: [] }); }); } - - renderTreemap () { + renderTreemap() { const { metric } = this.props; const colorScale = this.getScale(); const items = this.state.components - .filter(component => component.measures['ncloc']) - .map(component => { - const colorMeasure = component.measures[metric.key]; - - return { - id: component.id, - key: component.key, - name: component.name, - qualifier: component.qualifier, - size: component.measures['ncloc'], - color: colorMeasure != null ? colorScale(colorMeasure) : '#777', - tooltip: this.getTooltip(component), - label: component.name, - link: getComponentUrl(component.key) - }; - }); - + .filter(component => component.measures['ncloc']) + .map(component => { + const colorMeasure = component.measures[metric.key]; + return { + id: component.id, + key: component.key, + name: component.name, + qualifier: component.qualifier, + size: component.measures['ncloc'], + color: colorMeasure != null ? colorScale(colorMeasure) : '#777', + tooltip: this.getTooltip(component), + label: component.name, + link: getComponentUrl(component.key) + }; + }); return ( - <Treemap - items={items} - breadcrumbs={this.state.breadcrumbs} - height={HEIGHT} - canBeClicked={() => true} - onRectangleClick={this.handleRectangleClick.bind(this)} - onReset={this.handleReset.bind(this)}/> + <Treemap + items={items} + breadcrumbs={this.state.breadcrumbs} + height={HEIGHT} + canBeClicked={() => true} + onRectangleClick={this.handleRectangleClick.bind(this)} + onReset={this.handleReset.bind(this)} + /> ); } - - render () { + render() { const { metric } = this.props; const { fetching } = this.state; - if (fetching) { return ( - <div className="measure-details-treemap"> - <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> - <Spinner/> - </div> + <div className="measure-details-treemap"> + <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}> + <Spinner /> </div> + </div> ); } - return ( - <div className="measure-details-treemap"> - <ul className="list-inline note measure-details-treemap-legend"> - <li> - {translateWithParameters('component_measures.legend.color_x', getLocalizedMetricName(metric))} - </li> - <li> - {translateWithParameters('component_measures.legend.size_x', translate('metric.ncloc.name'))} - </li> - </ul> - {this.renderTreemap()} - </div> + <div className="measure-details-treemap"> + <ul className="list-inline note measure-details-treemap-legend"> + <li> + {translateWithParameters( + 'component_measures.legend.color_x', + getLocalizedMetricName(metric) + )} + </li> + <li> + {translateWithParameters( + 'component_measures.legend.size_x', + translate('metric.ncloc.name') + )} + </li> + </ul> + {this.renderTreemap()} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemapContainer.js b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemapContainer.js index a9057d5f4ad..5a3e26d98d4 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemapContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/details/treemap/MeasureTreemapContainer.js @@ -19,7 +19,10 @@ */ import { connect } from 'react-redux'; import MeasureTreemap from './MeasureTreemap'; -import { getMeasuresAppDetailsMetric, getMeasuresAppComponent } from '../../../../store/rootReducer'; +import { + getMeasuresAppDetailsMetric, + getMeasuresAppComponent +} from '../../../../store/rootReducer'; const mapStateToProps = state => { return { @@ -32,7 +35,4 @@ const mapDispatchToProps = () => { return {}; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(MeasureTreemap); +export default connect(mapStateToProps, mapDispatchToProps)(MeasureTreemap); diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasures.js b/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasures.js index 5c3bfc65748..c1782709ea0 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasures.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasures.js @@ -22,20 +22,21 @@ import AllMeasuresDomain from './AllMeasuresDomain'; import { getLeakPeriodLabel } from '../../../helpers/periods'; export default class AllMeasures extends React.Component { - render () { + render() { const { component, domains, periods } = this.props; const leakPeriodLabel = getLeakPeriodLabel(periods); return ( - <ul className="measures-domains"> - {domains.map(domain => ( - <AllMeasuresDomain - key={domain.name} - domain={domain} - component={component} - leakPeriodLabel={leakPeriodLabel}/> - ))} - </ul> + <ul className="measures-domains"> + {domains.map(domain => ( + <AllMeasuresDomain + key={domain.name} + domain={domain} + component={component} + leakPeriodLabel={leakPeriodLabel} + /> + ))} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresContainer.js b/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresContainer.js index c33daf93fcb..5ec9cc79ab8 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresContainer.js @@ -33,6 +33,4 @@ const mapStateToProps = state => { }; }; -export default connect( - mapStateToProps -)(AllMeasures); +export default connect(mapStateToProps)(AllMeasures); diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresDomain.js b/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresDomain.js index 56e6b60fdbd..be68ff12f75 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresDomain.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/AllMeasuresDomain.js @@ -22,23 +22,20 @@ import HomeMeasuresList from './HomeMeasuresList'; import { getLocalizedMetricDomain } from '../../../helpers/l10n'; export default class AllMeasuresDomain extends React.Component { - render () { + render() { const { domain, component, displayHeader } = this.props; return ( - <li> - {displayHeader && ( - <header className="page-header"> - <h3 className="page-title"> - {getLocalizedMetricDomain(domain.name)} - </h3> - </header> - )} + <li> + {displayHeader && + <header className="page-header"> + <h3 className="page-title"> + {getLocalizedMetricDomain(domain.name)} + </h3> + </header>} - <HomeMeasuresList - domain={domain} - component={component}/> - </li> + <HomeMeasuresList domain={domain} component={component} /> + </li> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasures.js b/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasures.js index 8f2f2915257..ce868f213f3 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasures.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasures.js @@ -23,21 +23,17 @@ import MeasureBubbleChartContainer from '../components/bubbleChart/MeasureBubble import { hasBubbleChart } from '../utils'; export default class DomainMeasures extends React.Component { - render () { + render() { const { component, domains } = this.props; const { domainName } = this.props.params; const domain = domains.find(d => d.name === domainName); return ( - <section id="component-measures-domain"> - <HomeMeasuresList - domain={domain} - component={component}/> + <section id="component-measures-domain"> + <HomeMeasuresList domain={domain} component={component} /> - {hasBubbleChart(domainName) && ( - <MeasureBubbleChartContainer domainName={domainName}/> - )} - </section> + {hasBubbleChart(domainName) && <MeasureBubbleChartContainer domainName={domainName} />} + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasuresContainer.js b/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasuresContainer.js index 15f4dd192bb..c442bfca57c 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasuresContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/DomainMeasuresContainer.js @@ -33,6 +33,4 @@ const mapStateToProps = state => { }; }; -export default connect( - mapStateToProps -)(DomainMeasures); +export default connect(mapStateToProps)(DomainMeasures); diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/Home.js b/server/sonar-web/src/main/js/apps/component-measures/home/Home.js index a1e20c51bb2..9e895d390e3 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/Home.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/Home.js @@ -24,17 +24,17 @@ import { getLeakPeriod } from '../../../helpers/periods'; import { translate, getLocalizedMetricDomain } from '../../../helpers/l10n'; export default class Home extends React.Component { - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); this.props.onDisplay(); this.props.fetchMeasures(); } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } - render () { + render() { const { component, domains, periods } = this.props; if (domains == null) { @@ -44,38 +44,41 @@ export default class Home extends React.Component { const leakPeriod = getLeakPeriod(periods); return ( - <section id="component-measures-home" className="page page-container page-limited"> - <header id="component-measures-home-header" className="home-header"> - <nav className="nav-pills pull-left"> - <ul> - <li> - <IndexLink - to={{ pathname: '/component_measures', query: { id: component.key } }} - activeClassName="active"> - {translate('all')} - </IndexLink> + <section id="component-measures-home" className="page page-container page-limited"> + <header id="component-measures-home-header" className="home-header"> + <nav className="nav-pills pull-left"> + <ul> + <li> + <IndexLink + to={{ pathname: '/component_measures', query: { id: component.key } }} + activeClassName="active" + > + {translate('all')} + </IndexLink> + </li> + {domains.map(domain => ( + <li key={domain.name}> + <Link + to={{ + pathname: `/component_measures/domain/${domain.name}`, + query: { id: component.key } + }} + activeClassName="active" + > + {getLocalizedMetricDomain(domain.name)} + </Link> </li> - {domains.map(domain => ( - <li key={domain.name}> - <Link - to={{ pathname: `/component_measures/domain/${domain.name}`, query: { id: component.key } }} - activeClassName="active"> - {getLocalizedMetricDomain(domain.name)} - </Link> - </li> - ))} - </ul> - </nav> + ))} + </ul> + </nav> - {leakPeriod != null && ( - <LeakPeriodLegend period={leakPeriod}/> - )} - </header> + {leakPeriod != null && <LeakPeriodLegend period={leakPeriod} />} + </header> - <main id="component-measures-home-main"> - {this.props.children} - </main> - </section> + <main id="component-measures-home-main"> + {this.props.children} + </main> + </section> ); } } diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/HomeContainer.js b/server/sonar-web/src/main/js/apps/component-measures/home/HomeContainer.js index e1c85edfce0..0605a3aec58 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/HomeContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/HomeContainer.js @@ -42,7 +42,4 @@ const mapDispatchToProps = dispatch => { }; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(Home); +export default connect(mapStateToProps, mapDispatchToProps)(Home); diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js b/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js index e8dfd64fcb4..187f34739be 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/HomeMeasuresList.js @@ -24,7 +24,7 @@ import MeasuresList from './MeasuresList'; import { domains } from '../config/domains'; import { getLocalizedMetricName } from '../../../helpers/l10n'; -function sortMeasures (measures, order) { +function sortMeasures(measures, order) { const [known, unknown] = partition(measures, measure => order.includes(measure.metric.key)); return [ ...sortBy(known, measure => order.indexOf(measure.metric.key)), @@ -32,7 +32,7 @@ function sortMeasures (measures, order) { ]; } -function filterIssuesMeasures (measures) { +function filterIssuesMeasures(measures) { const BANNED_MEASURES = [ 'blocker_violations', 'new_blocker_violations', @@ -55,29 +55,26 @@ const HomeMeasuresList = ({ domain, component }) => { const filteredMeasures = filterIssuesMeasures(measures); const configMain = config.main || []; - const [mainMeasures, otherMeasures] = partition(filteredMeasures, measure => configMain.includes(measure.metric.key)); + const [mainMeasures, otherMeasures] = partition(filteredMeasures, measure => + configMain.includes(measure.metric.key)); const configOrder = config.order || []; const sortedMainMeasures = sortMeasures(mainMeasures, configOrder); const sortedOtherMeasures = sortMeasures(otherMeasures, configOrder); return ( - <div className="home-measures-list clearfix"> - {sortedMainMeasures.length > 0 && ( - <MeasuresList - className="main-domain-measures" - measures={sortedMainMeasures} - component={component} - spaces={[]}/> - )} + <div className="home-measures-list clearfix"> + {sortedMainMeasures.length > 0 && + <MeasuresList + className="main-domain-measures" + measures={sortedMainMeasures} + component={component} + spaces={[]} + />} - {sortedOtherMeasures.length > 0 && ( - <MeasuresList - measures={sortedOtherMeasures} - component={component} - spaces={[]}/> - )} - </div> + {sortedOtherMeasures.length > 0 && + <MeasuresList measures={sortedOtherMeasures} component={component} spaces={[]} />} + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js b/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js index 44f2d8c5d4c..5b395201657 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/MeasureListValue.js @@ -26,16 +26,19 @@ const MeasureListValue = ({ measure }) => { if (isDiffMetric(metric)) { return ( - <div id={`measure-${measure.metric.key}-leak`} className="domain-measures-value domain-measures-leak"> - <Measure measure={measure}/> - </div> + <div + id={`measure-${measure.metric.key}-leak`} + className="domain-measures-value domain-measures-leak" + > + <Measure measure={measure} /> + </div> ); } return ( - <div id={`measure-${measure.metric.key}-value`} className="domain-measures-value"> - <Measure measure={measure}/> - </div> + <div id={`measure-${measure.metric.key}-value`} className="domain-measures-value"> + <Measure measure={measure} /> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/MeasuresList.js b/server/sonar-web/src/main/js/apps/component-measures/home/MeasuresList.js index 359ec83ba8e..c46c27e5d3a 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/MeasuresList.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/MeasuresList.js @@ -25,24 +25,27 @@ import IssueTypeIcon from '../../../components/ui/IssueTypeIcon'; const MeasuresList = ({ measures, component, className = 'domain-measures' }) => { return ( - <ul className={className}> - {measures.map(measure => ( - <li - key={measure.metric.key} - id={`measure-${measure.metric.key}`}> - <Link to={{ pathname: `/component_measures/metric/${measure.metric.key}`, query: { id: component.key } }}> - <div className="domain-measures-name"> - <IssueTypeIcon query={measure.metric.key} className="little-spacer-right"/> - <span id={`measure-${measure.metric.key}-name`}> - {getLocalizedMetricName(measure.metric)} - </span> - </div> + <ul className={className}> + {measures.map(measure => ( + <li key={measure.metric.key} id={`measure-${measure.metric.key}`}> + <Link + to={{ + pathname: `/component_measures/metric/${measure.metric.key}`, + query: { id: component.key } + }} + > + <div className="domain-measures-name"> + <IssueTypeIcon query={measure.metric.key} className="little-spacer-right" /> + <span id={`measure-${measure.metric.key}-name`}> + {getLocalizedMetricName(measure.metric)} + </span> + </div> - <MeasureListValue measure={measure}/> - </Link> - </li> - ))} - </ul> + <MeasureListValue measure={measure} /> + </Link> + </li> + ))} + </ul> ); }; diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/actions.js b/server/sonar-web/src/main/js/apps/component-measures/home/actions.js index b516d2e7bbb..ed8e64d79a6 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/actions.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/actions.js @@ -25,18 +25,18 @@ import { getMeasuresAppComponent, getMeasuresAppAllMetrics } from '../../../stor export const RECEIVE_MEASURES = 'measuresApp/home/RECEIVE_MEASURES'; -export function receiveMeasures (measures, periods) { +export function receiveMeasures(measures, periods) { return { type: RECEIVE_MEASURES, measures, periods }; } -function banQualityGate (component, measures) { +function banQualityGate(component, measures) { if (['VW', 'SVW'].includes(component.qualifier)) { return measures; } return measures.filter(measure => measure.metric !== 'alert_status'); } -export function fetchMeasures () { +export function fetchMeasures() { return (dispatch, getState) => { dispatch(startFetching()); @@ -45,23 +45,23 @@ export function fetchMeasures () { const metrics = getMeasuresAppAllMetrics(state); const metricKeys = metrics - .filter(metric => !metric.hidden) - .filter(metric => metric.type !== 'DATA' && metric.type !== 'DISTRIB') - .map(metric => metric.key); + .filter(metric => !metric.hidden) + .filter(metric => metric.type !== 'DATA' && metric.type !== 'DISTRIB') + .map(metric => metric.key); getMeasuresAndMeta(component.key, metricKeys, { additionalFields: 'periods' }).then(r => { const leakPeriod = getLeakPeriod(r.periods); const measures = banQualityGate(component, r.component.measures) - .map(measure => { - const metric = metrics.find(metric => metric.key === measure.metric); - const leak = getLeakValue(measure); - return { ...measure, metric, leak }; - }) - .filter(measure => { - const hasValue = measure.value != null; - const hasLeakValue = !!leakPeriod && measure.leak != null; - return hasValue || hasLeakValue; - }); + .map(measure => { + const metric = metrics.find(metric => metric.key === measure.metric); + const leak = getLeakValue(measure); + return { ...measure, metric, leak }; + }) + .filter(measure => { + const hasValue = measure.value != null; + const hasLeakValue = !!leakPeriod && measure.leak != null; + return hasValue || hasLeakValue; + }); dispatch(receiveMeasures(measures, r.periods)); dispatch(stopFetching()); diff --git a/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js b/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js index a24e6068313..f404b7addd1 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/home/reducer.js @@ -30,25 +30,36 @@ const initialState = { periods: undefined }; -function groupByDomains (measures) { - const KNOWN_DOMAINS = ['Releasability', 'Reliability', 'Security', 'Maintainability', 'Coverage', 'Duplications', - 'Size', 'Complexity']; +function groupByDomains(measures) { + const KNOWN_DOMAINS = [ + 'Releasability', + 'Reliability', + 'Security', + 'Maintainability', + 'Coverage', + 'Duplications', + 'Size', + 'Complexity' + ]; - const domains = sortBy(toPairs(groupBy(measures, measure => measure.metric.domain)).map(r => { - const [name, measures] = r; - const sortedMeasures = sortBy(measures, measure => getLocalizedMetricName(measure.metric)); + const domains = sortBy( + toPairs(groupBy(measures, measure => measure.metric.domain)).map(r => { + const [name, measures] = r; + const sortedMeasures = sortBy(measures, measure => getLocalizedMetricName(measure.metric)); - return { name, measures: sortedMeasures }; - }), 'name'); - const [knownDomains, unknownDomains] = - partition(domains, domain => KNOWN_DOMAINS.includes(domain.name)); + return { name, measures: sortedMeasures }; + }), + 'name' + ); + const [knownDomains, unknownDomains] = partition(domains, domain => + KNOWN_DOMAINS.includes(domain.name)); return [ ...sortBy(knownDomains, domain => KNOWN_DOMAINS.indexOf(domain.name)), ...sortBy(unknownDomains, domain => domain.name) ]; } -export default function (state = initialState, action = {}) { +export default function(state = initialState, action = {}) { switch (action.type) { case RECEIVE_MEASURES: return { diff --git a/server/sonar-web/src/main/js/apps/component-measures/hooks.js b/server/sonar-web/src/main/js/apps/component-measures/hooks.js index 39399fa5d92..4aad79c6034 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/hooks.js +++ b/server/sonar-web/src/main/js/apps/component-measures/hooks.js @@ -19,7 +19,7 @@ */ import { hasHistory } from './utils'; -export function checkHistoryExistence (nextState, replace) { +export function checkHistoryExistence(nextState, replace) { const { metricKey } = nextState.params; if (!hasHistory(metricKey)) { diff --git a/server/sonar-web/src/main/js/apps/component-measures/routes.js b/server/sonar-web/src/main/js/apps/component-measures/routes.js index 881dd3ca4ba..1fe9d219852 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/routes.js +++ b/server/sonar-web/src/main/js/apps/component-measures/routes.js @@ -32,18 +32,18 @@ import { checkHistoryExistence } from './hooks'; import './styles.css'; export default ( - <Route component={AppContainer}> - <Route component={HomeContainer}> - <IndexRoute component={AllMeasuresContainer}/> - <Route path="domain/:domainName" component={DomainMeasuresContainer}/> - </Route> + <Route component={AppContainer}> + <Route component={HomeContainer}> + <IndexRoute component={AllMeasuresContainer} /> + <Route path="domain/:domainName" component={DomainMeasuresContainer} /> + </Route> - <Route path="metric/:metricKey" component={MeasureDetailsContainer}> - <IndexRedirect to="list"/> - <Route path="list" component={ListViewContainer}/> - <Route path="tree" component={TreeViewContainer}/> - <Route path="history" component={MeasureHistoryContainer} onEnter={checkHistoryExistence}/> - <Route path="treemap" component={MeasureTreemapContainer}/> - </Route> + <Route path="metric/:metricKey" component={MeasureDetailsContainer}> + <IndexRedirect to="list" /> + <Route path="list" component={ListViewContainer} /> + <Route path="tree" component={TreeViewContainer} /> + <Route path="history" component={MeasureHistoryContainer} onEnter={checkHistoryExistence} /> + <Route path="treemap" component={MeasureTreemapContainer} /> </Route> + </Route> ); diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/listViewActions.js b/server/sonar-web/src/main/js/apps/component-measures/store/listViewActions.js index 7813babdc06..2bbd93dfa28 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/listViewActions.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/listViewActions.js @@ -25,16 +25,16 @@ import { getMeasuresAppList } from '../../../store/rootReducer'; export const UPDATE_STORE = 'measuresApp/drilldown/list/UPDATE_STORE'; -function updateStore (state) { +function updateStore(state) { return { type: UPDATE_STORE, state }; } -function getComplementary (metric) { +function getComplementary(metric) { const comp = complementary[metric] || []; return [metric, ...comp]; } -function makeRequest (baseComponent, metric, options, periodIndex = 1) { +function makeRequest(baseComponent, metric, options, periodIndex = 1) { const asc = metric.direction === 1; const ps = 100; const finalOptions = { asc, ps, metricSortFilter: 'withMeasuresOnly' }; @@ -56,7 +56,7 @@ function makeRequest (baseComponent, metric, options, periodIndex = 1) { return getComponentTree('leaves', baseComponent.key, getComplementary(metric.key), finalOptions); } -function fetchLeaves (baseComponent, metric, pageIndex = 1, periodIndex = 1) { +function fetchLeaves(baseComponent, metric, pageIndex = 1, periodIndex = 1) { const options = { p: pageIndex }; return makeRequest(baseComponent, metric, options, periodIndex).then(r => { @@ -76,7 +76,7 @@ function fetchLeaves (baseComponent, metric, pageIndex = 1, periodIndex = 1) { * @param metric * @param periodIndex */ -export function fetchList (baseComponent, metric, periodIndex = 1) { +export function fetchList(baseComponent, metric, periodIndex = 1) { return (dispatch, getState) => { const list = getMeasuresAppList(getState()); if (list.baseComponent === baseComponent && list.metric === metric) { @@ -85,17 +85,19 @@ export function fetchList (baseComponent, metric, periodIndex = 1) { dispatch(startFetching()); return fetchLeaves(baseComponent, metric, 1, periodIndex).then(r => { - dispatch(updateStore({ - ...r, - baseComponent, - metric - })); + dispatch( + updateStore({ + ...r, + baseComponent, + metric + }) + ); dispatch(stopFetching()); }); }; } -export function fetchMore (periodIndex) { +export function fetchMore(periodIndex) { return (dispatch, getState) => { const { baseComponent, metric, pageIndex, components } = getMeasuresAppList(getState()); dispatch(startFetching()); @@ -111,7 +113,7 @@ export function fetchMore (periodIndex) { * Select specified component from the list * @param component A component to select */ -export function selectComponent (component) { +export function selectComponent(component) { return dispatch => { dispatch(updateStore({ selected: component })); }; @@ -120,7 +122,7 @@ export function selectComponent (component) { /** * Select next element from the list of components */ -export function selectNext () { +export function selectNext() { return (dispatch, getState) => { const { components, selected } = getMeasuresAppList(getState()); const selectedIndex = components.indexOf(selected); @@ -134,7 +136,7 @@ export function selectNext () { /** * Select previous element from the list of components */ -export function selectPrevious () { +export function selectPrevious() { return (dispatch, getState) => { const { components, selected } = getMeasuresAppList(getState()); const selectedIndex = components.indexOf(selected); diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/listViewReducer.js b/server/sonar-web/src/main/js/apps/component-measures/store/listViewReducer.js index a90dae9ef02..ee8f9aeaef8 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/listViewReducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/listViewReducer.js @@ -25,7 +25,7 @@ const initialState = { total: 0 }; -export default function drilldownReducer (state = initialState, action = {}) { +export default function drilldownReducer(state = initialState, action = {}) { switch (action.type) { case DISPLAY_HOME: return initialState; diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/rootReducer.js b/server/sonar-web/src/main/js/apps/component-measures/store/rootReducer.js index a14d977134d..079a7e45693 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/rootReducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/rootReducer.js @@ -34,82 +34,42 @@ export default combineReducers({ status: statusReducer }); -export const getComponent = state => ( - state.app.component -); +export const getComponent = state => state.app.component; -export const getAllMetrics = state => ( - state.app.metrics -); +export const getAllMetrics = state => state.app.metrics; -export const getDetailsMetric = state => ( - state.details.metric -); +export const getDetailsMetric = state => state.details.metric; -export const getDetailsMeasure = state => ( - state.details.measure -); +export const getDetailsMeasure = state => state.details.measure; -export const getDetailsSecondaryMeasure = state => ( - state.details.secondaryMeasure -); +export const getDetailsSecondaryMeasure = state => state.details.secondaryMeasure; -export const getDetailsPeriods = state => ( - state.details.periods -); +export const getDetailsPeriods = state => state.details.periods; -export const isFetching = state => ( - state.status.fetching -); +export const isFetching = state => state.status.fetching; -export const getList = state => ( - state.list -); +export const getList = state => state.list; -export const getListComponents = state => ( - state.list.components -); +export const getListComponents = state => state.list.components; -export const getListSelected = state => ( - state.list.selected -); +export const getListSelected = state => state.list.selected; -export const getListTotal = state => ( - state.list.total -); +export const getListTotal = state => state.list.total; -export const getListPageIndex = state => ( - state.list.pageIndex -); +export const getListPageIndex = state => state.list.pageIndex; -export const getTree = state => ( - state.tree -); +export const getTree = state => state.tree; -export const getTreeComponents = state => ( - state.tree.components -); +export const getTreeComponents = state => state.tree.components; -export const getTreeBreadcrumbs = state => ( - state.tree.breadcrumbs -); +export const getTreeBreadcrumbs = state => state.tree.breadcrumbs; -export const getTreeSelected = state => ( - state.tree.selected -); +export const getTreeSelected = state => state.tree.selected; -export const getTreeTotal = state => ( - state.tree.total -); +export const getTreeTotal = state => state.tree.total; -export const getTreePageIndex = state => ( - state.tree.pageIndex -); +export const getTreePageIndex = state => state.tree.pageIndex; -export const getHomeDomains = state => ( - state.home.domains -); +export const getHomeDomains = state => state.home.domains; -export const getHomePeriods = state => ( - state.home.periods -); +export const getHomePeriods = state => state.home.periods; diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/statusActions.js b/server/sonar-web/src/main/js/apps/component-measures/store/statusActions.js index 3f786fe5d29..d07feba64d7 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/statusActions.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/statusActions.js @@ -20,10 +20,10 @@ export const START_FETCHING = 'measuresApp/status/START_FETCHING'; export const STOP_FETCHING = 'measuresApp/status/STOP_FETCHING'; -export function startFetching () { +export function startFetching() { return { type: START_FETCHING }; } -export function stopFetching () { +export function stopFetching() { return { type: STOP_FETCHING }; } diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/statusReducer.js b/server/sonar-web/src/main/js/apps/component-measures/store/statusReducer.js index 9b6f4bfbba2..1a993be900a 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/statusReducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/statusReducer.js @@ -23,7 +23,7 @@ const initialState = { fetching: false }; -export default function drilldownReducer (state = initialState, action = {}) { +export default function drilldownReducer(state = initialState, action = {}) { switch (action.type) { case START_FETCHING: return { ...state, fetching: true }; @@ -33,4 +33,3 @@ export default function drilldownReducer (state = initialState, action = {}) { return state; } } - diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js index e86eb0f0883..2d58b671872 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewActions.js @@ -41,7 +41,7 @@ export const INIT = 'measuresApp/drilldown/tree/INIT'; * @param state * @returns {{type: string, state: *}} */ -function updateStore (state) { +function updateStore(state) { return { type: UPDATE_STORE, state }; } @@ -52,7 +52,7 @@ function updateStore (state) { * @param periodIndex * @returns {{type: string, rootComponent: *, metric: *}} */ -function init (rootComponent, metric, periodIndex = 1) { +function init(rootComponent, metric, periodIndex = 1) { return { type: INIT, rootComponent, metric, periodIndex }; } @@ -60,12 +60,12 @@ function init (rootComponent, metric, periodIndex = 1) { * Workflow */ -function getComplementary (metric) { +function getComplementary(metric) { const comp = complementary[metric] || []; return [metric, ...comp]; } -function makeRequest (rootComponent, baseComponent, metric, options, periodIndex = 1) { +function makeRequest(rootComponent, baseComponent, metric, options, periodIndex = 1) { const asc = metric.direction === 1; const ps = 100; const finalOptions = { asc, ps, metricSortFilter: 'withMeasuresOnly' }; @@ -94,7 +94,7 @@ function makeRequest (rootComponent, baseComponent, metric, options, periodIndex return getComponentTree('children', finalKey, getComplementary(metric.key), finalOptions); } -function fetchComponents (rootComponent, baseComponent, metric, pageIndex = 1, periodIndex = 1) { +function fetchComponents(rootComponent, baseComponent, metric, pageIndex = 1, periodIndex = 1) { const options = { p: pageIndex }; return makeRequest(rootComponent, baseComponent, metric, options, periodIndex).then(r => { @@ -113,17 +113,19 @@ function fetchComponents (rootComponent, baseComponent, metric, pageIndex = 1, p * Fetch the first page of components for a given base component * @param baseComponent */ -function fetchList (baseComponent) { +function fetchList(baseComponent) { return (dispatch, getState) => { const { metric, periodIndex, rootComponent } = getMeasuresAppTree(getState()); dispatch(startFetching()); return fetchComponents(rootComponent, baseComponent, metric, 1, periodIndex).then(r => { - dispatch(updateStore({ - ...r, - baseComponent, - breadcrumbs: [baseComponent] - })); + dispatch( + updateStore({ + ...r, + baseComponent, + breadcrumbs: [baseComponent] + }) + ); dispatch(stopFetching()); }); }; @@ -137,7 +139,7 @@ function fetchList (baseComponent) { * @param periodIndex * @returns {function()} */ -export function start (rootComponent, metric, periodIndex = 1) { +export function start(rootComponent, metric, periodIndex = 1) { return (dispatch, getState) => { const tree = getMeasuresAppTree(getState()); if (rootComponent === tree.rootComponent && metric === tree.metric) { @@ -153,16 +155,18 @@ export function start (rootComponent, metric, periodIndex = 1) { * Drilldown to the component * @param component */ -export function drilldown (component) { +export function drilldown(component) { return (dispatch, getState) => { const { metric, rootComponent, breadcrumbs, periodIndex } = getMeasuresAppTree(getState()); dispatch(startFetching()); return fetchComponents(rootComponent, component, metric, 1, periodIndex).then(r => { - dispatch(updateStore({ - ...r, - breadcrumbs: [...breadcrumbs, component], - selected: undefined - })); + dispatch( + updateStore({ + ...r, + breadcrumbs: [...breadcrumbs, component], + selected: undefined + }) + ); dispatch(stopFetching()); }); }; @@ -172,27 +176,42 @@ export function drilldown (component) { * Go up using breadcrumbs * @param component */ -export function useBreadcrumbs (component) { +export function useBreadcrumbs(component) { return (dispatch, getState) => { const { metric, rootComponent, breadcrumbs, periodIndex } = getMeasuresAppTree(getState()); const index = breadcrumbs.indexOf(component); dispatch(startFetching()); return fetchComponents(rootComponent, component, metric, 1, periodIndex).then(r => { - dispatch(updateStore({ - ...r, - breadcrumbs: breadcrumbs.slice(0, index + 1), - selected: undefined - })); + dispatch( + updateStore({ + ...r, + breadcrumbs: breadcrumbs.slice(0, index + 1), + selected: undefined + }) + ); dispatch(stopFetching()); }); }; } -export function fetchMore () { +export function fetchMore() { return (dispatch, getState) => { - const { rootComponent, baseComponent, metric, pageIndex, components, periodIndex } = getMeasuresAppTree(getState()); + const { + rootComponent, + baseComponent, + metric, + pageIndex, + components, + periodIndex + } = getMeasuresAppTree(getState()); dispatch(startFetching()); - return fetchComponents(rootComponent, baseComponent, metric, pageIndex + 1, periodIndex).then(r => { + return fetchComponents( + rootComponent, + baseComponent, + metric, + pageIndex + 1, + periodIndex + ).then(r => { const nextComponents = [...components, ...r.components]; dispatch(updateStore({ ...r, components: nextComponents })); dispatch(stopFetching()); @@ -204,31 +223,35 @@ export function fetchMore () { * Select given component from the list * @param component */ -export function selectComponent (component) { +export function selectComponent(component) { return (dispatch, getState) => { const { breadcrumbs } = getMeasuresAppTree(getState()); const nextBreadcrumbs = [...breadcrumbs, component]; - dispatch(updateStore({ - selected: component, - breadcrumbs: nextBreadcrumbs - })); + dispatch( + updateStore({ + selected: component, + breadcrumbs: nextBreadcrumbs + }) + ); }; } /** * Select next element from the list of components */ -export function selectNext () { +export function selectNext() { return (dispatch, getState) => { const { components, selected, breadcrumbs } = getMeasuresAppTree(getState()); const selectedIndex = components.indexOf(selected); if (selectedIndex < components.length - 1) { const nextSelected = components[selectedIndex + 1]; const nextBreadcrumbs = [...initial(breadcrumbs), nextSelected]; - dispatch(updateStore({ - selected: nextSelected, - breadcrumbs: nextBreadcrumbs - })); + dispatch( + updateStore({ + selected: nextSelected, + breadcrumbs: nextBreadcrumbs + }) + ); } }; } @@ -236,17 +259,19 @@ export function selectNext () { /** * Select previous element from the list of components */ -export function selectPrevious () { +export function selectPrevious() { return (dispatch, getState) => { const { components, selected, breadcrumbs } = getMeasuresAppTree(getState()); const selectedIndex = components.indexOf(selected); if (selectedIndex > 0) { const nextSelected = components[selectedIndex - 1]; const nextBreadcrumbs = [...initial(breadcrumbs), nextSelected]; - dispatch(updateStore({ - selected: nextSelected, - breadcrumbs: nextBreadcrumbs - })); + dispatch( + updateStore({ + selected: nextSelected, + breadcrumbs: nextBreadcrumbs + }) + ); } }; } diff --git a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js index 0b8407b1436..05c6edb9b7f 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/store/treeViewReducer.js @@ -27,7 +27,7 @@ const initialState = { total: 0 }; -export default function drilldownReducer (state = initialState, action = {}) { +export default function drilldownReducer(state = initialState, action = {}) { switch (action.type) { case DISPLAY_HOME: return initialState; diff --git a/server/sonar-web/src/main/js/apps/component-measures/utils.js b/server/sonar-web/src/main/js/apps/component-measures/utils.js index fd60cf80236..6b3abc7eda4 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/utils.js +++ b/server/sonar-web/src/main/js/apps/component-measures/utils.js @@ -19,27 +19,28 @@ */ import bubbles from './config/bubbles'; import { - formatMeasure, - formatMeasureVariation, - getRatingTooltip as nextGetRatingTooltip + formatMeasure, + formatMeasureVariation, + getRatingTooltip as nextGetRatingTooltip } from '../../helpers/measures'; -export function isDiffMetric (metric) { +export function isDiffMetric(metric) { return metric.key.indexOf('new_') === 0; } -export function getLeakValue (measure, periodIndex = 1) { +export function getLeakValue(measure, periodIndex = 1) { if (!measure) { return null; } - const period = measure.periods ? - measure.periods.find(period => period.index === periodIndex) : null; + const period = measure.periods + ? measure.periods.find(period => period.index === periodIndex) + : null; return period ? period.value : null; } -export function getSingleMeasureValue (measures) { +export function getSingleMeasureValue(measures) { if (!measures || !measures.length) { return null; } @@ -47,20 +48,21 @@ export function getSingleMeasureValue (measures) { return measures[0].value; } -export function getSingleLeakValue (measures, periodIndex = 1) { +export function getSingleLeakValue(measures, periodIndex = 1) { if (!measures || !measures.length) { return null; } const measure = measures[0]; - const period = measure.periods ? - measure.periods.find(period => period.index === periodIndex) : null; + const period = measure.periods + ? measure.periods.find(period => period.index === periodIndex) + : null; return period ? period.value : null; } -export function formatLeak (value, metric) { +export function formatLeak(value, metric) { if (isDiffMetric(metric)) { return formatMeasure(value, metric.type); } else { @@ -68,8 +70,8 @@ export function formatLeak (value, metric) { } } -export function enhanceWithLeak (measures, periodIndex = 1) { - function enhanceSingle (measure) { +export function enhanceWithLeak(measures, periodIndex = 1) { + function enhanceSingle(measure) { return { ...measure, leak: getLeakValue(measure, periodIndex) }; } @@ -80,45 +82,43 @@ export function enhanceWithLeak (measures, periodIndex = 1) { } } -export function enhanceWithSingleMeasure (components, periodIndex = 1) { - return components - .map(component => { - return { - ...component, - value: getSingleMeasureValue(component.measures), - leak: getSingleLeakValue(component.measures, periodIndex) - }; - }); +export function enhanceWithSingleMeasure(components, periodIndex = 1) { + return components.map(component => { + return { + ...component, + value: getSingleMeasureValue(component.measures), + leak: getSingleLeakValue(component.measures, periodIndex) + }; + }); } -export function enhanceWithMeasure (components, metric, periodIndex = 1) { - return components - .map(component => { - const measuresWithLeak = enhanceWithLeak(component.measures, periodIndex); - const measure = measuresWithLeak.find(measure => measure.metric === metric); - const value = measure ? measure.value : null; - const leak = measure ? measure.leak : null; - return { ...component, value, leak, measures: measuresWithLeak }; - }); +export function enhanceWithMeasure(components, metric, periodIndex = 1) { + return components.map(component => { + const measuresWithLeak = enhanceWithLeak(component.measures, periodIndex); + const measure = measuresWithLeak.find(measure => measure.metric === metric); + const value = measure ? measure.value : null; + const leak = measure ? measure.leak : null; + return { ...component, value, leak, measures: measuresWithLeak }; + }); } -export function hasHistory (metricKey) { +export function hasHistory(metricKey) { return metricKey.indexOf('new_') !== 0; } -export function hasBubbleChart (domainName) { +export function hasBubbleChart(domainName) { return !!bubbles[domainName]; } -export function hasTreemap (metric) { +export function hasTreemap(metric) { return ['PERCENT', 'RATING', 'LEVEL'].indexOf(metric.type) !== -1; } -export function filterOutEmptyMeasures (components) { +export function filterOutEmptyMeasures(components) { return components.filter(component => component.value !== null || component.leak !== null); } -export function getRatingTooltip (metricKey, value) { +export function getRatingTooltip(metricKey, value) { const finalMetricKey = metricKey.indexOf('new_') === 0 ? metricKey.substr(4) : metricKey; const KNOWN_RATINGS = ['sqale_rating', 'reliability_rating', 'security_rating']; if (KNOWN_RATINGS.includes(finalMetricKey)) { diff --git a/server/sonar-web/src/main/js/apps/component/components/App.js b/server/sonar-web/src/main/js/apps/component/components/App.js index 735e89a21d1..8771c039178 100644 --- a/server/sonar-web/src/main/js/apps/component/components/App.js +++ b/server/sonar-web/src/main/js/apps/component/components/App.js @@ -29,8 +29,7 @@ export default class App extends React.Component { line?: string } } - } - + }; scrollToLine = () => { const { line } = this.props.location.query; if (line) { @@ -44,19 +43,20 @@ export default class App extends React.Component { } }; - render () { + render() { const { id, line } = this.props.location.query; const finalLine = line != null ? Number(line) : null; return ( - <div className="page"> + <div className="page"> <SourceViewer aroundLine={finalLine} component={id} highlightedLine={finalLine} - onLoaded={this.scrollToLine}/> - </div> + onLoaded={this.scrollToLine} + /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/component/routes.js b/server/sonar-web/src/main/js/apps/component/routes.js index 022e326a335..b8938d81faf 100644 --- a/server/sonar-web/src/main/js/apps/component/routes.js +++ b/server/sonar-web/src/main/js/apps/component/routes.js @@ -23,6 +23,6 @@ import { IndexRoute, Redirect } from 'react-router'; import App from './components/App'; export default [ - <Redirect key="1" from="/component/index" to="/component"/>, - <IndexRoute key="2" component={App}/> + <Redirect key="1" from="/component/index" to="/component" />, + <IndexRoute key="2" component={App} /> ]; diff --git a/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js b/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js index 0e87f4e8fc3..f632095516c 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/components/CustomMeasuresAppContainer.js @@ -23,12 +23,12 @@ import init from '../init'; import { getComponent } from '../../../store/rootReducer'; class CustomMeasuresAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { init(this.refs.container, this.props.component); } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/custom-measures/create-view.js b/server/sonar-web/src/main/js/apps/custom-measures/create-view.js index 43fa7396176..2c1363b237b 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/create-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/create-view.js @@ -21,8 +21,7 @@ import CustomMeasure from './custom-measure'; import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; const customMeasure = new CustomMeasure({ metricId: this.$('#create-custom-measure-metric').val(), @@ -31,18 +30,20 @@ export default FormView.extend({ projectId: this.options.projectId }); this.disableForm(); - return customMeasure.save(null, { - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return customMeasure + .save(null, { + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js b/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js index 3d3a550a877..1338212736a 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/custom-measure.js @@ -24,11 +24,11 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ idAttribute: 'id', - urlRoot () { + urlRoot() { return window.baseUrl + '/api/custom_measures'; }, - sync (method, model, options) { + sync(method, model, options) { const opts = options || {}; if (method === 'create') { defaults(opts, { @@ -54,4 +54,3 @@ export default Backbone.Model.extend({ return Backbone.ajax(opts); } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js b/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js index 2d2e132d494..512b11d279a 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/custom-measures.js @@ -24,45 +24,43 @@ import CustomMeasure from './custom-measure'; export default Backbone.Collection.extend({ model: CustomMeasure, - initialize (options) { + initialize(options) { this.projectId = options.projectId; }, - url () { + url() { return window.baseUrl + '/api/custom_measures/search'; }, - parse (r) { + parse(r) { this.total = r.total; this.p = r.p; this.ps = r.ps; return r.customMeasures; }, - fetch (options) { + fetch(options) { const opts = { data: {}, ...options }; this.q = opts.data.q; opts.data.projectId = this.projectId; return Backbone.Collection.prototype.fetch.call(this, opts); }, - fetchMore () { + fetchMore() { const p = this.p + 1; return this.fetch({ add: true, remove: false, data: { p, ps: this.ps, q: this.q } }); }, - refresh () { + refresh() { return this.fetch({ reset: true, data: { q: this.q } }); }, - hasMore () { + hasMore() { return this.total > this.p * this.ps; }, - getTakenMetrics () { + getTakenMetrics() { const metrics = this.map(model => model.get('metric').id); return uniq(metrics); } - }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js b/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js index 93ac4755a16..42c129e4427 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/delete-view.js @@ -23,26 +23,28 @@ import Template from './templates/custom-measures-delete.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { const that = this; const collection = this.model.collection; - return this.model.destroy({ - wait: true, - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .destroy({ + wait: true, + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/form-view.js b/server/sonar-web/src/main/js/apps/custom-measures/form-view.js index 39b7d8b3c79..d89fa0e800b 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/form-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/form-view.js @@ -24,13 +24,13 @@ import Template from './templates/custom-measures-form.hbs'; export default ModalForm.extend({ template: Template, - initialize () { + initialize() { this.metrics = new Metrics(); this.listenTo(this.metrics, 'reset', this.render); this.metrics.fetch({ reset: true }); }, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); this.$('#create-custom-measure-metric').select2({ @@ -39,22 +39,22 @@ export default ModalForm.extend({ }); }, - onDestroy () { + onDestroy() { ModalForm.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - getAvailableMetrics () { + getAvailableMetrics() { const takenMetrics = this.collection.getTakenMetrics(); return this.metrics.toJSON().filter(metric => takenMetrics.indexOf(metric.id) === -1); }, - serializeData () { + serializeData() { const metrics = this.getAvailableMetrics(); const isNew = !this.model; return { @@ -64,4 +64,3 @@ export default ModalForm.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/header-view.js b/server/sonar-web/src/main/js/apps/custom-measures/header-view.js index d9a61f1ae63..0c47f4e51ad 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/header-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/header-view.js @@ -28,16 +28,15 @@ export default Marionette.ItemView.extend({ 'click #custom-measures-create': 'onCreateClick' }, - onCreateClick (e) { + onCreateClick(e) { e.preventDefault(); this.createCustomMeasure(); }, - createCustomMeasure () { + createCustomMeasure() { new CreateView({ collection: this.collection, projectId: this.options.projectId }).render(); } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/init.js b/server/sonar-web/src/main/js/apps/custom-measures/init.js index a63ed638edb..debdadb157e 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/init.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/init.js @@ -25,7 +25,7 @@ import ListView from './list-view'; import ListFooterView from './list-footer-view'; const App = new Marionette.Application(); -const init = function (el, component) { +const init = function(el, component) { // Layout this.layout = new Layout({ el }); this.layout.render(); @@ -62,7 +62,6 @@ App.on('start', options => { init.call(App, options.el, options.component); }); -export default function (el, component) { +export default function(el, component) { App.start({ el, component }); } - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/layout.js b/server/sonar-web/src/main/js/apps/custom-measures/layout.js index 4cc3d7f652a..6630457663c 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/layout.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/layout.js @@ -29,4 +29,3 @@ export default Marionette.LayoutView.extend({ listFooterRegion: '#custom-measures-list-footer' } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js b/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js index a3df6fbd751..0830708a052 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/list-footer-view.js @@ -24,23 +24,23 @@ export default Marionette.ItemView.extend({ template: Template, collectionEvents: { - 'all': 'render' + all: 'render' }, events: { 'click #custom-measures-fetch-more': 'onMoreClick' }, - onMoreClick (e) { + onMoreClick(e) { e.preventDefault(); this.fetchMore(); }, - fetchMore () { + fetchMore() { this.collection.fetchMore(); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), total: this.collection.total, @@ -49,4 +49,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js b/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js index f0cf82e916f..374909f56b4 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/list-item-view.js @@ -31,34 +31,33 @@ export default Marionette.ItemView.extend({ 'click .js-custom-measure-delete': 'onDeleteClick' }, - onRender () { + onRender() { this.$el.attr('data-id', this.model.id); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onUpdateClick (e) { + onUpdateClick(e) { e.preventDefault(); this.updateCustomMeasure(); }, - onDeleteClick (e) { + onDeleteClick(e) { e.preventDefault(); this.deleteCustomMeasure(); }, - updateCustomMeasure () { + updateCustomMeasure() { new UpdateView({ model: this.model, collection: this.model.collection }).render(); }, - deleteCustomMeasure () { + deleteCustomMeasure() { new DeleteView({ model: this.model }).render(); } }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/list-view.js b/server/sonar-web/src/main/js/apps/custom-measures/list-view.js index 9d8af661b95..8a530bbb392 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/list-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/list-view.js @@ -26,4 +26,3 @@ export default Marionette.CompositeView.extend({ childView: ListItemView, childViewContainer: 'tbody' }); - diff --git a/server/sonar-web/src/main/js/apps/custom-measures/routes.js b/server/sonar-web/src/main/js/apps/custom-measures/routes.js index 57d44965c6d..cef57a1375d 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/routes.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import CustomMeasuresAppContainer from './components/CustomMeasuresAppContainer'; -export default ( - <IndexRoute component={CustomMeasuresAppContainer}/> -); +export default <IndexRoute component={CustomMeasuresAppContainer} />; diff --git a/server/sonar-web/src/main/js/apps/custom-measures/update-view.js b/server/sonar-web/src/main/js/apps/custom-measures/update-view.js index 24376d7c848..70ff5dbcc65 100644 --- a/server/sonar-web/src/main/js/apps/custom-measures/update-view.js +++ b/server/sonar-web/src/main/js/apps/custom-measures/update-view.js @@ -20,26 +20,27 @@ import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; this.model.set({ value: this.$('#create-custom-measure-value').val(), description: this.$('#create-custom-measure-description').val() }); this.disableForm(); - return this.model.save(null, { - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .save(null, { + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/components/GroupsAppContainer.js b/server/sonar-web/src/main/js/apps/groups/components/GroupsAppContainer.js index d8352cc6d48..6b2f868851c 100644 --- a/server/sonar-web/src/main/js/apps/groups/components/GroupsAppContainer.js +++ b/server/sonar-web/src/main/js/apps/groups/components/GroupsAppContainer.js @@ -21,11 +21,11 @@ import React from 'react'; import init from '../init'; export default class GroupsAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { init(this.refs.container); } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/groups/create-view.js b/server/sonar-web/src/main/js/apps/groups/create-view.js index 9935961e054..5e0c6132bfa 100644 --- a/server/sonar-web/src/main/js/apps/groups/create-view.js +++ b/server/sonar-web/src/main/js/apps/groups/create-view.js @@ -21,27 +21,28 @@ import Group from './group'; import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; const group = new Group({ name: this.$('#create-group-name').val(), description: this.$('#create-group-description').val() }); this.disableForm(); - return group.save(null, { - organization: this.collection.organization, - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return group + .save(null, { + organization: this.collection.organization, + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/delete-view.js b/server/sonar-web/src/main/js/apps/groups/delete-view.js index febd76a6ee0..c5aa60988a4 100644 --- a/server/sonar-web/src/main/js/apps/groups/delete-view.js +++ b/server/sonar-web/src/main/js/apps/groups/delete-view.js @@ -23,33 +23,35 @@ import Template from './templates/groups-delete.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { const that = this; const collection = this.model.collection; - return this.model.destroy({ - organization: collection.organization, - wait: true, - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - collection.total--; - that.destroy(); - }).fail(jqXHR => { - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .destroy({ + organization: collection.organization, + wait: true, + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + collection.total--; + that.destroy(); + }) + .fail(jqXHR => { + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); }, - showErrors (errors, warnings) { + showErrors(errors, warnings) { this.$('.js-modal-text').addClass('hidden'); this.disableForm(); ModalForm.prototype.showErrors.call(this, errors, warnings); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/form-view.js b/server/sonar-web/src/main/js/apps/groups/form-view.js index 841e7aedb8b..4ae9fe9a89f 100644 --- a/server/sonar-web/src/main/js/apps/groups/form-view.js +++ b/server/sonar-web/src/main/js/apps/groups/form-view.js @@ -23,19 +23,18 @@ import Template from './templates/groups-form.hbs'; export default ModalForm.extend({ template: Template, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { ModalForm.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/group.js b/server/sonar-web/src/main/js/apps/groups/group.js index 1e91f366ca7..a6a0d587a19 100644 --- a/server/sonar-web/src/main/js/apps/groups/group.js +++ b/server/sonar-web/src/main/js/apps/groups/group.js @@ -22,11 +22,11 @@ import pick from 'lodash/pick'; import Backbone from 'backbone'; export default Backbone.Model.extend({ - urlRoot () { + urlRoot() { return window.baseUrl + '/api/user_groups'; }, - sync (method, model, options) { + sync(method, model, options) { const opts = options || {}; if (method === 'create') { const data = pick(model.toJSON(), 'name', 'description'); @@ -61,4 +61,3 @@ export default Backbone.Model.extend({ return Backbone.ajax(opts); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/groups.js b/server/sonar-web/src/main/js/apps/groups/groups.js index 3a56e60b25c..e21b53ec6af 100644 --- a/server/sonar-web/src/main/js/apps/groups/groups.js +++ b/server/sonar-web/src/main/js/apps/groups/groups.js @@ -23,43 +23,43 @@ import Group from './group'; export default Backbone.Collection.extend({ model: Group, - initialize ({ organization }) { + initialize({ organization }) { this.organization = organization; }, - url () { + url() { return window.baseUrl + '/api/user_groups/search'; }, - parse (r) { + parse(r) { this.total = +r.total; this.p = +r.p; this.ps = +r.ps; return r.groups; }, - fetch (options) { + fetch(options) { const data = (options && options.data) || {}; this.q = data.q; - const finalOptions = this.organization ? { - ...options, - data: { ...data, organization: this.organization.key } - } : options; + const finalOptions = this.organization + ? { + ...options, + data: { ...data, organization: this.organization.key } + } + : options; return Backbone.Collection.prototype.fetch.call(this, finalOptions); }, - fetchMore () { + fetchMore() { const p = this.p + 1; return this.fetch({ add: true, remove: false, data: { p, ps: this.ps, q: this.q } }); }, - refresh () { + refresh() { return this.fetch({ reset: true, data: { q: this.q } }); }, - hasMore () { + hasMore() { return this.total > this.p * this.ps; } - }); - diff --git a/server/sonar-web/src/main/js/apps/groups/header-view.js b/server/sonar-web/src/main/js/apps/groups/header-view.js index 86e90d44b2f..537768242d8 100644 --- a/server/sonar-web/src/main/js/apps/groups/header-view.js +++ b/server/sonar-web/src/main/js/apps/groups/header-view.js @@ -25,31 +25,30 @@ export default Marionette.ItemView.extend({ template: Template, collectionEvents: { - 'request': 'showSpinner', - 'sync': 'hideSpinner' + request: 'showSpinner', + sync: 'hideSpinner' }, events: { 'click #groups-create': 'onCreateClick' }, - showSpinner () { + showSpinner() { this.$('.spinner').removeClass('hidden'); }, - hideSpinner () { + hideSpinner() { this.$('.spinner').addClass('hidden'); }, - onCreateClick (e) { + onCreateClick(e) { e.preventDefault(); this.createGroup(); }, - createGroup () { + createGroup() { new CreateView({ collection: this.collection }).render(); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/init.js b/server/sonar-web/src/main/js/apps/groups/init.js index f0d4983f392..5967a22bf76 100644 --- a/server/sonar-web/src/main/js/apps/groups/init.js +++ b/server/sonar-web/src/main/js/apps/groups/init.js @@ -26,7 +26,7 @@ import ListView from './list-view'; import ListFooterView from './list-footer-view'; const App = new Marionette.Application(); -const init = function ({ el, organization }) { +const init = function({ el, organization }) { // Layout this.layout = new Layout({ el }); this.layout.render(); @@ -58,7 +58,6 @@ App.on('start', options => { init.call(App, options); }); -export default function (el, organization) { +export default function(el, organization) { App.start({ el, organization }); } - diff --git a/server/sonar-web/src/main/js/apps/groups/layout.js b/server/sonar-web/src/main/js/apps/groups/layout.js index e1a2df6a65a..473e1f3a5fd 100644 --- a/server/sonar-web/src/main/js/apps/groups/layout.js +++ b/server/sonar-web/src/main/js/apps/groups/layout.js @@ -30,4 +30,3 @@ export default Marionette.LayoutView.extend({ listFooterRegion: '#groups-list-footer' } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/list-footer-view.js b/server/sonar-web/src/main/js/apps/groups/list-footer-view.js index f54ad9605c7..6062fbf0b05 100644 --- a/server/sonar-web/src/main/js/apps/groups/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/groups/list-footer-view.js @@ -24,23 +24,23 @@ export default Marionette.ItemView.extend({ template: Template, collectionEvents: { - 'all': 'render' + all: 'render' }, events: { 'click #groups-fetch-more': 'onMoreClick' }, - onMoreClick (e) { + onMoreClick(e) { e.preventDefault(); this.fetchMore(); }, - fetchMore () { + fetchMore() { this.collection.fetchMore(); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), total: this.collection.total, @@ -49,4 +49,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/list-item-view.js b/server/sonar-web/src/main/js/apps/groups/list-item-view.js index 77c5c7c8ab0..58ac7ef50b1 100644 --- a/server/sonar-web/src/main/js/apps/groups/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/groups/list-item-view.js @@ -35,44 +35,43 @@ export default Marionette.ItemView.extend({ 'click .js-group-users': 'onUsersClick' }, - onRender () { + onRender() { this.$el.attr('data-id', this.model.id); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onUpdateClick (e) { + onUpdateClick(e) { e.preventDefault(); this.updateGroup(); }, - onDeleteClick (e) { + onDeleteClick(e) { e.preventDefault(); this.deleteGroup(); }, - onUsersClick (e) { + onUsersClick(e) { e.preventDefault(); $('.tooltip').remove(); this.showUsers(); }, - updateGroup () { + updateGroup() { new UpdateView({ model: this.model, collection: this.model.collection }).render(); }, - deleteGroup () { + deleteGroup() { new DeleteView({ model: this.model }).render(); }, - showUsers () { + showUsers() { new UsersView({ model: this.model }).render(); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/list-view.js b/server/sonar-web/src/main/js/apps/groups/list-view.js index a2a75bb3742..52042b45663 100644 --- a/server/sonar-web/src/main/js/apps/groups/list-view.js +++ b/server/sonar-web/src/main/js/apps/groups/list-view.js @@ -27,27 +27,27 @@ export default Marionette.CompositeView.extend({ template: Template, collectionEvents: { - 'request': 'showLoading', - 'sync': 'hideLoading' + request: 'showLoading', + sync: 'hideLoading' }, - showLoading () { + showLoading() { this.$el.addClass('new-loading'); }, - hideLoading () { + hideLoading() { this.$el.removeClass('new-loading'); const query = this.collection.q || ''; - const shouldHideAnyone = this.collection.organization || !'anyone'.includes(query.toLowerCase()); + const shouldHideAnyone = this.collection.organization || + !'anyone'.includes(query.toLowerCase()); this.$('.js-anyone').toggleClass('hidden', shouldHideAnyone); }, - serializeData () { + serializeData() { return { ...Marionette.CompositeView.prototype.serializeData.apply(this, arguments), organization: this.collection.organization }; } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/routes.js b/server/sonar-web/src/main/js/apps/groups/routes.js index e08051eab57..682cb275dab 100644 --- a/server/sonar-web/src/main/js/apps/groups/routes.js +++ b/server/sonar-web/src/main/js/apps/groups/routes.js @@ -22,6 +22,4 @@ import { IndexRoute } from 'react-router'; import GroupsAppContainer from './components/GroupsAppContainer'; import forSingleOrganization from '../organizations/forSingleOrganization'; -export default ( - <IndexRoute component={forSingleOrganization(GroupsAppContainer)}/> -); +export default <IndexRoute component={forSingleOrganization(GroupsAppContainer)} />; diff --git a/server/sonar-web/src/main/js/apps/groups/search-view.js b/server/sonar-web/src/main/js/apps/groups/search-view.js index c48099c7848..6c25de952a0 100644 --- a/server/sonar-web/src/main/js/apps/groups/search-view.js +++ b/server/sonar-web/src/main/js/apps/groups/search-view.js @@ -30,21 +30,21 @@ export default Marionette.ItemView.extend({ 'keyup #groups-search-query': 'debouncedOnKeyUp' }, - initialize () { + initialize() { this._bufferedValue = null; this.debouncedOnKeyUp = debounce(this.onKeyUp, 400); }, - onRender () { + onRender() { this.delegateEvents(); }, - onFormSubmit (e) { + onFormSubmit(e) { e.preventDefault(); this.debouncedOnKeyUp(); }, - onKeyUp () { + onKeyUp() { const q = this.getQuery(); if (q === this._bufferedValue) { return; @@ -56,12 +56,11 @@ export default Marionette.ItemView.extend({ this.searchRequest = this.search(q); }, - getQuery () { + getQuery() { return this.$('#groups-search-query').val(); }, - search (q) { + search(q) { return this.collection.fetch({ reset: true, data: { q } }); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/update-view.js b/server/sonar-web/src/main/js/apps/groups/update-view.js index 70f3cbdc6b1..d785f929b34 100644 --- a/server/sonar-web/src/main/js/apps/groups/update-view.js +++ b/server/sonar-web/src/main/js/apps/groups/update-view.js @@ -20,27 +20,28 @@ import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; this.model.set({ name: this.$('#create-group-name').val(), description: this.$('#create-group-description').val() }); this.disableForm(); - return this.model.save(null, { - organization: this.collection.organization, - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .save(null, { + organization: this.collection.organization, + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/groups/users-view.js b/server/sonar-web/src/main/js/apps/groups/users-view.js index 9f07358759d..558be7d4160 100644 --- a/server/sonar-web/src/main/js/apps/groups/users-view.js +++ b/server/sonar-web/src/main/js/apps/groups/users-view.js @@ -24,14 +24,14 @@ import Template from './templates/groups-users.hbs'; export default Modal.extend({ template: Template, - onRender () { + onRender() { Modal.prototype.onRender.apply(this, arguments); new window.SelectList({ el: this.$('#groups-users'), width: '100%', readOnly: false, focusSearch: false, - format (item) { + format(item) { return `${item.name}<br><span class="note">${item.login}</span>`; }, queryParam: 'q', @@ -43,16 +43,15 @@ export default Modal.extend({ }, selectParameter: 'login', selectParameterValue: 'login', - parse (r) { + parse(r) { this.more = false; return r.users; } }); }, - onDestroy () { + onDestroy() { this.model.collection.refresh(); Modal.prototype.onDestroy.apply(this, arguments); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js b/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js index d7d1a67ebf3..40e9eae8ac5 100644 --- a/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js +++ b/server/sonar-web/src/main/js/apps/issues/BulkChangeForm.js @@ -37,14 +37,13 @@ type Issue = { transitions?: Array<string> }; -const hasAction = (action: string) => (issue: Issue) => ( - issue.actions && issue.actions.includes(action) -); +const hasAction = (action: string) => + (issue: Issue) => issue.actions && issue.actions.includes(action); export default ModalForm.extend({ template: Template, - initialize () { + initialize() { this.issues = null; this.paging = null; this.tags = null; @@ -52,7 +51,7 @@ export default ModalForm.extend({ this.loadTags(); }, - loadIssues () { + loadIssues() { const { query } = this.options; searchIssues({ ...query, @@ -65,14 +64,14 @@ export default ModalForm.extend({ }); }, - loadTags () { + loadTags() { searchIssueTags().then(r => { this.tags = r.tags; this.render(); }); }, - prepareAssigneeSelect () { + prepareAssigneeSelect() { const input = this.$('#assignee'); if (input.length) { const canBeAssignedToMe = this.issues && this.canBeAssignedToMe(this.issues); @@ -80,7 +79,10 @@ export default ModalForm.extend({ const canBeUnassigned = this.issues && this.canBeUnassigned(this.issues); const defaultOptions = []; if (canBeAssignedToMe && currentUser.isLoggedIn) { - defaultOptions.push({ id: currentUser.login, text: `${currentUser.name} (${currentUser.login})` }); + defaultOptions.push({ + id: currentUser.login, + text: `${currentUser.name} (${currentUser.login})` + }); } if (canBeUnassigned) { defaultOptions.push({ id: UNASSIGNED, text: translate('unassigned') }); @@ -92,7 +94,8 @@ export default ModalForm.extend({ width: INPUT_WIDTH, formatNoMatches: () => translate('select2.noMatches'), formatSearching: () => translate('select2.searching'), - formatInputTooShort: () => translateWithParameters('select2.tooShort', MINIMUM_QUERY_LENGTH), + formatInputTooShort: () => + translateWithParameters('select2.tooShort', MINIMUM_QUERY_LENGTH), query: query => { if (query.term.length === 0) { query.callback({ results: defaultOptions }); @@ -113,40 +116,47 @@ export default ModalForm.extend({ } }, - prepareTypeSelect () { - this.$('#type').select2({ - minimumResultsForSearch: 999, - width: INPUT_WIDTH - }).on('change', () => this.$('#set-type-action').prop('checked', true)); + prepareTypeSelect() { + this.$('#type') + .select2({ + minimumResultsForSearch: 999, + width: INPUT_WIDTH + }) + .on('change', () => this.$('#set-type-action').prop('checked', true)); }, - prepareSeveritySelect () { - const format = state => ( - state.id ? - `<i class="icon-severity-${state.id.toLowerCase()}"></i> ${state.text}` : - state.text - ); - this.$('#severity').select2({ - minimumResultsForSearch: 999, - width: INPUT_WIDTH, - formatResult: format, - formatSelection: format - }).on('change', () => this.$('#set-severity-action').prop('checked', true)); + prepareSeveritySelect() { + const format = state => + state.id + ? `<i class="icon-severity-${state.id.toLowerCase()}"></i> ${state.text}` + : state.text; + this.$('#severity') + .select2({ + minimumResultsForSearch: 999, + width: INPUT_WIDTH, + formatResult: format, + formatSelection: format + }) + .on('change', () => this.$('#set-severity-action').prop('checked', true)); }, - prepareTagsInput () { - this.$('#add_tags').select2({ - width: INPUT_WIDTH, - tags: this.tags - }).on('change', () => this.$('#add-tags-action').prop('checked', true)); + prepareTagsInput() { + this.$('#add_tags') + .select2({ + width: INPUT_WIDTH, + tags: this.tags + }) + .on('change', () => this.$('#add-tags-action').prop('checked', true)); - this.$('#remove_tags').select2({ - width: INPUT_WIDTH, - tags: this.tags - }).on('change', () => this.$('#remove-tags-action').prop('checked', true)); + this.$('#remove_tags') + .select2({ + width: INPUT_WIDTH, + tags: this.tags + }) + .on('change', () => this.$('#remove-tags-action').prop('checked', true)); }, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.prepareAssigneeSelect(); this.prepareTypeSelect(); @@ -154,7 +164,7 @@ export default ModalForm.extend({ this.prepareTagsInput(); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); const query = {}; @@ -215,35 +225,35 @@ export default ModalForm.extend({ ); }, - canBeAssigned (issues: Array<Issue>) { + canBeAssigned(issues: Array<Issue>) { return issues.filter(hasAction('assign')).length; }, - canBeAssignedToMe (issues: Array<Issue>) { + canBeAssignedToMe(issues: Array<Issue>) { return issues.filter(hasAction('assign_to_me')).length; }, - canBeUnassigned (issues: Array<Issue>) { + canBeUnassigned(issues: Array<Issue>) { return issues.filter(issue => issue.assignee).length; }, - canChangeType (issues: Array<Issue>) { + canChangeType(issues: Array<Issue>) { return issues.filter(hasAction('set_type')).length; }, - canChangeSeverity (issues: Array<Issue>) { + canChangeSeverity(issues: Array<Issue>) { return issues.filter(hasAction('set_severity')).length; }, - canChangeTags (issues: Array<Issue>) { + canChangeTags(issues: Array<Issue>) { return issues.filter(hasAction('set_tags')).length; }, - canBeCommented (issues: Array<Issue>) { + canBeCommented(issues: Array<Issue>) { return issues.filter(hasAction('comment')).length; }, - availableTransitions (issues: Array<Issue>) { + availableTransitions(issues: Array<Issue>) { const transitions = {}; issues.forEach(issue => { if (issue.transitions) { @@ -262,7 +272,7 @@ export default ModalForm.extend({ })); }, - serializeData () { + serializeData() { return { ...ModalForm.prototype.serializeData.apply(this, arguments), isLoaded: this.issues != null && this.tags != null, diff --git a/server/sonar-web/src/main/js/apps/issues/HeaderView.js b/server/sonar-web/src/main/js/apps/issues/HeaderView.js index 57a52667c78..596996f9d5c 100644 --- a/server/sonar-web/src/main/js/apps/issues/HeaderView.js +++ b/server/sonar-web/src/main/js/apps/issues/HeaderView.js @@ -28,11 +28,11 @@ export default Marionette.ItemView.extend({ 'change [name="issues-page-my"]': 'onMyIssuesChange' }, - initialize () { + initialize() { this.listenTo(this.options.app.state, 'change:query', this.render); }, - onMyIssuesChange () { + onMyIssuesChange() { const mode = this.$('[name="issues-page-my"]:checked').val(); if (mode === 'my') { this.options.app.state.updateFilter({ @@ -48,7 +48,7 @@ export default Marionette.ItemView.extend({ }); } }, - serializeData () { + serializeData() { const me = !!this.options.app.state.get('query').assigned_to_me; return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), @@ -58,4 +58,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js b/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js index 49d7152c45f..a1dcb64d7dc 100644 --- a/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js +++ b/server/sonar-web/src/main/js/apps/issues/component-viewer/main.js @@ -25,40 +25,40 @@ import SourceViewer from '../../../components/SourceViewer/SourceViewer'; import WithStore from '../../../components/shared/WithStore'; export default Marionette.ItemView.extend({ - template () { + template() { return '<div></div>'; }, - initialize (options) { + initialize(options) { this.handleLoadIssues = this.handleLoadIssues.bind(this); this.scrollToBaseIssue = this.scrollToBaseIssue.bind(this); this.selectIssue = this.selectIssue.bind(this); this.listenTo(options.app.state, 'change:selectedIndex', this.select); }, - onRender () { + onRender() { this.showViewer(); }, - onDestroy () { + onDestroy() { this.unbindShortcuts(); unmountComponentAtNode(this.el); }, - handleLoadIssues (component: string) { + handleLoadIssues(component: string) { // TODO fromLine: number, toLine: number const issues = this.options.app.list.toJSON().filter(issue => issue.componentKey === component); return Promise.resolve(issues); }, - showViewer (onLoaded) { + showViewer(onLoaded) { if (!this.baseIssue) { return; } const componentKey = this.baseIssue.get('component'); - render(( + render( <WithStore> <SourceViewer aroundLine={this.baseIssue.get('line')} @@ -67,19 +67,21 @@ export default Marionette.ItemView.extend({ loadIssues={this.handleLoadIssues} onLoaded={onLoaded} onIssueSelect={this.selectIssue} - selectedIssue={this.baseIssue.get('key')}/> - </WithStore> - ), this.el); + selectedIssue={this.baseIssue.get('key')} + /> + </WithStore>, + this.el + ); }, - openFileByIssue (issue) { + openFileByIssue(issue) { this.baseIssue = issue; this.selectedIssue = issue.get('key'); this.showViewer(this.scrollToBaseIssue); this.bindShortcuts(); }, - bindShortcuts () { + bindShortcuts() { key('up', 'componentViewer', () => { this.options.app.controller.selectPrev(); return false; @@ -94,11 +96,11 @@ export default Marionette.ItemView.extend({ }); }, - unbindShortcuts () { + unbindShortcuts() { key.deleteScope('componentViewer'); }, - select () { + select() { const selected = this.options.app.state.get('selectedIndex'); const selectedIssue = this.options.app.list.at(selected); @@ -111,21 +113,20 @@ export default Marionette.ItemView.extend({ } }, - scrollToLine (line) { + scrollToLine(line) { const row = this.$(`[data-line-number=${line}]`); const topOffset = $(window).height() / 2 - 60; const goal = row.length > 0 ? row.offset().top - topOffset : 0; $(window).scrollTop(goal); }, - selectIssue (issueKey) { + selectIssue(issueKey) { const issue = this.options.app.list.find(model => model.get('key') === issueKey); const index = this.options.app.list.indexOf(issue); this.options.app.state.set({ selectedIndex: index }); }, - scrollToBaseIssue () { + scrollToBaseIssue() { this.scrollToLine(this.baseIssue.get('line')); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesAppContainer.js b/server/sonar-web/src/main/js/apps/issues/components/IssuesAppContainer.js index 842e58927af..b1f3e70f3f0 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssuesAppContainer.js +++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesAppContainer.js @@ -27,23 +27,23 @@ class IssuesAppContainer extends React.Component { currentUser: React.PropTypes.any.isRequired }; - componentDidMount () { + componentDidMount() { this.stop = init(this.refs.container, this.props.currentUser); } - componentWillUnmount () { + componentWillUnmount() { this.stop(); } - render () { + render() { // placing container inside div is required, // because when backbone.marionette's layout is destroyed, // it also destroys the root element, // but react wants it to be there to unmount it return ( - <div> - <div ref="container"/> - </div> + <div> + <div ref="container" /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/issues/controller.js b/server/sonar-web/src/main/js/apps/issues/controller.js index 156a7f3632a..f98f292d4bd 100644 --- a/server/sonar-web/src/main/js/apps/issues/controller.js +++ b/server/sonar-web/src/main/js/apps/issues/controller.js @@ -27,7 +27,7 @@ import { receiveIssues } from '../../store/issues/duck'; const FACET_DATA_FIELDS = ['components', 'users', 'rules', 'languages']; export default Controller.extend({ - _issuesParameters () { + _issuesParameters() { return { p: this.options.app.state.get('page'), ps: this.pageSize, @@ -37,12 +37,12 @@ export default Controller.extend({ }; }, - receiveIssues (issues) { + receiveIssues(issues) { const store = getStore(); store.dispatch(receiveIssues(issues)); }, - fetchList (firstPage) { + fetchList(firstPage) { const that = this; if (firstPage == null) { firstPage = true; @@ -95,21 +95,26 @@ export default Controller.extend({ }); }, - isIssuePermalink () { + isIssuePermalink() { const query = this.options.app.state.get('query'); - return (query.issues != null) && this.options.app.list.length === 1; + return query.issues != null && this.options.app.list.length === 1; }, - _mergeCollections (a, b) { + _mergeCollections(a, b) { const collection = new Backbone.Collection(a); collection.add(b, { merge: true }); return collection.toJSON(); }, - requestFacet (id) { + requestFacet(id) { const that = this; const facet = this.options.app.facets.get(id); - const data = { facets: id, ps: 1, additionalFields: '_all', ...this.options.app.state.get('query') }; + const data = { + facets: id, + ps: 1, + additionalFields: '_all', + ...this.options.app.state.get('query') + }; if (this.options.app.state.get('query').assigned_to_me) { Object.assign(data, { assignees: '__me__' }); } @@ -118,7 +123,10 @@ export default Controller.extend({ } return $.get(window.baseUrl + '/api/issues/search', data, r => { FACET_DATA_FIELDS.forEach(field => { - that.options.app.facets[field] = that._mergeCollections(that.options.app.facets[field], r[field]); + that.options.app.facets[field] = that._mergeCollections( + that.options.app.facets[field], + r[field] + ); }); const facetData = r.facets.find(facet => facet.property === id); if (facetData != null) { @@ -127,12 +135,12 @@ export default Controller.extend({ }); }, - newSearch () { + newSearch() { this.options.app.state.unset('filter'); return this.options.app.state.setQuery({ resolved: 'false' }); }, - parseQuery () { + parseQuery() { const q = Controller.prototype.parseQuery.apply(this, arguments); delete q.asc; delete q.s; @@ -140,7 +148,7 @@ export default Controller.extend({ return q; }, - getQueryAsObject () { + getQueryAsObject() { const state = this.options.app.state; const query = state.get('query'); if (query.assigned_to_me) { @@ -152,7 +160,7 @@ export default Controller.extend({ return query; }, - getQuery (separator, addContext, handleMyIssues = false) { + getQuery(separator, addContext, handleMyIssues = false) { if (separator == null) { separator = '|'; } @@ -173,7 +181,7 @@ export default Controller.extend({ return route.join(separator); }, - _prepareComponent (issue) { + _prepareComponent(issue) { return { key: issue.get('component'), name: issue.get('componentLongName'), @@ -186,7 +194,7 @@ export default Controller.extend({ }; }, - showComponentViewer (issue) { + showComponentViewer(issue) { this.options.app.layout.workspaceComponentViewerRegion.reset(); key.setScope('componentViewer'); this.options.app.issuesView.unbindScrollEvents(); @@ -197,7 +205,7 @@ export default Controller.extend({ return this.options.app.componentViewer.openFileByIssue(issue); }, - closeComponentViewer () { + closeComponentViewer() { key.setScope('list'); $('body').click(); this.options.app.state.unset('component'); @@ -207,4 +215,3 @@ export default Controller.extend({ return this.options.app.issuesView.scrollTo(); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets-view.js b/server/sonar-web/src/main/js/apps/issues/facets-view.js index 02e5e8355eb..f706ef53a39 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets-view.js +++ b/server/sonar-web/src/main/js/apps/issues/facets-view.js @@ -56,9 +56,8 @@ const viewsMapping = { }; export default FacetsView.extend({ - getChildView (model) { + getChildView(model) { const view = viewsMapping[model.get('property')]; return view ? view : BaseFacet; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js index 5913ac7e923..471d7c75192 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/assignee-facet.js @@ -25,34 +25,34 @@ import Template from '../templates/facets/issues-assignee-facet.hbs'; export default CustomValuesFacet.extend({ template: Template, - getUrl () { + getUrl() { return window.baseUrl + '/api/users/search'; }, - prepareAjaxSearch () { + prepareAjaxSearch() { return { quietMillis: 300, url: this.getUrl(), - data (term, page) { + data(term, page) { return { q: term, p: page }; }, results: window.usersToSelect2 }; }, - onRender () { + onRender() { CustomValuesFacet.prototype.onRender.apply(this, arguments); const myIssuesSelected = !!this.options.app.state.get('query').assigned_to_me; this.$el.toggleClass('hidden', myIssuesSelected); const value = this.options.app.state.get('query').assigned; - if ((value != null) && (!value || value === 'false')) { + if (value != null && (!value || value === 'false')) { this.$('.js-facet').filter('[data-unassigned]').addClass('active'); } }, - toggleFacet (e) { + toggleFacet(e) { const unassigned = $(e.currentTarget).is('[data-unassigned]'); $(e.currentTarget).toggleClass('active'); if (unassigned) { @@ -72,7 +72,7 @@ export default CustomValuesFacet.extend({ } }, - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); const users = this.options.app.facets.users; values.forEach(v => { @@ -89,14 +89,14 @@ export default CustomValuesFacet.extend({ return values; }, - disable () { + disable() { return this.options.app.state.updateFilter({ assigned: null, assignees: null }); }, - addCustomValue () { + addCustomValue() { const property = this.model.get('property'); const customValue = this.$('.js-custom-value').select2('val'); let value = this.getValue(); @@ -110,15 +110,14 @@ export default CustomValuesFacet.extend({ return this.options.app.state.updateFilter(obj); }, - sortValues (values) { + sortValues(values) { return sortBy(values, v => v.val === '' ? -999999 : -v.count); }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js index 2725172d4d7..c652eba0abd 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js @@ -21,32 +21,32 @@ import CustomValuesFacet from './custom-values-facet'; import { translate, translateWithParameters } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ - getUrl () { + getUrl() { return window.baseUrl + '/api/issues/authors'; }, - prepareSearch () { + prepareSearch() { return this.$('.js-custom-value').select2({ placeholder: translate('search_verb'), minimumInputLength: 2, allowClear: false, - formatNoMatches () { + formatNoMatches() { return translate('select2.noMatches'); }, - formatSearching () { + formatSearching() { return translate('select2.searching'); }, - formatInputTooShort () { + formatInputTooShort() { return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: { quietMillis: 300, url: this.getUrl(), - data (term) { + data(term) { return { q: term, ps: 25 }; }, - results (data) { + results(data) { return { more: false, results: data.authors.map(author => { diff --git a/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js index 257e4f539ad..5d05caaeb2e 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/base-facet.js @@ -23,20 +23,19 @@ import Template from '../templates/facets/issues-base-facet.hbs'; export default BaseFacet.extend({ template: Template, - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); return this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' }); }, - onDestroy () { + onDestroy() { return this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), state: this.options.app.state.toJSON() }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js index 0fe178a0c35..a2f31cb9c37 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/context-facet.js @@ -23,11 +23,10 @@ import Template from '../templates/facets/issues-context-facet.hbs'; export default BaseFacet.extend({ template: Template, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), state: this.options.app.state.toJSON() }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js index 54eb5dd9e13..41110a8a6cd 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/creation-date-facet.js @@ -28,7 +28,7 @@ import { formatMeasure } from '../../../helpers/measures'; export default BaseFacet.extend({ template: Template, - events () { + events() { return { ...BaseFacet.prototype.events.apply(this, arguments), 'change input': 'applyFacet', @@ -43,7 +43,7 @@ export default BaseFacet.extend({ }; }, - onRender () { + onRender() { const that = this; this.$el.toggleClass('search-navigator-facet-box-collapsed', !this.model.get('enabled')); this.$('input').datepicker({ @@ -70,24 +70,26 @@ export default BaseFacet.extend({ values.reverse(); } values = values.map(v => { - const format = that.options.app.state.getFacetMode() === 'count' ? 'SHORT_INT' : 'SHORT_WORK_DUR'; + const format = that.options.app.state.getFacetMode() === 'count' + ? 'SHORT_INT' + : 'SHORT_WORK_DUR'; const text = formatMeasure(v.count, format); return { ...v, text }; }); return this.$('.js-barchart').barchart(values); }, - selectPeriodStart () { + selectPeriodStart() { return this.$('.js-period-start').datepicker('show'); }, - selectPeriodEnd () { + selectPeriodEnd() { return this.$('.js-period-end').datepicker('show'); }, - applyFacet () { + applyFacet() { const obj = { createdAt: null, createdInLast: null }; - this.$('input').each(function () { + this.$('input').each(function() { const property = $(this).prop('name'); const value = $(this).val(); obj[property] = value; @@ -95,7 +97,7 @@ export default BaseFacet.extend({ return this.options.app.state.updateFilter(obj); }, - disable () { + disable() { return this.options.app.state.updateFilter({ createdAfter: null, createdBefore: null, @@ -105,7 +107,7 @@ export default BaseFacet.extend({ }); }, - selectBar (e) { + selectBar(e) { const periodStart = $(e.currentTarget).data('period-start'); const periodEnd = $(e.currentTarget).data('period-end'); return this.options.app.state.updateFilter({ @@ -117,7 +119,7 @@ export default BaseFacet.extend({ }); }, - selectPeriod (period) { + selectPeriod(period) { return this.options.app.state.updateFilter({ createdAfter: null, createdBefore: null, @@ -127,27 +129,27 @@ export default BaseFacet.extend({ }); }, - onAllClick (e) { + onAllClick(e) { e.preventDefault(); return this.disable(); }, - onLastWeekClick (e) { + onLastWeekClick(e) { e.preventDefault(); return this.selectPeriod('1w'); }, - onLastMonthClick (e) { + onLastMonthClick(e) { e.preventDefault(); return this.selectPeriod('1m'); }, - onLastYearClick (e) { + onLastYearClick(e) { e.preventDefault(); return this.selectPeriod('1y'); }, - onLeakClick (e) { + onLeakClick(e) { e.preventDefault(); this.options.app.state.updateFilter({ createdAfter: null, @@ -158,7 +160,7 @@ export default BaseFacet.extend({ }); }, - serializeData () { + serializeData() { const hasLeak = this.options.app.state.get('contextComponentQualifier') === 'TRK'; return { @@ -172,4 +174,3 @@ export default BaseFacet.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js index c376b0c60ba..a6168f350f1 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js @@ -24,34 +24,32 @@ import { translate, translateWithParameters } from '../../../helpers/l10n'; export default BaseFacet.extend({ template: Template, - events () { + events() { return { ...BaseFacet.prototype.events.apply(this, arguments), 'change .js-custom-value': 'addCustomValue' }; }, - getUrl () { + getUrl() {}, - }, - - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); return this.prepareSearch(); }, - prepareSearch () { + prepareSearch() { return this.$('.js-custom-value').select2({ placeholder: translate('search_verb'), minimumInputLength: 2, allowClear: false, - formatNoMatches () { + formatNoMatches() { return translate('select2.noMatches'); }, - formatSearching () { + formatSearching() { return translate('select2.searching'); }, - formatInputTooShort () { + formatInputTooShort() { return translateWithParameters('select2.tooShort', 2); }, width: '100%', @@ -59,20 +57,20 @@ export default BaseFacet.extend({ }); }, - prepareAjaxSearch () { + prepareAjaxSearch() { return { quietMillis: 300, url: this.getUrl(), - data (term, page) { + data(term, page) { return { s: term, p: page }; }, - results (data) { + results(data) { return { more: data.more, results: data.results }; } }; }, - addCustomValue () { + addCustomValue() { const property = this.model.get('property'); const customValue = this.$('.js-custom-value').select2('val'); let value = this.getValue(); diff --git a/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js index de473867146..11b9a69a46d 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/file-facet.js @@ -24,16 +24,18 @@ import Template from '../templates/facets/issues-file-facet.hbs'; export default BaseFacet.extend({ template: Template, - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); - const widths = this.$('.facet-stat').map(function () { - return $(this).outerWidth(); - }).get(); + const widths = this.$('.facet-stat') + .map(function() { + return $(this).outerWidth(); + }) + .get(); const maxValueWidth = Math.max(...widths); return this.$('.facet-name').css('padding-right', maxValueWidth); }, - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); const source = this.options.app.facets.components; values.forEach(v => { @@ -50,11 +52,10 @@ export default BaseFacet.extend({ return values; }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js index d293cd69493..d57d9c79cce 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/issue-key-facet.js @@ -23,19 +23,18 @@ import Template from '../templates/facets/issues-issue-key-facet.hbs'; export default BaseFacet.extend({ template: Template, - onRender () { + onRender() { return this.$el.toggleClass('hidden', !this.options.app.state.get('query').issues); }, - disable () { + disable() { return this.options.app.state.updateFilter({ issues: null }); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), issues: this.options.app.state.get('query').issues }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js index e9bd0d7e702..789ae16ca93 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js @@ -21,32 +21,32 @@ import CustomValuesFacet from './custom-values-facet'; import { translate, translateWithParameters } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ - getUrl () { + getUrl() { return window.baseUrl + '/api/languages/list'; }, - prepareSearch () { + prepareSearch() { return this.$('.js-custom-value').select2({ placeholder: translate('search_verb'), minimumInputLength: 2, allowClear: false, - formatNoMatches () { + formatNoMatches() { return translate('select2.noMatches'); }, - formatSearching () { + formatSearching() { return translate('select2.searching'); }, - formatInputTooShort () { + formatInputTooShort() { return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: { quietMillis: 300, url: this.getUrl(), - data (term) { + data(term) { return { q: term, ps: 0 }; }, - results (data) { + results(data) { return { more: false, results: data.languages.map(lang => { @@ -58,7 +58,7 @@ export default CustomValuesFacet.extend({ }); }, - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); const source = this.options.app.facets.languages; values.forEach(v => { @@ -75,7 +75,7 @@ export default CustomValuesFacet.extend({ return values; }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) diff --git a/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js index fc15d54b2cb..dd54e82c8d2 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/mode-facet.js @@ -24,18 +24,17 @@ import Template from '../templates/facets/issues-mode-facet.hbs'; export default BaseFacet.extend({ template: Template, - toggleFacet (e) { + toggleFacet(e) { const isCount = $(e.currentTarget).is('[data-value="count"]'); return this.options.app.state.updateFilter({ facetMode: isCount ? 'count' : 'effort' }); }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), mode: this.options.app.state.getFacetMode() }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/module-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/module-facet.js index 8daa791519f..b6e87598bff 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/module-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/module-facet.js @@ -20,7 +20,7 @@ import BaseFacet from './base-facet'; export default BaseFacet.extend({ - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); const components = this.options.app.facets.components; values.forEach(v => { @@ -37,11 +37,10 @@ export default BaseFacet.extend({ return values; }, - serializeData () { + serializeData() { return { ...BaseFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js index 4e4e78722cf..9bd37e64b03 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js @@ -25,25 +25,25 @@ import { areThereCustomOrganizations, getOrganization } from '../../../store/org export default CustomValuesFacet.extend({ template: Template, - getUrl () { + getUrl() { return window.baseUrl + '/api/components/search'; }, - prepareSearchForViews () { + prepareSearchForViews() { const contextId = this.options.app.state.get('contextComponentUuid'); return { url: window.baseUrl + '/api/components/tree', - data (term, page) { + data(term, page) { return { q: term, p: page, qualifiers: 'TRK', baseComponentId: contextId }; } }; }, - prepareAjaxSearch () { + prepareAjaxSearch() { const options = { quietMillis: 300, url: this.getUrl(), - data (term, page) { + data(term, page) { return { q: term, p: page, qualifiers: 'TRK' }; }, results: r => ({ @@ -61,18 +61,18 @@ export default CustomValuesFacet.extend({ return options; }, - prepareSearch () { + prepareSearch() { return this.$('.js-custom-value').select2({ placeholder: translate('search_verb'), minimumInputLength: 3, allowClear: false, - formatNoMatches () { + formatNoMatches() { return translate('select2.noMatches'); }, - formatSearching () { + formatSearching() { return translate('select2.searching'); }, - formatInputTooShort () { + formatInputTooShort() { return translateWithParameters('select2.tooShort', 3); }, width: '100%', @@ -80,7 +80,7 @@ export default CustomValuesFacet.extend({ }); }, - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); const projects = this.options.app.facets.components; const displayOrganizations = areThereCustomOrganizations(); @@ -92,8 +92,9 @@ export default CustomValuesFacet.extend({ const project = projects.find(p => p.uuid === uuid); if (project != null) { label = project.longName; - organization = displayOrganizations && project.organization ? - getOrganization(project.organization) : null; + organization = displayOrganizations && project.organization + ? getOrganization(project.organization) + : null; } } v.label = label; @@ -102,7 +103,7 @@ export default CustomValuesFacet.extend({ return values; }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) diff --git a/server/sonar-web/src/main/js/apps/issues/facets/reporter-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/reporter-facet.js index b4ff93f08b6..3e691aea9be 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/reporter-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/reporter-facet.js @@ -20,22 +20,22 @@ import CustomValuesFacet from './custom-values-facet'; export default CustomValuesFacet.extend({ - getUrl () { + getUrl() { return window.baseUrl + '/api/users/search'; }, - prepareAjaxSearch () { + prepareAjaxSearch() { return { quietMillis: 300, url: this.getUrl(), - data (term, page) { + data(term, page) { return { q: term, p: page }; }, results: window.usersToSelect2 }; }, - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); const source = this.options.app.facets.users; values.forEach(v => { @@ -52,11 +52,10 @@ export default CustomValuesFacet.extend({ return values; }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js index b3a44863fd3..c0289fe5956 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/resolution-facet.js @@ -25,15 +25,15 @@ import Template from '../templates/facets/issues-resolution-facet.hbs'; export default BaseFacet.extend({ template: Template, - onRender () { + onRender() { BaseFacet.prototype.onRender.apply(this, arguments); const value = this.options.app.state.get('query').resolved; - if ((value != null) && (!value || value === 'false')) { + if (value != null && (!value || value === 'false')) { this.$('.js-facet').filter('[data-unresolved]').addClass('active'); } }, - toggleFacet (e) { + toggleFacet(e) { const unresolved = $(e.currentTarget).is('[data-unresolved]'); $(e.currentTarget).toggleClass('active'); if (unresolved) { @@ -51,16 +51,15 @@ export default BaseFacet.extend({ } }, - disable () { + disable() { return this.options.app.state.updateFilter({ resolved: null, resolutions: null }); }, - sortValues (values) { + sortValues(values) { const order = ['', 'FIXED', 'FALSE-POSITIVE', 'WONTFIX', 'REMOVED']; return sortBy(values, v => order.indexOf(v.val)); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js index 14ff18c0d18..75445570098 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js @@ -21,7 +21,7 @@ import CustomValuesFacet from './custom-values-facet'; import { translate, translateWithParameters } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ - prepareSearch () { + prepareSearch() { let url = window.baseUrl + '/api/rules/search?f=name,langName'; const languages = this.options.app.state.get('query').languages; if (languages != null) { @@ -31,23 +31,23 @@ export default CustomValuesFacet.extend({ placeholder: translate('search_verb'), minimumInputLength: 2, allowClear: false, - formatNoMatches () { + formatNoMatches() { return translate('select2.noMatches'); }, - formatSearching () { + formatSearching() { return translate('select2.searching'); }, - formatInputTooShort () { + formatInputTooShort() { return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: { url, quietMillis: 300, - data (term, page) { + data(term, page) { return { q: term, p: page }; }, - results (data) { + results(data) { const results = data.rules.map(rule => { const lang = rule.langName || translate('manual'); return { @@ -64,7 +64,7 @@ export default CustomValuesFacet.extend({ }); }, - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); const rules = this.options.app.facets.rules; values.forEach(v => { @@ -86,7 +86,7 @@ export default CustomValuesFacet.extend({ return values; }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) diff --git a/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js index 7c5fdf42dbd..6e2a83deb6b 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/severity-facet.js @@ -24,9 +24,8 @@ import Template from '../templates/facets/issues-severity-facet.hbs'; export default BaseFacet.extend({ template: Template, - sortValues (values) { + sortValues(values) { const order = ['BLOCKER', 'MINOR', 'CRITICAL', 'INFO', 'MAJOR']; return sortBy(values, v => order.indexOf(v.val)); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js index c805b66687b..4259ecb1930 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/status-facet.js @@ -24,9 +24,8 @@ import Template from '../templates/facets/issues-status-facet.hbs'; export default BaseFacet.extend({ template: Template, - sortValues (values) { + sortValues(values) { const order = ['OPEN', 'RESOLVED', 'REOPENED', 'CLOSED', 'CONFIRMED']; return sortBy(values, v => order.indexOf(v.val)); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js index dbb30433e05..8bb629ff3d4 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js @@ -21,7 +21,7 @@ import CustomValuesFacet from './custom-values-facet'; import { translate } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ - prepareSearch () { + prepareSearch() { let url = window.baseUrl + '/api/issues/tags?ps=10'; const tags = this.options.app.state.get('query').tags; if (tags != null) { @@ -31,20 +31,20 @@ export default CustomValuesFacet.extend({ placeholder: translate('search_verb'), minimumInputLength: 0, allowClear: false, - formatNoMatches () { + formatNoMatches() { return translate('select2.noMatches'); }, - formatSearching () { + formatSearching() { return translate('select2.searching'); }, width: '100%', ajax: { url, quietMillis: 300, - data (term) { + data(term) { return { q: term, ps: 10 }; }, - results (data) { + results(data) { const results = data.tags.map(tag => { return { id: tag, text: tag }; }); @@ -54,7 +54,7 @@ export default CustomValuesFacet.extend({ }); }, - getValuesWithLabels () { + getValuesWithLabels() { const values = this.model.getValues(); values.forEach(v => { v.label = v.val; @@ -63,7 +63,7 @@ export default CustomValuesFacet.extend({ return values; }, - serializeData () { + serializeData() { return { ...CustomValuesFacet.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.getValuesWithLabels()) diff --git a/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js index 63ebd0921f1..6cc723ade7b 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/type-facet.js @@ -24,9 +24,8 @@ import Template from '../templates/facets/issues-type-facet.hbs'; export default BaseFacet.extend({ template: Template, - sortValues (values) { + sortValues(values) { const order = ['BUG', 'VULNERABILITY', 'CODE_SMELL']; return sortBy(values, v => order.indexOf(v.val)); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/init.js b/server/sonar-web/src/main/js/apps/issues/init.js index 8a1d1757385..0fb32e839ab 100644 --- a/server/sonar-web/src/main/js/apps/issues/init.js +++ b/server/sonar-web/src/main/js/apps/issues/init.js @@ -32,7 +32,7 @@ import FacetsView from './facets-view'; import HeaderView from './HeaderView'; const App = new Marionette.Application(); -const init = function ({ el, user }) { +const init = function({ el, user }) { this.state = new State({ user, canBulkChange: user.isLoggedIn }); this.list = new Issues(); this.facets = new Facets(); @@ -76,7 +76,7 @@ App.on('start', el => { init.call(App, el); }); -export default function (el, user) { +export default function(el, user) { App.start({ el, user }); return () => { @@ -85,4 +85,3 @@ export default function (el, user) { $('#footer').removeClass('search-navigator-footer'); }; } - diff --git a/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js b/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js index e9f24195def..c3f45efbfe9 100644 --- a/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js +++ b/server/sonar-web/src/main/js/apps/issues/issue-filter-view.js @@ -24,18 +24,17 @@ import Template from './templates/issues-issue-filter-form.hbs'; export default ActionOptionsView.extend({ template: Template, - selectOption (e) { + selectOption(e) { const property = $(e.currentTarget).data('property'); const value = $(e.currentTarget).data('value'); this.trigger('select', property, value); ActionOptionsView.prototype.selectOption.apply(this, arguments); }, - serializeData () { + serializeData() { return { ...ActionOptionsView.prototype.serializeData.apply(this, arguments), s: this.model.get('severity') }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/layout.js b/server/sonar-web/src/main/js/apps/issues/layout.js index 08197adb658..c796baccb9c 100644 --- a/server/sonar-web/src/main/js/apps/issues/layout.js +++ b/server/sonar-web/src/main/js/apps/issues/layout.js @@ -33,29 +33,30 @@ export default Marionette.LayoutView.extend({ workspaceComponentViewerRegion: '.issues-workspace-component-viewer' }, - onRender () { + onRender() { this.$('.search-navigator').addClass('sticky'); const top = this.$('.search-navigator').offset().top; this.$('.search-navigator-workspace-header').css({ top }); this.$('.search-navigator-side').css({ top }).isolatedScroll(); }, - showSpinner (region) { - return this[region].show(new Marionette.ItemView({ - template: () => '<i class="spinner"></i>' - })); + showSpinner(region) { + return this[region].show( + new Marionette.ItemView({ + template: () => '<i class="spinner"></i>' + }) + ); }, - showComponentViewer () { + showComponentViewer() { this.scroll = $(window).scrollTop(); this.$('.issues').addClass('issues-extended-view'); }, - hideComponentViewer () { + hideComponentViewer() { this.$('.issues').removeClass('issues-extended-view'); if (this.scroll != null) { $(window).scrollTop(this.scroll); } } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/models/issue.js b/server/sonar-web/src/main/js/apps/issues/models/issue.js index 8878d04f6e7..218e27810ad 100644 --- a/server/sonar-web/src/main/js/apps/issues/models/issue.js +++ b/server/sonar-web/src/main/js/apps/issues/models/issue.js @@ -20,7 +20,7 @@ import Issue from '../../../components/issue/models/issue'; export default Issue.extend({ - reset (attrs, options) { + reset(attrs, options) { const keepFields = ['index', 'selected', 'comments']; keepFields.forEach(field => { attrs[field] = this.get(field); @@ -28,4 +28,3 @@ export default Issue.extend({ return Issue.prototype.reset.call(this, attrs, options); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/models/issues.js b/server/sonar-web/src/main/js/apps/issues/models/issues.js index d7340187c0a..9ea6454a484 100644 --- a/server/sonar-web/src/main/js/apps/issues/models/issues.js +++ b/server/sonar-web/src/main/js/apps/issues/models/issues.js @@ -23,11 +23,11 @@ import Issue from './issue'; export default Backbone.Collection.extend({ model: Issue, - url () { + url() { return window.baseUrl + '/api/issues/search'; }, - _injectRelational (issue, source, baseField, lookupField) { + _injectRelational(issue, source, baseField, lookupField) { const baseValue = issue[baseField]; if (baseValue != null && Array.isArray(source) && source.length > 0) { const lookupValue = source.find(candidate => candidate[lookupField] === baseValue); @@ -41,7 +41,7 @@ export default Backbone.Collection.extend({ return issue; }, - _injectCommentsRelational (issue, users) { + _injectCommentsRelational(issue, users) { if (issue.comments) { const that = this; const newComments = issue.comments.map(comment => { @@ -55,7 +55,7 @@ export default Backbone.Collection.extend({ return issue; }, - _prepareClosed (issue) { + _prepareClosed(issue) { if (issue.status === 'CLOSED') { issue.flows = []; delete issue.textRange; @@ -63,7 +63,7 @@ export default Backbone.Collection.extend({ return issue; }, - ensureTextRange (issue) { + ensureTextRange(issue) { if (issue.line && !issue.textRange) { // FIXME 999999 issue.textRange = { @@ -76,7 +76,7 @@ export default Backbone.Collection.extend({ return issue; }, - parseIssues (r, startIndex = 0) { + parseIssues(r, startIndex = 0) { const that = this; return r.issues.map((issue, index) => { Object.assign(issue, { index: startIndex + index }); @@ -92,11 +92,11 @@ export default Backbone.Collection.extend({ }); }, - setIndex () { + setIndex() { return this.forEach((issue, index) => issue.set({ index })); }, - selectByKeys (keys) { + selectByKeys(keys) { const that = this; keys.forEach(key => { const issue = that.get(key); @@ -106,4 +106,3 @@ export default Backbone.Collection.extend({ }); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/models/state.js b/server/sonar-web/src/main/js/apps/issues/models/state.js index a972f951cd1..b367cc670b0 100644 --- a/server/sonar-web/src/main/js/apps/issues/models/state.js +++ b/server/sonar-web/src/main/js/apps/issues/models/state.js @@ -61,22 +61,21 @@ export default State.extend({ 'createdAt' ], transform: { - 'resolved': 'resolutions', - 'assigned': 'assignees', - 'createdBefore': 'createdAt', - 'createdAfter': 'createdAt', - 'sinceLeakPeriod': 'createdAt', - 'createdInLast': 'createdAt' + resolved: 'resolutions', + assigned: 'assignees', + createdBefore: 'createdAt', + createdAfter: 'createdAt', + sinceLeakPeriod: 'createdAt', + createdInLast: 'createdAt' } }, - getFacetMode () { + getFacetMode() { const query = this.get('query'); return query.facetMode || 'count'; }, - toJSON () { + toJSON() { return { facetMode: this.getFacetMode(), ...this.attributes }; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/router.js b/server/sonar-web/src/main/js/apps/issues/router.js index 680de8b4538..ac35322a355 100644 --- a/server/sonar-web/src/main/js/apps/issues/router.js +++ b/server/sonar-web/src/main/js/apps/issues/router.js @@ -25,12 +25,11 @@ export default Router.extend({ ':query': 'index' }, - home () { + home() { return this.navigate('resolved=false', { trigger: true, replace: true }); }, - index (query) { + index(query) { this.options.app.state.setQuery(this.options.app.controller.parseQuery(query)); } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/routes.js b/server/sonar-web/src/main/js/apps/issues/routes.js index 3e779a1b90d..94f564e8728 100644 --- a/server/sonar-web/src/main/js/apps/issues/routes.js +++ b/server/sonar-web/src/main/js/apps/issues/routes.js @@ -26,6 +26,6 @@ const onSearchEnter = (nextState, replace) => { }; export default [ - <IndexRoute key="index" component={IssuesAppContainer}/>, - <Route key="search" path="search" onEnter={onSearchEnter}/> + <IndexRoute key="index" component={IssuesAppContainer} />, + <Route key="search" path="search" onEnter={onSearchEnter} /> ]; diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js index 10354a9cb1b..877ace41d16 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-header-view.js @@ -25,7 +25,7 @@ import { getOrganization, areThereCustomOrganizations } from '../../store/organi export default WorkspaceHeaderView.extend({ template: Template, - events () { + events() { return { ...WorkspaceHeaderView.prototype.events.apply(this, arguments), 'click .js-selection': 'onSelectionClick', @@ -35,17 +35,17 @@ export default WorkspaceHeaderView.extend({ }; }, - onSelectionClick (e) { + onSelectionClick(e) { e.preventDefault(); this.toggleSelection(); }, - onBulkChangeSelectedClick (e) { + onBulkChangeSelectedClick(e) { e.preventDefault(); this.bulkChangeSelected(); }, - afterBulkChange () { + afterBulkChange() { const selectedIndex = this.options.app.state.get('selectedIndex'); const selectedKeys = this.options.app.list.where({ selected: true }).map(item => item.id); this.options.app.controller.fetchList().done(() => { @@ -54,20 +54,20 @@ export default WorkspaceHeaderView.extend({ }); }, - render () { + render() { if (!this._suppressUpdate) { WorkspaceHeaderView.prototype.render.apply(this, arguments); } }, - toggleSelection () { + toggleSelection() { this._suppressUpdate = true; const selectedCount = this.options.app.list.where({ selected: true }).length; const someSelected = selectedCount > 0; return someSelected ? this.selectNone() : this.selectAll(); }, - selectNone () { + selectNone() { this.options.app.list.where({ selected: true }).forEach(issue => { issue.set({ selected: false }); }); @@ -75,7 +75,7 @@ export default WorkspaceHeaderView.extend({ this.render(); }, - selectAll () { + selectAll() { this.options.app.list.forEach(issue => { issue.set({ selected: true }); }); @@ -83,15 +83,15 @@ export default WorkspaceHeaderView.extend({ this.render(); }, - returnToList () { + returnToList() { this.options.app.controller.closeComponentViewer(); }, - newSearch () { + newSearch() { this.options.app.controller.newSearch(); }, - bulkChange () { + bulkChange() { const query = this.options.app.controller.getQueryAsObject(); new BulkChangeForm({ query, @@ -99,7 +99,7 @@ export default WorkspaceHeaderView.extend({ }).render(); }, - bulkChangeSelected () { + bulkChangeSelected() { const selected = this.options.app.list.where({ selected: true }); const selectedKeys = selected.map(item => item.id).slice(0, 500); const query = { issues: selectedKeys.join() }; @@ -109,7 +109,7 @@ export default WorkspaceHeaderView.extend({ }).render(); }, - serializeData () { + serializeData() { const issuesCount = this.options.app.list.length; const selectedCount = this.options.app.list.where({ selected: true }).length; const allSelected = issuesCount > 0 && issuesCount === selectedCount; @@ -131,11 +131,12 @@ export default WorkspaceHeaderView.extend({ data.state.component.project = null; data.state.component.subProject = null; } else { - const organization = areThereCustomOrganizations() ? getOrganization(component.projectOrganization) : null; + const organization = areThereCustomOrganizations() + ? getOrganization(component.projectOrganization) + : null; Object.assign(data, { organization }); } } return data; } }); - diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js index 6ff7dc1b23a..eea72dc3e28 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js @@ -23,7 +23,7 @@ import { translate } from '../../helpers/l10n'; export default Marionette.ItemView.extend({ className: 'search-navigator-no-results', - template () { + template() { return translate('issue_filter.no_issues'); } }); diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js index 8c357939b0e..ec59af550c0 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-list-item-view.js @@ -38,7 +38,7 @@ const SHOULD_NULL = { export default Marionette.ItemView.extend({ className: 'issues-workspace-list-item', - initialize (options) { + initialize(options) { this.openComponentViewer = this.openComponentViewer.bind(this); this.onIssueFilterClick = this.onIssueFilterClick.bind(this); this.onIssueCheck = this.onIssueCheck.bind(this); @@ -47,11 +47,11 @@ export default Marionette.ItemView.extend({ this.subscribeToStore(); }, - template () { + template() { return '<div></div>'; }, - subscribeToStore () { + subscribeToStore() { const store = getStore(); store.subscribe(() => { const issue = getIssueByKey(store.getState(), this.model.get('key')); @@ -59,18 +59,18 @@ export default Marionette.ItemView.extend({ }); }, - onRender () { + onRender() { this.showIssue(); }, - onDestroy () { + onDestroy() { unmountComponentAtNode(this.el); }, - showIssue () { + showIssue() { const selected = this.model.get('index') === this.options.app.state.get('selectedIndex'); - render(( + render( <WithStore> <ConnectedIssue issueKey={this.model.get('key')} @@ -78,12 +78,14 @@ export default Marionette.ItemView.extend({ onCheck={this.onIssueCheck} onClick={this.openComponentViewer} onFilterClick={this.onIssueFilterClick} - selected={selected}/> - </WithStore> - ), this.el); + selected={selected} + /> + </WithStore>, + this.el + ); }, - onIssueFilterClick (e) { + onIssueFilterClick(e) { const that = this; e.preventDefault(); e.stopPropagation(); @@ -110,7 +112,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - onIssueCheck (e) { + onIssueCheck(e) { e.preventDefault(); e.stopPropagation(); this.model.set({ selected: !this.model.get('selected') }); @@ -118,7 +120,7 @@ export default Marionette.ItemView.extend({ this.options.app.state.set({ selected }); }, - changeSelection () { + changeSelection() { const selected = this.model.get('index') === this.options.app.state.get('selectedIndex'); if (selected) { this.select(); @@ -127,26 +129,29 @@ export default Marionette.ItemView.extend({ } }, - selectCurrent () { + selectCurrent() { this.options.app.state.set({ selectedIndex: this.model.get('index') }); }, - resetIssue (options) { + resetIssue(options) { const that = this; const key = this.model.get('key'); const componentUuid = this.model.get('componentUuid'); const index = this.model.get('index'); const selected = this.model.get('selected'); - this.model.reset({ - key, - componentUuid, - index, - selected - }, { silent: true }); + this.model.reset( + { + key, + componentUuid, + index, + selected + }, + { silent: true } + ); return this.model.fetch(options).done(() => that.trigger('reset')); }, - openComponentViewer () { + openComponentViewer() { this.options.app.state.set({ selectedIndex: this.model.get('index') }); if (this.options.app.state.has('component')) { return this.options.app.controller.closeComponentViewer(); diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js index 383d3145f24..f74b7c912b2 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-list-view.js @@ -35,7 +35,7 @@ export default WorkspaceListView.extend({ childViewContainer: '.js-list', emptyView: EmptyView, - bindShortcuts () { + bindShortcuts() { const that = this; WorkspaceListView.prototype.bindShortcuts.apply(this, arguments); key('right', 'list', () => { @@ -50,13 +50,13 @@ export default WorkspaceListView.extend({ }); }, - unbindShortcuts () { + unbindShortcuts() { WorkspaceListView.prototype.unbindShortcuts.apply(this, arguments); key.unbind('right', 'list'); key.unbind('space', 'list'); }, - scrollTo () { + scrollTo() { const selectedIssue = this.collection.at(this.options.app.state.get('selectedIndex')); if (selectedIssue == null) { return; @@ -67,7 +67,9 @@ export default WorkspaceListView.extend({ if (selectedIssueView.$el.prev().is('.issues-workspace-list-component')) { viewTop -= COMPONENT_HEIGHT; } - const viewBottom = selectedIssueView.$el.offset().top + selectedIssueView.$el.outerHeight() + BOTTOM_OFFSET; + const viewBottom = selectedIssueView.$el.offset().top + + selectedIssueView.$el.outerHeight() + + BOTTOM_OFFSET; const windowTop = $(window).scrollTop(); const windowBottom = windowTop + $(window).height(); if (viewTop < windowTop) { @@ -78,7 +80,7 @@ export default WorkspaceListView.extend({ } }, - attachHtml (compositeView, childView, index) { + attachHtml(compositeView, childView, index) { const container = this.getChildViewContainer(compositeView); const model = this.collection.at(index); if (model != null) { @@ -98,7 +100,7 @@ export default WorkspaceListView.extend({ container.append(childView.el); }, - displayComponent (container, model) { + displayComponent(container, model) { const data = { ...model.toJSON() }; const qualifier = this.options.app.state.get('contextComponentQualifier'); if (qualifier === 'VW' || qualifier === 'SVW') { @@ -108,13 +110,15 @@ export default WorkspaceListView.extend({ } else if (qualifier === 'BRC') { Object.assign(data, { organization: undefined, project: undefined, subProject: undefined }); } else { - const organization = areThereCustomOrganizations() ? getOrganization(model.get('projectOrganization')) : null; + const organization = areThereCustomOrganizations() + ? getOrganization(model.get('projectOrganization')) + : null; Object.assign(data, { organization }); } container.append(this.componentTemplate(data)); }, - destroyChildren () { + destroyChildren() { WorkspaceListView.prototype.destroyChildren.apply(this, arguments); this.$('.issues-workspace-list-component').remove(); } diff --git a/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js b/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js index 480cae44e6a..e7c94acd956 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js +++ b/server/sonar-web/src/main/js/apps/maintenance/components/MaintenanceAppContainer.js @@ -21,11 +21,11 @@ import React from 'react'; import init from '../init'; export default class MaintenanceAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { init(this.refs.container, false); } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js b/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js index 92cd653d09b..d29ec360bdd 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js +++ b/server/sonar-web/src/main/js/apps/maintenance/components/SetupAppContainer.js @@ -21,11 +21,11 @@ import React from 'react'; import init from '../init'; export default class SetupAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { init(this.refs.container, true); } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/maintenance/init.js b/server/sonar-web/src/main/js/apps/maintenance/init.js index f35ebe571b2..3d86d8fc881 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/init.js +++ b/server/sonar-web/src/main/js/apps/maintenance/init.js @@ -32,7 +32,6 @@ App.on('start', options => { mainView.render().refresh(); }); -export default function (el, setup) { +export default function(el, setup) { App.start({ el, setup }); } - diff --git a/server/sonar-web/src/main/js/apps/maintenance/main-view.js b/server/sonar-web/src/main/js/apps/maintenance/main-view.js index 502105b754b..064ac731f10 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/main-view.js +++ b/server/sonar-web/src/main/js/apps/maintenance/main-view.js @@ -29,18 +29,21 @@ export default Marionette.ItemView.extend({ 'click #start-migration': 'startMigration' }, - initialize () { + initialize() { this.requestOptions = { type: 'GET', url: window.baseUrl + '/api/system/' + (this.options.setup ? 'db_migration_status' : 'status') }; - this.pollingInternal = setInterval(() => { - this.refresh(); - }, 5000); + this.pollingInternal = setInterval( + () => { + this.refresh(); + }, + 5000 + ); this.wasStarting = false; }, - refresh () { + refresh() { return Backbone.ajax(this.requestOptions).done(r => { if (r.status === 'STARTING') { this.wasStarting = true; @@ -59,11 +62,11 @@ export default Marionette.ItemView.extend({ }); }, - stopPolling () { + stopPolling() { clearInterval(this.pollingInternal); }, - startMigration () { + startMigration() { Backbone.ajax({ url: window.baseUrl + '/api/system/migrate_db', type: 'POST' @@ -73,21 +76,26 @@ export default Marionette.ItemView.extend({ }); }, - onRender () { - $('.page-simple').toggleClass('panel-warning', this.model.get('state') === 'MIGRATION_REQUIRED'); + onRender() { + $('.page-simple').toggleClass( + 'panel-warning', + this.model.get('state') === 'MIGRATION_REQUIRED' + ); }, - goHome () { - setInterval(() => { - window.location = window.baseUrl + '/'; - }, 2500); + goHome() { + setInterval( + () => { + window.location = window.baseUrl + '/'; + }, + 2500 + ); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), setup: this.options.setup }; } }); - diff --git a/server/sonar-web/src/main/js/apps/maintenance/routes.js b/server/sonar-web/src/main/js/apps/maintenance/routes.js index aefaf292080..e6b19e9a5a3 100644 --- a/server/sonar-web/src/main/js/apps/maintenance/routes.js +++ b/server/sonar-web/src/main/js/apps/maintenance/routes.js @@ -22,10 +22,6 @@ import { IndexRoute } from 'react-router'; import MaintenanceAppContainer from './components/MaintenanceAppContainer'; import SetupAppContainer from './components/SetupAppContainer'; -export const maintenanceRoutes = ( - <IndexRoute component={MaintenanceAppContainer}/> -); +export const maintenanceRoutes = <IndexRoute component={MaintenanceAppContainer} />; -export const setupRoutes = ( - <IndexRoute component={SetupAppContainer}/> -); +export const setupRoutes = <IndexRoute component={SetupAppContainer} />; diff --git a/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js b/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js index 48eb43de8d1..d150c1997d6 100644 --- a/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js +++ b/server/sonar-web/src/main/js/apps/metrics/components/MetricsAppContainer.js @@ -21,11 +21,11 @@ import React from 'react'; import init from '../init'; export default class MetricsAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { init(this.refs.container); } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/metrics/create-view.js b/server/sonar-web/src/main/js/apps/metrics/create-view.js index a31f2330721..8570f323c7a 100644 --- a/server/sonar-web/src/main/js/apps/metrics/create-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/create-view.js @@ -21,8 +21,7 @@ import Metric from './metric'; import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; const metric = new Metric({ key: this.$('#create-metric-key').val(), @@ -32,21 +31,23 @@ export default FormView.extend({ type: this.$('#create-metric-type').val() }); this.disableForm(); - return metric.save(null, { - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.collection.refresh(); - if (that.options.domains.indexOf(metric.get('domain')) === -1) { - that.options.domains.push(metric.get('domain')); - } - that.destroy(); - }).fail(jqXHR => { - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - that.enableForm(); - }); + return metric + .save(null, { + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.collection.refresh(); + if (that.options.domains.indexOf(metric.get('domain')) === -1) { + that.options.domains.push(metric.get('domain')); + } + that.destroy(); + }) + .fail(jqXHR => { + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + that.enableForm(); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/delete-view.js b/server/sonar-web/src/main/js/apps/metrics/delete-view.js index dcb50c0694a..694bcf71d06 100644 --- a/server/sonar-web/src/main/js/apps/metrics/delete-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/delete-view.js @@ -23,25 +23,28 @@ import Template from './templates/metrics-delete.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { const that = this; const collection = this.model.collection; - return this.model.destroy({ - wait: true, - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .destroy({ + wait: true, + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); diff --git a/server/sonar-web/src/main/js/apps/metrics/form-view.js b/server/sonar-web/src/main/js/apps/metrics/form-view.js index 8ad22ac4643..d0ab24e62e7 100644 --- a/server/sonar-web/src/main/js/apps/metrics/form-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/form-view.js @@ -24,48 +24,50 @@ import Template from './templates/metrics-form.hbs'; export default ModalForm.extend({ template: Template, - onRender () { + onRender() { const that = this; ModalForm.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); - this.$('#create-metric-domain').select2({ - width: '250px', - createSearchChoice (term) { - return { id: term, text: '+' + term }; - }, - createSearchChoicePosition: 'top', - initSelection (element, callback) { - const value = $(element).val(); - callback({ id: value, text: value }); - }, - query (options) { - const items = that.options.domains.filter(d => d.toLowerCase().indexOf(options.term.toLowerCase()) !== -1); - const results = items.map(item => { - return { id: item, text: item }; - }); - options.callback({ results, more: false }); - } - }).select2('val', this.model && this.model.get('domain')); + this.$('#create-metric-domain') + .select2({ + width: '250px', + createSearchChoice(term) { + return { id: term, text: '+' + term }; + }, + createSearchChoicePosition: 'top', + initSelection(element, callback) { + const value = $(element).val(); + callback({ id: value, text: value }); + }, + query(options) { + const items = that.options.domains.filter( + d => d.toLowerCase().indexOf(options.term.toLowerCase()) !== -1 + ); + const results = items.map(item => { + return { id: item, text: item }; + }); + options.callback({ results, more: false }); + } + }) + .select2('val', this.model && this.model.get('domain')); this.$('#create-metric-type').select2({ width: '250px' }); }, - onDestroy () { + onDestroy() { ModalForm.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - serializeData () { + serializeData() { return { ...ModalForm.prototype.serializeData.apply(this, arguments), domains: this.options.domains, types: this.options.types }; } - }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/header-view.js b/server/sonar-web/src/main/js/apps/metrics/header-view.js index 1a8fcb1fdb3..afb091b96c6 100644 --- a/server/sonar-web/src/main/js/apps/metrics/header-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/header-view.js @@ -28,12 +28,12 @@ export default Marionette.ItemView.extend({ 'click #metrics-create': 'onCreateClick' }, - onCreateClick (e) { + onCreateClick(e) { e.preventDefault(); this.createMetric(); }, - createMetric () { + createMetric() { new CreateView({ collection: this.collection, domains: this.options.domains, @@ -42,4 +42,3 @@ export default Marionette.ItemView.extend({ }).render(); } }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/init.js b/server/sonar-web/src/main/js/apps/metrics/init.js index a8648e12cfa..5f4560cef9f 100644 --- a/server/sonar-web/src/main/js/apps/metrics/init.js +++ b/server/sonar-web/src/main/js/apps/metrics/init.js @@ -26,7 +26,7 @@ import ListView from './list-view'; import ListFooterView from './list-footer-view'; const App = new Marionette.Application(); -const init = function (el) { +const init = function(el) { // Layout this.layout = new Layout({ el }); this.layout.render(); @@ -59,12 +59,12 @@ const init = function (el) { this.metrics.fetch(); }; -App.requestDomains = function () { +App.requestDomains = function() { return $.get(window.baseUrl + '/api/metrics/domains').done(r => { App.domains = r.domains; }); }; -App.requestTypes = function () { +App.requestTypes = function() { return $.get(window.baseUrl + '/api/metrics/types').done(r => { App.types = r.types; }); @@ -76,7 +76,6 @@ App.on('start', el => { }); }); -export default function (el) { +export default function(el) { App.start(el); } - diff --git a/server/sonar-web/src/main/js/apps/metrics/layout.js b/server/sonar-web/src/main/js/apps/metrics/layout.js index 762747b4d42..14d774d8907 100644 --- a/server/sonar-web/src/main/js/apps/metrics/layout.js +++ b/server/sonar-web/src/main/js/apps/metrics/layout.js @@ -29,4 +29,3 @@ export default Marionette.LayoutView.extend({ listFooterRegion: '#metrics-list-footer' } }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js b/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js index 7e1bf38ec06..686503801ec 100644 --- a/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/list-footer-view.js @@ -24,23 +24,23 @@ export default Marionette.ItemView.extend({ template: Template, collectionEvents: { - 'all': 'render' + all: 'render' }, events: { 'click #metrics-fetch-more': 'onMoreClick' }, - onMoreClick (e) { + onMoreClick(e) { e.preventDefault(); this.fetchMore(); }, - fetchMore () { + fetchMore() { this.collection.fetchMore(); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), total: this.collection.total, @@ -49,4 +49,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/list-item-view.js b/server/sonar-web/src/main/js/apps/metrics/list-item-view.js index d46cd8251ac..8219128493f 100644 --- a/server/sonar-web/src/main/js/apps/metrics/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/list-item-view.js @@ -32,28 +32,26 @@ export default Marionette.ItemView.extend({ 'click .js-metric-delete': 'onDeleteClick' }, - onRender () { - this.$el - .attr('data-id', this.model.id) - .attr('data-key', this.model.get('key')); + onRender() { + this.$el.attr('data-id', this.model.id).attr('data-key', this.model.get('key')); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onUpdateClick (e) { + onUpdateClick(e) { e.preventDefault(); this.updateMetric(); }, - onDeleteClick (e) { + onDeleteClick(e) { e.preventDefault(); this.deleteMetric(); }, - updateMetric () { + updateMetric() { new UpdateView({ model: this.model, collection: this.model.collection, @@ -62,8 +60,7 @@ export default Marionette.ItemView.extend({ }).render(); }, - deleteMetric () { + deleteMetric() { new DeleteView({ model: this.model }).render(); } }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/list-view.js b/server/sonar-web/src/main/js/apps/metrics/list-view.js index f349f0fafd7..2d3bd2af723 100644 --- a/server/sonar-web/src/main/js/apps/metrics/list-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/list-view.js @@ -24,11 +24,10 @@ export default Marionette.CollectionView.extend({ tagName: 'ul', childView: ListItemView, - childViewOptions () { + childViewOptions() { return { types: this.options.types, domains: this.options.domains }; } }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/metric.js b/server/sonar-web/src/main/js/apps/metrics/metric.js index 4616b3caa64..12e186ce6f1 100644 --- a/server/sonar-web/src/main/js/apps/metrics/metric.js +++ b/server/sonar-web/src/main/js/apps/metrics/metric.js @@ -24,11 +24,11 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ idAttribute: 'id', - urlRoot () { + urlRoot() { return window.baseUrl + '/api/metrics'; }, - sync (method, model, options) { + sync(method, model, options) { const opts = options || {}; if (method === 'create') { defaults(opts, { @@ -54,4 +54,3 @@ export default Backbone.Model.extend({ return Backbone.ajax(opts); } }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/metrics.js b/server/sonar-web/src/main/js/apps/metrics/metrics.js index e0f3944c611..42b78ec4977 100644 --- a/server/sonar-web/src/main/js/apps/metrics/metrics.js +++ b/server/sonar-web/src/main/js/apps/metrics/metrics.js @@ -23,36 +23,34 @@ import Metric from './metric'; export default Backbone.Collection.extend({ model: Metric, - url () { + url() { return window.baseUrl + '/api/metrics/search'; }, - parse (r) { + parse(r) { this.total = r.total; this.p = r.p; this.ps = r.ps; return r.metrics; }, - fetch (options) { + fetch(options) { const opts = { data: {}, ...options }; this.q = opts.data.q; opts.data.isCustom = true; return Backbone.Collection.prototype.fetch.call(this, opts); }, - fetchMore () { + fetchMore() { const p = this.p + 1; return this.fetch({ add: true, remove: false, data: { p, ps: this.ps, q: this.q } }); }, - refresh () { + refresh() { return this.fetch({ reset: true, data: { q: this.q } }); }, - hasMore () { + hasMore() { return this.total > this.p * this.ps; } - }); - diff --git a/server/sonar-web/src/main/js/apps/metrics/routes.js b/server/sonar-web/src/main/js/apps/metrics/routes.js index 5eb9a1cdabf..fe9790a43b1 100644 --- a/server/sonar-web/src/main/js/apps/metrics/routes.js +++ b/server/sonar-web/src/main/js/apps/metrics/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import MetricsAppContainer from './components/MetricsAppContainer'; -export default ( - <IndexRoute component={MetricsAppContainer}/> -); +export default <IndexRoute component={MetricsAppContainer} />; diff --git a/server/sonar-web/src/main/js/apps/metrics/update-view.js b/server/sonar-web/src/main/js/apps/metrics/update-view.js index ff8183fd5f5..fbc4807ff18 100644 --- a/server/sonar-web/src/main/js/apps/metrics/update-view.js +++ b/server/sonar-web/src/main/js/apps/metrics/update-view.js @@ -20,8 +20,7 @@ import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; this.model.set({ key: this.$('#create-metric-key').val(), @@ -31,18 +30,20 @@ export default FormView.extend({ type: this.$('#create-metric-type').val() }); this.disableForm(); - return this.model.save(null, { - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .save(null, { + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/organizations/actions.js b/server/sonar-web/src/main/js/apps/organizations/actions.js index dafc8c38dba..61f0bd8ac0b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/actions.js +++ b/server/sonar-web/src/main/js/apps/organizations/actions.js @@ -25,48 +25,55 @@ import { addGlobalSuccessMessage } from '../../store/globalMessages/duck'; import { translate, translateWithParameters } from '../../helpers/l10n'; import type { Organization } from '../../store/organizations/duck'; -const onRejected = (dispatch: Function) => (error: Object) => { - onFail(dispatch)(error); - return Promise.reject(); -}; - -export const fetchOrganization = (key: string): Function => (dispatch: Function): Promise<*> => { - const onFulfilled = ([organization, navigation]) => { - if (organization) { - const organizationWithPermissions = { ...organization, ...navigation }; - dispatch(actions.receiveOrganizations([organizationWithPermissions])); - } +const onRejected = (dispatch: Function) => + (error: Object) => { + onFail(dispatch)(error); + return Promise.reject(); }; - return Promise.all([ - api.getOrganization(key), - api.getOrganizationNavigation(key) - ]).then(onFulfilled, onFail(dispatch)); -}; +export const fetchOrganization = (key: string): Function => + (dispatch: Function): Promise<*> => { + const onFulfilled = ([organization, navigation]) => { + if (organization) { + const organizationWithPermissions = { ...organization, ...navigation }; + dispatch(actions.receiveOrganizations([organizationWithPermissions])); + } + }; -export const createOrganization = (fields: {}): Function => (dispatch: Function): Promise<*> => { - const onFulfilled = (organization: Organization) => { - dispatch(actions.createOrganization(organization)); - dispatch(addGlobalSuccessMessage(translateWithParameters('organization.created', organization.name))); + return Promise.all([api.getOrganization(key), api.getOrganizationNavigation(key)]).then( + onFulfilled, + onFail(dispatch) + ); }; - return api.createOrganization(fields).then(onFulfilled, onRejected(dispatch)); -}; +export const createOrganization = (fields: {}): Function => + (dispatch: Function): Promise<*> => { + const onFulfilled = (organization: Organization) => { + dispatch(actions.createOrganization(organization)); + dispatch( + addGlobalSuccessMessage(translateWithParameters('organization.created', organization.name)) + ); + }; -export const updateOrganization = (key: string, changes: {}): Function => (dispatch: Function): Promise<*> => { - const onFulfilled = () => { - dispatch(actions.updateOrganization(key, changes)); - dispatch(addGlobalSuccessMessage(translate('organization.updated'))); + return api.createOrganization(fields).then(onFulfilled, onRejected(dispatch)); }; - return api.updateOrganization(key, changes).then(onFulfilled, onFail(dispatch)); -}; +export const updateOrganization = (key: string, changes: {}): Function => + (dispatch: Function): Promise<*> => { + const onFulfilled = () => { + dispatch(actions.updateOrganization(key, changes)); + dispatch(addGlobalSuccessMessage(translate('organization.updated'))); + }; -export const deleteOrganization = (key: string): Function => (dispatch: Function): Promise<*> => { - const onFulfilled = () => { - dispatch(actions.deleteOrganization(key)); - dispatch(addGlobalSuccessMessage(translate('organization.deleted'))); + return api.updateOrganization(key, changes).then(onFulfilled, onFail(dispatch)); }; - return api.deleteOrganization(key).then(onFulfilled, onFail(dispatch)); -}; +export const deleteOrganization = (key: string): Function => + (dispatch: Function): Promise<*> => { + const onFulfilled = () => { + dispatch(actions.deleteOrganization(key)); + dispatch(addGlobalSuccessMessage(translate('organization.deleted'))); + }; + + return api.deleteOrganization(key).then(onFulfilled, onFail(dispatch)); + }; diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAdmin.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAdmin.js index 956a6c466b9..5fe8271e694 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAdmin.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAdmin.js @@ -26,28 +26,28 @@ import handleRequiredAuthorization from '../../../app/utils/handleRequiredAuthor class OrganizationAdmin extends React.Component { props: { children: Object, - organization: { canAdmin: boolean }, + organization: { canAdmin: boolean } }; - componentDidMount () { + componentDidMount() { this.checkPermissions(); } - componentDidUpdate () { + componentDidUpdate() { this.checkPermissions(); } - isOrganizationAdmin () { + isOrganizationAdmin() { return this.props.organization.canAdmin; } - checkPermissions () { + checkPermissions() { if (!this.isOrganizationAdmin()) { handleRequiredAuthorization(); } } - render () { + render() { if (!this.isOrganizationAdmin()) { return null; } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.js index 1cea413985e..caf6cd849ef 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.js @@ -60,63 +60,65 @@ class OrganizationDelete extends React.Component { this.setState({ deleting: false }); }; - renderModal () { + renderModal() { return ( - <Modal isOpen={true} - contentLabel="modal form" - className="modal" - overlayClassName="modal-overlay" - onRequestClose={this.handleCloseModal}> - - <header className="modal-head"> - <h2>{translate('organization.delete')}</h2> - </header> - - <form onSubmit={this.handleSubmit}> - <div className="modal-body"> - {translate('organization.delete.question')} - </div> - - <footer className="modal-foot"> - {this.state.loading ? ( - <i className="spinner"/> - ) : ( - <div> - <button type="submit" className="button-red">{translate('delete')}</button> - <button type="reset" className="button-link" onClick={this.handleCloseModal}> - {translate('cancel')} - </button> - </div> - )} - </footer> - </form> - - </Modal> + <Modal + isOpen={true} + contentLabel="modal form" + className="modal" + overlayClassName="modal-overlay" + onRequestClose={this.handleCloseModal} + > + + <header className="modal-head"> + <h2>{translate('organization.delete')}</h2> + </header> + + <form onSubmit={this.handleSubmit}> + <div className="modal-body"> + {translate('organization.delete.question')} + </div> + + <footer className="modal-foot"> + {this.state.loading + ? <i className="spinner" /> + : <div> + <button type="submit" className="button-red">{translate('delete')}</button> + <button type="reset" className="button-link" onClick={this.handleCloseModal}> + {translate('cancel')} + </button> + </div>} + </footer> + </form> + + </Modal> ); } - render () { + render() { return ( - <div className="page page-limited"> - <Helmet - title={`${translate('organization.delete')} - ${this.props.organization.name}`} - titleTemplate="%s - SonarQube"/> - - <header className="page-header"> - <h1 className="page-title">{translate('organization.delete')}</h1> - <div className="page-description">{translate('organization.delete.description')}</div> - </header> - - <div> - <button - className="button-red" - disabled={this.state.loading || this.state.deleting} - onClick={this.handleOpenModal}> - {translate('delete')} - </button> - {this.state.deleting && this.renderModal()} - </div> + <div className="page page-limited"> + <Helmet + title={`${translate('organization.delete')} - ${this.props.organization.name}`} + titleTemplate="%s - SonarQube" + /> + + <header className="page-header"> + <h1 className="page-title">{translate('organization.delete')}</h1> + <div className="page-description">{translate('organization.delete.description')}</div> + </header> + + <div> + <button + className="button-red" + disabled={this.state.loading || this.state.deleting} + onClick={this.handleOpenModal} + > + {translate('delete')} + </button> + {this.state.deleting && this.renderModal()} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js index 167295b689c..63edc23329d 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.js @@ -45,7 +45,7 @@ class OrganizationEdit extends React.Component { url: string }; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = { loading: false, @@ -59,11 +59,11 @@ class OrganizationEdit extends React.Component { this.changeAvatarImage = debounce(this.changeAvatarImage, 500); } - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -93,93 +93,98 @@ class OrganizationEdit extends React.Component { }); }; - render () { + render() { return ( - <div className="page page-limited"> - <header className="page-header"> - <h1 className="page-title">{translate('organization.edit')}</h1> - </header> - - <form onSubmit={this.handleSubmit}> - <div className="modal-field"> - <label htmlFor="organization-name"> - {translate('organization.name')} - <em className="mandatory">*</em> - </label> - <input id="organization-name" - name="name" - required={true} - type="text" - maxLength="64" - value={this.state.name} - disabled={this.state.loading} - onChange={e => this.setState({ name: e.target.value })}/> - <div className="modal-field-description"> - {translate('organization.name.description')} - </div> + <div className="page page-limited"> + <header className="page-header"> + <h1 className="page-title">{translate('organization.edit')}</h1> + </header> + + <form onSubmit={this.handleSubmit}> + <div className="modal-field"> + <label htmlFor="organization-name"> + {translate('organization.name')} + <em className="mandatory">*</em> + </label> + <input + id="organization-name" + name="name" + required={true} + type="text" + maxLength="64" + value={this.state.name} + disabled={this.state.loading} + onChange={e => this.setState({ name: e.target.value })} + /> + <div className="modal-field-description"> + {translate('organization.name.description')} </div> - <div className="modal-field"> - <label htmlFor="organization-avatar"> - {translate('organization.avatar')} - </label> - <input id="organization-avatar" - name="avatar" - type="text" - maxLength="256" - value={this.state.avatar} - disabled={this.state.loading} - onChange={this.handleAvatarInputChange}/> - <div className="modal-field-description"> - {translate('organization.avatar.description')} - </div> - {!!this.state.avatarImage && ( - <div className="spacer-top spacer-bottom"> - <div className="little-spacer-bottom"> - {translate('organization.avatar.preview')} - {':'} - </div> - <img src={this.state.avatarImage} alt="" height={30}/> - </div> - )} + </div> + <div className="modal-field"> + <label htmlFor="organization-avatar"> + {translate('organization.avatar')} + </label> + <input + id="organization-avatar" + name="avatar" + type="text" + maxLength="256" + value={this.state.avatar} + disabled={this.state.loading} + onChange={this.handleAvatarInputChange} + /> + <div className="modal-field-description"> + {translate('organization.avatar.description')} </div> - <div className="modal-field"> - <label htmlFor="organization-description"> - {translate('description')} - </label> - <textarea id="organization-description" - name="description" - rows="3" - maxLength="256" - value={this.state.description} - disabled={this.state.loading} - onChange={e => this.setState({ description: e.target.value })}/> - <div className="modal-field-description"> - {translate('organization.description.description')} - </div> + {!!this.state.avatarImage && + <div className="spacer-top spacer-bottom"> + <div className="little-spacer-bottom"> + {translate('organization.avatar.preview')} + {':'} + </div> + <img src={this.state.avatarImage} alt="" height={30} /> + </div>} + </div> + <div className="modal-field"> + <label htmlFor="organization-description"> + {translate('description')} + </label> + <textarea + id="organization-description" + name="description" + rows="3" + maxLength="256" + value={this.state.description} + disabled={this.state.loading} + onChange={e => this.setState({ description: e.target.value })} + /> + <div className="modal-field-description"> + {translate('organization.description.description')} </div> - <div className="modal-field"> - <label htmlFor="organization-url"> - {translate('organization.url')} - </label> - <input id="organization-url" - name="url" - type="text" - maxLength="256" - value={this.state.url} - disabled={this.state.loading} - onChange={e => this.setState({ url: e.target.value })}/> - <div className="modal-field-description"> - {translate('organization.url.description')} - </div> + </div> + <div className="modal-field"> + <label htmlFor="organization-url"> + {translate('organization.url')} + </label> + <input + id="organization-url" + name="url" + type="text" + maxLength="256" + value={this.state.url} + disabled={this.state.loading} + onChange={e => this.setState({ url: e.target.value })} + /> + <div className="modal-field-description"> + {translate('organization.url.description')} </div> - <div className="modal-field"> - <button type="submit" disabled={this.state.loading}>{translate('save')}</button> - {this.state.loading && ( - <i className="spinner spacer-left"/> - )} - </div> - </form> - </div> + </div> + <div className="modal-field"> + <button type="submit" disabled={this.state.loading}>{translate('save')}</button> + {this.state.loading && <i className="spinner spacer-left" />} + </div> + </form> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationFavoriteProjects.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationFavoriteProjects.js index 044703cd791..52213c4300d 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationFavoriteProjects.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationFavoriteProjects.js @@ -36,21 +36,24 @@ class OrganizationFavoriteProjects extends React.Component { } }; - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } - render () { + render() { return ( - <div id="projects-page" className="page page-limited"> - <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube"/> - <PageHeaderContainer organization={this.props.organization}/> - <FavoriteProjectsContainer location={this.props.location} organization={this.props.organization}/> - </div> + <div id="projects-page" className="page page-limited"> + <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube" /> + <PageHeaderContainer organization={this.props.organization} /> + <FavoriteProjectsContainer + location={this.props.location} + organization={this.props.organization} + /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroups.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroups.js index 62e361de3be..e760b783bad 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroups.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationGroups.js @@ -29,12 +29,12 @@ class OrganizationGroups extends React.Component { organization: Organization }; - componentDidMount () { + componentDidMount() { init(this.refs.container, this.props.organization); } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js index a6a2e82f165..709801728d3 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js @@ -45,7 +45,7 @@ class OrganizationPage extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.props.fetchOrganization(this.props.params.organizationKey).then(() => { if (this.mounted) { @@ -54,26 +54,26 @@ class OrganizationPage extends React.Component { }); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - render () { + render() { const { organization } = this.props; if (!organization || organization.canAdmin == null) { if (this.state.loading) { return null; } else { - return <NotFound/>; + return <NotFound />; } } return ( - <div> - <OrganizationNavigation organization={organization} location={this.props.location}/> - {this.props.children} - </div> + <div> + <OrganizationNavigation organization={organization} location={this.props.location} /> + {this.props.children} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissionTemplates.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissionTemplates.js index 541f1e51648..e5df0d8557b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissionTemplates.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissionTemplates.js @@ -30,12 +30,8 @@ class OrganizationPermissionTemplates extends React.Component { organization: Organization }; - render () { - return ( - <AppContainer - location={this.props.location} - organization={this.props.organization}/> - ); + render() { + return <AppContainer location={this.props.location} organization={this.props.organization} />; } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissions.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissions.js index 8be852a0c66..79fb720a1e0 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissions.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPermissions.js @@ -29,10 +29,8 @@ class OrganizationPermissions extends React.Component { organization: Organization }; - render () { - return ( - <GlobalPermissionsApp organization={this.props.organization}/> - ); + render() { + return <GlobalPermissionsApp organization={this.props.organization} />; } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.js index 1b71ee0f02d..7eac312780b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjects.js @@ -36,24 +36,25 @@ class OrganizationProjects extends React.Component { } }; - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } - render () { + render() { return ( - <div id="projects-page" className="page page-limited"> - <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube"/> - <PageHeaderContainer organization={this.props.organization}/> - <AllProjectsContainer - isFavorite={false} - location={this.props.location} - organization={this.props.organization}/> - </div> + <div id="projects-page" className="page page-limited"> + <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube" /> + <PageHeaderContainer organization={this.props.organization} /> + <AllProjectsContainer + isFavorite={false} + location={this.props.location} + organization={this.props.organization} + /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsManagement.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsManagement.js index e6d2ac2ff14..5a16f004c63 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsManagement.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationProjectsManagement.js @@ -29,10 +29,8 @@ class OrganizationProjectsManagement extends React.Component { organization: Organization }; - render () { - return ( - <AppContainer organization={this.props.organization}/> - ); + render() { + return <AppContainer organization={this.props.organization} />; } } diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationAdmin-test.js b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationAdmin-test.js index 340f760d386..321be58a0ae 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationAdmin-test.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationAdmin-test.js @@ -23,18 +23,22 @@ import { UnconnectedOrganizationAdmin } from '../OrganizationAdmin'; it('should render children', () => { const organization = { canAdmin: true }; - expect(shallow( - <UnconnectedOrganizationAdmin organization={organization}> + expect( + shallow( + <UnconnectedOrganizationAdmin organization={organization}> <div>hello</div> </UnconnectedOrganizationAdmin> - )).toMatchSnapshot(); + ) + ).toMatchSnapshot(); }); it('should not render anything', () => { const organization = { canAdmin: false }; - expect(shallow( - <UnconnectedOrganizationAdmin organization={organization}> + expect( + shallow( + <UnconnectedOrganizationAdmin organization={organization}> <div>hello</div> </UnconnectedOrganizationAdmin> - )).toMatchSnapshot(); + ) + ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationDelete-test.js b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationDelete-test.js index 79ebe1ca2ec..b85f6c8b162 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationDelete-test.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationDelete-test.js @@ -23,7 +23,7 @@ import { UnconnectedOrganizationDelete } from '../OrganizationDelete'; it('smoke test', () => { const organization = { key: 'foo', name: 'Foo' }; - const wrapper = shallow(<UnconnectedOrganizationDelete organization={organization}/>); + const wrapper = shallow(<UnconnectedOrganizationDelete organization={organization} />); expect(wrapper).toMatchSnapshot(); wrapper.setState({ deleting: true }); diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEdit-test.js b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEdit-test.js index d147b83ad32..2a1080b4f54 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEdit-test.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationEdit-test.js @@ -23,7 +23,7 @@ import { UnconnectedOrganizationEdit } from '../OrganizationEdit'; it('smoke test', () => { const organization = { key: 'foo', name: 'Foo' }; - const wrapper = shallow(<UnconnectedOrganizationEdit organization={organization}/>); + const wrapper = shallow(<UnconnectedOrganizationEdit organization={organization} />); expect(wrapper).toMatchSnapshot(); wrapper.setState({ diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationPage-test.js b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationPage-test.js index 01ffd045378..69afb1dc902 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationPage-test.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/OrganizationPage-test.js @@ -24,8 +24,8 @@ import { UnconnectedOrganizationPage } from '../OrganizationPage'; it('smoke test', () => { const wrapper = shallow( <UnconnectedOrganizationPage> - <div>hello</div> - </UnconnectedOrganizationPage> + <div>hello</div> + </UnconnectedOrganizationPage> ); expect(wrapper).toMatchSnapshot(); @@ -37,8 +37,8 @@ it('smoke test', () => { it('not found', () => { const wrapper = shallow( <UnconnectedOrganizationPage> - <div>hello</div> - </UnconnectedOrganizationPage> + <div>hello</div> + </UnconnectedOrganizationPage> ); wrapper.setState({ loading: false }); expect(wrapper).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.js b/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.js index f2727dde31a..a171c1c7485 100644 --- a/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.js +++ b/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.js @@ -27,7 +27,7 @@ const forSingleOrganization = (ComposedComponent: Object) => { class X extends React.Component { static displayName = `forSingleOrganization(${ComposedComponent.displayName})}`; - render () { + render() { const { customOrganizations, router, ...other } = this.props; if (customOrganizations) { @@ -35,7 +35,7 @@ const forSingleOrganization = (ComposedComponent: Object) => { return null; } - return <ComposedComponent {...other}/>; + return <ComposedComponent {...other} />; } } diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js index ae69f59d20b..c1ffa729acf 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigation.js @@ -46,109 +46,118 @@ export default class OrganizationNavigation extends React.Component { } }; - renderAdministration () { + renderAdministration() { const { organization, location } = this.props; const adminActive = ADMIN_PATHS.some(path => - location.pathname.endsWith(`organizations/${organization.key}/${path}`) - ); + location.pathname.endsWith(`organizations/${organization.key}/${path}`)); return ( - <li className={adminActive ? 'active': ''}> - <a className="dropdown-toggle navbar-admin-link" data-toggle="dropdown" href="#"> - {translate('layout.settings')} <i className="icon-dropdown"/> - </a> - <ul className="dropdown-menu"> - <li> - <Link to={`/organizations/${organization.key}/groups`} activeClassName="active"> - {translate('user_groups.page')} - </Link> - </li> - <li> - <Link to={`/organizations/${organization.key}/permissions`} activeClassName="active"> - {translate('permissions.page')} - </Link> - </li> - <li> - <Link to={`/organizations/${organization.key}/permission_templates`} activeClassName="active"> - {translate('permission_templates')} - </Link> - </li> + <li className={adminActive ? 'active' : ''}> + <a className="dropdown-toggle navbar-admin-link" data-toggle="dropdown" href="#"> + {translate('layout.settings')} <i className="icon-dropdown" /> + </a> + <ul className="dropdown-menu"> + <li> + <Link to={`/organizations/${organization.key}/groups`} activeClassName="active"> + {translate('user_groups.page')} + </Link> + </li> + <li> + <Link to={`/organizations/${organization.key}/permissions`} activeClassName="active"> + {translate('permissions.page')} + </Link> + </li> + <li> + <Link + to={`/organizations/${organization.key}/permission_templates`} + activeClassName="active" + > + {translate('permission_templates')} + </Link> + </li> + <li> + <Link + to={`/organizations/${organization.key}/projects_management`} + activeClassName="active" + > + {translate('projects_management')} + </Link> + </li> + <li> + <Link to={`/organizations/${organization.key}/edit`} activeClassName="active"> + {translate('edit')} + </Link> + </li> + {organization.canDelete && <li> - <Link to={`/organizations/${organization.key}/projects_management`} activeClassName="active"> - {translate('projects_management')} + <Link to={`/organizations/${organization.key}/delete`} activeClassName="active"> + {translate('delete')} </Link> - </li> - <li> - <Link to={`/organizations/${organization.key}/edit`} activeClassName="active"> - {translate('edit')} - </Link> - </li> - {organization.canDelete && ( - <li> - <Link to={`/organizations/${organization.key}/delete`} activeClassName="active"> - {translate('delete')} - </Link> - </li> - )} - </ul> - </li> + </li>} + </ul> + </li> ); } - render () { + render() { const { organization, location } = this.props; - const isHomeActive = - location.pathname === `organizations/${organization.key}/projects` || - location.pathname === `organizations/${organization.key}/projects/favorite`; + const isHomeActive = location.pathname === `organizations/${organization.key}/projects` || + location.pathname === `organizations/${organization.key}/projects/favorite`; return ( - <nav className="navbar navbar-context page-container" id="context-navigation"> - <div className="navbar-context-inner"> - <div className="container"> - <h2 className="navbar-context-title"> - <span className="navbar-context-title-qualifier little-spacer-right"> - <OrganizationIcon/> - </span> - <Link to={`/organizations/${organization.key}`} className="link-base-color"> - <strong>{organization.name}</strong> - </Link> - </h2> - - {organization.description != null && ( - <div className="navbar-context-description"> - <p className="text-limited text-top" title={organization.description}>{organization.description}</p> - </div> - )} - + <nav className="navbar navbar-context page-container" id="context-navigation"> + <div className="navbar-context-inner"> + <div className="container"> + <h2 className="navbar-context-title"> + <span className="navbar-context-title-qualifier little-spacer-right"> + <OrganizationIcon /> + </span> + <Link to={`/organizations/${organization.key}`} className="link-base-color"> + <strong>{organization.name}</strong> + </Link> + </h2> - <div className="navbar-context-meta"> - {!!organization.avatar && ( - <img src={organization.avatar} height={30} alt={organization.name}/> - )} - {organization.url != null && ( - <div> - <p className="text-limited text-top"> - <a className="link-underline" href={organization.url} title={organization.url} rel="nofollow"> - {organization.url} - </a> - </p> - </div> - )} - </div> + {organization.description != null && + <div className="navbar-context-description"> + <p className="text-limited text-top" title={organization.description}> + {organization.description} + </p> + </div>} - <ul className="nav navbar-nav nav-tabs"> - <li> - <Link to={`/organizations/${organization.key}/projects`} className={isHomeActive ? 'active': ''}> - {translate('projects.page')} - </Link> - </li> - {organization.canAdmin && this.renderAdministration()} - </ul> + <div className="navbar-context-meta"> + {!!organization.avatar && + <img src={organization.avatar} height={30} alt={organization.name} />} + {organization.url != null && + <div> + <p className="text-limited text-top"> + <a + className="link-underline" + href={organization.url} + title={organization.url} + rel="nofollow" + > + {organization.url} + </a> + </p> + </div>} </div> + + <ul className="nav navbar-nav nav-tabs"> + <li> + <Link + to={`/organizations/${organization.key}/projects`} + className={isHomeActive ? 'active' : ''} + > + {translate('projects.page')} + </Link> + </li> + {organization.canAdmin && this.renderAdministration()} + </ul> </div> - </nav> + </div> + </nav> ); } } diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js index 938d00665d1..09254c5aaf3 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/OrganizationNavigation-test.js @@ -23,21 +23,36 @@ import OrganizationNavigation from '../OrganizationNavigation'; it('regular user', () => { const organization = { key: 'foo', name: 'Foo', canAdmin: false, canDelete: false }; - expect(shallow( - <OrganizationNavigation location={{ pathname: '/organizations/foo' }} organization={organization}/> - )).toMatchSnapshot(); + expect( + shallow( + <OrganizationNavigation + location={{ pathname: '/organizations/foo' }} + organization={organization} + /> + ) + ).toMatchSnapshot(); }); it('admin', () => { const organization = { key: 'foo', name: 'Foo', canAdmin: true, canDelete: true }; - expect(shallow( - <OrganizationNavigation location={{ pathname: '/organizations/foo' }} organization={organization}/> - )).toMatchSnapshot(); + expect( + shallow( + <OrganizationNavigation + location={{ pathname: '/organizations/foo' }} + organization={organization} + /> + ) + ).toMatchSnapshot(); }); it('undeletable org', () => { const organization = { key: 'foo', name: 'Foo', canAdmin: true, canDelete: false }; - expect(shallow( - <OrganizationNavigation location={{ pathname: '/organizations/foo' }} organization={organization}/> - )).toMatchSnapshot(); + expect( + shallow( + <OrganizationNavigation + location={{ pathname: '/organizations/foo' }} + organization={organization} + /> + ) + ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/organizations/routes.js b/server/sonar-web/src/main/js/apps/organizations/routes.js index 7b3aed8ab99..6621e19c153 100644 --- a/server/sonar-web/src/main/js/apps/organizations/routes.js +++ b/server/sonar-web/src/main/js/apps/organizations/routes.js @@ -31,17 +31,17 @@ import OrganizationProjectsManagement from './components/OrganizationProjectsMan import OrganizationDelete from './components/OrganizationDelete'; export default ( - <Route path=":organizationKey" component={OrganizationPage}> - <IndexRedirect to="projects"/> - <Route path="projects" component={OrganizationProjects}/> - <Route path="projects/favorite" component={OrganizationFavoriteProjects}/> - <Route component={OrganizationAdmin}> - <Route path="delete" component={OrganizationDelete}/> - <Route path="edit" component={OrganizationEdit}/> - <Route path="groups" component={OrganizationGroups}/> - <Route path="permissions" component={OrganizationPermissions}/> - <Route path="permission_templates" component={OrganizationPermissionTemplates}/> - <Route path="projects_management" component={OrganizationProjectsManagement}/> - </Route> + <Route path=":organizationKey" component={OrganizationPage}> + <IndexRedirect to="projects" /> + <Route path="projects" component={OrganizationProjects} /> + <Route path="projects/favorite" component={OrganizationFavoriteProjects} /> + <Route component={OrganizationAdmin}> + <Route path="delete" component={OrganizationDelete} /> + <Route path="edit" component={OrganizationEdit} /> + <Route path="groups" component={OrganizationGroups} /> + <Route path="permissions" component={OrganizationPermissions} /> + <Route path="permission_templates" component={OrganizationPermissionTemplates} /> + <Route path="projects_management" component={OrganizationProjectsManagement} /> </Route> + </Route> ); diff --git a/server/sonar-web/src/main/js/apps/overview/actions.js b/server/sonar-web/src/main/js/apps/overview/actions.js index 4647b6ac94c..24e403ebb4e 100644 --- a/server/sonar-web/src/main/js/apps/overview/actions.js +++ b/server/sonar-web/src/main/js/apps/overview/actions.js @@ -24,9 +24,11 @@ import { onFail } from '../../store/rootActions'; const PAGE_SIZE = 5; -export const fetchRecentProjectActivity = (project: string) => (dispatch: Function) => ( - api.getProjectActivity(project, { pageSize: PAGE_SIZE }).then( - ({ analyses, paging }) => dispatch(receiveProjectActivity(project, analyses, paging)), - onFail(dispatch) - ) -); +export const fetchRecentProjectActivity = (project: string) => + (dispatch: Function) => + api + .getProjectActivity(project, { pageSize: PAGE_SIZE }) + .then( + ({ analyses, paging }) => dispatch(receiveProjectActivity(project, analyses, paging)), + onFail(dispatch) + ); diff --git a/server/sonar-web/src/main/js/apps/overview/components/App.js b/server/sonar-web/src/main/js/apps/overview/components/App.js index c30c80f2630..83a1f73c1e3 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/App.js +++ b/server/sonar-web/src/main/js/apps/overview/components/App.js @@ -38,7 +38,7 @@ class App extends React.Component { props: Props; state: Object; - componentDidMount () { + componentDidMount() { if (['VW', 'SVW'].includes(this.props.component.qualifier)) { this.props.router.replace({ pathname: '/view', @@ -47,30 +47,26 @@ class App extends React.Component { } } - shouldComponentUpdate (nextProps: Props) { + shouldComponentUpdate(nextProps: Props) { return shallowCompare(this, nextProps); } - render () { + render() { const { component } = this.props; if (['FIL', 'UTS'].includes(component.qualifier)) { return ( - <div className="page"> - <SourceViewer component={component.key}/> - </div> + <div className="page"> + <SourceViewer component={component.key} /> + </div> ); } if (!component.snapshotDate) { - return <EmptyOverview {...this.props}/>; + return <EmptyOverview {...this.props} />; } - return ( - <OverviewApp - {...this.props} - leakPeriodIndex="1"/> - ); + return <OverviewApp {...this.props} leakPeriodIndex="1" />; } } diff --git a/server/sonar-web/src/main/js/apps/overview/components/EmptyOverview.js b/server/sonar-web/src/main/js/apps/overview/components/EmptyOverview.js index 534fa8e2747..8bba1c5c7a5 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/EmptyOverview.js +++ b/server/sonar-web/src/main/js/apps/overview/components/EmptyOverview.js @@ -22,15 +22,15 @@ import { translate } from '../../../helpers/l10n'; const EmptyOverview = ({ component }) => { return ( - <div className="page page-limited"> - <div className="alert alert-warning"> - {translate('provisioning.no_analysis')} - </div> - <div className="big-spacer-top"> - <h4>{translate('key')}</h4> - <code>{component.key}</code> - </div> + <div className="page page-limited"> + <div className="alert alert-warning"> + {translate('provisioning.no_analysis')} </div> + <div className="big-spacer-top"> + <h4>{translate('key')}</h4> + <code>{component.key}</code> + </div> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.js b/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.js index 098613fe2d3..c8c51930f06 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.js +++ b/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.js @@ -51,31 +51,36 @@ type PreviousVersionPeriod = { mode: 'previous_version' }; -type Period = DaysPeriod | DatePeriod | VersionPeriod | PreviousAnalysisPeriod | PreviousVersionPeriod; +type Period = + | DaysPeriod + | DatePeriod + | VersionPeriod + | PreviousAnalysisPeriod + | PreviousVersionPeriod; export default class LeakPeriodLegend extends React.Component { props: { period: Period }; - render () { + render() { const { period } = this.props; const leakPeriodLabel = getPeriodLabel(period); const leakPeriodDate = getPeriodDate(period); const momentDate = moment(leakPeriodDate); const fromNow = momentDate.fromNow(); - const note = ['date', 'days'].includes(period.mode) ? - translateWithParameters('overview.last_analysis_x', fromNow) : - translateWithParameters('overview.started_x', fromNow); - const tooltip = ['date', 'days'].includes(period.mode) ? - translateWithParameters('overview.last_analysis_on_x', momentDate.format('LL')) : - translateWithParameters('overview.started_on_x', momentDate.format('LL')); + const note = ['date', 'days'].includes(period.mode) + ? translateWithParameters('overview.last_analysis_x', fromNow) + : translateWithParameters('overview.started_x', fromNow); + const tooltip = ['date', 'days'].includes(period.mode) + ? translateWithParameters('overview.last_analysis_on_x', momentDate.format('LL')) + : translateWithParameters('overview.started_on_x', momentDate.format('LL')); return ( - <div className="overview-legend" title={tooltip} data-toggle="tooltip"> - {translateWithParameters('overview.leak_period_x', leakPeriodLabel)} - <br/> - <span className="note">{note}</span> - </div> + <div className="overview-legend" title={tooltip} data-toggle="tooltip"> + {translateWithParameters('overview.leak_period_x', leakPeriodLabel)} + <br /> + <span className="note">{note}</span> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js index 4de489272c2..eefe20f3438 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js +++ b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js @@ -76,12 +76,7 @@ const METRICS = [ 'new_lines' ]; -const HISTORY_METRICS_LIST = [ - 'sqale_index', - 'duplicated_lines_density', - 'ncloc', - 'coverage' -]; +const HISTORY_METRICS_LIST = ['sqale_index', 'duplicated_lines_density', 'ncloc', 'coverage']; export default class OverviewApp extends React.Component { static propTypes = { @@ -92,37 +87,33 @@ export default class OverviewApp extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; document.querySelector('html').classList.add('dashboard-page'); - this.loadMeasures(this.props.component) - .then(() => this.loadHistory(this.props.component)); + this.loadMeasures(this.props.component).then(() => this.loadHistory(this.props.component)); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (this.props.component !== nextProps.component) { - this.loadMeasures(nextProps.component) - .then(() => this.loadHistory(nextProps.component)); + this.loadMeasures(nextProps.component).then(() => this.loadHistory(nextProps.component)); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; document.querySelector('html').classList.remove('dashboard-page'); } - loadMeasures (component) { + loadMeasures(component) { this.setState({ loading: true }); - return getMeasuresAndMeta( - component.key, - METRICS, - { additionalFields: 'metrics,periods' } - ).then(r => { + return getMeasuresAndMeta(component.key, METRICS, { + additionalFields: 'metrics,periods' + }).then(r => { if (this.mounted) { this.setState({ loading: false, @@ -133,7 +124,7 @@ export default class OverviewApp extends React.Component { }); } - loadHistory (component) { + loadHistory(component) { return getTimeMachineData(component.key, HISTORY_METRICS_LIST).then(r => { if (this.mounted) { const history = {}; @@ -150,15 +141,15 @@ export default class OverviewApp extends React.Component { }); } - renderLoading () { + renderLoading() { return ( - <div className="text-center"> - <i className="spinner spinner-margin"/> - </div> + <div className="text-center"> + <i className="spinner spinner-margin" /> + </div> ); } - render () { + render() { const { component } = this.props; const { loading, measures, periods, history, historyStartDate } = this.state; @@ -170,29 +161,26 @@ export default class OverviewApp extends React.Component { const domainProps = { component, measures, leakPeriod, history, historyStartDate }; return ( - <div className="page page-limited"> - <div className="overview page-with-sidebar"> - <div className="overview-main page-main"> - <QualityGate - component={component} - measures={measures} - periods={periods}/> - - <TooltipsContainer> - <div className="overview-domains-list"> - <BugsAndVulnerabilities {...domainProps}/> - <CodeSmells {...domainProps}/> - <Coverage {...domainProps}/> - <Duplications {...domainProps}/> - </div> - </TooltipsContainer> - </div> - - <div className="page-sidebar-fixed"> - <Meta component={component} measures={measures}/> - </div> + <div className="page page-limited"> + <div className="overview page-with-sidebar"> + <div className="overview-main page-main"> + <QualityGate component={component} measures={measures} periods={periods} /> + + <TooltipsContainer> + <div className="overview-domains-list"> + <BugsAndVulnerabilities {...domainProps} /> + <CodeSmells {...domainProps} /> + <Coverage {...domainProps} /> + <Duplications {...domainProps} /> + </div> + </TooltipsContainer> + </div> + + <div className="page-sidebar-fixed"> + <Meta component={component} measures={measures} /> </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/components/Timeline.js b/server/sonar-web/src/main/js/apps/overview/components/Timeline.js index f1ded836d83..0c42ba8daff 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/Timeline.js +++ b/server/sonar-web/src/main/js/apps/overview/components/Timeline.js @@ -26,18 +26,16 @@ const HEIGHT = 80; export default class Timeline extends React.Component { static propTypes = { - history: React.PropTypes.arrayOf( - React.PropTypes.object - ).isRequired, + history: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, before: React.PropTypes.object, after: React.PropTypes.object }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - filterSnapshots () { + filterSnapshots() { const { history, before, after } = this.props; return history.filter(s => { @@ -47,7 +45,7 @@ export default class Timeline extends React.Component { }); } - render () { + render() { const snapshots = this.filterSnapshots(); if (snapshots.length < 2) { @@ -61,15 +59,16 @@ export default class Timeline extends React.Component { const domain = [0, d3.max(this.props.history, d => d.value)]; return ( - <LineChart - data={data} - domain={domain} - interpolate="basis" - displayBackdrop={true} - displayPoints={false} - displayVerticalGrid={false} - height={HEIGHT} - padding={[0, 0, 0, 0]}/> + <LineChart + data={data} + domain={domain} + interpolate="basis" + displayBackdrop={true} + displayPoints={false} + displayVerticalGrid={false} + height={HEIGHT} + padding={[0, 0, 0, 0]} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.js b/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.js index c405831ca2e..01d73ea8c74 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.js +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/App-test.js @@ -25,18 +25,18 @@ import EmptyOverview from '../EmptyOverview'; it('should render OverviewApp', () => { const component = { id: 'id', snapshotDate: '2016-01-01' }; - const output = shallow(<UnconnectedApp component={component}/>); + const output = shallow(<UnconnectedApp component={component} />); expect(output.type()).toBe(OverviewApp); }); it('should render EmptyOverview', () => { const component = { id: 'id' }; - const output = shallow(<UnconnectedApp component={component}/>); + const output = shallow(<UnconnectedApp component={component} />); expect(output.type()).toBe(EmptyOverview); }); it('should pass leakPeriodIndex', () => { const component = { id: 'id', snapshotDate: '2016-01-01' }; - const output = shallow(<UnconnectedApp component={component}/>); + const output = shallow(<UnconnectedApp component={component} />); expect(output.prop('leakPeriodIndex')).toBe('1'); }); diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/EmptyOverview-test.js b/server/sonar-web/src/main/js/apps/overview/components/__tests__/EmptyOverview-test.js index 2e7c038c02b..7c9c06b16a5 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/EmptyOverview-test.js +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/EmptyOverview-test.js @@ -27,6 +27,6 @@ it('should render component key', () => { key: 'abcd', snapshotDate: '2016-01-01' }; - const output = shallow(<EmptyOverview component={component}/>); + const output = shallow(<EmptyOverview component={component} />); expect(output.find('code').text()).toBe('abcd'); }); diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.js b/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.js index 14cb53d4927..9d5a585c783 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.js +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/LeakPeriodLegend-test.js @@ -28,7 +28,7 @@ describe('check note', () => { mode: 'days', parameter: '10' }; - expect(shallow(<LeakPeriodLegend period={period}/>).find('.note')).toMatchSnapshot(); + expect(shallow(<LeakPeriodLegend period={period} />).find('.note')).toMatchSnapshot(); }); it('date', () => { @@ -37,7 +37,7 @@ describe('check note', () => { mode: 'date', parameter: '2013-01-01' }; - expect(shallow(<LeakPeriodLegend period={period}/>).find('.note')).toMatchSnapshot(); + expect(shallow(<LeakPeriodLegend period={period} />).find('.note')).toMatchSnapshot(); }); it('version', () => { @@ -46,7 +46,7 @@ describe('check note', () => { mode: 'version', parameter: '0.1' }; - expect(shallow(<LeakPeriodLegend period={period}/>).find('.note')).toMatchSnapshot(); + expect(shallow(<LeakPeriodLegend period={period} />).find('.note')).toMatchSnapshot(); }); it('previous_version', () => { @@ -54,7 +54,7 @@ describe('check note', () => { date: '2013-09-22T00:00:00+0200', mode: 'previous_version' }; - expect(shallow(<LeakPeriodLegend period={period}/>).find('.note')).toMatchSnapshot(); + expect(shallow(<LeakPeriodLegend period={period} />).find('.note')).toMatchSnapshot(); }); it('previous_analysis', () => { @@ -62,6 +62,6 @@ describe('check note', () => { date: '2013-09-22T00:00:00+0200', mode: 'previous_analysis' }; - expect(shallow(<LeakPeriodLegend period={period}/>).find('.note')).toMatchSnapshot(); + expect(shallow(<LeakPeriodLegend period={period} />).find('.note')).toMatchSnapshot(); }); }); diff --git a/server/sonar-web/src/main/js/apps/overview/events/AnalysesList.js b/server/sonar-web/src/main/js/apps/overview/events/AnalysesList.js index cfcc0d9b13a..a152ea9b021 100644 --- a/server/sonar-web/src/main/js/apps/overview/events/AnalysesList.js +++ b/server/sonar-web/src/main/js/apps/overview/events/AnalysesList.js @@ -41,22 +41,22 @@ class AnalysesList extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.fetchData(); } - componentDidUpdate (prevProps: Props) { + componentDidUpdate(prevProps: Props) { if (prevProps.project !== this.props.project) { this.fetchData(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - fetchData () { + fetchData() { this.setState({ loading: true }); this.props.fetchRecentProjectActivity(this.props.project).then(() => { if (this.mounted) { @@ -65,25 +65,23 @@ class AnalysesList extends React.Component { }); } - renderList (analyses) { + renderList(analyses) { if (!analyses.length) { return ( - <p className="spacer-top note"> - {translate('no_results')} - </p> + <p className="spacer-top note"> + {translate('no_results')} + </p> ); } return ( - <ul className="spacer-top"> - {analyses.map(analysis => ( - <Analysis key={analysis.key} analysis={analysis}/> - ))} - </ul> + <ul className="spacer-top"> + {analyses.map(analysis => <Analysis key={analysis.key} analysis={analysis} />)} + </ul> ); } - render () { + render() { const { analyses } = this.props; const { loading } = this.state; @@ -92,19 +90,19 @@ class AnalysesList extends React.Component { } return ( - <div className="overview-meta-card"> - <h4 className="overview-meta-header"> - {translate('project_activity.page')} - </h4> - - {this.renderList(analyses)} - - <div className="spacer-top small"> - <Link to={{ pathname: '/project/activity', query: { id: this.props.project } }}> - {translate('show_more')} - </Link> - </div> + <div className="overview-meta-card"> + <h4 className="overview-meta-header"> + {translate('project_activity.page')} + </h4> + + {this.renderList(analyses)} + + <div className="spacer-top small"> + <Link to={{ pathname: '/project/activity', query: { id: this.props.project } }}> + {translate('show_more')} + </Link> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/events/Analysis.js b/server/sonar-web/src/main/js/apps/overview/events/Analysis.js index b8ae0621fc1..f01c4aa9ae6 100644 --- a/server/sonar-web/src/main/js/apps/overview/events/Analysis.js +++ b/server/sonar-web/src/main/js/apps/overview/events/Analysis.js @@ -29,25 +29,23 @@ export default class Analysis extends React.Component { analysis: AnalysisType }; - render () { + render() { const { analysis } = this.props; return ( - <TooltipsContainer> - <li className="overview-analysis"> - <div className="small little-spacer-bottom"> - <strong> - <FormattedDate date={analysis.date} format="LL"/> - </strong> - </div> + <TooltipsContainer> + <li className="overview-analysis"> + <div className="small little-spacer-bottom"> + <strong> + <FormattedDate date={analysis.date} format="LL" /> + </strong> + </div> - {analysis.events.length > 0 ? ( - <Events events={analysis.events} canAdmin={false}/> - ) : ( - <span className="note">{translate('project_activity.project_analyzed')}</span> - )} - </li> - </TooltipsContainer> + {analysis.events.length > 0 + ? <Events events={analysis.events} canAdmin={false} /> + : <span className="note">{translate('project_activity.project_analyzed')}</span>} + </li> + </TooltipsContainer> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js b/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js index 53789632221..ae498439ff5 100644 --- a/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js +++ b/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js @@ -19,6 +19,6 @@ */ import { translate } from '../../../helpers/l10n'; -export function getMetricName (metricKey) { +export function getMetricName(metricKey) { return translate('overview.metric', metricKey); } diff --git a/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.js b/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.js index c2ae36e9306..aaeaececee4 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.js +++ b/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.js @@ -27,7 +27,7 @@ import BugIcon from '../../../components/ui/BugIcon'; import VulnerabilityIcon from '../../../components/ui/VulnerabilityIcon'; class BugsAndVulnerabilities extends React.Component { - renderHeader () { + renderHeader() { const { component } = this.props; const bugsDomainUrl = { pathname: '/component_measures/domain/Reliability', @@ -39,17 +39,17 @@ class BugsAndVulnerabilities extends React.Component { }; return ( - <div className="overview-card-header"> - <div className="overview-title"> - <Link to={bugsDomainUrl}>{translate('metric.bugs.name')}</Link> - {' & '} - <Link to={vulnerabilitiesDomainUrl}>{translate('metric.vulnerabilities.name')}</Link> - </div> + <div className="overview-card-header"> + <div className="overview-title"> + <Link to={bugsDomainUrl}>{translate('metric.bugs.name')}</Link> + {' & '} + <Link to={vulnerabilitiesDomainUrl}>{translate('metric.vulnerabilities.name')}</Link> </div> + </div> ); } - renderLeak () { + renderLeak() { const { leakPeriod } = this.props; if (leakPeriod == null) { @@ -57,85 +57,85 @@ class BugsAndVulnerabilities extends React.Component { } return ( - <div className="overview-domain-leak"> - <LeakPeriodLegend period={leakPeriod}/> + <div className="overview-domain-leak"> + <LeakPeriodLegend period={leakPeriod} /> - <div className="overview-domain-measures"> - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - <span style={{ marginLeft: 30 }}> - {this.props.renderIssues('new_bugs', 'BUG')} - </span> - {this.props.renderRating('new_reliability_rating')} - </div> - <div className="overview-domain-measure-label"> - <span className="little-spacer-right"><BugIcon/></span> - {getMetricName('new_bugs')} - </div> + <div className="overview-domain-measures"> + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + <span style={{ marginLeft: 30 }}> + {this.props.renderIssues('new_bugs', 'BUG')} + </span> + {this.props.renderRating('new_reliability_rating')} </div> + <div className="overview-domain-measure-label"> + <span className="little-spacer-right"><BugIcon /></span> + {getMetricName('new_bugs')} + </div> + </div> - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - <span style={{ marginLeft: 30 }}> - {this.props.renderIssues('new_vulnerabilities', 'VULNERABILITY')} - </span> - {this.props.renderRating('new_security_rating')} - </div> - <div className="overview-domain-measure-label"> - <span className="little-spacer-right"><VulnerabilityIcon/></span> - {getMetricName('new_vulnerabilities')} - </div> + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + <span style={{ marginLeft: 30 }}> + {this.props.renderIssues('new_vulnerabilities', 'VULNERABILITY')} + </span> + {this.props.renderRating('new_security_rating')} + </div> + <div className="overview-domain-measure-label"> + <span className="little-spacer-right"><VulnerabilityIcon /></span> + {getMetricName('new_vulnerabilities')} </div> </div> </div> + </div> ); } - renderNutshell () { + renderNutshell() { return ( - <div className="overview-domain-nutshell"> - <div className="overview-domain-measures"> + <div className="overview-domain-nutshell"> + <div className="overview-domain-measures"> - <div className="overview-domain-measure"> - <div className="display-inline-block text-middle" style={{ paddingLeft: 56 }}> - <div className="overview-domain-measure-value"> - {this.props.renderIssues('bugs', 'BUG')} - {this.props.renderRating('reliability_rating')} - </div> - <div className="overview-domain-measure-label"> - <span className="little-spacer-right"><BugIcon/></span> - {getMetricName('bugs')} - </div> + <div className="overview-domain-measure"> + <div className="display-inline-block text-middle" style={{ paddingLeft: 56 }}> + <div className="overview-domain-measure-value"> + {this.props.renderIssues('bugs', 'BUG')} + {this.props.renderRating('reliability_rating')} + </div> + <div className="overview-domain-measure-label"> + <span className="little-spacer-right"><BugIcon /></span> + {getMetricName('bugs')} </div> </div> + </div> - <div className="overview-domain-measure"> - <div className="display-inline-block text-middle"> - <div className="overview-domain-measure-value"> - {this.props.renderIssues('vulnerabilities', 'VULNERABILITY')} - {this.props.renderRating('security_rating')} - </div> - <div className="overview-domain-measure-label"> - <span className="little-spacer-right"><VulnerabilityIcon/></span> - {getMetricName('vulnerabilities')} - </div> + <div className="overview-domain-measure"> + <div className="display-inline-block text-middle"> + <div className="overview-domain-measure-value"> + {this.props.renderIssues('vulnerabilities', 'VULNERABILITY')} + {this.props.renderRating('security_rating')} + </div> + <div className="overview-domain-measure-label"> + <span className="little-spacer-right"><VulnerabilityIcon /></span> + {getMetricName('vulnerabilities')} </div> </div> </div> </div> + </div> ); } - render () { + render() { return ( - <div className="overview-card overview-card-special"> - {this.renderHeader()} + <div className="overview-card overview-card-special"> + {this.renderHeader()} - <div className="overview-domain-panel"> - {this.renderNutshell()} - {this.renderLeak()} - </div> + <div className="overview-domain-panel"> + {this.renderNutshell()} + {this.renderLeak()} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.js b/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.js index 826f71bbf98..0010c70c199 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.js +++ b/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.js @@ -28,13 +28,11 @@ import { getComponentIssuesUrl } from '../../../helpers/urls'; import CodeSmellIcon from '../../../components/ui/CodeSmellIcon'; class CodeSmells extends React.Component { - renderHeader () { - return this.props.renderHeader( - 'Maintainability', - translate('metric.code_smells.name')); + renderHeader() { + return this.props.renderHeader('Maintainability', translate('metric.code_smells.name')); } - renderDebt (metric, type) { + renderDebt(metric, type) { const { measures, component } = this.props; const measure = measures.find(measure => measure.metric.key === metric); const value = this.props.getValue(measure); @@ -45,36 +43,36 @@ class CodeSmells extends React.Component { } const formattedSnapshotDate = moment(component.snapshotDate).format('LLL'); - const tooltip = translateWithParameters('widget.as_calculated_on_x', - formattedSnapshotDate); + const tooltip = translateWithParameters('widget.as_calculated_on_x', formattedSnapshotDate); return ( - <Link to={getComponentIssuesUrl(component.key, params)}> - <span title={tooltip} data-toggle="tooltip"> - {formatMeasure(value, 'SHORT_WORK_DUR')} - </span> - </Link> + <Link to={getComponentIssuesUrl(component.key, params)}> + <span title={tooltip} data-toggle="tooltip"> + {formatMeasure(value, 'SHORT_WORK_DUR')} + </span> + </Link> ); } - renderTimelineStartDate () { + renderTimelineStartDate() { const momentDate = moment(this.props.historyStartDate); const fromNow = momentDate.fromNow(); return ( - <span className="overview-domain-timeline-date"> - {translateWithParameters('overview.started_x', fromNow)} - </span> + <span className="overview-domain-timeline-date"> + {translateWithParameters('overview.started_x', fromNow)} + </span> ); } - renderTimeline (range, displayDate) { + renderTimeline(range, displayDate) { return this.props.renderTimeline( 'sqale_index', range, - displayDate ? this.renderTimelineStartDate() : null); + displayDate ? this.renderTimelineStartDate() : null + ); } - renderLeak () { + renderLeak() { const { leakPeriod } = this.props; if (leakPeriod == null) { @@ -82,82 +80,81 @@ class CodeSmells extends React.Component { } return ( - <div className="overview-domain-leak"> - <div className="overview-domain-measures"> - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - <span style={{ marginLeft: 30 }}> - {this.renderDebt('new_technical_debt', 'CODE_SMELL')} - </span> - {this.props.renderRating('new_maintainability_rating')} - </div> - <div className="overview-domain-measure-label"> - {getMetricName('new_effort')} - </div> + <div className="overview-domain-leak"> + <div className="overview-domain-measures"> + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + <span style={{ marginLeft: 30 }}> + {this.renderDebt('new_technical_debt', 'CODE_SMELL')} + </span> + {this.props.renderRating('new_maintainability_rating')} </div> - - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - {this.props.renderIssues('new_code_smells', 'CODE_SMELL')} - </div> - <div className="overview-domain-measure-label"> - <span className="little-spacer-right"><CodeSmellIcon/></span> - {getMetricName('new_code_smells')} - </div> + <div className="overview-domain-measure-label"> + {getMetricName('new_effort')} </div> </div> - {this.renderTimeline('after')} + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + {this.props.renderIssues('new_code_smells', 'CODE_SMELL')} + </div> + <div className="overview-domain-measure-label"> + <span className="little-spacer-right"><CodeSmellIcon /></span> + {getMetricName('new_code_smells')} + </div> + </div> </div> + + {this.renderTimeline('after')} + </div> ); } - renderNutshell () { + renderNutshell() { return ( - <div className="overview-domain-nutshell"> - <div className="overview-domain-measures"> - - <div className="overview-domain-measure"> - <div className="display-inline-block text-middle" - style={{ paddingLeft: 56 }}> - <div className="overview-domain-measure-value"> - {this.renderDebt('sqale_index', 'CODE_SMELL')} - {this.props.renderRating('sqale_rating')} - </div> - <div className="overview-domain-measure-label"> - {getMetricName('effort')} - </div> + <div className="overview-domain-nutshell"> + <div className="overview-domain-measures"> + + <div className="overview-domain-measure"> + <div className="display-inline-block text-middle" style={{ paddingLeft: 56 }}> + <div className="overview-domain-measure-value"> + {this.renderDebt('sqale_index', 'CODE_SMELL')} + {this.props.renderRating('sqale_rating')} + </div> + <div className="overview-domain-measure-label"> + {getMetricName('effort')} </div> </div> + </div> - <div className="overview-domain-measure"> - <div className="display-inline-block text-middle"> - <div className="overview-domain-measure-value"> - {this.props.renderIssues('code_smells', 'CODE_SMELL')} - </div> - <div className="overview-domain-measure-label"> - <span className="little-spacer-right"><CodeSmellIcon/></span> - {getMetricName('code_smells')} - </div> + <div className="overview-domain-measure"> + <div className="display-inline-block text-middle"> + <div className="overview-domain-measure-value"> + {this.props.renderIssues('code_smells', 'CODE_SMELL')} + </div> + <div className="overview-domain-measure-label"> + <span className="little-spacer-right"><CodeSmellIcon /></span> + {getMetricName('code_smells')} </div> </div> </div> - - {this.renderTimeline('before', true)} </div> + + {this.renderTimeline('before', true)} + </div> ); } - render () { + render() { return ( - <div className="overview-card" id="overview-code-smells"> - {this.renderHeader()} + <div className="overview-card" id="overview-code-smells"> + {this.renderHeader()} - <div className="overview-domain-panel"> - {this.renderNutshell()} - {this.renderLeak()} - </div> + <div className="overview-domain-panel"> + {this.renderNutshell()} + {this.renderLeak()} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/main/Coverage.js b/server/sonar-web/src/main/js/apps/overview/main/Coverage.js index aa9a34d38e9..ccd8896ae30 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/Coverage.js +++ b/server/sonar-web/src/main/js/apps/overview/main/Coverage.js @@ -26,170 +26,158 @@ import { translate } from '../../../helpers/l10n'; import CoverageRating from '../../../components/ui/CoverageRating'; class Coverage extends React.Component { - getCoverage () { + getCoverage() { const { measures } = this.props; const { value } = measures.find(measure => measure.metric.key === 'coverage'); return Number(value); } - getNewCoverageMeasure () { + getNewCoverageMeasure() { const { measures } = this.props; return measures.find(measure => measure.metric.key === 'new_coverage'); } - getNewLinesToCover () { + getNewLinesToCover() { const { measures } = this.props; return measures.find(measure => measure.metric.key === 'new_lines_to_cover'); } - renderHeader () { - return this.props.renderHeader( - 'Coverage', - translate('metric.coverage.name')); + renderHeader() { + return this.props.renderHeader('Coverage', translate('metric.coverage.name')); } - renderTimeline (range) { + renderTimeline(range) { return this.props.renderTimeline('coverage', range); } - renderTests () { + renderTests() { return this.props.renderMeasure('tests'); } - renderCoverage () { + renderCoverage() { const { component } = this.props; const metric = 'coverage'; const coverage = this.getCoverage(); return ( - <div className="overview-domain-measure"> - <div className="display-inline-block text-middle big-spacer-right"> - <CoverageRating value={coverage} size="big"/> + <div className="overview-domain-measure"> + <div className="display-inline-block text-middle big-spacer-right"> + <CoverageRating value={coverage} size="big" /> + </div> + + <div className="display-inline-block text-middle"> + <div className="overview-domain-measure-value"> + <DrilldownLink component={component.key} metric={metric}> + <span className="js-overview-main-coverage"> + {formatMeasure(coverage, 'PERCENT')} + </span> + </DrilldownLink> </div> - <div className="display-inline-block text-middle"> - <div className="overview-domain-measure-value"> - <DrilldownLink component={component.key} metric={metric}> - <span className="js-overview-main-coverage"> - {formatMeasure(coverage, 'PERCENT')} - </span> - </DrilldownLink> - </div> - - <div className="overview-domain-measure-label"> - {getMetricName('coverage')} - </div> + <div className="overview-domain-measure-label"> + {getMetricName('coverage')} </div> </div> + </div> ); } - renderNewCoverage () { + renderNewCoverage() { const { component, leakPeriod } = this.props; const newCoverageMeasure = this.getNewCoverageMeasure(); const newLinesToCover = this.getNewLinesToCover(); - const newCoverageValue = newCoverageMeasure ? - getPeriodValue(newCoverageMeasure, leakPeriod.index) : null; - const newLinesToCoverValue = newLinesToCover ? - getPeriodValue(newLinesToCover, leakPeriod.index) : null; + const newCoverageValue = newCoverageMeasure + ? getPeriodValue(newCoverageMeasure, leakPeriod.index) + : null; + const newLinesToCoverValue = newLinesToCover + ? getPeriodValue(newLinesToCover, leakPeriod.index) + : null; - const formattedValue = newCoverageValue != null ? ( - <div> + const formattedValue = newCoverageValue != null + ? <div> <DrilldownLink - component={component.key} - metric={newCoverageMeasure.metric.key} - period={leakPeriod.index}> + component={component.key} + metric={newCoverageMeasure.metric.key} + period={leakPeriod.index} + > <span className="js-overview-main-new-coverage"> {formatMeasure(newCoverageValue, 'PERCENT')} </span> </DrilldownLink> </div> - ) : ( - <span>—</span> - ); - - const label = (newLinesToCoverValue != null && newLinesToCoverValue > 0) ? ( - <div className="overview-domain-measure-label"> + : <span>—</span>; + const label = newLinesToCoverValue != null && newLinesToCoverValue > 0 + ? <div className="overview-domain-measure-label"> {translate('overview.coverage_on')} - <br/> + <br /> <DrilldownLink - className="spacer-right overview-domain-secondary-measure-value" - component={component.key} - metric={newLinesToCover.metric.key} - period={leakPeriod.index}> + className="spacer-right overview-domain-secondary-measure-value" + component={component.key} + metric={newLinesToCover.metric.key} + period={leakPeriod.index} + > <span className="js-overview-main-new-coverage"> {formatMeasure(newLinesToCoverValue, 'SHORT_INT')} </span> </DrilldownLink> {getMetricName('new_lines_to_cover')} </div> - ) : ( - <div className="overview-domain-measure-label"> + : <div className="overview-domain-measure-label"> {getMetricName('new_coverage')} - </div> - ); - + </div>; return ( - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - {formattedValue} - </div> - {label} + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + {formattedValue} </div> + {label} + </div> ); } - - renderNutshell () { + renderNutshell() { return ( - <div className="overview-domain-nutshell"> - <div className="overview-domain-measures"> - {this.renderCoverage()} - {this.renderTests()} - </div> - - {this.renderTimeline('before')} + <div className="overview-domain-nutshell"> + <div className="overview-domain-measures"> + {this.renderCoverage()} + {this.renderTests()} </div> + + {this.renderTimeline('before')} + </div> ); } - - renderLeak () { + renderLeak() { const { leakPeriod } = this.props; - if (leakPeriod == null) { return null; } - return ( - <div className="overview-domain-leak"> - <div className="overview-domain-measures"> - {this.renderNewCoverage()} - </div> - - {this.renderTimeline('after')} + <div className="overview-domain-leak"> + <div className="overview-domain-measures"> + {this.renderNewCoverage()} </div> + + {this.renderTimeline('after')} + </div> ); } - - render () { + render() { const { measures } = this.props; const coverageMeasure = measures.find(measure => measure.metric.key === 'coverage'); - if (coverageMeasure == null) { return null; } - return ( - <div className="overview-card"> - {this.renderHeader()} + <div className="overview-card"> + {this.renderHeader()} - <div className="overview-domain-panel"> - {this.renderNutshell()} - {this.renderLeak()} - </div> + <div className="overview-domain-panel"> + {this.renderNutshell()} + {this.renderLeak()} </div> + </div> ); } } - export default enhance(Coverage); diff --git a/server/sonar-web/src/main/js/apps/overview/main/Duplications.js b/server/sonar-web/src/main/js/apps/overview/main/Duplications.js index cb1d98832e5..85bcf914fdf 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/Duplications.js +++ b/server/sonar-web/src/main/js/apps/overview/main/Duplications.js @@ -26,155 +26,144 @@ import { translate } from '../../../helpers/l10n'; import DuplicationsRating from '../../../components/ui/DuplicationsRating'; class Duplications extends React.Component { - renderHeader () { - return this.props.renderHeader( - 'Duplications', - translate('overview.domain.duplications')); + renderHeader() { + return this.props.renderHeader('Duplications', translate('overview.domain.duplications')); } - renderTimeline (range) { + renderTimeline(range) { return this.props.renderTimeline('duplicated_lines_density', range); } - renderDuplicatedBlocks () { + renderDuplicatedBlocks() { return this.props.renderMeasure('duplicated_blocks'); } - renderDuplications () { + renderDuplications() { const { component, measures } = this.props; const measure = measures.find(measure => measure.metric.key === 'duplicated_lines_density'); const duplications = Number(measure.value); return ( - <div className="overview-domain-measure"> - <div className="display-inline-block text-middle big-spacer-right"> - <DuplicationsRating value={duplications} size="big"/> - </div> + <div className="overview-domain-measure"> + <div className="display-inline-block text-middle big-spacer-right"> + <DuplicationsRating value={duplications} size="big" /> + </div> - <div className="display-inline-block text-middle"> - <div className="overview-domain-measure-value"> - <DrilldownLink component={component.key} metric="duplicated_lines_density"> - {formatMeasure(duplications, 'PERCENT')} - </DrilldownLink> - </div> + <div className="display-inline-block text-middle"> + <div className="overview-domain-measure-value"> + <DrilldownLink component={component.key} metric="duplicated_lines_density"> + {formatMeasure(duplications, 'PERCENT')} + </DrilldownLink> + </div> - <div className="overview-domain-measure-label"> - {getMetricName('duplications')} - </div> + <div className="overview-domain-measure-label"> + {getMetricName('duplications')} </div> </div> + </div> ); } - renderNewDuplications () { + renderNewDuplications() { const { component, measures, leakPeriod } = this.props; - const newDuplicationsMeasure = measures - .find(measure => measure.metric.key === 'new_duplicated_lines_density'); - const newLinesMeasure = measures - .find(measure => measure.metric.key === 'new_lines'); + const newDuplicationsMeasure = measures.find( + measure => measure.metric.key === 'new_duplicated_lines_density' + ); + const newLinesMeasure = measures.find(measure => measure.metric.key === 'new_lines'); - const newDuplicationsValue = newDuplicationsMeasure ? - getPeriodValue(newDuplicationsMeasure, leakPeriod.index) : null; - const newLinesValue = newLinesMeasure ? - getPeriodValue(newLinesMeasure, leakPeriod.index) : null; + const newDuplicationsValue = newDuplicationsMeasure + ? getPeriodValue(newDuplicationsMeasure, leakPeriod.index) + : null; + const newLinesValue = newLinesMeasure + ? getPeriodValue(newLinesMeasure, leakPeriod.index) + : null; - const formattedValue = newDuplicationsValue != null ? ( - <div> + const formattedValue = newDuplicationsValue != null + ? <div> <DrilldownLink - component={component.key} - metric={newDuplicationsMeasure.metric.key} - period={leakPeriod.index}> + component={component.key} + metric={newDuplicationsMeasure.metric.key} + period={leakPeriod.index} + > <span className="js-overview-main-new-duplications"> {formatMeasure(newDuplicationsValue, 'PERCENT')} </span> </DrilldownLink> </div> - ) : ( - <span>—</span> - ); - - const label = (newLinesValue != null && newLinesValue > 0) ? ( - <div className="overview-domain-measure-label"> + : <span>—</span>; + const label = newLinesValue != null && newLinesValue > 0 + ? <div className="overview-domain-measure-label"> {translate('overview.duplications_on')} - <br/> + <br /> <DrilldownLink - className="spacer-right overview-domain-secondary-measure-value" - component={component.key} - metric={newLinesMeasure.metric.key} - period={leakPeriod.index}> + className="spacer-right overview-domain-secondary-measure-value" + component={component.key} + metric={newLinesMeasure.metric.key} + period={leakPeriod.index} + > <span className="js-overview-main-new-lines"> {formatMeasure(newLinesValue, 'SHORT_INT')} </span> </DrilldownLink> {getMetricName('new_lines')} </div> - ) : ( - <div className="overview-domain-measure-label"> + : <div className="overview-domain-measure-label"> {getMetricName('new_duplications')} - </div> - ); - + </div>; return ( - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - {formattedValue} - </div> - {label} + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + {formattedValue} </div> + {label} + </div> ); } - - renderNutshell () { + renderNutshell() { return ( - <div className="overview-domain-nutshell"> - <div className="overview-domain-measures"> - {this.renderDuplications()} - {this.renderDuplicatedBlocks()} - </div> - - {this.renderTimeline('before')} + <div className="overview-domain-nutshell"> + <div className="overview-domain-measures"> + {this.renderDuplications()} + {this.renderDuplicatedBlocks()} </div> + + {this.renderTimeline('before')} + </div> ); } - - renderLeak () { + renderLeak() { const { leakPeriod } = this.props; - if (leakPeriod == null) { return null; } - return ( - <div className="overview-domain-leak"> - <div className="overview-domain-measures"> - {this.renderNewDuplications()} - </div> - - {this.renderTimeline('after')} + <div className="overview-domain-leak"> + <div className="overview-domain-measures"> + {this.renderNewDuplications()} </div> + + {this.renderTimeline('after')} + </div> ); } - - render () { + render() { const { measures } = this.props; - const duplications = - measures.find(measure => measure.metric.key === 'duplicated_lines_density'); - + const duplications = measures.find( + measure => measure.metric.key === 'duplicated_lines_density' + ); if (duplications == null) { return null; } - return ( - <div className="overview-card"> - {this.renderHeader()} + <div className="overview-card"> + {this.renderHeader()} - <div className="overview-domain-panel"> - {this.renderNutshell()} - {this.renderLeak()} - </div> + <div className="overview-domain-panel"> + {this.renderNutshell()} + {this.renderLeak()} </div> + </div> ); } } - export default enhance(Duplications); diff --git a/server/sonar-web/src/main/js/apps/overview/main/enhance.js b/server/sonar-web/src/main/js/apps/overview/main/enhance.js index 69fb57ab108..4b71fb7f615 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/enhance.js +++ b/server/sonar-web/src/main/js/apps/overview/main/enhance.js @@ -36,27 +36,27 @@ import { translateWithParameters } from '../../../helpers/l10n'; import { getPeriodDate } from '../../../helpers/periods'; import { getComponentIssuesUrl } from '../../../helpers/urls'; -export default function enhance (ComposedComponent) { +export default function enhance(ComposedComponent) { return class extends React.Component { static displayName = `enhance(${ComposedComponent.displayName})}`; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - getValue (measure) { + getValue(measure) { const { leakPeriod } = this.props; if (!measure) { return 0; } - return isDiffMetric(measure.metric.key) ? - getPeriodValue(measure, leakPeriod.index) : - measure.value; + return isDiffMetric(measure.metric.key) + ? getPeriodValue(measure, leakPeriod.index) + : measure.value; } - renderHeader (domain, label) { + renderHeader(domain, label) { const { component } = this.props; const domainUrl = { pathname: `/component_measures/domain/${domain}`, @@ -64,15 +64,15 @@ export default function enhance (ComposedComponent) { }; return ( - <div className="overview-card-header"> - <div className="overview-title"> - <Link to={domainUrl}>{label}</Link> - </div> + <div className="overview-card-header"> + <div className="overview-title"> + <Link to={domainUrl}>{label}</Link> </div> + </div> ); } - renderMeasure (metricKey) { + renderMeasure(metricKey) { const { measures, component } = this.props; const measure = measures.find(measure => measure.metric.key === metricKey); @@ -81,123 +81,110 @@ export default function enhance (ComposedComponent) { } return ( - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - <DrilldownLink component={component.key} metric={metricKey}> + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + <DrilldownLink component={component.key} metric={metricKey}> <span className="js-overview-main-tests"> {formatMeasure(measure.value, getShortType(measure.metric.type))} </span> - </DrilldownLink> - </div> + </DrilldownLink> + </div> - <div className="overview-domain-measure-label"> - {measure.metric.name} - </div> + <div className="overview-domain-measure-label"> + {measure.metric.name} </div> + </div> ); } - renderMeasureVariation (metricKey, customLabel) { + renderMeasureVariation(metricKey, customLabel) { const NO_VALUE = '—'; const { measures, leakPeriod } = this.props; - const measure = measures.find(measure => measure.metric.key === metricKey); const periodValue = getPeriodValue(measure, leakPeriod.index); - const formatted = periodValue != null ? - formatMeasureVariation(periodValue, getShortType(measure.metric.type)) : - NO_VALUE; - + const formatted = periodValue != null + ? formatMeasureVariation(periodValue, getShortType(measure.metric.type)) + : NO_VALUE; return ( - <div className="overview-domain-measure"> - <div className="overview-domain-measure-value"> - {formatted} - </div> + <div className="overview-domain-measure"> + <div className="overview-domain-measure-value"> + {formatted} + </div> - <div className="overview-domain-measure-label"> - {customLabel || measure.metric.name} - </div> + <div className="overview-domain-measure-label"> + {customLabel || measure.metric.name} </div> + </div> ); } - - renderRating (metricKey) { + renderRating(metricKey) { const { component, measures } = this.props; const measure = measures.find(measure => measure.metric.key === metricKey); - if (!measure) { return null; } - const value = this.getValue(measure); - const title = getRatingTooltip(metricKey, value); - return ( - <div className="overview-domain-measure-sup" title={title} data-toggle="tooltip"> - <DrilldownLink className="link-no-underline" component={component.key} metric={metricKey}> - <Rating value={value}/> - </DrilldownLink> - </div> + <div className="overview-domain-measure-sup" title={title} data-toggle="tooltip"> + <DrilldownLink className="link-no-underline" component={component.key} metric={metricKey}> + <Rating value={value} /> + </DrilldownLink> + </div> ); } - - renderIssues (metric, type) { + renderIssues(metric, type) { const { measures, component } = this.props; const measure = measures.find(measure => measure.metric.key === metric); const value = this.getValue(measure); - const params = { resolved: 'false', types: type }; - + const params = { + resolved: 'false', + types: type + }; if (isDiffMetric(metric)) { Object.assign(params, { sinceLeakPeriod: 'true' }); } - const formattedSnapshotDate = moment(component.snapshotDate).format('LLL'); const tooltip = translateWithParameters('widget.as_calculated_on_x', formattedSnapshotDate); - return ( - <Link to={getComponentIssuesUrl(component.key, params)}> - <span title={tooltip} data-toggle="tooltip"> - {formatMeasure(value, 'SHORT_INT')} - </span> - </Link> + <Link to={getComponentIssuesUrl(component.key, params)}> + <span title={tooltip} data-toggle="tooltip"> + {formatMeasure(value, 'SHORT_INT')} + </span> + </Link> ); } - - renderTimeline (metricKey, range, children) { + renderTimeline(metricKey, range, children) { if (!this.props.history) { return null; } - const history = this.props.history[metricKey]; - if (!history) { return null; } - const props = { history, [range]: getPeriodDate(this.props.leakPeriod) }; - return ( - <div className="overview-domain-timeline"> - <Timeline {...props}/> - {children} - </div> + <div className="overview-domain-timeline"> + <Timeline {...props} /> + {children} + </div> ); } - - render () { + render() { return ( - <ComposedComponent - {...this.props} - getValue={this.getValue.bind(this)} - renderHeader={this.renderHeader.bind(this)} - renderMeasure={this.renderMeasure.bind(this)} - renderMeasureVariation={this.renderMeasureVariation.bind(this)} - renderRating={this.renderRating.bind(this)} - renderIssues={this.renderIssues.bind(this)} - renderTimeline={this.renderTimeline.bind(this)}/> + <ComposedComponent + {...this.props} + getValue={this.getValue.bind(this)} + renderHeader={this.renderHeader.bind(this)} + renderMeasure={this.renderMeasure.bind(this)} + renderMeasureVariation={this.renderMeasureVariation.bind(this)} + renderRating={this.renderRating.bind(this)} + renderIssues={this.renderIssues.bind(this)} + renderTimeline={this.renderTimeline.bind(this)} + /> ); } }; diff --git a/server/sonar-web/src/main/js/apps/overview/meta/Meta.js b/server/sonar-web/src/main/js/apps/overview/meta/Meta.js index 777edf975cb..b5102e26d64 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/Meta.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/Meta.js @@ -45,35 +45,26 @@ const Meta = ({ component, measures, areThereCustomOrganizations }) => { const shouldShowOrganizationKey = component.organization != null && areThereCustomOrganizations; return ( - <div className="overview-meta"> - {hasDescription && ( - <div className="overview-meta-card overview-meta-description"> - {description} - </div> - )} + <div className="overview-meta"> + {hasDescription && + <div className="overview-meta-card overview-meta-description"> + {description} + </div>} - <MetaSize component={component} measures={measures}/> + <MetaSize component={component} measures={measures} /> - {shouldShowQualityGate && ( - <MetaQualityGate gate={qualityGate}/> - )} + {shouldShowQualityGate && <MetaQualityGate gate={qualityGate} />} - {shouldShowQualityProfiles && ( - <MetaQualityProfiles profiles={qualityProfiles}/> - )} + {shouldShowQualityProfiles && <MetaQualityProfiles profiles={qualityProfiles} />} - <MetaLinks component={component}/> + <MetaLinks component={component} /> - <MetaKey component={component}/> + <MetaKey component={component} /> - {shouldShowOrganizationKey && ( - <MetaOrganizationKey component={component}/> - )} + {shouldShowOrganizationKey && <MetaOrganizationKey component={component} />} - {isProject && ( - <AnalysesList project={component.key}/> - )} - </div> + {isProject && <AnalysesList project={component.key} />} + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaKey.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaKey.js index 8f960b940cd..e5d3e94f567 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaKey.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaKey.js @@ -22,17 +22,18 @@ import { translate } from '../../../helpers/l10n'; const MetaKey = ({ component }) => { return ( - <div className="overview-meta-card"> - <h4 className="overview-meta-header"> - {translate('key')} - </h4> - <input - className="overview-key" - type="text" - value={component.key} - readOnly={true} - onClick={e => e.target.select()}/> - </div> + <div className="overview-meta-card"> + <h4 className="overview-meta-header"> + {translate('key')} + </h4> + <input + className="overview-key" + type="text" + value={component.key} + readOnly={true} + onClick={e => e.target.select()} + /> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.js index 0da02baa3bf..cadb3d6faeb 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.js @@ -31,7 +31,7 @@ type Link = { type State = {| expanded: boolean - |}; +|}; export default class MetaLink extends React.Component { props: { @@ -48,37 +48,42 @@ export default class MetaLink extends React.Component { this.setState((s: State): State => ({ expanded: !s.expanded })); }; - renderLinkIcon (link: Link) { + renderLinkIcon(link: Link) { if (link.type === 'issue') { - return <BugTrackerIcon/>; + return <BugTrackerIcon />; } - return isProvided(link) ? - <i className={`icon-color-link icon-${link.type}`}/> : - <i className="icon-color-link icon-detach"/>; + return isProvided(link) + ? <i className={`icon-color-link icon-${link.type}`} /> + : <i className="icon-color-link icon-detach" />; } - render () { + render() { const { link } = this.props; return ( - <li> - <a className="link-with-icon" href={link.url} target="_blank" - onClick={!isClickable(link) && this.handleClick}> - {this.renderLinkIcon(link)} - - {link.name} - </a> - {this.state.expanded && ( - <div className="little-spacer-top"> - <input type="text" - className="overview-key" - value={link.url} - readOnly={true} - onClick={e => e.target.select()}/> - </div> - )} - </li> + <li> + <a + className="link-with-icon" + href={link.url} + target="_blank" + onClick={!isClickable(link) && this.handleClick} + > + {this.renderLinkIcon(link)} + + {link.name} + </a> + {this.state.expanded && + <div className="little-spacer-top"> + <input + type="text" + className="overview-key" + value={link.url} + readOnly={true} + onClick={e => e.target.select()} + /> + </div>} + </li> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.js index f5e909a8dc3..3d6711101a5 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaLinks.js @@ -29,22 +29,22 @@ export default class MetaLinks extends React.Component { state = {}; - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadLinks(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.component !== this.props.component) { this.loadLinks(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadLinks () { + loadLinks() { getProjectLinks(this.props.component.key).then(links => { if (this.mounted) { this.setState({ links }); @@ -52,7 +52,7 @@ export default class MetaLinks extends React.Component { }); } - render () { + render() { const { links } = this.state; if (links == null || links.length === 0) { @@ -62,13 +62,11 @@ export default class MetaLinks extends React.Component { const orderedLinks = orderLinks(links); return ( - <div className="overview-meta-card"> - <ul className="overview-meta-list"> - {orderedLinks.map(link => ( - <MetaLink key={link.id} link={link}/> - ))} - </ul> - </div> + <div className="overview-meta-card"> + <ul className="overview-meta-list"> + {orderedLinks.map(link => <MetaLink key={link.id} link={link} />)} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaOrganizationKey.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaOrganizationKey.js index 4ad14038ec5..111e84d9b7a 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaOrganizationKey.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaOrganizationKey.js @@ -22,17 +22,18 @@ import { translate } from '../../../helpers/l10n'; const MetaOrganizationKey = ({ component }) => { return ( - <div className="overview-meta-card"> - <h4 className="overview-meta-header"> - {translate('organization_key')} - </h4> - <input - className="overview-key" - type="text" - value={component.organization} - readOnly={true} - onClick={e => e.target.select()}/> - </div> + <div className="overview-meta-card"> + <h4 className="overview-meta-header"> + {translate('organization_key')} + </h4> + <input + className="overview-key" + type="text" + value={component.organization} + readOnly={true} + onClick={e => e.target.select()} + /> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityGate.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityGate.js index ec589edd8a1..3bdda5734d1 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityGate.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityGate.js @@ -24,24 +24,23 @@ import { getQualityGateUrl } from '../../../helpers/urls'; const MetaQualityGate = ({ gate }) => { return ( - <div className="overview-meta-card"> - <h4 className="overview-meta-header"> - {translate('overview.quality_gate')} - </h4> + <div className="overview-meta-card"> + <h4 className="overview-meta-header"> + {translate('overview.quality_gate')} + </h4> - <ul className="overview-meta-list"> - <li> - {gate.isDefault && ( - <span className="note spacer-right"> - {'(' + translate('default') + ')'} - </span> - )} - <Link to={getQualityGateUrl(gate.key)}> - {gate.name} - </Link> - </li> - </ul> - </div> + <ul className="overview-meta-list"> + <li> + {gate.isDefault && + <span className="note spacer-right"> + {'(' + translate('default') + ')'} + </span>} + <Link to={getQualityGateUrl(gate.key)}> + {gate.name} + </Link> + </li> + </ul> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.js index b016665f831..d971e541743 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.js @@ -31,19 +31,18 @@ class MetaQualityProfiles extends React.Component { deprecatedByKey: {} }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadDeprecatedRules(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadDeprecatedRules () { - const requests = this.props.profiles.map(profile => ( - this.loadDeprecatedRulesForProfile(profile.key) - )); + loadDeprecatedRules() { + const requests = this.props.profiles.map(profile => + this.loadDeprecatedRulesForProfile(profile.key)); Promise.all(requests).then(responses => { if (this.mounted) { const deprecatedByKey = {}; @@ -56,7 +55,7 @@ class MetaQualityProfiles extends React.Component { }); } - loadDeprecatedRulesForProfile (profileKey) { + loadDeprecatedRulesForProfile(profileKey) { const data = { qprofile: profileKey, activation: 'true', @@ -66,63 +65,64 @@ class MetaQualityProfiles extends React.Component { return searchRules(data).then(r => r.total); } - getDeprecatedRulesCount (profile) { + getDeprecatedRulesCount(profile) { const count = this.state.deprecatedByKey[profile.key]; return count || 0; } - renderProfile (profile) { + renderProfile(profile) { const languageFromStore = this.props.languages[profile.language]; const languageName = languageFromStore ? languageFromStore.name : profile.language; const inner = ( - <div className="text-ellipsis"> - <span className="note spacer-right"> - {'(' + languageName + ')'} - </span> - <Link to={getQualityProfileUrl(profile.key)}> - {profile.name} - </Link> - </div> + <div className="text-ellipsis"> + <span className="note spacer-right"> + {'(' + languageName + ')'} + </span> + <Link to={getQualityProfileUrl(profile.key)}> + {profile.name} + </Link> + </div> ); const count = this.getDeprecatedRulesCount(profile); if (count > 0) { - const tooltip = - translateWithParameters('overview.deprecated_profile', count); + const tooltip = translateWithParameters('overview.deprecated_profile', count); return ( - <li key={profile.key} - className="overview-deprecated-rules" - title={tooltip} - data-toggle="tooltip"> - {inner} - </li> + <li + key={profile.key} + className="overview-deprecated-rules" + title={tooltip} + data-toggle="tooltip" + > + {inner} + </li> ); } return ( - <li key={profile.key}> - {inner} - </li> + <li key={profile.key}> + {inner} + </li> ); } - render () { + render() { const { profiles } = this.props; return ( - <TooltipsContainer> - <div className="overview-meta-card"> - <h4 className="overview-meta-header"> - {translate('overview.quality_profiles')} - </h4> - - <ul className="overview-meta-list"> - {profiles.map(profile => this.renderProfile(profile))} - </ul> - </div> - </TooltipsContainer> + <TooltipsContainer> + <div className="overview-meta-card"> + <h4 className="overview-meta-header"> + {translate('overview.quality_profiles')} + </h4> + + <ul className="overview-meta-list"> + {profiles.map(profile => this.renderProfile(profile))} + </ul> + </div> + </TooltipsContainer> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.js b/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.js index 2d836e85a5c..41659f64124 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.js @@ -30,32 +30,31 @@ export default class MetaSize extends React.Component { measures: React.PropTypes.array.isRequired }; - render () { - const ncloc = this.props.measures - .find(measure => measure.metric.key === 'ncloc'); - const languageDistribution = this.props.measures - .find(measure => measure.metric.key === 'ncloc_language_distribution'); + render() { + const ncloc = this.props.measures.find(measure => measure.metric.key === 'ncloc'); + const languageDistribution = this.props.measures.find( + measure => measure.metric.key === 'ncloc_language_distribution' + ); if (ncloc == null || languageDistribution == null) { return null; } return ( - <div id="overview-size" className="overview-meta-card"> - <div id="overview-ncloc" className="overview-meta-size-ncloc"> - <span className="spacer-right"> - <SizeRating value={ncloc.value}/> - </span> - <DrilldownLink component={this.props.component.key} metric="ncloc"> - {formatMeasure(ncloc.value, 'SHORT_INT')} - </DrilldownLink> - <div className="overview-domain-measure-label text-muted">{getMetricName('ncloc')}</div> - </div> - <div id="overview-language-distribution" - className="overview-meta-size-lang-dist"> - <LanguageDistribution distribution={languageDistribution.value}/> - </div> + <div id="overview-size" className="overview-meta-card"> + <div id="overview-ncloc" className="overview-meta-size-ncloc"> + <span className="spacer-right"> + <SizeRating value={ncloc.value} /> + </span> + <DrilldownLink component={this.props.component.key} metric="ncloc"> + {formatMeasure(ncloc.value, 'SHORT_INT')} + </DrilldownLink> + <div className="overview-domain-measure-label text-muted">{getMetricName('ncloc')}</div> + </div> + <div id="overview-language-distribution" className="overview-meta-size-lang-dist"> + <LanguageDistribution distribution={languageDistribution.value} /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.js b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.js index f661877b510..1f0cd416d08 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.js +++ b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.js @@ -30,9 +30,7 @@ it('should match snapshot', () => { type: 'foo' }; - expect(shallow( - <MetaLink link={link}/> - )).toMatchSnapshot(); + expect(shallow(<MetaLink link={link} />)).toMatchSnapshot(); }); it('should expand and collapse link', () => { @@ -43,7 +41,7 @@ it('should expand and collapse link', () => { type: 'foo' }; - const wrapper = shallow(<MetaLink link={link}/>); + const wrapper = shallow(<MetaLink link={link} />); expect(wrapper).toMatchSnapshot(); // expand diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/EmptyQualityGate.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/EmptyQualityGate.js index 88334a346b9..cdb8b2eb66e 100644 --- a/server/sonar-web/src/main/js/apps/overview/qualityGate/EmptyQualityGate.js +++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/EmptyQualityGate.js @@ -22,14 +22,14 @@ import { translate } from '../../../helpers/l10n'; const EmptyQualityGate = () => { return ( - <div className="overview-quality-gate"> - <h2 className="overview-title"> - {translate('overview.quality_gate')} - </h2> - <p className="overview-quality-gate-warning"> - {translate('overview.you_should_define_quality_gate')} - </p> - </div> + <div className="overview-quality-gate"> + <h2 className="overview-title"> + {translate('overview.quality_gate')} + </h2> + <p className="overview-quality-gate-warning"> + {translate('overview.you_should_define_quality_gate')} + </p> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js index 6b872f96c9c..0968fec0d3b 100644 --- a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js +++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js @@ -24,22 +24,20 @@ import { ComponentType, MeasuresListType, PeriodsListType } from '../propTypes'; import { translate } from '../../../helpers/l10n'; import Level from '../../../components/ui/Level'; -function parseQualityGateDetails (rawDetails) { +function parseQualityGateDetails(rawDetails) { return JSON.parse(rawDetails); } -function isProject (component) { +function isProject(component) { return component.qualifier === 'TRK'; } const QualityGate = ({ component, measures, periods }) => { - const statusMeasure = - measures.find(measure => measure.metric.key === 'alert_status'); - const detailsMeasure = - measures.find(measure => measure.metric.key === 'quality_gate_details'); + const statusMeasure = measures.find(measure => measure.metric.key === 'alert_status'); + const detailsMeasure = measures.find(measure => measure.metric.key === 'quality_gate_details'); if (!statusMeasure) { - return isProject(component) ? <EmptyQualityGate/> : null; + return isProject(component) ? <EmptyQualityGate /> : null; } const level = statusMeasure.value; @@ -50,19 +48,15 @@ const QualityGate = ({ component, measures, periods }) => { } return ( - <div className="overview-quality-gate" id="overview-quality-gate"> - <h2 className="overview-title"> - {translate('overview.quality_gate')} - <Level level={level}/> - </h2> + <div className="overview-quality-gate" id="overview-quality-gate"> + <h2 className="overview-title"> + {translate('overview.quality_gate')} + <Level level={level} /> + </h2> - {conditions.length > 0 && ( - <QualityGateConditions - component={component} - periods={periods} - conditions={conditions}/> - )} - </div> + {conditions.length > 0 && + <QualityGateConditions component={component} periods={periods} conditions={conditions} />} + </div> ); }; @@ -73,4 +67,3 @@ QualityGate.propTypes = { }; export default QualityGate; - diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateCondition.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateCondition.js index 064c3d2b447..e42eaf2be69 100644 --- a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateCondition.js +++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateCondition.js @@ -55,7 +55,7 @@ export default class QualityGateCondition extends React.Component { } }; - getIssuesUrl (sinceLeakPeriod: boolean, customQuery: {}) { + getIssuesUrl(sinceLeakPeriod: boolean, customQuery: {}) { const query: Object = { resolved: 'false', ...customQuery @@ -66,11 +66,11 @@ export default class QualityGateCondition extends React.Component { return getComponentIssuesUrl(this.props.component.key, query); } - getUrlForCodeSmells (sinceLeakPeriod: boolean) { + getUrlForCodeSmells(sinceLeakPeriod: boolean) { return this.getIssuesUrl(sinceLeakPeriod, { types: 'CODE_SMELL' }); } - getUrlForBugsOrVulnerabilities (type: string, sinceLeakPeriod: boolean) { + getUrlForBugsOrVulnerabilities(type: string, sinceLeakPeriod: boolean) { const RATING_TO_SEVERITIES_MAPPING = { '1': 'BLOCKER,CRITICAL,MAJOR,MINOR', '2': 'BLOCKER,CRITICAL,MAJOR', @@ -87,13 +87,13 @@ export default class QualityGateCondition extends React.Component { }); } - getUrlForType (type: string, sinceLeakPeriod: boolean) { - return type === 'CODE_SMELL' ? - this.getUrlForCodeSmells(sinceLeakPeriod) : - this.getUrlForBugsOrVulnerabilities(type, sinceLeakPeriod); + getUrlForType(type: string, sinceLeakPeriod: boolean) { + return type === 'CODE_SMELL' + ? this.getUrlForCodeSmells(sinceLeakPeriod) + : this.getUrlForBugsOrVulnerabilities(type, sinceLeakPeriod); } - wrapWithLink (children: Object) { + wrapWithLink(children: Object) { const { component, periods, condition } = this.props; const period = getPeriod(periods, condition.period); @@ -102,37 +102,36 @@ export default class QualityGateCondition extends React.Component { const className = classNames( 'overview-quality-gate-condition', 'overview-quality-gate-condition-' + condition.level.toLowerCase(), - { 'overview-quality-gate-condition-leak': period != null } + { 'overview-quality-gate-condition-leak': period != null } ); const metricKey = condition.measure.metric.key; const RATING_METRICS_MAPPING = { - 'reliability_rating': ['BUG', false], - 'new_reliability_rating': ['BUG', true], - 'security_rating': ['VULNERABILITY', false], - 'new_security_rating': ['VULNERABILITY', true], - 'sqale_rating': ['CODE_SMELL', false], - 'new_sqale_rating': ['CODE_SMELL', true] + reliability_rating: ['BUG', false], + new_reliability_rating: ['BUG', true], + security_rating: ['VULNERABILITY', false], + new_security_rating: ['VULNERABILITY', true], + sqale_rating: ['CODE_SMELL', false], + new_sqale_rating: ['CODE_SMELL', true] }; - return RATING_METRICS_MAPPING[metricKey] ? ( - <Link to={this.getUrlForType(...RATING_METRICS_MAPPING[metricKey])} className={className}> - {children} - </Link> - ) : ( - <DrilldownLink - className={className} - component={component.key} - metric={condition.measure.metric.key} - period={condition.period} - periodDate={periodDate}> - {children} - </DrilldownLink> - ); + return RATING_METRICS_MAPPING[metricKey] + ? <Link to={this.getUrlForType(...RATING_METRICS_MAPPING[metricKey])} className={className}> + {children} + </Link> + : <DrilldownLink + className={className} + component={component.key} + metric={condition.measure.metric.key} + period={condition.period} + periodDate={periodDate} + > + {children} + </DrilldownLink>; } - render () { + render() { const { periods, condition } = this.props; const { measure } = condition; @@ -141,40 +140,36 @@ export default class QualityGateCondition extends React.Component { const isRating = metric.type === 'RATING'; const isDiff = isDiffMetric(metric.key); - const threshold = condition.level === 'ERROR' ? - condition.error : - condition.warning; + const threshold = condition.level === 'ERROR' ? condition.error : condition.warning; - const actual = condition.period ? - getPeriodValue(measure, condition.period) : - measure.value; + const actual = condition.period ? getPeriodValue(measure, condition.period) : measure.value; const period = getPeriod(periods, condition.period); - const operator = isRating ? - translate('quality_gates.operator', condition.op, 'rating') : - translate('quality_gates.operator', condition.op); + const operator = isRating + ? translate('quality_gates.operator', condition.op, 'rating') + : translate('quality_gates.operator', condition.op); return this.wrapWithLink( <div className="overview-quality-gate-condition-container"> - <div className="overview-quality-gate-condition-value"> - <Measure measure={{ value: actual, leak: actual }} metric={metric}/> - </div> + <div className="overview-quality-gate-condition-value"> + <Measure measure={{ value: actual, leak: actual }} metric={metric} /> + </div> - <div> - <div className="overview-quality-gate-condition-metric"> - <IssueTypeIcon query={metric.key} className="little-spacer-right"/> - {metric.name} - </div> - {!isDiff && period != null && ( - <div className="overview-quality-gate-condition-period"> - {translate('quality_gates.conditions.leak')} - </div> - )} - <div className="overview-quality-gate-threshold"> - {operator} {formatMeasure(threshold, metric.type)} - </div> + <div> + <div className="overview-quality-gate-condition-metric"> + <IssueTypeIcon query={metric.key} className="little-spacer-right" /> + {metric.name} + </div> + {!isDiff && + period != null && + <div className="overview-quality-gate-condition-period"> + {translate('quality_gates.conditions.leak')} + </div>} + <div className="overview-quality-gate-threshold"> + {operator} {formatMeasure(threshold, metric.type)} </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js index e689587fcb2..6c036de57de 100644 --- a/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js +++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGateConditions.js @@ -27,7 +27,7 @@ import { enhanceMeasuresWithMetrics } from '../../../helpers/measures'; const LEVEL_ORDER = ['ERROR', 'WARN']; -function enhanceConditions (conditions, measures) { +function enhanceConditions(conditions, measures) { return conditions.map(c => { const measure = measures.find(measure => measure.metric.key === c.metric); return { ...c, measure }; @@ -44,36 +44,33 @@ export default class QualityGateConditions extends React.Component { loading: true }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadFailedMeasures(); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentDidUpdate (prevProps) { - if (prevProps.conditions !== this.props.conditions || - prevProps.component !== this.props.component) { + componentDidUpdate(prevProps) { + if ( + prevProps.conditions !== this.props.conditions || prevProps.component !== this.props.component + ) { this.loadFailedMeasures(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadFailedMeasures () { + loadFailedMeasures() { const { component, conditions } = this.props; const failedConditions = conditions.filter(c => c.level !== 'OK'); if (failedConditions.length > 0) { const metrics = failedConditions.map(condition => condition.metric); - getMeasuresAndMeta( - component.key, - metrics, - { additionalFields: 'metrics' } - ).then(r => { + getMeasuresAndMeta(component.key, metrics, { additionalFields: 'metrics' }).then(r => { if (this.mounted) { const measures = enhanceMeasuresWithMetrics(r.component.measures, r.metrics); this.setState({ @@ -87,7 +84,7 @@ export default class QualityGateConditions extends React.Component { } } - render () { + render() { const { component, periods } = this.props; const { loading, conditions } = this.state; @@ -102,16 +99,19 @@ export default class QualityGateConditions extends React.Component { ); return ( - <div id="overview-quality-gate-conditions-list" - className="overview-quality-gate-conditions-list clearfix"> - {sortedConditions.map(condition => ( - <QualityGateCondition - key={condition.measure.metric.key} - component={component} - periods={periods} - condition={condition}/> - ))} - </div> + <div + id="overview-quality-gate-conditions-list" + className="overview-quality-gate-conditions-list clearfix" + > + {sortedConditions.map(condition => ( + <QualityGateCondition + key={condition.measure.metric.key} + component={component} + periods={periods} + condition={condition} + /> + ))} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/QualityGateCondition-test.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/QualityGateCondition-test.js index 6b9323eafcc..e798bcd3326 100644 --- a/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/QualityGateCondition-test.js +++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/QualityGateCondition-test.js @@ -53,9 +53,11 @@ it('open_issues', () => { metric: 'open_issues', op: 'GT' }; - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); it('new_open_issues', () => { @@ -74,49 +76,63 @@ it('new_open_issues', () => { metric: 'new_open_issues', op: 'GT' }; - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); it('reliability_rating', () => { const condition = mockRatingCondition('reliability_rating'); - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); it('security_rating', () => { const condition = mockRatingCondition('security_rating'); - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); it('sqale_rating', () => { const condition = mockRatingCondition('sqale_rating'); - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); it('new_reliability_rating', () => { const condition = mockRatingCondition('new_reliability_rating'); - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); it('new_security_rating', () => { const condition = mockRatingCondition('new_security_rating'); - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); it('new_sqale_rating', () => { const condition = mockRatingCondition('new_sqale_rating'); - expect(shallow( - <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition}/> - )).toMatchSnapshot(); + expect( + shallow( + <QualityGateCondition component={{ key: 'abcd-key' }} periods={[]} condition={condition} /> + ) + ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/overview/routes.js b/server/sonar-web/src/main/js/apps/overview/routes.js index fcfa259f54b..a8f9dc5e335 100644 --- a/server/sonar-web/src/main/js/apps/overview/routes.js +++ b/server/sonar-web/src/main/js/apps/overview/routes.js @@ -22,6 +22,6 @@ import { IndexRoute, Redirect } from 'react-router'; import AppContainer from './components/AppContainer'; export default [ - <Redirect key="redirect" from="/dashboard/index" to="/dashboard"/>, - <IndexRoute key="index" component={AppContainer}/> + <Redirect key="redirect" from="/dashboard/index" to="/dashboard" />, + <IndexRoute key="index" component={AppContainer} /> ]; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js b/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js index 2119972b66e..1741a96ca90 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js @@ -45,7 +45,7 @@ export default class ActionsCell extends React.Component { router: React.PropTypes.object }; - handleUpdateClick (e) { + handleUpdateClick(e) { e.preventDefault(); new UpdateView({ model: new Backbone.Model(this.props.permissionTemplate), @@ -53,142 +53,137 @@ export default class ActionsCell extends React.Component { }).render(); } - handleDeleteClick (e) { + handleDeleteClick(e) { e.preventDefault(); new DeleteView({ model: new Backbone.Model(this.props.permissionTemplate) - }).on('done', () => { - const pathname = this.props.organization ? - `/organizations/${this.props.organization.key}/permission_templates` : - '/permission_templates'; - this.context.router.replace(pathname); - this.props.refresh(); - }).render(); + }) + .on('done', () => { + const pathname = this.props.organization + ? `/organizations/${this.props.organization.key}/permission_templates` + : '/permission_templates'; + this.context.router.replace(pathname); + this.props.refresh(); + }) + .render(); } - setDefault (qualifier, e) { + setDefault(qualifier, e) { e.preventDefault(); - setDefaultPermissionTemplate( - this.props.permissionTemplate.id, - qualifier - ).then(this.props.refresh); + setDefaultPermissionTemplate(this.props.permissionTemplate.id, qualifier).then( + this.props.refresh + ); } - getAvailableQualifiers () { - const topQualifiers = this.props.organization && !this.props.organization.isDefault ? - ['TRK'] : - this.props.topQualifiers; + getAvailableQualifiers() { + const topQualifiers = this.props.organization && !this.props.organization.isDefault + ? ['TRK'] + : this.props.topQualifiers; return difference(topQualifiers, this.props.permissionTemplate.defaultFor); } - renderDropdownIcon (icon) { + renderDropdownIcon(icon) { const style = { display: 'inline-block', width: 16, marginRight: 4, textAlign: 'center' }; - return ( - <div style={style}>{icon}</div> - ); + return <div style={style}>{icon}</div>; } - renderSetDefaultsControl () { + renderSetDefaultsControl() { const availableQualifiers = this.getAvailableQualifiers(); if (availableQualifiers.length === 0) { return null; } - return this.props.topQualifiers.length === 1 ? - this.renderIfSingleTopQualifier(availableQualifiers) : - this.renderIfMultipleTopQualifiers(availableQualifiers); + return this.props.topQualifiers.length === 1 + ? this.renderIfSingleTopQualifier(availableQualifiers) + : this.renderIfMultipleTopQualifiers(availableQualifiers); } - renderSetDefaultLink (qualifier, child) { + renderSetDefaultLink(qualifier, child) { return ( - <li key={qualifier}> - <a href="#" - className="js-set-default" - data-qualifier={qualifier} - onClick={this.setDefault.bind(this, qualifier)}> - {this.renderDropdownIcon(<i className="icon-check"/>)} - {child} - </a> - </li> + <li key={qualifier}> + <a + href="#" + className="js-set-default" + data-qualifier={qualifier} + onClick={this.setDefault.bind(this, qualifier)} + > + {this.renderDropdownIcon(<i className="icon-check" />)} + {child} + </a> + </li> ); } - renderIfSingleTopQualifier (availableQualifiers) { - return availableQualifiers.map(qualifier => ( - this.renderSetDefaultLink(qualifier, ( - <span>{translate('permission_templates.set_default')}</span> - ))) - ); + renderIfSingleTopQualifier(availableQualifiers) { + return availableQualifiers.map(qualifier => + this.renderSetDefaultLink( + qualifier, + <span>{translate('permission_templates.set_default')}</span> + )); } - renderIfMultipleTopQualifiers (availableQualifiers) { - return availableQualifiers.map(qualifier => ( - this.renderSetDefaultLink(qualifier, ( - <span> - {translate('permission_templates.set_default_for')} - {' '} - <QualifierIcon qualifier={qualifier}/> - {' '} - {translate('qualifiers', qualifier)} - </span> - ))) - ); + renderIfMultipleTopQualifiers(availableQualifiers) { + return availableQualifiers.map(qualifier => + this.renderSetDefaultLink( + qualifier, + <span> + {translate('permission_templates.set_default_for')} + {' '} + <QualifierIcon qualifier={qualifier} /> + {' '} + {translate('qualifiers', qualifier)} + </span> + )); } - render () { + render() { const { permissionTemplate: t, organization } = this.props; - const pathname = organization ? - `/organizations/${organization.key}/permission_templates` : - '/permission_templates'; + const pathname = organization + ? `/organizations/${organization.key}/permission_templates` + : '/permission_templates'; return ( - <div className="dropdown"> - <button className="dropdown-toggle" data-toggle="dropdown"> - {translate('actions')} - {' '} - <i className="icon-dropdown"/> - </button> - - <ul className="dropdown-menu dropdown-menu-right"> - {this.renderSetDefaultsControl()} - - {!this.props.fromDetails && ( - <li> - <Link to={{ pathname, query: { id: t.id } }}> - {this.renderDropdownIcon(<i className="icon-edit"/>)} - Edit Permissions - </Link> - </li> - )} + <div className="dropdown"> + <button className="dropdown-toggle" data-toggle="dropdown"> + {translate('actions')} + {' '} + <i className="icon-dropdown" /> + </button> + <ul className="dropdown-menu dropdown-menu-right"> + {this.renderSetDefaultsControl()} + + {!this.props.fromDetails && + <li> + <Link to={{ pathname, query: { id: t.id } }}> + {this.renderDropdownIcon(<i className="icon-edit" />)} + Edit Permissions + </Link> + </li>} + + <li> + <a href="#" className="js-update" onClick={this.handleUpdateClick.bind(this)}> + {this.renderDropdownIcon(<i className="icon-edit" />)} + Update Details + </a> + </li> + + {t.defaultFor.length === 0 && <li> - <a href="#" - className="js-update" - onClick={this.handleUpdateClick.bind(this)}> - {this.renderDropdownIcon(<i className="icon-edit"/>)} - Update Details + <a href="#" className="js-delete" onClick={this.handleDeleteClick.bind(this)}> + {this.renderDropdownIcon(<i className="icon-delete" />)} + {translate('delete')} </a> - </li> - - {t.defaultFor.length === 0 && ( - <li> - <a href="#" - className="js-delete" - onClick={this.handleDeleteClick.bind(this)}> - {this.renderDropdownIcon(<i className="icon-delete"/>)} - {translate('delete')} - </a> - </li> - )} - </ul> - </div> + </li>} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/App.js b/server/sonar-web/src/main/js/apps/permission-templates/components/App.js index 0bf2c2fa669..911468cc821 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/App.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/App.js @@ -21,11 +21,7 @@ import React from 'react'; import Home from './Home'; import Template from './Template'; import { getPermissionTemplates } from '../../../api/permissions'; -import { - sortPermissions, - mergePermissionsToTemplates, - mergeDefaultsToTemplates -} from '../utils'; +import { sortPermissions, mergePermissionsToTemplates, mergeDefaultsToTemplates } from '../utils'; import '../../permissions/styles.css'; export default class App extends React.Component { @@ -41,22 +37,24 @@ export default class App extends React.Component { permissionTemplates: [] }; - componentWillMount () { + componentWillMount() { this.requestPermissions = this.requestPermissions.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.requestPermissions(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - requestPermissions () { + requestPermissions() { const { organization } = this.props; - const request = organization ? getPermissionTemplates(organization.key) : getPermissionTemplates(); + const request = organization + ? getPermissionTemplates(organization.key) + : getPermissionTemplates(); return request.then(r => { if (this.mounted) { const permissions = sortPermissions(r.permissions); @@ -73,22 +71,23 @@ export default class App extends React.Component { }); } - renderTemplate (id) { + renderTemplate(id) { if (!this.state.ready) { return null; } const template = this.state.permissionTemplates.find(t => t.id === id); return ( - <Template - organization={this.props.organization} - template={template} - refresh={this.requestPermissions} - topQualifiers={this.props.topQualifiers}/> + <Template + organization={this.props.organization} + template={template} + refresh={this.requestPermissions} + topQualifiers={this.props.topQualifiers} + /> ); } - render () { + render() { const { id } = this.props.location.query; if (id) { @@ -96,13 +95,14 @@ export default class App extends React.Component { } return ( - <Home - organization={this.props.organization} - topQualifiers={this.props.topQualifiers} - permissions={this.state.permissions} - permissionTemplates={this.state.permissionTemplates} - ready={this.state.ready} - refresh={this.requestPermissions}/> + <Home + organization={this.props.organization} + topQualifiers={this.props.topQualifiers} + permissions={this.state.permissions} + permissionTemplates={this.state.permissionTemplates} + ready={this.state.ready} + refresh={this.requestPermissions} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/AppContainer.js b/server/sonar-web/src/main/js/apps/permission-templates/components/AppContainer.js index 4a62e4c7c7a..d324dd36255 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/AppContainer.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/AppContainer.js @@ -26,6 +26,4 @@ const mapStateToProps = state => ({ topQualifiers: getRootQualifiers(getAppState(state)) }); -export default connect( - mapStateToProps -)(App); +export default connect(mapStateToProps)(App); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js b/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js index fa28961122c..2d13657c8a4 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js @@ -28,21 +28,21 @@ export default class Defaults extends React.Component { permissionTemplate: PermissionTemplateType.isRequired }; - render () { - const qualifiersToDisplay = this.props.organization && !this.props.organization.isDefault ? - ['TRK'] : - this.props.permissionTemplate.defaultFor; + render() { + const qualifiersToDisplay = this.props.organization && !this.props.organization.isDefault + ? ['TRK'] + : this.props.permissionTemplate.defaultFor; const qualifiers = sortBy(qualifiersToDisplay) - .map(qualifier => translate('qualifiers', qualifier)) - .join(', '); + .map(qualifier => translate('qualifiers', qualifier)) + .join(', '); return ( - <div> - <span className="badge spacer-right"> - {translate('default')} for {qualifiers} - </span> - </div> + <div> + <span className="badge spacer-right"> + {translate('default')} for {qualifiers} + </span> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/Header.js b/server/sonar-web/src/main/js/apps/permission-templates/components/Header.js index 9473e5fb219..4a1d348bf0e 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/Header.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/Header.js @@ -33,48 +33,48 @@ export default class Header extends React.Component { router: React.PropTypes.object }; - componentWillMount () { + componentWillMount() { this.handleCreateClick = this.handleCreateClick.bind(this); } - handleCreateClick (e) { + handleCreateClick(e) { e.preventDefault(); const { organization } = this.props; - new CreateView({ organization }).on('done', r => { - this.props.refresh().then(() => { - const pathname = organization ? - `/organizations/${organization.key}/permission_templates` : - '/permission_templates'; - this.context.router.push({ - pathname, - query: { id: r.permissionTemplate.id } + new CreateView({ organization }) + .on('done', r => { + this.props.refresh().then(() => { + const pathname = organization + ? `/organizations/${organization.key}/permission_templates` + : '/permission_templates'; + this.context.router.push({ + pathname, + query: { id: r.permissionTemplate.id } + }); }); - }); - }).render(); + }) + .render(); } - render () { + render() { return ( - <header id="project-permissions-header" className="page-header"> - <h1 className="page-title"> - {translate('permission_templates.page')} - </h1> + <header id="project-permissions-header" className="page-header"> + <h1 className="page-title"> + {translate('permission_templates.page')} + </h1> - {!this.props.ready && ( - <i className="spinner"/> - )} + {!this.props.ready && <i className="spinner" />} - <div className="page-actions"> - <button onClick={this.handleCreateClick}> - {translate('create')} - </button> - </div> + <div className="page-actions"> + <button onClick={this.handleCreateClick}> + {translate('create')} + </button> + </div> - <p className="page-description"> - {translate('permission_templates.page.description')} - </p> - </header> + <p className="page-description"> + {translate('permission_templates.page.description')} + </p> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/Home.js b/server/sonar-web/src/main/js/apps/permission-templates/components/Home.js index d07ca10d75c..aa23792c19f 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/Home.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/Home.js @@ -34,27 +34,27 @@ export default class Home extends React.Component { refresh: React.PropTypes.func.isRequired }; - render () { + render() { return ( - <div className="page page-limited"> - <Helmet - title={translate('permission_templates.page')} - titleTemplate="SonarQube - %s"/> + <div className="page page-limited"> + <Helmet title={translate('permission_templates.page')} titleTemplate="SonarQube - %s" /> - <Header - organization={this.props.organization} - ready={this.props.ready} - refresh={this.props.refresh}/> + <Header + organization={this.props.organization} + ready={this.props.ready} + refresh={this.props.refresh} + /> - <TooltipsContainer> - <List - organization={this.props.organization} - permissionTemplates={this.props.permissionTemplates} - permissions={this.props.permissions} - topQualifiers={this.props.topQualifiers} - refresh={this.props.refresh}/> - </TooltipsContainer> - </div> + <TooltipsContainer> + <List + organization={this.props.organization} + permissionTemplates={this.props.permissionTemplates} + permissions={this.props.permissions} + topQualifiers={this.props.topQualifiers} + refresh={this.props.refresh} + /> + </TooltipsContainer> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/List.js b/server/sonar-web/src/main/js/apps/permission-templates/components/List.js index 30d2de1feb0..dbee8b797c3 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/List.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/List.js @@ -25,28 +25,28 @@ import { PermissionTemplateType, CallbackType } from '../propTypes'; export default class List extends React.Component { static propTypes = { organization: React.PropTypes.object, - permissionTemplates: React.PropTypes.arrayOf( - PermissionTemplateType).isRequired, + permissionTemplates: React.PropTypes.arrayOf(PermissionTemplateType).isRequired, permissions: React.PropTypes.array.isRequired, topQualifiers: React.PropTypes.array.isRequired, refresh: CallbackType }; - render () { + render() { const permissionTemplates = this.props.permissionTemplates.map(p => ( - <ListItem - key={p.id} - organization={this.props.organization} - permissionTemplate={p} - topQualifiers={this.props.topQualifiers} - refresh={this.props.refresh}/> + <ListItem + key={p.id} + organization={this.props.organization} + permissionTemplate={p} + topQualifiers={this.props.topQualifiers} + refresh={this.props.refresh} + /> )); return ( - <table id="permission-templates" className="data zebra permissions-table"> - <ListHeader permissions={this.props.permissions}/> - <tbody>{permissionTemplates}</tbody> - </table> + <table id="permission-templates" className="data zebra permissions-table"> + <ListHeader permissions={this.props.permissions} /> + <tbody>{permissionTemplates}</tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js b/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js index 552b78c18a5..29a1cf51d33 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js @@ -24,25 +24,22 @@ export default class ListHeader extends React.Component { permissions: React.PropTypes.array.isRequired }; - render () { + render() { const cells = this.props.permissions.map(p => ( - <th key={p.key} className="permission-column"> - {p.name} - <i - className="icon-help little-spacer-left" - title={p.description} - data-toggle="tooltip"/> - </th> + <th key={p.key} className="permission-column"> + {p.name} + <i className="icon-help little-spacer-left" title={p.description} data-toggle="tooltip" /> + </th> )); return ( - <thead> + <thead> <tr> <th> </th> {cells} <th className="thin nowrap text-right"> </th> </tr> - </thead> + </thead> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/ListItem.js b/server/sonar-web/src/main/js/apps/permission-templates/components/ListItem.js index 3126e0cc7f8..15c586572a7 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/ListItem.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/ListItem.js @@ -33,12 +33,12 @@ export default class ListItem extends React.Component { refresh: CallbackType }; - componentWillMount () { + componentWillMount() { this.handleShowGroups = this.handleShowGroups.bind(this); this.handleShowUsers = this.handleShowUsers.bind(this); } - handleShowGroups (permission) { + handleShowGroups(permission) { new GroupsView({ permission, permissionTemplate: this.props.permissionTemplate, @@ -46,7 +46,7 @@ export default class ListItem extends React.Component { }).render(); } - handleShowUsers (permission) { + handleShowUsers(permission) { new UsersView({ permission, permissionTemplate: this.props.permissionTemplate, @@ -54,30 +54,30 @@ export default class ListItem extends React.Component { }).render(); } - render () { + render() { const permissions = this.props.permissionTemplate.permissions.map(p => ( - <PermissionCell key={p.key} permission={p}/> + <PermissionCell key={p.key} permission={p} /> )); return ( - <tr - data-id={this.props.permissionTemplate.id} - data-name={this.props.permissionTemplate.name}> - <NameCell - organization={this.props.organization} - permissionTemplate={this.props.permissionTemplate} - topQualifiers={this.props.topQualifiers}/> + <tr data-id={this.props.permissionTemplate.id} data-name={this.props.permissionTemplate.name}> + <NameCell + organization={this.props.organization} + permissionTemplate={this.props.permissionTemplate} + topQualifiers={this.props.topQualifiers} + /> - {permissions} + {permissions} - <td className="nowrap thin text-right"> - <ActionsCell - organization={this.props.organization} - permissionTemplate={this.props.permissionTemplate} - topQualifiers={this.props.topQualifiers} - refresh={this.props.refresh}/> - </td> - </tr> + <td className="nowrap thin text-right"> + <ActionsCell + organization={this.props.organization} + permissionTemplate={this.props.permissionTemplate} + topQualifiers={this.props.topQualifiers} + refresh={this.props.refresh} + /> + </td> + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/NameCell.js b/server/sonar-web/src/main/js/apps/permission-templates/components/NameCell.js index f971c33003c..73c0f217530 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/NameCell.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/NameCell.js @@ -28,39 +28,37 @@ export default class NameCell extends React.Component { permissionTemplate: PermissionTemplateType.isRequired }; - render () { + render() { const { permissionTemplate: t, organization } = this.props; - const pathname = organization ? - `/organizations/${organization.key}/permission_templates` : - '/permission_templates'; + const pathname = organization + ? `/organizations/${organization.key}/permission_templates` + : '/permission_templates'; return ( - <td> - <Link to={{ pathname, query: { id: t.id } }}> - <strong className="js-name">{t.name}</strong> - </Link> + <td> + <Link to={{ pathname, query: { id: t.id } }}> + <strong className="js-name">{t.name}</strong> + </Link> - {t.defaultFor.length > 0 && ( - <div className="spacer-top js-defaults"> - <Defaults - permissionTemplate={this.props.permissionTemplate} - organization={organization}/> - </div> - )} + {t.defaultFor.length > 0 && + <div className="spacer-top js-defaults"> + <Defaults + permissionTemplate={this.props.permissionTemplate} + organization={organization} + /> + </div>} - {!!t.description && ( - <div className="spacer-top js-description"> - {t.description} - </div> - )} + {!!t.description && + <div className="spacer-top js-description"> + {t.description} + </div>} - {!!t.projectKeyPattern && ( - <div className="spacer-top js-project-key-pattern"> - Project Key Pattern: <code>{t.projectKeyPattern}</code> - </div> - )} - </td> + {!!t.projectKeyPattern && + <div className="spacer-top js-project-key-pattern"> + Project Key Pattern: <code>{t.projectKeyPattern}</code> + </div>} + </td> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionCell.js b/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionCell.js index 75e71777f78..8ff09842585 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionCell.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/PermissionCell.js @@ -26,27 +26,26 @@ export default class PermissionCell extends React.Component { permission: PermissionType.isRequired }; - render () { + render() { const { permission: p } = this.props; return ( - <td className="permission-column" data-permission={p.key}> - <div className="permission-column-inner"> - <ul> - {p.withProjectCreator && ( - <li className="little-spacer-bottom"> - {translate('permission_templates.project_creators')} - </li> - )} + <td className="permission-column" data-permission={p.key}> + <div className="permission-column-inner"> + <ul> + {p.withProjectCreator && <li className="little-spacer-bottom"> - <strong>{p.usersCount}</strong>{' user(s)'} - </li> - <li> - <strong>{p.groupsCount}</strong>{' group(s)'} - </li> - </ul> - </div> - </td> + {translate('permission_templates.project_creators')} + </li>} + <li className="little-spacer-bottom"> + <strong>{p.usersCount}</strong>{' user(s)'} + </li> + <li> + <strong>{p.groupsCount}</strong>{' group(s)'} + </li> + </ul> + </div> + </td> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js b/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js index 2ee080765c7..974ef4834f4 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/Template.js @@ -37,7 +37,7 @@ class Template extends React.Component { topQualifiers: React.PropTypes.array.isRequired }; - componentWillMount () { + componentWillMount() { this.requestHolders = this.requestHolders.bind(this); this.requestHoldersDebounced = debounce(this.requestHolders, 250); this.handleSelectPermission = this.handleSelectPermission.bind(this); @@ -47,16 +47,16 @@ class Template extends React.Component { this.handleFilter = this.handleFilter.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.requestHolders(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - requestHolders (realQuery) { + requestHolders(realQuery) { this.props.updateStore({ loading: true }); const { template } = this.props; @@ -66,15 +66,13 @@ class Template extends React.Component { const finalQuery = realQuery != null ? realQuery : query; if (filter !== 'groups') { - requests.push(api.getPermissionTemplateUsers( - template.id, finalQuery, selectedPermission)); + requests.push(api.getPermissionTemplateUsers(template.id, finalQuery, selectedPermission)); } else { requests.push(Promise.resolve([])); } if (filter !== 'users') { - requests.push(api.getPermissionTemplateGroups( - template.id, finalQuery, selectedPermission)); + requests.push(api.getPermissionTemplateGroups(template.id, finalQuery, selectedPermission)); } else { requests.push(Promise.resolve([])); } @@ -88,31 +86,29 @@ class Template extends React.Component { }); } - handleToggleUser (user, permission) { + handleToggleUser(user, permission) { if (user.login === '<creator>') { this.handleToggleProjectCreator(user, permission); return; } const { template } = this.props; const hasPermission = user.permissions.includes(permission); - const request = hasPermission ? - api.revokeTemplatePermissionFromUser( - template.id, user.login, permission) : - api.grantTemplatePermissionToUser( - template.id, user.login, permission); + const request = hasPermission + ? api.revokeTemplatePermissionFromUser(template.id, user.login, permission) + : api.grantTemplatePermissionToUser(template.id, user.login, permission); request.then(() => this.requestHolders()).then(this.props.refresh); } - handleToggleProjectCreator (user, permission) { + handleToggleProjectCreator(user, permission) { const { template } = this.props; const hasPermission = user.permissions.includes(permission); - const request = hasPermission ? - api.removeProjectCreatorFromTemplate(template.id, permission) : - api.addProjectCreatorToTemplate(template.id, permission); + const request = hasPermission + ? api.removeProjectCreatorFromTemplate(template.id, permission) + : api.addProjectCreatorToTemplate(template.id, permission); request.then(() => this.requestHolders()).then(this.props.refresh); } - handleToggleGroup (group, permission) { + handleToggleGroup(group, permission) { const { template, organization } = this.props; const hasPermission = group.permissions.includes(permission); const data = { @@ -123,25 +119,25 @@ class Template extends React.Component { if (organization) { Object.assign(data, { organization: organization.key }); } - const request = hasPermission ? - api.revokeTemplatePermissionFromGroup(data) : - api.grantTemplatePermissionToGroup(data); + const request = hasPermission + ? api.revokeTemplatePermissionFromGroup(data) + : api.grantTemplatePermissionToGroup(data); request.then(() => this.requestHolders()).then(this.props.refresh); } - handleSearch (query) { + handleSearch(query) { this.props.updateStore({ query }); if (query.length === 0 || query.length > 2) { this.requestHoldersDebounced(query); } } - handleFilter (filter) { + handleFilter(filter) { this.props.updateStore({ filter }); this.requestHolders(); } - handleSelectPermission (selectedPermission) { + handleSelectPermission(selectedPermission) { const store = this.props.getStore(); if (selectedPermission === store.selectedPermission) { this.props.updateStore({ selectedPermission: null }); @@ -151,26 +147,23 @@ class Template extends React.Component { this.requestHolders(); } - shouldDisplayCreator (creatorPermissions) { + shouldDisplayCreator(creatorPermissions) { const store = this.props.getStore(); const CREATOR_NAME = translate('permission_templates.project_creators'); const isFiltered = store.filter !== 'all'; - const matchQuery = - !store.query || - CREATOR_NAME.toLocaleLowerCase().includes(store.query.toLowerCase()); + const matchQuery = !store.query || + CREATOR_NAME.toLocaleLowerCase().includes(store.query.toLowerCase()); - const matchPermission = - store.selectedPermission == null || - creatorPermissions.includes(store.selectedPermission); + const matchPermission = store.selectedPermission == null || + creatorPermissions.includes(store.selectedPermission); return !isFiltered && matchQuery && matchPermission; } - render () { - const title = translate('permission_templates.page') + ' - ' + - this.props.template.name; + render() { + const title = translate('permission_templates.page') + ' - ' + this.props.template.name; const permissions = PERMISSIONS_ORDER_FOR_PROJECT.map(p => ({ key: p, @@ -182,8 +175,8 @@ class Template extends React.Component { const allUsers = [...store.users]; const creatorPermissions = this.props.template.permissions - .filter(p => p.withProjectCreator) - .map(p => p.key); + .filter(p => p.withProjectCreator) + .map(p => p.key); if (this.shouldDisplayCreator(creatorPermissions)) { const creator = { @@ -196,39 +189,38 @@ class Template extends React.Component { } return ( - <div className="page page-limited"> - <Helmet - title={title} - titleTemplate="SonarQube - %s"/> - - <TemplateHeader - organization={this.props.organization} - template={this.props.template} - loading={store.loading} - refresh={this.props.refresh} - topQualifiers={this.props.topQualifiers}/> - - <TemplateDetails - organization={this.props.organization} - template={this.props.template}/> - - <HoldersList - permissions={permissions} - selectedPermission={store.selectedPermission} - users={allUsers} - groups={store.groups} - onSelectPermission={this.handleSelectPermission} - onToggleUser={this.handleToggleUser} - onToggleGroup={this.handleToggleGroup}> - - <SearchForm - query={store.query} - filter={store.filter} - onSearch={this.handleSearch} - onFilter={this.handleFilter}/> - - </HoldersList> - </div> + <div className="page page-limited"> + <Helmet title={title} titleTemplate="SonarQube - %s" /> + + <TemplateHeader + organization={this.props.organization} + template={this.props.template} + loading={store.loading} + refresh={this.props.refresh} + topQualifiers={this.props.topQualifiers} + /> + + <TemplateDetails organization={this.props.organization} template={this.props.template} /> + + <HoldersList + permissions={permissions} + selectedPermission={store.selectedPermission} + users={allUsers} + groups={store.groups} + onSelectPermission={this.handleSelectPermission} + onToggleUser={this.handleToggleUser} + onToggleGroup={this.handleToggleGroup} + > + + <SearchForm + query={store.query} + filter={store.filter} + onSearch={this.handleSearch} + onFilter={this.handleFilter} + /> + + </HoldersList> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateDetails.js b/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateDetails.js index ed4d3b467ad..a5cc6f61e5c 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateDetails.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateDetails.js @@ -26,31 +26,26 @@ export default class TemplateDetails extends React.Component { template: React.PropTypes.object.isRequired }; - render () { + render() { const { template } = this.props; return ( - <div className="big-spacer-bottom"> - {template.defaultFor.length > 0 && ( - <div className="spacer-top js-defaults"> - <Defaults - permissionTemplate={template} - organization={this.props.organization}/> - </div> - )} + <div className="big-spacer-bottom"> + {template.defaultFor.length > 0 && + <div className="spacer-top js-defaults"> + <Defaults permissionTemplate={template} organization={this.props.organization} /> + </div>} - {!!template.description && ( - <div className="spacer-top js-description"> - {template.description} - </div> - )} + {!!template.description && + <div className="spacer-top js-description"> + {template.description} + </div>} - {!!template.projectKeyPattern && ( - <div className="spacer-top js-project-key-pattern"> - Project Key Pattern: <code>{template.projectKeyPattern}</code> - </div> - )} - </div> + {!!template.projectKeyPattern && + <div className="spacer-top js-project-key-pattern"> + Project Key Pattern: <code>{template.projectKeyPattern}</code> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateHeader.js b/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateHeader.js index 04110a66ec4..8a2d07fb13d 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateHeader.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/TemplateHeader.js @@ -31,38 +31,37 @@ export default class TemplateHeader extends React.Component { topQualifiers: React.PropTypes.array.isRequired }; - render () { + render() { const { template, organization } = this.props; - const pathname = organization ? - `/organizations/${organization.key}/permission_templates` : - '/permission_templates'; + const pathname = organization + ? `/organizations/${organization.key}/permission_templates` + : '/permission_templates'; return ( - <header id="project-permissions-header" className="page-header"> - <div className="note spacer-bottom"> - <Link to={pathname} className="text-muted"> - {translate('permission_templates.page')} - </Link> - </div> + <header id="project-permissions-header" className="page-header"> + <div className="note spacer-bottom"> + <Link to={pathname} className="text-muted"> + {translate('permission_templates.page')} + </Link> + </div> - <h1 className="page-title"> - {template.name} - </h1> + <h1 className="page-title"> + {template.name} + </h1> - {this.props.loading && ( - <i className="spinner"/> - )} + {this.props.loading && <i className="spinner" />} - <div className="pull-right"> - <ActionsCell - organization={this.props.organization} - permissionTemplate={this.props.template} - topQualifiers={this.props.topQualifiers} - refresh={this.props.refresh} - fromDetails={true}/> - </div> - </header> + <div className="pull-right"> + <ActionsCell + organization={this.props.organization} + permissionTemplate={this.props.template} + topQualifiers={this.props.topQualifiers} + refresh={this.props.refresh} + fromDetails={true} + /> + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/ActionsCell-test.js b/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/ActionsCell-test.js index c2e83d5c093..3bf2dbe380e 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/ActionsCell-test.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/ActionsCell-test.js @@ -28,13 +28,14 @@ const SAMPLE = { defaultFor: [] }; -function renderActionsCell (props) { +function renderActionsCell(props) { return shallow( <ActionsCell - permissionTemplate={SAMPLE} - topQualifiers={['TRK', 'VW']} - refresh={() => true} - {...props}/> + permissionTemplate={SAMPLE} + topQualifiers={['TRK', 'VW']} + refresh={() => true} + {...props} + /> ); } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/Defaults-test.js b/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/Defaults-test.js index 9ea49a681f8..581cfbd6ee3 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/Defaults-test.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/Defaults-test.js @@ -29,26 +29,26 @@ const SAMPLE = { it('should render one qualifier', () => { const sample = { ...SAMPLE, defaultFor: ['DEV'] }; - const output = shallow(<Defaults permissionTemplate={sample}/>); + const output = shallow(<Defaults permissionTemplate={sample} />); expect(output).toMatchSnapshot(); }); it('should render several qualifiers', () => { const sample = { ...SAMPLE, defaultFor: ['TRK', 'VW'] }; - const output = shallow(<Defaults permissionTemplate={sample}/>); + const output = shallow(<Defaults permissionTemplate={sample} />); expect(output).toMatchSnapshot(); }); it('should render several qualifiers for default organization', () => { const sample = { ...SAMPLE, defaultFor: ['TRK', 'VW'] }; const organization = { isDefault: true }; - const output = shallow(<Defaults permissionTemplate={sample} organization={organization}/>); + const output = shallow(<Defaults permissionTemplate={sample} organization={organization} />); expect(output).toMatchSnapshot(); }); it('should render only projects for custom organization', () => { const sample = { ...SAMPLE, defaultFor: ['TRK', 'VW'] }; const organization = { isDefault: false }; - const output = shallow(<Defaults permissionTemplate={sample} organization={organization}/>); + const output = shallow(<Defaults permissionTemplate={sample} organization={organization} />); expect(output).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/routes.js b/server/sonar-web/src/main/js/apps/permission-templates/routes.js index b91954d5f7f..497a7817a42 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/routes.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/routes.js @@ -22,6 +22,4 @@ import { IndexRoute } from 'react-router'; import AppContainer from './components/AppContainer'; import forSingleOrganization from '../organizations/forSingleOrganization'; -export default ( - <IndexRoute component={forSingleOrganization(AppContainer)}/> -); +export default <IndexRoute component={forSingleOrganization(AppContainer)} />; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/utils.js b/server/sonar-web/src/main/js/apps/permission-templates/utils.js index 99d1b2d3bc9..3b634820b5b 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/utils.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/utils.js @@ -26,7 +26,7 @@ export const PERMISSIONS_ORDER = ['user', 'codeviewer', 'issueadmin', 'admin', ' * @param {Array} permissions * @returns {Array} */ -export function sortPermissions (permissions) { +export function sortPermissions(permissions) { return sortBy(permissions, p => PERMISSIONS_ORDER.indexOf(p.key)); } @@ -36,12 +36,14 @@ export function sortPermissions (permissions) { * @param {Array} basePermissions * @returns {Array} */ -export function mergePermissionsToTemplates (permissionTemplates, basePermissions) { +export function mergePermissionsToTemplates(permissionTemplates, basePermissions) { return permissionTemplates.map(permissionTemplate => { // it's important to keep the order of the permission template's permissions // the same as the order of base permissions const permissions = basePermissions.map(basePermission => { - const projectPermission = permissionTemplate.permissions.find(p => p.key === basePermission.key); + const projectPermission = permissionTemplate.permissions.find( + p => p.key === basePermission.key + ); return { usersCount: 0, groupsCount: 0, ...basePermission, ...projectPermission }; }); @@ -55,7 +57,7 @@ export function mergePermissionsToTemplates (permissionTemplates, basePermission * @param {Array} defaultTemplates * @returns {Array} */ -export function mergeDefaultsToTemplates (permissionTemplates, defaultTemplates = []) { +export function mergeDefaultsToTemplates(permissionTemplates, defaultTemplates = []) { return permissionTemplates.map(permissionTemplate => { const defaultFor = []; diff --git a/server/sonar-web/src/main/js/apps/permission-templates/views/CreateView.js b/server/sonar-web/src/main/js/apps/permission-templates/views/CreateView.js index f46d91ca715..70e80add995 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/views/CreateView.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/views/CreateView.js @@ -22,7 +22,7 @@ import { createPermissionTemplate } from '../../../api/permissions'; import { parseError } from '../../code/utils'; export default FormView.extend({ - sendRequest () { + sendRequest() { this.disableForm(); const data = { name: this.$('#permission-template-name').val(), diff --git a/server/sonar-web/src/main/js/apps/permission-templates/views/DeleteView.js b/server/sonar-web/src/main/js/apps/permission-templates/views/DeleteView.js index b1a7f1f30da..4304ab0b0ee 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/views/DeleteView.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/views/DeleteView.js @@ -25,12 +25,12 @@ import { parseError } from '../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { deletePermissionTemplate({ templateId: this.model.id }).then( () => { this.trigger('done'); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/views/FormView.js b/server/sonar-web/src/main/js/apps/permission-templates/views/FormView.js index 726daa185ab..1bf56cf1e01 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/views/FormView.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/views/FormView.js @@ -23,7 +23,7 @@ import Template from '../templates/permission-templates-form.hbs'; export default ModalForm.extend({ template: Template, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); this.$('#create-custom-measure-metric').select2({ @@ -32,12 +32,12 @@ export default ModalForm.extend({ }); }, - onDestroy () { + onDestroy() { ModalForm.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/views/GroupsView.js b/server/sonar-web/src/main/js/apps/permission-templates/views/GroupsView.js index 71f72c59d27..e90ec39e5d7 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/views/GroupsView.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/views/GroupsView.js @@ -21,22 +21,22 @@ import Modal from '../../../components/common/modals'; import Template from '../templates/permission-templates-groups.hbs'; import '../../../components/SelectList'; -function getSearchUrl (permission, permissionTemplate) { +function getSearchUrl(permission, permissionTemplate) { return window.baseUrl + - `/api/permissions/template_groups?ps=100&permission=${permission.key}&templateId=${permissionTemplate.id}`; + `/api/permissions/template_groups?ps=100&permission=${permission.key}&templateId=${permissionTemplate.id}`; } export default Modal.extend({ template: Template, - onRender () { + onRender() { Modal.prototype.onRender.apply(this, arguments); new window.SelectList({ el: this.$('#permission-templates-groups'), width: '100%', readOnly: false, focusSearch: false, - format (item) { + format(item) { return item.name; }, queryParam: 'q', @@ -49,21 +49,21 @@ export default Modal.extend({ }, selectParameter: 'groupName', selectParameterValue: 'name', - parse (r) { + parse(r) { this.more = false; return r.groups; } }); }, - onDestroy () { + onDestroy() { if (this.options.refresh) { this.options.refresh(); } Modal.prototype.onDestroy.apply(this, arguments); }, - serializeData () { + serializeData() { return { ...Modal.prototype.serializeData.apply(this, arguments), permissionName: this.options.permission.name, diff --git a/server/sonar-web/src/main/js/apps/permission-templates/views/UpdateView.js b/server/sonar-web/src/main/js/apps/permission-templates/views/UpdateView.js index 094feb677d8..886cd53934b 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/views/UpdateView.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/views/UpdateView.js @@ -22,7 +22,7 @@ import { updatePermissionTemplate } from '../../../api/permissions'; import { parseError } from '../../code/utils'; export default FormView.extend({ - sendRequest () { + sendRequest() { this.disableForm(); updatePermissionTemplate({ id: this.model.id, diff --git a/server/sonar-web/src/main/js/apps/permission-templates/views/UsersView.js b/server/sonar-web/src/main/js/apps/permission-templates/views/UsersView.js index ee25cb2fa23..24674f744a7 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/views/UsersView.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/views/UsersView.js @@ -21,46 +21,50 @@ import Modal from '../../../components/common/modals'; import Template from '../templates/permission-templates-users.hbs'; import '../../../components/SelectList'; import { - addProjectCreatorToTemplate, - removeProjectCreatorFromTemplate + addProjectCreatorToTemplate, + removeProjectCreatorFromTemplate } from '../../../api/permissions'; export default Modal.extend({ template: Template, - events () { + events() { return { ...Modal.prototype.events.apply(this, arguments), 'change #grant-to-project-creators': 'onCheckboxChange' }; }, - onCheckboxChange () { + onCheckboxChange() { const checked = this.$('#grant-to-project-creators').is(':checked'); if (checked) { addProjectCreatorToTemplate( this.options.permissionTemplate.name, - this.options.permission.key); + this.options.permission.key + ); } else { removeProjectCreatorFromTemplate( this.options.permissionTemplate.name, - this.options.permission.key); + this.options.permission.key + ); } }, - onRender () { + onRender() { Modal.prototype.onRender.apply(this, arguments); - this.$('[data-toggle="tooltip"]') - .tooltip({ container: 'body', placement: 'bottom' }); - const searchUrl = window.baseUrl + '/api/permissions/template_users?ps=100&permission=' + - this.options.permission.key + '&templateId=' + this.options.permissionTemplate.id; + this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); + const searchUrl = window.baseUrl + + '/api/permissions/template_users?ps=100&permission=' + + this.options.permission.key + + '&templateId=' + + this.options.permissionTemplate.id; new window.SelectList({ searchUrl, el: this.$('#permission-templates-users'), width: '100%', readOnly: false, focusSearch: false, - format (item) { + format(item) { return `${item.name}<br><span class="note">${item.login}</span>`; }, queryParam: 'q', @@ -72,14 +76,14 @@ export default Modal.extend({ }, selectParameter: 'login', selectParameterValue: 'login', - parse (r) { + parse(r) { this.more = false; return r.users; } }); }, - onDestroy () { + onDestroy() { if (this.options.refresh) { this.options.refresh(); } @@ -87,7 +91,7 @@ export default Modal.extend({ Modal.prototype.onDestroy.apply(this, arguments); }, - serializeData () { + serializeData() { return { ...Modal.prototype.serializeData.apply(this, arguments), permission: this.options.permission, diff --git a/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersList.js b/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersList.js index d94862233a2..1748d6dda1e 100644 --- a/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersList.js +++ b/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersList.js @@ -41,26 +41,16 @@ import { getPermissionsAppSelectedPermission } from '../../../../store/rootReducer'; -const PERMISSIONS_ORDER = [ - 'admin', - 'profileadmin', - 'gateadmin', - 'scan', - 'provisioning' -]; - -const PERMISSIONS_FOR_CUSTOM_ORG = [ - 'admin', - 'scan', - 'provisioning' -]; +const PERMISSIONS_ORDER = ['admin', 'profileadmin', 'gateadmin', 'scan', 'provisioning']; + +const PERMISSIONS_FOR_CUSTOM_ORG = ['admin', 'scan', 'provisioning']; class AllHoldersList extends React.Component { - componentDidMount () { + componentDidMount() { this.props.loadHolders(); } - handleToggleUser (user, permission) { + handleToggleUser(user, permission) { const hasPermission = user.permissions.includes(permission); if (hasPermission) { @@ -70,7 +60,7 @@ class AllHoldersList extends React.Component { } } - handleToggleGroup (group, permission) { + handleToggleGroup(group, permission) { const hasPermission = group.permissions.includes(permission); if (hasPermission) { @@ -80,10 +70,10 @@ class AllHoldersList extends React.Component { } } - render () { - const order = (this.props.organization && !this.props.organization.isDefault) ? - PERMISSIONS_FOR_CUSTOM_ORG : - PERMISSIONS_ORDER; + render() { + const order = this.props.organization && !this.props.organization.isDefault + ? PERMISSIONS_FOR_CUSTOM_ORG + : PERMISSIONS_ORDER; const l10nPrefix = this.props.organization ? 'organizations_permissions' : 'global_permissions'; @@ -94,22 +84,24 @@ class AllHoldersList extends React.Component { })); return ( - <HoldersList - permissions={permissions} - selectedPermission={this.props.selectedPermission} - users={this.props.users} - groups={this.props.groups} - onSelectPermission={this.props.onSelectPermission} - onToggleUser={this.handleToggleUser.bind(this)} - onToggleGroup={this.handleToggleGroup.bind(this)}> - - <SearchForm - query={this.props.query} - filter={this.props.filter} - onSearch={this.props.onSearch} - onFilter={this.props.onFilter}/> - - </HoldersList> + <HoldersList + permissions={permissions} + selectedPermission={this.props.selectedPermission} + users={this.props.users} + groups={this.props.groups} + onSelectPermission={this.props.onSelectPermission} + onToggleUser={this.handleToggleUser.bind(this)} + onToggleGroup={this.handleToggleGroup.bind(this)} + > + + <SearchForm + query={this.props.query} + filter={this.props.filter} + onSearch={this.props.onSearch} + onFilter={this.props.onFilter} + /> + + </HoldersList> ); } } @@ -134,17 +126,14 @@ const mapDispatchToProps = (dispatch, ownProps: OwnProps) => { onFilter: filter => dispatch(updateFilter(filter, organizationKey)), onSelectPermission: permission => dispatch(selectPermission(permission, organizationKey)), grantPermissionToUser: (login, permission) => - dispatch(grantToUser(login, permission, organizationKey)), + dispatch(grantToUser(login, permission, organizationKey)), revokePermissionFromUser: (login, permission) => - dispatch(revokeFromUser(login, permission, organizationKey)), + dispatch(revokeFromUser(login, permission, organizationKey)), grantPermissionToGroup: (groupName, permission) => - dispatch(grantToGroup(groupName, permission, organizationKey)), + dispatch(grantToGroup(groupName, permission, organizationKey)), revokePermissionFromGroup: (groupName, permission) => - dispatch(revokeFromGroup(groupName, permission, organizationKey)) + dispatch(revokeFromGroup(groupName, permission, organizationKey)) }; }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(AllHoldersList); +export default connect(mapStateToProps, mapDispatchToProps)(AllHoldersList); diff --git a/server/sonar-web/src/main/js/apps/permissions/global/components/App.js b/server/sonar-web/src/main/js/apps/permissions/global/components/App.js index 265d5029adf..f0ee0912120 100644 --- a/server/sonar-web/src/main/js/apps/permissions/global/components/App.js +++ b/server/sonar-web/src/main/js/apps/permissions/global/components/App.js @@ -31,13 +31,13 @@ export default class App extends React.Component { organization?: {} }; - render () { + render() { return ( - <div className="page page-limited"> - <PageHeader organization={this.props.organization}/> - <PageError/> - <AllHoldersList organization={this.props.organization}/> - </div> + <div className="page page-limited"> + <PageHeader organization={this.props.organization} /> + <PageError /> + <AllHoldersList organization={this.props.organization} /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/permissions/global/components/PageHeader.js b/server/sonar-web/src/main/js/apps/permissions/global/components/PageHeader.js index 7d58a7b12f6..4475144a332 100644 --- a/server/sonar-web/src/main/js/apps/permissions/global/components/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/permissions/global/components/PageHeader.js @@ -32,25 +32,23 @@ class PageHeader extends React.Component { loading: false }; - render () { - const title = this.props.organization ? - translate('permissions.page') : - translate('global_permissions.page'); + render() { + const title = this.props.organization + ? translate('permissions.page') + : translate('global_permissions.page'); - const description = this.props.organization ? - translate('organization_permissions.page.description') : - translate('global_permissions.page.description'); + const description = this.props.organization + ? translate('organization_permissions.page.description') + : translate('global_permissions.page.description'); return ( - <header className="page-header"> - <h1 className="page-title">{title}</h1> + <header className="page-header"> + <h1 className="page-title">{title}</h1> - {this.props.loading && ( - <i className="spinner"/> - )} + {this.props.loading && <i className="spinner" />} - <div className="page-description">{description}</div> - </header> + <div className="page-description">{description}</div> + </header> ); } } @@ -59,6 +57,4 @@ const mapStateToProps = state => ({ loading: isPermissionsAppLoading(state) }); -export default connect( - mapStateToProps -)(PageHeader); +export default connect(mapStateToProps)(PageHeader); diff --git a/server/sonar-web/src/main/js/apps/permissions/global/store/actions.js b/server/sonar-web/src/main/js/apps/permissions/global/store/actions.js index f4e42e77f1c..64c80c2b924 100644 --- a/server/sonar-web/src/main/js/apps/permissions/global/store/actions.js +++ b/server/sonar-web/src/main/js/apps/permissions/global/store/actions.js @@ -41,102 +41,118 @@ import { type Dispatch = (Object) => void; type GetState = () => Object; -export const loadHolders = (organization?: string) => (dispatch: Dispatch, getState: GetState) => { - const query = getPermissionsAppQuery(getState()); - const filter = getPermissionsAppFilter(getState()); - const selectedPermission = getPermissionsAppSelectedPermission(getState()); +export const loadHolders = (organization?: string) => + (dispatch: Dispatch, getState: GetState) => { + const query = getPermissionsAppQuery(getState()); + const filter = getPermissionsAppFilter(getState()); + const selectedPermission = getPermissionsAppSelectedPermission(getState()); - dispatch({ type: REQUEST_HOLDERS, query }); + dispatch({ type: REQUEST_HOLDERS, query }); - const requests = []; + const requests = []; - if (filter !== 'groups') { - requests.push(api.getGlobalPermissionsUsers(query, selectedPermission, organization)); - } else { - requests.push(Promise.resolve([])); - } + if (filter !== 'groups') { + requests.push(api.getGlobalPermissionsUsers(query, selectedPermission, organization)); + } else { + requests.push(Promise.resolve([])); + } - if (filter !== 'users') { - requests.push(api.getGlobalPermissionsGroups(query, selectedPermission, organization)); - } else { - requests.push(Promise.resolve([])); - } + if (filter !== 'users') { + requests.push(api.getGlobalPermissionsGroups(query, selectedPermission, organization)); + } else { + requests.push(Promise.resolve([])); + } - return Promise.all(requests).then(responses => ( - dispatch({ - type: RECEIVE_HOLDERS_SUCCESS, - users: responses[0], - groups: responses[1], - query - }) - )).catch(e => { - return parseError(e).then(message => dispatch(raiseError(message))); - }); -}; + return Promise.all(requests) + .then(responses => + dispatch({ + type: RECEIVE_HOLDERS_SUCCESS, + users: responses[0], + groups: responses[1], + query + })) + .catch(e => { + return parseError(e).then(message => dispatch(raiseError(message))); + }); + }; -export const updateQuery = (query: string = '', organization?: string) => (dispatch: Dispatch) => { - dispatch({ type: UPDATE_QUERY, query }); - if (query.length === 0 || query.length > 2) { - dispatch(loadHolders(organization)); - } -}; +export const updateQuery = (query: string = '', organization?: string) => + (dispatch: Dispatch) => { + dispatch({ type: UPDATE_QUERY, query }); + if (query.length === 0 || query.length > 2) { + dispatch(loadHolders(organization)); + } + }; -export const updateFilter = (filter: string, organization?: string) => (dispatch: Dispatch) => { - dispatch({ type: UPDATE_FILTER, filter }); - dispatch(loadHolders(organization)); -}; +export const updateFilter = (filter: string, organization?: string) => + (dispatch: Dispatch) => { + dispatch({ type: UPDATE_FILTER, filter }); + dispatch(loadHolders(organization)); + }; export const selectPermission = (permission: string, organization?: string) => - (dispatch: Dispatch, getState: GetState) => { - const selectedPermission = getPermissionsAppSelectedPermission(getState()); - if (selectedPermission !== permission) { - dispatch({ type: SELECT_PERMISSION, permission }); - } else { - dispatch({ type: SELECT_PERMISSION, permission: null }); - } - dispatch(loadHolders(organization)); - }; + (dispatch: Dispatch, getState: GetState) => { + const selectedPermission = getPermissionsAppSelectedPermission(getState()); + if (selectedPermission !== permission) { + dispatch({ type: SELECT_PERMISSION, permission }); + } else { + dispatch({ type: SELECT_PERMISSION, permission: null }); + } + dispatch(loadHolders(organization)); + }; export const grantToUser = (login: string, permission: string, organization?: string) => - (dispatch: Dispatch) => { - api.grantPermissionToUser(null, login, permission, organization).then(() => { + (dispatch: Dispatch) => { + api + .grantPermissionToUser(null, login, permission, organization) + .then(() => { dispatch({ type: GRANT_PERMISSION_TO_USER, login, permission }); - }).catch(e => { + }) + .catch(e => { return parseError(e).then(message => dispatch(raiseError(message))); }); - }; + }; export const revokeFromUser = (login: string, permission: string, organization?: string) => - (dispatch: Dispatch) => { - api.revokePermissionFromUser(null, login, permission, organization).then(() => { + (dispatch: Dispatch) => { + api + .revokePermissionFromUser(null, login, permission, organization) + .then(() => { dispatch({ type: REVOKE_PERMISSION_TO_USER, login, permission }); - }).catch(e => { + }) + .catch(e => { return parseError(e).then(message => dispatch(raiseError(message))); }); - }; + }; export const grantToGroup = (groupName: string, permission: string, organization?: string) => - (dispatch: Dispatch) => { - api.grantPermissionToGroup(null, groupName, permission, organization).then(() => { + (dispatch: Dispatch) => { + api + .grantPermissionToGroup(null, groupName, permission, organization) + .then(() => { dispatch({ type: GRANT_PERMISSION_TO_GROUP, groupName, permission }); - }).catch(e => { + }) + .catch(e => { return parseError(e).then(message => dispatch(raiseError(message))); }); - }; + }; export const revokeFromGroup = (groupName: string, permission: string, organization?: string) => - (dispatch: Dispatch) => { - api.revokePermissionFromGroup(null, groupName, permission, organization).then(() => { + (dispatch: Dispatch) => { + api + .revokePermissionFromGroup(null, groupName, permission, organization) + .then(() => { dispatch({ type: REVOKE_PERMISSION_FROM_GROUP, groupName, permission }); - }).catch(e => { + }) + .catch(e => { return parseError(e).then(message => dispatch(raiseError(message))); }); - }; + }; diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/AllHoldersList.js b/server/sonar-web/src/main/js/apps/permissions/project/components/AllHoldersList.js index 507cd76849a..3e1d4dafb61 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/components/AllHoldersList.js +++ b/server/sonar-web/src/main/js/apps/permissions/project/components/AllHoldersList.js @@ -47,59 +47,43 @@ class AllHoldersList extends React.Component { project: React.PropTypes.object.isRequired }; - componentDidMount () { + componentDidMount() { this.props.loadHolders(this.props.project.key); } - handleSearch (query) { + handleSearch(query) { this.props.onSearch(this.props.project.key, query); } - handleFilter (filter) { + handleFilter(filter) { this.props.onFilter(this.props.project.key, filter); } - handleToggleUser (user, permission) { + handleToggleUser(user, permission) { const hasPermission = user.permissions.includes(permission); if (hasPermission) { - this.props.revokePermissionFromUser( - this.props.project.key, - user.login, - permission - ); + this.props.revokePermissionFromUser(this.props.project.key, user.login, permission); } else { - this.props.grantPermissionToUser( - this.props.project.key, - user.login, - permission - ); + this.props.grantPermissionToUser(this.props.project.key, user.login, permission); } } - handleToggleGroup (group, permission) { + handleToggleGroup(group, permission) { const hasPermission = group.permissions.includes(permission); if (hasPermission) { - this.props.revokePermissionFromGroup( - this.props.project.key, - group.name, - permission - ); + this.props.revokePermissionFromGroup(this.props.project.key, group.name, permission); } else { - this.props.grantPermissionToGroup( - this.props.project.key, - group.name, - permission - ); + this.props.grantPermissionToGroup(this.props.project.key, group.name, permission); } } - handleSelectPermission (permission) { + handleSelectPermission(permission) { this.props.onSelectPermission(this.props.project.key, permission); } - render () { + render() { const order = PERMISSIONS_ORDER_BY_QUALIFIER[this.props.project.qualifier]; const permissions = order.map(p => ({ key: p, @@ -108,22 +92,24 @@ class AllHoldersList extends React.Component { })); return ( - <HoldersList - permissions={permissions} - selectedPermission={this.props.selectedPermission} - users={this.props.users} - groups={this.props.groups} - onSelectPermission={this.handleSelectPermission.bind(this)} - onToggleUser={this.handleToggleUser.bind(this)} - onToggleGroup={this.handleToggleGroup.bind(this)}> - - <SearchForm - query={this.props.query} - filter={this.props.filter} - onSearch={this.handleSearch.bind(this)} - onFilter={this.handleFilter.bind(this)}/> - - </HoldersList> + <HoldersList + permissions={permissions} + selectedPermission={this.props.selectedPermission} + users={this.props.users} + groups={this.props.groups} + onSelectPermission={this.handleSelectPermission.bind(this)} + onToggleUser={this.handleToggleUser.bind(this)} + onToggleGroup={this.handleToggleGroup.bind(this)} + > + + <SearchForm + query={this.props.query} + filter={this.props.filter} + onSearch={this.handleSearch.bind(this)} + onFilter={this.handleFilter.bind(this)} + /> + + </HoldersList> ); } } @@ -144,21 +130,20 @@ type OwnProps = { const mapDispatchToProps = (dispatch, ownProps: OwnProps) => ({ loadHolders: projectKey => dispatch(loadHolders(projectKey, ownProps.project.organization)), - onSearch: (projectKey, query) => dispatch(updateQuery(projectKey, query, ownProps.project.organization)), - onFilter: (projectKey, filter) => dispatch(updateFilter(projectKey, filter, ownProps.project.organization)), + onSearch: (projectKey, query) => + dispatch(updateQuery(projectKey, query, ownProps.project.organization)), + onFilter: (projectKey, filter) => + dispatch(updateFilter(projectKey, filter, ownProps.project.organization)), onSelectPermission: (projectKey, permission) => - dispatch(selectPermission(projectKey, permission, ownProps.project.organization)), + dispatch(selectPermission(projectKey, permission, ownProps.project.organization)), grantPermissionToUser: (projectKey, login, permission) => - dispatch(grantToUser(projectKey, login, permission, ownProps.project.organization)), + dispatch(grantToUser(projectKey, login, permission, ownProps.project.organization)), revokePermissionFromUser: (projectKey, login, permission) => - dispatch(revokeFromUser(projectKey, login, permission, ownProps.project.organization)), + dispatch(revokeFromUser(projectKey, login, permission, ownProps.project.organization)), grantPermissionToGroup: (projectKey, groupName, permission) => - dispatch(grantToGroup(projectKey, groupName, permission, ownProps.project.organization)), + dispatch(grantToGroup(projectKey, groupName, permission, ownProps.project.organization)), revokePermissionFromGroup: (projectKey, groupName, permission) => - dispatch(revokeFromGroup(projectKey, groupName, permission, ownProps.project.organization)) + dispatch(revokeFromGroup(projectKey, groupName, permission, ownProps.project.organization)) }); -export default connect( - mapStateToProps, - mapDispatchToProps -)(AllHoldersList); +export default connect(mapStateToProps, mapDispatchToProps)(AllHoldersList); diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/App.js b/server/sonar-web/src/main/js/apps/permissions/project/components/App.js index 86836c68996..e43ab53f8b1 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/components/App.js +++ b/server/sonar-web/src/main/js/apps/permissions/project/components/App.js @@ -32,17 +32,17 @@ class App extends React.Component { component: React.PropTypes.object }; - render () { + render() { if (!this.props.component) { return null; } return ( - <div className="page page-limited"> - <PageHeader project={this.props.component} currentUser={this.props.currentUser}/> - <PageError/> - <AllHoldersList project={this.props.component}/> - </div> + <div className="page page-limited"> + <PageHeader project={this.props.component} currentUser={this.props.currentUser} /> + <PageError /> + <AllHoldersList project={this.props.component} /> + </div> ); } } @@ -53,4 +53,3 @@ const mapStateToProps = (state, ownProps) => ({ }); export default connect(mapStateToProps)(App); - diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js b/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js index 74816c0fef9..fd3882dbb36 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js @@ -35,46 +35,44 @@ class PageHeader extends React.Component { loading: false }; - componentWillMount () { + componentWillMount() { this.handleApplyTemplate = this.handleApplyTemplate.bind(this); } - handleApplyTemplate (e) { + handleApplyTemplate(e) { e.preventDefault(); e.target.blur(); const { project, loadHolders } = this.props; const organization = project.organization ? { key: project.organization } : null; new ApplyTemplateView({ project, organization }) - .on('done', () => loadHolders(project.key)) - .render(); + .on('done', () => loadHolders(project.key)) + .render(); } - render () { + render() { const configuration = this.props.project.configuration; - const canApplyPermissionTemplate = configuration != null && configuration.canApplyPermissionTemplate; + const canApplyPermissionTemplate = configuration != null && + configuration.canApplyPermissionTemplate; return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('permissions.page')} - </h1> + <header className="page-header"> + <h1 className="page-title"> + {translate('permissions.page')} + </h1> - {this.props.loading && ( - <i className="spinner"/> - )} + {this.props.loading && <i className="spinner" />} - {canApplyPermissionTemplate && ( - <div className="page-actions"> - <button className="js-apply-template" onClick={this.handleApplyTemplate}> - Apply Template - </button> - </div> - )} + {canApplyPermissionTemplate && + <div className="page-actions"> + <button className="js-apply-template" onClick={this.handleApplyTemplate}> + Apply Template + </button> + </div>} - <div className="page-description"> - {translate('roles.page.description2')} - </div> - </header> + <div className="page-description"> + {translate('roles.page.description2')} + </div> + </header> ); } } @@ -87,7 +85,4 @@ const mapDispatchToProps = (dispatch, ownProps) => ({ loadHolders: projectKey => dispatch(loadHolders(projectKey, ownProps.project.organization)) }); -export default connect( - mapStateToProps, - mapDispatchToProps -)(PageHeader); +export default connect(mapStateToProps, mapDispatchToProps)(PageHeader); diff --git a/server/sonar-web/src/main/js/apps/permissions/project/constants.js b/server/sonar-web/src/main/js/apps/permissions/project/constants.js index fc79b3bc605..7a92d73237d 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/constants.js +++ b/server/sonar-web/src/main/js/apps/permissions/project/constants.js @@ -17,27 +17,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export const PERMISSIONS_ORDER_FOR_PROJECT = [ - 'user', - 'codeviewer', - 'issueadmin', - 'admin', - 'scan' -]; +export const PERMISSIONS_ORDER_FOR_PROJECT = ['user', 'codeviewer', 'issueadmin', 'admin', 'scan']; -export const PERMISSIONS_ORDER_FOR_VIEW = [ - 'user', - 'admin' -]; +export const PERMISSIONS_ORDER_FOR_VIEW = ['user', 'admin']; -export const PERMISSIONS_ORDER_FOR_DEV = [ - 'user', - 'admin' -]; +export const PERMISSIONS_ORDER_FOR_DEV = ['user', 'admin']; export const PERMISSIONS_ORDER_BY_QUALIFIER = { - 'TRK': PERMISSIONS_ORDER_FOR_PROJECT, - 'VW': PERMISSIONS_ORDER_FOR_VIEW, - 'SVW': PERMISSIONS_ORDER_FOR_VIEW, - 'DEV': PERMISSIONS_ORDER_FOR_DEV + TRK: PERMISSIONS_ORDER_FOR_PROJECT, + VW: PERMISSIONS_ORDER_FOR_VIEW, + SVW: PERMISSIONS_ORDER_FOR_VIEW, + DEV: PERMISSIONS_ORDER_FOR_DEV }; diff --git a/server/sonar-web/src/main/js/apps/permissions/project/store/actions.js b/server/sonar-web/src/main/js/apps/permissions/project/store/actions.js index 020622b615d..4536851bfa7 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/store/actions.js +++ b/server/sonar-web/src/main/js/apps/permissions/project/store/actions.js @@ -42,112 +42,141 @@ type Dispatch = (Object) => void; type GetState = () => Object; export const loadHolders = (project: string, organization?: string) => - (dispatch: Dispatch, getState: GetState) => { - const query = getPermissionsAppQuery(getState()); - const filter = getPermissionsAppFilter(getState()); - const selectedPermission = getPermissionsAppSelectedPermission(getState()); + (dispatch: Dispatch, getState: GetState) => { + const query = getPermissionsAppQuery(getState()); + const filter = getPermissionsAppFilter(getState()); + const selectedPermission = getPermissionsAppSelectedPermission(getState()); - dispatch({ type: REQUEST_HOLDERS, query }); + dispatch({ type: REQUEST_HOLDERS, query }); - const requests = []; + const requests = []; - if (filter !== 'groups') { - requests.push(api.getPermissionsUsersForComponent(project, query, selectedPermission, organization)); - } else { - requests.push(Promise.resolve([])); - } + if (filter !== 'groups') { + requests.push( + api.getPermissionsUsersForComponent(project, query, selectedPermission, organization) + ); + } else { + requests.push(Promise.resolve([])); + } - if (filter !== 'users') { - requests.push(api.getPermissionsGroupsForComponent(project, query, selectedPermission, organization)); - } else { - requests.push(Promise.resolve([])); - } + if (filter !== 'users') { + requests.push( + api.getPermissionsGroupsForComponent(project, query, selectedPermission, organization) + ); + } else { + requests.push(Promise.resolve([])); + } - return Promise.all(requests).then(responses => ( - dispatch({ - type: RECEIVE_HOLDERS_SUCCESS, - users: responses[0], - groups: responses[1], - query - }) - )).catch(e => { + return Promise.all(requests) + .then(responses => + dispatch({ + type: RECEIVE_HOLDERS_SUCCESS, + users: responses[0], + groups: responses[1], + query + })) + .catch(e => { return parseError(e).then(message => dispatch(raiseError(message))); }); - }; + }; export const updateQuery = (project: string, query: string, organization?: string) => - (dispatch: Dispatch) => { - dispatch({ type: UPDATE_QUERY, query }); - if (query.length === 0 || query.length > 2) { - dispatch(loadHolders(project, organization)); - } - }; + (dispatch: Dispatch) => { + dispatch({ type: UPDATE_QUERY, query }); + if (query.length === 0 || query.length > 2) { + dispatch(loadHolders(project, organization)); + } + }; export const updateFilter = (project: string, filter: string, organization?: string) => - (dispatch: Dispatch) => { - dispatch({ type: UPDATE_FILTER, filter }); - dispatch(loadHolders(project, organization)); - }; + (dispatch: Dispatch) => { + dispatch({ type: UPDATE_FILTER, filter }); + dispatch(loadHolders(project, organization)); + }; export const selectPermission = (project: string, permission: string, organization?: string) => - (dispatch: Dispatch, getState: GetState) => { - const selectedPermission = getPermissionsAppSelectedPermission(getState()); - if (selectedPermission !== permission) { - dispatch({ type: SELECT_PERMISSION, permission }); - } else { - dispatch({ type: SELECT_PERMISSION, permission: null }); - } - dispatch(loadHolders(project, organization)); - }; + (dispatch: Dispatch, getState: GetState) => { + const selectedPermission = getPermissionsAppSelectedPermission(getState()); + if (selectedPermission !== permission) { + dispatch({ type: SELECT_PERMISSION, permission }); + } else { + dispatch({ type: SELECT_PERMISSION, permission: null }); + } + dispatch(loadHolders(project, organization)); + }; -export const grantToUser = (project: string, login: string, permission: string, organization?: string) => - (dispatch: Dispatch) => { - api.grantPermissionToUser(project, login, permission, organization).then(() => { +export const grantToUser = ( + project: string, + login: string, + permission: string, + organization?: string +) => + (dispatch: Dispatch) => { + api + .grantPermissionToUser(project, login, permission, organization) + .then(() => { dispatch({ type: GRANT_PERMISSION_TO_USER, login, permission }); - }).catch(e => { + }) + .catch(e => { return parseError(e).then(message => dispatch(raiseError(message))); }); - }; + }; -export const revokeFromUser = (project: string, login: string, permission: string, organization?: string) => - (dispatch: Dispatch) => { - api.revokePermissionFromUser(project, login, permission, organization).then(() => { +export const revokeFromUser = ( + project: string, + login: string, + permission: string, + organization?: string +) => + (dispatch: Dispatch) => { + api + .revokePermissionFromUser(project, login, permission, organization) + .then(() => { dispatch({ type: REVOKE_PERMISSION_TO_USER, login, permission }); - }).catch(e => { + }) + .catch(e => { return parseError(e).then(message => dispatch(raiseError(message))); }); - }; + }; export const grantToGroup = ( - project: string, - groupName: string, - permission: string, - organization?: string -) => (dispatch: Dispatch) => { - api.grantPermissionToGroup(project, groupName, permission, organization).then(() => { - dispatch({ - type: GRANT_PERMISSION_TO_GROUP, - groupName, - permission - }); - }).catch(e => { - return parseError(e).then(message => dispatch(raiseError(message))); - }); -}; + project: string, + groupName: string, + permission: string, + organization?: string +) => + (dispatch: Dispatch) => { + api + .grantPermissionToGroup(project, groupName, permission, organization) + .then(() => { + dispatch({ + type: GRANT_PERMISSION_TO_GROUP, + groupName, + permission + }); + }) + .catch(e => { + return parseError(e).then(message => dispatch(raiseError(message))); + }); + }; export const revokeFromGroup = ( - project: string, - groupName: string, - permission: string, - organization?: string -) => (dispatch: Dispatch) => { - api.revokePermissionFromGroup(project, groupName, permission, organization).then(() => { - dispatch({ - type: REVOKE_PERMISSION_FROM_GROUP, - groupName, - permission - }); - }).catch(e => { - return parseError(e).then(message => dispatch(raiseError(message))); - }); -}; + project: string, + groupName: string, + permission: string, + organization?: string +) => + (dispatch: Dispatch) => { + api + .revokePermissionFromGroup(project, groupName, permission, organization) + .then(() => { + dispatch({ + type: REVOKE_PERMISSION_FROM_GROUP, + groupName, + permission + }); + }) + .catch(e => { + return parseError(e).then(message => dispatch(raiseError(message))); + }); + }; diff --git a/server/sonar-web/src/main/js/apps/permissions/project/views/ApplyTemplateView.js b/server/sonar-web/src/main/js/apps/permissions/project/views/ApplyTemplateView.js index 1bd87b4e9b9..07e5da1482d 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/views/ApplyTemplateView.js +++ b/server/sonar-web/src/main/js/apps/permissions/project/views/ApplyTemplateView.js @@ -18,31 +18,28 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import ModalForm from '../../../../components/common/modal-form'; -import { - applyTemplateToProject, - getPermissionTemplates -} from '../../../../api/permissions'; +import { applyTemplateToProject, getPermissionTemplates } from '../../../../api/permissions'; import Template from '../templates/ApplyTemplateTemplate.hbs'; export default ModalForm.extend({ template: Template, - initialize () { + initialize() { this.loadPermissionTemplates(); this.done = false; }, - loadPermissionTemplates () { - const request = this.options.organization ? - getPermissionTemplates(this.options.organization.key) : - getPermissionTemplates(); + loadPermissionTemplates() { + const request = this.options.organization + ? getPermissionTemplates(this.options.organization.key) + : getPermissionTemplates(); return request.then(r => { this.permissionTemplates = r.permissionTemplates; this.render(); }); }, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('#project-permissions-template').select2({ width: '250px', @@ -50,7 +47,7 @@ export default ModalForm.extend({ }); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); const permissionTemplate = this.$('#project-permissions-template').val(); this.disableForm(); @@ -62,19 +59,21 @@ export default ModalForm.extend({ if (this.options.organization) { data.organization = this.options.organization.key; } - applyTemplateToProject(data).then(() => { - this.trigger('done'); - this.done = true; - this.render(); - }).catch(function (e) { - e.response.json().then(r => { - this.showErrors(r.errors, r.warnings); - this.enableForm(); + applyTemplateToProject(data) + .then(() => { + this.trigger('done'); + this.done = true; + this.render(); + }) + .catch(function(e) { + e.response.json().then(r => { + this.showErrors(r.errors, r.warnings); + this.enableForm(); + }); }); - }); }, - serializeData () { + serializeData() { return { permissionTemplates: this.permissionTemplates, project: this.options.project, diff --git a/server/sonar-web/src/main/js/apps/permissions/routes.js b/server/sonar-web/src/main/js/apps/permissions/routes.js index f68c9e392e9..388fffb75b6 100644 --- a/server/sonar-web/src/main/js/apps/permissions/routes.js +++ b/server/sonar-web/src/main/js/apps/permissions/routes.js @@ -24,9 +24,7 @@ import ProjectPermissionsApp from './project/components/App'; import forSingleOrganization from '../organizations/forSingleOrganization'; export const globalPermissionsRoutes = ( - <IndexRoute component={forSingleOrganization(GlobalPermissionsApp)}/> + <IndexRoute component={forSingleOrganization(GlobalPermissionsApp)} /> ); -export const projectPermissionsRoutes = ( - <IndexRoute component={ProjectPermissionsApp}/> -); +export const projectPermissionsRoutes = <IndexRoute component={ProjectPermissionsApp} />; diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupHolder.js b/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupHolder.js index 96888c119f5..9c8f5d24cb4 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupHolder.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupHolder.js @@ -30,54 +30,51 @@ export default class GroupHolder extends React.Component { onToggle: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleClick (permission, e) { + handleClick(permission, e) { e.preventDefault(); e.target.blur(); this.props.onToggle(this.props.group, permission); } - render () { + render() { const { selectedPermission } = this.props; const permissionCells = this.props.permissionsOrder.map(p => ( - <td key={p.key} - className="text-center text-middle" - style={{ backgroundColor: p.key === selectedPermission ? '#d9edf7' : 'transparent' }}> - <button - className="button-clean" - onClick={this.handleClick.bind(this, p.key)}> - {this.props.permissions.includes(p.key) ? ( - <i className="icon-checkbox icon-checkbox-checked"/> - ) : ( - <i className="icon-checkbox"/> - )} - </button> - </td> + <td + key={p.key} + className="text-center text-middle" + style={{ backgroundColor: p.key === selectedPermission ? '#d9edf7' : 'transparent' }} + > + <button className="button-clean" onClick={this.handleClick.bind(this, p.key)}> + {this.props.permissions.includes(p.key) + ? <i className="icon-checkbox icon-checkbox-checked" /> + : <i className="icon-checkbox" />} + </button> + </td> )); const { group } = this.props; return ( - <tr> - <td className="nowrap"> - <div className="display-inline-block text-middle big-spacer-right"> - <GroupIcon/> + <tr> + <td className="nowrap"> + <div className="display-inline-block text-middle big-spacer-right"> + <GroupIcon /> + </div> + <div className="display-inline-block text-middle"> + <div> + <strong>{group.name}</strong> </div> - <div className="display-inline-block text-middle"> - <div> - <strong>{group.name}</strong> - </div> - <div className="little-spacer-top" - style={{ whiteSpace: 'normal' }}> - {group.description} - </div> + <div className="little-spacer-top" style={{ whiteSpace: 'normal' }}> + {group.description} </div> - </td> - {permissionCells} - </tr> + </div> + </td> + {permissionCells} + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupIcon.js b/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupIcon.js index 0e9f8c3efe5..2e6a55fdba3 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupIcon.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/GroupIcon.js @@ -22,16 +22,14 @@ import React from 'react'; const GroupIcon = () => { /* eslint max-len: 0 */ return ( - <div style={{ padding: '4px 3px 0' }}> - <svg xmlns="http://www.w3.org/2000/svg" - width="30" - height="28" - viewBox="0 0 480 448"> - <path - fill="#aaa" - d="M148.25 224q-40.5 1.25-66.25 32H48.5Q28 256 14 245.875T0 216.25Q0 128 31 128q1.5 0 10.875 5.25t24.375 10.625T96 149.25q16.75 0 33.25-5.75Q128 152.75 128 160q0 34.75 20.25 64zM416 383.25q0 30-18.25 47.375T349.25 448h-218.5q-30.25 0-48.5-17.375T64 383.25q0-13.25.875-25.875t3.5-27.25T75 303t10.75-24.375 15.5-20.25T122.625 245t27.875-5q2.5 0 10.75 5.375t18.25 12 26.75 12T240 274.75t33.75-5.375 26.75-12 18.25-12T329.5 240q15.25 0 27.875 5t21.375 13.375 15.5 20.25T405 303t6.625 27.125 3.5 27.25.875 25.875zM160 64q0 26.5-18.75 45.25T96 128t-45.25-18.75T32 64t18.75-45.25T96 0t45.25 18.75T160 64zm176 96q0 39.75-28.125 67.875T240 256t-67.875-28.125T144 160t28.125-67.875T240 64t67.875 28.125T336 160zm144 56.25q0 19.5-14 29.625T431.5 256H398q-25.75-30.75-66.25-32Q352 194.75 352 160q0-7.25-1.25-16.5 16.5 5.75 33.25 5.75 14.75 0 29.75-5.375t24.375-10.625T449 128q31 0 31 88.25zM448 64q0 26.5-18.75 45.25T384 128t-45.25-18.75T320 64t18.75-45.25T384 0t45.25 18.75T448 64z"/> - </svg> - </div> + <div style={{ padding: '4px 3px 0' }}> + <svg xmlns="http://www.w3.org/2000/svg" width="30" height="28" viewBox="0 0 480 448"> + <path + fill="#aaa" + d="M148.25 224q-40.5 1.25-66.25 32H48.5Q28 256 14 245.875T0 216.25Q0 128 31 128q1.5 0 10.875 5.25t24.375 10.625T96 149.25q16.75 0 33.25-5.75Q128 152.75 128 160q0 34.75 20.25 64zM416 383.25q0 30-18.25 47.375T349.25 448h-218.5q-30.25 0-48.5-17.375T64 383.25q0-13.25.875-25.875t3.5-27.25T75 303t10.75-24.375 15.5-20.25T122.625 245t27.875-5q2.5 0 10.75 5.375t18.25 12 26.75 12T240 274.75t33.75-5.375 26.75-12 18.25-12T329.5 240q15.25 0 27.875 5t21.375 13.375 15.5 20.25T405 303t6.625 27.125 3.5 27.25.875 25.875zM160 64q0 26.5-18.75 45.25T96 128t-45.25-18.75T32 64t18.75-45.25T96 0t45.25 18.75T160 64zm176 96q0 39.75-28.125 67.875T240 256t-67.875-28.125T144 160t28.125-67.875T240 64t67.875 28.125T336 160zm144 56.25q0 19.5-14 29.625T431.5 256H398q-25.75-30.75-66.25-32Q352 194.75 352 160q0-7.25-1.25-16.5 16.5 5.75 33.25 5.75 14.75 0 29.75-5.375t24.375-10.625T449 128q31 0 31 88.25zM448 64q0 26.5-18.75 45.25T384 128t-45.25-18.75T320 64t18.75-45.25T384 0t45.25 18.75T448 64z" + /> + </svg> + </div> ); }; diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/HoldersList.js b/server/sonar-web/src/main/js/apps/permissions/shared/components/HoldersList.js index a54dfd784bd..783d54f0110 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/HoldersList.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/HoldersList.js @@ -34,89 +34,92 @@ export default class HoldersList extends React.Component { onToggleGroup: React.PropTypes.func.isRequired }; - handlePermissionClick (permission, e) { + handlePermissionClick(permission, e) { e.preventDefault(); e.target.blur(); this.props.onSelectPermission(permission); } - renderTableHeader () { + renderTableHeader() { const { selectedPermission } = this.props; const cells = this.props.permissions.map(p => ( - <th key={p.key} - className="permission-column text-center" - style={{ - backgroundColor: p.key === selectedPermission ? '#d9edf7' : - 'transparent' - }}> - <div className="permission-column-inner"> - <a href="#" - title={`Filter by "${p.name}" permission`} - data-toggle="tooltip" - onClick={this.handlePermissionClick.bind(this, p.key)}> - {p.name} - </a> - <i className="icon-help little-spacer-left" - title={p.description} - data-toggle="tooltip"/> - </div> - </th> + <th + key={p.key} + className="permission-column text-center" + style={{ + backgroundColor: p.key === selectedPermission ? '#d9edf7' : 'transparent' + }} + > + <div className="permission-column-inner"> + <a + href="#" + title={`Filter by "${p.name}" permission`} + data-toggle="tooltip" + onClick={this.handlePermissionClick.bind(this, p.key)} + > + {p.name} + </a> + <i className="icon-help little-spacer-left" title={p.description} data-toggle="tooltip" /> + </div> + </th> )); return ( - <thead> - <tr> - <td className="nowrap bordered-bottom"> - {this.props.children} - </td> - {cells} - </tr> - </thead> + <thead> + <tr> + <td className="nowrap bordered-bottom"> + {this.props.children} + </td> + {cells} + </tr> + </thead> ); } - renderEmpty () { + renderEmpty() { const columns = this.props.permissions.length + 1; return ( - <tr> - <td colSpan={columns}> - {translate('no_results_search')} - </td> - </tr> + <tr> + <td colSpan={columns}> + {translate('no_results_search')} + </td> + </tr> ); } - render () { + render() { const users = this.props.users.map(user => ( - <UserHolder - key={'user-' + user.login} - user={user} - permissions={user.permissions} - selectedPermission={this.props.selectedPermission} - permissionsOrder={this.props.permissions} - onToggle={this.props.onToggleUser}/> + <UserHolder + key={'user-' + user.login} + user={user} + permissions={user.permissions} + selectedPermission={this.props.selectedPermission} + permissionsOrder={this.props.permissions} + onToggle={this.props.onToggleUser} + /> )); const groups = this.props.groups.map(group => ( - <GroupHolder - key={'group-' + group.id} - group={group} - permissions={group.permissions} - selectedPermission={this.props.selectedPermission} - permissionsOrder={this.props.permissions} - onToggle={this.props.onToggleGroup}/> + <GroupHolder + key={'group-' + group.id} + group={group} + permissions={group.permissions} + selectedPermission={this.props.selectedPermission} + permissionsOrder={this.props.permissions} + onToggle={this.props.onToggleGroup} + /> )); return ( - <TooltipsContainer> - <table className="data zebra permissions-table"> - {this.renderTableHeader()} - <tbody> - {users.length === 0 && groups.length === 0 && this.renderEmpty()} - {users} - {groups} - </tbody> - </table> - </TooltipsContainer> + <TooltipsContainer> + <table className="data zebra permissions-table"> + {this.renderTableHeader()} + <tbody> + {users.length === 0 && groups.length === 0 && this.renderEmpty()} + {users} + {groups} + </tbody> + </table> + </TooltipsContainer> ); } } diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.js b/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.js index c7faca28cd3..18ce601f8c6 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.js @@ -26,7 +26,7 @@ class PageError extends React.Component { message: React.PropTypes.string }; - render () { + render() { const { message } = this.props; if (!message) { @@ -34,9 +34,9 @@ class PageError extends React.Component { } return ( - <div className="alert alert-danger"> - {message} - </div> + <div className="alert alert-danger"> + {message} + </div> ); } } @@ -45,6 +45,4 @@ const mapStateToProps = state => ({ message: getPermissionsAppError(state) }); -export default connect( - mapStateToProps -)(PageError); +export default connect(mapStateToProps)(PageError); diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/SearchForm.js b/server/sonar-web/src/main/js/apps/permissions/shared/components/SearchForm.js index bc8b02b0195..2f340624ce8 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/SearchForm.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/SearchForm.js @@ -29,26 +29,26 @@ export default class SearchForm extends React.Component { onFilter: React.PropTypes.func }; - componentWillMount () { + componentWillMount() { this.handleSubmit = this.handleSubmit.bind(this); this.handleSearch = this.handleSearch.bind(this); } - handleSubmit (e) { + handleSubmit(e) { e.preventDefault(); this.handleSearch(); } - handleSearch () { + handleSearch() { const { value } = this.refs.searchInput; this.props.onSearch(value); } - handleFilter (filter) { + handleFilter(filter) { this.props.onFilter(filter); } - render () { + render() { const { query, filter } = this.props; const filterOptions = [ @@ -58,38 +58,41 @@ export default class SearchForm extends React.Component { ]; return ( - <div> + <div> - <RadioToggle - value={filter} - options={filterOptions} - name="users-or-groups" - onCheck={this.handleFilter.bind(this)}/> + <RadioToggle + value={filter} + options={filterOptions} + name="users-or-groups" + onCheck={this.handleFilter.bind(this)} + /> - <form - className="search-box display-inline-block text-middle big-spacer-left" - onSubmit={this.handleSubmit}> - <button className="search-box-submit button-clean"> - <i className="icon-search"/> - </button> - <input - ref="searchInput" - value={query} - className="search-box-input" - style={{ width: 100 }} - type="search" - placeholder={translate('search_verb')} - onChange={this.handleSearch.bind(this)}/> - {query.length > 0 && query.length < 3 && ( - <div className="search-box-input-note tooltip bottom fade in"> - <div className="tooltip-inner"> - {translateWithParameters('select2.tooShort', 3)} - </div> - <div className="tooltip-arrow" style={{ left: 23 }}/> - </div> - )} - </form> - </div> + <form + className="search-box display-inline-block text-middle big-spacer-left" + onSubmit={this.handleSubmit} + > + <button className="search-box-submit button-clean"> + <i className="icon-search" /> + </button> + <input + ref="searchInput" + value={query} + className="search-box-input" + style={{ width: 100 }} + type="search" + placeholder={translate('search_verb')} + onChange={this.handleSearch.bind(this)} + /> + {query.length > 0 && + query.length < 3 && + <div className="search-box-input-note tooltip bottom fade in"> + <div className="tooltip-inner"> + {translateWithParameters('select2.tooShort', 3)} + </div> + <div className="tooltip-arrow" style={{ left: 23 }} /> + </div>} + </form> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/UserHolder.js b/server/sonar-web/src/main/js/apps/permissions/shared/components/UserHolder.js index db8ff4b6c5f..084830794b9 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/UserHolder.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/UserHolder.js @@ -31,32 +31,30 @@ export default class UserHolder extends React.Component { onToggle: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleClick (permission, e) { + handleClick(permission, e) { e.preventDefault(); e.target.blur(); this.props.onToggle(this.props.user, permission); } - render () { + render() { const { selectedPermission } = this.props; const permissionCells = this.props.permissionsOrder.map(p => ( - <td key={p.key} - className="text-center text-middle" - style={{ backgroundColor: p.key === selectedPermission ? '#d9edf7' : 'transparent' }}> - <button - className="button-clean" - onClick={this.handleClick.bind(this, p.key)}> - {this.props.permissions.includes(p.key) ? ( - <i className="icon-checkbox icon-checkbox-checked"/> - ) : ( - <i className="icon-checkbox"/> - )} - </button> - </td> + <td + key={p.key} + className="text-center text-middle" + style={{ backgroundColor: p.key === selectedPermission ? '#d9edf7' : 'transparent' }} + > + <button className="button-clean" onClick={this.handleClick.bind(this, p.key)}> + {this.props.permissions.includes(p.key) + ? <i className="icon-checkbox icon-checkbox-checked" /> + : <i className="icon-checkbox" />} + </button> + </td> )); const { user } = this.props; @@ -64,33 +62,24 @@ export default class UserHolder extends React.Component { const isCreator = user.login === '<creator>'; return ( - <tr> - <td className="nowrap"> - {!isCreator && ( - <Avatar - email={user.email} - size={36} - className="text-middle big-spacer-right"/> - )} - <div className="display-inline-block text-middle"> - <div> - <strong>{user.name}</strong> - {!isCreator && ( - <span className="note spacer-left">{user.login}</span> - )} - </div> - {!isCreator && ( - <div className="little-spacer-top">{user.email}</div> - )} - {isCreator && ( - <div className="little-spacer-top" style={{ whiteSpace: 'normal' }}> - {translate('permission_templates.project_creators.explanation')} - </div> - )} + <tr> + <td className="nowrap"> + {!isCreator && + <Avatar email={user.email} size={36} className="text-middle big-spacer-right" />} + <div className="display-inline-block text-middle"> + <div> + <strong>{user.name}</strong> + {!isCreator && <span className="note spacer-left">{user.login}</span>} </div> - </td> - {permissionCells} - </tr> + {!isCreator && <div className="little-spacer-top">{user.email}</div>} + {isCreator && + <div className="little-spacer-top" style={{ whiteSpace: 'normal' }}> + {translate('permission_templates.project_creators.explanation')} + </div>} + </div> + </td> + {permissionCells} + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js b/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js index c05b9ad5637..9708a736397 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/byName.js @@ -18,7 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import keyBy from 'lodash/keyBy'; -import { RECEIVE_HOLDERS_SUCCESS, GRANT_PERMISSION_TO_GROUP, REVOKE_PERMISSION_FROM_GROUP } from '../actions'; +import { + RECEIVE_HOLDERS_SUCCESS, + GRANT_PERMISSION_TO_GROUP, + REVOKE_PERMISSION_FROM_GROUP +} from '../actions'; const byName = (state = {}, action = {}) => { if (action.type === RECEIVE_HOLDERS_SUCCESS) { @@ -30,8 +34,7 @@ const byName = (state = {}, action = {}) => { return { ...state, [action.groupName]: newGroup }; } else if (action.type === REVOKE_PERMISSION_FROM_GROUP) { const newGroup = { ...state[action.groupName] }; - newGroup.permissions = newGroup.permissions - .filter(p => p !== action.permission); + newGroup.permissions = newGroup.permissions.filter(p => p !== action.permission); return { ...state, [action.groupName]: newGroup }; } else { return state; diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/groups.js b/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/groups.js index a72f737e867..49f4c2162e5 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/groups.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/store/groups/groups.js @@ -27,4 +27,4 @@ export default combineReducers({ }); export const getGroups = state => - getNames(state.names).map(name => getGroupByName(state.byName, name)); + getNames(state.names).map(name => getGroupByName(state.byName, name)); diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js b/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js index 81ef1b98ec1..006a5b932c1 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/store/users/byLogin.js @@ -18,7 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import keyBy from 'lodash/keyBy'; -import { RECEIVE_HOLDERS_SUCCESS, GRANT_PERMISSION_TO_USER, REVOKE_PERMISSION_TO_USER } from '../actions'; +import { + RECEIVE_HOLDERS_SUCCESS, + GRANT_PERMISSION_TO_USER, + REVOKE_PERMISSION_TO_USER +} from '../actions'; const byLogin = (state = {}, action = {}) => { if (action.type === RECEIVE_HOLDERS_SUCCESS) { @@ -30,8 +34,7 @@ const byLogin = (state = {}, action = {}) => { return { ...state, [action.login]: newUser }; } else if (action.type === REVOKE_PERMISSION_TO_USER) { const newUser = { ...state[action.login] }; - newUser.permissions = newUser.permissions - .filter(p => p !== action.permission); + newUser.permissions = newUser.permissions.filter(p => p !== action.permission); return { ...state, [action.login]: newUser }; } else { return state; diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/store/users/users.js b/server/sonar-web/src/main/js/apps/permissions/shared/store/users/users.js index 0ec0018ddad..08ab640522a 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/store/users/users.js +++ b/server/sonar-web/src/main/js/apps/permissions/shared/store/users/users.js @@ -27,4 +27,4 @@ export default combineReducers({ }); export const getUsers = state => - getLogins(state.logins).map(login => getUserByLogin(state.byLogin, login)); + getLogins(state.logins).map(login => getUserByLogin(state.byLogin, login)); diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js index eaa1e3d537b..273850ea38b 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js +++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/ConfirmationModal.js @@ -24,26 +24,25 @@ import { deleteProject } from '../../../api/components'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.showSpinner(); deleteProject(this.options.project.key) - .then(() => { - this.trigger('done'); - }) - .catch(function (e) { - e.response.json().then(r => { - this.hideSpinner(); - this.showErrors(r.errors, r.warnings); - this.enableForm(); - }); + .then(() => { + this.trigger('done'); + }) + .catch(function(e) { + e.response.json().then(r => { + this.hideSpinner(); + this.showErrors(r.errors, r.warnings); + this.enableForm(); }); + }); }, - serializeData () { + serializeData() { return { project: this.options.project }; } }); - diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js index f641a279e6c..6bfe208da9c 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js +++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/Deletion.js @@ -28,16 +28,16 @@ class Deletion extends React.Component { component: React.PropTypes.object }; - render () { + render() { if (!this.props.component) { return null; } return ( - <div className="page page-limited"> - <Header/> - <Form component={this.props.component}/> - </div> + <div className="page page-limited"> + <Header /> + <Form component={this.props.component} /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js index 5f36feac5dc..77a6faf9591 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js +++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/Form.js @@ -26,22 +26,22 @@ export default class Form extends React.Component { component: React.PropTypes.object.isRequired }; - handleDelete (e) { + handleDelete(e) { e.preventDefault(); new ConfirmationModal({ project: this.props.component }) - .on('done', () => { - window.location = window.baseUrl + '/'; - }) - .render(); + .on('done', () => { + window.location = window.baseUrl + '/'; + }) + .render(); } - render () { + render() { return ( - <form onSubmit={this.handleDelete.bind(this)}> - <button id="delete-project" className="button-red"> - {translate('delete')} - </button> - </form> + <form onSubmit={this.handleDelete.bind(this)}> + <button id="delete-project" className="button-red"> + {translate('delete')} + </button> + </form> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/deletion/Header.js b/server/sonar-web/src/main/js/apps/project-admin/deletion/Header.js index 86bbac8839c..bc28ea70f3e 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/deletion/Header.js +++ b/server/sonar-web/src/main/js/apps/project-admin/deletion/Header.js @@ -21,16 +21,16 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class Header extends React.Component { - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('deletion.page')} - </h1> - <div className="page-description"> - {translate('project_deletion.page.description')} - </div> - </header> + <header className="page-header"> + <h1 className="page-title"> + {translate('deletion.page')} + </h1> + <div className="page-description"> + {translate('project_deletion.page.description')} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js index 0e04b507be6..5a8e3755950 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js @@ -25,9 +25,9 @@ import { translate, translateWithParameters } from '../../../helpers/l10n'; import { bulkChangeKey } from '../../../api/components'; import { parseError } from '../../code/utils'; import { - addGlobalErrorMessage, - addGlobalSuccessMessage, - closeAllGlobalMessages + addGlobalErrorMessage, + addGlobalSuccessMessage, + closeAllGlobalMessages } from '../../../store/globalMessages/duck'; import { reloadUpdateKeyPage } from './utils'; import RecentHistory from '../../../app/components/nav/component/RecentHistory'; @@ -46,54 +46,57 @@ class BulkUpdate extends React.Component { newComponentKey: null }; - handleSubmit (replace, by) { + handleSubmit(replace, by) { this.loadResults(replace, by); } - handleConfirm () { + handleConfirm() { this.setState({ updating: true }); const { component } = this.props; const { replace, by } = this.state; - bulkChangeKey(component.key, replace, by).then(r => { - const result = r.keys.find(result => result.key === component.key); - const newComponentKey = result != null ? result.newKey : component.key; - - if (newComponentKey !== component.key) { - RecentHistory.remove(component.key); - } - - this.props.addGlobalSuccessMessage( - translate('update_key.key_updated.reload')); - this.setState({ updating: false }); - reloadUpdateKeyPage(newComponentKey); - }).catch(e => { - this.setState({ updating: false }); - parseError(e).then(message => this.props.addGlobalErrorMessage(message)); - }); + bulkChangeKey(component.key, replace, by) + .then(r => { + const result = r.keys.find(result => result.key === component.key); + const newComponentKey = result != null ? result.newKey : component.key; + + if (newComponentKey !== component.key) { + RecentHistory.remove(component.key); + } + + this.props.addGlobalSuccessMessage(translate('update_key.key_updated.reload')); + this.setState({ updating: false }); + reloadUpdateKeyPage(newComponentKey); + }) + .catch(e => { + this.setState({ updating: false }); + parseError(e).then(message => this.props.addGlobalErrorMessage(message)); + }); } - loadResults (replace, by) { + loadResults(replace, by) { const { component } = this.props; - bulkChangeKey(component.key, replace, by, true).then(r => { - this.setState({ results: r.keys, replace, by }); - this.props.closeAllGlobalMessages(); - }).catch(e => { - this.setState({ results: null }); - parseError(e).then(message => this.props.addGlobalErrorMessage(message)); - }); + bulkChangeKey(component.key, replace, by, true) + .then(r => { + this.setState({ results: r.keys, replace, by }); + this.props.closeAllGlobalMessages(); + }) + .catch(e => { + this.setState({ results: null }); + parseError(e).then(message => this.props.addGlobalErrorMessage(message)); + }); } - renderUpdating () { + renderUpdating() { return ( - <div id="project-key-bulk-update"> - <i className="spinner"/> - </div> + <div id="project-key-bulk-update"> + <i className="spinner" /> + </div> ); } - render () { + render() { const { component } = this.props; const { updating, updated } = this.state; const { results, replace, by } = this.state; @@ -107,38 +110,36 @@ class BulkUpdate extends React.Component { } return ( - <div id="project-key-bulk-update"> - <header className="big-spacer-bottom"> - <div className="spacer-bottom"> - {translate('update_key.bulk_change_description')} - </div> - <div> - {translateWithParameters( - 'update_key.current_key_for_project_x_is_x', - component.name, - component.key - )} - </div> - </header> - - <BulkUpdateForm onSubmit={this.handleSubmit.bind(this)}/> - - {results != null && ( - <BulkUpdateResults - results={results} - replace={replace} - by={by} - onConfirm={this.handleConfirm.bind(this)}/> - )} - </div> + <div id="project-key-bulk-update"> + <header className="big-spacer-bottom"> + <div className="spacer-bottom"> + {translate('update_key.bulk_change_description')} + </div> + <div> + {translateWithParameters( + 'update_key.current_key_for_project_x_is_x', + component.name, + component.key + )} + </div> + </header> + + <BulkUpdateForm onSubmit={this.handleSubmit.bind(this)} /> + + {results != null && + <BulkUpdateResults + results={results} + replace={replace} + by={by} + onConfirm={this.handleConfirm.bind(this)} + />} + </div> ); } } -export default connect( - null, { - addGlobalErrorMessage, - addGlobalSuccessMessage, - closeAllGlobalMessages - } -)(BulkUpdate); +export default connect(null, { + addGlobalErrorMessage, + addGlobalSuccessMessage, + closeAllGlobalMessages +})(BulkUpdate); diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js index 870cd88a8bb..24938cafc3c 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateForm.js @@ -25,7 +25,7 @@ export default class BulkUpdateForm extends React.Component { onSubmit: React.PropTypes.func.isRequired }; - handleSubmit (e) { + handleSubmit(e) { e.preventDefault(); this.refs.submit.blur(); @@ -35,41 +35,40 @@ export default class BulkUpdateForm extends React.Component { this.props.onSubmit(replace, by); } - render () { + render() { return ( - <form onSubmit={this.handleSubmit.bind(this)}> - <div className="modal-field"> - <label htmlFor="bulk-update-replace"> - {translate('update_key.replace')} - </label> - <input - ref="replace" - id="bulk-update-replace" - name="replace" - type="text" - placeholder={translate('update_key.replace_example')} - required={true}/> - </div> + <form onSubmit={this.handleSubmit.bind(this)}> + <div className="modal-field"> + <label htmlFor="bulk-update-replace"> + {translate('update_key.replace')} + </label> + <input + ref="replace" + id="bulk-update-replace" + name="replace" + type="text" + placeholder={translate('update_key.replace_example')} + required={true} + /> + </div> - <div className="modal-field"> - <label htmlFor="bulk-update-by"> - {translate('update_key.by')} - </label> - <input - ref="by" - id="bulk-update-by" - name="by" - type="text" - placeholder={translate('update_key.by_example')} - required={true}/> - <button - ref="submit" - id="bulk-update-see-results" - className="big-spacer-left"> - {translate('update_key.see_results')} - </button> - </div> - </form> + <div className="modal-field"> + <label htmlFor="bulk-update-by"> + {translate('update_key.by')} + </label> + <input + ref="by" + id="bulk-update-by" + name="by" + type="text" + placeholder={translate('update_key.by_example')} + required={true} + /> + <button ref="submit" id="bulk-update-see-results" className="big-spacer-left"> + {translate('update_key.see_results')} + </button> + </div> + </form> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js index 546a803dc25..7b6bbb3550e 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdateResults.js @@ -27,85 +27,68 @@ export default class BulkUpdateResults extends React.Component { onConfirm: React.PropTypes.func.isRequired }; - handleConfirm (e) { + handleConfirm(e) { e.preventDefault(); e.target.blur(); this.props.onConfirm(); } - render () { + render() { const { results, replace, by } = this.props; const isEmpty = results.length === 0; const hasDuplications = some(results, r => r.duplicate); const canUpdate = !isEmpty && !hasDuplications; return ( - <div id="bulk-update-simulation" className="big-spacer-top"> - {isEmpty && ( - <div id="bulk-update-nothing" className="spacer-bottom"> - {translateWithParameters( - 'update_key.no_key_to_update', - replace - )} - </div> - )} + <div id="bulk-update-simulation" className="big-spacer-top"> + {isEmpty && + <div id="bulk-update-nothing" className="spacer-bottom"> + {translateWithParameters('update_key.no_key_to_update', replace)} + </div>} - {hasDuplications && ( - <div id="bulk-update-duplicate" className="spacer-bottom"> - {translateWithParameters( - 'update_key.cant_update_because_duplicate_keys', - replace, - by - )} - </div> - )} + {hasDuplications && + <div id="bulk-update-duplicate" className="spacer-bottom"> + {translateWithParameters('update_key.cant_update_because_duplicate_keys', replace, by)} + </div>} - {canUpdate && ( - <div className="spacer-bottom"> - {translate('update_key.keys_will_be_updated_as_follows')} - </div> - )} + {canUpdate && + <div className="spacer-bottom"> + {translate('update_key.keys_will_be_updated_as_follows')} + </div>} - {!isEmpty && ( - <table - id="bulk-update-results" - className="data zebra zebra-hover"> - <thead> - <tr> - <th>{translate('update_key.old_key')}</th> - <th>{translate('update_key.new_key')}</th> - </tr> - </thead> - <tbody> - {results.map(result => ( - <tr key={result.key} data-key={result.key}> - <td className="js-old-key"> - {result.key} - </td> - <td className="js-new-key"> - {result.duplicate && ( - <span className="spacer-right badge badge-danger"> - {translate('update_key.duplicate_key')} - </span> - )} - {result.newKey} - </td> - </tr> - ))} - </tbody> - </table> - )} + {!isEmpty && + <table id="bulk-update-results" className="data zebra zebra-hover"> + <thead> + <tr> + <th>{translate('update_key.old_key')}</th> + <th>{translate('update_key.new_key')}</th> + </tr> + </thead> + <tbody> + {results.map(result => ( + <tr key={result.key} data-key={result.key}> + <td className="js-old-key"> + {result.key} + </td> + <td className="js-new-key"> + {result.duplicate && + <span className="spacer-right badge badge-danger"> + {translate('update_key.duplicate_key')} + </span>} + {result.newKey} + </td> + </tr> + ))} + </tbody> + </table>} - <div className="big-spacer-top"> - {canUpdate && ( - <button - id="bulk-update-confirm" - onClick={this.handleConfirm.bind(this)}> - {translate('update_verb')} - </button> - )} - </div> + <div className="big-spacer-top"> + {canUpdate && + <button id="bulk-update-confirm" onClick={this.handleConfirm.bind(this)}> + {translate('update_verb')} + </button>} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js b/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js index 66139f35369..7928cb05f4c 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/FineGrainedUpdate.js @@ -22,31 +22,29 @@ import UpdateKeyForm from './UpdateKeyForm'; import QualifierIcon from '../../../components/shared/qualifier-icon'; export default class FineGrainedUpdate extends React.Component { - render () { + render() { const { component, modules } = this.props; const components = [component, ...modules]; return ( - <div id="project-key-fine-grained-update"> - <table className="data zebra"> - <tbody> - {components.map(component => ( - <tr key={component.key}> - <td className="width-40"> - <QualifierIcon qualifier={component.qualifier}/> - {' '} - {component.name} - </td> - <td> - <UpdateKeyForm - component={component} - onKeyChange={this.props.onKeyChange}/> - </td> - </tr> - ))} - </tbody> - </table> - </div> + <div id="project-key-fine-grained-update"> + <table className="data zebra"> + <tbody> + {components.map(component => ( + <tr key={component.key}> + <td className="width-40"> + <QualifierIcon qualifier={component.qualifier} /> + {' '} + {component.name} + </td> + <td> + <UpdateKeyForm component={component} onKeyChange={this.props.onKeyChange} /> + </td> + </tr> + ))} + </tbody> + </table> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/Header.js b/server/sonar-web/src/main/js/apps/project-admin/key/Header.js index 7f5120cf563..8b079387c1b 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/Header.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/Header.js @@ -21,16 +21,16 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class Header extends React.Component { - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('update_key.page')} - </h1> - <div className="page-description"> - {translate('update_key.page.description')} - </div> - </header> + <header className="page-header"> + <h1 className="page-title"> + {translate('update_key.page')} + </h1> + <div className="page-description"> + {translate('update_key.page.description')} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js index 42c3929bb5f..661ab118e01 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/Key.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/Key.js @@ -27,9 +27,9 @@ import FineGrainedUpdate from './FineGrainedUpdate'; import { fetchProjectModules, changeKey } from '../store/actions'; import { translate } from '../../../helpers/l10n'; import { - addGlobalErrorMessage, - closeAllGlobalMessages, - addGlobalSuccessMessage + addGlobalErrorMessage, + closeAllGlobalMessages, + addGlobalSuccessMessage } from '../../../store/globalMessages/duck'; import { parseError } from '../../code/utils'; import { reloadUpdateKeyPage } from './utils'; @@ -50,38 +50,39 @@ class Key extends React.Component { tab: 'bulk' }; - componentDidMount () { + componentDidMount() { this.props.fetchProjectModules(this.props.component.key); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleChangeKey (key, newKey) { - return this.props.changeKey(key, newKey).then(() => { - if (key === this.props.component.key) { - this.props.addGlobalSuccessMessage( - translate('update_key.key_updated.reload')); - RecentHistory.remove(key); - reloadUpdateKeyPage(newKey); - } else { - this.props.addGlobalSuccessMessage( - translate('update_key.key_updated')); - } - }).catch(e => { - parseError(e).then(this.props.addGlobalErrorMessage); - }); + handleChangeKey(key, newKey) { + return this.props + .changeKey(key, newKey) + .then(() => { + if (key === this.props.component.key) { + this.props.addGlobalSuccessMessage(translate('update_key.key_updated.reload')); + RecentHistory.remove(key); + reloadUpdateKeyPage(newKey); + } else { + this.props.addGlobalSuccessMessage(translate('update_key.key_updated')); + } + }) + .catch(e => { + parseError(e).then(this.props.addGlobalErrorMessage); + }); } - handleChangeTab (tab, e) { + handleChangeTab(tab, e) { e.preventDefault(); e.target.blur(); this.setState({ tab }); this.props.closeAllGlobalMessages(); } - render () { + render() { const { component, modules } = this.props; const noModules = modules != null && modules.length === 0; @@ -90,59 +91,55 @@ class Key extends React.Component { const { tab } = this.state; return ( - <div id="project-key" className="page page-limited"> - <Header/> - - {modules == null && ( - <i className="spinner"/> - )} - - {noModules && ( - <div> - <UpdateForm - component={component} - onKeyChange={this.handleChangeKey.bind(this)}/> - </div> - )} - - {hasModules && ( - <div> - <div className="big-spacer-bottom"> - <ul className="tabs"> - <li> - <a id="update-key-tab-bulk" - className={tab === 'bulk' ? 'selected' : ''} - href="#" - onClick={this.handleChangeTab.bind(this, 'bulk')}> - {translate('update_key.bulk_update')} - </a> - </li> - <li> - <a id="update-key-tab-fine" - className={tab === 'fine' ? 'selected' : ''} - href="#" - onClick={this.handleChangeTab.bind(this, 'fine')}> - {translate('update_key.fine_grained_key_update')} - </a> - </li> - </ul> - </div> - - {tab === 'bulk' && ( - <BulkUpdate component={component}/> - )} - - {tab === 'fine' && ( - <FineGrainedUpdate - component={component} - modules={modules} - onKeyChange={this.handleChangeKey.bind(this)} - onSuccess={this.props.closeAllGlobalMessages} - onError={this.props.addGlobalErrorMessage}/> - )} - </div> - )} - </div> + <div id="project-key" className="page page-limited"> + <Header /> + + {modules == null && <i className="spinner" />} + + {noModules && + <div> + <UpdateForm component={component} onKeyChange={this.handleChangeKey.bind(this)} /> + </div>} + + {hasModules && + <div> + <div className="big-spacer-bottom"> + <ul className="tabs"> + <li> + <a + id="update-key-tab-bulk" + className={tab === 'bulk' ? 'selected' : ''} + href="#" + onClick={this.handleChangeTab.bind(this, 'bulk')} + > + {translate('update_key.bulk_update')} + </a> + </li> + <li> + <a + id="update-key-tab-fine" + className={tab === 'fine' ? 'selected' : ''} + href="#" + onClick={this.handleChangeTab.bind(this, 'fine')} + > + {translate('update_key.fine_grained_key_update')} + </a> + </li> + </ul> + </div> + + {tab === 'bulk' && <BulkUpdate component={component} />} + + {tab === 'fine' && + <FineGrainedUpdate + component={component} + modules={modules} + onKeyChange={this.handleChangeKey.bind(this)} + onSuccess={this.props.closeAllGlobalMessages} + onError={this.props.addGlobalErrorMessage} + />} + </div>} + </div> ); } } @@ -152,12 +149,10 @@ const mapStateToProps = (state, ownProps) => ({ modules: getProjectAdminProjectModules(state, ownProps.location.query.id) }); -export default connect( - mapStateToProps, { - fetchProjectModules, - changeKey, - addGlobalErrorMessage, - addGlobalSuccessMessage, - closeAllGlobalMessages - } -)(Key); +export default connect(mapStateToProps, { + fetchProjectModules, + changeKey, + addGlobalErrorMessage, + addGlobalSuccessMessage, + closeAllGlobalMessages +})(Key); diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js index 38b2f68a4b1..b037f6f27b9 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateForm.js @@ -29,7 +29,7 @@ export default class UpdateForm extends React.Component { state = { newKey: null }; - handleSubmit (e) { + handleSubmit(e) { e.preventDefault(); const newKey = this.refs.newKey.value; @@ -41,46 +41,48 @@ export default class UpdateForm extends React.Component { }).render(); } - handleChange (e) { + handleChange(e) { const newKey = e.target.value; this.setState({ newKey }); } - handleReset (e) { + handleReset(e) { e.preventDefault(); this.setState({ newKey: null }); } - render () { - const value = this.state.newKey != null ? - this.state.newKey : - this.props.component.key; + render() { + const value = this.state.newKey != null ? this.state.newKey : this.props.component.key; const hasChanged = value !== this.props.component.key; return ( - <form onSubmit={this.handleSubmit.bind(this)}> - <input - ref="newKey" - id="update-key-new-key" - className="input-super-large" - value={value} - type="text" - placeholder={translate('update_key.new_key')} - required={true} - onChange={this.handleChange.bind(this)}/> + <form onSubmit={this.handleSubmit.bind(this)}> + <input + ref="newKey" + id="update-key-new-key" + className="input-super-large" + value={value} + type="text" + placeholder={translate('update_key.new_key')} + required={true} + onChange={this.handleChange.bind(this)} + /> - <div className="spacer-top"> - <button id="update-key-submit" disabled={!hasChanged}> - {translate('update_verb')} - </button> - {' '} - <button id="update-key-reset" disabled={!hasChanged} - onClick={this.handleReset.bind(this)}> - {translate('reset_verb')} - </button> - </div> - </form> + <div className="spacer-top"> + <button id="update-key-submit" disabled={!hasChanged}> + {translate('update_verb')} + </button> + {' '} + <button + id="update-key-reset" + disabled={!hasChanged} + onClick={this.handleReset.bind(this)} + > + {translate('reset_verb')} + </button> + </div> + </form> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js index 711cdacffec..847324cec15 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/UpdateKeyForm.js @@ -28,18 +28,18 @@ export default class UpdateKeyForm extends React.Component { state = {}; - componentWillMount () { + componentWillMount() { this.handleInputChange = this.handleInputChange.bind(this); this.handleUpdateClick = this.handleUpdateClick.bind(this); this.handleResetClick = this.handleResetClick.bind(this); } - handleInputChange (e) { + handleInputChange(e) { const key = e.target.value; this.setState({ key }); } - handleUpdateClick (e) { + handleUpdateClick(e) { e.preventDefault(); e.target.blur(); @@ -52,41 +52,39 @@ export default class UpdateKeyForm extends React.Component { }).render(); } - handleResetClick (e) { + handleResetClick(e) { e.preventDefault(); e.target.blur(); this.setState({ key: null }); } - render () { + render() { const { component } = this.props; - const value = this.state.key != null ? - this.state.key : - component.key; + const value = this.state.key != null ? this.state.key : component.key; - const hasChanged = this.state.key != null && - this.state.key !== component.key; + const hasChanged = this.state.key != null && this.state.key !== component.key; return ( - <div className="js-fine-grained-update" data-key={component.key}> - <input - ref="newKey" - className="input-super-large big-spacer-right" - type="text" - value={value} - onChange={this.handleInputChange}/> + <div className="js-fine-grained-update" data-key={component.key}> + <input + ref="newKey" + className="input-super-large big-spacer-right" + type="text" + value={value} + onChange={this.handleInputChange} + /> - <div className="button-group"> - <button disabled={!hasChanged} onClick={this.handleUpdateClick}> - {translate('update_verb')} - </button> + <div className="button-group"> + <button disabled={!hasChanged} onClick={this.handleUpdateClick}> + {translate('update_verb')} + </button> - <button disabled={!hasChanged} onClick={this.handleResetClick}> - {translate('reset_verb')} - </button> - </div> + <button disabled={!hasChanged} onClick={this.handleResetClick}> + {translate('reset_verb')} + </button> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/utils.js b/server/sonar-web/src/main/js/apps/project-admin/key/utils.js index 8cddf76bce0..bc5f8221bcd 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/utils.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/utils.js @@ -18,8 +18,10 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ export const reloadUpdateKeyPage = componentKey => { - setTimeout(() => { - window.location = window.baseUrl + - '/project/key?id=' + encodeURIComponent(componentKey); - }, 3000); + setTimeout( + () => { + window.location = window.baseUrl + '/project/key?id=' + encodeURIComponent(componentKey); + }, + 3000 + ); }; diff --git a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js index d4909a18ba7..5edbfb2dd1f 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js +++ b/server/sonar-web/src/main/js/apps/project-admin/key/views/UpdateKeyConfirmation.js @@ -23,7 +23,7 @@ import Template from './UpdateKeyConfirmation.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.showSpinner(); @@ -32,11 +32,10 @@ export default ModalForm.extend({ this.destroy(); }, - serializeData () { + serializeData() { return { component: this.options.component, newKey: this.options.newKey }; } }); - diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Header.js b/server/sonar-web/src/main/js/apps/project-admin/links/Header.js index 635a27cbc8f..d8df7093718 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/Header.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/Header.js @@ -26,7 +26,7 @@ export default class Header extends React.Component { onCreate: React.PropTypes.func.isRequired }; - handleCreateClick (e) { + handleCreateClick(e) { e.preventDefault(); e.target.blur(); new CreationModal({ @@ -34,23 +34,21 @@ export default class Header extends React.Component { }).render(); } - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('project_links.page')} - </h1> - <div className="page-actions"> - <button - id="create-project-link" - onClick={this.handleCreateClick.bind(this)}> - {translate('create')} - </button> - </div> - <div className="page-description"> - {translate('project_links.page.description')} - </div> - </header> + <header className="page-header"> + <h1 className="page-title"> + {translate('project_links.page')} + </h1> + <div className="page-actions"> + <button id="create-project-link" onClick={this.handleCreateClick.bind(this)}> + {translate('create')} + </button> + </div> + <div className="page-description"> + {translate('project_links.page.description')} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.js b/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.js index a36b3a0064a..8ebe995b727 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/LinkRow.js @@ -29,64 +29,64 @@ export default class LinkRow extends React.Component { onDelete: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleDeleteClick (e) { + handleDeleteClick(e) { e.preventDefault(); e.target.blur(); this.props.onDelete(); } - renderIcon (iconClassName) { + renderIcon(iconClassName) { if (iconClassName === 'icon-issue') { return ( - <div className="display-inline-block text-top spacer-right"> - <BugTrackerIcon/> - </div> + <div className="display-inline-block text-top spacer-right"> + <BugTrackerIcon /> + </div> ); } return ( - <div className="display-inline-block text-top spacer-right"> - <i className={iconClassName}/> - </div> + <div className="display-inline-block text-top spacer-right"> + <i className={iconClassName} /> + </div> ); } - renderNameForProvided (link) { + renderNameForProvided(link) { return ( - <div> - {this.renderIcon(`icon-${link.type}`)} - <div className="display-inline-block text-top"> - <div> - <span className="js-name">{link.name}</span> - </div> - <div className="note little-spacer-top"> - <span className="js-type">{`sonar.links.${link.type}`}</span> - </div> + <div> + {this.renderIcon(`icon-${link.type}`)} + <div className="display-inline-block text-top"> + <div> + <span className="js-name">{link.name}</span> + </div> + <div className="note little-spacer-top"> + <span className="js-type">{`sonar.links.${link.type}`}</span> </div> </div> + </div> ); } - renderName (link) { + renderName(link) { if (isProvided(link)) { return this.renderNameForProvided(link); } return ( - <div> - {this.renderIcon('icon-detach')} - <div className="display-inline-block text-top"> - <span className="js-name">{link.name}</span> - </div> + <div> + {this.renderIcon('icon-detach')} + <div className="display-inline-block text-top"> + <span className="js-name">{link.name}</span> </div> + </div> ); } - renderUrl (link) { + renderUrl(link) { if (isClickable(link)) { return <a href={link.url} target="_blank">{link.url}</a>; } @@ -94,29 +94,27 @@ export default class LinkRow extends React.Component { return link.url; } - renderDeleteButton (link) { + renderDeleteButton(link) { if (isProvided(link)) { return null; } return ( - <button - className="button-red js-delete-button" - onClick={this.handleDeleteClick.bind(this)}> - {translate('delete')} - </button> + <button className="button-red js-delete-button" onClick={this.handleDeleteClick.bind(this)}> + {translate('delete')} + </button> ); } - render () { + render() { const { link } = this.props; return ( - <tr data-name={link.name}> - <td className="nowrap">{this.renderName(link)}</td> - <td className="nowrap js-url">{this.renderUrl(link)}</td> - <td className="thin nowrap">{this.renderDeleteButton(link)}</td> - </tr> + <tr data-name={link.name}> + <td className="nowrap">{this.renderName(link)}</td> + <td className="nowrap js-url">{this.renderUrl(link)}</td> + <td className="thin nowrap">{this.renderDeleteButton(link)}</td> + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Links.js b/server/sonar-web/src/main/js/apps/project-admin/links/Links.js index e25ed2cc587..00807d9adad 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/Links.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/Links.js @@ -23,11 +23,7 @@ import { connect } from 'react-redux'; import Header from './Header'; import Table from './Table'; import DeletionModal from './views/DeletionModal'; -import { - fetchProjectLinks, - deleteProjectLink, - createProjectLink -} from '../store/actions'; +import { fetchProjectLinks, deleteProjectLink, createProjectLink } from '../store/actions'; import { getProjectAdminProjectLinks, getComponent } from '../../../store/rootReducer'; class Links extends React.Component { @@ -36,38 +32,37 @@ class Links extends React.Component { links: React.PropTypes.array }; - componentWillMount () { + componentWillMount() { this.handleCreateLink = this.handleCreateLink.bind(this); this.handleDeleteLink = this.handleDeleteLink.bind(this); } - componentDidMount () { + componentDidMount() { this.props.fetchProjectLinks(this.props.component.key); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleCreateLink (name, url) { + handleCreateLink(name, url) { return this.props.createProjectLink(this.props.component.key, name, url); } - handleDeleteLink (link) { - new DeletionModal({ link }).on('done', () => { - this.props.deleteProjectLink(this.props.component.key, link.id); - }).render(); + handleDeleteLink(link) { + new DeletionModal({ link }) + .on('done', () => { + this.props.deleteProjectLink(this.props.component.key, link.id); + }) + .render(); } - render () { + render() { return ( - <div className="page page-limited"> - <Header - onCreate={this.handleCreateLink}/> - <Table - links={this.props.links} - onDelete={this.handleDeleteLink}/> - </div> + <div className="page page-limited"> + <Header onCreate={this.handleCreateLink} /> + <Table links={this.props.links} onDelete={this.handleDeleteLink} /> + </div> ); } } @@ -77,7 +72,8 @@ const mapStateToProps = (state, ownProps) => ({ links: getProjectAdminProjectLinks(state, ownProps.location.query.id) }); -export default connect( - mapStateToProps, - { fetchProjectLinks, createProjectLink, deleteProjectLink } -)(Links); +export default connect(mapStateToProps, { + fetchProjectLinks, + createProjectLink, + deleteProjectLink +})(Links); diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/Table.js b/server/sonar-web/src/main/js/apps/project-admin/links/Table.js index 779403718a5..d71f6709220 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/Table.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/Table.js @@ -29,46 +29,43 @@ export default class Table extends React.Component { onDelete: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleDeleteLink (link) { + handleDeleteLink(link) { this.props.onDelete(link); } - renderHeader () { + renderHeader() { // keep empty cell for actions return ( - <thead> - <tr> - <th className="nowrap"> - {translate('project_links.name')} - </th> - <th className="nowrap width-100"> - {translate('project_links.url')} - </th> - <th className="thin"> </th> - </tr> - </thead> + <thead> + <tr> + <th className="nowrap"> + {translate('project_links.name')} + </th> + <th className="nowrap width-100"> + {translate('project_links.url')} + </th> + <th className="thin"> </th> + </tr> + </thead> ); } - render () { + render() { const orderedLinks = orderLinks(this.props.links); const linkRows = orderedLinks.map(link => ( - <LinkRow - key={link.id} - link={link} - onDelete={this.handleDeleteLink.bind(this, link)}/> + <LinkRow key={link.id} link={link} onDelete={this.handleDeleteLink.bind(this, link)} /> )); return ( - <table id="project-links" className="data zebra"> - {this.renderHeader()} - <tbody>{linkRows}</tbody> - </table> + <table id="project-links" className="data zebra"> + {this.renderHeader()} + <tbody>{linkRows}</tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/utils.js b/server/sonar-web/src/main/js/apps/project-admin/links/utils.js index 65fcf6582f4..7b6486df900 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/utils.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/utils.js @@ -20,19 +20,13 @@ import partition from 'lodash/partition'; import sortBy from 'lodash/sortBy'; -const PROVIDED_TYPES = [ - 'homepage', - 'ci', - 'issue', - 'scm', - 'scm_dev' -]; +const PROVIDED_TYPES = ['homepage', 'ci', 'issue', 'scm', 'scm_dev']; -export function isProvided (link) { +export function isProvided(link) { return PROVIDED_TYPES.includes(link.type); } -export function orderLinks (links) { +export function orderLinks(links) { const [provided, unknown] = partition(links, isProvided); return [ ...sortBy(provided, link => PROVIDED_TYPES.indexOf(link.type)), @@ -40,7 +34,7 @@ export function orderLinks (links) { ]; } -export function isClickable (link) { +export function isClickable(link) { // stupid simple check return link.url.indexOf('http') === 0; } diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js b/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js index dd20358900d..9547362ecd5 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/views/CreationModal.js @@ -24,19 +24,16 @@ import { parseError } from '../../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); const name = this.$('#create-link-name').val(); const url = this.$('#create-link-url').val(); - this.options.onCreate(name, url) - .then(() => this.destroy()) - .catch(e => { - parseError(e).then(msg => this.showSingleError(msg)); - this.enableForm(); - }); + this.options.onCreate(name, url).then(() => this.destroy()).catch(e => { + parseError(e).then(msg => this.showSingleError(msg)); + this.enableForm(); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js b/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js index b58fc289f99..232857084c5 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js +++ b/server/sonar-web/src/main/js/apps/project-admin/links/views/DeletionModal.js @@ -25,23 +25,22 @@ import { parseError } from '../../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); deleteLink(this.options.link.id) - .then(() => { - this.trigger('done'); - this.destroy(); - }) - .catch(e => { - parseError(e).then(msg => this.showSingleError(msg)); - this.enableForm(); - }); + .then(() => { + this.trigger('done'); + this.destroy(); + }) + .catch(e => { + parseError(e).then(msg => this.showSingleError(msg)); + this.enableForm(); + }); }, - serializeData () { + serializeData() { return { link: this.options.link }; } }); - diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js index ee804e1fed4..a02fead0ffd 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Form.js @@ -34,26 +34,26 @@ export default class Form extends React.Component { loading: false }; - componentWillMount () { + componentWillMount() { this.handleChange = this.handleChange.bind(this); this.renderGateName = this.renderGateName.bind(this); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.gate !== this.props.gate) { this.stopLoading(); } } - stopLoading () { + stopLoading() { this.setState({ loading: false }); } - handleChange (option) { + handleChange(option) { const { gate } = this.props; const isSet = gate == null && option.value != null; @@ -67,21 +67,21 @@ export default class Form extends React.Component { } } - renderGateName (gateOption) { + renderGateName(gateOption) { if (gateOption.isDefault) { return ( - <span> - <strong>{translate('default')}</strong> - {': '} - {gateOption.label} - </span> + <span> + <strong>{translate('default')}</strong> + {': '} + {gateOption.label} + </span> ); } return gateOption.label; } - renderSelect () { + renderSelect() { const { gate, allGates } = this.props; const options = allGates.map(gate => ({ @@ -99,25 +99,26 @@ export default class Form extends React.Component { } return ( - <Select - options={options} - valueRenderer={this.renderGateName} - optionRenderer={this.renderGateName} - value={gate && gate.id} - clearable={false} - placeholder={translate('none')} - style={{ width: 300 }} - disabled={this.state.loading} - onChange={this.handleChange.bind(this)}/> + <Select + options={options} + valueRenderer={this.renderGateName} + optionRenderer={this.renderGateName} + value={gate && gate.id} + clearable={false} + placeholder={translate('none')} + style={{ width: 300 }} + disabled={this.state.loading} + onChange={this.handleChange.bind(this)} + /> ); } - render () { + render() { return ( - <div> - {this.renderSelect()} - {this.state.loading && <i className="spinner spacer-left"/>} - </div> + <div> + {this.renderSelect()} + {this.state.loading && <i className="spinner spacer-left" />} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Header.js b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Header.js index 2e3b6ef0f4a..4562e4faccd 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Header.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/Header.js @@ -21,16 +21,16 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class Header extends React.Component { - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('project_quality_gate.page')} - </h1> - <div className="page-description"> - {translate('project_quality_gate.page.description')} - </div> - </header> + <header className="page-header"> + <h1 className="page-title"> + {translate('project_quality_gate.page')} + </h1> + <div className="page-description"> + {translate('project_quality_gate.page.description')} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js index 5b29ac2b0f1..855b23f82e9 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-gate/QualityGate.js @@ -23,7 +23,11 @@ import shallowCompare from 'react-addons-shallow-compare'; import Header from './Header'; import Form from './Form'; import { fetchProjectGate, setProjectGate } from '../store/actions'; -import { getProjectAdminAllGates, getProjectAdminProjectGate, getComponent } from '../../../store/rootReducer'; +import { + getProjectAdminAllGates, + getProjectAdminProjectGate, + getComponent +} from '../../../store/rootReducer'; class QualityGate extends React.Component { static propTypes = { @@ -32,27 +36,28 @@ class QualityGate extends React.Component { gate: React.PropTypes.object }; - componentDidMount () { + componentDidMount() { this.props.fetchProjectGate(this.props.component.key); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleChangeGate (oldId, newId) { + handleChangeGate(oldId, newId) { this.props.setProjectGate(this.props.component.key, oldId, newId); } - render () { + render() { return ( - <div id="project-quality-gate" className="page page-limited"> - <Header/> - <Form - allGates={this.props.allGates} - gate={this.props.gate} - onChange={this.handleChangeGate.bind(this)}/> - </div> + <div id="project-quality-gate" className="page page-limited"> + <Header /> + <Form + allGates={this.props.allGates} + gate={this.props.gate} + onChange={this.handleChangeGate.bind(this)} + /> + </div> ); } } @@ -63,7 +68,4 @@ const mapStateToProps = (state, ownProps) => ({ gate: getProjectAdminProjectGate(state, ownProps.location.query.id) }); -export default connect( - mapStateToProps, - { fetchProjectGate, setProjectGate } -)(QualityGate); +export default connect(mapStateToProps, { fetchProjectGate, setProjectGate })(QualityGate); diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Header.js b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Header.js index b837b802b14..2e7f7dca3ed 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Header.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Header.js @@ -21,16 +21,16 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class Header extends React.Component { - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('project_quality_profiles.page')} - </h1> - <div className="page-description"> - {translate('project_quality_profiles.page.description')} - </div> - </header> + <header className="page-header"> + <h1 className="page-title"> + {translate('project_quality_profiles.page')} + </h1> + <div className="page-description"> + {translate('project_quality_profiles.page.description')} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/ProfileRow.js b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/ProfileRow.js index 2bf47d13220..aaeab20a652 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/ProfileRow.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/ProfileRow.js @@ -33,38 +33,38 @@ export default class ProfileRow extends React.Component { loading: false }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentWillUpdate (nextProps) { + componentWillUpdate(nextProps) { if (nextProps.profile !== this.props.profile) { this.setState({ loading: false }); } } - handleChange (option) { + handleChange(option) { if (this.props.profile.key !== option.value) { this.setState({ loading: true }); this.props.onChangeProfile(this.props.profile.key, option.value); } } - renderProfileName (profileOption) { + renderProfileName(profileOption) { if (profileOption.isDefault) { return ( - <span> - <strong>{translate('default')}</strong> - {': '} - {profileOption.label} - </span> + <span> + <strong>{translate('default')}</strong> + {': '} + {profileOption.label} + </span> ); } return profileOption.label; } - renderProfileSelect () { + renderProfileSelect() { const { profile, possibleProfiles } = this.props; const options = possibleProfiles.map(profile => ({ @@ -74,28 +74,30 @@ export default class ProfileRow extends React.Component { })); return ( - <Select - options={options} - valueRenderer={this.renderProfileName} - optionRenderer={this.renderProfileName} - value={profile.key} - clearable={false} - style={{ width: 300 }} - disabled={this.state.loading} - onChange={this.handleChange.bind(this)}/> + <Select + options={options} + valueRenderer={this.renderProfileName} + optionRenderer={this.renderProfileName} + value={profile.key} + clearable={false} + style={{ width: 300 }} + disabled={this.state.loading} + onChange={this.handleChange.bind(this)} + /> ); } - render () { + render() { const { profile } = this.props; return ( - <tr data-key={profile.language}> - <td className="thin nowrap">{profile.languageName}</td> - <td className="thin nowrap">{this.renderProfileSelect()}</td> - <td>{this.state.loading && <i className="spinner"/>} - </td> - </tr> + <tr data-key={profile.language}> + <td className="thin nowrap">{profile.languageName}</td> + <td className="thin nowrap">{this.renderProfileSelect()}</td> + <td> + {this.state.loading && <i className="spinner" />} + </td> + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js index eee707639ac..88d4c79c5c7 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/QualityProfiles.js @@ -36,34 +36,33 @@ class QualityProfiles extends React.Component { profiles: React.PropTypes.array }; - componentDidMount () { + componentDidMount() { this.props.fetchProjectProfiles(this.props.component.key); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleChangeProfile (oldKey, newKey) { + handleChangeProfile(oldKey, newKey) { this.props.setProjectProfile(this.props.component.key, oldKey, newKey); } - render () { + render() { const { allProfiles, profiles } = this.props; return ( - <div className="page page-limited"> - <Header/> + <div className="page page-limited"> + <Header /> - {profiles.length > 0 ? ( - <Table - allProfiles={allProfiles} - profiles={profiles} - onChangeProfile={this.handleChangeProfile.bind(this)}/> - ) : ( - <i className="spinner"/> - )} - </div> + {profiles.length > 0 + ? <Table + allProfiles={allProfiles} + profiles={profiles} + onChangeProfile={this.handleChangeProfile.bind(this)} + /> + : <i className="spinner" />} + </div> ); } } @@ -74,7 +73,6 @@ const mapStateToProps = (state, ownProps) => ({ profiles: getProjectAdminProjectProfiles(state, ownProps.location.query.id) }); -export default connect( - mapStateToProps, - { fetchProjectProfiles, setProjectProfile } -)(QualityProfiles); +export default connect(mapStateToProps, { fetchProjectProfiles, setProjectProfile })( + QualityProfiles +); diff --git a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js index 426cca3fd6f..4b3d6bdc3aa 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js +++ b/server/sonar-web/src/main/js/apps/project-admin/quality-profiles/Table.js @@ -31,41 +31,42 @@ export default class Table extends React.Component { onChangeProfile: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - renderHeader () { + renderHeader() { // keep one empty cell for the spinner return ( - <thead> - <tr> - <th className="thin nowrap">{translate('language')}</th> - <th className="thin nowrap">{translate('quality_profile')}</th> - <th> </th> - </tr> - </thead> + <thead> + <tr> + <th className="thin nowrap">{translate('language')}</th> + <th className="thin nowrap">{translate('quality_profile')}</th> + <th> </th> + </tr> + </thead> ); } - render () { + render() { const profilesByLanguage = groupBy(this.props.allProfiles, 'language'); const orderedProfiles = orderBy(this.props.profiles, 'languageName'); // set key to language to avoid destroying of component const profileRows = orderedProfiles.map(profile => ( - <ProfileRow - key={profile.language} - profile={profile} - possibleProfiles={profilesByLanguage[profile.language]} - onChangeProfile={this.props.onChangeProfile}/> + <ProfileRow + key={profile.language} + profile={profile} + possibleProfiles={profilesByLanguage[profile.language]} + onChangeProfile={this.props.onChangeProfile} + /> )); return ( - <table className="data zebra"> - {this.renderHeader()} - <tbody>{profileRows}</tbody> - </table> + <table className="data zebra"> + {this.renderHeader()} + <tbody>{profileRows}</tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/project-admin/routes.js b/server/sonar-web/src/main/js/apps/project-admin/routes.js index 92e96500c48..a7b363c2c7b 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/routes.js +++ b/server/sonar-web/src/main/js/apps/project-admin/routes.js @@ -26,9 +26,9 @@ import Links from './links/Links'; import Key from './key/Key'; export default [ - <Route key="deletion" path="deletion" component={Deletion}/>, - <Route key="quality_profiles" path="quality_profiles" component={QualityProfiles}/>, - <Route key="quality_gate" path="quality_gate" component={QualityGate}/>, - <Route key="links" path="links" component={Links}/>, - <Route key="key" path="key" component={Key}/> + <Route key="deletion" path="deletion" component={Deletion} />, + <Route key="quality_profiles" path="quality_profiles" component={QualityProfiles} />, + <Route key="quality_gate" path="quality_gate" component={QualityGate} />, + <Route key="links" path="links" component={Links} />, + <Route key="key" path="key" component={Key} /> ]; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/actions.js b/server/sonar-web/src/main/js/apps/project-admin/store/actions.js index 9cb5cd83fea..2f96a8bf723 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/actions.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/actions.js @@ -17,7 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { getQualityProfiles, associateProject, dissociateProject } from '../../../api/quality-profiles'; +import { + getQualityProfiles, + associateProject, + dissociateProject +} from '../../../api/quality-profiles'; import { fetchQualityGates, getGateForProject, @@ -43,16 +47,14 @@ export const receiveProjectProfiles = (projectKey, profiles) => ({ profiles }); -export const fetchProjectProfiles = projectKey => dispatch => { - Promise.all([ - getQualityProfiles(), - getQualityProfiles({ projectKey }) - ]).then(responses => { - const [allProfiles, projectProfiles] = responses; - dispatch(receiveProfiles(allProfiles)); - dispatch(receiveProjectProfiles(projectKey, projectProfiles)); - }); -}; +export const fetchProjectProfiles = projectKey => + dispatch => { + Promise.all([getQualityProfiles(), getQualityProfiles({ projectKey })]).then(responses => { + const [allProfiles, projectProfiles] = responses; + dispatch(receiveProfiles(allProfiles)); + dispatch(receiveProjectProfiles(projectKey, projectProfiles)); + }); + }; export const SET_PROJECT_PROFILE = 'projectAdmin/SET_PROJECT_PROFILE'; const setProjectProfileAction = (projectKey, oldProfileKey, newProfileKey) => ({ @@ -63,21 +65,25 @@ const setProjectProfileAction = (projectKey, oldProfileKey, newProfileKey) => ({ }); export const setProjectProfile = (projectKey, oldKey, newKey) => - (dispatch, getState) => { - const state = getState(); - const newProfile = getProjectAdminProfileByKey(state, newKey); - const request = newProfile.isDefault ? - dissociateProject(oldKey, projectKey) : - associateProject(newKey, projectKey); - - request.then(() => { - dispatch(setProjectProfileAction(projectKey, oldKey, newKey)); - dispatch(addGlobalSuccessMessage( + (dispatch, getState) => { + const state = getState(); + const newProfile = getProjectAdminProfileByKey(state, newKey); + const request = newProfile.isDefault + ? dissociateProject(oldKey, projectKey) + : associateProject(newKey, projectKey); + + request.then(() => { + dispatch(setProjectProfileAction(projectKey, oldKey, newKey)); + dispatch( + addGlobalSuccessMessage( translateWithParameters( 'project_quality_profile.successfully_updated', - newProfile.languageName))); - }); - }; + newProfile.languageName + ) + ) + ); + }); + }; export const RECEIVE_GATES = 'projectAdmin/RECEIVE_GATES'; export const receiveGates = gates => ({ @@ -92,16 +98,14 @@ export const receiveProjectGate = (projectKey, gate) => ({ gate }); -export const fetchProjectGate = projectKey => dispatch => { - Promise.all([ - fetchQualityGates(), - getGateForProject(projectKey) - ]).then(responses => { - const [allGates, projectGate] = responses; - dispatch(receiveGates(allGates)); - dispatch(receiveProjectGate(projectKey, projectGate)); - }); -}; +export const fetchProjectGate = projectKey => + dispatch => { + Promise.all([fetchQualityGates(), getGateForProject(projectKey)]).then(responses => { + const [allGates, projectGate] = responses; + dispatch(receiveGates(allGates)); + dispatch(receiveProjectGate(projectKey, projectGate)); + }); + }; export const SET_PROJECT_GATE = 'projectAdmin/SET_PROJECT_GATE'; const setProjectGateAction = (projectKey, gateId) => ({ @@ -110,17 +114,17 @@ const setProjectGateAction = (projectKey, gateId) => ({ gateId }); -export const setProjectGate = (projectKey, oldId, newId) => dispatch => { - const request = newId != null ? - associateGateWithProject(newId, projectKey) : - dissociateGateWithProject(oldId, projectKey); +export const setProjectGate = (projectKey, oldId, newId) => + dispatch => { + const request = newId != null + ? associateGateWithProject(newId, projectKey) + : dissociateGateWithProject(oldId, projectKey); - request.then(() => { - dispatch(setProjectGateAction(projectKey, newId)); - dispatch(addGlobalSuccessMessage( - translate('project_quality_gate.successfully_updated'))); - }); -}; + request.then(() => { + dispatch(setProjectGateAction(projectKey, newId)); + dispatch(addGlobalSuccessMessage(translate('project_quality_gate.successfully_updated'))); + }); + }; export const RECEIVE_PROJECT_LINKS = 'projectAdmin/RECEIVE_PROJECT_LINKS'; export const receiveProjectLinks = (projectKey, links) => ({ @@ -129,11 +133,12 @@ export const receiveProjectLinks = (projectKey, links) => ({ links }); -export const fetchProjectLinks = projectKey => dispatch => { - getProjectLinks(projectKey).then(links => { - dispatch(receiveProjectLinks(projectKey, links)); - }); -}; +export const fetchProjectLinks = projectKey => + dispatch => { + getProjectLinks(projectKey).then(links => { + dispatch(receiveProjectLinks(projectKey, links)); + }); + }; export const ADD_PROJECT_LINK = 'projectAdmin/ADD_PROJECT_LINK'; const addProjectLink = (projectKey, link) => ({ @@ -142,11 +147,12 @@ const addProjectLink = (projectKey, link) => ({ link }); -export const createProjectLink = (projectKey, name, url) => dispatch => { - return createLink(projectKey, name, url).then(link => { - dispatch(addProjectLink(projectKey, link)); - }); -}; +export const createProjectLink = (projectKey, name, url) => + dispatch => { + return createLink(projectKey, name, url).then(link => { + dispatch(addProjectLink(projectKey, link)); + }); + }; export const DELETE_PROJECT_LINK = 'projectAdmin/DELETE_PROJECT_LINK'; export const deleteProjectLink = (projectKey, linkId) => ({ @@ -162,12 +168,13 @@ const receiveProjectModules = (projectKey, modules) => ({ modules }); -export const fetchProjectModules = projectKey => dispatch => { - const options = { qualifiers: 'BRC', s: 'name', ps: 500 }; - getTree(projectKey, options).then(r => { - dispatch(receiveProjectModules(projectKey, r.components)); - }); -}; +export const fetchProjectModules = projectKey => + dispatch => { + const options = { qualifiers: 'BRC', s: 'name', ps: 500 }; + getTree(projectKey, options).then(r => { + dispatch(receiveProjectModules(projectKey, r.components)); + }); + }; export const CHANGE_KEY = 'projectAdmin/CHANGE_KEY'; const changeKeyAction = (key, newKey) => ({ @@ -176,7 +183,7 @@ const changeKeyAction = (key, newKey) => ({ newKey }); -export const changeKey = (key, newKey) => dispatch => { - return changeKeyApi(key, newKey) - .then(() => dispatch(changeKeyAction(key, newKey))); -}; +export const changeKey = (key, newKey) => + dispatch => { + return changeKeyApi(key, newKey).then(() => dispatch(changeKeyAction(key, newKey))); + }; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/components.js b/server/sonar-web/src/main/js/apps/project-admin/store/components.js index 8b0431c0aac..59f53b674b0 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/components.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/components.js @@ -43,5 +43,4 @@ const components = (state = {}, action = {}) => { export default components; -export const getComponentByKey = (state, key) => - state[key]; +export const getComponentByKey = (state, key) => state[key]; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/gateByProject.js b/server/sonar-web/src/main/js/apps/project-admin/store/gateByProject.js index 60e59da62cb..451f531d1ca 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/gateByProject.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/gateByProject.js @@ -34,5 +34,4 @@ const gateByProject = (state = {}, action = {}) => { export default gateByProject; -export const getProjectGate = (state, projectKey) => - state[projectKey]; +export const getProjectGate = (state, projectKey) => state[projectKey]; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/gates.js b/server/sonar-web/src/main/js/apps/project-admin/store/gates.js index 6ae23e59536..319b8ac3f36 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/gates.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/gates.js @@ -32,8 +32,6 @@ const gates = (state = {}, action = {}) => { export default gates; -export const getAllGates = state => - values(state); +export const getAllGates = state => values(state); -export const getGate = (state, id) => - state[id]; +export const getGate = (state, id) => state[id]; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/links.js b/server/sonar-web/src/main/js/apps/project-admin/store/links.js index 21ed90621eb..1f5bc45b153 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/links.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/links.js @@ -40,5 +40,4 @@ const links = (state = {}, action = {}) => { export default links; -export const getLink = (state, id) => - state[id]; +export const getLink = (state, id) => state[id]; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js b/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js index 0a0cc65537a..54413eeb56e 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/linksByProject.js @@ -18,11 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import without from 'lodash/without'; -import { - RECEIVE_PROJECT_LINKS, - DELETE_PROJECT_LINK, - ADD_PROJECT_LINK -} from './actions'; +import { RECEIVE_PROJECT_LINKS, DELETE_PROJECT_LINK, ADD_PROJECT_LINK } from './actions'; const linksByProject = (state = {}, action = {}) => { if (action.type === RECEIVE_PROJECT_LINKS) { diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js b/server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js index f5bd74e80d1..98229cc4076 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/modulesByProject.js @@ -46,5 +46,4 @@ const modulesByProject = (state = {}, action = {}) => { export default modulesByProject; -export const getProjectModules = (state, projectKey) => - state[projectKey]; +export const getProjectModules = (state, projectKey) => state[projectKey]; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js b/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js index a9d1bc650cc..01302f946c7 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/profiles.js @@ -32,8 +32,6 @@ const profiles = (state = {}, action = {}) => { export default profiles; -export const getAllProfiles = state => - values(state); +export const getAllProfiles = state => values(state); -export const getProfile = (state, key) => - state[key]; +export const getProfile = (state, key) => state[key]; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js b/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js index 3079d15d0d4..3eed6b11561 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/profilesByProject.js @@ -28,10 +28,7 @@ const profilesByProject = (state = {}, action = {}) => { if (action.type === SET_PROJECT_PROFILE) { const profileKeys = state[action.projectKey]; - const nextProfileKeys = [ - ...without(profileKeys, action.oldProfileKey), - action.newProfileKey - ]; + const nextProfileKeys = [...without(profileKeys, action.oldProfileKey), action.newProfileKey]; return { ...state, [action.projectKey]: nextProfileKeys }; } @@ -40,5 +37,4 @@ const profilesByProject = (state = {}, action = {}) => { export default profilesByProject; -export const getProfiles = (state, projectKey) => - state[projectKey] || []; +export const getProfiles = (state, projectKey) => state[projectKey] || []; diff --git a/server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js b/server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js index 721d3accfc6..fabf41003ec 100644 --- a/server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js +++ b/server/sonar-web/src/main/js/apps/project-admin/store/rootReducer.js @@ -18,23 +18,16 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { combineReducers } from 'redux'; -import profiles, { - getProfile, - getAllProfiles as nextGetAllProfiles -} from './profiles'; +import profiles, { getProfile, getAllProfiles as nextGetAllProfiles } from './profiles'; import profilesByProject, { getProfiles } from './profilesByProject'; import gates, { getAllGates as nextGetAllGates, getGate } from './gates'; import gateByProject, { getProjectGate as nextGetProjectGate } from './gateByProject'; import links, { getLink } from './links'; import linksByProject, { getLinks } from './linksByProject'; -import components, { - getComponentByKey as nextGetComponentByKey -} from './components'; -import modulesByProject, { - getProjectModules as nextGetProjectModules -} from './modulesByProject'; +import components, { getComponentByKey as nextGetComponentByKey } from './components'; +import modulesByProject, { getProjectModules as nextGetProjectModules } from './modulesByProject'; import globalMessages, { - getGlobalMessages as nextGetGlobalMessages + getGlobalMessages as nextGetGlobalMessages } from '../../../store/globalMessages/duck'; const rootReducer = combineReducers({ @@ -51,34 +44,28 @@ const rootReducer = combineReducers({ export default rootReducer; -export const getProfileByKey = (state, profileKey) => - getProfile(state.profiles, profileKey); +export const getProfileByKey = (state, profileKey) => getProfile(state.profiles, profileKey); -export const getAllProfiles = state => - nextGetAllProfiles(state.profiles); +export const getAllProfiles = state => nextGetAllProfiles(state.profiles); export const getProjectProfiles = (state, projectKey) => - getProfiles(state.profilesByProject, projectKey) - .map(profileKey => getProfileByKey(state, profileKey)); + getProfiles(state.profilesByProject, projectKey).map(profileKey => + getProfileByKey(state, profileKey)); -export const getGateById = (state, gateId) => - getGate(state.gates, gateId); +export const getGateById = (state, gateId) => getGate(state.gates, gateId); -export const getAllGates = state => - nextGetAllGates(state.gates); +export const getAllGates = state => nextGetAllGates(state.gates); export const getProjectGate = (state, projectKey) => - getGateById(state, nextGetProjectGate(state.gateByProject, projectKey)); + getGateById(state, nextGetProjectGate(state.gateByProject, projectKey)); -export const getLinkById = (state, linkId) => - getLink(state.links, linkId); +export const getLinkById = (state, linkId) => getLink(state.links, linkId); export const getProjectLinks = (state, projectKey) => - getLinks(state.linksByProject, projectKey) - .map(linkId => getLinkById(state, linkId)); + getLinks(state.linksByProject, projectKey).map(linkId => getLinkById(state, linkId)); export const getComponentByKey = (state, componentKey) => - nextGetComponentByKey(state.components, componentKey); + nextGetComponentByKey(state.components, componentKey); export const getProjectModules = (state, projectKey) => { const moduleKeys = nextGetProjectModules(state.modulesByProject, projectKey); @@ -88,5 +75,4 @@ export const getProjectModules = (state, projectKey) => { return moduleKeys.map(moduleKey => getComponentByKey(state, moduleKey)); }; -export const getGlobalMessages = state => - nextGetGlobalMessages(state.globalMessages); +export const getGlobalMessages = state => nextGetGlobalMessages(state.globalMessages); diff --git a/server/sonar-web/src/main/js/apps/projectActivity/actions.js b/server/sonar-web/src/main/js/apps/projectActivity/actions.js index ed8971d762d..8b1851e6959 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/actions.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/actions.js @@ -30,58 +30,67 @@ import { import { onFail } from '../../store/rootActions'; import { getProjectActivity } from '../../store/rootReducer'; -const rejectOnFail = (dispatch: Function) => (error: Object) => { - onFail(dispatch)(error); - return Promise.reject(); -}; +const rejectOnFail = (dispatch: Function) => + (error: Object) => { + onFail(dispatch)(error); + return Promise.reject(); + }; -export const fetchProjectActivity = (project: string, filter: ?string) => (dispatch: Function): void => { - api.getProjectActivity(project, { category: filter }).then( - ({ analyses, paging }) => dispatch(receiveProjectActivity(project, analyses, paging)), - onFail(dispatch) - ); -}; +export const fetchProjectActivity = (project: string, filter: ?string) => + (dispatch: Function): void => { + api + .getProjectActivity(project, { category: filter }) + .then( + ({ analyses, paging }) => dispatch(receiveProjectActivity(project, analyses, paging)), + onFail(dispatch) + ); + }; export const fetchMoreProjectActivity = (project: string, filter: ?string) => - (dispatch: Function, getState: Function): void => { - const projectActivity = getProjectActivity(getState()); - const { pageIndex } = getPaging(projectActivity, project); + (dispatch: Function, getState: Function): void => { + const projectActivity = getProjectActivity(getState()); + const { pageIndex } = getPaging(projectActivity, project); - api.getProjectActivity(project, { category: filter, pageIndex: pageIndex + 1 }).then( + api + .getProjectActivity(project, { category: filter, pageIndex: pageIndex + 1 }) + .then( ({ analyses, paging }) => dispatch(receiveProjectActivity(project, analyses, paging)), onFail(dispatch) ); - }; + }; export const addCustomEvent = (analysis: string, name: string, category?: string) => - (dispatch: Function): Promise<*> => { - return api.createEvent(analysis, name, category).then( + (dispatch: Function): Promise<*> => { + return api + .createEvent(analysis, name, category) + .then( ({ analysis, ...event }) => dispatch(addEvent(analysis, event)), rejectOnFail(dispatch) ); - }; + }; -export const deleteEvent = (analysis: string, event: string) => (dispatch: Function): Promise<*> => { - return api.deleteEvent(event).then( - () => dispatch(deleteEventAction(analysis, event)), - rejectOnFail(dispatch) - ); -}; +export const deleteEvent = (analysis: string, event: string) => + (dispatch: Function): Promise<*> => { + return api + .deleteEvent(event) + .then(() => dispatch(deleteEventAction(analysis, event)), rejectOnFail(dispatch)); + }; -export const addVersion = (analysis: string, version: string) => (dispatch: Function): Promise<*> => { - return dispatch(addCustomEvent(analysis, version, 'VERSION')); -}; +export const addVersion = (analysis: string, version: string) => + (dispatch: Function): Promise<*> => { + return dispatch(addCustomEvent(analysis, version, 'VERSION')); + }; -export const changeEvent = (event: string, name: string) => (dispatch: Function): Promise<*> => { - return api.changeEvent(event, name).then( - () => dispatch(changeEventAction(event, { name })), - rejectOnFail(dispatch) - ); -}; +export const changeEvent = (event: string, name: string) => + (dispatch: Function): Promise<*> => { + return api + .changeEvent(event, name) + .then(() => dispatch(changeEventAction(event, { name })), rejectOnFail(dispatch)); + }; -export const deleteAnalysis = (project: string, analysis: string) => (dispatch: Function): Promise<*> => { - return api.deleteAnalysis(analysis).then( - () => dispatch(deleteAnalysisAction(project, analysis)), - rejectOnFail(dispatch) - ); -}; +export const deleteAnalysis = (project: string, analysis: string) => + (dispatch: Function): Promise<*> => { + return api + .deleteAnalysis(analysis) + .then(() => dispatch(deleteAnalysisAction(project, analysis)), rejectOnFail(dispatch)); + }; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ChangeIcon.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ChangeIcon.js index 866906bc5dc..c2593893c77 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ChangeIcon.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ChangeIcon.js @@ -21,13 +21,15 @@ import React from 'react'; export default class ChangeIcon extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg width="12" height="12" viewBox="0 0 14 14"> - <path fill="#236a97" - d="M3.35 12.82l.85-.84L2.02 9.8l-.84.85v.98h1.2v1.2h.97zM8.2 4.24c0-.13-.08-.2-.22-.2-.06 0-.1.02-.15.06l-5 5c-.05.05-.08.1-.08.17 0 .13.07.2.2.2.07 0 .12-.02.16-.06l5.02-5c.05-.04.07-.1.07-.16zm-.5-1.77l3.83 3.84-7.7 7.7H0v-3.84l7.7-7.7zm6.3.88c0 .33-.1.6-.34.84L12.12 5.7 8.28 1.88 9.8.35c.24-.23.5-.35.85-.35.32 0 .6.12.84.35l2.16 2.16c.23.25.34.53.34.85z"/> - </svg> + <svg width="12" height="12" viewBox="0 0 14 14"> + <path + fill="#236a97" + d="M3.35 12.82l.85-.84L2.02 9.8l-.84.85v.98h1.2v1.2h.97zM8.2 4.24c0-.13-.08-.2-.22-.2-.06 0-.1.02-.15.06l-5 5c-.05.05-.08.1-.08.17 0 .13.07.2.2.2.07 0 .12-.02.16-.06l5.02-5c.05-.04.07-.1.07-.16zm-.5-1.77l3.83 3.84-7.7 7.7H0v-3.84l7.7-7.7zm6.3.88c0 .33-.1.6-.34.84L12.12 5.7 8.28 1.88 9.8.35c.24-.23.5-.35.85-.35.32 0 .6.12.84.35l2.16 2.16c.23.25.34.53.34.85z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/DeleteIcon.js b/server/sonar-web/src/main/js/apps/projectActivity/components/DeleteIcon.js index 855ea898341..ddea41d70bb 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/DeleteIcon.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/DeleteIcon.js @@ -21,13 +21,15 @@ import React from 'react'; export default class DeleteIcon extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg width="12" height="12" viewBox="0 0 14 14"> - <path fill="#d4333f" - d="M14 11.27c0 .3-.1.58-.33.8l-1.6 1.6c-.22.22-.5.33-.8.33-.32 0-.6-.1-.8-.33L7 10.2l-3.46 3.47c-.22.22-.5.33-.8.33-.32 0-.6-.1-.8-.33l-1.6-1.6c-.23-.22-.34-.5-.34-.8 0-.32.1-.6.33-.8L3.8 7 .32 3.54C.1 3.32 0 3.04 0 2.74c0-.32.1-.6.33-.8l1.6-1.6c.22-.23.5-.34.8-.34.32 0 .6.1.8.33L7 3.8 10.46.32c.22-.22.5-.33.8-.33.32 0 .6.1.8.33l1.6 1.6c.23.22.34.5.34.8 0 .32-.1.6-.33.8L10.2 7l3.47 3.46c.22.22.33.5.33.8z"/> - </svg> + <svg width="12" height="12" viewBox="0 0 14 14"> + <path + fill="#d4333f" + d="M14 11.27c0 .3-.1.58-.33.8l-1.6 1.6c-.22.22-.5.33-.8.33-.32 0-.6-.1-.8-.33L7 10.2l-3.46 3.47c-.22.22-.5.33-.8.33-.32 0-.6-.1-.8-.33l-1.6-1.6c-.23-.22-.34-.5-.34-.8 0-.32.1-.6.33-.8L3.8 7 .32 3.54C.1 3.32 0 3.04 0 2.74c0-.32.1-.6.33-.8l1.6-1.6c.22-.23.5-.34.8-.34.32 0 .6.1.8.33L7 3.8 10.46.32c.22-.22.5-.33.8-.33.32 0 .6.1.8.33l1.6 1.6c.23.22.34.5.34.8 0 .32-.1.6-.33.8L10.2 7l3.47 3.46c.22.22.33.5.33.8z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/Event.js b/server/sonar-web/src/main/js/apps/projectActivity/components/Event.js index bfce7925021..a604e60ae26 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/Event.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/Event.js @@ -47,11 +47,11 @@ export default class Event extends React.Component { deleting: false }; - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -75,44 +75,39 @@ export default class Event extends React.Component { } }; - render () { + render() { const { event, canAdmin } = this.props; const canChange = ['OTHER', 'VERSION'].includes(event.category); - const canDelete = event.category === 'OTHER' || (event.category === 'VERSION' && !this.props.isFirst); + const canDelete = event.category === 'OTHER' || + (event.category === 'VERSION' && !this.props.isFirst); const showActions = canAdmin && (canChange || canDelete); return ( - <div className="project-activity-event"> - <EventInner event={this.props.event}/> + <div className="project-activity-event"> + <EventInner event={this.props.event} /> - {showActions && ( - <div className="project-activity-event-actions"> - {canChange && ( - <button className="js-change-event button-clean" onClick={this.startChanging}> - <ChangeIcon/> - </button> - )} - {canDelete && ( - <button className="js-delete-event button-clean" onClick={this.startDeleting}> - <DeleteIcon/> - </button> - )} - </div> - )} + {showActions && + <div className="project-activity-event-actions"> + {canChange && + <button className="js-change-event button-clean" onClick={this.startChanging}> + <ChangeIcon /> + </button>} + {canDelete && + <button className="js-delete-event button-clean" onClick={this.startDeleting}> + <DeleteIcon /> + </button>} + </div>} - {this.state.changing && ( - <ChangeCustomEventForm - event={this.props.event} - onClose={this.stopChanging}/> - )} + {this.state.changing && + <ChangeCustomEventForm event={this.props.event} onClose={this.stopChanging} />} - {this.state.deleting && ( - <RemoveCustomEventForm - analysis={this.props.analysis} - event={this.props.event} - onClose={this.stopDeleting}/> - )} - </div> + {this.state.deleting && + <RemoveCustomEventForm + analysis={this.props.analysis} + event={this.props.event} + onClose={this.stopDeleting} + />} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/EventInner.js b/server/sonar-web/src/main/js/apps/projectActivity/components/EventInner.js index a0b91e5f07b..b133876e44b 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/EventInner.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/EventInner.js @@ -29,23 +29,21 @@ export default class EventInner extends React.Component { event: EventType }; - render () { + render() { const { event } = this.props; if (event.category === 'VERSION') { - return ( - <span className="badge project-activity-version-badge">{this.props.event.name}</span> - ); + return <span className="badge project-activity-version-badge">{this.props.event.name}</span>; } return ( - <TooltipsContainer> - <span> - <span className="note">{translate('event.category', event.category)}:</span> - {' '} - <strong title={event.description} data-toggle="tooltip">{event.name}</strong> - </span> - </TooltipsContainer> + <TooltipsContainer> + <span> + <span className="note">{translate('event.category', event.category)}:</span> + {' '} + <strong title={event.description} data-toggle="tooltip">{event.name}</strong> + </span> + </TooltipsContainer> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js b/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js index d2b5eb0b0c5..18a48fbfc23 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/Events.js @@ -31,26 +31,27 @@ export default class Events extends React.Component { canAdmin: boolean }; - render () { + render() { const sortedEvents: Array<EventType> = sortBy( this.props.events, - // versions first + // versions first (event: EventType) => event.category === 'VERSION' ? 0 : 1, - // then the rest sorted by category + // then the rest sorted by category 'category' ); return ( - <div className="project-activity-events"> - {sortedEvents.map(event => ( - <Event - key={event.key} - analysis={this.props.analysis} - event={event} - isFirst={this.props.isFirst} - canAdmin={this.props.canAdmin}/> - ))} - </div> + <div className="project-activity-events"> + {sortedEvents.map(event => ( + <Event + key={event.key} + analysis={this.props.analysis} + event={event} + isFirst={this.props.isFirst} + canAdmin={this.props.canAdmin} + /> + ))} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js index 4ff9fe2efaa..60989c83a47 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js @@ -38,44 +38,48 @@ class ProjectActivityAnalysesList extends React.Component { canAdmin: boolean }; - render () { + render() { if (!this.props.analyses) { return null; } if (this.props.analyses.length === 0) { - return ( - <div className="note">{translate('no_results')}</div> - ); + return <div className="note">{translate('no_results')}</div>; } const firstAnalysis = this.props.analyses[0]; - const byDay = groupBy(this.props.analyses, analysis => moment(analysis.date).startOf('day').valueOf()); + const byDay = groupBy(this.props.analyses, analysis => + moment(analysis.date).startOf('day').valueOf()); return ( - <div className="boxed-group boxed-group-inner"> - <ul className="project-activity-days-list"> - {Object.keys(byDay).map(day => ( - <li key={day} className="project-activity-day" data-day={moment(Number(day)).format('YYYY-MM-DD')}> - <div className="project-activity-date"> - <FormattedDate date={Number(day)} format="LL"/> - </div> + <div className="boxed-group boxed-group-inner"> + <ul className="project-activity-days-list"> + {Object.keys(byDay).map(day => ( + <li + key={day} + className="project-activity-day" + data-day={moment(Number(day)).format('YYYY-MM-DD')} + > + <div className="project-activity-date"> + <FormattedDate date={Number(day)} format="LL" /> + </div> - <ul className="project-activity-analyses-list"> - {byDay[day].map(analysis => ( - <ProjectActivityAnalysis - key={analysis.key} - analysis={analysis} - isFirst={analysis === firstAnalysis} - project={this.props.project} - canAdmin={this.props.canAdmin}/> - ))} - </ul> - </li> - ))} - </ul> - </div> + <ul className="project-activity-analyses-list"> + {byDay[day].map(analysis => ( + <ProjectActivityAnalysis + key={analysis.key} + analysis={analysis} + isFirst={analysis === firstAnalysis} + project={this.props.project} + canAdmin={this.props.canAdmin} + /> + ))} + </ul> + </li> + ))} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js index faaacb0eb51..019047c157b 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysis.js @@ -35,54 +35,49 @@ export default class ProjectActivityAnalysis extends React.Component { canAdmin: boolean }; - render () { + render() { const { date, events } = this.props.analysis; const { isFirst, canAdmin } = this.props; const version = events.find(event => event.category === 'VERSION'); return ( - <li className="project-activity-analysis clearfix"> - {canAdmin && ( - <div className="project-activity-analysis-actions"> - <div className="dropdown display-inline-block"> - <button className="js-create button-small" data-toggle="dropdown"> - {translate('create')} <i className="icon-dropdown"/> - </button> - <ul className="dropdown-menu dropdown-menu-right"> - {version == null && ( - <li> - <AddVersionForm analysis={this.props.analysis}/> - </li> - )} - <li> - <AddCustomEventForm analysis={this.props.analysis}/> - </li> - </ul> - </div> + <li className="project-activity-analysis clearfix"> + {canAdmin && + <div className="project-activity-analysis-actions"> + <div className="dropdown display-inline-block"> + <button className="js-create button-small" data-toggle="dropdown"> + {translate('create')} <i className="icon-dropdown" /> + </button> + <ul className="dropdown-menu dropdown-menu-right"> + {version == null && + <li> + <AddVersionForm analysis={this.props.analysis} /> + </li>} + <li> + <AddCustomEventForm analysis={this.props.analysis} /> + </li> + </ul> + </div> - {!isFirst && ( - <div className="display-inline-block little-spacer-left"> - <RemoveAnalysisForm - analysis={this.props.analysis} - project={this.props.project}/> - </div> - )} - </div> - )} + {!isFirst && + <div className="display-inline-block little-spacer-left"> + <RemoveAnalysisForm analysis={this.props.analysis} project={this.props.project} /> + </div>} + </div>} - <div className="project-activity-time"> - <FormattedDate date={date} format="LT" tooltipFormat="LTS"/> - </div> + <div className="project-activity-time"> + <FormattedDate date={date} format="LT" tooltipFormat="LTS" /> + </div> - {events.length > 0 && ( - <Events - analysis={this.props.analysis.key} - events={events} - isFirst={this.props.isFirst} - canAdmin={canAdmin}/> - )} - </li> + {events.length > 0 && + <Events + analysis={this.props.analysis.key} + events={events} + isFirst={this.props.isFirst} + canAdmin={canAdmin} + />} + </li> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js index 7c92934c10f..eb1a476b2c6 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js @@ -44,12 +44,12 @@ class ProjectActivityApp extends React.Component { filter: null }; - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); this.props.fetchProjectActivity(this.props.location.query.id); } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } @@ -58,25 +58,23 @@ class ProjectActivityApp extends React.Component { this.props.fetchProjectActivity(this.props.location.query.id, filter); }; - render () { + render() { const project = this.props.location.query.id; const { configuration } = this.props.project; const canAdmin = configuration ? configuration.showHistory : false; return ( - <div id="project-activity" className="page page-limited"> - <ProjectActivityPageHeader - project={project} - filter={this.state.filter} - changeFilter={this.handleFilter}/> + <div id="project-activity" className="page page-limited"> + <ProjectActivityPageHeader + project={project} + filter={this.state.filter} + changeFilter={this.handleFilter} + /> - <ProjectActivityAnalysesList - project={project} - canAdmin={canAdmin}/> + <ProjectActivityAnalysesList project={project} canAdmin={canAdmin} /> - <ProjectActivityPageFooter - project={project}/> - </div> + <ProjectActivityPageFooter project={project} /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFooter.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFooter.js index 1a13ac51604..a1d8b47b9de 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFooter.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFooter.js @@ -38,7 +38,7 @@ class ProjectActivityPageFooter extends React.Component { this.props.fetchMoreProjectActivity(this.props.project); }; - render () { + render() { const { analyses, paging } = this.props; if (!paging || analyses.length === 0) { @@ -46,7 +46,7 @@ class ProjectActivityPageFooter extends React.Component { } return ( - <ListFooter count={analyses.length} total={paging.total} loadMore={this.handleLoadMore}/> + <ListFooter count={analyses.length} total={paging.total} loadMore={this.handleLoadMore} /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.js index dc84d22e328..fd30a408880 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.js @@ -32,31 +32,31 @@ export default class ProjectActivityPageHeader extends React.Component { handleChange = (option: null | { value: string }) => { this.props.changeFilter(option && option.value); - } - - render () { + }; + render() { const selectOptions = ['VERSION', 'QUALITY_GATE', 'QUALITY_PROFILE', 'OTHER'].map(category => ({ label: translate('event.category', category), value: category })); return ( - <header className="page-header"> - <div className="page-actions"> - <Select - className="input-medium" - placeholder={translate('filter_verb') + '...'} - clearable={true} - searchable={false} - value={this.props.filter} - options={selectOptions} - onChange={this.handleChange}/> - </div> + <header className="page-header"> + <div className="page-actions"> + <Select + className="input-medium" + placeholder={translate('filter_verb') + '...'} + clearable={true} + searchable={false} + value={this.props.filter} + options={selectOptions} + onChange={this.handleChange} + /> + </div> - <div className="page-description"> - {translate('project_activity.page.description')} - </div> - </header> + <div className="page-description"> + {translate('project_activity.page.description')} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddCustomEventForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddCustomEventForm.js index a25e1e4681b..c7da027a6bb 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddCustomEventForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddCustomEventForm.js @@ -24,7 +24,7 @@ import { addCustomEvent } from '../../actions'; import AddEventForm from './AddEventForm'; const AddCustomEventForm = props => ( - <AddEventForm {...props} addEventButtonText="project_activity.add_custom_event"/> + <AddEventForm {...props} addEventButtonText="project_activity.add_custom_event" /> ); const mapStateToProps = null; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js index 3300757e5ca..af57cdd3131 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddEventForm.js @@ -45,11 +45,11 @@ export default class AddEventForm extends React.Component { name: '' }; - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -87,60 +87,62 @@ export default class AddEventForm extends React.Component { handleSubmit = (e: Object) => { e.preventDefault(); this.setState({ processing: true }); - this.props.addEvent(this.props.analysis.key, this.state.name) - .then(this.stopProcessingAndClose, this.stopProcessing); + this.props + .addEvent(this.props.analysis.key, this.state.name) + .then(this.stopProcessingAndClose, this.stopProcessing); }; - renderModal () { + renderModal() { return ( - <Modal isOpen={true} - contentLabel="modal form" - className="modal" - overlayClassName="modal-overlay" - onRequestClose={this.closeForm}> - - <header className="modal-head"> - <h2>{translate(this.props.addEventButtonText)}</h2> - </header> - - <form onSubmit={this.handleSubmit}> - <div className="modal-body"> - <div className="modal-field"> - <label>{translate('name')}</label> - <input - value={this.state.name} - autoFocus={true} - disabled={this.state.processing} - className="input-medium" - type="text" - onChange={this.changeInput}/> - </div> + <Modal + isOpen={true} + contentLabel="modal form" + className="modal" + overlayClassName="modal-overlay" + onRequestClose={this.closeForm} + > + + <header className="modal-head"> + <h2>{translate(this.props.addEventButtonText)}</h2> + </header> + + <form onSubmit={this.handleSubmit}> + <div className="modal-body"> + <div className="modal-field"> + <label>{translate('name')}</label> + <input + value={this.state.name} + autoFocus={true} + disabled={this.state.processing} + className="input-medium" + type="text" + onChange={this.changeInput} + /> </div> - - <footer className="modal-foot"> - {this.state.processing ? ( - <i className="spinner"/> - ) : ( - <div> - <button type="submit">{translate('save')}</button> - <button type="reset" className="button-link" onClick={this.closeForm}> - {translate('cancel')} - </button> - </div> - )} - </footer> - </form> - - </Modal> + </div> + + <footer className="modal-foot"> + {this.state.processing + ? <i className="spinner" /> + : <div> + <button type="submit">{translate('save')}</button> + <button type="reset" className="button-link" onClick={this.closeForm}> + {translate('cancel')} + </button> + </div>} + </footer> + </form> + + </Modal> ); } - render () { + render() { return ( - <a className="js-add-event button-small" href="#" onClick={this.openForm}> - {translate(this.props.addEventButtonText)} - {this.state.open && this.renderModal()} - </a> + <a className="js-add-event button-small" href="#" onClick={this.openForm}> + {translate(this.props.addEventButtonText)} + {this.state.open && this.renderModal()} + </a> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddVersionForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddVersionForm.js index 5b05319fa06..423a538b506 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddVersionForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddVersionForm.js @@ -24,7 +24,7 @@ import { addVersion } from '../../actions'; import AddEventForm from './AddEventForm'; const AddVersionForm = props => ( - <AddEventForm {...props} addEventButtonText="project_activity.add_version"/> + <AddEventForm {...props} addEventButtonText="project_activity.add_version" /> ); const mapStateToProps = null; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeCustomEventForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeCustomEventForm.js index fcdda142ba8..a05895d37b0 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeCustomEventForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeCustomEventForm.js @@ -24,9 +24,7 @@ import ChangeEventForm from './ChangeEventForm'; import { changeEvent } from '../../actions'; const ChangeCustomEventForm = props => ( - <ChangeEventForm - {...props} - changeEventButtonText="project_activity.change_custom_event"/> + <ChangeEventForm {...props} changeEventButtonText="project_activity.change_custom_event" /> ); const mapStateToProps = null; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeEventForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeEventForm.js index f693752efcb..a85e6547b8c 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeEventForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeEventForm.js @@ -40,7 +40,7 @@ export default class ChangeEventForm extends React.Component { props: Props; state: State; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = { processing: false, @@ -48,11 +48,11 @@ export default class ChangeEventForm extends React.Component { }; } - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -85,51 +85,53 @@ export default class ChangeEventForm extends React.Component { handleSubmit = (e: Object) => { e.preventDefault(); this.setState({ processing: true }); - this.props.changeEvent(this.props.event.key, this.state.name) - .then(this.stopProcessingAndClose, this.stopProcessing); + this.props + .changeEvent(this.props.event.key, this.state.name) + .then(this.stopProcessingAndClose, this.stopProcessing); }; - render () { + render() { return ( - <Modal isOpen={true} - contentLabel="modal form" - className="modal" - overlayClassName="modal-overlay" - onRequestClose={this.closeForm}> - - <header className="modal-head"> - <h2>{translate(this.props.changeEventButtonText)}</h2> - </header> - - <form onSubmit={this.handleSubmit}> - <div className="modal-body"> - <div className="modal-field"> - <label>{translate('name')}</label> - <input - value={this.state.name} - autoFocus={true} - disabled={this.state.processing} - className="input-medium" - type="text" - onChange={this.changeInput}/> - </div> + <Modal + isOpen={true} + contentLabel="modal form" + className="modal" + overlayClassName="modal-overlay" + onRequestClose={this.closeForm} + > + + <header className="modal-head"> + <h2>{translate(this.props.changeEventButtonText)}</h2> + </header> + + <form onSubmit={this.handleSubmit}> + <div className="modal-body"> + <div className="modal-field"> + <label>{translate('name')}</label> + <input + value={this.state.name} + autoFocus={true} + disabled={this.state.processing} + className="input-medium" + type="text" + onChange={this.changeInput} + /> </div> - - <footer className="modal-foot"> - {this.state.processing ? ( - <i className="spinner"/> - ) : ( - <div> - <button type="submit">{translate('change_verb')}</button> - <button type="reset" className="button-link" onClick={this.closeForm}> - {translate('cancel')} - </button> - </div> - )} - </footer> - </form> - - </Modal> + </div> + + <footer className="modal-foot"> + {this.state.processing + ? <i className="spinner" /> + : <div> + <button type="submit">{translate('change_verb')}</button> + <button type="reset" className="button-link" onClick={this.closeForm}> + {translate('cancel')} + </button> + </div>} + </footer> + </form> + + </Modal> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeVersionForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeVersionForm.js index 5df29b8a6c4..50abf9ae8a9 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeVersionForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/ChangeVersionForm.js @@ -24,9 +24,7 @@ import ChangeEventForm from './ChangeEventForm'; import { changeEvent } from '../../actions'; const ChangeVersionForm = props => ( - <ChangeEventForm - {...props} - changeEventButtonText="project_activity.change_version"/> + <ChangeEventForm {...props} changeEventButtonText="project_activity.change_version" /> ); const mapStateToProps = null; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveAnalysisForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveAnalysisForm.js index e0f67adc502..b3f42d2db18 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveAnalysisForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveAnalysisForm.js @@ -45,11 +45,11 @@ class RemoveAnalysisForm extends React.Component { processing: false }; - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -80,51 +80,52 @@ class RemoveAnalysisForm extends React.Component { handleSubmit = (e: Object) => { e.preventDefault(); this.setState({ processing: true }); - this.props.deleteAnalysis(this.props.project, this.props.analysis.key) - .then(this.stopProcessingAndClose, this.stopProcessing); + this.props + .deleteAnalysis(this.props.project, this.props.analysis.key) + .then(this.stopProcessingAndClose, this.stopProcessing); }; - renderModal () { + renderModal() { return ( - <Modal isOpen={true} - contentLabel="modal form" - className="modal" - overlayClassName="modal-overlay" - onRequestClose={this.closeForm}> - - <header className="modal-head"> - <h2>{translate('project_activity.delete_analysis')}</h2> - </header> - - <form onSubmit={this.handleSubmit}> - <div className="modal-body"> - {translate('project_activity.delete_analysis.question')} - </div> - - <footer className="modal-foot"> - {this.state.processing ? ( - <i className="spinner"/> - ) : ( - <div> - <button type="submit" className="button-red">{translate('delete')}</button> - <button type="reset" className="button-link" onClick={this.closeForm}> - {translate('cancel')} - </button> - </div> - )} - </footer> - </form> - - </Modal> + <Modal + isOpen={true} + contentLabel="modal form" + className="modal" + overlayClassName="modal-overlay" + onRequestClose={this.closeForm} + > + + <header className="modal-head"> + <h2>{translate('project_activity.delete_analysis')}</h2> + </header> + + <form onSubmit={this.handleSubmit}> + <div className="modal-body"> + {translate('project_activity.delete_analysis.question')} + </div> + + <footer className="modal-foot"> + {this.state.processing + ? <i className="spinner" /> + : <div> + <button type="submit" className="button-red">{translate('delete')}</button> + <button type="reset" className="button-link" onClick={this.closeForm}> + {translate('cancel')} + </button> + </div>} + </footer> + </form> + + </Modal> ); } - render () { + render() { return ( - <button className="js-delete-analysis button-small button-red" onClick={this.openForm}> - {translate('delete')} - {this.state.open && this.renderModal()} - </button> + <button className="js-delete-analysis button-small button-red" onClick={this.openForm}> + {translate('delete')} + {this.state.open && this.renderModal()} + </button> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveCustomEventForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveCustomEventForm.js index 057c31d4992..1b97fb0efbf 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveCustomEventForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveCustomEventForm.js @@ -24,10 +24,11 @@ import RemoveEventForm from './RemoveEventForm'; import { deleteEvent } from '../../actions'; const RemoveCustomEventForm = props => ( - <RemoveEventForm - {...props} - removeEventButtonText="project_activity.remove_custom_event" - removeEventQuestion="project_activity.remove_custom_event.question"/> + <RemoveEventForm + {...props} + removeEventButtonText="project_activity.remove_custom_event" + removeEventQuestion="project_activity.remove_custom_event.question" + /> ); const mapStateToProps = null; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveEventForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveEventForm.js index 68aece1d4ce..155af276a76 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveEventForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveEventForm.js @@ -44,11 +44,11 @@ export default class RemoveVersionForm extends React.Component { processing: false }; - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -72,42 +72,45 @@ export default class RemoveVersionForm extends React.Component { handleSubmit = (e: Object) => { e.preventDefault(); this.setState({ processing: true }); - this.props.deleteEvent(this.props.analysis, this.props.event.key) - .then(this.stopProcessingAndClose, this.stopProcessing); + this.props + .deleteEvent(this.props.analysis, this.props.event.key) + .then(this.stopProcessingAndClose, this.stopProcessing); }; - render () { + render() { return ( - <Modal isOpen={true} - contentLabel="modal form" - className="modal" - overlayClassName="modal-overlay" - onRequestClose={this.closeForm}> + <Modal + isOpen={true} + contentLabel="modal form" + className="modal" + overlayClassName="modal-overlay" + onRequestClose={this.closeForm} + > - <header className="modal-head"> - <h2>{translate(this.props.removeEventButtonText)}</h2> - </header> + <header className="modal-head"> + <h2>{translate(this.props.removeEventButtonText)}</h2> + </header> - <form onSubmit={this.handleSubmit}> - <div className="modal-body"> - {translate(this.props.removeEventQuestion)} - </div> + <form onSubmit={this.handleSubmit}> + <div className="modal-body"> + {translate(this.props.removeEventQuestion)} + </div> - <footer className="modal-foot"> - {this.state.processing ? ( - <i className="spinner"/> - ) : ( - <div> - <button type="submit" className="button-red" autoFocus={true}>{translate('delete')}</button> - <button type="reset" className="button-link" onClick={this.closeForm}> - {translate('cancel')} - </button> - </div> - )} - </footer> - </form> + <footer className="modal-foot"> + {this.state.processing + ? <i className="spinner" /> + : <div> + <button type="submit" className="button-red" autoFocus={true}> + {translate('delete')} + </button> + <button type="reset" className="button-link" onClick={this.closeForm}> + {translate('cancel')} + </button> + </div>} + </footer> + </form> - </Modal> + </Modal> ); } } diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveVersionForm.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveVersionForm.js index a75e34fed54..d7c92607bfd 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveVersionForm.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/RemoveVersionForm.js @@ -24,10 +24,11 @@ import RemoveEventForm from './RemoveEventForm'; import { deleteEvent } from '../../actions'; const RemoveVersionForm = props => ( - <RemoveEventForm - {...props} - removeEventButtonText="project_activity.remove_version" - removeEventQuestion="project_activity.remove_version.question"/> + <RemoveEventForm + {...props} + removeEventButtonText="project_activity.remove_version" + removeEventQuestion="project_activity.remove_version.question" + /> ); const mapStateToProps = null; diff --git a/server/sonar-web/src/main/js/apps/projectActivity/routes.js b/server/sonar-web/src/main/js/apps/projectActivity/routes.js index cc2204c018e..5c2042e8395 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/routes.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/routes.js @@ -22,6 +22,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import ProjectActivityApp from './components/ProjectActivityApp'; -export default ( - <IndexRoute component={ProjectActivityApp}/> -); +export default <IndexRoute component={ProjectActivityApp} />; diff --git a/server/sonar-web/src/main/js/apps/projects-admin/AppContainer.js b/server/sonar-web/src/main/js/apps/projects-admin/AppContainer.js index baca690631f..dc382be6fc6 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/AppContainer.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/AppContainer.js @@ -24,20 +24,21 @@ import { getCurrentUser, getAppState } from '../../store/rootReducer'; import { getRootQualifiers } from '../../store/appState/duck'; class AppContainer extends React.Component { - render () { - const hasProvisionPermission = this.props.organization ? - this.props.organization.canProvisionProjects : - this.props.user.permissions.global.indexOf('provisioning') !== -1; + render() { + const hasProvisionPermission = this.props.organization + ? this.props.organization.canProvisionProjects + : this.props.user.permissions.global.indexOf('provisioning') !== -1; - const topLevelQualifiers = this.props.organization && !this.props.organization.isDefault ? - ['TRK'] : - this.props.rootQualifiers; + const topLevelQualifiers = this.props.organization && !this.props.organization.isDefault + ? ['TRK'] + : this.props.rootQualifiers; return ( - <Main - hasProvisionPermission={hasProvisionPermission} - topLevelQualifiers={topLevelQualifiers} - organization={this.props.organization}/> + <Main + hasProvisionPermission={hasProvisionPermission} + topLevelQualifiers={topLevelQualifiers} + organization={this.props.organization} + /> ); } } @@ -47,6 +48,4 @@ const mapStateToProps = state => ({ user: getCurrentUser(state) }); -export default connect( - mapStateToProps -)(AppContainer); +export default connect(mapStateToProps)(AppContainer); diff --git a/server/sonar-web/src/main/js/apps/projects-admin/__tests__/projects-test.js b/server/sonar-web/src/main/js/apps/projects-admin/__tests__/projects-test.js index 4684de66847..ebe90b8f947 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/__tests__/projects-test.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/__tests__/projects-test.js @@ -28,7 +28,7 @@ it('should render list of projects with no selection', () => { { id: '2', key: 'b', name: 'B', qualifier: 'TRK' } ]; - const result = shallow(<Projects projects={projects} selection={[]} refresh={jest.fn()}/>); + const result = shallow(<Projects projects={projects} selection={[]} refresh={jest.fn()} />); expect(result.find('tr').length).toBe(2); expect(result.find(Checkbox).filterWhere(n => n.prop('checked')).length).toBe(0); }); @@ -40,7 +40,9 @@ it('should render list of projects with one selected', () => { ]; const selection = ['a']; - const result = shallow(<Projects projects={projects} selection={selection} refresh={jest.fn()}/>); + const result = shallow( + <Projects projects={projects} selection={selection} refresh={jest.fn()} /> + ); expect(result.find('tr').length).toBe(2); expect(result.find(Checkbox).filterWhere(n => n.prop('checked')).length).toBe(1); }); diff --git a/server/sonar-web/src/main/js/apps/projects-admin/create-view.js b/server/sonar-web/src/main/js/apps/projects-admin/create-view.js index fb44ac62486..6d9de3d3d6b 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/create-view.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/create-view.js @@ -24,22 +24,22 @@ import Template from './templates/projects-create-form.hbs'; export default ModalForm.extend({ template: Template, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { ModalForm.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { const data = { name: this.$('#create-project-name').val(), branch: this.$('#create-project-branch').val(), @@ -50,21 +50,21 @@ export default ModalForm.extend({ } this.disableForm(); return createProject(data) - .then(project => { - if (this.options.refresh) { - this.options.refresh(); - } - this.enableForm(); - this.createdProject = project; - this.render(); - }) - .catch(error => { - this.enableForm(); - error.response.json().then(r => this.showErrors(r.errors, r.warnings)); - }); + .then(project => { + if (this.options.refresh) { + this.options.refresh(); + } + this.enableForm(); + this.createdProject = project; + this.render(); + }) + .catch(error => { + this.enableForm(); + error.response.json().then(r => this.showErrors(r.errors, r.warnings)); + }); }, - serializeData () { + serializeData() { return { ...ModalForm.prototype.serializeData.apply(this, arguments), createdProject: this.createdProject diff --git a/server/sonar-web/src/main/js/apps/projects-admin/delete-view.js b/server/sonar-web/src/main/js/apps/projects-admin/delete-view.js index e8ff84ca107..99bc391cbc5 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/delete-view.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/delete-view.js @@ -23,10 +23,9 @@ import Template from './templates/projects-delete.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.options.deleteProjects(); this.destroy(); } }); - diff --git a/server/sonar-web/src/main/js/apps/projects-admin/form-view.js b/server/sonar-web/src/main/js/apps/projects-admin/form-view.js index 8fcdefb44a5..cb2ed3ec2da 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/form-view.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/form-view.js @@ -20,20 +20,18 @@ import ModalForm from '../../components/common/modal-form'; export default ModalForm.extend({ - - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { ModalForm.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); } - }); diff --git a/server/sonar-web/src/main/js/apps/projects-admin/header.js b/server/sonar-web/src/main/js/apps/projects-admin/header.js index 0a2a58fe5e9..32196f5023f 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/header.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/header.js @@ -26,14 +26,14 @@ export default class Header extends React.Component { hasProvisionPermission: React.PropTypes.bool.isRequired }; - createProject () { + createProject() { new CreateView({ refresh: this.props.refresh, organization: this.props.organization }).render(); } - bulkApplyTemplate () { + bulkApplyTemplate() { new BulkApplyTemplateView({ total: this.props.total, selection: this.props.selection, @@ -43,43 +43,45 @@ export default class Header extends React.Component { }).render(); } - renderCreateButton () { + renderCreateButton() { if (!this.props.hasProvisionPermission) { return null; } return ( - <li> - <button onClick={this.createProject.bind(this)}> - Create Project - </button> - </li> + <li> + <button onClick={this.createProject.bind(this)}> + Create Project + </button> + </li> ); } - renderBulkApplyTemplateButton () { + renderBulkApplyTemplateButton() { return ( - <li> - <button onClick={this.bulkApplyTemplate.bind(this)}> - Bulk Apply Permission Template - </button> - </li> + <li> + <button onClick={this.bulkApplyTemplate.bind(this)}> + Bulk Apply Permission Template + </button> + </li> ); } - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title">Projects Management</h1> - <div className="page-actions"> - <ul className="list-inline"> - {this.renderCreateButton()} - {this.renderBulkApplyTemplateButton()} - </ul> - </div> - <p className="page-description">Use this page to delete multiple projects at once, or to provision projects - if you would like to configure them before the first analysis. Note that once a project is provisioned, you - have access to perform all project configurations on it.</p> - </header> + <header className="page-header"> + <h1 className="page-title">Projects Management</h1> + <div className="page-actions"> + <ul className="list-inline"> + {this.renderCreateButton()} + {this.renderBulkApplyTemplateButton()} + </ul> + </div> + <p className="page-description"> + Use this page to delete multiple projects at once, or to provision projects + if you would like to configure them before the first analysis. Note that once a project is provisioned, you + have access to perform all project configurations on it. + </p> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects-admin/main.js b/server/sonar-web/src/main/js/apps/projects-admin/main.js index d23dabeab8c..ad8a243ba60 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/main.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/main.js @@ -34,7 +34,7 @@ export default React.createClass({ organization: React.PropTypes.object }, - getInitialState () { + getInitialState() { return { ready: false, projects: [], @@ -47,15 +47,15 @@ export default React.createClass({ }; }, - componentWillMount () { + componentWillMount() { this.requestProjects = debounce(this.requestProjects, 250); }, - componentDidMount () { + componentDidMount() { this.requestProjects(); }, - getFilters () { + getFilters() { const filters = { ps: PAGE_SIZE }; if (this.state.page !== 1) { filters.p = this.state.page; @@ -69,7 +69,7 @@ export default React.createClass({ return filters; }, - requestProjects () { + requestProjects() { switch (this.state.type) { case TYPE.ALL: this.requestAllProjects(); @@ -82,11 +82,11 @@ export default React.createClass({ break; default: - // should never happen + // should never happen } }, - requestGhosts () { + requestGhosts() { const data = this.getFilters(); getGhosts(data).then(r => { let projects = r.projects.map(project => ({ @@ -101,7 +101,7 @@ export default React.createClass({ }); }, - requestProvisioned () { + requestProvisioned() { const data = this.getFilters(); getProvisioned(data).then(r => { let projects = r.projects.map(project => ({ @@ -116,7 +116,7 @@ export default React.createClass({ }); }, - requestAllProjects () { + requestAllProjects() { const data = this.getFilters(); data.qualifiers = this.state.qualifiers; getComponents(data).then(r => { @@ -128,62 +128,70 @@ export default React.createClass({ }); }, - loadMore () { - this.setState({ ready: false, page: this.state.page + 1 }, - this.requestProjects); + loadMore() { + this.setState({ ready: false, page: this.state.page + 1 }, this.requestProjects); }, - onSearch (query) { - this.setState({ - ready: false, - page: 1, - query, - selection: [] - }, this.requestProjects); + onSearch(query) { + this.setState( + { + ready: false, + page: 1, + query, + selection: [] + }, + this.requestProjects + ); }, - onTypeChanged (newType) { - this.setState({ - ready: false, - page: 1, - query: '', - type: newType, - qualifiers: 'TRK', - selection: [] - }, this.requestProjects); + onTypeChanged(newType) { + this.setState( + { + ready: false, + page: 1, + query: '', + type: newType, + qualifiers: 'TRK', + selection: [] + }, + this.requestProjects + ); }, - onQualifierChanged (newQualifier) { - this.setState({ - ready: false, - page: 1, - query: '', - type: TYPE.ALL, - qualifiers: newQualifier, - selection: [] - }, this.requestProjects); + onQualifierChanged(newQualifier) { + this.setState( + { + ready: false, + page: 1, + query: '', + type: TYPE.ALL, + qualifiers: newQualifier, + selection: [] + }, + this.requestProjects + ); }, - onProjectSelected (project) { + onProjectSelected(project) { const newSelection = uniq([].concat(this.state.selection, project.key)); this.setState({ selection: newSelection }); }, - onProjectDeselected (project) { + onProjectDeselected(project) { const newSelection = without(this.state.selection, project.key); this.setState({ selection: newSelection }); }, - onAllSelected () { + onAllSelected() { const newSelection = this.state.projects.map(project => project.key); this.setState({ selection: newSelection }); }, - onAllDeselected () { + onAllDeselected() { this.setState({ selection: [] }); }, - deleteProjects () { + deleteProjects() { this.setState({ ready: false }); const projects = this.state.selection.join(','); const data = { projects }; @@ -195,41 +203,47 @@ export default React.createClass({ }); }, - render () { + render() { return ( - <div className="page page-limited"> - <Header - hasProvisionPermission={this.props.hasProvisionPermission} - selection={this.state.selection} - total={this.state.total} - query={this.state.query} - qualifier={this.state.qualifiers} - refresh={this.requestProjects} - organization={this.props.organization}/> - - <Search {...this.props} {...this.state} - onSearch={this.onSearch} - onTypeChanged={this.onTypeChanged} - onQualifierChanged={this.onQualifierChanged} - onAllSelected={this.onAllSelected} - onAllDeselected={this.onAllDeselected} - deleteProjects={this.deleteProjects}/> - - <Projects - ready={this.state.ready} - projects={this.state.projects} - refresh={this.requestProjects} - selection={this.state.selection} - onProjectSelected={this.onProjectSelected} - onProjectDeselected={this.onProjectDeselected} - organization={this.props.organization}/> - - <ListFooter - ready={this.state.ready} - count={this.state.projects.length} - total={this.state.total} - loadMore={this.loadMore}/> - </div> + <div className="page page-limited"> + <Header + hasProvisionPermission={this.props.hasProvisionPermission} + selection={this.state.selection} + total={this.state.total} + query={this.state.query} + qualifier={this.state.qualifiers} + refresh={this.requestProjects} + organization={this.props.organization} + /> + + <Search + {...this.props} + {...this.state} + onSearch={this.onSearch} + onTypeChanged={this.onTypeChanged} + onQualifierChanged={this.onQualifierChanged} + onAllSelected={this.onAllSelected} + onAllDeselected={this.onAllDeselected} + deleteProjects={this.deleteProjects} + /> + + <Projects + ready={this.state.ready} + projects={this.state.projects} + refresh={this.requestProjects} + selection={this.state.selection} + onProjectSelected={this.onProjectSelected} + onProjectDeselected={this.onProjectDeselected} + organization={this.props.organization} + /> + + <ListFooter + ready={this.state.ready} + count={this.state.projects.length} + total={this.state.total} + loadMore={this.loadMore} + /> + </div> ); } }); diff --git a/server/sonar-web/src/main/js/apps/projects-admin/projects.js b/server/sonar-web/src/main/js/apps/projects-admin/projects.js index 7c2aaf752f8..d81de1966f4 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/projects.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/projects.js @@ -33,11 +33,11 @@ export default class Projects extends React.Component { organization: React.PropTypes.object }; - componentWillMount () { + componentWillMount() { this.renderProject = this.renderProject.bind(this); } - onProjectCheck (project, checked) { + onProjectCheck(project, checked) { if (checked) { this.props.onProjectSelected(project); } else { @@ -45,7 +45,7 @@ export default class Projects extends React.Component { } } - onApplyTemplateClick (project, e) { + onApplyTemplateClick(project, e) { e.preventDefault(); e.target.blur(); new ApplyTemplateView({ @@ -54,64 +54,66 @@ export default class Projects extends React.Component { }).render(); } - isProjectSelected (project) { + isProjectSelected(project) { return this.props.selection.indexOf(project.key) !== -1; } - renderProject (project) { + renderProject(project) { const permissionsUrl = getComponentPermissionsUrl(project.key); return ( - <tr key={project.key}> - <td className="thin"> - <Checkbox - checked={this.isProjectSelected(project)} - onCheck={this.onProjectCheck.bind(this, project)}/> - </td> - <td className="nowrap"> - <Link to={{ pathname: '/dashboard', query: { id: project.key } }} className="link-with-icon"> - <QualifierIcon qualifier={project.qualifier}/> + <tr key={project.key}> + <td className="thin"> + <Checkbox + checked={this.isProjectSelected(project)} + onCheck={this.onProjectCheck.bind(this, project)} + /> + </td> + <td className="nowrap"> + <Link + to={{ pathname: '/dashboard', query: { id: project.key } }} + className="link-with-icon" + > + <QualifierIcon qualifier={project.qualifier} /> + {' '} + <span>{project.name}</span> + </Link> + </td> + <td className="nowrap"> + <span className="note">{project.key}</span> + </td> + <td className="thin nowrap"> + <div className="dropdown"> + <button className="dropdown-toggle" data-toggle="dropdown"> + {translate('actions')} {' '} - <span>{project.name}</span> - </Link> - </td> - <td className="nowrap"> - <span className="note">{project.key}</span> - </td> - <td className="thin nowrap"> - <div className="dropdown"> - <button className="dropdown-toggle" data-toggle="dropdown"> - {translate('actions')} - {' '} - <i className="icon-dropdown"/> - </button> - <ul className="dropdown-menu dropdown-menu-right"> - <li> - <Link to={permissionsUrl}> - {translate('edit_permissions')} - </Link> - </li> - <li> - <a href="#" onClick={this.onApplyTemplateClick.bind(this, project)}> - {translate('projects_role.apply_template')} - </a> - </li> - </ul> - </div> - </td> - </tr> + <i className="icon-dropdown" /> + </button> + <ul className="dropdown-menu dropdown-menu-right"> + <li> + <Link to={permissionsUrl}> + {translate('edit_permissions')} + </Link> + </li> + <li> + <a href="#" onClick={this.onApplyTemplateClick.bind(this, project)}> + {translate('projects_role.apply_template')} + </a> + </li> + </ul> + </div> + </td> + </tr> ); } - render () { - const className = classNames('data', 'zebra', - { 'new-loading': !this.props.ready } - ); + render() { + const className = classNames('data', 'zebra', { 'new-loading': !this.props.ready }); return ( - <table className={className}> - <tbody>{this.props.projects.map(this.renderProject)}</tbody> - </table> + <table className={className}> + <tbody>{this.props.projects.map(this.renderProject)}</tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects-admin/routes.js b/server/sonar-web/src/main/js/apps/projects-admin/routes.js index 476f772ff21..476312d444e 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/routes.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/routes.js @@ -22,6 +22,4 @@ import { IndexRoute } from 'react-router'; import AppContainer from './AppContainer'; import forSingleOrganization from '../organizations/forSingleOrganization'; -export default ( - <IndexRoute component={forSingleOrganization(AppContainer)}/> -); +export default <IndexRoute component={forSingleOrganization(AppContainer)} />; diff --git a/server/sonar-web/src/main/js/apps/projects-admin/search.js b/server/sonar-web/src/main/js/apps/projects-admin/search.js index 865cad77a79..efd640663db 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/search.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/search.js @@ -30,17 +30,17 @@ export default React.createClass({ onSearch: React.PropTypes.func.isRequired }, - onSubmit (e) { + onSubmit(e) { e.preventDefault(); this.search(); }, - search () { + search() { const q = this.refs.input.value; this.props.onSearch(q); }, - getTypeOptions () { + getTypeOptions() { return [ { value: TYPE.ALL, label: 'All' }, { value: TYPE.PROVISIONED, label: 'Provisioned' }, @@ -48,33 +48,28 @@ export default React.createClass({ ]; }, - getQualifierOptions () { + getQualifierOptions() { const options = this.props.topLevelQualifiers.map(q => { return { value: q, label: translate('qualifiers', q) }; }); return sortBy(options, option => QUALIFIERS_ORDER.indexOf(option.value)); }, - renderCheckbox () { + renderCheckbox() { const isAllChecked = this.props.projects.length > 0 && - this.props.selection.length === this.props.projects.length; + this.props.selection.length === this.props.projects.length; const thirdState = this.props.projects.length > 0 && - this.props.selection.length > 0 && - this.props.selection.length < this.props.projects.length; + this.props.selection.length > 0 && + this.props.selection.length < this.props.projects.length; const checked = isAllChecked || thirdState; - return ( - <Checkbox - checked={checked} - thirdState={thirdState} - onCheck={this.onCheck}/> - ); + return <Checkbox checked={checked} thirdState={thirdState} onCheck={this.onCheck} />; }, - renderSpinner () { - return <i className="spinner"/>; + renderSpinner() { + return <i className="spinner" />; }, - onCheck (checked) { + onCheck(checked) { if (checked) { this.props.onAllSelected(); } else { @@ -82,41 +77,46 @@ export default React.createClass({ } }, - renderGhostsDescription () { + renderGhostsDescription() { if (this.props.type !== TYPE.GHOSTS || !this.props.ready) { return null; } - return <div className="spacer-top alert alert-info">{translate('bulk_deletion.ghosts.description')}</div>; + return ( + <div className="spacer-top alert alert-info"> + {translate('bulk_deletion.ghosts.description')} + </div> + ); }, - deleteProjects () { + deleteProjects() { new DeleteView({ deleteProjects: this.props.deleteProjects }).render(); }, - renderQualifierFilter () { + renderQualifierFilter() { const options = this.getQualifierOptions(); if (options.length < 2) { return null; } return ( - <td className="thin nowrap text-middle"> - <RadioToggle - options={this.getQualifierOptions()} - value={this.props.qualifiers} - name="projects-qualifier" - onCheck={this.props.onQualifierChanged}/> - </td> + <td className="thin nowrap text-middle"> + <RadioToggle + options={this.getQualifierOptions()} + value={this.props.qualifiers} + name="projects-qualifier" + onCheck={this.props.onQualifierChanged} + /> + </td> ); }, - render () { + render() { const isSomethingSelected = this.props.projects.length > 0 && this.props.selection.length > 0; return ( - <div className="panel panel-vertical bordered-bottom spacer-bottom"> - <table className="data"> - <tbody> + <div className="panel panel-vertical bordered-bottom spacer-bottom"> + <table className="data"> + <tbody> <tr> <td className="thin text-middle"> {this.props.ready ? this.renderCheckbox() : this.renderSpinner()} @@ -124,34 +124,41 @@ export default React.createClass({ {this.renderQualifierFilter()} <td className="thin nowrap text-middle"> <RadioToggle - options={this.getTypeOptions()} - value={this.props.type} - name="projects-type" - onCheck={this.props.onTypeChanged}/> + options={this.getTypeOptions()} + value={this.props.type} + name="projects-type" + onCheck={this.props.onTypeChanged} + /> </td> <td className="text-middle"> <form onSubmit={this.onSubmit} className="search-box"> <button className="search-box-submit button-clean"> - <i className="icon-search"/> + <i className="icon-search" /> </button> - <input onChange={this.search} - value={this.props.query} - ref="input" - className="search-box-input" - type="search" - placeholder="Search"/> + <input + onChange={this.search} + value={this.props.query} + ref="input" + className="search-box-input" + type="search" + placeholder="Search" + /> </form> </td> <td className="thin text-middle"> - <button onClick={this.deleteProjects} className="button-red" - disabled={!isSomethingSelected}>Delete + <button + onClick={this.deleteProjects} + className="button-red" + disabled={!isSomethingSelected} + > + Delete </button> </td> </tr> - </tbody> - </table> - {this.renderGhostsDescription()} - </div> + </tbody> + </table> + {this.renderGhostsDescription()} + </div> ); } }); diff --git a/server/sonar-web/src/main/js/apps/projects-admin/views/BulkApplyTemplateView.js b/server/sonar-web/src/main/js/apps/projects-admin/views/BulkApplyTemplateView.js index caf07293005..9769576cc53 100644 --- a/server/sonar-web/src/main/js/apps/projects-admin/views/BulkApplyTemplateView.js +++ b/server/sonar-web/src/main/js/apps/projects-admin/views/BulkApplyTemplateView.js @@ -19,31 +19,31 @@ */ import ModalForm from '../../../components/common/modal-form'; import { - applyTemplateToProject, - bulkApplyTemplate, - getPermissionTemplates + applyTemplateToProject, + bulkApplyTemplate, + getPermissionTemplates } from '../../../api/permissions'; import Template from '../templates/BulkApplyTemplateTemplate.hbs'; export default ModalForm.extend({ template: Template, - initialize () { + initialize() { this.loadPermissionTemplates(); this.done = false; }, - loadPermissionTemplates () { - const request = this.options.organization ? - getPermissionTemplates(this.options.organization.key) : - getPermissionTemplates(); + loadPermissionTemplates() { + const request = this.options.organization + ? getPermissionTemplates(this.options.organization.key) + : getPermissionTemplates(); return request.then(r => { this.permissionTemplates = r.permissionTemplates; this.render(); }); }, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('#project-permissions-template').select2({ width: '250px', @@ -51,7 +51,7 @@ export default ModalForm.extend({ }); }, - bulkApplyToAll (permissionTemplate) { + bulkApplyToAll(permissionTemplate) { const data = { templateId: permissionTemplate }; if (this.options.query) { @@ -69,7 +69,7 @@ export default ModalForm.extend({ return bulkApplyTemplate(data); }, - bulkApplyToSelected (permissionTemplate) { + bulkApplyToSelected(permissionTemplate) { const { selection } = this.options; let lastRequest = Promise.resolve(); @@ -84,29 +84,31 @@ export default ModalForm.extend({ return lastRequest; }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); const permissionTemplate = this.$('#project-permissions-template').val(); const applyTo = this.$('[name="apply-to"]:checked').val(); this.disableForm(); - const request = applyTo === 'all' ? - this.bulkApplyToAll(permissionTemplate) : - this.bulkApplyToSelected(permissionTemplate); - - request.then(() => { - this.trigger('done'); - this.done = true; - this.render(); - }).catch(e => { - e.response.json().then(r => { - this.showErrors(r.errors, r.warnings); - this.enableForm(); + const request = applyTo === 'all' + ? this.bulkApplyToAll(permissionTemplate) + : this.bulkApplyToSelected(permissionTemplate); + + request + .then(() => { + this.trigger('done'); + this.done = true; + this.render(); + }) + .catch(e => { + e.response.json().then(r => { + this.showErrors(r.errors, r.warnings); + this.enableForm(); + }); }); - }); }, - serializeData () { + serializeData() { return { permissionTemplates: this.permissionTemplates, selection: this.options.selection, diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js index 030dbb68e5e..f1b7730649a 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.js @@ -35,28 +35,28 @@ export default class AllProjects extends React.Component { query: {} }; - componentDidMount () { + componentDidMount() { this.handleQueryChange(); document.getElementById('footer').classList.add('search-navigator-footer'); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.location.query !== this.props.location.query) { this.handleQueryChange(); } } - componentWillUnmount () { + componentWillUnmount() { document.getElementById('footer').classList.remove('search-navigator-footer'); } - handleQueryChange () { + handleQueryChange() { const query = parseUrlQuery(this.props.location.query); this.setState({ query }); this.props.fetchProjects(query, this.props.isFavorite, this.props.organization); } - render () { + render() { const isFiltered = Object.keys(this.state.query).some(key => this.state.query[key] != null); return ( @@ -66,19 +66,22 @@ export default class AllProjects extends React.Component { <PageSidebar query={this.state.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> </div> </aside> <div className="page-main"> - <PageHeaderContainer/> + <PageHeaderContainer /> <ProjectsListContainer isFavorite={this.props.isFavorite} isFiltered={isFiltered} - organization={this.props.organization}/> + organization={this.props.organization} + /> <ProjectsListFooterContainer query={this.state.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> </div> </div> ); diff --git a/server/sonar-web/src/main/js/apps/projects/components/App.js b/server/sonar-web/src/main/js/apps/projects/components/App.js index 0cf8a92fbdb..bd9e6468d10 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/App.js +++ b/server/sonar-web/src/main/js/apps/projects/components/App.js @@ -23,20 +23,20 @@ import { translate } from '../../../helpers/l10n'; import '../styles.css'; export default class App extends React.Component { - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } - render () { + render() { return ( - <div id="projects-page" className="page page-limited"> - <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube"/> - {this.props.children} - </div> + <div id="projects-page" className="page page-limited"> + <Helmet title={translate('projects.page')} titleTemplate="%s - SonarQube" /> + {this.props.children} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.js b/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.js index 745b9696bf5..aa306689acd 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.js +++ b/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelector.js @@ -40,16 +40,16 @@ class DefaultPageSelector extends React.PureComponent { props: Props; state: State; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = {}; } - componentDidMount () { + componentDidMount() { this.defineIfShouldBeRedirected(); } - componentDidUpdate (prevProps: Props) { + componentDidUpdate(prevProps: Props) { if (prevProps.location !== this.props.location) { this.defineIfShouldBeRedirected(); } else if (this.state.shouldBeRedirected === true) { @@ -57,7 +57,7 @@ class DefaultPageSelector extends React.PureComponent { } } - defineIfShouldBeRedirected () { + defineIfShouldBeRedirected() { if (Object.keys(this.props.location.query).length > 0) { // show ALL projects when there are some filters this.setState({ shouldBeRedirected: false }); @@ -80,7 +80,7 @@ class DefaultPageSelector extends React.PureComponent { } } - render () { + render() { if (this.state.shouldBeRedirected == null || this.state.shouldBeRedirected === true) { return null; } else { @@ -88,7 +88,8 @@ class DefaultPageSelector extends React.PureComponent { <AllProjectsContainer isFavorite={false} location={this.props.location} - user={this.props.currentUser}/> + user={this.props.currentUser} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.js b/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.js index b0d1bf7bd78..8b4156532ab 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.js +++ b/server/sonar-web/src/main/js/apps/projects/components/EmptyInstance.js @@ -21,11 +21,11 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class EmptyInstance extends React.Component { - render () { + render() { return ( - <div className="projects-empty-list"> - <h3>{translate('projects.no_projects.empty_instance')}</h3> - </div> + <div className="projects-empty-list"> + <h3>{translate('projects.no_projects.empty_instance')}</h3> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js index c554ad6a86e..74c2372ea37 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilter.js @@ -36,7 +36,7 @@ export default class FavoriteFilter extends React.PureComponent { } }; - render () { + render() { if (!this.props.user.isLoggedIn) { return null; } @@ -57,7 +57,8 @@ export default class FavoriteFilter extends React.PureComponent { to={pathnameForFavorite} className="button" activeClassName="button-active" - onClick={this.handleSaveFavorite}> + onClick={this.handleSaveFavorite} + > {translate('my_favorites')} </Link> <IndexLink @@ -65,7 +66,8 @@ export default class FavoriteFilter extends React.PureComponent { to={pathnameForAll} className="button" activeClassName="button-active" - onClick={this.handleSaveAll}> + onClick={this.handleSaveAll} + > {translate('all')} </IndexLink> </div> diff --git a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.js b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.js index 7ffbb1b2c36..d3994b39bdb 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.js @@ -25,6 +25,4 @@ const mapStateToProps = state => ({ user: getCurrentUser(state) }); -export default connect( - mapStateToProps -)(FavoriteFilter); +export default connect(mapStateToProps)(FavoriteFilter); diff --git a/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjectsContainer.js b/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjectsContainer.js index d0afc946ca0..8d242c75556 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjectsContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/FavoriteProjectsContainer.js @@ -27,7 +27,4 @@ const mapStateToProps = state => ({ isFavorite: true }); -export default connect( - mapStateToProps, - { fetchProjects } -)(AllProjects); +export default connect(mapStateToProps, { fetchProjects })(AllProjects); diff --git a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.js b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.js index 072e51fe86f..43709aecbe3 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.js +++ b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.js @@ -22,15 +22,17 @@ import { Link } from 'react-router'; import { translate } from '../../../helpers/l10n'; export default class NoFavoriteProjects extends React.Component { - render () { + render() { return ( - <div className="projects-empty-list"> - <h3>{translate('projects.no_favorite_projects')}</h3> - <p className="big-spacer-top">{translate('projects.no_favorite_projects.engagement')}</p> - <p className="big-spacer-top"> - <Link to="/projects/all" className="button">{translate('projects.explore_projects')}</Link> - </p> - </div> + <div className="projects-empty-list"> + <h3>{translate('projects.no_favorite_projects')}</h3> + <p className="big-spacer-top">{translate('projects.no_favorite_projects.engagement')}</p> + <p className="big-spacer-top"> + <Link to="/projects/all" className="button"> + {translate('projects.explore_projects')} + </Link> + </p> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/NoProjects.js b/server/sonar-web/src/main/js/apps/projects/components/NoProjects.js index aa628bd67fd..c2194ad5409 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/NoProjects.js +++ b/server/sonar-web/src/main/js/apps/projects/components/NoProjects.js @@ -21,12 +21,12 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class NoProjects extends React.Component { - render () { + render() { return ( - <div className="projects-empty-list"> - <h3>{translate('projects.no_projects.1')}</h3> - <p className="big-spacer-top">{translate('projects.no_projects.2')}</p> - </div> + <div className="projects-empty-list"> + <h3>{translate('projects.no_projects.1')}</h3> + <p className="big-spacer-top">{translate('projects.no_projects.2')}</p> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js b/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js index f5beb136459..8b09599eb16 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/projects/components/PageHeader.js @@ -26,23 +26,22 @@ export default class PageHeader extends React.Component { total: React.PropTypes.number }; - render () { + render() { const { loading } = this.props; return ( - <header className="page-header"> - <div className="page-actions projects-page-actions"> - {!!loading && ( - <i className="spinner spacer-right"/> - )} + <header className="page-header"> + <div className="page-actions projects-page-actions"> + {!!loading && <i className="spinner spacer-right" />} - {this.props.total != null && ( - <span> - <strong id="projects-total">{this.props.total}</strong> {translate('projects._projects')} - </span> - )} - </div> - </header> + {this.props.total != null && + <span> + <strong id="projects-total">{this.props.total}</strong> + {' '} + {translate('projects._projects')} + </span>} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageHeaderContainer.js b/server/sonar-web/src/main/js/apps/projects/components/PageHeaderContainer.js index eb0cce97447..5d817b926fe 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/PageHeaderContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/PageHeaderContainer.js @@ -21,6 +21,4 @@ import { connect } from 'react-redux'; import PageHeader from './PageHeader'; import { getProjectsAppState } from '../../../store/rootReducer'; -export default connect( - state => getProjectsAppState(state) -)(PageHeader); +export default connect(state => getProjectsAppState(state))(PageHeader); diff --git a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js index 11c4fb75cef..cd030e5d45d 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js +++ b/server/sonar-web/src/main/js/apps/projects/components/PageSidebar.js @@ -39,7 +39,7 @@ export default class PageSidebar extends React.PureComponent { organization: React.PropTypes.object }; - render () { + render() { const isFiltered = Object.keys(this.props.query).some(key => this.props.query[key] != null); const basePathName = this.props.organization @@ -49,7 +49,7 @@ export default class PageSidebar extends React.PureComponent { return ( <div className="search-navigator-facets-list"> - <FavoriteFilterContainer/> + <FavoriteFilterContainer /> <div className="projects-facets-header clearfix"> {isFiltered && @@ -63,45 +63,55 @@ export default class PageSidebar extends React.PureComponent { <SearchFilterContainer query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> </div> <QualityGateFilter query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <ReliabilityFilter query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <SecurityFilter query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <MaintainabilityFilter query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <CoverageFilter query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <DuplicationsFilter query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <SizeFilter query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <LanguagesFilterContainer query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> <TagsFilterContainer query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js index 6a63633b480..18efa9f2e64 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js @@ -39,7 +39,7 @@ export default class ProjectCard extends React.PureComponent { } }; - render () { + render() { const { project } = this.props; if (project == null) { @@ -58,17 +58,17 @@ export default class ProjectCard extends React.PureComponent { <div data-key={project.key} className={className}> {displayQualityGate && <div className="boxed-group-actions"> - <ProjectCardQualityGate status={this.props.measures['alert_status']}/> + <ProjectCardQualityGate status={this.props.measures['alert_status']} /> </div>} <div className="boxed-group-header"> {project.isFavorite != null && - <FavoriteContainer className="spacer-right" componentKey={project.key}/>} + <FavoriteContainer className="spacer-right" componentKey={project.key} />} <h2 className="project-card-name"> {this.props.organization == null && project.organization != null && <span className="text-normal"> - <Organization organizationKey={project.organization}/> + <Organization organizationKey={project.organization} /> </span>} <Link to={{ pathname: '/dashboard', query: { id: project.key } }}> {project.name} @@ -78,7 +78,7 @@ export default class ProjectCard extends React.PureComponent { {isProjectAnalyzed ? <div className="boxed-group-inner"> - {areProjectMeasuresLoaded && <ProjectCardMeasures measures={this.props.measures}/>} + {areProjectMeasuresLoaded && <ProjectCardMeasures measures={this.props.measures} />} </div> : <div className="boxed-group-inner"> <div className="note project-card-not-analyzed"> diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js index f7bbb1a7e33..3b789e8bd24 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.js @@ -25,7 +25,7 @@ import { getLanguages } from '../../../store/rootReducer'; import { translate } from '../../../helpers/l10n'; class ProjectCardLanguages extends React.Component { - getLanguageName (key) { + getLanguageName(key) { if (key === '<null>') { return translate('unknown'); } @@ -33,7 +33,7 @@ class ProjectCardLanguages extends React.Component { return language != null ? language.name : key; } - render () { + render() { const { distribution } = this.props; if (distribution == null) { @@ -41,13 +41,13 @@ class ProjectCardLanguages extends React.Component { } const parsedLanguages = distribution.split(';').map(item => item.split('=')); - const finalLanguages = sortBy(parsedLanguages, l => (-1) * Number(l[1])) + const finalLanguages = sortBy(parsedLanguages, l => -1 * Number(l[1])) .slice(0, 2) .map(l => this.getLanguageName(l[0])); const tooltip = ( <span> - {finalLanguages.map(language => <span key={language}>{language}<br/></span>)} + {finalLanguages.map(language => <span key={language}>{language}<br /></span>)} </span> ); diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardMeasures.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardMeasures.js index 94d8c5fdaad..6d08f16980e 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardMeasures.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardMeasures.js @@ -31,7 +31,7 @@ export default class ProjectCardMeasures extends React.PureComponent { measures: React.PropTypes.object }; - render () { + render() { const { measures } = this.props; if (measures == null) { @@ -39,91 +39,94 @@ export default class ProjectCardMeasures extends React.PureComponent { } return ( - <div className="project-card-measures"> - <div className="project-card-measure" data-key="reliability_rating"> - <div className="project-card-measure-inner"> - <div className="project-card-measure-number"> - <Rating value={measures['reliability_rating']}/> - </div> - <div className="project-card-measure-label"> - {translate('metric_domain.Reliability')} - </div> + <div className="project-card-measures"> + <div className="project-card-measure" data-key="reliability_rating"> + <div className="project-card-measure-inner"> + <div className="project-card-measure-number"> + <Rating value={measures['reliability_rating']} /> + </div> + <div className="project-card-measure-label"> + {translate('metric_domain.Reliability')} </div> </div> + </div> - <div className="project-card-measure" data-key="security_rating"> - <div className="project-card-measure-inner"> - <div className="project-card-measure-number"> - <Rating value={measures['security_rating']}/> - </div> - <div className="project-card-measure-label"> - {translate('metric_domain.Security')} - </div> + <div className="project-card-measure" data-key="security_rating"> + <div className="project-card-measure-inner"> + <div className="project-card-measure-number"> + <Rating value={measures['security_rating']} /> + </div> + <div className="project-card-measure-label"> + {translate('metric_domain.Security')} </div> </div> + </div> - <div className="project-card-measure" data-key="sqale_rating"> - <div className="project-card-measure-inner"> - <div className="project-card-measure-number"> - <Rating value={measures['sqale_rating']}/> - </div> - <div className="project-card-measure-label"> - {translate('metric_domain.Maintainability')} - </div> + <div className="project-card-measure" data-key="sqale_rating"> + <div className="project-card-measure-inner"> + <div className="project-card-measure-number"> + <Rating value={measures['sqale_rating']} /> + </div> + <div className="project-card-measure-label"> + {translate('metric_domain.Maintainability')} </div> </div> + </div> - <div className="project-card-measure" data-key="coverage"> - <div className="project-card-measure-inner"> - <div className="project-card-measure-number"> - {measures['coverage'] != null && ( - <span className="spacer-right"> - <CoverageRating value={measures['coverage']}/> - </span> - )} - <Measure measure={{ value: measures['coverage'] }} - metric={{ key: 'coverage', type: 'PERCENT' }}/> - </div> - <div className="project-card-measure-label"> - {translate('metric.coverage.name')} - </div> + <div className="project-card-measure" data-key="coverage"> + <div className="project-card-measure-inner"> + <div className="project-card-measure-number"> + {measures['coverage'] != null && + <span className="spacer-right"> + <CoverageRating value={measures['coverage']} /> + </span>} + <Measure + measure={{ value: measures['coverage'] }} + metric={{ key: 'coverage', type: 'PERCENT' }} + /> + </div> + <div className="project-card-measure-label"> + {translate('metric.coverage.name')} </div> </div> + </div> - <div className="project-card-measure" data-key="duplicated_lines_density"> + <div className="project-card-measure" data-key="duplicated_lines_density"> + <div className="project-card-measure-inner"> + <div className="project-card-measure-number"> + {measures['duplicated_lines_density'] != null && + <span className="spacer-right"> + <DuplicationsRating value={measures['duplicated_lines_density']} /> + </span>} + <Measure + measure={{ value: measures['duplicated_lines_density'] }} + metric={{ key: 'duplicated_lines_density', type: 'PERCENT' }} + /> + </div> + <div className="project-card-measure-label"> + {translate('metric.duplicated_lines_density.short_name')} + </div> + </div> + </div> + + {measures['ncloc'] != null && + <div className="project-card-measure" data-key="ncloc"> <div className="project-card-measure-inner"> <div className="project-card-measure-number"> - {measures['duplicated_lines_density'] != null && ( - <span className="spacer-right"> - <DuplicationsRating value={measures['duplicated_lines_density']}/> - </span> - )} - <Measure measure={{ value: measures['duplicated_lines_density'] }} - metric={{ key: 'duplicated_lines_density', type: 'PERCENT' }}/> + <span className="spacer-right"> + <SizeRating value={measures['ncloc']} /> + </span> + <Measure + measure={{ value: measures['ncloc'] }} + metric={{ key: 'ncloc', type: 'SHORT_INT' }} + /> </div> <div className="project-card-measure-label"> - {translate('metric.duplicated_lines_density.short_name')} + <ProjectCardLanguages distribution={measures['ncloc_language_distribution']} /> </div> </div> - </div> - - {measures['ncloc'] != null && ( - <div className="project-card-measure" data-key="ncloc"> - <div className="project-card-measure-inner"> - <div className="project-card-measure-number"> - <span className="spacer-right"> - <SizeRating value={measures['ncloc']}/> - </span> - <Measure measure={{ value: measures['ncloc'] }} - metric={{ key: 'ncloc', type: 'SHORT_INT' }}/> - </div> - <div className="project-card-measure-label"> - <ProjectCardLanguages distribution={measures['ncloc_language_distribution']}/> - </div> - </div> - </div> - )} - </div> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js index cd12fc07ae5..1c4995a8bb8 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardQualityGate.js @@ -26,7 +26,7 @@ export default class ProjectCardQualityGate extends React.PureComponent { status: React.PropTypes.string }; - render () { + render() { const { status } = this.props; if (!status) { @@ -34,15 +34,15 @@ export default class ProjectCardQualityGate extends React.PureComponent { } return ( - <div className="project-card-measure project-card-quality-gate"> - <div className="project-card-measure-inner"> - <span className="small spacer-right"> - {translate('overview.quality_gate')} - {':'} - </span> - <Level level={status} small={true}/> - </div> + <div className="project-card-measure project-card-quality-gate"> + <div className="project-card-measure-inner"> + <span className="small spacer-right"> + {translate('overview.quality_gate')} + {':'} + </span> + <Level level={status} small={true} /> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.js index 93ba8a35c69..1c4cae090f2 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsList.js @@ -31,17 +31,17 @@ export default class ProjectsList extends React.PureComponent { organization: React.PropTypes.object }; - renderNoProjects () { + renderNoProjects() { if (this.props.isFavorite && !this.props.isFiltered) { - return <NoFavoriteProjects/>; + return <NoFavoriteProjects />; } else if (!this.props.isFiltered) { - return <EmptyInstance/>; + return <EmptyInstance />; } else { - return <NoProjects/>; + return <NoProjects />; } } - render () { + render() { const { projects } = this.props; if (projects == null) { @@ -49,18 +49,17 @@ export default class ProjectsList extends React.PureComponent { } return ( - <div className="projects-list"> - {projects.length > 0 ? ( - projects.map(projectKey => ( - <ProjectCardContainer - key={projectKey} - projectKey={projectKey} - organization={this.props.organization}/> - )) - ) : ( - this.renderNoProjects() - )} - </div> + <div className="projects-list"> + {projects.length > 0 + ? projects.map(projectKey => ( + <ProjectCardContainer + key={projectKey} + projectKey={projectKey} + organization={this.props.organization} + /> + )) + : this.renderNoProjects()} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListContainer.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListContainer.js index a9efaeb3bde..f326a8f02c7 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListContainer.js @@ -21,9 +21,7 @@ import { connect } from 'react-redux'; import ProjectsList from './ProjectsList'; import { getProjects, getProjectsAppState } from '../../../store/rootReducer'; -export default connect( - state => ({ - projects: getProjects(state), - total: getProjectsAppState(state).total - }) -)(ProjectsList); +export default connect(state => ({ + projects: getProjects(state), + total: getProjectsAppState(state).total +}))(ProjectsList); diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooter.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooter.js index 9ecdd3d367e..745b6683372 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooter.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooter.js @@ -25,11 +25,11 @@ export default class ProjectsListFooter extends React.Component { total: React.PropTypes.number.isRequired }; - render () { + render() { if (!this.props.total) { return null; } - return <ListFooter {...this.props}/>; + return <ListFooter {...this.props} />; } } diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooterContainer.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooterContainer.js index 4fafc66df07..542be063a7d 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooterContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectsListFooterContainer.js @@ -33,10 +33,8 @@ const mapStateToProps = state => { }; const mapDispatchToProps = (dispatch, ownProps) => ({ - loadMore: () => dispatch(fetchMoreProjects(ownProps.query, ownProps.isFavorite, ownProps.organization)) + loadMore: () => + dispatch(fetchMoreProjects(ownProps.query, ownProps.isFavorite, ownProps.organization)) }); -export default connect( - mapStateToProps, - mapDispatchToProps -)(ProjectsListFooter); +export default connect(mapStateToProps, mapDispatchToProps)(ProjectsListFooter); diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js index 1ada9d2f0db..23d90396a25 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCard-test.js @@ -26,7 +26,7 @@ const MEASURES = {}; it('should display analysis date', () => { expect( - shallow(<ProjectCard measures={MEASURES} project={PROJECT}/>).find( + shallow(<ProjectCard measures={MEASURES} project={PROJECT} />).find( '.project-card-analysis-date' ) ).toMatchSnapshot(); @@ -35,12 +35,12 @@ it('should display analysis date', () => { it('should NOT display analysis date', () => { const project = { ...PROJECT, analysisDate: undefined }; expect( - shallow(<ProjectCard measures={MEASURES} project={project}/>) - .find('.project-card-analysis-date') - .exists() + shallow(<ProjectCard measures={MEASURES} project={project} />) + .find('.project-card-analysis-date') + .exists() ).toBeFalsy(); }); it('should display loading', () => { - expect(shallow(<ProjectCard project={PROJECT}/>)).toMatchSnapshot(); + expect(shallow(<ProjectCard project={PROJECT} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardMeasures-test.js b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardMeasures-test.js index 8ef28b879ec..b0d6e3280b3 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardMeasures-test.js +++ b/server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCardMeasures-test.js @@ -23,39 +23,39 @@ import ProjectCardMeasures from '../ProjectCardMeasures'; it('should not render coverage', () => { const measures = { - 'alert_status': 'ERROR', - 'duplicated_lines_density': '9.8', - 'ncloc': '2053', - 'reliability_rating': '1.0', - 'security_rating': '1.0', - 'sqale_rating': '1.0' + alert_status: 'ERROR', + duplicated_lines_density: '9.8', + ncloc: '2053', + reliability_rating: '1.0', + security_rating: '1.0', + sqale_rating: '1.0' }; - const wrapper = shallow(<ProjectCardMeasures measures={measures}/>); + const wrapper = shallow(<ProjectCardMeasures measures={measures} />); expect(wrapper).toMatchSnapshot(); }); it('should not render duplications', () => { const measures = { - 'alert_status': 'ERROR', - 'coverage': '88.3', - 'ncloc': '2053', - 'reliability_rating': '1.0', - 'security_rating': '1.0', - 'sqale_rating': '1.0' + alert_status: 'ERROR', + coverage: '88.3', + ncloc: '2053', + reliability_rating: '1.0', + security_rating: '1.0', + sqale_rating: '1.0' }; - const wrapper = shallow(<ProjectCardMeasures measures={measures}/>); + const wrapper = shallow(<ProjectCardMeasures measures={measures} />); expect(wrapper).toMatchSnapshot(); }); it('should not render ncloc', () => { const measures = { - 'alert_status': 'ERROR', - 'coverage': '88.3', - 'duplicated_lines_density': '9.8', - 'reliability_rating': '1.0', - 'security_rating': '1.0', - 'sqale_rating': '1.0' + alert_status: 'ERROR', + coverage: '88.3', + duplicated_lines_density: '9.8', + reliability_rating: '1.0', + security_rating: '1.0', + sqale_rating: '1.0' }; - const wrapper = shallow(<ProjectCardMeasures measures={measures}/>); + const wrapper = shallow(<ProjectCardMeasures measures={measures} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.js index 69312bb565d..46c3ed99a22 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/CoverageFilter.js @@ -33,13 +33,14 @@ export default class CoverageFilter extends React.PureComponent { property = 'coverage'; - renderOption (option, selected) { + renderOption(option, selected) { return ( <span> <CoverageRating value={getCoverageRatingAverageValue(option)} size="small" - muted={!selected}/> + muted={!selected} + /> <span className="spacer-left"> {getCoverageRatingLabel(option)} </span> @@ -47,12 +48,12 @@ export default class CoverageFilter extends React.PureComponent { ); } - getFacetValueForOption (facet, option) { + getFacetValueForOption(facet, option) { const map = ['80.0-*', '70.0-80.0', '50.0-70.0', '30.0-50.0', '*-30.0']; return facet[map[option - 1]]; } - render () { + render() { return ( <FilterContainer property={this.property} @@ -70,9 +71,11 @@ export default class CoverageFilter extends React.PureComponent { query={this.props.query} isFavorite={this.props.isFavorite} organization={this.props.organization} - sortDesc="right"/> + sortDesc="right" + /> </FilterHeader> - }/> + } + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.js index 48dbc3331cd..b4f4585d025 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/DuplicationsFilter.js @@ -36,13 +36,14 @@ export default class DuplicationsFilter extends React.PureComponent { property = 'duplications'; - renderOption (option, selected) { + renderOption(option, selected) { return ( <span> <DuplicationsRating value={getDuplicationsRatingAverageValue(option)} size="small" - muted={!selected}/> + muted={!selected} + /> <span className="spacer-left"> {getDuplicationsRatingLabel(option)} </span> @@ -50,31 +51,33 @@ export default class DuplicationsFilter extends React.PureComponent { ); } - getFacetValueForOption (facet, option) { + getFacetValueForOption(facet, option) { const map = ['*-3.0', '3.0-5.0', '5.0-10.0', '10.0-20.0', '20.0-*']; return facet[map[option - 1]]; } - render () { + render() { return ( - <FilterContainer - property={this.property} - options={[1, 2, 3, 4, 5]} - query={this.props.query} - renderOption={this.renderOption} - isFavorite={this.props.isFavorite} - organization={this.props.organization} - getFacetValueForOption={this.getFacetValueForOption} - highlightUnder={1} - header={ - <FilterHeader name="Duplications"> - <SortingFilter - property={this.property} - query={this.props.query} - isFavorite={this.props.isFavorite} - organization={this.props.organization}/> - </FilterHeader> - }/> + <FilterContainer + property={this.property} + options={[1, 2, 3, 4, 5]} + query={this.props.query} + renderOption={this.renderOption} + isFavorite={this.props.isFavorite} + organization={this.props.organization} + getFacetValueForOption={this.getFacetValueForOption} + highlightUnder={1} + header={ + <FilterHeader name="Duplications"> + <SortingFilter + property={this.property} + query={this.props.query} + isFavorite={this.props.isFavorite} + organization={this.props.organization} + /> + </FilterHeader> + } + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/Filter.js b/server/sonar-web/src/main/js/apps/projects/filters/Filter.js index 7008f2bc86f..ea5eb9e40f5 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/Filter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/Filter.js @@ -51,18 +51,18 @@ export default class Filter extends React.PureComponent { halfWidth: false }; - isSelected (option) { + isSelected(option) { const { value } = this.props; return Array.isArray(value) ? value.includes(option) : option === value; } - highlightUnder (option) { + highlightUnder(option) { return this.props.highlightUnder != null && option !== null && option > this.props.highlightUnder; } - getPath (option) { + getPath(option) { const { property, value } = this.props; let urlOption; @@ -78,7 +78,7 @@ export default class Filter extends React.PureComponent { return getFilterUrl(this.props, { [property]: urlOption }); } - renderOptionBar (facetValue) { + renderOptionBar(facetValue) { if (facetValue == null || !this.props.maxFacetValue) { return null; } @@ -86,12 +86,13 @@ export default class Filter extends React.PureComponent { <div className="projects-facet-bar"> <div className="projects-facet-bar-inner" - style={{ width: facetValue / this.props.maxFacetValue * 60 }}/> + style={{ width: facetValue / this.props.maxFacetValue * 60 }} + /> </div> ); } - renderOption (option) { + renderOption(option) { const { facet, getFacetValueForOption, value } = this.props; const className = classNames( 'facet', @@ -126,7 +127,7 @@ export default class Filter extends React.PureComponent { ); } - renderOptions () { + renderOptions() { const { options } = this.props; if (options && options.length > 0) { return ( @@ -143,7 +144,7 @@ export default class Filter extends React.PureComponent { } } - render () { + render() { return ( <div className="search-navigator-facet-box" data-key={this.props.property}> {this.props.header} diff --git a/server/sonar-web/src/main/js/apps/projects/filters/FilterHeader.js b/server/sonar-web/src/main/js/apps/projects/filters/FilterHeader.js index ee98c26230b..7ac7113d587 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/FilterHeader.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/FilterHeader.js @@ -28,7 +28,7 @@ type Props = { export default class FilterHeader extends React.PureComponent { props: Props; - render () { + render() { return ( <div className="search-navigator-facet-header projects-facet-header"> {this.props.name} diff --git a/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.js index b73200036cc..ae89055ba10 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/IssuesFilter.js @@ -32,20 +32,20 @@ export default class IssuesFilter extends React.PureComponent { organization: React.PropTypes.object }; - renderOption (option, selected) { + renderOption(option, selected) { return ( <span> - <Rating value={option} small={true} muted={!selected}/> + <Rating value={option} small={true} muted={!selected} /> {option > 1 && option < 5 && <span className="note spacer-left">and worse</span>} </span> ); } - getFacetValueForOption (facet, option) { + getFacetValueForOption(facet, option) { return facet[option]; } - render () { + render() { return ( <FilterContainer property={this.props.property} @@ -62,9 +62,11 @@ export default class IssuesFilter extends React.PureComponent { property={this.props.property} query={this.props.query} isFavorite={this.props.isFavorite} - organization={this.props.organization}/> + organization={this.props.organization} + /> </FilterHeader> - }/> + } + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js index 7aa13b9fad5..9a7b75988da 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.js @@ -46,10 +46,11 @@ export default class LanguagesFilter extends React.PureComponent { renderOption = (option: string) => ( <SearchableFilterOption optionKey={option} - option={getLanguageByKey(this.props.languages, option)}/> + option={getLanguageByKey(this.props.languages, option)} + /> ); - getSearchOptions (facet: {}, languages: {}) { + getSearchOptions(facet: {}, languages: {}) { let languageKeys = Object.keys(languages); if (facet) { languageKeys = difference(languageKeys, Object.keys(facet)); @@ -57,13 +58,13 @@ export default class LanguagesFilter extends React.PureComponent { return languageKeys.map(key => ({ label: languages[key].name, value: key })); } - getSortedOptions (facet: {} = {}) { + getSortedOptions(facet: {} = {}) { return sortBy(Object.keys(facet), [option => -facet[option], option => option]); } getFacetValueForOption = (facet: {} = {}, option: string) => facet[option]; - render () { + render() { return ( <Filter property={this.property} @@ -77,7 +78,7 @@ export default class LanguagesFilter extends React.PureComponent { organization={this.props.organization} getFacetValueForOption={this.getFacetValueForOption} highlightUnder={1} - header={<FilterHeader name="Languages"/>} + header={<FilterHeader name="Languages" />} footer={ <SearchableFilterFooter property={this.property} @@ -85,8 +86,10 @@ export default class LanguagesFilter extends React.PureComponent { options={this.getSearchOptions(this.props.facet, this.props.languages)} isFavorite={this.props.isFavorite} organization={this.props.organization} - router={this.props.router}/> - }/> + router={this.props.router} + /> + } + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.js index e05067f6684..2f8c422dac4 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/MaintainabilityFilter.js @@ -21,7 +21,7 @@ import React from 'react'; import IssuesFilter from './IssuesFilter'; export default class MaintainabilityFilter extends React.Component { - render () { - return <IssuesFilter {...this.props} name="Maintainability" property="maintainability"/>; + render() { + return <IssuesFilter {...this.props} name="Maintainability" property="maintainability" />; } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.js index fc190415936..367f8588ec9 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/QualityGateFilter.js @@ -29,15 +29,15 @@ export default class QualityGateFilter extends React.PureComponent { organization: React.PropTypes.object }; - renderOption (option, selected) { - return <Level level={option} small={true} muted={!selected}/>; + renderOption(option, selected) { + return <Level level={option} small={true} muted={!selected} />; } - getFacetValueForOption (facet, option) { + getFacetValueForOption(facet, option) { return facet[option]; } - render () { + render() { return ( <FilterContainer property="gate" @@ -48,9 +48,8 @@ export default class QualityGateFilter extends React.PureComponent { organization={this.props.organization} getFacetValueForOption={this.getFacetValueForOption} highlightUnder={1} - header={ - <FilterHeader name="Quality Gate"/> - }/> + header={<FilterHeader name="Quality Gate" />} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.js index 1ae8889363e..da1372a2a86 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/ReliabilityFilter.js @@ -21,7 +21,7 @@ import React from 'react'; import IssuesFilter from './IssuesFilter'; export default class ReliabilityFilter extends React.Component { - render () { - return <IssuesFilter {...this.props} name="Reliability" property="reliability"/>; + render() { + return <IssuesFilter {...this.props} name="Reliability" property="reliability" />; } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SearchFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/SearchFilter.js index 50c83dd967e..b54d6a19cff 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SearchFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SearchFilter.js @@ -35,14 +35,14 @@ export default class SearchFilter extends React.PureComponent { props: Props; state: State; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = { userQuery: props.query.search }; } - componentWillReceiveProps (nextProps: Props) { + componentWillReceiveProps(nextProps: Props) { if ( this.props.query.search === this.state.userQuery && nextProps.query.search !== this.props.query.search @@ -60,7 +60,7 @@ export default class SearchFilter extends React.PureComponent { } }; - render () { + render() { const { userQuery } = this.state; const inputClassName = classNames('input-super-large', { touched: userQuery && userQuery.length < 2 @@ -74,7 +74,8 @@ export default class SearchFilter extends React.PureComponent { className={inputClassName} placeholder={translate('projects.search')} onChange={this.handleQueryChange} - autoComplete="off"/> + autoComplete="off" + /> <span className="note spacer-left"> {translateWithParameters('select2.tooShort', 2)} </span> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js b/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js index be8b92a2bfb..72b89f46ca8 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SearchFilterContainer.js @@ -35,18 +35,18 @@ class SearchFilterContainer extends React.Component { handleSearch: (userQuery?: string) => void; props: Props; - constructor (props: Props) { + constructor(props: Props) { super(props); this.handleSearch = debounce(this.handleSearch.bind(this), 250); } - handleSearch (userQuery?: string) { + handleSearch(userQuery?: string) { const path = getFilterUrl(this.props, { search: userQuery || null }); this.props.router.push(path); } - render () { - return <SearchFilter query={this.props.query} handleSearch={this.handleSearch}/>; + render() { + return <SearchFilter query={this.props.query} handleSearch={this.handleSearch} />; } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterFooter.js b/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterFooter.js index 1d23bbced21..b9292ab1874 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterFooter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterFooter.js @@ -27,7 +27,7 @@ type Props = { property: string, query: {}, options: [{ label: string, value: string }], - router: { push: ({ pathname: string, query?: {}}) => void }, + router: { push: ({ pathname: string, query?: {} }) => void }, onInputChange?: (string) => void, onOpen?: (void) => void, isLoading?: boolean, @@ -44,7 +44,7 @@ export default class SearchableFilterFooter extends React.PureComponent { this.props.router.push(path); }; - render () { + render() { return ( <div className="search-navigator-facet-footer projects-facet-footer"> <Select @@ -56,7 +56,8 @@ export default class SearchableFilterFooter extends React.PureComponent { onInputChange={this.props.onInputChange} onOpen={this.props.onOpen} isLoading={this.props.isLoading} - options={this.props.options}/> + options={this.props.options} + /> </div> ); } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterOption.js b/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterOption.js index af658f6834d..ef176a9e45e 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterOption.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SearchableFilterOption.js @@ -26,7 +26,7 @@ export default class SearchableFilterOption extends React.PureComponent { option: React.PropTypes.object }; - render () { + render() { const optionName = this.props.option ? this.props.option.name : this.props.optionKey; return <span>{this.props.optionKey !== '<null>' ? optionName : translate('unknown')}</span>; } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.js index 61120c1a245..22eac70799c 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SecurityFilter.js @@ -21,7 +21,7 @@ import React from 'react'; import IssuesFilter from './IssuesFilter'; export default class SecurityFilter extends React.Component { - render () { - return <IssuesFilter {...this.props} name="Security" property="security"/>; + render() { + return <IssuesFilter {...this.props} name="Security" property="security" />; } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.js index 65e61a2c4fb..1a107f2156a 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SizeFilter.js @@ -34,10 +34,10 @@ export default class SizeFilter extends React.PureComponent { property = 'size'; - renderOption (option, selected) { + renderOption(option, selected) { return ( <span> - <SizeRating value={getSizeRatingAverageValue(option)} small={true} muted={!selected}/> + <SizeRating value={getSizeRatingAverageValue(option)} small={true} muted={!selected} /> <span className="spacer-left"> {getSizeRatingLabel(option)} </span> @@ -53,11 +53,12 @@ export default class SizeFilter extends React.PureComponent { isFavorite={this.props.isFavorite} organization={this.props.organization} leftText={translate('biggest')} - rightText={translate('smallest')}/> + rightText={translate('smallest')} + /> ); }; - getFacetValueForOption (facet, option) { + getFacetValueForOption(facet, option) { const map = [ '*-1000.0', '1000.0-10000.0', @@ -68,7 +69,7 @@ export default class SizeFilter extends React.PureComponent { return facet[map[option - 1]]; } - render () { + render() { return ( <FilterContainer property={this.property} @@ -87,9 +88,11 @@ export default class SizeFilter extends React.PureComponent { isFavorite={this.props.isFavorite} organization={this.props.organization} leftText={translate('biggest')} - rightText={translate('smallest')}/> + rightText={translate('smallest')} + /> </FilterHeader> - }/> + } + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/SortingFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/SortingFilter.js index 80030468909..d0586c38a0f 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/SortingFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/SortingFilter.js @@ -39,7 +39,7 @@ export default class SortingFilter extends React.PureComponent { rightText: translate('best') }; - isSortActive (side) { + isSortActive(side) { const { sort } = this.props.query; if (sort && sort[0] === '-') { return sort.substr(1) === this.props.property && side === this.props.sortDesc; @@ -48,13 +48,13 @@ export default class SortingFilter extends React.PureComponent { } } - getLinkClass (side) { + getLinkClass(side) { return classNames('button button-small button-grey', { 'button-active': this.isSortActive(side) }); } - getLinkPath (side) { + getLinkPath(side) { if (this.isSortActive(side)) { return getFilterUrl(this.props, { sort: null }); } @@ -63,11 +63,11 @@ export default class SortingFilter extends React.PureComponent { }); } - blurLink (event) { + blurLink(event) { event.target.blur(); } - render () { + render() { const { leftText, rightText } = this.props; return ( @@ -77,13 +77,15 @@ export default class SortingFilter extends React.PureComponent { <Link onClick={this.blurLink} className={this.getLinkClass('left')} - to={this.getLinkPath('left')}> + to={this.getLinkPath('left')} + > {leftText} </Link> <Link onClick={this.blurLink} className={this.getLinkClass('right')} - to={this.getLinkPath('right')}> + to={this.getLinkPath('right')} + > {rightText} </Link> </div> diff --git a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js index 50463304e54..7344d20ee2d 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/TagsFilter.js @@ -35,7 +35,7 @@ type Props = { facet?: {}, isFavorite?: boolean, organization?: {}, - maxFacetValue?: number, + maxFacetValue?: number }; type State = { @@ -56,14 +56,14 @@ export default class TagsFilter extends React.PureComponent { }; property = 'tags'; - constructor (props: Props) { + constructor(props: Props) { super(props); this.handleSearch = debounce(this.handleSearch.bind(this), 250); } - renderOption = (option: string) => <SearchableFilterOption optionKey={option}/>; + renderOption = (option: string) => <SearchableFilterOption optionKey={option} />; - getSearchOptions (facet: {}, tags: Array<string>) { + getSearchOptions(facet: {}, tags: Array<string>) { let tagsCopy = [...tags]; if (facet) { tagsCopy = difference(tagsCopy, Object.keys(facet)); @@ -81,13 +81,13 @@ export default class TagsFilter extends React.PureComponent { } }; - getSortedOptions (facet: {} = {}) { + getSortedOptions(facet: {} = {}) { return sortBy(Object.keys(facet), [option => -facet[option], option => option]); } getFacetValueForOption = (facet: {}, option: string) => facet[option]; - render () { + render() { return ( <Filter property={this.property} @@ -101,7 +101,7 @@ export default class TagsFilter extends React.PureComponent { organization={this.props.organization} getFacetValueForOption={this.getFacetValueForOption} highlightUnder={1} - header={<FilterHeader name="Tags"/>} + header={<FilterHeader name="Tags" />} footer={ <SearchableFilterFooter property={this.property} @@ -112,8 +112,10 @@ export default class TagsFilter extends React.PureComponent { onInputChange={this.handleSearch} isFavorite={this.props.isFavorite} organization={this.props.organization} - router={this.props.router}/> - }/> + router={this.props.router} + /> + } + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/LanguagesFilter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/LanguagesFilter-test.js index c508af7616a..181da5b497e 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/LanguagesFilter-test.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/LanguagesFilter-test.js @@ -56,7 +56,8 @@ it('should render the languages without the ones in the facet', () => { query={{ languages: null }} languages={languages} router={fakeRouter} - facet={languagesFacet}/> + facet={languagesFacet} + /> ); expect(wrapper).toMatchSnapshot(); }); @@ -69,7 +70,8 @@ it('should render the languages facet with the selected languages', () => { languages={languages} router={fakeRouter} facet={languagesFacet} - isFavorite={true}/> + isFavorite={true} + /> ); expect(wrapper).toMatchSnapshot(); expect(wrapper.find('Filter').shallow()).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchFilter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchFilter-test.js index c72c3328178..9e6594db965 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchFilter-test.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchFilter-test.js @@ -22,29 +22,17 @@ import { shallow } from 'enzyme'; import SearchFilter from '../SearchFilter'; it('should render correctly without any search query', () => { - const wrapper = shallow( - <SearchFilter - handleSearch={() => {}} - query={{ search: null }}/> - ); + const wrapper = shallow(<SearchFilter handleSearch={() => {}} query={{ search: null }} />); expect(wrapper).toMatchSnapshot(); }); it('should render with a search query', () => { - const wrapper = shallow( - <SearchFilter - handleSearch={() => {}} - query={{ search: 'foo' }}/> - ); + const wrapper = shallow(<SearchFilter handleSearch={() => {}} query={{ search: 'foo' }} />); expect(wrapper).toMatchSnapshot(); }); it('should display a help message when there is less than 2 characters', () => { - const wrapper = shallow( - <SearchFilter - handleSearch={() => {}} - query={{ search: 'a' }}/> - ); + const wrapper = shallow(<SearchFilter handleSearch={() => {}} query={{ search: 'a' }} />); expect(wrapper).toMatchSnapshot(); wrapper.setState({ userQuery: 'foo' }); expect(wrapper).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchableFilterFooter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchableFilterFooter-test.js index e62d8f89299..c8f5a59ea74 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchableFilterFooter-test.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SearchableFilterFooter-test.js @@ -39,7 +39,8 @@ it('should render the languages without the ones in the facet', () => { property="languages" query={{ languages: null }} options={languageOptions} - router={fakeRouter}/> + router={fakeRouter} + /> ); expect(wrapper).toMatchSnapshot(); expect(wrapper.find('Select').props().options.length).toBe(3); @@ -51,7 +52,8 @@ it('should render the tags without the ones in the facet', () => { property="tags" query={{ tags: ['java'] }} options={tagOptions} - isFavorite={true}/> + isFavorite={true} + /> ); expect(wrapper).toMatchSnapshot(); expect(wrapper.find('Select').props().options.length).toBe(3); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SortingFilter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SortingFilter-test.js index 98134517425..a73ffcbadf9 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SortingFilter-test.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/SortingFilter-test.js @@ -22,11 +22,7 @@ import { shallow } from 'enzyme'; import SortingFilter from '../SortingFilter'; it('should render with default parameters and empty query', () => { - const wrapper = shallow( - <SortingFilter - property="foo" - query={{}}/> - ); + const wrapper = shallow(<SortingFilter property="foo" query={{}} />); expect(wrapper).toMatchSnapshot(); const sortingFilter = wrapper.instance(); expect(sortingFilter.isSortActive('left')).toBeFalsy(); @@ -35,22 +31,14 @@ it('should render with default parameters and empty query', () => { it('should render with custom parameters', () => { const wrapper = shallow( - <SortingFilter - property="foo" - query={{}} - sortDesc="right" - leftText="worst" - rightText="best"/> + <SortingFilter property="foo" query={{}} sortDesc="right" leftText="worst" rightText="best" /> ); expect(wrapper).toMatchSnapshot(); }); it('should render correctly with matching query', () => { const wrapper = shallow( - <SortingFilter - property="foo" - query={{ sort: '-foo', languages: 'php,cpp' }} - sortDesc="right"/> + <SortingFilter property="foo" query={{ sort: '-foo', languages: 'php,cpp' }} sortDesc="right" /> ); expect(wrapper).toMatchSnapshot(); const sortingFilter = wrapper.instance(); @@ -59,11 +47,7 @@ it('should render correctly with matching query', () => { }); it('should render correctly with no matching query', () => { - const wrapper = shallow( - <SortingFilter - property="foo" - query={{ sort: 'bar' }}/> - ); + const wrapper = shallow(<SortingFilter property="foo" query={{ sort: 'bar' }} />); expect(wrapper).toMatchSnapshot(); const sortingFilter = wrapper.instance(); expect(sortingFilter.isSortActive('left')).toBeFalsy(); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/TagsFilter-test.js b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/TagsFilter-test.js index 26f8eda70d1..c7af892335f 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/__tests__/TagsFilter-test.js +++ b/server/sonar-web/src/main/js/apps/projects/filters/__tests__/TagsFilter-test.js @@ -27,10 +27,7 @@ const fakeRouter = { push: () => {} }; it('should render the tags without the ones in the facet', () => { const wrapper = shallow( - <TagsFilter - query={{ tags: null }} - router={fakeRouter} - facet={tagsFacet}/> + <TagsFilter query={{ tags: null }} router={fakeRouter} facet={tagsFacet} /> ); expect(wrapper).toMatchSnapshot(); wrapper.setState({ tags }); @@ -44,7 +41,8 @@ it('should render the tags facet with the selected tags', () => { value={['lang', 'sonar']} router={fakeRouter} facet={tagsFacet} - isFavorite={true}/> + isFavorite={true} + /> ); expect(wrapper).toMatchSnapshot(); expect(wrapper.find('Filter').shallow()).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/apps/projects/routes.js b/server/sonar-web/src/main/js/apps/projects/routes.js index 8c389ca9d77..371a29f49a9 100644 --- a/server/sonar-web/src/main/js/apps/projects/routes.js +++ b/server/sonar-web/src/main/js/apps/projects/routes.js @@ -26,13 +26,14 @@ import { saveAll } from './utils'; export default ( <Route component={App}> - <IndexRoute component={DefaultPageSelector}/> + <IndexRoute component={DefaultPageSelector} /> <Route path="all" onEnter={(_, replace) => { saveAll(); replace('/projects'); - }}/> - <Route path="favorite" component={FavoriteProjectsContainer}/> + }} + /> + <Route path="favorite" component={FavoriteProjectsContainer} /> </Route> ); diff --git a/server/sonar-web/src/main/js/apps/projects/store/actions.js b/server/sonar-web/src/main/js/apps/projects/store/actions.js index 4f1b29642ff..0bac164f8c2 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/actions.js +++ b/server/sonar-web/src/main/js/apps/projects/store/actions.js @@ -58,58 +58,63 @@ const FACETS = [ 'tags' ]; -const onFail = dispatch => error => { - parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); - dispatch(updateState({ loading: false })); -}; +const onFail = dispatch => + error => { + parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); + dispatch(updateState({ loading: false })); + }; -const onReceiveMeasures = (dispatch, expectedProjectKeys) => response => { - const byComponentKey = groupBy(response.measures, 'component'); +const onReceiveMeasures = (dispatch, expectedProjectKeys) => + response => { + const byComponentKey = groupBy(response.measures, 'component'); - const toStore = {}; + const toStore = {}; - // fill store with empty objects for expected projects - // this is required to not have "null"s for provisioned projects - expectedProjectKeys.forEach(projectKey => toStore[projectKey] = {}); + // fill store with empty objects for expected projects + // this is required to not have "null"s for provisioned projects + expectedProjectKeys.forEach(projectKey => toStore[projectKey] = {}); - Object.keys(byComponentKey).forEach(componentKey => { - const measures = {}; - byComponentKey[componentKey].forEach(measure => { - measures[measure.metric] = measure.value; + Object.keys(byComponentKey).forEach(componentKey => { + const measures = {}; + byComponentKey[componentKey].forEach(measure => { + measures[measure.metric] = measure.value; + }); + toStore[componentKey] = measures; }); - toStore[componentKey] = measures; - }); - - dispatch(receiveComponentsMeasures(toStore)); -}; -const onReceiveOrganizations = dispatch => response => { - dispatch(receiveOrganizations(response.organizations)); -}; - -const fetchProjectMeasures = projects => dispatch => { - if (!projects.length) { - return Promise.resolve(); - } - - const projectKeys = projects.map(project => project.key); - return getMeasuresForProjects(projectKeys, METRICS).then( - onReceiveMeasures(dispatch, projectKeys), - onFail(dispatch) - ); -}; - -const fetchProjectOrganizations = projects => dispatch => { - if (!projects.length) { - return Promise.resolve(); - } - - const organizationKeys = uniq(projects.map(project => project.organization)); - return getOrganizations(organizationKeys).then( - onReceiveOrganizations(dispatch), - onFail(dispatch) - ); -}; + dispatch(receiveComponentsMeasures(toStore)); + }; + +const onReceiveOrganizations = dispatch => + response => { + dispatch(receiveOrganizations(response.organizations)); + }; + +const fetchProjectMeasures = projects => + dispatch => { + if (!projects.length) { + return Promise.resolve(); + } + + const projectKeys = projects.map(project => project.key); + return getMeasuresForProjects(projectKeys, METRICS).then( + onReceiveMeasures(dispatch, projectKeys), + onFail(dispatch) + ); + }; + +const fetchProjectOrganizations = projects => + dispatch => { + if (!projects.length) { + return Promise.resolve(); + } + + const organizationKeys = uniq(projects.map(project => project.organization)); + return getOrganizations(organizationKeys).then( + onReceiveOrganizations(dispatch), + onFail(dispatch) + ); + }; const handleFavorites = (dispatch, projects) => { const toAdd = projects.filter(project => project.isFavorite); @@ -119,55 +124,59 @@ const handleFavorites = (dispatch, projects) => { } }; -const onReceiveProjects = dispatch => response => { - dispatch(receiveComponents(response.components)); - dispatch(receiveProjects(response.components, response.facets)); - handleFavorites(dispatch, response.components); - Promise.all([ - dispatch(fetchProjectMeasures(response.components)), - dispatch(fetchProjectOrganizations(response.components)) - ]).then(() => { - dispatch(updateState({ loading: false })); - }); - dispatch( - updateState({ - total: response.paging.total, - pageIndex: response.paging.pageIndex - }) - ); -}; - -const onReceiveMoreProjects = dispatch => response => { - dispatch(receiveComponents(response.components)); - dispatch(receiveMoreProjects(response.components)); - handleFavorites(dispatch, response.components); - Promise.all([ - dispatch(fetchProjectMeasures(response.components)), - dispatch(fetchProjectOrganizations(response.components)) - ]).then(() => { - dispatch(updateState({ loading: false })); - }); - dispatch(updateState({ pageIndex: response.paging.pageIndex })); -}; - -export const fetchProjects = (query, isFavorite, organization) => dispatch => { - dispatch(updateState({ loading: true })); - const data = convertToQueryData(query, isFavorite, organization, { - ps: PAGE_SIZE, - facets: FACETS.join(), - f: 'analysisDate' - }); - return searchProjects(data).then(onReceiveProjects(dispatch), onFail(dispatch)); -}; - -export const fetchMoreProjects = (query, isFavorite, organization) => (dispatch, getState) => { - dispatch(updateState({ loading: true })); - const state = getState(); - const { pageIndex } = getProjectsAppState(state); - const data = convertToQueryData(query, isFavorite, organization, { - ps: PAGE_SIZE, - p: pageIndex + 1, - f: 'analysisDate' - }); - return searchProjects(data).then(onReceiveMoreProjects(dispatch), onFail(dispatch)); -}; +const onReceiveProjects = dispatch => + response => { + dispatch(receiveComponents(response.components)); + dispatch(receiveProjects(response.components, response.facets)); + handleFavorites(dispatch, response.components); + Promise.all([ + dispatch(fetchProjectMeasures(response.components)), + dispatch(fetchProjectOrganizations(response.components)) + ]).then(() => { + dispatch(updateState({ loading: false })); + }); + dispatch( + updateState({ + total: response.paging.total, + pageIndex: response.paging.pageIndex + }) + ); + }; + +const onReceiveMoreProjects = dispatch => + response => { + dispatch(receiveComponents(response.components)); + dispatch(receiveMoreProjects(response.components)); + handleFavorites(dispatch, response.components); + Promise.all([ + dispatch(fetchProjectMeasures(response.components)), + dispatch(fetchProjectOrganizations(response.components)) + ]).then(() => { + dispatch(updateState({ loading: false })); + }); + dispatch(updateState({ pageIndex: response.paging.pageIndex })); + }; + +export const fetchProjects = (query, isFavorite, organization) => + dispatch => { + dispatch(updateState({ loading: true })); + const data = convertToQueryData(query, isFavorite, organization, { + ps: PAGE_SIZE, + facets: FACETS.join(), + f: 'analysisDate' + }); + return searchProjects(data).then(onReceiveProjects(dispatch), onFail(dispatch)); + }; + +export const fetchMoreProjects = (query, isFavorite, organization) => + (dispatch, getState) => { + dispatch(updateState({ loading: true })); + const state = getState(); + const { pageIndex } = getProjectsAppState(state); + const data = convertToQueryData(query, isFavorite, organization, { + ps: PAGE_SIZE, + p: pageIndex + 1, + f: 'analysisDate' + }); + return searchProjects(data).then(onReceiveMoreProjects(dispatch), onFail(dispatch)); + }; diff --git a/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js b/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js index 03640a8b2f4..cd15ca36fdb 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js +++ b/server/sonar-web/src/main/js/apps/projects/store/facetsDuck.js @@ -32,9 +32,7 @@ const CUMULATIVE_FACETS = [ 'size' ]; -const REVERSED_FACETS = [ - 'coverage' -]; +const REVERSED_FACETS = ['coverage']; const mapFacetValues = values => { const map = {}; @@ -62,9 +60,9 @@ const getFacetsMap = facets => { if (REVERSED_FACETS.includes(property)) { values.reverse(); } - map[property] = CUMULATIVE_FACETS.includes(property) ? - cumulativeMapFacetValues(values) : - mapFacetValues(values); + map[property] = CUMULATIVE_FACETS.includes(property) + ? cumulativeMapFacetValues(values) + : mapFacetValues(values); }); return map; }; @@ -77,9 +75,7 @@ const reducer = createMap( export default reducer; -export const getFacetByProperty = (state, property) => ( - state[property] -); +export const getFacetByProperty = (state, property) => state[property]; export const getMaxFacetValue = state => { const allValues = flatMap(Object.values(state), facet => Object.values(facet)); diff --git a/server/sonar-web/src/main/js/apps/projects/store/reducer.js b/server/sonar-web/src/main/js/apps/projects/store/reducer.js index 4e9d480a099..f7713f1ffd7 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/reducer.js +++ b/server/sonar-web/src/main/js/apps/projects/store/reducer.js @@ -24,18 +24,11 @@ import facets, * as fromFacets from './facetsDuck'; export default combineReducers({ projects, state, facets }); -export const getProjects = state => ( - fromProjects.getProjects(state.projects) -); +export const getProjects = state => fromProjects.getProjects(state.projects); -export const getState = state => ( - state.state -); +export const getState = state => state.state; -export const getFacetByProperty = (state, property) => ( - fromFacets.getFacetByProperty(state.facets, property) -); +export const getFacetByProperty = (state, property) => + fromFacets.getFacetByProperty(state.facets, property); -export const getMaxFacetValue = state => ( - fromFacets.getMaxFacetValue(state.facets) -); +export const getMaxFacetValue = state => fromFacets.getMaxFacetValue(state.facets); diff --git a/server/sonar-web/src/main/js/apps/projects/store/stateDuck.js b/server/sonar-web/src/main/js/apps/projects/store/stateDuck.js index b2f0da3c31a..2b1e5ad297c 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/stateDuck.js +++ b/server/sonar-web/src/main/js/apps/projects/store/stateDuck.js @@ -29,15 +29,12 @@ export const updateState = changes => ({ }); export default createValue( - // should update + // should update (state, action) => action.type === actions.UPDATE_STATE, - - // should reset + // should reset () => false, - - // get next value + // get next value (state, action) => ({ ...state, ...action.changes }), - - // default value - {} + // default value + {} ); diff --git a/server/sonar-web/src/main/js/apps/projects/store/utils.js b/server/sonar-web/src/main/js/apps/projects/store/utils.js index ca6feab5b21..63ee07a6563 100644 --- a/server/sonar-web/src/main/js/apps/projects/store/utils.js +++ b/server/sonar-web/src/main/js/apps/projects/store/utils.js @@ -22,7 +22,7 @@ const getAsNumericRating = value => { return null; } const num = Number(value); - return (num > 0 && num < 6) ? num : null; + return num > 0 && num < 6 ? num : null; }; const getAsLevel = value => { @@ -47,47 +47,47 @@ const getAsArray = (values, elementGetter) => { }; export const parseUrlQuery = urlQuery => ({ - 'gate': getAsLevel(urlQuery['gate']), - 'reliability': getAsNumericRating(urlQuery['reliability']), - 'security': getAsNumericRating(urlQuery['security']), - 'maintainability': getAsNumericRating(urlQuery['maintainability']), - 'coverage': getAsNumericRating(urlQuery['coverage']), - 'duplications': getAsNumericRating(urlQuery['duplications']), - 'size': getAsNumericRating(urlQuery['size']), - 'languages': getAsArray(urlQuery['languages'], getAsString), - 'tags': getAsArray(urlQuery['tags'], getAsString), - 'search': getAsString(urlQuery['search']), - 'sort': getAsString(urlQuery['sort']) + gate: getAsLevel(urlQuery['gate']), + reliability: getAsNumericRating(urlQuery['reliability']), + security: getAsNumericRating(urlQuery['security']), + maintainability: getAsNumericRating(urlQuery['maintainability']), + coverage: getAsNumericRating(urlQuery['coverage']), + duplications: getAsNumericRating(urlQuery['duplications']), + size: getAsNumericRating(urlQuery['size']), + languages: getAsArray(urlQuery['languages'], getAsString), + tags: getAsArray(urlQuery['tags'], getAsString), + search: getAsString(urlQuery['search']), + sort: getAsString(urlQuery['sort']) }); export const mapMetricToProperty = metricKey => { const map = { - 'reliability_rating': 'reliability', - 'security_rating': 'security', - 'sqale_rating': 'maintainability', - 'coverage': 'coverage', - 'duplicated_lines_density': 'duplications', - 'ncloc': 'size', - 'alert_status': 'gate', - 'languages': 'languages', - 'tags': 'tags', - 'query': 'search' + reliability_rating: 'reliability', + security_rating: 'security', + sqale_rating: 'maintainability', + coverage: 'coverage', + duplicated_lines_density: 'duplications', + ncloc: 'size', + alert_status: 'gate', + languages: 'languages', + tags: 'tags', + query: 'search' }; return map[metricKey]; }; export const mapPropertyToMetric = property => { const map = { - 'reliability': 'reliability_rating', - 'security': 'security_rating', - 'maintainability': 'sqale_rating', - 'coverage': 'coverage', - 'duplications': 'duplicated_lines_density', - 'size': 'ncloc', - 'gate': 'alert_status', - 'languages': 'languages', - 'tags': 'tags', - 'search': 'query' + reliability: 'reliability_rating', + security: 'security_rating', + maintainability: 'sqale_rating', + coverage: 'coverage', + duplications: 'duplicated_lines_density', + size: 'ncloc', + gate: 'alert_status', + languages: 'languages', + tags: 'tags', + search: 'query' }; return map[property]; }; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js index 8685303f700..d21b39d2fc3 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionForm.js @@ -22,8 +22,8 @@ import Select from 'react-select'; import sortBy from 'lodash/sortBy'; import { translate, getLocalizedMetricName, getLocalizedMetricDomain } from '../../../helpers/l10n'; -export default function AddConditionForm ({ metrics, onSelect }) { - function handleChange (option) { +export default function AddConditionForm({ metrics, onSelect }) { + function handleChange(option) { const metric = option.value; // e.target.value = ''; @@ -55,13 +55,14 @@ export default function AddConditionForm ({ metrics, onSelect }) { }); return ( - <div className="big-spacer-top panel bg-muted"> - <Select - id="quality-gate-new-condition-metric" - className="text-middle input-large" - options={optionsWithDomains} - placeholder={translate('quality_gates.add_condition')} - onChange={handleChange}/> - </div> + <div className="big-spacer-top panel bg-muted"> + <Select + id="quality-gate-new-condition-metric" + className="text-middle input-large" + options={optionsWithDomains} + placeholder={translate('quality_gates.add_condition')} + onChange={handleChange} + /> + </div> ); } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js index 863fa62b866..e5f66c5a98d 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js @@ -27,7 +27,7 @@ import { translate, getLocalizedMetricName } from '../../../helpers/l10n'; import { formatMeasure } from '../../../helpers/measures'; export default class Condition extends Component { - constructor (props) { + constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { @@ -39,7 +39,7 @@ export default class Condition extends Component { }; } - componentDidMount () { + componentDidMount() { const { condition } = this.props; if (!condition.id) { @@ -47,29 +47,29 @@ export default class Condition extends Component { } } - handleChange () { + handleChange() { this.setState({ changed: true }); } - handleOperatorChange (option) { + handleOperatorChange(option) { const { value } = option; this.setState({ changed: true, op: value }); } - handlePeriodChange (checked) { + handlePeriodChange(checked) { const period = checked ? '1' : undefined; this.setState({ changed: true, period }); } - handleWarningChange (value) { + handleWarningChange(value) { this.setState({ changed: true, warning: value }); } - handleErrorChange (value) { + handleErrorChange(value) { this.setState({ changed: true, error: value }); } - handleSaveClick (e) { + handleSaveClick(e) { const { qualityGate, condition, metric, onSaveCondition, onError, onResetError } = this.props; const period = this.state.period; const data = { @@ -88,14 +88,16 @@ export default class Condition extends Component { } e.preventDefault(); - createCondition(qualityGate.id, data).then(newCondition => { - this.setState({ changed: false }); - onSaveCondition(condition, newCondition); - onResetError(); - }).catch(error => onError(error)); + createCondition(qualityGate.id, data) + .then(newCondition => { + this.setState({ changed: false }); + onSaveCondition(condition, newCondition); + onResetError(); + }) + .catch(error => onError(error)); } - handleUpdateClick (e) { + handleUpdateClick(e) { const { condition, onSaveCondition, metric, onError, onResetError } = this.props; const period = this.state.period; const data = { @@ -115,14 +117,16 @@ export default class Condition extends Component { } e.preventDefault(); - updateCondition(data).then(newCondition => { - this.setState({ changed: false }); - onSaveCondition(condition, newCondition); - onResetError(); - }).catch(error => onError(error)); + updateCondition(data) + .then(newCondition => { + this.setState({ changed: false }); + onSaveCondition(condition, newCondition); + onResetError(); + }) + .catch(error => onError(error)); } - handleDeleteClick (e) { + handleDeleteClick(e) { const { qualityGate, condition, metric, onDeleteCondition } = this.props; e.preventDefault(); @@ -134,14 +138,14 @@ export default class Condition extends Component { }).render(); } - handleCancelClick (e) { + handleCancelClick(e) { const { condition, onDeleteCondition } = this.props; e.preventDefault(); onDeleteCondition(condition); } - renderPeriodValue () { + renderPeriodValue() { const { condition, metric } = this.props; const isLeakSelected = !!this.state.period; const isDiffMetric = condition.metric.indexOf('new_') === 0; @@ -149,26 +153,26 @@ export default class Condition extends Component { if (isDiffMetric) { return ( - <span className="note"> - {translate('quality_gates.condition.leak.unconditional')} - </span> + <span className="note"> + {translate('quality_gates.condition.leak.unconditional')} + </span> ); } if (isRating) { return ( - <span className="note"> - {translate('quality_gates.condition.leak.never')} - </span> + <span className="note"> + {translate('quality_gates.condition.leak.never')} + </span> ); } - return isLeakSelected ? - translate('quality_gates.condition.leak.yes') : - translate('quality_gates.condition.leak.no'); + return isLeakSelected + ? translate('quality_gates.condition.leak.yes') + : translate('quality_gates.condition.leak.no'); } - renderPeriod () { + renderPeriod() { const { condition, metric, edit } = this.props; const isDiffMetric = condition.metric.indexOf('new_') === 0; @@ -179,26 +183,20 @@ export default class Condition extends Component { return this.renderPeriodValue(); } - return ( - <Checkbox - checked={isLeakSelected} - onCheck={this.handlePeriodChange.bind(this)}/> - ); + return <Checkbox checked={isLeakSelected} onCheck={this.handlePeriodChange.bind(this)} />; } - renderOperator () { + renderOperator() { const { condition, edit, metric } = this.props; if (!edit) { - return metric.type === 'RATING' ? - translate('quality_gates.operator', condition.op, 'rating') : - translate('quality_gates.operator', condition.op); + return metric.type === 'RATING' + ? translate('quality_gates.operator', condition.op, 'rating') + : translate('quality_gates.operator', condition.op); } if (metric.type === 'RATING') { - return ( - <span className="note">{translate('quality_gates.operator.GT.rating')}</span> - ); + return <span className="note">{translate('quality_gates.operator.GT.rating')}</span>; } const operators = ['LT', 'GT', 'EQ', 'NE']; @@ -208,94 +206,94 @@ export default class Condition extends Component { }); return ( - <Select - ref="operator" - className="input-medium" - name="operator" - value={this.state.op} - clearable={false} - searchable={false} - options={operatorOptions} - onChange={this.handleOperatorChange.bind(this)}/> + <Select + ref="operator" + className="input-medium" + name="operator" + value={this.state.op} + clearable={false} + searchable={false} + options={operatorOptions} + onChange={this.handleOperatorChange.bind(this)} + /> ); } - render () { + render() { const { condition, edit, metric } = this.props; return ( - <tr> - <td className="text-middle nowrap"> - {getLocalizedMetricName(metric)} - {metric.hidden && ( - <span className="text-danger little-spacer-left"> - {translate('deprecated')} - </span> - )} - </td> - - <td className="thin text-middle nowrap"> - {this.renderPeriod()} - </td> - - <td className="thin text-middle nowrap"> - {this.renderOperator()} - </td> - - <td className="thin text-middle nowrap"> - {edit ? ( - <ThresholdInput - name="warning" - value={this.state.warning} - metric={metric} - onChange={value => this.handleWarningChange(value)}/> - ) : formatMeasure(condition.warning, metric.type)} - </td> - + <tr> + <td className="text-middle nowrap"> + {getLocalizedMetricName(metric)} + {metric.hidden && + <span className="text-danger little-spacer-left"> + {translate('deprecated')} + </span>} + </td> + + <td className="thin text-middle nowrap"> + {this.renderPeriod()} + </td> + + <td className="thin text-middle nowrap"> + {this.renderOperator()} + </td> + + <td className="thin text-middle nowrap"> + {edit + ? <ThresholdInput + name="warning" + value={this.state.warning} + metric={metric} + onChange={value => this.handleWarningChange(value)} + /> + : formatMeasure(condition.warning, metric.type)} + </td> + + <td className="thin text-middle nowrap"> + {edit + ? <ThresholdInput + name="error" + value={this.state.error} + metric={metric} + onChange={value => this.handleErrorChange(value)} + /> + : formatMeasure(condition.error, metric.type)} + </td> + + {edit && <td className="thin text-middle nowrap"> - {edit ? ( - <ThresholdInput - name="error" - value={this.state.error} - metric={metric} - onChange={value => this.handleErrorChange(value)}/> - ) : formatMeasure(condition.error, metric.type)} - </td> - - {edit && ( - <td className="thin text-middle nowrap"> - {condition.id ? ( - <div className="button-group"> - <button - className="update-condition" - disabled={!this.state.changed} - onClick={this.handleUpdateClick.bind(this)}> - {translate('update_verb')} - </button> - <button - className="button-red delete-condition" - onClick={this.handleDeleteClick.bind(this)}> - {translate('delete')} - </button> - </div> - ) : ( - <div className="button-group"> - <button - className="add-condition" - onClick={this.handleSaveClick.bind(this)}> - {translate('add_verb')} - </button> - <a - className="action cancel-add-condition" - href="#" - onClick={this.handleCancelClick.bind(this)}> - {translate('cancel')} - </a> - </div> - )} - </td> - )} - - </tr> + {condition.id + ? <div className="button-group"> + <button + className="update-condition" + disabled={!this.state.changed} + onClick={this.handleUpdateClick.bind(this)} + > + {translate('update_verb')} + </button> + <button + className="button-red delete-condition" + onClick={this.handleDeleteClick.bind(this)} + > + {translate('delete')} + </button> + </div> + : <div className="button-group"> + <button className="add-condition" onClick={this.handleSaveClick.bind(this)}> + {translate('add_verb')} + </button> + <a + className="action cancel-add-condition" + href="#" + onClick={this.handleCancelClick.bind(this)} + > + {translate('cancel')} + </a> + </div>} + </td>} + + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js index 435e8f1cbac..48cf7b78752 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js @@ -25,7 +25,7 @@ import AddConditionForm from './AddConditionForm'; import Condition from './Condition'; import { translate, getLocalizedMetricName } from '../../../helpers/l10n'; -function getKey (condition, index) { +function getKey(condition, index) { return condition.id ? condition.id : `new-${index}`; } @@ -34,13 +34,13 @@ export default class Conditions extends React.Component { error: null }; - componentWillUpdate (nextProps) { + componentWillUpdate(nextProps) { if (nextProps.qualityGate !== this.props.qualityGate) { this.setState({ error: null }); } } - handleError (error) { + handleError(error) { try { error.response.json().then(r => { const message = r.errors.map(e => e.msg).join('. '); @@ -51,19 +51,19 @@ export default class Conditions extends React.Component { } } - handleResetError () { + handleResetError() { this.setState({ error: null }); } - render () { + render() { const { - qualityGate, - conditions, - metrics, - edit, - onAddCondition, - onSaveCondition, - onDeleteCondition + qualityGate, + conditions, + metrics, + edit, + onAddCondition, + onSaveCondition, + onDeleteCondition } = this.props; const sortedConditions = sortBy(conditions, condition => { @@ -73,48 +73,45 @@ export default class Conditions extends React.Component { const duplicates = []; const savedConditions = conditions.filter(condition => condition.id != null); savedConditions.forEach(condition => { - const sameCount = savedConditions - .filter(sample => sample.metric === condition.metric && sample.period === condition.period) - .length; + const sameCount = savedConditions.filter( + sample => sample.metric === condition.metric && sample.period === condition.period + ).length; if (sameCount > 1) { duplicates.push(condition); } }); - const uniqDuplicates = uniqBy(duplicates, d => d.metric) - .map(condition => { - const metric = metrics.find(metric => metric.key === condition.metric); - return { ...condition, metric }; - }); + const uniqDuplicates = uniqBy(duplicates, d => d.metric).map(condition => { + const metric = metrics.find(metric => metric.key === condition.metric); + return { ...condition, metric }; + }); return ( - <div id="quality-gate-conditions" className="quality-gate-section"> - <h3 className="spacer-bottom"> - {translate('quality_gates.conditions')} - </h3> + <div id="quality-gate-conditions" className="quality-gate-section"> + <h3 className="spacer-bottom"> + {translate('quality_gates.conditions')} + </h3> - <ConditionsAlert/> + <ConditionsAlert /> - {this.state.error && ( - <div className="alert alert-danger"> - {this.state.error} - </div> - )} + {this.state.error && + <div className="alert alert-danger"> + {this.state.error} + </div>} - {uniqDuplicates.length > 0 && ( - <div className="alert alert-warning"> - <p>{translate('quality_gates.duplicated_conditions')}</p> - <ul className="list-styled spacer-top"> - {uniqDuplicates.map(d => ( - <li key={d.metric.key}>{getLocalizedMetricName(d.metric)}</li> - ))} - </ul> - </div> - )} + {uniqDuplicates.length > 0 && + <div className="alert alert-warning"> + <p>{translate('quality_gates.duplicated_conditions')}</p> + <ul className="list-styled spacer-top"> + {uniqDuplicates.map(d => ( + <li key={d.metric.key}>{getLocalizedMetricName(d.metric)}</li> + ))} + </ul> + </div>} - {sortedConditions.length ? ( - <table id="quality-gate-conditions" className="data zebra zebra-hover"> - <thead> + {sortedConditions.length + ? <table id="quality-gate-conditions" className="data zebra zebra-hover"> + <thead> <tr> <th className="nowrap"> {translate('quality_gates.conditions.metric')} @@ -131,34 +128,31 @@ export default class Conditions extends React.Component { <th className="thin nowrap"> {translate('quality_gates.conditions.error')} </th> - {edit && <th/>} + {edit && <th />} </tr> - </thead> - <tbody> + </thead> + <tbody> {sortedConditions.map((condition, index) => ( - <Condition - key={getKey(condition, index)} - qualityGate={qualityGate} - condition={condition} - metric={metrics.find(metric => metric.key === condition.metric)} - edit={edit} - onSaveCondition={onSaveCondition} - onDeleteCondition={onDeleteCondition} - onError={this.handleError.bind(this)} - onResetError={this.handleResetError.bind(this)}/> + <Condition + key={getKey(condition, index)} + qualityGate={qualityGate} + condition={condition} + metric={metrics.find(metric => metric.key === condition.metric)} + edit={edit} + onSaveCondition={onSaveCondition} + onDeleteCondition={onDeleteCondition} + onError={this.handleError.bind(this)} + onResetError={this.handleResetError.bind(this)} + /> ))} - </tbody> - </table> - ) : ( - <div className="big-spacer-top"> - {translate('quality_gates.no_conditions')} - </div> - )} + </tbody> + </table> + : <div className="big-spacer-top"> + {translate('quality_gates.no_conditions')} + </div>} - {edit && ( - <AddConditionForm metrics={metrics} onSelect={onAddCondition}/> - )} - </div> + {edit && <AddConditionForm metrics={metrics} onSelect={onAddCondition} />} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionsAlert.js b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionsAlert.js index 2d9a606bb5c..a7d754f2028 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionsAlert.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionsAlert.js @@ -25,48 +25,43 @@ export default class ConditionsAlert extends Component { expanded: false }; - handleMoreClick (e) { + handleMoreClick(e) { e.preventDefault(); this.setState({ expanded: true }); } - render () { + render() { const { expanded } = this.state; return ( - <div className="big-spacer-bottom"> - {translate('quality_gates.introduction')} - {!expanded && ( - <a - className="spacer-left" - href="#" - onClick={this.handleMoreClick.bind(this)}> - {translate('more')} - </a> - )} - {expanded && ( - <div className="spacer-top"> - {translate('quality_gates.health_icons')} - <ul> - <li className="little-spacer-top"> - <i className="icon-alert-ok"/> - {' '} - {translate('alerts.notes.ok')} - </li> - <li className="little-spacer-top"> - <i className="icon-alert-warn"/> - {' '} - {translate('alerts.notes.warn')} - </li> - <li className="little-spacer-top"> - <i className="icon-alert-error"/> - {' '} - {translate('alerts.notes.error')} - </li> - </ul> - </div> - )} - </div> + <div className="big-spacer-bottom"> + {translate('quality_gates.introduction')} + {!expanded && + <a className="spacer-left" href="#" onClick={this.handleMoreClick.bind(this)}> + {translate('more')} + </a>} + {expanded && + <div className="spacer-top"> + {translate('quality_gates.health_icons')} + <ul> + <li className="little-spacer-top"> + <i className="icon-alert-ok" /> + {' '} + {translate('alerts.notes.ok')} + </li> + <li className="little-spacer-top"> + <i className="icon-alert-warn" /> + {' '} + {translate('alerts.notes.warn')} + </li> + <li className="little-spacer-top"> + <i className="icon-alert-error" /> + {' '} + {translate('alerts.notes.error')} + </li> + </ul> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js index ef3e1589a41..7d603a8baa1 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js @@ -18,7 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React, { Component } from 'react'; -import { fetchQualityGate, setQualityGateAsDefault, unsetQualityGateAsDefault } from '../../../api/quality-gates'; +import { + fetchQualityGate, + setQualityGateAsDefault, + unsetQualityGateAsDefault +} from '../../../api/quality-gates'; import DetailsHeader from './DetailsHeader'; import DetailsContent from './DetailsContent'; import RenameView from '../views/rename-view'; @@ -26,17 +30,17 @@ import CopyView from '../views/copy-view'; import DeleteView from '../views/delete-view'; export default class Details extends Component { - componentDidMount () { + componentDidMount() { this.fetchDetails(); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.params.id !== this.props.params.id) { this.fetchDetails(); } } - fetchDetails () { + fetchDetails() { const { id } = this.props.params; const { onShow } = this.props; @@ -45,7 +49,7 @@ export default class Details extends Component { }); } - handleRenameClick () { + handleRenameClick() { const { qualityGate, onRename } = this.props; new RenameView({ @@ -56,7 +60,7 @@ export default class Details extends Component { }).render(); } - handleCopyClick () { + handleCopyClick() { const { qualityGate, onCopy } = this.props; const { router } = this.context; @@ -69,19 +73,17 @@ export default class Details extends Component { }).render(); } - handleSetAsDefaultClick () { + handleSetAsDefaultClick() { const { qualityGate, onSetAsDefault, onUnsetAsDefault } = this.props; if (qualityGate.isDefault) { - unsetQualityGateAsDefault(qualityGate.id) - .then(() => onUnsetAsDefault(qualityGate)); + unsetQualityGateAsDefault(qualityGate.id).then(() => onUnsetAsDefault(qualityGate)); } else { - setQualityGateAsDefault(qualityGate.id) - .then(() => onSetAsDefault(qualityGate)); + setQualityGateAsDefault(qualityGate.id).then(() => onSetAsDefault(qualityGate)); } } - handleDeleteClick () { + handleDeleteClick() { const { qualityGate, onDelete } = this.props; const { router } = this.context; @@ -94,39 +96,41 @@ export default class Details extends Component { }).render(); } - render () { + render() { const { qualityGate, edit, metrics } = this.props; const { onAddCondition, onDeleteCondition, onSaveCondition } = this.props; if (!qualityGate) { return ( - <div className="search-navigator-workspace"> - <div className="search-navigator-workspace-header" style={{ top: 30 }}> - <h2 className="search-navigator-header-component"> </h2> - </div> - <div className="search-navigator-workspace-details"/> + <div className="search-navigator-workspace"> + <div className="search-navigator-workspace-header" style={{ top: 30 }}> + <h2 className="search-navigator-header-component"> </h2> </div> + <div className="search-navigator-workspace-details" /> + </div> ); } return ( - <div className="search-navigator-workspace"> - <DetailsHeader - qualityGate={qualityGate} - edit={edit} - onRename={this.handleRenameClick.bind(this)} - onCopy={this.handleCopyClick.bind(this)} - onSetAsDefault={this.handleSetAsDefaultClick.bind(this)} - onDelete={this.handleDeleteClick.bind(this)}/> - - <DetailsContent - gate={qualityGate} - canEdit={edit} - metrics={metrics} - onAddCondition={onAddCondition} - onSaveCondition={onSaveCondition} - onDeleteCondition={onDeleteCondition}/> - </div> + <div className="search-navigator-workspace"> + <DetailsHeader + qualityGate={qualityGate} + edit={edit} + onRename={this.handleRenameClick.bind(this)} + onCopy={this.handleCopyClick.bind(this)} + onSetAsDefault={this.handleSetAsDefaultClick.bind(this)} + onDelete={this.handleDeleteClick.bind(this)} + /> + + <DetailsContent + gate={qualityGate} + canEdit={edit} + metrics={metrics} + onAddCondition={onAddCondition} + onSaveCondition={onSaveCondition} + onDeleteCondition={onDeleteCondition} + /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js index 58e632a3455..a2cfd55fb01 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js @@ -23,41 +23,34 @@ import Projects from './Projects'; import { translate } from '../../../helpers/l10n'; export default class DetailsContent extends Component { - render () { + render() { const { gate, canEdit, metrics } = this.props; const { onAddCondition, onDeleteCondition, onSaveCondition } = this.props; const conditions = gate.conditions || []; - const defaultMessage = canEdit ? - translate('quality_gates.projects_for_default.edit') : - translate('quality_gates.projects_for_default'); + const defaultMessage = canEdit + ? translate('quality_gates.projects_for_default.edit') + : translate('quality_gates.projects_for_default'); return ( - <div - ref="container" - className="search-navigator-workspace-details"> - <Conditions - qualityGate={gate} - conditions={conditions} - metrics={metrics} - edit={canEdit} - onAddCondition={onAddCondition} - onSaveCondition={onSaveCondition} - onDeleteCondition={onDeleteCondition}/> + <div ref="container" className="search-navigator-workspace-details"> + <Conditions + qualityGate={gate} + conditions={conditions} + metrics={metrics} + edit={canEdit} + onAddCondition={onAddCondition} + onSaveCondition={onSaveCondition} + onDeleteCondition={onDeleteCondition} + /> - <div id="quality-gate-projects" className="quality-gate-section"> - <h3 className="spacer-bottom"> - {translate('quality_gates.projects')} - </h3> - {gate.isDefault ? ( - defaultMessage - ) : ( - <Projects - qualityGate={gate} - edit={canEdit}/> - )} - </div> + <div id="quality-gate-projects" className="quality-gate-section"> + <h3 className="spacer-bottom"> + {translate('quality_gates.projects')} + </h3> + {gate.isDefault ? defaultMessage : <Projects qualityGate={gate} edit={canEdit} />} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.js b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.js index 68d80c12fa4..0831488c196 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.js @@ -20,57 +20,49 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; -export default function DetailsHeader ({ qualityGate, edit, onRename, onCopy, onSetAsDefault, onDelete }) { - function handleRenameClick (e) { +export default function DetailsHeader( + { qualityGate, edit, onRename, onCopy, onSetAsDefault, onDelete } +) { + function handleRenameClick(e) { e.preventDefault(); onRename(); } - function handleCopyClick (e) { + function handleCopyClick(e) { e.preventDefault(); onCopy(); } - function handleSetAsDefaultClick (e) { + function handleSetAsDefaultClick(e) { e.preventDefault(); onSetAsDefault(); } - function handleDeleteClick (e) { + function handleDeleteClick(e) { e.preventDefault(); onDelete(); } return ( - <div className="search-navigator-workspace-header" style={{ top: 30 }}> - <h2 className="search-navigator-header-component">{qualityGate.name}</h2> - {edit && ( - <div className="search-navigator-header-actions"> - <div className="button-group"> - <button - id="quality-gate-rename" - onClick={handleRenameClick}> - {translate('rename')} - </button> - <button - id="quality-gate-copy" - onClick={handleCopyClick}> - {translate('copy')} - </button> - <button - id="quality-gate-toggle-default" - onClick={handleSetAsDefaultClick}> - {qualityGate.isDefault ? translate('unset_as_default') : translate('set_as_default')} - </button> - <button - id="quality-gate-delete" - className="button-red" - onClick={handleDeleteClick}> - {translate('delete')} - </button> - </div> - </div> - )} - </div> + <div className="search-navigator-workspace-header" style={{ top: 30 }}> + <h2 className="search-navigator-header-component">{qualityGate.name}</h2> + {edit && + <div className="search-navigator-header-actions"> + <div className="button-group"> + <button id="quality-gate-rename" onClick={handleRenameClick}> + {translate('rename')} + </button> + <button id="quality-gate-copy" onClick={handleCopyClick}> + {translate('copy')} + </button> + <button id="quality-gate-toggle-default" onClick={handleSetAsDefaultClick}> + {qualityGate.isDefault ? translate('unset_as_default') : translate('set_as_default')} + </button> + <button id="quality-gate-delete" className="button-red" onClick={handleDeleteClick}> + {translate('delete')} + </button> + </div> + </div>} + </div> ); } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Intro.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Intro.js index 19ff5896be6..e1c4c262097 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Intro.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Intro.js @@ -20,13 +20,13 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; -export default function Intro () { +export default function Intro() { return ( - <div className="search-navigator-workspace"> - <div className="search-navigator-intro markdown"> - <p>{translate('quality_gates.intro.1')}</p> - <p>{translate('quality_gates.intro.2')}</p> - </div> + <div className="search-navigator-workspace"> + <div className="search-navigator-intro markdown"> + <p>{translate('quality_gates.intro.1')}</p> + <p>{translate('quality_gates.intro.2')}</p> </div> + </div> ); } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/List.js b/server/sonar-web/src/main/js/apps/quality-gates/components/List.js index 5be37fc4560..2b00fc48dd6 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/List.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/List.js @@ -21,32 +21,32 @@ import React from 'react'; import { Link } from 'react-router'; import { translate } from '../../../helpers/l10n'; -export default function List ({ qualityGates }) { +export default function List({ qualityGates }) { return ( - <div className="list-group"> - {qualityGates.map(qualityGate => ( - <Link - key={qualityGate.id} - to={`/quality_gates/show/${qualityGate.id}`} - activeClassName="active" - className="list-group-item" - data-id={qualityGate.id}> - <table> - <tbody> - <tr> - <td className="text-top"> - {qualityGate.name} - </td> - <td className="text-top thin nowrap spacer-left"> - {qualityGate.isDefault && ( - <span className="badge pull-right">{translate('default')}</span> - )} - </td> - </tr> - </tbody> - </table> - </Link> - ))} - </div> + <div className="list-group"> + {qualityGates.map(qualityGate => ( + <Link + key={qualityGate.id} + to={`/quality_gates/show/${qualityGate.id}`} + activeClassName="active" + className="list-group-item" + data-id={qualityGate.id} + > + <table> + <tbody> + <tr> + <td className="text-top"> + {qualityGate.name} + </td> + <td className="text-top thin nowrap spacer-left"> + {qualityGate.isDefault && + <span className="badge pull-right">{translate('default')}</span>} + </td> + </tr> + </tbody> + </table> + </Link> + ))} + </div> ); } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.js b/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.js index e0dc5e30bd9..2c48ed591a3 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ListHeader.js @@ -21,24 +21,23 @@ import React from 'react'; import CreateView from '../views/create-view'; import { translate } from '../../../helpers/l10n'; -export default function ListHeader ({ canEdit, onAdd }) { - function handleAddClick (e) { +export default function ListHeader({ canEdit, onAdd }) { + function handleAddClick(e) { e.preventDefault(); new CreateView({ onAdd }).render(); } return ( - <div> - <h1 className="page-title">{translate('quality_gates.page')}</h1> - {canEdit && ( - <div className="page-actions"> - <div className="button-group"> - <button id="quality-gate-add" onClick={handleAddClick}> - {translate('create')} - </button> - </div> - </div> - )} - </div> + <div> + <h1 className="page-title">{translate('quality_gates.page')}</h1> + {canEdit && + <div className="page-actions"> + <div className="button-group"> + <button id="quality-gate-add" onClick={handleAddClick}> + {translate('create')} + </button> + </div> + </div>} + </div> ); } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js index cc1cfbc192f..1d9cee71918 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js @@ -21,23 +21,23 @@ import React, { Component } from 'react'; import ProjectsView from '../views/gate-projects-view'; export default class Projects extends Component { - componentDidMount () { + componentDidMount() { this.renderView(); } - componentWillUpdate () { + componentWillUpdate() { this.destroyView(); } - componentDidUpdate () { + componentDidUpdate() { this.renderView(); } - componentWillUnmount () { + componentWillUnmount() { this.destroyView(); } - renderView () { + renderView() { const { qualityGate, edit } = this.props; this.projectsView = new ProjectsView({ @@ -48,15 +48,13 @@ export default class Projects extends Component { this.projectsView.render(); } - destroyView () { + destroyView() { if (this.projectsView) { this.projectsView.destroy(); } } - render () { - return ( - <div ref="container"/> - ); + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js index a261aa2142a..cb7ec0746fb 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js @@ -21,22 +21,19 @@ import React, { Component } from 'react'; import ListHeader from './ListHeader'; import List from './List'; import { - fetchQualityGatesAppDetails, - fetchQualityGates as fetchQualityGatesAPI + fetchQualityGatesAppDetails, + fetchQualityGates as fetchQualityGatesAPI } from '../../../api/quality-gates'; export default class QualityGatesApp extends Component { state = {}; - componentDidMount () { + componentDidMount() { this.fetchQualityGates(); } - fetchQualityGates () { - Promise.all([ - fetchQualityGatesAppDetails(), - fetchQualityGatesAPI() - ]).then(responses => { + fetchQualityGates() { + Promise.all([fetchQualityGatesAppDetails(), fetchQualityGatesAPI()]).then(responses => { const [details, qualityGates] = responses; const { updateStore } = this.props; @@ -44,7 +41,7 @@ export default class QualityGatesApp extends Component { }); } - handleAdd (qualityGate) { + handleAdd(qualityGate) { const { addQualityGate } = this.props; const { router } = this.context; @@ -52,24 +49,22 @@ export default class QualityGatesApp extends Component { router.push(`/quality_gates/show/${qualityGate.id}`); } - render () { + render() { const { children, qualityGates, edit } = this.props; return ( - <div className="search-navigator sticky search-navigator-extended-view"> - <div className="search-navigator-side search-navigator-side-light" style={{ top: 30 }}> - <div className="search-navigator-filters"> - <ListHeader - canEdit={edit} - onAdd={this.handleAdd.bind(this)}/> - </div> - <div className="quality-gates-results panel"> - {qualityGates && <List qualityGates={qualityGates}/>} - </div> + <div className="search-navigator sticky search-navigator-extended-view"> + <div className="search-navigator-side search-navigator-side-light" style={{ top: 30 }}> + <div className="search-navigator-filters"> + <ListHeader canEdit={edit} onAdd={this.handleAdd.bind(this)} /> + </div> + <div className="quality-gates-results panel"> + {qualityGates && <List qualityGates={qualityGates} />} </div> - - {!!qualityGates && children} </div> + + {!!qualityGates && children} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js b/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js index 68b12aa73db..43e3630fc4e 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js @@ -40,7 +40,7 @@ export default class ThresholdInput extends React.Component { } }; - renderRatingInput () { + renderRatingInput() { const { name, value } = this.props; const options = [ @@ -53,18 +53,19 @@ export default class ThresholdInput extends React.Component { const realValue = value === '' ? null : value; return ( - <Select - className="input-tiny text-middle" - name={name} - value={realValue} - options={options} - searchable={false} - placeholder="" - onChange={this.handleSelectChange}/> + <Select + className="input-tiny text-middle" + name={name} + value={realValue} + options={options} + searchable={false} + placeholder="" + onChange={this.handleSelectChange} + /> ); } - render () { + render() { const { name, value, metric } = this.props; if (metric.type === 'RATING') { @@ -72,14 +73,15 @@ export default class ThresholdInput extends React.Component { } return ( - <input - name={name} - type="text" - className="input-tiny text-middle" - value={value} - data-type={metric.type} - placeholder={metric.placeholder} - onChange={this.handleChange}/> + <input + name={name} + type="text" + className="input-tiny text-middle" + value={value} + data-type={metric.type} + placeholder={metric.placeholder} + onChange={this.handleChange} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js index b0ca0801102..738b63fc2b7 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js @@ -26,11 +26,7 @@ import { change } from '../../../../helpers/testUtils'; describe('on strings', () => { it('should render text input', () => { const input = shallow( - <ThresholdInput - name="foo" - value="2" - metric={{ type: 'INTEGER' }} - onChange={jest.fn()}/> + <ThresholdInput name="foo" value="2" metric={{ type: 'INTEGER' }} onChange={jest.fn()} /> ).find('input'); expect(input.length).toEqual(1); expect(input.prop('name')).toEqual('foo'); @@ -40,11 +36,7 @@ describe('on strings', () => { it('should change', () => { const onChange = jest.fn(); const input = shallow( - <ThresholdInput - name="foo" - value="2" - metric={{ type: 'INTEGER' }} - onChange={onChange}/> + <ThresholdInput name="foo" value="2" metric={{ type: 'INTEGER' }} onChange={onChange} /> ).find('input'); change(input, 'bar'); expect(onChange).toBeCalledWith('bar'); @@ -54,11 +46,7 @@ describe('on strings', () => { describe('on ratings', () => { it('should render Select', () => { const select = shallow( - <ThresholdInput - name="foo" - value="2" - metric={{ type: 'RATING' }} - onChange={jest.fn()}/> + <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={jest.fn()} /> ).find(Select); expect(select.length).toEqual(1); expect(select.prop('value')).toEqual('2'); @@ -67,11 +55,7 @@ describe('on ratings', () => { it('should set', () => { const onChange = jest.fn(); const select = shallow( - <ThresholdInput - name="foo" - value="2" - metric={{ type: 'RATING' }} - onChange={onChange}/> + <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={onChange} /> ).find(Select); select.prop('onChange')({ label: 'D', value: '4' }); expect(onChange).toBeCalledWith('4'); @@ -80,11 +64,7 @@ describe('on ratings', () => { it('should unset', () => { const onChange = jest.fn(); const select = shallow( - <ThresholdInput - name="foo" - value="2" - metric={{ type: 'RATING' }} - onChange={onChange}/> + <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={onChange} /> ).find(Select); select.prop('onChange')(null); expect(onChange).toBeCalledWith(''); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js b/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js index 623b238d399..85083752c90 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/containers/DetailsContainer.js @@ -32,9 +32,7 @@ import { import Details from '../components/Details'; import { getQualityGatesAppState } from '../../../store/rootReducer'; -const mapStateToProps = state => ( - getQualityGatesAppState(state) -); +const mapStateToProps = state => getQualityGatesAppState(state); const mapDispatchToProps = dispatch => ({ onShow: qualityGate => dispatch(showQualityGate(qualityGate)), @@ -44,11 +42,9 @@ const mapDispatchToProps = dispatch => ({ onSetAsDefault: qualityGate => dispatch(setQualityGateAsDefault(qualityGate)), onUnsetAsDefault: qualityGate => dispatch(unsetQualityGateAsDefault(qualityGate)), onAddCondition: metric => dispatch(addCondition(metric)), - onSaveCondition: (oldCondition, newCondition) => dispatch(saveCondition(oldCondition, newCondition)), + onSaveCondition: (oldCondition, newCondition) => + dispatch(saveCondition(oldCondition, newCondition)), onDeleteCondition: condition => dispatch(deleteCondition(condition)) }); -export default connect( - mapStateToProps, - mapDispatchToProps -)(Details); +export default connect(mapStateToProps, mapDispatchToProps)(Details); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js b/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js index 27a4c349117..6574fa7324f 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/containers/QualityGatesAppContainer.js @@ -22,9 +22,7 @@ import { setState, addQualityGate, deleteQualityGate } from '../store/actions'; import QualityGateApp from '../components/QualityGatesApp'; import { getQualityGatesAppState } from '../../../store/rootReducer'; -const mapStateToProps = state => ( - getQualityGatesAppState(state) -); +const mapStateToProps = state => getQualityGatesAppState(state); const mapDispatchToProps = dispatch => ({ updateStore: nextState => dispatch(setState(nextState)), @@ -32,7 +30,4 @@ const mapDispatchToProps = dispatch => ({ deleteQualityGate: qualityGate => dispatch(deleteQualityGate(qualityGate)) }); -export default connect( - mapStateToProps, - mapDispatchToProps -)(QualityGateApp); +export default connect(mapStateToProps, mapDispatchToProps)(QualityGateApp); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/routes.js b/server/sonar-web/src/main/js/apps/quality-gates/routes.js index c271827b58c..7c6b54381b2 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/routes.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/routes.js @@ -24,10 +24,10 @@ import Intro from './components/Intro'; import DetailsContainer from './containers/DetailsContainer'; export default ( - <Route component={QualityGatesAppContainer}> - <Redirect from="/quality_gates/index" to="/quality_gates/"/> + <Route component={QualityGatesAppContainer}> + <Redirect from="/quality_gates/index" to="/quality_gates/" /> - <IndexRoute component={Intro}/> - <Route path="show/:id" component={DetailsContainer}/> - </Route> + <IndexRoute component={Intro} /> + <Route path="show/:id" component={DetailsContainer} /> + </Route> ); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js b/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js index dc5c91b2ad9..0dcea3223d1 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ export const SET_STATE = 'qualityGates/SET_STATE'; -export function setState (nextState) { +export function setState(nextState) { return { type: SET_STATE, nextState @@ -26,7 +26,7 @@ export function setState (nextState) { } export const ADD = 'qualityGates/ADD'; -export function addQualityGate (qualityGate) { +export function addQualityGate(qualityGate) { return { type: ADD, qualityGate @@ -34,7 +34,7 @@ export function addQualityGate (qualityGate) { } export const DELETE = 'qualityGates/DELETE'; -export function deleteQualityGate (qualityGate) { +export function deleteQualityGate(qualityGate) { return { type: DELETE, qualityGate @@ -42,7 +42,7 @@ export function deleteQualityGate (qualityGate) { } export const SHOW = 'qualityGates/SHOW'; -export function showQualityGate (qualityGate) { +export function showQualityGate(qualityGate) { return { type: SHOW, qualityGate @@ -50,7 +50,7 @@ export function showQualityGate (qualityGate) { } export const RENAME = 'qualityGates/RENAME'; -export function renameQualityGate (qualityGate, newName) { +export function renameQualityGate(qualityGate, newName) { return { type: RENAME, qualityGate, @@ -59,7 +59,7 @@ export function renameQualityGate (qualityGate, newName) { } export const COPY = 'qualityGates/COPY'; -export function copyQualityGate (qualityGate) { +export function copyQualityGate(qualityGate) { return { type: COPY, qualityGate @@ -67,7 +67,7 @@ export function copyQualityGate (qualityGate) { } export const SET_AS_DEFAULT = 'SET_AS_DEFAULT'; -export function setQualityGateAsDefault (qualityGate) { +export function setQualityGateAsDefault(qualityGate) { return { type: SET_AS_DEFAULT, qualityGate @@ -75,7 +75,7 @@ export function setQualityGateAsDefault (qualityGate) { } export const UNSET_AS_DEFAULT = 'qualityGates/UNSET_AS_DEFAULT'; -export function unsetQualityGateAsDefault (qualityGate) { +export function unsetQualityGateAsDefault(qualityGate) { return { type: UNSET_AS_DEFAULT, qualityGate @@ -83,7 +83,7 @@ export function unsetQualityGateAsDefault (qualityGate) { } export const ADD_CONDITION = 'qualityGates/ADD_CONDITION'; -export function addCondition (metric) { +export function addCondition(metric) { return { type: ADD_CONDITION, metric @@ -91,7 +91,7 @@ export function addCondition (metric) { } export const SAVE_CONDITION = 'qualityGates/SAVE_CONDITION'; -export function saveCondition (oldCondition, newCondition) { +export function saveCondition(oldCondition, newCondition) { return { type: SAVE_CONDITION, oldCondition, @@ -100,7 +100,7 @@ export function saveCondition (oldCondition, newCondition) { } export const DELETE_CONDITION = 'qualityGates/DELETE_CONDITION'; -export function deleteCondition (condition) { +export function deleteCondition(condition) { return { type: DELETE_CONDITION, condition diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js b/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js index 5b55ff64969..05fc9df3e65 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js @@ -18,23 +18,23 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { - SET_STATE, - ADD, - DELETE, - SHOW, - RENAME, - COPY, - SET_AS_DEFAULT, - UNSET_AS_DEFAULT, - ADD_CONDITION, - DELETE_CONDITION, - SAVE_CONDITION + SET_STATE, + ADD, + DELETE, + SHOW, + RENAME, + COPY, + SET_AS_DEFAULT, + UNSET_AS_DEFAULT, + ADD_CONDITION, + DELETE_CONDITION, + SAVE_CONDITION } from './actions'; import { checkIfDefault, addCondition, deleteCondition, replaceCondition } from './utils'; const initialState = {}; -export default function rootReducer (state = initialState, action = {}) { +export default function rootReducer(state = initialState, action = {}) { switch (action.type) { case SET_STATE: return { ...state, ...action.nextState }; @@ -42,17 +42,25 @@ export default function rootReducer (state = initialState, action = {}) { case COPY: return { ...state, qualityGates: [...state.qualityGates, action.qualityGate] }; case DELETE: - return { ...state, qualityGates: state.qualityGates.filter(candidate => candidate.id !== action.qualityGate.id) }; + return { + ...state, + qualityGates: state.qualityGates.filter(candidate => candidate.id !== action.qualityGate.id) + }; case SHOW: return { ...state, - qualityGate: { ...action.qualityGate, isDefault: checkIfDefault(action.qualityGate, state.qualityGates) } + qualityGate: { + ...action.qualityGate, + isDefault: checkIfDefault(action.qualityGate, state.qualityGates) + } }; case RENAME: return { ...state, qualityGates: state.qualityGates.map(candidate => { - return candidate.id === action.qualityGate.id ? { ...candidate, name: action.newName } : candidate; + return candidate.id === action.qualityGate.id + ? { ...candidate, name: action.newName } + : candidate; }), qualityGate: { ...state.qualityGate, name: action.newName } }; @@ -62,13 +70,18 @@ export default function rootReducer (state = initialState, action = {}) { qualityGates: state.qualityGates.map(candidate => { return { ...candidate, isDefault: candidate.id === action.qualityGate.id }; }), - qualityGate: { ...state.qualityGate, isDefault: state.qualityGate.id === action.qualityGate.id } + qualityGate: { + ...state.qualityGate, + isDefault: state.qualityGate.id === action.qualityGate.id + } }; case UNSET_AS_DEFAULT: return { ...state, qualityGates: state.qualityGates.map(candidate => { - return candidate.id === action.qualityGate.id ? { ...candidate, isDefault: false } : candidate; + return candidate.id === action.qualityGate.id + ? { ...candidate, isDefault: false } + : candidate; }), qualityGate: { ...state.qualityGate, isDefault: false } }; diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/utils.js b/server/sonar-web/src/main/js/apps/quality-gates/store/utils.js index 761a5e08526..db4efa9de9c 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/store/utils.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/store/utils.js @@ -17,13 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export function checkIfDefault (qualityGate, list) { +export function checkIfDefault(qualityGate, list) { const finding = list.find(candidate => candidate.id === qualityGate.id); return finding ? finding.isDefault : false; } -export function addCondition (qualityGate, metric) { +export function addCondition(qualityGate, metric) { const condition = { metric, op: 'LT', @@ -36,17 +36,15 @@ export function addCondition (qualityGate, metric) { return { ...qualityGate, conditions }; } -export function deleteCondition (qualityGate, condition) { - const conditions = qualityGate.conditions - .filter(candidate => candidate !== condition); +export function deleteCondition(qualityGate, condition) { + const conditions = qualityGate.conditions.filter(candidate => candidate !== condition); return { ...qualityGate, conditions }; } -export function replaceCondition (qualityGate, oldCondition, newCondition) { - const conditions = qualityGate.conditions - .map(candidate => { - return candidate === oldCondition ? newCondition : candidate; - }); +export function replaceCondition(qualityGate, oldCondition, newCondition) { + const conditions = qualityGate.conditions.map(candidate => { + return candidate === oldCondition ? newCondition : candidate; + }); return { ...qualityGate, conditions }; } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/copy-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/copy-view.js index 684f33a882f..56e431a1d1c 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/views/copy-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/views/copy-view.js @@ -25,13 +25,13 @@ import { parseError } from '../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { const { id } = this.options.qualityGate; const name = this.$('#quality-gate-form-name').val(); @@ -47,8 +47,7 @@ export default ModalForm.extend({ ); }, - serializeData () { + serializeData() { return { method: 'copy', ...this.options.qualityGate }; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/create-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/create-view.js index ba8bb4ec3fc..52857783c48 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/views/create-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/views/create-view.js @@ -25,13 +25,13 @@ import { parseError } from '../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { const name = this.$('#quality-gate-form-name').val(); createQualityGate(name).then( @@ -46,8 +46,7 @@ export default ModalForm.extend({ ); }, - serializeData () { + serializeData() { return { method: 'create' }; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/delete-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/delete-view.js index 097193486c9..35968644518 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/views/delete-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/views/delete-view.js @@ -25,13 +25,13 @@ import { parseError } from '../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { const { id } = this.options.qualityGate; deleteQualityGate(id).then( @@ -46,8 +46,7 @@ export default ModalForm.extend({ ); }, - serializeData () { + serializeData() { return this.options.qualityGate; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js index 8a2e78abbe9..6ab82044087 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js @@ -26,13 +26,13 @@ import { parseError } from '../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { return deleteCondition(this.options.condition.id).then( () => { this.destroy(); @@ -45,11 +45,10 @@ export default ModalForm.extend({ ); }, - serializeData () { + serializeData() { return { metric: this.options.metric, localizedMetricName: getLocalizedMetricName(this.options.metric) }; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js index 88bcad4d847..fa9d4cc1aba 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js @@ -25,7 +25,7 @@ import { translate } from '../../../helpers/l10n'; export default Marionette.ItemView.extend({ template: Template, - onRender () { + onRender() { const { qualityGate } = this.options; new window.SelectList({ @@ -33,7 +33,7 @@ export default Marionette.ItemView.extend({ width: '100%', readOnly: !this.options.edit, focusSearch: false, - format (item) { + format(item) { return item.name; }, searchUrl: window.baseUrl + '/api/qualitygates/search?gateId=' + qualityGate.id, @@ -57,7 +57,7 @@ export default Marionette.ItemView.extend({ }); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), canEdit: this.options.edit diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/rename-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/rename-view.js index 75ffc986086..acc5f71c4d3 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/views/rename-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/views/rename-view.js @@ -25,13 +25,13 @@ import { parseError } from '../../code/utils'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { const { id } = this.options.qualityGate; const name = this.$('#quality-gate-form-name').val(); @@ -47,8 +47,7 @@ export default ModalForm.extend({ ); }, - serializeData () { + serializeData() { return { method: 'rename', ...this.options.qualityGate }; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js index fa80a900211..d79a8d705a1 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/__tests__/utils-test.js @@ -19,11 +19,11 @@ */ import { sortProfiles } from '../utils'; -function createProfile (key, parentKey) { +function createProfile(key, parentKey) { return { name: key, key, parentKey }; } -function checkOrder (list, order) { +function checkOrder(list, order) { const listKeys = list.map(item => item.key); expect(listKeys).toEqual(order); } @@ -33,39 +33,27 @@ describe('#sortProfiles', () => { const profile1 = createProfile('profile1'); const profile2 = createProfile('profile2'); const profile3 = createProfile('profile3'); - checkOrder( - sortProfiles([profile1, profile2, profile3]), - ['profile1', 'profile2', 'profile3'] - ); + checkOrder(sortProfiles([profile1, profile2, profile3]), ['profile1', 'profile2', 'profile3']); }); it('should sort by name', () => { const profile1 = createProfile('profile1'); const profile2 = createProfile('profile2'); const profile3 = createProfile('profile3'); - checkOrder( - sortProfiles([profile3, profile1, profile2]), - ['profile1', 'profile2', 'profile3'] - ); + checkOrder(sortProfiles([profile3, profile1, profile2]), ['profile1', 'profile2', 'profile3']); }); it('should sort with children', () => { const child1 = createProfile('child1', 'parent'); const child2 = createProfile('child2', 'parent'); const parent = createProfile('parent'); - checkOrder( - sortProfiles([child1, child2, parent]), - ['parent', 'child1', 'child2'] - ); + checkOrder(sortProfiles([child1, child2, parent]), ['parent', 'child1', 'child2']); }); it('should sort single branch', () => { const profile1 = createProfile('profile1'); const profile2 = createProfile('profile2', 'profile3'); const profile3 = createProfile('profile3', 'profile1'); - checkOrder( - sortProfiles([profile3, profile2, profile1]), - ['profile1', 'profile3', 'profile2'] - ); + checkOrder(sortProfiles([profile3, profile2, profile1]), ['profile1', 'profile3', 'profile2']); }); }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js index aae490f8039..cd70278214d 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/Changelog.js @@ -29,17 +29,16 @@ export default class Changelog extends React.Component { events: React.PropTypes.array.isRequired }; - render () { + render() { let isEvenRow = false; const rows = this.props.events.map((event, index) => { const prev = index > 0 ? this.props.events[index - 1] : null; const isSameDate = prev != null && moment(prev.date).diff(event.date, 'seconds') < 10; - const isBulkChange = - prev != null && - isSameDate && - prev.authorName === event.authorName && - prev.action === event.action; + const isBulkChange = prev != null && + isSameDate && + prev.authorName === event.authorName && + prev.action === event.action; if (!isBulkChange) { isEvenRow = !isEvenRow; @@ -48,57 +47,52 @@ export default class Changelog extends React.Component { const className = 'js-profile-changelog-event ' + (isEvenRow ? 'even' : 'odd'); return ( - <tr key={index} className={className}> - <td className="thin nowrap"> - {!isBulkChange && moment(event.date).format('LLL')} - </td> + <tr key={index} className={className}> + <td className="thin nowrap"> + {!isBulkChange && moment(event.date).format('LLL')} + </td> - <td className="thin nowrap"> - {!isBulkChange && ( - event.authorName ? ( - <span>{event.authorName}</span> - ) : ( - <span className="note">System</span> - ) - )} - </td> + <td className="thin nowrap"> + {!isBulkChange && + (event.authorName + ? <span>{event.authorName}</span> + : <span className="note">System</span>)} + </td> - <td className="thin nowrap"> - {!isBulkChange && ( - translate('quality_profiles.changelog', event.action) - )} - </td> + <td className="thin nowrap"> + {!isBulkChange && translate('quality_profiles.changelog', event.action)} + </td> - <td style={{ lineHeight: '1.5' }}> - <Link to={getRulesUrl({ 'rule_key': event.ruleKey })}> - {event.ruleName} - </Link> - </td> + <td style={{ lineHeight: '1.5' }}> + <Link to={getRulesUrl({ rule_key: event.ruleKey })}> + {event.ruleName} + </Link> + </td> - <td className="thin nowrap"> - <ChangesList changes={event.params}/> - </td> - </tr> + <td className="thin nowrap"> + <ChangesList changes={event.params} /> + </td> + </tr> ); }); return ( - <table className="data zebra-hover"> - <thead> - <tr> - <th className="thin nowrap"> - {translate('date')} - {' '} - <i className="icon-sort-desc"/> - </th> - <th className="thin nowrap">{translate('user')}</th> - <th className="thin nowrap">{translate('action')}</th> - <th>{translate('rule')}</th> - <th className="thin nowrap">{translate('parameters')}</th> - </tr> - </thead> - <tbody>{rows}</tbody> - </table> + <table className="data zebra-hover"> + <thead> + <tr> + <th className="thin nowrap"> + {translate('date')} + {' '} + <i className="icon-sort-desc" /> + </th> + <th className="thin nowrap">{translate('user')}</th> + <th className="thin nowrap">{translate('action')}</th> + <th>{translate('rule')}</th> + <th className="thin nowrap">{translate('parameters')}</th> + </tr> + </thead> + <tbody>{rows}</tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js index 69efa080546..8de4383ca42 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogContainer.js @@ -39,28 +39,28 @@ export default class ChangelogContainer extends React.Component { loading: true }; - componentWillMount () { + componentWillMount() { this.handleFromDateChange = this.handleFromDateChange.bind(this); this.handleToDateChange = this.handleToDateChange.bind(this); this.handleReset = this.handleReset.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadChangelog(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.location !== this.props.location) { this.loadChangelog(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadChangelog () { + loadChangelog() { this.setState({ loading: true }); const { query } = this.props.location; const data = { profileKey: this.props.profile.key }; @@ -83,7 +83,7 @@ export default class ChangelogContainer extends React.Component { }); } - loadMore (e) { + loadMore(e) { e.preventDefault(); e.target.blur(); @@ -112,58 +112,54 @@ export default class ChangelogContainer extends React.Component { }); } - handleFromDateChange (fromDate) { + handleFromDateChange(fromDate) { const query = { ...this.props.location.query, since: fromDate }; this.context.router.push({ pathname: '/profiles/changelog', query }); } - handleToDateChange (toDate) { + handleToDateChange(toDate) { const query = { ...this.props.location.query, to: toDate }; this.context.router.push({ pathname: '/profiles/changelog', query }); } - handleReset () { + handleReset() { const query = { key: this.props.profile.key }; this.context.router.push({ pathname: '/profiles/changelog', query }); } - render () { + render() { const { query } = this.props.location; const shouldDisplayFooter = this.state.events != null && - this.state.events.length < this.state.total; + this.state.events.length < this.state.total; return ( - <div className="quality-profile-box js-profile-changelog"> - <header className="spacer-bottom"> - <ChangelogSearch - fromDate={query.since} - toDate={query.to} - onFromDateChange={this.handleFromDateChange} - onToDateChange={this.handleToDateChange} - onReset={this.handleReset}/> - - {this.state.loading && ( - <i className="spinner spacer-left"/> - )} - </header> - - {this.state.events != null && this.state.events.length === 0 && ( - <ChangelogEmpty/> - )} - - {this.state.events != null && this.state.events.length > 0 && ( - <Changelog events={this.state.events}/> - )} - - {shouldDisplayFooter && ( - <footer className="text-center spacer-top small"> - <a href="#" onClick={this.loadMore.bind(this)}> - {translate('show_more')} - </a> - </footer> - )} - </div> + <div className="quality-profile-box js-profile-changelog"> + <header className="spacer-bottom"> + <ChangelogSearch + fromDate={query.since} + toDate={query.to} + onFromDateChange={this.handleFromDateChange} + onToDateChange={this.handleToDateChange} + onReset={this.handleReset} + /> + + {this.state.loading && <i className="spinner spacer-left" />} + </header> + + {this.state.events != null && this.state.events.length === 0 && <ChangelogEmpty />} + + {this.state.events != null && + this.state.events.length > 0 && + <Changelog events={this.state.events} />} + + {shouldDisplayFooter && + <footer className="text-center spacer-top small"> + <a href="#" onClick={this.loadMore.bind(this)}> + {translate('show_more')} + </a> + </footer>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js index fd8794f9f2d..1baf1d73e4f 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogEmpty.js @@ -21,7 +21,7 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class ChangelogEmpty extends React.Component { - render () { + render() { return ( <div className="big-spacer-top"> {translate('no_results')} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js index 814bca6f518..1106ba94b34 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.js @@ -30,33 +30,32 @@ export default class ChangelogSearch extends React.Component { onReset: React.PropTypes.func.isRequired }; - handleResetClick (e) { + handleResetClick(e) { e.preventDefault(); e.target.blur(); this.props.onReset(); } - render () { + render() { return ( - <div className="display-inline-block" - id="quality-profile-changelog-form"> - <DateInput - name="since" - value={this.props.fromDate} - placeholder="From" - onChange={this.props.onFromDateChange}/> - {' — '} - <DateInput - name="to" - value={this.props.toDate} - placeholder="To" - onChange={this.props.onToDateChange}/> - <button - className="spacer-left" - onClick={this.handleResetClick.bind(this)}> - {translate('reset_verb')} - </button> - </div> + <div className="display-inline-block" id="quality-profile-changelog-form"> + <DateInput + name="since" + value={this.props.fromDate} + placeholder="From" + onChange={this.props.onFromDateChange} + /> + {' — '} + <DateInput + name="to" + value={this.props.toDate} + placeholder="To" + onChange={this.props.onToDateChange} + /> + <button className="spacer-left" onClick={this.handleResetClick.bind(this)}> + {translate('reset_verb')} + </button> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js index 64c85983ed5..9ec1807227a 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangesList.js @@ -26,21 +26,19 @@ export default class ChangesList extends React.Component { changes: React.PropTypes.object.isRequired }; - render () { + render() { const { changes } = this.props; return ( - <ul> - {Object.keys(changes).map(key => ( - <li key={key}> - {key === 'severity' ? ( - <SeverityChange severity={changes[key]}/> - ) : ( - <ParameterChange name={key} value={changes[key]}/> - )} - </li> - ))} - </ul> + <ul> + {Object.keys(changes).map(key => ( + <li key={key}> + {key === 'severity' + ? <SeverityChange severity={changes[key]} /> + : <ParameterChange name={key} value={changes[key]} />} + </li> + ))} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js index f57f20c32ee..7b4e0168979 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ParameterChange.js @@ -26,28 +26,24 @@ export default class ParameterChange extends React.Component { value: React.PropTypes.any }; - render () { + render() { const { name, value } = this.props; if (value == null) { return ( - <div style={{ whiteSpace: 'normal' }}> - {translateWithParameters( - 'quality_profiles.changelog.parameter_reset_to_default_value', - name - )} - </div> - ); - } - - return ( <div style={{ whiteSpace: 'normal' }}> {translateWithParameters( - 'quality_profiles.parameter_set_to', - name, - value + 'quality_profiles.changelog.parameter_reset_to_default_value', + name )} </div> + ); + } + + return ( + <div style={{ whiteSpace: 'normal' }}> + {translateWithParameters('quality_profiles.parameter_set_to', name, value)} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js index 9b4a5a952b1..c6e20846d83 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/SeverityChange.js @@ -26,13 +26,13 @@ export default class SeverityChange extends React.Component { severity: React.PropTypes.string.isRequired }; - render () { + render() { return ( - <div> - {translate('quality_profiles.severity_set_to')} - {' '} - <SeverityHelper severity={this.props.severity}/> - </div> + <div> + {translate('quality_profiles.severity_set_to')} + {' '} + <SeverityHelper severity={this.props.severity} /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js index a0a7bf417f2..32774553ba1 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/Changelog-test.js @@ -22,7 +22,7 @@ import React from 'react'; import Changelog from '../Changelog'; import ChangesList from '../ChangesList'; -function createEvent (overrides) { +function createEvent(overrides) { return { date: '2016-01-01', authorName: 'John', @@ -36,44 +36,44 @@ function createEvent (overrides) { it('should render events', () => { const events = [createEvent(), createEvent()]; - const changelog = shallow(<Changelog events={events}/>); + const changelog = shallow(<Changelog events={events} />); expect(changelog.find('tbody').find('tr').length).toBe(2); }); it('should render event date', () => { const events = [createEvent()]; - const changelog = shallow(<Changelog events={events}/>); + const changelog = shallow(<Changelog events={events} />); expect(changelog.text()).toContain('2016'); }); it('should render author', () => { const events = [createEvent()]; - const changelog = shallow(<Changelog events={events}/>); + const changelog = shallow(<Changelog events={events} />); expect(changelog.text()).toContain('John'); }); it('should render system author', () => { const events = [createEvent({ authorName: undefined })]; - const changelog = shallow(<Changelog events={events}/>); + const changelog = shallow(<Changelog events={events} />); expect(changelog.text()).toContain('System'); }); it('should render action', () => { const events = [createEvent()]; - const changelog = shallow(<Changelog events={events}/>); + const changelog = shallow(<Changelog events={events} />); expect(changelog.text()).toContain('ACTIVATED'); }); it('should render rule', () => { const events = [createEvent()]; - const changelog = shallow(<Changelog events={events}/>); + const changelog = shallow(<Changelog events={events} />); expect(changelog.find('Link').prop('to')).toContain('rule_key=squid1234'); }); it('should render ChangesList', () => { const params = { severity: 'BLOCKER' }; const events = [createEvent({ params })]; - const changelog = shallow(<Changelog events={events}/>); + const changelog = shallow(<Changelog events={events} />); const changesList = changelog.find(ChangesList); expect(changesList.length).toBe(1); expect(changesList.prop('changes')).toBe(params); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js index 3a22a61a706..be461db98d4 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangelogSearch-test.js @@ -28,11 +28,12 @@ it('should render DateInput', () => { const onToDateChange = jest.fn(); const output = shallow( <ChangelogSearch - fromDate="2016-01-01" - toDate="2016-05-05" - onFromDateChange={onFromDateChange} - onToDateChange={onToDateChange} - onReset={jest.fn()}/> + fromDate="2016-01-01" + toDate="2016-05-05" + onFromDateChange={onFromDateChange} + onToDateChange={onToDateChange} + onReset={jest.fn()} + /> ); const dateInputs = output.find(DateInput); expect(dateInputs.length).toBe(2); @@ -46,11 +47,12 @@ it('should reset', () => { const onReset = jest.fn(); const output = shallow( <ChangelogSearch - fromDate="2016-01-01" - toDate="2016-05-05" - onFromDateChange={jest.fn()} - onToDateChange={jest.fn()} - onReset={onReset}/> + fromDate="2016-01-01" + toDate="2016-05-05" + onFromDateChange={jest.fn()} + onToDateChange={jest.fn()} + onReset={onReset} + /> ); expect(onReset).not.toBeCalled(); click(output.find('button')); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js index 862ddb628a4..7ccb56ee199 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ChangesList-test.js @@ -25,20 +25,20 @@ import ParameterChange from '../ParameterChange'; it('should render changes', () => { const changes = { severity: 'BLOCKER', foo: 'bar' }; - const output = shallow(<ChangesList changes={changes}/>); + const output = shallow(<ChangesList changes={changes} />); expect(output.find('li').length).toBe(2); }); it('should render severity change', () => { const changes = { severity: 'BLOCKER' }; - const output = shallow(<ChangesList changes={changes}/>).find(SeverityChange); + const output = shallow(<ChangesList changes={changes} />).find(SeverityChange); expect(output.length).toBe(1); expect(output.prop('severity')).toBe('BLOCKER'); }); it('should render parameter change', () => { const changes = { foo: 'bar' }; - const output = shallow(<ChangesList changes={changes}/>).find(ParameterChange); + const output = shallow(<ChangesList changes={changes} />).find(ParameterChange); expect(output.length).toBe(1); expect(output.prop('name')).toBe('foo'); expect(output.prop('value')).toBe('bar'); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js index 089fbf7dc95..25032b3e07a 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/ParameterChange-test.js @@ -22,7 +22,7 @@ import React from 'react'; import ParameterChange from '../ParameterChange'; it('should render different messages', () => { - const first = shallow(<ParameterChange name="foo"/>); - const second = shallow(<ParameterChange name="foo" value="bar"/>); + const first = shallow(<ParameterChange name="foo" />); + const second = shallow(<ParameterChange name="foo" value="bar" />); expect(first.text()).not.toBe(second.text()); }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js index 769edae3fb4..d6f5e10e353 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/SeverityChange-test.js @@ -23,7 +23,7 @@ import SeverityChange from '../SeverityChange'; import SeverityHelper from '../../../../components/shared/severity-helper'; it('should render SeverityHelper', () => { - const output = shallow(<SeverityChange severity="BLOCKER"/>).find(SeverityHelper); + const output = shallow(<SeverityChange severity="BLOCKER" />).find(SeverityHelper); expect(output.length).toBe(1); expect(output.prop('severity')).toBe('BLOCKER'); }); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js index 8be0c0b07bb..a41bc66c8ad 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.js @@ -37,27 +37,26 @@ export default class ComparisonContainer extends React.Component { loading: false }; - componentWillMount () { + componentWillMount() { this.handleCompare = this.handleCompare.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadResults(); } - componentDidUpdate (prevProps) { - if (prevProps.profile !== this.props.profile || - prevProps.location !== this.props.location) { + componentDidUpdate(prevProps) { + if (prevProps.profile !== this.props.profile || prevProps.location !== this.props.location) { this.loadResults(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadResults () { + loadResults() { const { withKey } = this.props.location.query; if (!withKey) { this.setState({ left: null, loading: false }); @@ -79,7 +78,7 @@ export default class ComparisonContainer extends React.Component { }); } - handleCompare (withKey) { + handleCompare(withKey) { this.context.router.push({ pathname: '/profiles/compare', query: { @@ -89,34 +88,33 @@ export default class ComparisonContainer extends React.Component { }); } - render () { + render() { const { profile, profiles, location } = this.props; const { withKey } = location.query; const { left, right, inLeft, inRight, modified } = this.state; return ( - <div className="quality-profile-box js-profile-comparison"> - <header className="spacer-bottom"> - <ComparisonForm - withKey={withKey} - profile={profile} - profiles={profiles} - onCompare={this.handleCompare}/> + <div className="quality-profile-box js-profile-comparison"> + <header className="spacer-bottom"> + <ComparisonForm + withKey={withKey} + profile={profile} + profiles={profiles} + onCompare={this.handleCompare} + /> - {this.state.loading && ( - <i className="spinner spacer-left"/> - )} - </header> + {this.state.loading && <i className="spinner spacer-left" />} + </header> - {left != null && ( - <ComparisonResults - left={left} - right={right} - inLeft={inLeft} - inRight={inRight} - modified={modified}/> - )} - </div> + {left != null && + <ComparisonResults + left={left} + right={right} + inLeft={inLeft} + inRight={inRight} + modified={modified} + />} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js index 2de2961deee..7d7298dc761 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonEmpty.js @@ -21,7 +21,7 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class ComparisonEmpty extends React.Component { - render () { + render() { return ( <div className="big-spacer-top"> {translate('quality_profile.empty_comparison')} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js index f89a71c282d..f686b415b5a 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.js @@ -29,28 +29,29 @@ export default class ComparisonForm extends React.Component { onCompare: React.PropTypes.func.isRequired }; - handleChange (option) { + handleChange(option) { this.props.onCompare(option.value); } - render () { + render() { const { profile, profiles, withKey } = this.props; const options = profiles - .filter(p => p.language === profile.language && p !== profile) - .map(p => ({ value: p.key, label: p.name })); + .filter(p => p.language === profile.language && p !== profile) + .map(p => ({ value: p.key, label: p.name })); return ( - <div className="display-inline-block"> - <label className="spacer-right"> - {translate('quality_profiles.compare_with')} - </label> - <Select - value={withKey} - options={options} - clearable={false} - className="input-large" - onChange={this.handleChange.bind(this)}/> - </div> + <div className="display-inline-block"> + <label className="spacer-right"> + {translate('quality_profiles.compare_with')} + </label> + <Select + value={withKey} + options={options} + clearable={false} + className="input-large" + onChange={this.handleChange.bind(this)} + /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js index 9a147f55b9b..bd8793490d3 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResults.js @@ -37,141 +37,133 @@ export default class ComparisonResults extends React.Component { modified: React.PropTypes.array.isRequired }; - renderRule (rule, severity) { + renderRule(rule, severity) { return ( - <div> - <SeverityIcon severity={severity}/> - {' '} - <Link to={getRulesUrl({ 'rule_key': rule.key })}> - {rule.name} - </Link> - </div> + <div> + <SeverityIcon severity={severity} /> + {' '} + <Link to={getRulesUrl({ rule_key: rule.key })}> + {rule.name} + </Link> + </div> ); } - renderParameters (params) { + renderParameters(params) { if (!params) { return null; } return ( - <ul> - {Object.keys(params).map(key => ( - <li key={key} className="spacer-top"> - <code>{key}{': '}{params[key]}</code> - </li> - ))} - </ul> + <ul> + {Object.keys(params).map(key => ( + <li key={key} className="spacer-top"> + <code>{key}{': '}{params[key]}</code> + </li> + ))} + </ul> ); } - renderLeft () { + renderLeft() { if (this.props.inLeft.length === 0) { return null; } const header = ( - <tr key="left-header"> - <td> - <h6> - {translateWithParameters( - 'quality_profiles.x_rules_only_in', - this.props.inLeft.length - )} - {' '} - {this.props.left.name} - </h6> - </td> - <td> </td> - </tr> + <tr key="left-header"> + <td> + <h6> + {translateWithParameters('quality_profiles.x_rules_only_in', this.props.inLeft.length)} + {' '} + {this.props.left.name} + </h6> + </td> + <td> </td> + </tr> ); const rows = this.props.inLeft.map(rule => ( - <tr key={`left-${rule.key}`} className="js-comparison-in-left"> - <td>{this.renderRule(rule, rule.severity)}</td> - <td> </td> - </tr> + <tr key={`left-${rule.key}`} className="js-comparison-in-left"> + <td>{this.renderRule(rule, rule.severity)}</td> + <td> </td> + </tr> )); return [header, ...rows]; } - renderRight () { + renderRight() { if (this.props.inRight.length === 0) { return null; } const header = ( - <tr key="right-header"> - <td> </td> - <td> - <h6> - {translateWithParameters( - 'quality_profiles.x_rules_only_in', - this.props.inRight.length - )} - {' '} - {this.props.right.name} - </h6> - </td> - </tr> + <tr key="right-header"> + <td> </td> + <td> + <h6> + {translateWithParameters('quality_profiles.x_rules_only_in', this.props.inRight.length)} + {' '} + {this.props.right.name} + </h6> + </td> + </tr> ); const rows = this.props.inRight.map(rule => ( - <tr key={`right-${rule.key}`} - className="js-comparison-in-right"> - <td> </td> - <td>{this.renderRule(rule, rule.severity)}</td> - </tr> + <tr key={`right-${rule.key}`} className="js-comparison-in-right"> + <td> </td> + <td>{this.renderRule(rule, rule.severity)}</td> + </tr> )); return [header, ...rows]; } - renderModified () { + renderModified() { if (this.props.modified.length === 0) { return null; } const header = ( - <tr key="modified-header"> - <td colSpan="2" className="text-center"> - <h6> - {translateWithParameters( - 'quality_profiles.x_rules_have_different_configuration', - this.props.modified.length - )} - </h6> - </td> - </tr> + <tr key="modified-header"> + <td colSpan="2" className="text-center"> + <h6> + {translateWithParameters( + 'quality_profiles.x_rules_have_different_configuration', + this.props.modified.length + )} + </h6> + </td> + </tr> ); const secondHeader = ( - <tr key="modified-second-header"> - <td><h6>{this.props.left.name}</h6></td> - <td><h6>{this.props.right.name}</h6></td> - </tr> + <tr key="modified-second-header"> + <td><h6>{this.props.left.name}</h6></td> + <td><h6>{this.props.right.name}</h6></td> + </tr> ); const rows = this.props.modified.map(rule => ( - <tr key={`modified-${rule.key}`} - className="js-comparison-modified"> - <td> - {this.renderRule(rule, rule.left.severity)} - {this.renderParameters(rule.left.params)} - </td> - <td> - {this.renderRule(rule, rule.right.severity)} - {this.renderParameters(rule.right.params)} - </td> - </tr> + <tr key={`modified-${rule.key}`} className="js-comparison-modified"> + <td> + {this.renderRule(rule, rule.left.severity)} + {this.renderParameters(rule.left.params)} + </td> + <td> + {this.renderRule(rule, rule.right.severity)} + {this.renderParameters(rule.right.params)} + </td> + </tr> )); return [header, secondHeader, ...rows]; } - render () { + render() { if (!this.props.inLeft.length && !this.props.inRight.length && !this.props.modified.length) { - return <ComparisonEmpty/>; + return <ComparisonEmpty />; } return ( - <table className="data zebra quality-profile-comparison-table"> - <tbody> - {this.renderLeft()} - {this.renderRight()} - {this.renderModified()} - </tbody> - </table> + <table className="data zebra quality-profile-comparison-table"> + <tbody> + {this.renderLeft()} + {this.renderRight()} + {this.renderModified()} + </tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js index b4fbaa0d9d0..b972451e628 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonForm-test.js @@ -33,10 +33,11 @@ it('should render Select with right options', () => { const output = shallow( <ComparisonForm - withKey="another" - profile={profile} - profiles={profiles} - onCompare={() => true}/> + withKey="another" + profile={profile} + profiles={profiles} + onCompare={() => true} + /> ).find(Select); expect(output.length).toBe(1); expect(output.prop('value')).toBe('another'); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js index e76bed9d67a..41b3b90bb12 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResults-test.js @@ -27,19 +27,18 @@ import SeverityIcon from '../../../../components/shared/severity-icon'; it('should render ComparisonEmpty', () => { const output = shallow( <ComparisonResults - left={{ name: 'left' }} - right={{ name: 'right' }} - inLeft={[]} - inRight={[]} - modified={[]}/> + left={{ name: 'left' }} + right={{ name: 'right' }} + inLeft={[]} + inRight={[]} + modified={[]} + /> ); expect(output.is(ComparisonEmpty)).toBe(true); }); it('should compare', () => { - const inLeft = [ - { key: 'rule1', name: 'rule1', severity: 'BLOCKER' } - ]; + const inLeft = [{ key: 'rule1', name: 'rule1', severity: 'BLOCKER' }]; const inRight = [ { key: 'rule2', name: 'rule2', severity: 'CRITICAL' }, { key: 'rule3', name: 'rule3', severity: 'MAJOR' } @@ -61,11 +60,12 @@ it('should compare', () => { const output = shallow( <ComparisonResults - left={{ name: 'left' }} - right={{ name: 'right' }} - inLeft={inLeft} - inRight={inRight} - modified={modified}/> + left={{ name: 'left' }} + right={{ name: 'right' }} + inLeft={inLeft} + inRight={inRight} + modified={modified} + /> ); const leftDiffs = output.find('.js-comparison-in-left'); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js index 6d7b0caf51f..f8fd41c66c5 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.js @@ -25,27 +25,24 @@ import '../styles.css'; export default class App extends React.Component { state = { loading: true }; - componentWillMount () { + componentWillMount() { document.querySelector('html').classList.add('dashboard-page'); this.updateProfiles = this.updateProfiles.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadData(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; document.querySelector('html').classList.remove('dashboard-page'); } - loadData () { + loadData() { this.setState({ loading: true }); - Promise.all([ - getExporters(), - getQualityProfiles() - ]).then(responses => { + Promise.all([getExporters(), getQualityProfiles()]).then(responses => { if (this.mounted) { const [exporters, profiles] = responses; this.setState({ @@ -57,7 +54,7 @@ export default class App extends React.Component { }); } - updateProfiles () { + updateProfiles() { return getQualityProfiles().then(profiles => { if (this.mounted) { this.setState({ profiles: sortProfiles(profiles) }); @@ -65,9 +62,9 @@ export default class App extends React.Component { }); } - renderChild () { + renderChild() { if (this.state.loading) { - return <i className="spinner"/>; + return <i className="spinner" />; } const finalLanguages = Object.values(this.props.languages); @@ -83,11 +80,11 @@ export default class App extends React.Component { }); } - render () { + render() { return ( - <div className="page page-limited"> - {this.renderChild()} - </div> + <div className="page page-limited"> + {this.renderChild()} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js index c2d4e81eccf..a19ddff98b6 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.js @@ -21,9 +21,7 @@ import { connect } from 'react-redux'; import App from './App'; import { getLanguages, getCurrentUser } from '../../../store/rootReducer'; -export default connect( - state => ({ - currentUser: getCurrentUser(state), - languages: getLanguages(state) - }) -)(App); +export default connect(state => ({ + currentUser: getCurrentUser(state), + languages: getLanguages(state) +}))(App); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js index c03f5550d09..7c11c4a88f5 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.js @@ -38,51 +38,56 @@ export default class ProfileActions extends React.Component { router: React.PropTypes.object }; - handleRenameClick (e) { + handleRenameClick(e) { e.preventDefault(); new RenameProfileView({ profile: this.props.profile - }).on('done', () => { - this.props.updateProfiles(); - }).render(); + }) + .on('done', () => { + this.props.updateProfiles(); + }) + .render(); } - handleCopyClick (e) { + handleCopyClick(e) { e.preventDefault(); new CopyProfileView({ profile: this.props.profile - }).on('done', profile => { - this.props.updateProfiles().then(() => { - this.context.router.push({ - pathname: '/profiles/show', - query: { key: profile.key } + }) + .on('done', profile => { + this.props.updateProfiles().then(() => { + this.context.router.push({ + pathname: '/profiles/show', + query: { key: profile.key } + }); }); - }); - }).render(); + }) + .render(); } - handleSetDefaultClick (e) { + handleSetDefaultClick(e) { e.preventDefault(); - setDefaultProfile(this.props.profile.key) - .then(this.props.updateProfiles); + setDefaultProfile(this.props.profile.key).then(this.props.updateProfiles); } - handleDeleteClick (e) { + handleDeleteClick(e) { e.preventDefault(); new DeleteProfileView({ profile: this.props.profile - }).on('done', () => { - this.context.router.replace('/profiles'); - this.props.updateProfiles(); - }).render(); + }) + .on('done', () => { + this.context.router.replace('/profiles'); + this.props.updateProfiles(); + }) + .render(); } - render () { + render() { const { profile, canAdmin } = this.props; const backupUrl = window.baseUrl + - '/api/qualityprofiles/backup?profileKey=' + - encodeURIComponent(profile.key); + '/api/qualityprofiles/backup?profileKey=' + + encodeURIComponent(profile.key); const activateMoreUrl = getRulesUrl({ qprofile: profile.key, @@ -90,63 +95,57 @@ export default class ProfileActions extends React.Component { }); return ( - <ul className="dropdown-menu dropdown-menu-right"> - {canAdmin && ( - <li> - <Link to={activateMoreUrl}> - {translate('quality_profiles.activate_more_rules')} - </Link> - </li> - )} + <ul className="dropdown-menu dropdown-menu-right"> + {canAdmin && <li> - <a id="quality-profile-backup" href={backupUrl}> - {translate('backup_verb')} + <Link to={activateMoreUrl}> + {translate('quality_profiles.activate_more_rules')} + </Link> + </li>} + <li> + <a id="quality-profile-backup" href={backupUrl}> + {translate('backup_verb')} + </a> + </li> + <li> + <Link + to={{ pathname: '/profiles/compare', query: { key: profile.key } }} + id="quality-profile-compare" + > + {translate('compare')} + </Link> + </li> + {canAdmin && + <li> + <a id="quality-profile-copy" href="#" onClick={this.handleCopyClick.bind(this)}> + {translate('copy')} </a> - </li> + </li>} + {canAdmin && <li> - <Link - to={{ pathname: '/profiles/compare', query: { key: profile.key } }} - id="quality-profile-compare"> - {translate('compare')} - </Link> - </li> - {canAdmin && ( - <li> - <a id="quality-profile-copy" - href="#" - onClick={this.handleCopyClick.bind(this)}> - {translate('copy')} - </a> - </li> - )} - {canAdmin && ( - <li> - <a id="quality-profile-rename" - href="#" - onClick={this.handleRenameClick.bind(this)}> - {translate('rename')} - </a> - </li> - )} - {canAdmin && !profile.isDefault && ( - <li> - <a id="quality-profile-set-as-default" - href="#" - onClick={this.handleSetDefaultClick.bind(this)}> - {translate('set_as_default')} - </a> - </li> - )} - {canAdmin && !profile.isDefault && ( - <li> - <a id="quality-profile-delete" - href="#" - onClick={this.handleDeleteClick.bind(this)}> - {translate('delete')} - </a> - </li> - )} - </ul> + <a id="quality-profile-rename" href="#" onClick={this.handleRenameClick.bind(this)}> + {translate('rename')} + </a> + </li>} + {canAdmin && + !profile.isDefault && + <li> + <a + id="quality-profile-set-as-default" + href="#" + onClick={this.handleSetDefaultClick.bind(this)} + > + {translate('set_as_default')} + </a> + </li>} + {canAdmin && + !profile.isDefault && + <li> + <a id="quality-profile-delete" href="#" onClick={this.handleDeleteClick.bind(this)}> + {translate('delete')} + </a> + </li>} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js index 5a56dd90eac..e11cbe0968c 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.js @@ -32,33 +32,30 @@ export default class ProfileContainer extends React.Component { updateProfiles: React.PropTypes.func }; - render () { + render() { const { profiles, location, ...other } = this.props; const { key } = location.query; const profile = profiles.find(profile => profile.key === key); if (!profile) { - return <ProfileNotFound/>; + return <ProfileNotFound />; } - const child = React.cloneElement( - this.props.children, - { profile, profiles, ...other }); + const child = React.cloneElement(this.props.children, { profile, profiles, ...other }); const title = translate('quality_profiles.page') + ' - ' + profile.name; return ( - <div> - <Helmet - title={title} - titleTemplate="SonarQube - %s"/> + <div> + <Helmet title={title} titleTemplate="SonarQube - %s" /> - <ProfileHeader - profile={profile} - canAdmin={this.props.canAdmin} - updateProfiles={this.props.updateProfiles}/> - {child} - </div> + <ProfileHeader + profile={profile} + canAdmin={this.props.canAdmin} + updateProfiles={this.props.updateProfiles} + /> + {child} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js index e8a97c5d332..369a6a067fa 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileDate.js @@ -27,23 +27,21 @@ export default class ProfileDate extends React.Component { date: React.PropTypes.string }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - render () { + render() { const { date } = this.props; if (!date) { - return ( - <span>{translate('never')}</span> - ); + return <span>{translate('never')}</span>; } return ( - <span title={moment(date).format('LLL')} data-toggle="tooltip"> - {moment(date).fromNow()} - </span> + <span title={moment(date).format('LLL')} data-toggle="tooltip"> + {moment(date).fromNow()} + </span> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js index 762d28f163b..6fbb379a887 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileLink.js @@ -25,16 +25,17 @@ export default class ProfileLink extends React.Component { profileKey: React.PropTypes.string.isRequired }; - render () { + render() { const { profileKey, children, ...other } = this.props; const query = { key: profileKey }; return ( - <Link - to={{ pathname: '/profiles/show', query }} - activeClassName="link-no-underline" - {...other}> - {children} - </Link> + <Link + to={{ pathname: '/profiles/show', query }} + activeClassName="link-no-underline" + {...other} + > + {children} + </Link> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js index 74fb2329842..2dff3d655e0 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileNotFound.js @@ -22,19 +22,19 @@ import { IndexLink } from 'react-router'; import { translate } from '../../../helpers/l10n'; export default class ProfileNotFound extends React.Component { - render () { + render() { return ( - <div className="quality-profile-not-found"> - <div className="note spacer-bottom"> - <IndexLink to="/profiles/" className="text-muted"> - {translate('quality_profiles.page')} - </IndexLink> - </div> + <div className="quality-profile-not-found"> + <div className="note spacer-bottom"> + <IndexLink to="/profiles/" className="text-muted"> + {translate('quality_profiles.page')} + </IndexLink> + </div> - <div> - {translate('quality_profiles.not_found')} - </div> + <div> + {translate('quality_profiles.not_found')} </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js index 0e3fe8f2209..da6f052f635 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.js @@ -27,19 +27,17 @@ import { createFakeProfile } from '../../utils'; it('should render ProfileHeader', () => { const targetProfile = createFakeProfile({ key: 'profile1' }); - const profiles = [ - targetProfile, - createFakeProfile({ key: 'profile2' }) - ]; + const profiles = [targetProfile, createFakeProfile({ key: 'profile2' })]; const updateProfiles = jest.fn(); const output = shallow( <ProfileContainer - location={{ query: { key: 'profile1' } }} - profiles={profiles} - canAdmin={false} - updateProfiles={updateProfiles}> - <div/> - </ProfileContainer> + location={{ query: { key: 'profile1' } }} + profiles={profiles} + canAdmin={false} + updateProfiles={updateProfiles} + > + <div /> + </ProfileContainer> ); const header = output.find(ProfileHeader); expect(header.length).toBe(1); @@ -49,35 +47,32 @@ it('should render ProfileHeader', () => { }); it('should render ProfileNotFound', () => { - const profiles = [ - createFakeProfile({ key: 'profile1' }), - createFakeProfile({ key: 'profile2' }) - ]; + const profiles = [createFakeProfile({ key: 'profile1' }), createFakeProfile({ key: 'profile2' })]; const output = shallow( <ProfileContainer - location={{ query: { key: 'random' } }} - profiles={profiles} - canAdmin={false} - updateProfiles={() => true}> - <div/> - </ProfileContainer> + location={{ query: { key: 'random' } }} + profiles={profiles} + canAdmin={false} + updateProfiles={() => true} + > + <div /> + </ProfileContainer> ); expect(output.is(ProfileNotFound)).toBe(true); }); it('should render Helmet', () => { - const profiles = [ - createFakeProfile({ key: 'profile1', name: 'First Profile' }) - ]; + const profiles = [createFakeProfile({ key: 'profile1', name: 'First Profile' })]; const updateProfiles = jest.fn(); const output = shallow( <ProfileContainer - location={{ query: { key: 'profile1' } }} - profiles={profiles} - canAdmin={false} - updateProfiles={updateProfiles}> - <div/> - </ProfileContainer> + location={{ query: { key: 'profile1' } }} + profiles={profiles} + canAdmin={false} + updateProfiles={updateProfiles} + > + <div /> + </ProfileContainer> ); const helmet = output.find(Helmet); expect(helmet.length).toBe(1); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js index 9417e8298cb..b6deaa8ddc7 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.js @@ -31,20 +31,20 @@ export default class ProfileDetails extends React.Component { updateProfiles: React.PropTypes.func }; - render () { + render() { return ( - <div> - <div className="quality-profile-grid"> - <div className="quality-profile-grid-left"> - <ProfileRules {...this.props}/> - <ProfileExporters {...this.props}/> - </div> - <div className="quality-profile-grid-right"> - <ProfileInheritance {...this.props}/> - <ProfileProjects {...this.props}/> - </div> + <div> + <div className="quality-profile-grid"> + <div className="quality-profile-grid-left"> + <ProfileRules {...this.props} /> + <ProfileExporters {...this.props} /> + </div> + <div className="quality-profile-grid-right"> + <ProfileInheritance {...this.props} /> + <ProfileProjects {...this.props} /> </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js index cad4399c855..1a7e9df653f 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileExporters.js @@ -25,40 +25,40 @@ export default class ProfileExporters extends React.Component { exporters: React.PropTypes.array.isRequired }; - getExportUrl (exporter) { - return window.baseUrl + '/api/qualityprofiles/export' + - '?exporterKey=' + encodeURIComponent(exporter.key) + - '&language=' + encodeURIComponent(this.props.profile.language) + - '&name=' + encodeURIComponent(this.props.profile.name); + getExportUrl(exporter) { + return window.baseUrl + + '/api/qualityprofiles/export' + + '?exporterKey=' + + encodeURIComponent(exporter.key) + + '&language=' + + encodeURIComponent(this.props.profile.language) + + '&name=' + + encodeURIComponent(this.props.profile.name); } - render () { + render() { const { exporters, profile } = this.props; - const exportersForLanguage = exporters.filter(e => ( - e.languages.includes(profile.language) - )); + const exportersForLanguage = exporters.filter(e => e.languages.includes(profile.language)); if (exportersForLanguage.length === 0) { return null; } return ( - <div className="quality-profile-box quality-profile-exporters"> - <header className="big-spacer-bottom"> - <h2>{translate('quality_profiles.exporters')}</h2> - </header> - <ul> - {exportersForLanguage.map(exporter => ( - <li key={exporter.key} - data-key={exporter.key} - className="spacer-top"> - <a href={this.getExportUrl(exporter)} target="_blank"> - {exporter.name} - </a> - </li> - ))} - </ul> - </div> + <div className="quality-profile-box quality-profile-exporters"> + <header className="big-spacer-bottom"> + <h2>{translate('quality_profiles.exporters')}</h2> + </header> + <ul> + {exportersForLanguage.map(exporter => ( + <li key={exporter.key} data-key={exporter.key} className="spacer-top"> + <a href={this.getExportUrl(exporter)} target="_blank"> + {exporter.name} + </a> + </li> + ))} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js index 8a5025a789f..b75c90c1373 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js @@ -33,106 +33,106 @@ export default class ProfileHeader extends React.Component { updateProfiles: React.PropTypes.func.isRequired }; - renderUpdateDate () { + renderUpdateDate() { const { profile } = this.props; let inner = ( - <span> - {translate('quality_profiles.updated_')} - {' '} - <ProfileDate date={profile.userUpdatedAt}/> - </span> + <span> + {translate('quality_profiles.updated_')} + {' '} + <ProfileDate date={profile.userUpdatedAt} /> + </span> ); if (isStagnant(profile)) { inner = ( - <span className="badge badge-normal-size badge-focus"> - {inner} - </span> + <span className="badge badge-normal-size badge-focus"> + {inner} + </span> ); } return ( - <li className="small spacer-right"> - {inner} - </li> + <li className="small spacer-right"> + {inner} + </li> ); } - renderUsageDate () { + renderUsageDate() { const { profile } = this.props; let inner = ( - <span> - {translate('quality_profiles.used_')} - {' '} - <ProfileDate date={profile.lastUsed}/> - </span> + <span> + {translate('quality_profiles.used_')} + {' '} + <ProfileDate date={profile.lastUsed} /> + </span> ); if (!profile.lastUsed) { inner = ( - <span className="badge badge-normal-size badge-focus"> - {inner} - </span> + <span className="badge badge-normal-size badge-focus"> + {inner} + </span> ); } return ( - <li className="small big-spacer-right"> - {inner} - </li> + <li className="small big-spacer-right"> + {inner} + </li> ); } - render () { + render() { const { profile } = this.props; return ( - <header className="page-header quality-profile-header"> - <div className="note spacer-bottom"> - <IndexLink to="/profiles/" className="text-muted"> - {translate('quality_profiles.page')} - </IndexLink> - {' / '} - <Link - to={{ pathname: '/profiles/', query: { language: profile.language } }} - className="text-muted"> - {profile.languageName} - </Link> - </div> + <header className="page-header quality-profile-header"> + <div className="note spacer-bottom"> + <IndexLink to="/profiles/" className="text-muted"> + {translate('quality_profiles.page')} + </IndexLink> + {' / '} + <Link + to={{ pathname: '/profiles/', query: { language: profile.language } }} + className="text-muted" + > + {profile.languageName} + </Link> + </div> - <h1 className="page-title"> - <ProfileLink - profileKey={profile.key} - className="link-base-color"> - {profile.name} - </ProfileLink> - </h1> + <h1 className="page-title"> + <ProfileLink profileKey={profile.key} className="link-base-color"> + {profile.name} + </ProfileLink> + </h1> - <div className="pull-right"> - <ul className="list-inline" style={{ lineHeight: '24px' }}> - {this.renderUpdateDate()} - {this.renderUsageDate()} - <li> - <Link - to={{ pathname: '/profiles/changelog', query: { key: profile.key } }} - className="button"> - {translate('changelog')} - </Link> - </li> - <li> - <div className="pull-left dropdown"> - <button className="dropdown-toggle" - data-toggle="dropdown"> - {translate('actions')} - {' '} - <i className="icon-dropdown"/> - </button> - <ProfileActions - profile={profile} - canAdmin={this.props.canAdmin} - updateProfiles={this.props.updateProfiles}/> - </div> - </li> - </ul> - </div> - </header> + <div className="pull-right"> + <ul className="list-inline" style={{ lineHeight: '24px' }}> + {this.renderUpdateDate()} + {this.renderUsageDate()} + <li> + <Link + to={{ pathname: '/profiles/changelog', query: { key: profile.key } }} + className="button" + > + {translate('changelog')} + </Link> + </li> + <li> + <div className="pull-left dropdown"> + <button className="dropdown-toggle" data-toggle="dropdown"> + {translate('actions')} + {' '} + <i className="icon-dropdown" /> + </button> + <ProfileActions + profile={profile} + canAdmin={this.props.canAdmin} + updateProfiles={this.props.updateProfiles} + /> + </div> + </li> + </ul> + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js index 14deb69d2fe..d17198f89d5 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.js @@ -35,26 +35,26 @@ export default class ProfileInheritance extends React.Component { loading: true }; - componentWillMount () { + componentWillMount() { this.handleChangeParent = this.handleChangeParent.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadData(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.profile !== this.props.profile) { this.loadData(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadData () { + loadData() { getProfileInheritance(this.props.profile.key).then(r => { if (this.mounted) { const { ancestors, children } = r; @@ -68,66 +68,67 @@ export default class ProfileInheritance extends React.Component { }); } - handleChangeParent (e) { + handleChangeParent(e) { e.preventDefault(); new ChangeParentView({ profile: this.props.profile, profiles: this.props.profiles - }).on('done', () => { - this.props.updateProfiles(); - }).render(); + }) + .on('done', () => { + this.props.updateProfiles(); + }) + .render(); } - render () { + render() { const highlightCurrent = !this.state.loading && - (this.state.ancestors.length > 0 || this.state.children.length > 0); + (this.state.ancestors.length > 0 || this.state.children.length > 0); const currentClassName = classNames('js-inheritance-current', { selected: highlightCurrent }); return ( - <div className="quality-profile-inheritance"> - <header className="big-spacer-bottom clearfix"> - <h2 className="pull-left"> - {translate('quality_profiles.profile_inheritance')} - </h2> - {this.props.canAdmin && ( - <button - className="pull-right js-change-parent" - onClick={this.handleChangeParent}> - {translate('quality_profiles.change_parent')} - </button> - )} - </header> + <div className="quality-profile-inheritance"> + <header className="big-spacer-bottom clearfix"> + <h2 className="pull-left"> + {translate('quality_profiles.profile_inheritance')} + </h2> + {this.props.canAdmin && + <button className="pull-right js-change-parent" onClick={this.handleChangeParent}> + {translate('quality_profiles.change_parent')} + </button>} + </header> - {!this.state.loading && ( - <table className="data zebra"> - <tbody> - {this.state.ancestors.map((ancestor, index) => ( - <ProfileInheritanceBox - key={ancestor.key} - profile={ancestor} - depth={index} - className="js-inheritance-ancestor"/> - ))} + {!this.state.loading && + <table className="data zebra"> + <tbody> + {this.state.ancestors.map((ancestor, index) => ( + <ProfileInheritanceBox + key={ancestor.key} + profile={ancestor} + depth={index} + className="js-inheritance-ancestor" + /> + ))} - <ProfileInheritanceBox - profile={this.state.profile} - depth={this.state.ancestors.length} - displayLink={false} - className={currentClassName}/> + <ProfileInheritanceBox + profile={this.state.profile} + depth={this.state.ancestors.length} + displayLink={false} + className={currentClassName} + /> - {this.state.children.map(child => ( - <ProfileInheritanceBox - key={child.key} - profile={child} - depth={this.state.ancestors.length + 1} - className="js-inheritance-child"/> - ))} - </tbody> - </table> - )} - </div> + {this.state.children.map(child => ( + <ProfileInheritanceBox + key={child.key} + profile={child} + depth={this.state.ancestors.length + 1} + className="js-inheritance-child" + /> + ))} + </tbody> + </table>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js index 651f768ef5c..7e8b464ad16 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.js @@ -38,40 +38,36 @@ export default class ProfileInheritanceBox extends React.Component { displayLink: true }; - render () { + render() { const { profile, className } = this.props; const offset = 25 * this.props.depth; return ( - <tr className={className}> - <td> - <div style={{ paddingLeft: offset }}> - {this.props.displayLink ? ( - <ProfileLink profileKey={profile.key}> - {profile.name} - </ProfileLink> - ) : profile.name} - </div> - </td> + <tr className={className}> + <td> + <div style={{ paddingLeft: offset }}> + {this.props.displayLink + ? <ProfileLink profileKey={profile.key}> + {profile.name} + </ProfileLink> + : profile.name} + </div> + </td> - <td> - {translateWithParameters( - 'quality_profile.x_active_rules', - profile.activeRuleCount - )} - </td> + <td> + {translateWithParameters('quality_profile.x_active_rules', profile.activeRuleCount)} + </td> - <td> - {profile.overridingRuleCount != null && ( - <p> - {translateWithParameters( - 'quality_profiles.x_overridden_rules', - profile.overridingRuleCount - )} - </p> - )} - </td> - </tr> + <td> + {profile.overridingRuleCount != null && + <p> + {translateWithParameters( + 'quality_profiles.x_overridden_rules', + profile.overridingRuleCount + )} + </p>} + </td> + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js index d35c972d424..fffdb362366 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js @@ -35,26 +35,26 @@ export default class ProfileProjects extends React.Component { projects: null }; - componentWillMount () { + componentWillMount() { this.loadProjects = this.loadProjects.bind(this); } - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadProjects(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.profile !== this.props.profile) { this.loadProjects(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadProjects () { + loadProjects() { if (this.props.profile.isDefault) { return; } @@ -71,7 +71,7 @@ export default class ProfileProjects extends React.Component { }); } - handleChange (e) { + handleChange(e) { e.preventDefault(); e.target.blur(); new ChangeProjectsView({ @@ -80,18 +80,18 @@ export default class ProfileProjects extends React.Component { }).render(); } - renderDefault () { + renderDefault() { return ( - <div> - <span className="badge spacer-right"> - {translate('default')} - </span> - {translate('quality_profiles.projects_for_default')} - </div> + <div> + <span className="badge spacer-right"> + {translate('default')} + </span> + {translate('quality_profiles.projects_for_default')} + </div> ); } - renderProjects () { + renderProjects() { const { projects } = this.state; if (projects == null) { @@ -100,51 +100,49 @@ export default class ProfileProjects extends React.Component { if (projects.length === 0) { return ( - <div> - {translate('quality_profiles.no_projects_associated_to_profile')} - </div> + <div> + {translate('quality_profiles.no_projects_associated_to_profile')} + </div> ); } return ( - <ul> - {projects.map(project => ( - <li key={project.uuid} className="spacer-top js-profile-project" data-key={project.key}> - <Link to={{ pathname: '/dashboard', query: { id: project.key } }} className="link-with-icon"> - <QualifierIcon qualifier="TRK"/> - {' '} - <span>{project.name}</span> - </Link> - </li> - ))} - </ul> + <ul> + {projects.map(project => ( + <li key={project.uuid} className="spacer-top js-profile-project" data-key={project.key}> + <Link + to={{ pathname: '/dashboard', query: { id: project.key } }} + className="link-with-icon" + > + <QualifierIcon qualifier="TRK" /> + {' '} + <span>{project.name}</span> + </Link> + </li> + ))} + </ul> ); } - render () { + render() { return ( - <div className="quality-profile-projects"> - <header className="page-header"> - <h2 className="page-title"> - {translate('projects')} - </h2> - - {this.props.canAdmin && !this.props.profile.isDefault && ( - <div className="pull-right"> - <button - className="js-change-projects" - onClick={this.handleChange.bind(this)}> - {translate('quality_profiles.change_projects')} - </button> - </div> - )} - </header> - - {this.props.profile.isDefault ? - this.renderDefault() : - this.renderProjects() - } - </div> + <div className="quality-profile-projects"> + <header className="page-header"> + <h2 className="page-title"> + {translate('projects')} + </h2> + + {this.props.canAdmin && + !this.props.profile.isDefault && + <div className="pull-right"> + <button className="js-change-projects" onClick={this.handleChange.bind(this)}> + {translate('quality_profiles.change_projects')} + </button> + </div>} + </header> + + {this.props.profile.isDefault ? this.renderDefault() : this.renderProjects()} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js index 0185bbc5af2..79bad9a8e38 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js @@ -43,22 +43,22 @@ export default class ProfileRules extends React.Component { activatedByType: keyBy(TYPES.map(t => ({ val: t, count: null })), 'val') }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadRules(); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.profile !== this.props.profile) { this.loadRules(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadAllRules () { + loadAllRules() { return searchRules({ languages: this.props.profile.language, ps: 1, @@ -66,7 +66,7 @@ export default class ProfileRules extends React.Component { }); } - loadActivatedRules () { + loadActivatedRules() { return searchRules({ qprofile: this.props.profile.key, activation: 'true', @@ -75,11 +75,8 @@ export default class ProfileRules extends React.Component { }); } - loadRules () { - Promise.all([ - this.loadAllRules(), - this.loadActivatedRules() - ]).then(responses => { + loadRules() { + Promise.all([this.loadAllRules(), this.loadActivatedRules()]).then(responses => { if (this.mounted) { const [allRules, activatedRules] = responses; this.setState({ @@ -92,7 +89,7 @@ export default class ProfileRules extends React.Component { }); } - getTooltip (count, total) { + getTooltip(count, total) { if (count == null || total == null) { return ''; } @@ -100,18 +97,19 @@ export default class ProfileRules extends React.Component { return translateWithParameters( 'quality_profiles.x_activated_out_of_y', formatMeasure(count, 'INT'), - formatMeasure(total, 'INT')); + formatMeasure(total, 'INT') + ); } - renderActiveTitle () { + renderActiveTitle() { return ( - <strong> - {translate('total')} - </strong> + <strong> + {translate('total')} + </strong> ); } - renderActiveCount () { + renderActiveCount() { const rulesUrl = getRulesUrl({ qprofile: this.props.profile.key, activation: 'true' @@ -122,15 +120,15 @@ export default class ProfileRules extends React.Component { } return ( - <Link to={rulesUrl}> - <strong> - {formatMeasure(this.state.activatedTotal, 'SHORT_INT')} - </strong> - </Link> + <Link to={rulesUrl}> + <strong> + {formatMeasure(this.state.activatedTotal, 'SHORT_INT')} + </strong> + </Link> ); } - renderActiveTotal () { + renderActiveTotal() { const rulesUrl = getRulesUrl({ qprofile: this.props.profile.key, activation: 'false' @@ -145,33 +143,30 @@ export default class ProfileRules extends React.Component { } return ( - <Link to={rulesUrl} className="small text-muted"> - <strong> - {formatMeasure( - this.state.total - this.state.activatedTotal, - 'SHORT_INT' - )} - </strong> - </Link> + <Link to={rulesUrl} className="small text-muted"> + <strong> + {formatMeasure(this.state.total - this.state.activatedTotal, 'SHORT_INT')} + </strong> + </Link> ); } - getTooltipForType (type) { + getTooltipForType(type) { const { count } = this.state.activatedByType[type]; const total = this.state.allByType[type].count; return this.getTooltip(count, total); } - renderTitleForType (type) { + renderTitleForType(type) { return ( - <span> - <IssueTypeIcon query={type} className="little-spacer-right"/> - {translate('issue.type', type, 'plural')} - </span> + <span> + <IssueTypeIcon query={type} className="little-spacer-right" /> + {translate('issue.type', type, 'plural')} + </span> ); } - renderCountForType (type) { + renderCountForType(type) { const rulesUrl = getRulesUrl({ qprofile: this.props.profile.key, activation: 'true', @@ -185,13 +180,13 @@ export default class ProfileRules extends React.Component { } return ( - <Link to={rulesUrl}> - {formatMeasure(count, 'SHORT_INT')} - </Link> + <Link to={rulesUrl}> + {formatMeasure(count, 'SHORT_INT')} + </Link> ); } - renderTotalForType (type) { + renderTotalForType(type) { const rulesUrl = getRulesUrl({ qprofile: this.props.profile.key, activation: 'false', @@ -210,13 +205,13 @@ export default class ProfileRules extends React.Component { } return ( - <Link to={rulesUrl} className="small text-muted"> - {formatMeasure(total - count, 'SHORT_INT')} - </Link> + <Link to={rulesUrl} className="small text-muted"> + {formatMeasure(total - count, 'SHORT_INT')} + </Link> ); } - renderDeprecated () { + renderDeprecated() { const { profile } = this.props; if (profile.activeDeprecatedRuleCount === 0) { @@ -226,65 +221,66 @@ export default class ProfileRules extends React.Component { const url = getDeprecatedActiveRulesUrl({ qprofile: profile.key }); return ( - <div className="quality-profile-rules-deprecated clearfix"> - <div className="pull-left"> - {translate('quality_profiles.deprecated_rules')} - </div> - <div className="pull-right"> - <Link to={url}> - {profile.activeDeprecatedRuleCount} - </Link> - </div> + <div className="quality-profile-rules-deprecated clearfix"> + <div className="pull-left"> + {translate('quality_profiles.deprecated_rules')} </div> + <div className="pull-right"> + <Link to={url}> + {profile.activeDeprecatedRuleCount} + </Link> + </div> + </div> ); } - render () { + render() { const activateMoreUrl = getRulesUrl({ qprofile: this.props.profile.key, activation: 'false' }); return ( - <div className="quality-profile-rules"> - <div className="quality-profile-rules-distribution"> - <table className="data condensed"> - <thead> - <tr> - <th> - <h2>{translate('rules')}</h2> - </th> - <th>Active</th> - <th>Inactive</th> - </tr> - </thead> - <tbody> + <div className="quality-profile-rules"> + <div className="quality-profile-rules-distribution"> + <table className="data condensed"> + <thead> + <tr> + <th> + <h2>{translate('rules')}</h2> + </th> + <th>Active</th> + <th>Inactive</th> + </tr> + </thead> + <tbody> + <ProfileRulesRow + key="all" + renderTitle={this.renderActiveTitle.bind(this)} + renderCount={this.renderActiveCount.bind(this)} + renderTotal={this.renderActiveTotal.bind(this)} + /> + {TYPES.map(type => ( <ProfileRulesRow - key="all" - renderTitle={this.renderActiveTitle.bind(this)} - renderCount={this.renderActiveCount.bind(this)} - renderTotal={this.renderActiveTotal.bind(this)}/> - {TYPES.map(type => ( - <ProfileRulesRow - key={type} - renderTitle={this.renderTitleForType.bind(this, type)} - renderCount={this.renderCountForType.bind(this, type)} - renderTotal={this.renderTotalForType.bind(this, type)}/> - ))} - </tbody> - </table> - - {this.props.canAdmin && ( - <div className="text-right big-spacer-top"> - <Link to={activateMoreUrl} className="button js-activate-rules"> - {translate('quality_profiles.activate_more')} - </Link> - </div> - )} - </div> - - {this.renderDeprecated()} + key={type} + renderTitle={this.renderTitleForType.bind(this, type)} + renderCount={this.renderCountForType.bind(this, type)} + renderTotal={this.renderTotalForType.bind(this, type)} + /> + ))} + </tbody> + </table> + + {this.props.canAdmin && + <div className="text-right big-spacer-top"> + <Link to={activateMoreUrl} className="button js-activate-rules"> + {translate('quality_profiles.activate_more')} + </Link> + </div>} </div> + + {this.renderDeprecated()} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js index d1553551f1f..ae74c615802 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js @@ -26,21 +26,21 @@ export default class ProfileRulesRow extends React.Component { renderTotal: React.PropTypes.func.isRequired }; - render () { + render() { const { renderTitle, renderCount, renderTotal } = this.props; return ( - <tr> - <td> - {renderTitle()} - </td> - <td className="thin nowrap text-right"> - {renderCount()} - </td> - <td className="thin nowrap text-right"> - {renderTotal()} - </td> - </tr> + <tr> + <td> + {renderTitle()} + </td> + <td className="thin nowrap text-right"> + {renderCount()} + </td> + <td className="thin nowrap text-right"> + {renderTotal()} + </td> + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js index b074b21decb..b87f3ceb5df 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/Evolution.js @@ -28,13 +28,13 @@ export default class Evolution extends React.Component { profiles: ProfilesListType.isRequired }; - render () { + render() { return ( - <div className="quality-profiles-evolution"> - <EvolutionDeprecated profiles={this.props.profiles}/> - <EvolutionStagnant profiles={this.props.profiles}/> - <EvolutionRules/> - </div> + <div className="quality-profiles-evolution"> + <EvolutionDeprecated profiles={this.props.profiles} /> + <EvolutionStagnant profiles={this.props.profiles} /> + <EvolutionRules /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js index cb8cd4a54de..a198b3197ad 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionDeprecated.js @@ -30,53 +30,53 @@ export default class EvolutionDeprecated extends React.Component { profiles: ProfilesListType.isRequired }; - render () { - const profilesWithDeprecations = this.props.profiles - .filter(profile => profile.activeDeprecatedRuleCount > 0); + render() { + const profilesWithDeprecations = this.props.profiles.filter( + profile => profile.activeDeprecatedRuleCount > 0 + ); if (profilesWithDeprecations.length === 0) { return null; } - const sortedProfiles = - sortBy(profilesWithDeprecations, p => -p.activeDeprecatedRuleCount); + const sortedProfiles = sortBy(profilesWithDeprecations, p => -p.activeDeprecatedRuleCount); return ( - <div - className="quality-profile-box quality-profiles-evolution-deprecated"> - <div className="spacer-bottom"> - <strong>{translate('quality_profiles.deprecated_rules')}</strong> - </div> - <div className="spacer-bottom"> - {translateWithParameters( - 'quality_profiles.deprecated_rules_are_still_activated', - profilesWithDeprecations.length - )} - </div> - <ul> - {sortedProfiles.map(profile => ( - <li key={profile.key} className="spacer-top"> - <div className="text-ellipsis"> - <ProfileLink - profileKey={profile.key} - className="link-no-underline"> - {profile.name} - </ProfileLink> - </div> - <div className="note"> - {profile.languageName} - {', '} - <Link to={getDeprecatedActiveRulesUrl({ qprofile: profile.key })} className="text-muted"> - {translateWithParameters( - 'quality_profile.x_rules', - profile.activeDeprecatedRuleCount - )} - </Link> - </div> - </li> - ))} - </ul> + <div className="quality-profile-box quality-profiles-evolution-deprecated"> + <div className="spacer-bottom"> + <strong>{translate('quality_profiles.deprecated_rules')}</strong> + </div> + <div className="spacer-bottom"> + {translateWithParameters( + 'quality_profiles.deprecated_rules_are_still_activated', + profilesWithDeprecations.length + )} </div> + <ul> + {sortedProfiles.map(profile => ( + <li key={profile.key} className="spacer-top"> + <div className="text-ellipsis"> + <ProfileLink profileKey={profile.key} className="link-no-underline"> + {profile.name} + </ProfileLink> + </div> + <div className="note"> + {profile.languageName} + {', '} + <Link + to={getDeprecatedActiveRulesUrl({ qprofile: profile.key })} + className="text-muted" + > + {translateWithParameters( + 'quality_profile.x_rules', + profile.activeDeprecatedRuleCount + )} + </Link> + </div> + </li> + ))} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js index fcf766eca58..fee0049a0a2 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionRules.js @@ -30,7 +30,7 @@ const RULES_LIMIT = 10; const PERIOD_START_MOMENT = moment().subtract(1, 'year'); -function parseRules (r) { +function parseRules(r) { const { rules, actives } = r; return rules.map(rule => { const activations = actives[rule.key]; @@ -41,22 +41,22 @@ function parseRules (r) { export default class EvolutionRules extends React.Component { state = {}; - componentDidMount () { + componentDidMount() { this.mounted = true; this.loadLatestRules(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - loadLatestRules () { + loadLatestRules() { const data = { - 'available_since': PERIOD_START_MOMENT.format('YYYY-MM-DD'), - 's': 'createdAt', - 'asc': false, - 'ps': RULES_LIMIT, - 'f': 'name,langName,actives' + available_since: PERIOD_START_MOMENT.format('YYYY-MM-DD'), + s: 'createdAt', + asc: false, + ps: RULES_LIMIT, + f: 'name,langName,actives' }; searchRules(data).then(r => { @@ -69,58 +69,55 @@ export default class EvolutionRules extends React.Component { }); } - render () { + render() { if (!this.state.latestRulesTotal) { return null; } const newRulesUrl = getRulesUrl({ - 'available_since': PERIOD_START_MOMENT.format('YYYY-MM-DD') + available_since: PERIOD_START_MOMENT.format('YYYY-MM-DD') }); return ( - <div className="quality-profile-box quality-profiles-evolution-rules"> - <div className="clearfix"> - <strong className="pull-left"> - {translate('quality_profiles.latest_new_rules')} - </strong> - </div> - <ul> - {this.state.latestRules.map(rule => ( - <li key={rule.key} className="spacer-top"> - <div className="text-ellipsis"> - <Link to={getRulesUrl({ 'rule_key': rule.key })} className="link-no-underline"> - {' '} - {rule.name} - </Link> - <div className="note"> - {rule.activations ? ( - translateWithParameters( - 'quality_profiles.latest_new_rules.activated', - rule.langName, - rule.activations - ) - ) : ( - translateWithParameters( - 'quality_profiles.latest_new_rules.not_activated', - rule.langName - ) - )} - </div> - </div> - </li> - ))} - </ul> - {this.state.latestRulesTotal > RULES_LIMIT && ( - <div className="spacer-top"> - <Link to={newRulesUrl} className="small"> - {translate('see_all')} + <div className="quality-profile-box quality-profiles-evolution-rules"> + <div className="clearfix"> + <strong className="pull-left"> + {translate('quality_profiles.latest_new_rules')} + </strong> + </div> + <ul> + {this.state.latestRules.map(rule => ( + <li key={rule.key} className="spacer-top"> + <div className="text-ellipsis"> + <Link to={getRulesUrl({ rule_key: rule.key })} className="link-no-underline"> {' '} - {formatMeasure(this.state.latestRulesTotal, 'SHORT_INT')} + {rule.name} </Link> + <div className="note"> + {rule.activations + ? translateWithParameters( + 'quality_profiles.latest_new_rules.activated', + rule.langName, + rule.activations + ) + : translateWithParameters( + 'quality_profiles.latest_new_rules.not_activated', + rule.langName + )} + </div> </div> - )} - </div> + </li> + ))} + </ul> + {this.state.latestRulesTotal > RULES_LIMIT && + <div className="spacer-top"> + <Link to={newRulesUrl} className="small"> + {translate('see_all')} + {' '} + {formatMeasure(this.state.latestRulesTotal, 'SHORT_INT')} + </Link> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js index 9977d61fe7d..833ec05fd33 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/EvolutionStagnant.js @@ -29,7 +29,7 @@ export default class EvolutionStagnant extends React.Component { profiles: ProfilesListType.isRequired }; - render () { + render() { // TODO filter built-in out const outdated = this.props.profiles.filter(isStagnant); @@ -39,33 +39,30 @@ export default class EvolutionStagnant extends React.Component { } return ( - <div - className="quality-profile-box quality-profiles-evolution-stagnant"> - <div className="spacer-bottom"> - <strong>{translate('quality_profiles.stagnant_profiles')}</strong> - </div> - <div className="spacer-bottom"> - {translate('quality_profiles.not_updated_more_than_year')} - </div> - <ul> - {outdated.map(profile => ( - <li key={profile.key} className="spacer-top"> - <div className="text-ellipsis"> - <ProfileLink - profileKey={profile.key} - className="link-no-underline"> - {profile.name} - </ProfileLink> - </div> - <div className="note"> - {profile.languageName} - {', '} - updated on {moment(profile.rulesUpdatedAt).format('LL')} - </div> - </li> - ))} - </ul> + <div className="quality-profile-box quality-profiles-evolution-stagnant"> + <div className="spacer-bottom"> + <strong>{translate('quality_profiles.stagnant_profiles')}</strong> </div> + <div className="spacer-bottom"> + {translate('quality_profiles.not_updated_more_than_year')} + </div> + <ul> + {outdated.map(profile => ( + <li key={profile.key} className="spacer-top"> + <div className="text-ellipsis"> + <ProfileLink profileKey={profile.key} className="link-no-underline"> + {profile.name} + </ProfileLink> + </div> + <div className="note"> + {profile.languageName} + {', '} + updated on {moment(profile.rulesUpdatedAt).format('LL')} + </div> + </li> + ))} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js index 3c1fe72be35..e5979422006 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.js @@ -25,24 +25,22 @@ import ProfilesList from './ProfilesList'; import { translate } from '../../../helpers/l10n'; export default class HomeContainer extends React.Component { - render () { + render() { return ( - <div> - <Helmet - title={translate('quality_profiles.page')} - titleTemplate="SonarQube - %s"/> + <div> + <Helmet title={translate('quality_profiles.page')} titleTemplate="SonarQube - %s" /> - <PageHeader {...this.props}/> + <PageHeader {...this.props} /> - <div className="page-with-sidebar"> - <div className="page-main"> - <ProfilesList {...this.props}/> - </div> - <div className="page-sidebar"> - <Evolution {...this.props}/> - </div> + <div className="page-with-sidebar"> + <div className="page-main"> + <ProfilesList {...this.props} /> + </div> + <div className="page-sidebar"> + <Evolution {...this.props} /> </div> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js index 6c3257429da..f83101f8259 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.js @@ -35,15 +35,15 @@ export default class PageHeader extends React.Component { state = {}; - componentDidMount () { + componentDidMount() { this.mounted = true; } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - retrieveImporters () { + retrieveImporters() { if (this.state.importers) { return Promise.resolve(this.state.importers); } else { @@ -54,83 +54,82 @@ export default class PageHeader extends React.Component { } } - handleCreateClick (e) { + handleCreateClick(e) { e.preventDefault(); e.target.blur(); this.retrieveImporters().then(importers => { new CreateProfileView({ languages: this.props.languages, importers - }).on('done', profile => { - this.props.updateProfiles().then(() => { - this.context.router.push({ - pathname: '/profiles/show', - query: { key: profile.key } + }) + .on('done', profile => { + this.props.updateProfiles().then(() => { + this.context.router.push({ + pathname: '/profiles/show', + query: { key: profile.key } + }); }); - }); - }).render(); + }) + .render(); }); } - handleRestoreClick (e) { + handleRestoreClick(e) { e.preventDefault(); - new RestoreProfileView() - .on('done', this.props.updateProfiles) - .render(); + new RestoreProfileView().on('done', this.props.updateProfiles).render(); } - handleRestoreBuiltIn (e) { + handleRestoreBuiltIn(e) { e.preventDefault(); new RestoreBuiltInProfilesView({ languages: this.props.languages }) - .on('done', this.props.updateProfiles) - .render(); + .on('done', this.props.updateProfiles) + .render(); } - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title"> - {translate('quality_profiles.page')} - </h1> + <header className="page-header"> + <h1 className="page-title"> + {translate('quality_profiles.page')} + </h1> - {this.props.canAdmin && ( - <div className="page-actions button-group dropdown"> - <button - id="quality-profiles-create" - onClick={this.handleCreateClick.bind(this)}> - {translate('create')} - </button> - <button - className="dropdown-toggle js-more-admin-actions" - data-toggle="dropdown"> - <i className="icon-dropdown"/> - </button> - <ul className="dropdown-menu dropdown-menu-right"> - <li> - <a href="#" - id="quality-profiles-restore" - onClick={this.handleRestoreClick.bind(this)}> - {translate('quality_profiles.restore_profile')} - </a> - </li> + {this.props.canAdmin && + <div className="page-actions button-group dropdown"> + <button id="quality-profiles-create" onClick={this.handleCreateClick.bind(this)}> + {translate('create')} + </button> + <button className="dropdown-toggle js-more-admin-actions" data-toggle="dropdown"> + <i className="icon-dropdown" /> + </button> + <ul className="dropdown-menu dropdown-menu-right"> + <li> + <a + href="#" + id="quality-profiles-restore" + onClick={this.handleRestoreClick.bind(this)} + > + {translate('quality_profiles.restore_profile')} + </a> + </li> - <li> - <a href="#" - id="quality-profiles-restore-built-in" - onClick={this.handleRestoreBuiltIn.bind(this)}> - {translate('quality_profiles.restore_built_in_profiles')} - </a> - </li> - </ul> - </div> - )} + <li> + <a + href="#" + id="quality-profiles-restore-built-in" + onClick={this.handleRestoreBuiltIn.bind(this)} + > + {translate('quality_profiles.restore_built_in_profiles')} + </a> + </li> + </ul> + </div>} - <div className="page-description markdown"> - {translate('quality_profiles.intro1')} - <br/> - {translate('quality_profiles.intro2')} - </div> - </header> + <div className="page-description markdown"> + {translate('quality_profiles.intro1')} + <br /> + {translate('quality_profiles.intro2')} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js index d92018fa184..47a80df6252 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js @@ -36,93 +36,80 @@ export default class ProfilesList extends React.Component { updateProfiles: React.PropTypes.func.isRequired }; - renderProfiles (profiles) { + renderProfiles(profiles) { return profiles.map(profile => ( - <ProfilesListRow - key={profile.key} - profile={profile} - canAdmin={this.props.canAdmin} - updateProfiles={this.props.updateProfiles}/> + <ProfilesListRow + key={profile.key} + profile={profile} + canAdmin={this.props.canAdmin} + updateProfiles={this.props.updateProfiles} + /> )); } - renderHeader (languageKey, profilesCount) { + renderHeader(languageKey, profilesCount) { const language = this.props.languages.find(l => l.key === languageKey); return ( - <thead> - <tr> - <th> - {language.name} - {', '} - {translateWithParameters( - 'quality_profiles.x_profiles', - profilesCount - )} - </th> - <th className="text-right nowrap"> - {translate('quality_profiles.list.projects')} - </th> - <th className="text-right nowrap"> - {translate('quality_profiles.list.rules')} - </th> - <th className="text-right nowrap"> - {translate('quality_profiles.list.updated')} - </th> - <th className="text-right nowrap"> - {translate('quality_profiles.list.used')} - </th> - {this.props.canAdmin && ( - <th> </th> - )} - </tr> - </thead> + <thead> + <tr> + <th> + {language.name} + {', '} + {translateWithParameters('quality_profiles.x_profiles', profilesCount)} + </th> + <th className="text-right nowrap"> + {translate('quality_profiles.list.projects')} + </th> + <th className="text-right nowrap"> + {translate('quality_profiles.list.rules')} + </th> + <th className="text-right nowrap"> + {translate('quality_profiles.list.updated')} + </th> + <th className="text-right nowrap"> + {translate('quality_profiles.list.used')} + </th> + {this.props.canAdmin && <th> </th>} + </tr> + </thead> ); } - render () { + render() { const { profiles, languages } = this.props; const { language } = this.props.location.query; const profilesIndex = groupBy(profiles, profile => profile.language); - const profilesToShow = language ? - pick(profilesIndex, language) : - profilesIndex; + const profilesToShow = language ? pick(profilesIndex, language) : profilesIndex; const languagesToShow = sortBy(Object.keys(profilesToShow)); return ( - <div> - <ProfilesListHeader - languages={languages} - currentFilter={language}/> + <div> + <ProfilesListHeader languages={languages} currentFilter={language} /> - {Object.keys(profilesToShow).length === 0 && ( - <div className="alert alert-warning spacer-top"> - {translate('no_results')} - </div> - )} + {Object.keys(profilesToShow).length === 0 && + <div className="alert alert-warning spacer-top"> + {translate('no_results')} + </div>} - {languagesToShow.map(languageKey => ( - <div key={languageKey} - className="quality-profile-box quality-profiles-table"> - <table data-language={languageKey} - className="data zebra zebra-hover"> + {languagesToShow.map(languageKey => ( + <div key={languageKey} className="quality-profile-box quality-profiles-table"> + <table data-language={languageKey} className="data zebra zebra-hover"> - {this.renderHeader( - languageKey, - profilesToShow[languageKey].length)} + {this.renderHeader(languageKey, profilesToShow[languageKey].length)} - <TooltipsContainer> - <tbody> - {this.renderProfiles(profilesToShow[languageKey])} - </tbody> - </TooltipsContainer> + <TooltipsContainer> + <tbody> + {this.renderProfiles(profilesToShow[languageKey])} + </tbody> + </TooltipsContainer> - </table> - </div> - ))} + </table> + </div> + ))} - </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js index b655f5e5a88..1eb246821aa 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js @@ -28,56 +28,55 @@ export default class ProfilesListHeader extends React.Component { currentFilter: React.PropTypes.string }; - renderFilterToggle () { + renderFilterToggle() { const { languages, currentFilter } = this.props; - const currentLanguage = currentFilter && - languages.find(l => l.key === currentFilter); + const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter); - const label = currentFilter ? - translateWithParameters( - 'quality_profiles.x_Profiles', - currentLanguage.name) : - translate('quality_profiles.all_profiles'); + const label = currentFilter + ? translateWithParameters('quality_profiles.x_Profiles', currentLanguage.name) + : translate('quality_profiles.all_profiles'); return ( - <a className="dropdown-toggle link-no-underline js-language-filter" - href="#" - data-toggle="dropdown"> - {label} <i className="icon-dropdown"/> - </a> + <a + className="dropdown-toggle link-no-underline js-language-filter" + href="#" + data-toggle="dropdown" + > + {label} <i className="icon-dropdown" /> + </a> ); } - renderFilterMenu () { + renderFilterMenu() { return ( - <ul className="dropdown-menu"> - <li> - <IndexLink to="/profiles/"> - {translate('quality_profiles.all_profiles')} + <ul className="dropdown-menu"> + <li> + <IndexLink to="/profiles/"> + {translate('quality_profiles.all_profiles')} + </IndexLink> + </li> + {this.props.languages.map(language => ( + <li key={language.key}> + <IndexLink + to={{ pathname: '/profiles/', query: { language: language.key } }} + className="js-language-filter-option" + data-language={language.key} + > + {language.name} </IndexLink> </li> - {this.props.languages.map(language => ( - <li key={language.key}> - <IndexLink - to={{ pathname: '/profiles/', query: { language: language.key } }} - className="js-language-filter-option" - data-language={language.key}> - {language.name} - </IndexLink> - </li> - ))} - </ul> + ))} + </ul> ); } - render () { + render() { if (this.props.languages.length < 2) { return null; } const { languages, currentFilter } = this.props; - const currentLanguage = currentFilter && - languages.find(l => l.key === currentFilter); + const currentLanguage = currentFilter && languages.find(l => l.key === currentFilter); // if unknown language, then if (currentFilter && !currentLanguage) { @@ -85,12 +84,12 @@ export default class ProfilesListHeader extends React.Component { } return ( - <header className="quality-profiles-list-header clearfix"> - <div className="dropdown"> - {this.renderFilterToggle()} - {this.renderFilterMenu()} - </div> - </header> + <header className="quality-profiles-list-header clearfix"> + <div className="dropdown"> + {this.renderFilterToggle()} + {this.renderFilterMenu()} + </div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js index e13abad16a8..9498b26ac92 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.js @@ -35,41 +35,41 @@ export default class ProfilesListRow extends React.Component { updateProfiles: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - renderName () { + renderName() { const { profile } = this.props; const offset = 25 * (profile.depth - 1); return ( - <div style={{ paddingLeft: offset }}> - <ProfileLink profileKey={profile.key}> - {profile.name} - </ProfileLink> - </div> + <div style={{ paddingLeft: offset }}> + <ProfileLink profileKey={profile.key}> + {profile.name} + </ProfileLink> + </div> ); } - renderProjects () { + renderProjects() { const { profile } = this.props; if (profile.isDefault) { return ( - <span className="badge"> - {translate('default')} - </span> + <span className="badge"> + {translate('default')} + </span> ); } return ( - <span> - {profile.projectCount} - </span> + <span> + {profile.projectCount} + </span> ); } - renderRules () { + renderRules() { const { profile } = this.props; const activeRulesUrl = getRulesUrl({ @@ -84,27 +84,28 @@ export default class ProfilesListRow extends React.Component { }); return ( - <div> - {profile.activeDeprecatedRuleCount > 0 && ( - <span className="spacer-right"> - <Link to={deprecatedRulesUrl} - className="badge badge-normal-size badge-danger-light" - title={translate('quality_profiles.deprecated_rules')} - data-toggle="tooltip"> - {profile.activeDeprecatedRuleCount} - </Link> - </span> - )} + <div> + {profile.activeDeprecatedRuleCount > 0 && + <span className="spacer-right"> + <Link + to={deprecatedRulesUrl} + className="badge badge-normal-size badge-danger-light" + title={translate('quality_profiles.deprecated_rules')} + data-toggle="tooltip" + > + {profile.activeDeprecatedRuleCount} + </Link> + </span>} - <Link to={activeRulesUrl}> - {profile.activeRuleCount} - </Link> - </div> + <Link to={activeRulesUrl}> + {profile.activeRuleCount} + </Link> + </div> ); } - renderUpdateDate () { - const date = <ProfileDate date={this.props.profile.userUpdatedAt}/>; + renderUpdateDate() { + const date = <ProfileDate date={this.props.profile.userUpdatedAt} />; if (isStagnant(this.props.profile)) { return <span className="badge badge-normal-size badge-focus">{date}</span>; } else { @@ -112,9 +113,9 @@ export default class ProfilesListRow extends React.Component { } } - renderUsageDate () { + renderUsageDate() { const { lastUsed } = this.props.profile; - const date = <ProfileDate date={lastUsed}/>; + const date = <ProfileDate date={lastUsed} />; if (!lastUsed) { return <span className="badge badge-normal-size badge-focus">{date}</span>; } else { @@ -122,40 +123,42 @@ export default class ProfilesListRow extends React.Component { } } - render () { + render() { return ( - <tr className="quality-profiles-table-row" - data-key={this.props.profile.key} - data-name={this.props.profile.name}> - <td className="quality-profiles-table-name"> - {this.renderName()} - </td> - <td className="quality-profiles-table-projects thin nowrap text-right"> - {this.renderProjects()} - </td> - <td className="quality-profiles-table-rules thin nowrap text-right"> - {this.renderRules()} - </td> - <td className="quality-profiles-table-date thin nowrap text-right"> - {this.renderUpdateDate()} - </td> - <td className="quality-profiles-table-date thin nowrap text-right"> - {this.renderUsageDate()} - </td> - {this.props.canAdmin && ( - <td className="quality-profiles-table-actions thin nowrap text-right"> - <div className="dropdown"> - <button className="dropdown-toggle" data-toggle="dropdown"> - <i className="icon-dropdown"/> - </button> - <ProfileActions - profile={this.props.profile} - canAdmin={this.props.canAdmin} - updateProfiles={this.props.updateProfiles}/> - </div> - </td> - )} - </tr> + <tr + className="quality-profiles-table-row" + data-key={this.props.profile.key} + data-name={this.props.profile.name} + > + <td className="quality-profiles-table-name"> + {this.renderName()} + </td> + <td className="quality-profiles-table-projects thin nowrap text-right"> + {this.renderProjects()} + </td> + <td className="quality-profiles-table-rules thin nowrap text-right"> + {this.renderRules()} + </td> + <td className="quality-profiles-table-date thin nowrap text-right"> + {this.renderUpdateDate()} + </td> + <td className="quality-profiles-table-date thin nowrap text-right"> + {this.renderUsageDate()} + </td> + {this.props.canAdmin && + <td className="quality-profiles-table-actions thin nowrap text-right"> + <div className="dropdown"> + <button className="dropdown-toggle" data-toggle="dropdown"> + <i className="icon-dropdown" /> + </button> + <ProfileActions + profile={this.props.profile} + canAdmin={this.props.canAdmin} + updateProfiles={this.props.updateProfiles} + /> + </div> + </td>} + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js b/server/sonar-web/src/main/js/apps/quality-profiles/routes.js index 55ce4f1bacc..85c42a87438 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/routes.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/routes.js @@ -27,15 +27,15 @@ import ChangelogContainer from './changelog/ChangelogContainer'; import ComparisonContainer from './compare/ComparisonContainer'; export default ( - <Route component={AppContainer}> - <Redirect from="/profiles/index" to="/profiles"/> + <Route component={AppContainer}> + <Redirect from="/profiles/index" to="/profiles" /> - <IndexRoute component={HomeContainer}/> + <IndexRoute component={HomeContainer} /> - <Route component={ProfileContainer}> - <Route path="show" component={ProfileDetails}/> - <Route path="changelog" component={ChangelogContainer}/> - <Route path="compare" component={ComparisonContainer}/> - </Route> + <Route component={ProfileContainer}> + <Route path="show" component={ProfileDetails} /> + <Route path="changelog" component={ChangelogContainer} /> + <Route path="compare" component={ComparisonContainer} /> </Route> + </Route> ); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js b/server/sonar-web/src/main/js/apps/quality-profiles/utils.js index ebbcddac6f1..0ebe30db86f 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/utils.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/utils.js @@ -27,18 +27,17 @@ type Profiles = Array<{ parentKey?: string }>; -export function sortProfiles (profiles: Profiles) { +export function sortProfiles(profiles: Profiles) { const result = []; const sorted = sortBy(profiles, 'name'); - function retrieveChildren (parent) { - return sorted.filter(p => ( - (parent == null && p.parentKey == null) || - (parent != null && p.parentKey === parent.key) - )); + function retrieveChildren(parent) { + return sorted.filter( + p => (parent == null && p.parentKey == null) || (parent != null && p.parentKey === parent.key) + ); } - function putProfile (profile = null, depth = 0) { + function putProfile(profile = null, depth = 0) { const children = retrieveChildren(profile); if (profile != null) { @@ -53,7 +52,7 @@ export function sortProfiles (profiles: Profiles) { return result; } -export function createFakeProfile (overrides: {}) { +export function createFakeProfile(overrides: {}) { return { key: 'key', name: 'name', @@ -68,6 +67,6 @@ export function createFakeProfile (overrides: {}) { }; } -export function isStagnant (profile: { userUpdatedAt: string }) { +export function isStagnant(profile: { userUpdatedAt: string }) { return moment().diff(moment(profile.userUpdatedAt), 'years') >= 1; } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js index 4bf8a064fa9..01c83a69ee1 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeParentView.js @@ -24,7 +24,7 @@ import { changeProfileParent } from '../../../api/quality-profiles'; export default ModalFormView.extend({ template: Template, - onRender () { + onRender() { ModalFormView.prototype.onRender.apply(this, arguments); this.$('select').select2({ allowClear: false, @@ -33,35 +33,35 @@ export default ModalFormView.extend({ }); }, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { let parent = this.$('#change-profile-parent').val(); if (parent === '#none') { parent = ''; } changeProfileParent(this.options.profile.key, parent) - .then(() => { - this.destroy(); - this.trigger('done'); - }) - .catch(e => { - if (e.response.status === 400) { - this.enableForm(); - e.response.json().then(r => this.showErrors(r.errors, r.warnings)); - } - }); + .then(() => { + this.destroy(); + this.trigger('done'); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); }, - serializeData () { + serializeData() { const { profile } = this.options; - const profiles = this.options.profiles - .filter(p => p !== profile && p.language === profile.language); + const profiles = this.options.profiles.filter( + p => p !== profile && p.language === profile.language + ); return { ...profile, profiles }; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js index 6a66ad7b9f3..df5a7facd0c 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/ChangeProjectsView.js @@ -26,13 +26,14 @@ import '../../../components/SelectList'; export default ModalFormView.extend({ template: Template, - onRender () { + onRender() { ModalFormView.prototype.onRender.apply(this, arguments); const { key } = this.options.profile; - const searchUrl = window.baseUrl + '/api/qualityprofiles/projects?key=' + - encodeURIComponent(key); + const searchUrl = window.baseUrl + + '/api/qualityprofiles/projects?key=' + + encodeURIComponent(key); new window.SelectList({ searchUrl, @@ -40,7 +41,7 @@ export default ModalFormView.extend({ width: '100%', readOnly: false, focusSearch: false, - format (item) { + format(item) { return escapeHtml(item.name); }, selectUrl: window.baseUrl + '/api/qualityprofiles/add_project', @@ -63,9 +64,8 @@ export default ModalFormView.extend({ }); }, - onDestroy () { + onDestroy() { this.options.loadProjects(); ModalFormView.prototype.onDestroy.apply(this, arguments); } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js index 07a55cb67c6..c16397a652f 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/CopyProfileView.js @@ -24,29 +24,28 @@ import { copyProfile } from '../../../api/quality-profiles'; export default ModalFormView.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { const name = this.$('#copy-profile-name').val(); copyProfile(this.options.profile.key, name) - .then(profile => { - this.destroy(); - this.trigger('done', profile); - }) - .catch(e => { - if (e.response.status === 400) { - this.enableForm(); - e.response.json().then(r => this.showErrors(r.errors, r.warnings)); - } - }); + .then(profile => { + this.destroy(); + this.trigger('done', profile); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); }, - serializeData () { + serializeData() { return this.options.profile; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js index 4072d21500f..8e12b9668a1 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/CreateProfileView.js @@ -25,30 +25,30 @@ import { createQualityProfile } from '../../../api/quality-profiles'; export default ModalFormView.extend({ template: Template, - events () { + events() { return { ...ModalFormView.prototype.events.apply(this, arguments), 'change #create-profile-language': 'onLanguageChange' }; }, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); const form = this.$('form')[0]; const data = new FormData(form); createQualityProfile(data) - .then(r => { - this.trigger('done', r.profile); - this.destroy(); - }) - .catch(e => { - e.response.json().then(r => this.showErrors(r.errors, r.warnings)); - }); + .then(r => { + this.trigger('done', r.profile); + this.destroy(); + }) + .catch(e => { + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + }); }, - onRender () { + onRender() { ModalFormView.prototype.onRender.apply(this, arguments); this.$('select').select2({ width: '250px', @@ -57,11 +57,11 @@ export default ModalFormView.extend({ this.onLanguageChange(); }, - onLanguageChange () { + onLanguageChange() { const that = this; const language = this.$('#create-profile-language').val(); const importers = this.getImportersForLanguages(language); - this.$('.js-importer').each(function () { + this.$('.js-importer').each(function() { that.emptyInput($(this)); $(this).addClass('hidden'); }); @@ -70,22 +70,20 @@ export default ModalFormView.extend({ }); }, - emptyInput (e) { + emptyInput(e) { e.wrap('<form>').closest('form').get(0).reset(); e.unwrap(); }, - getImportersForLanguages (language) { + getImportersForLanguages(language) { if (language != null) { - return this.options.importers.filter(importer => ( - importer.languages.indexOf(language) !== -1 - )); + return this.options.importers.filter(importer => importer.languages.indexOf(language) !== -1); } else { return []; } }, - serializeData () { + serializeData() { return { ...ModalFormView.prototype.serializeData.apply(this, arguments), languages: this.options.languages, @@ -93,4 +91,3 @@ export default ModalFormView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js index 4b7efecb1d4..0c5d8a61732 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/DeleteProfileView.js @@ -25,31 +25,30 @@ export default ModalFormView.extend({ template: Template, modelEvents: { - 'destroy': 'destroy' + destroy: 'destroy' }, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { deleteProfile(this.options.profile.key) - .then(() => { - this.destroy(); - this.trigger('done'); - }) - .catch(e => { - if (e.response.status === 400) { - this.enableForm(); - e.response.json().then(r => this.showErrors(r.errors, r.warnings)); - } - }); + .then(() => { + this.destroy(); + this.trigger('done'); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); }, - serializeData () { + serializeData() { return this.options.profile; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js index 53922a5f95a..daf8db1ff04 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/RenameProfileView.js @@ -24,28 +24,27 @@ import { renameProfile } from '../../../api/quality-profiles'; export default ModalFormView.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { const name = this.$('#rename-profile-name').val(); renameProfile(this.options.profile.key, name) - .then(profile => { - this.destroy(); - this.trigger('done', profile); - }) - .catch(e => { - if (e.response.status === 400) { - this.enableForm(); - e.response.json().then(r => this.showErrors(r.errors, r.warnings)); - } - }); + .then(profile => { + this.destroy(); + this.trigger('done', profile); + }) + .catch(e => { + if (e.response.status === 400) { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + } + }); }, - serializeData () { + serializeData() { return this.options.profile; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js index 87e4977634d..39d0c720887 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreBuiltInProfilesView.js @@ -26,11 +26,11 @@ export default ModalFormView.extend({ template: Template, successTemplate: TemplateSuccess, - getTemplate () { + getTemplate() { return this.selectedLanguage ? this.successTemplate : this.template; }, - onRender () { + onRender() { ModalFormView.prototype.onRender.apply(this, arguments); this.$('select').select2({ width: '250px', @@ -38,33 +38,31 @@ export default ModalFormView.extend({ }); }, - onFormSubmit () { + onFormSubmit() { ModalFormView.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.sendRequest(); }, - sendRequest () { + sendRequest() { const language = this.$('#restore-built-in-profiles-language').val(); - this.selectedLanguage = this.options.languages - .find(l => l.key === language).name; + this.selectedLanguage = this.options.languages.find(l => l.key === language).name; restoreBuiltInProfiles(language) - .then(() => { - this.done = true; - this.render(); - this.trigger('done'); - }) - .catch(e => { - this.enableForm(); - e.response.json().then(r => this.showErrors(r.errors, r.warnings)); - }); + .then(() => { + this.done = true; + this.render(); + this.trigger('done'); + }) + .catch(e => { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + }); }, - serializeData () { + serializeData() { return { languages: this.options.languages, selectedLanguage: this.selectedLanguage }; } }); - diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js index 5ac8ac3aa9c..ebd1fabe870 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/views/RestoreProfileView.js @@ -24,27 +24,27 @@ import { restoreQualityProfile } from '../../../api/quality-profiles'; export default ModalFormView.extend({ template: Template, - onFormSubmit (e) { + onFormSubmit(e) { ModalFormView.prototype.onFormSubmit.apply(this, arguments); const data = new FormData(e.currentTarget); this.disableForm(); restoreQualityProfile(data) - .then(r => { - this.profile = r.profile; - this.ruleSuccesses = r.ruleSuccesses; - this.ruleFailures = r.ruleFailures; - this.render(); - this.trigger('done'); - }) - .catch(e => { - this.enableForm(); - e.response.json().then(r => this.showErrors(r.errors, r.warnings)); - }); + .then(r => { + this.profile = r.profile; + this.ruleSuccesses = r.ruleSuccesses; + this.ruleFailures = r.ruleFailures; + this.render(); + this.trigger('done'); + }) + .catch(e => { + this.enableForm(); + e.response.json().then(r => this.showErrors(r.errors, r.warnings)); + }); }, - serializeData () { + serializeData() { return { ...ModalFormView.prototype.serializeData.apply(this, arguments), profile: this.profile, diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.js b/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.js index da445dc52fd..61b589e49c0 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.js +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginForm.js @@ -38,66 +38,75 @@ export default class LoginForm extends React.Component { this.props.onSubmit(this.state.login, this.state.password); }; - render () { + render() { return ( - <div> - <h1 className="maintenance-title text-center">Log In to SonarQube</h1> + <div> + <h1 className="maintenance-title text-center">Log In to SonarQube</h1> - {this.props.identityProviders.length > 0 && ( - <section className="oauth-providers"> - <ul> - {this.props.identityProviders.map(identityProvider => ( - <li key={identityProvider.key}> - <a href={`${window.baseUrl}/sessions/init/${identityProvider.key}`} - style={{ backgroundColor: identityProvider.backgroundColor }} - title={`Log in with ${identityProvider.name}`}> - <img alt={identityProvider.name} width="20" height="20" - src={window.baseUrl + identityProvider.iconPath}/> - <span>Log in with {identityProvider.name}</span> - </a> - </li> - ))} - </ul> - </section> - )} + {this.props.identityProviders.length > 0 && + <section className="oauth-providers"> + <ul> + {this.props.identityProviders.map(identityProvider => ( + <li key={identityProvider.key}> + <a + href={`${window.baseUrl}/sessions/init/${identityProvider.key}`} + style={{ backgroundColor: identityProvider.backgroundColor }} + title={`Log in with ${identityProvider.name}`} + > + <img + alt={identityProvider.name} + width="20" + height="20" + src={window.baseUrl + identityProvider.iconPath} + /> + <span>Log in with {identityProvider.name}</span> + </a> + </li> + ))} + </ul> + </section>} - <form id="login_form" onSubmit={this.handleSubmit}> - <GlobalMessagesContainer/> + <form id="login_form" onSubmit={this.handleSubmit}> + <GlobalMessagesContainer /> - <div className="big-spacer-bottom"> - <label htmlFor="login" className="login-label">{translate('login')}</label> - <input type="text" - id="login" - name="login" - className="login-input" - maxLength="255" - required={true} - autoFocus={true} - placeholder={translate('login')} - value={this.state.login} - onChange={e => this.setState({ login: e.target.value })}/> - </div> + <div className="big-spacer-bottom"> + <label htmlFor="login" className="login-label">{translate('login')}</label> + <input + type="text" + id="login" + name="login" + className="login-input" + maxLength="255" + required={true} + autoFocus={true} + placeholder={translate('login')} + value={this.state.login} + onChange={e => this.setState({ login: e.target.value })} + /> + </div> - <div className="big-spacer-bottom"> - <label htmlFor="password" className="login-label">{translate('password')}</label> - <input type="password" - id="password" - name="password" - className="login-input" - required={true} - placeholder={translate('password')} - value={this.state.password} - onChange={e => this.setState({ password: e.target.value })}/> - </div> + <div className="big-spacer-bottom"> + <label htmlFor="password" className="login-label">{translate('password')}</label> + <input + type="password" + id="password" + name="password" + className="login-input" + required={true} + placeholder={translate('password')} + value={this.state.password} + onChange={e => this.setState({ password: e.target.value })} + /> + </div> - <div> - <div className="text-right overflow-hidden"> - <button name="commit" type="submit">{translate('sessions.log_in')}</button> - <a className="spacer-left" href={window.baseUrl + '/'}>{translate('cancel')}</a> - </div> + <div> + <div className="text-right overflow-hidden"> + <button name="commit" type="submit">{translate('sessions.log_in')}</button> + <a className="spacer-left" href={window.baseUrl + '/'}>{translate('cancel')}</a> </div> - </form> - </div> + </div> + </form> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.js b/server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.js index 90237122ec5..e7a9ee6849d 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.js +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginFormContainer.js @@ -34,7 +34,7 @@ class LoginFormContainer extends React.Component { state = {}; - componentDidMount () { + componentDidMount() { this.mounted = true; getIdentityProviders().then(r => { if (this.mounted) { @@ -43,7 +43,7 @@ class LoginFormContainer extends React.Component { }); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } @@ -55,19 +55,18 @@ class LoginFormContainer extends React.Component { }; handleSubmit = (login: string, password: string) => { - this.props.doLogin(login, password).then( - this.handleSuccessfulLogin, - () => { /* do nothing */ } - ); + this.props.doLogin(login, password).then(this.handleSuccessfulLogin, () => { + /* do nothing */ + }); }; - render () { + render() { if (!this.state.identityProviders) { return null; } return ( - <LoginForm identityProviders={this.state.identityProviders} onSubmit={this.handleSubmit}/> + <LoginForm identityProviders={this.state.identityProviders} onSubmit={this.handleSubmit} /> ); } } diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Logout.js b/server/sonar-web/src/main/js/apps/sessions/components/Logout.js index ae1a658970e..6d076682589 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/Logout.js +++ b/server/sonar-web/src/main/js/apps/sessions/components/Logout.js @@ -26,23 +26,24 @@ import { translate } from '../../../helpers/l10n'; import RecentHistory from '../../../app/components/nav/component/RecentHistory'; class Logout extends React.Component { - componentDidMount () { - this.props.doLogout() - .then(() => { - RecentHistory.clear(); - window.location = window.baseUrl + '/'; - }) - .catch(() => { - /* do nothing */ - }); + componentDidMount() { + this.props + .doLogout() + .then(() => { + RecentHistory.clear(); + window.location = window.baseUrl + '/'; + }) + .catch(() => { + /* do nothing */ + }); } - render () { + render() { return ( - <div> - <GlobalMessagesContainer/> - {translate('logging_out')} - </div> + <div> + <GlobalMessagesContainer /> + {translate('logging_out')} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js b/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js index 0d299d8991c..6cd65fff7f6 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js +++ b/server/sonar-web/src/main/js/apps/sessions/components/Unauthorized.js @@ -25,25 +25,24 @@ export default class Unauthorized extends React.Component { location: React.PropTypes.object.isRequired }; - render () { + render() { const { message } = this.props.location.query; return ( - <div className="text-center"> - <p id="unauthorized"> - You're not authorized to access this page. Please contact the administrator. - </p> + <div className="text-center"> + <p id="unauthorized"> + You're not authorized to access this page. Please contact the administrator. + </p> - {!!message && ( - <p className="spacer-top"> - Reason : {message} - </p> - )} + {!!message && + <p className="spacer-top"> + Reason : {message} + </p>} - <div className="big-spacer-top"> - <a href={window.baseUrl + '/'}>Home</a> - </div> + <div className="big-spacer-top"> + <a href={window.baseUrl + '/'}>Home</a> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/sessions/routes.js b/server/sonar-web/src/main/js/apps/sessions/routes.js index 888a409263f..5909cbb53fd 100644 --- a/server/sonar-web/src/main/js/apps/sessions/routes.js +++ b/server/sonar-web/src/main/js/apps/sessions/routes.js @@ -24,8 +24,8 @@ import Logout from './components/Logout'; import Unauthorized from './components/Unauthorized'; export default [ - <Redirect key="login" from="/sessions/login" to="/sessions/new"/>, - <Route key="new" path="new" component={LoginFormContainer}/>, - <Route key="logout" path="logout" component={Logout}/>, - <Route key="unauthorized" path="unauthorized" component={Unauthorized}/> + <Redirect key="login" from="/sessions/login" to="/sessions/new" />, + <Route key="new" path="new" component={LoginFormContainer} />, + <Route key="logout" path="logout" component={Logout} />, + <Route key="unauthorized" path="unauthorized" component={Unauthorized} /> ]; diff --git a/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.js b/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.js index 8915e423058..7edb667be3b 100644 --- a/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.js +++ b/server/sonar-web/src/main/js/apps/settings/__tests__/utils-test.js @@ -18,12 +18,14 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { getEmptyValue, getDefaultValue } from '../utils'; -import { TYPE_PROPERTY_SET, TYPE_STRING, TYPE_SINGLE_SELECT_LIST, TYPE_BOOLEAN } from '../constants'; +import { + TYPE_PROPERTY_SET, + TYPE_STRING, + TYPE_SINGLE_SELECT_LIST, + TYPE_BOOLEAN +} from '../constants'; -const fields = [ - { key: 'foo', type: TYPE_STRING }, - { key: 'bar', type: TYPE_SINGLE_SELECT_LIST } -]; +const fields = [{ key: 'foo', type: TYPE_STRING }, { key: 'bar', type: TYPE_SINGLE_SELECT_LIST }]; describe('#getEmptyValue()', () => { it('should work for property sets', () => { @@ -49,7 +51,10 @@ describe('#getDefaultValue()', () => { }; it('should work for boolean field when passing true', () => check(true, 'settings.boolean.true')); - it('should work for boolean field when passing "true"', () => check('true', 'settings.boolean.true')); - it('should work for boolean field when passing false', () => check(false, 'settings.boolean.false')); - it('should work for boolean field when passing "false"', () => check('false', 'settings.boolean.false')); + it('should work for boolean field when passing "true"', () => + check('true', 'settings.boolean.true')); + it('should work for boolean field when passing false', () => + check(false, 'settings.boolean.false')); + it('should work for boolean field when passing "false"', () => + check('false', 'settings.boolean.false')); }); diff --git a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.js b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.js index 63ec0cd750f..f8777a4cfd8 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/AllCategoriesList.js @@ -24,8 +24,8 @@ import CategoriesList from './CategoriesList'; import { getSettingsAppAllCategories } from '../../../store/rootReducer'; class AllCategoriesList extends React.Component { - render () { - return <CategoriesList {...this.props}/>; + render() { + return <CategoriesList {...this.props} />; } } @@ -33,6 +33,4 @@ const mapStateToProps = state => ({ categories: getSettingsAppAllCategories(state) }); -export default connect( - mapStateToProps -)(AllCategoriesList); +export default connect(mapStateToProps)(AllCategoriesList); diff --git a/server/sonar-web/src/main/js/apps/settings/components/App.js b/server/sonar-web/src/main/js/apps/settings/components/App.js index f8324cd2675..9701d248b2a 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/App.js +++ b/server/sonar-web/src/main/js/apps/settings/components/App.js @@ -44,7 +44,7 @@ class App extends React.Component { props: Props; state: State = { loaded: false }; - componentDidMount () { + componentDidMount() { document.querySelector('html').classList.add('dashboard-page'); const componentKey = this.props.component ? this.props.component.key : null; this.props.fetchSettings(componentKey).then(() => { @@ -52,22 +52,22 @@ class App extends React.Component { }); } - shouldComponentUpdate (nextProps: Props, nextState: ?{}) { + shouldComponentUpdate(nextProps: Props, nextState: ?{}) { return shallowCompare(this, nextProps, nextState); } - componentDidUpdate (prevProps) { + componentDidUpdate(prevProps) { if (prevProps.component !== this.props.component) { const componentKey = this.props.component ? this.props.component.key : null; this.props.fetchSettings(componentKey); } } - componentWillUnmount () { + componentWillUnmount() { document.querySelector('html').classList.remove('dashboard-page'); } - render () { + render() { if (!this.state.loaded) { return null; } @@ -76,26 +76,23 @@ class App extends React.Component { const selectedCategory = query.category || this.props.defaultCategory; return ( - <div id="settings-page" className="page page-limited"> - <PageHeader component={this.props.component}/> - <div className="settings-layout"> - <div className="settings-side"> - <AllCategoriesList - component={this.props.component} - selectedCategory={selectedCategory} - defaultCategory={this.props.defaultCategory}/> - </div> - <div className="settings-main"> - <CategoryDefinitionsList - component={this.props.component} - category={selectedCategory}/> + <div id="settings-page" className="page page-limited"> + <PageHeader component={this.props.component} /> + <div className="settings-layout"> + <div className="settings-side"> + <AllCategoriesList + component={this.props.component} + selectedCategory={selectedCategory} + defaultCategory={this.props.defaultCategory} + /> + </div> + <div className="settings-main"> + <CategoryDefinitionsList component={this.props.component} category={selectedCategory} /> - {selectedCategory === 'exclusions' && ( - <WildcardsHelp/> - )} - </div> + {selectedCategory === 'exclusions' && <WildcardsHelp />} </div> </div> + </div> ); } } @@ -104,8 +101,4 @@ const mapStateToProps = state => ({ defaultCategory: getSettingsAppDefaultCategory(state) }); -export default connect( - mapStateToProps, - { fetchSettings } -)(App); - +export default connect(mapStateToProps, { fetchSettings })(App); diff --git a/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js b/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js index 191339ce650..00a3751b00a 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js +++ b/server/sonar-web/src/main/js/apps/settings/components/AppContainer.js @@ -22,7 +22,9 @@ import App from './App'; import { getComponent } from '../../../store/rootReducer'; const mapStateToProps = (state, ownProps) => ({ - component: ownProps.location.query.id ? getComponent(state, ownProps.location.query.id) : undefined + component: ownProps.location.query.id + ? getComponent(state, ownProps.location.query.id) + : undefined }); export default connect(mapStateToProps)(App); diff --git a/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js b/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js index 0620131e13d..d6c89287b91 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/CategoriesList.js @@ -39,11 +39,11 @@ type Props = { export default class CategoriesList extends React.Component { rops: Props; - shouldComponentUpdate (nextProps: Props, nextState: ?{}) { + shouldComponentUpdate(nextProps: Props, nextState: ?{}) { return shallowCompare(this, nextProps, nextState); } - renderLink (category: Category) { + renderLink(category: Category) { const query = {}; if (category.key !== this.props.defaultCategory) { @@ -54,29 +54,34 @@ export default class CategoriesList extends React.Component { query.id = this.props.component.key; } - const className = category.key.toLowerCase() === this.props.selectedCategory.toLowerCase() ? 'active' : ''; + const className = category.key.toLowerCase() === this.props.selectedCategory.toLowerCase() + ? 'active' + : ''; const pathname = this.props.component ? '/project/settings' : '/settings'; return ( - <IndexLink to={{ pathname, query }} className={className} title={category.name}> - {category.name} - </IndexLink> + <IndexLink to={{ pathname, query }} className={className} title={category.name}> + {category.name} + </IndexLink> ); } - render () { - const categoriesWithName = this.props.categories.map(key => ({ key, name: getCategoryName(key) })); + render() { + const categoriesWithName = this.props.categories.map(key => ({ + key, + name: getCategoryName(key) + })); const sortedCategories = sortBy(categoriesWithName, category => category.name.toLowerCase()); return ( - <ul className="settings-menu"> - {sortedCategories.map(category => ( - <li key={category.key}> - {this.renderLink(category)} - </li> - ))} - </ul> + <ul className="settings-menu"> + {sortedCategories.map(category => ( + <li key={category.key}> + {this.renderLink(category)} + </li> + ))} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.js b/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.js index 56f2fbd056f..2759f04b1e3 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.js @@ -23,10 +23,9 @@ import { connect } from 'react-redux'; import SubCategoryDefinitionsList from './SubCategoryDefinitionsList'; import { getSettingsAppSettingsForCategory } from '../../../store/rootReducer'; - class CategoryDefinitionsList extends React.Component { - render () { - return <SubCategoryDefinitionsList {...this.props}/>; + render() { + return <SubCategoryDefinitionsList {...this.props} />; } } @@ -34,6 +33,4 @@ const mapStateToProps = (state, ownProps) => ({ settings: getSettingsAppSettingsForCategory(state, ownProps.category) }); -export default connect( - mapStateToProps -)(CategoryDefinitionsList); +export default connect(mapStateToProps)(CategoryDefinitionsList); diff --git a/server/sonar-web/src/main/js/apps/settings/components/Definition.js b/server/sonar-web/src/main/js/apps/settings/components/Definition.js index 3b1605e94b8..b16c3207caf 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/Definition.js +++ b/server/sonar-web/src/main/js/apps/settings/components/Definition.js @@ -25,7 +25,12 @@ import classNames from 'classnames'; import Input from './inputs/Input'; import DefinitionDefaults from './DefinitionDefaults'; import DefinitionChanges from './DefinitionChanges'; -import { getPropertyName, getPropertyDescription, getSettingValue, isDefaultOrInherited } from '../utils'; +import { + getPropertyName, + getPropertyDescription, + getSettingValue, + isDefaultOrInherited +} from '../utils'; import { translateWithParameters, translate } from '../../../helpers/l10n'; import { resetValue, saveValue } from '../store/actions'; import { passValidation } from '../store/settingsPage/validationMessages/actions'; @@ -59,25 +64,25 @@ class Definition extends React.Component { success: false }; - componentDidMount () { + componentDidMount() { this.mounted = true; } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - safeSetState (changes) { + safeSetState(changes) { if (this.mounted) { this.setState(changes); } } - handleChange (value) { + handleChange(value) { clearTimeout(this.timeout); this.props.changeValue(this.props.setting.definition.key, value); if (this.props.setting.definition.type === TYPE_PASSWORD) { @@ -85,30 +90,40 @@ class Definition extends React.Component { } } - handleReset () { + handleReset() { const componentKey = this.props.component ? this.props.component.key : null; const { definition } = this.props.setting; - return this.props.resetValue(definition.key, componentKey).then(() => { - this.safeSetState({ success: true }); - this.timeout = setTimeout(() => this.safeSetState({ success: false }), 3000); - }).catch(() => { /* do nothing */ }); + return this.props + .resetValue(definition.key, componentKey) + .then(() => { + this.safeSetState({ success: true }); + this.timeout = setTimeout(() => this.safeSetState({ success: false }), 3000); + }) + .catch(() => { + /* do nothing */ + }); } - handleCancel () { + handleCancel() { this.props.cancelChange(this.props.setting.definition.key); this.props.passValidation(this.props.setting.definition.key); } - handleSave () { + handleSave() { this.safeSetState({ success: false }); const componentKey = this.props.component ? this.props.component.key : null; - this.props.saveValue(this.props.setting.definition.key, componentKey).then(() => { - this.safeSetState({ success: true }); - this.timeout = setTimeout(() => this.safeSetState({ success: false }), 3000); - }).catch(() => { /* do nothing */ }); + this.props + .saveValue(this.props.setting.definition.key, componentKey) + .then(() => { + this.safeSetState({ success: true }); + this.timeout = setTimeout(() => this.safeSetState({ success: false }), 3000); + }) + .catch(() => { + /* do nothing */ + }); } - render () { + render() { const { setting, changedValue, loading } = this.props; const { definition } = setting; const propertyName = getPropertyName(definition); @@ -124,66 +139,70 @@ class Definition extends React.Component { const isDefault = isDefaultOrInherited(setting) && !hasValueChanged; return ( - <div className={className} data-key={definition.key}> - <div className="settings-definition-left"> - <h3 className="settings-definition-name" title={propertyName}> - {propertyName} - </h3> - - <div className="settings-definition-description markdown small spacer-top" - dangerouslySetInnerHTML={{ __html: getPropertyDescription(definition) }}/> - - <div className="settings-definition-key note little-spacer-top"> - {translateWithParameters('settings.key_x', definition.key)} - </div> + <div className={className} data-key={definition.key}> + <div className="settings-definition-left"> + <h3 className="settings-definition-name" title={propertyName}> + {propertyName} + </h3> + + <div + className="settings-definition-description markdown small spacer-top" + dangerouslySetInnerHTML={{ __html: getPropertyDescription(definition) }} + /> + + <div className="settings-definition-key note little-spacer-top"> + {translateWithParameters('settings.key_x', definition.key)} </div> + </div> - <div className="settings-definition-right"> - <Input setting={setting} value={effectiveValue} onChange={this.handleChange.bind(this)}/> - - {!hasValueChanged && ( - <DefinitionDefaults - setting={setting} - isDefault={isDefault} - onReset={() => this.handleReset()}/> - )} - - {hasValueChanged && ( - <DefinitionChanges - onSave={this.handleSave.bind(this)} - onCancel={this.handleCancel.bind(this)}/> - )} - - <div className="settings-definition-state"> - {loading && ( - <span className="text-info"> - <span className="settings-definition-state-icon"> - <i className="spinner"/> - </span> - {translate('settings.state.saving')} - </span> - )} - - {!loading && (this.props.validationMessage != null) && ( - <span className="text-danger"> - <span className="settings-definition-state-icon"> - <i className="icon-alert-error"/> - </span> - {translateWithParameters('settings.state.validation_failed', this.props.validationMessage)} - </span> - )} - - {!loading && this.state.success && ( - <span className="text-success"> - <span className="settings-definition-state-icon"> - <i className="icon-check"/> - </span> - {translate('settings.state.saved')} - </span> - )} - </div> + <div className="settings-definition-right"> + <Input setting={setting} value={effectiveValue} onChange={this.handleChange.bind(this)} /> + + {!hasValueChanged && + <DefinitionDefaults + setting={setting} + isDefault={isDefault} + onReset={() => this.handleReset()} + />} + + {hasValueChanged && + <DefinitionChanges + onSave={this.handleSave.bind(this)} + onCancel={this.handleCancel.bind(this)} + />} + + <div className="settings-definition-state"> + {loading && + <span className="text-info"> + <span className="settings-definition-state-icon"> + <i className="spinner" /> + </span> + {translate('settings.state.saving')} + </span>} + + {!loading && + this.props.validationMessage != null && + <span className="text-danger"> + <span className="settings-definition-state-icon"> + <i className="icon-alert-error" /> + </span> + {translateWithParameters( + 'settings.state.validation_failed', + this.props.validationMessage + )} + </span>} + + {!loading && + this.state.success && + <span className="text-success"> + <span className="settings-definition-state-icon"> + <i className="icon-check" /> + </span> + {translate('settings.state.saved')} + </span>} </div> </div> + </div> ); } } @@ -194,7 +213,10 @@ const mapStateToProps = (state, ownProps) => ({ validationMessage: getSettingsAppValidationMessage(state, ownProps.setting.definition.key) }); -export default connect( - mapStateToProps, - { changeValue, saveValue, resetValue, passValidation, cancelChange } -)(Definition); +export default connect(mapStateToProps, { + changeValue, + saveValue, + resetValue, + passValidation, + cancelChange +})(Definition); diff --git a/server/sonar-web/src/main/js/apps/settings/components/DefinitionChanges.js b/server/sonar-web/src/main/js/apps/settings/components/DefinitionChanges.js index 4f1dda6ebda..ee378179dfc 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/DefinitionChanges.js +++ b/server/sonar-web/src/main/js/apps/settings/components/DefinitionChanges.js @@ -28,33 +28,36 @@ export default class DefinitionChanges extends React.Component { onCancel: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps: {}, nextState: ?{}) { + shouldComponentUpdate(nextProps: {}, nextState: ?{}) { return shallowCompare(this, nextProps, nextState); } - handleSaveClick (e: Object) { + handleSaveClick(e: Object) { e.preventDefault(); e.target.blur(); this.props.onSave(); } - handleCancelChange (e: Object) { + handleCancelChange(e: Object) { e.preventDefault(); e.target.blur(); this.props.onCancel(); } - render () { + render() { return ( - <div className="settings-definition-changes"> - <button className="js-save-changes button-success" onClick={e => this.handleSaveClick(e)}> - {translate('save')} - </button> + <div className="settings-definition-changes"> + <button className="js-save-changes button-success" onClick={e => this.handleSaveClick(e)}> + {translate('save')} + </button> - <button className="js-cancel-changes big-spacer-left button-link" onClick={e => this.handleCancelChange(e)}> - {translate('cancel')} - </button> - </div> + <button + className="js-cancel-changes big-spacer-left button-link" + onClick={e => this.handleCancelChange(e)} + > + {translate('cancel')} + </button> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js b/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js index 4d6c3f0ad40..7d3655801f8 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js +++ b/server/sonar-web/src/main/js/apps/settings/components/DefinitionDefaults.js @@ -29,33 +29,33 @@ export default class DefinitionDefaults extends React.Component { onReset: React.PropTypes.func.isRequired }; - handleReset (e: Object) { + handleReset(e: Object) { e.preventDefault(); e.target.blur(); this.props.onReset(); } - render () { + render() { const { setting, isDefault } = this.props; const { definition } = setting; const isExplicitlySet = !isDefault && !isEmptyValue(definition, getSettingValue(setting)); return ( - <div> - {isDefault && ( - <div className="spacer-top note" style={{ lineHeight: '24px' }}> - {translate('settings._default')} - </div> - )} + <div> + {isDefault && + <div className="spacer-top note" style={{ lineHeight: '24px' }}> + {translate('settings._default')} + </div>} - {isExplicitlySet && ( - <div className="spacer-top nowrap"> - <button onClick={e => this.handleReset(e)}>{translate('reset_verb')}</button> - <span className="spacer-left note">{translate('default')}{': '}{getDefaultValue(setting)}</span> - </div> - )} - </div> + {isExplicitlySet && + <div className="spacer-top nowrap"> + <button onClick={e => this.handleReset(e)}>{translate('reset_verb')}</button> + <span className="spacer-left note"> + {translate('default')}{': '}{getDefaultValue(setting)} + </span> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/DefinitionsList.js b/server/sonar-web/src/main/js/apps/settings/components/DefinitionsList.js index d99c81ca9b8..ca8222a7496 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/DefinitionsList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/DefinitionsList.js @@ -28,19 +28,19 @@ export default class DefinitionsList extends React.Component { settings: React.PropTypes.array.isRequired }; - shouldComponentUpdate (nextProps: {}, nextState: ?{}) { + shouldComponentUpdate(nextProps: {}, nextState: ?{}) { return shallowCompare(this, nextProps, nextState); } - render () { + render() { return ( - <ul className="settings-definitions-list"> - {this.props.settings.map(setting => ( - <li key={setting.definition.key}> - <Definition component={this.props.component} setting={setting}/> - </li> - ))} - </ul> + <ul className="settings-definitions-list"> + {this.props.settings.map(setting => ( + <li key={setting.definition.key}> + <Definition component={this.props.component} setting={setting} /> + </li> + ))} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/EmailForm.js b/server/sonar-web/src/main/js/apps/settings/components/EmailForm.js index ea88bfe84df..e923f635443 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/EmailForm.js +++ b/server/sonar-web/src/main/js/apps/settings/components/EmailForm.js @@ -25,7 +25,7 @@ import { parseError } from '../../code/utils'; import { getCurrentUser } from '../../../store/rootReducer'; class EmailForm extends React.Component { - constructor (props) { + constructor(props) { super(props); this.state = { recipient: this.props.currentUser.email, @@ -37,7 +37,7 @@ class EmailForm extends React.Component { }; } - handleFormSubmit (e) { + handleFormSubmit(e) { e.preventDefault(); this.setState({ success: false, error: null, loading: true }); const { recipient, subject, message } = this.state; @@ -47,72 +47,78 @@ class EmailForm extends React.Component { ); } - render () { + render() { return ( - <div className="huge-spacer-top"> - <h3 className="spacer-bottom">{translate('email_configuration.test.title')}</h3> + <div className="huge-spacer-top"> + <h3 className="spacer-bottom">{translate('email_configuration.test.title')}</h3> - <form style={{ marginLeft: 201 }} onSubmit={e => this.handleFormSubmit(e)}> - {this.state.success && ( - <div className="modal-field"> - <div className="alert alert-success"> - {translateWithParameters('email_configuration.test.email_was_sent_to_x', this.state.recipient)} - </div> - </div> - )} - - {this.state.error != null && ( - <div className="modal-field"> - <div className="alert alert-danger"> - {this.state.error} - </div> - </div> - )} - - <div className="modal-field"> - <label htmlFor="test-email-to"> - {translate('email_configuration.test.to_address')} - <em className="mandatory">*</em> - </label> - <input - id="test-email-to" - type="email" - required={true} - value={this.state.recipient} - disabled={this.state.loading} - onChange={e => this.setState({ recipient: e.target.value })}/> - </div> + <form style={{ marginLeft: 201 }} onSubmit={e => this.handleFormSubmit(e)}> + {this.state.success && <div className="modal-field"> - <label htmlFor="test-email-subject"> - {translate('email_configuration.test.subject')} - </label> - <input - id="test-email-subject" - type="text" - value={this.state.subject} - disabled={this.state.loading} - onChange={e => this.setState({ subject: e.target.value })}/> - </div> - <div className="modal-field"> - <label htmlFor="test-email-message"> - {translate('email_configuration.test.message')} - <em className="mandatory">*</em> - </label> - <textarea - id="test-email-title" - required={true} - rows="5" - value={this.state.message} - disabled={this.state.loading} - onChange={e => this.setState({ message: e.target.value })}/> - </div> + <div className="alert alert-success"> + {translateWithParameters( + 'email_configuration.test.email_was_sent_to_x', + this.state.recipient + )} + </div> + </div>} + {this.state.error != null && <div className="modal-field"> - {this.state.loading && <i className="spacer-right spinner"/>} - <button disabled={this.state.loading}>{translate('email_configuration.test.send')}</button> - </div> - </form> - </div> + <div className="alert alert-danger"> + {this.state.error} + </div> + </div>} + + <div className="modal-field"> + <label htmlFor="test-email-to"> + {translate('email_configuration.test.to_address')} + <em className="mandatory">*</em> + </label> + <input + id="test-email-to" + type="email" + required={true} + value={this.state.recipient} + disabled={this.state.loading} + onChange={e => this.setState({ recipient: e.target.value })} + /> + </div> + <div className="modal-field"> + <label htmlFor="test-email-subject"> + {translate('email_configuration.test.subject')} + </label> + <input + id="test-email-subject" + type="text" + value={this.state.subject} + disabled={this.state.loading} + onChange={e => this.setState({ subject: e.target.value })} + /> + </div> + <div className="modal-field"> + <label htmlFor="test-email-message"> + {translate('email_configuration.test.message')} + <em className="mandatory">*</em> + </label> + <textarea + id="test-email-title" + required={true} + rows="5" + value={this.state.message} + disabled={this.state.loading} + onChange={e => this.setState({ message: e.target.value })} + /> + </div> + + <div className="modal-field"> + {this.state.loading && <i className="spacer-right spinner" />} + <button disabled={this.state.loading}> + {translate('email_configuration.test.send')} + </button> + </div> + </form> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js b/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js index 237645dc176..0240fa7c61b 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js @@ -26,20 +26,20 @@ export default class PageHeader extends React.Component { component: React.PropTypes.object }; - render () { - const title = this.props.component != null ? - translate('project_settings.page') : - translate('settings.page'); + render() { + const title = this.props.component != null + ? translate('project_settings.page') + : translate('settings.page'); - const description = this.props.component != null ? - translate('project_settings.page.description') : - translate('settings.page.description'); + const description = this.props.component != null + ? translate('project_settings.page.description') + : translate('settings.page.description'); return ( - <header className="page-header"> - <h1 className="page-title">{title}</h1> - <div className="page-description">{description}</div> - </header> + <header className="page-header"> + <h1 className="page-title">{title}</h1> + <div className="page-description">{description}</div> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js index e4adb0ef07b..f6db05ef5fe 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js @@ -32,41 +32,46 @@ export default class SubCategoryDefinitionsList extends React.Component { settings: React.PropTypes.array.isRequired }; - shouldComponentUpdate (nextProps: {}, nextState: ?{}) { + shouldComponentUpdate(nextProps: {}, nextState: ?{}) { return shallowCompare(this, nextProps, nextState); } - renderEmailForm (subCategoryKey: string) { + renderEmailForm(subCategoryKey: string) { const isEmailSettings = this.props.category === 'general' && subCategoryKey === 'email'; if (!isEmailSettings) { return null; } - return <EmailForm/>; + return <EmailForm />; } - render () { + render() { const bySubCategory = groupBy(this.props.settings, setting => setting.definition.subCategory); const subCategories = Object.keys(bySubCategory).map(key => ({ key, name: getSubCategoryName(bySubCategory[key][0].definition.category, key), description: getSubCategoryDescription(bySubCategory[key][0].definition.category, key) })); - const sortedSubCategories = sortBy(subCategories, subCategory => subCategory.name.toLowerCase()); + const sortedSubCategories = sortBy(subCategories, subCategory => + subCategory.name.toLowerCase()); return ( - <ul className="settings-sub-categories-list"> - {sortedSubCategories.map(subCategory => ( - <li key={subCategory.key}> - <h2 className="settings-sub-category-name">{subCategory.name}</h2> - {subCategory.description != null && ( - <div className="settings-sub-category-description markdown" - dangerouslySetInnerHTML={{ __html: subCategory.description }}/> - )} - <DefinitionsList settings={bySubCategory[subCategory.key]} component={this.props.component}/> - {this.renderEmailForm(subCategory.key)} - </li> - ))} - </ul> + <ul className="settings-sub-categories-list"> + {sortedSubCategories.map(subCategory => ( + <li key={subCategory.key}> + <h2 className="settings-sub-category-name">{subCategory.name}</h2> + {subCategory.description != null && + <div + className="settings-sub-category-description markdown" + dangerouslySetInnerHTML={{ __html: subCategory.description }} + />} + <DefinitionsList + settings={bySubCategory[subCategory.key]} + component={this.props.component} + /> + {this.renderEmailForm(subCategory.key)} + </li> + ))} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/WildcardsHelp.js b/server/sonar-web/src/main/js/apps/settings/components/WildcardsHelp.js index c7e192ba74e..c9e06ec513d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/WildcardsHelp.js +++ b/server/sonar-web/src/main/js/apps/settings/components/WildcardsHelp.js @@ -20,105 +20,106 @@ import React from 'react'; export default class WildcardsHelp extends React.Component { - render () { + render() { return ( - <div className="huge-spacer-top"> - <h2 className="spacer-bottom">Wildcards</h2> - <p className="spacer-bottom">Following rules are applied:</p> + <div className="huge-spacer-top"> + <h2 className="spacer-bottom">Wildcards</h2> + <p className="spacer-bottom">Following rules are applied:</p> - <table className="data spacer-bottom"> - <tbody> - <tr> - <td>*</td> - <td>Match zero or more characters</td> - </tr> - <tr> - <td>**</td> - <td>Match zero or more directories</td> - </tr> - <tr> - <td>?</td> - <td>Match a single character</td> - </tr> - </tbody> - </table> + <table className="data spacer-bottom"> + <tbody> + <tr> + <td>*</td> + <td>Match zero or more characters</td> + </tr> + <tr> + <td>**</td> + <td>Match zero or more directories</td> + </tr> + <tr> + <td>?</td> + <td>Match a single character</td> + </tr> + </tbody> + </table> - <table className="data zebra"> - <thead> - <tr> - <th>Example</th> - <th>Matches</th> - <th>Does not match</th> - </tr> - </thead> - <tbody> - <tr> - <td>**/foo/*.js</td> - <td> - <ul> - <li>src/foo/bar.js</li> - <li>lib/ui/foo/bar.js</li> - </ul> - </td> - <td> - <ul> - <li>src/bar.js</li> - <li>src/foo2/bar.js</li> - </ul> - </td> - </tr> - <tr> - <td>src/foo/*bar*.js</td> - <td> - <ul> - <li>src/foo/bar.js</li> - <li>src/foo/bar1.js</li> - <li>src/foo/bar123.js</li> - <li>src/foo/123bar123.js</li> - </ul> - </td> - <td> - <ul> - <li>src/foo/ui/bar.js</li> - <li>src/bar.js</li> - </ul> - </td> - </tr> - <tr> - <td>src/foo/**</td> - <td> - <ul> - <li>src/foo/bar.js</li> - <li>src/foo/ui/bar.js</li> - </ul> - </td> - <td> - <ul> - <li>src/bar/foo/bar.js</li> - <li>src/bar.js</li> - </ul> - </td> - </tr> - <tr> - <td>**/foo?.js - </td> - <td> - <ul> - <li>src/foo1.js</li> - <li>src/bar/foo1.js</li> - </ul> - </td> - <td> - <ul> - <li>src/foo.js</li> - <li>src/foo12.js</li> - <li>src/12foo3.js</li> - </ul> - </td> - </tr> - </tbody> - </table> - </div> + <table className="data zebra"> + <thead> + <tr> + <th>Example</th> + <th>Matches</th> + <th>Does not match</th> + </tr> + </thead> + <tbody> + <tr> + <td>**/foo/*.js</td> + <td> + <ul> + <li>src/foo/bar.js</li> + <li>lib/ui/foo/bar.js</li> + </ul> + </td> + <td> + <ul> + <li>src/bar.js</li> + <li>src/foo2/bar.js</li> + </ul> + </td> + </tr> + <tr> + <td>src/foo/*bar*.js</td> + <td> + <ul> + <li>src/foo/bar.js</li> + <li>src/foo/bar1.js</li> + <li>src/foo/bar123.js</li> + <li>src/foo/123bar123.js</li> + </ul> + </td> + <td> + <ul> + <li>src/foo/ui/bar.js</li> + <li>src/bar.js</li> + </ul> + </td> + </tr> + <tr> + <td>src/foo/**</td> + <td> + <ul> + <li>src/foo/bar.js</li> + <li>src/foo/ui/bar.js</li> + </ul> + </td> + <td> + <ul> + <li>src/bar/foo/bar.js</li> + <li>src/bar.js</li> + </ul> + </td> + </tr> + <tr> + <td> + **/foo?.js + </td> + <td> + <ul> + <li>src/foo1.js</li> + <li>src/bar/foo1.js</li> + </ul> + </td> + <td> + <ul> + <li>src/foo.js</li> + <li>src/foo12.js</li> + <li>src/12foo3.js</li> + </ul> + </td> + </tr> + </tbody> + </table> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/Input.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/Input.js index a1c9d4c3c10..43daae89c40 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/Input.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/Input.js @@ -31,21 +31,21 @@ export default class Input extends React.Component { onChange: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - render () { + render() { const { definition } = this.props.setting; if (definition.multiValues) { - return <MultiValueInput {...this.props}/>; + return <MultiValueInput {...this.props} />; } if (definition.type === TYPE_PROPERTY_SET) { - return <PropertySetInput {...this.props}/>; + return <PropertySetInput {...this.props} />; } - return <PrimitiveInput {...this.props}/>; + return <PrimitiveInput {...this.props} />; } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForBoolean.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForBoolean.js index 0c0b9e122e3..ff566af6e3f 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForBoolean.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForBoolean.js @@ -28,21 +28,16 @@ export default class InputForBoolean extends React.Component { value: React.PropTypes.oneOfType([React.PropTypes.bool, React.PropTypes.string]) }; - render () { + render() { const hasValue = this.props.value != null; const displayedValue = hasValue ? this.props.value : false; return ( - <div className="display-inline-block text-top"> - <Toggle - name={this.props.name} - value={displayedValue} - onChange={this.props.onChange}/> + <div className="display-inline-block text-top"> + <Toggle name={this.props.name} value={displayedValue} onChange={this.props.onChange} /> - {!hasValue && ( - <span className="spacer-left note">{translate('settings.not_set')}</span> - )} - </div> + {!hasValue && <span className="spacer-left note">{translate('settings.not_set')}</span>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForNumber.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForNumber.js index 437b671ab25..c0101776587 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForNumber.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForNumber.js @@ -21,9 +21,7 @@ import React from 'react'; import SimpleInput from './SimpleInput'; export default class InputForNumber extends React.Component { - render () { - return ( - <SimpleInput {...this.props} className="input-small" type="text"/> - ); + render() { + return <SimpleInput {...this.props} className="input-small" type="text" />; } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.js index 195eabdc220..0605da6d32e 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForPassword.js @@ -29,53 +29,54 @@ export default class InputForPassword extends React.Component { changing: false }; - handleInputChange (e) { + handleInputChange(e) { this.setState({ value: e.target.value }); } - handleChangeClick (e) { + handleChangeClick(e) { e.preventDefault(); e.target.blur(); this.setState({ changing: true }); } - handleCancelChangeClick (e) { + handleCancelChangeClick(e) { e.preventDefault(); e.target.blur(); this.setState({ changing: false, value: '' }); } - handleFormSubmit (e) { + handleFormSubmit(e) { e.preventDefault(); this.props.onChange(this.state.value); this.setState({ changing: false, value: '' }); } - renderInput () { + renderInput() { return ( - <div> - <form onSubmit={e => this.handleFormSubmit(e)}> - <input className="hidden" type="password"/> - <input - value={this.state.value} - name={this.props.name} - className="js-password-input input-large text-top" - type="password" - autoFocus={true} - autoComplete={false} - onChange={e => this.handleInputChange(e)}/> + <div> + <form onSubmit={e => this.handleFormSubmit(e)}> + <input className="hidden" type="password" /> + <input + value={this.state.value} + name={this.props.name} + className="js-password-input input-large text-top" + type="password" + autoFocus={true} + autoComplete={false} + onChange={e => this.handleInputChange(e)} + /> - <button className="spacer-left button-success">{translate('save')}</button> + <button className="spacer-left button-success">{translate('save')}</button> - <a className="spacer-left" href="#" onClick={e => this.handleCancelChangeClick(e)}> - {translate('cancel')} - </a> - </form> - </div> + <a className="spacer-left" href="#" onClick={e => this.handleCancelChangeClick(e)}> + {translate('cancel')} + </a> + </form> + </div> ); } - render () { + render() { if (this.state.changing) { return this.renderInput(); } @@ -83,15 +84,13 @@ export default class InputForPassword extends React.Component { const hasValue = !!this.props.value; return ( - <div> - {hasValue && ( - <i className="big-spacer-right icon-lock icon-gray"/> - )} + <div> + {hasValue && <i className="big-spacer-right icon-lock icon-gray" />} - <button onClick={e => this.handleChangeClick(e)}> - {hasValue ? translate('change_verb') : translate('set')} - </button> - </div> + <button onClick={e => this.handleChangeClick(e)}> + {hasValue ? translate('change_verb') : translate('set')} + </button> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.js index 150bbe46e2a..bfdfdd60996 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForSingleSelectList.js @@ -27,24 +27,25 @@ export default class InputForSingleSelectList extends React.Component { options: React.PropTypes.arrayOf(React.PropTypes.string).isRequired }; - handleInputChange (option) { + handleInputChange(option) { this.props.onChange(option.value); } - render () { + render() { const options = this.props.options.map(option => ({ label: option, value: option })); return ( - <Select - name={this.props.name} - className="input-large" - options={options} - clearable={false} - value={this.props.value} - onChange={option => this.handleInputChange(option)}/> + <Select + name={this.props.name} + className="input-large" + options={options} + clearable={false} + value={this.props.value} + onChange={option => this.handleInputChange(option)} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForString.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForString.js index 6f9149ebc9b..21083885163 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForString.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForString.js @@ -21,9 +21,7 @@ import React from 'react'; import SimpleInput from './SimpleInput'; export default class InputForString extends React.Component { - render () { - return ( - <SimpleInput {...this.props} className="input-large" type="text"/> - ); + render() { + return <SimpleInput {...this.props} className="input-large" type="text" />; } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForText.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForText.js index a3753bde499..3a62920746d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForText.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/InputForText.js @@ -23,18 +23,19 @@ import { defaultInputPropTypes } from '../../propTypes'; export default class InputForText extends React.Component { static propTypes = defaultInputPropTypes; - handleInputChange (e) { + handleInputChange(e) { this.props.onChange(e.target.value); } - render () { + render() { return ( - <textarea - name={this.props.name} - className="input-super-large text-top" - rows="5" - value={this.props.value || ''} - onChange={e => this.handleInputChange(e)}/> + <textarea + name={this.props.name} + className="input-super-large text-top" + rows="5" + value={this.props.value || ''} + onChange={e => this.handleInputChange(e)} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/MultiValueInput.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/MultiValueInput.js index 3bb311dcd45..79329842b57 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/MultiValueInput.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/MultiValueInput.js @@ -28,17 +28,17 @@ export default class MultiValueInput extends React.Component { onChange: React.PropTypes.func.isRequired }; - ensureValue () { + ensureValue() { return this.props.value || []; } - handleSingleInputChange (index, value) { + handleSingleInputChange(index, value) { const newValue = [...this.ensureValue()]; newValue.splice(index, 1, value); this.props.onChange(newValue); } - handleDeleteValue (e, index) { + handleDeleteValue(e, index) { e.preventDefault(); e.target.blur(); @@ -47,7 +47,7 @@ export default class MultiValueInput extends React.Component { this.props.onChange(newValue); } - prepareSetting () { + prepareSetting() { const { setting } = this.props; const newDefinition = { ...setting.definition, multiValues: false }; return { @@ -57,34 +57,38 @@ export default class MultiValueInput extends React.Component { }; } - renderInput (value, index, isLast) { + renderInput(value, index, isLast) { return ( - <li key={index} className="spacer-bottom"> - <PrimitiveInput - setting={this.prepareSetting()} - value={value} - onChange={this.handleSingleInputChange.bind(this, index)}/> + <li key={index} className="spacer-bottom"> + <PrimitiveInput + setting={this.prepareSetting()} + value={value} + onChange={this.handleSingleInputChange.bind(this, index)} + /> - {!isLast && ( - <div className="display-inline-block spacer-left"> - <button className="js-remove-value button-clean" onClick={e => this.handleDeleteValue(e, index)}> - <i className="icon-delete"/> - </button> - </div> - )} - </li> + {!isLast && + <div className="display-inline-block spacer-left"> + <button + className="js-remove-value button-clean" + onClick={e => this.handleDeleteValue(e, index)} + > + <i className="icon-delete" /> + </button> + </div>} + </li> ); } - render () { + render() { const displayedValue = [...this.ensureValue(), ...getEmptyValue(this.props.setting.definition)]; return ( - <div> - <ul> - {displayedValue.map((value, index) => this.renderInput(value, index, index === displayedValue.length - 1))} - </ul> - </div> + <div> + <ul> + {displayedValue.map((value, index) => + this.renderInput(value, index, index === displayedValue.length - 1))} + </ul> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/PrimitiveInput.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/PrimitiveInput.js index f962066cade..35ace9d8b47 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/PrimitiveInput.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/PrimitiveInput.js @@ -44,7 +44,7 @@ export default class PrimitiveInput extends React.Component { onChange: React.PropTypes.func.isRequired }; - render () { + render() { const { setting, value, onChange, ...other } = this.props; const { definition } = setting; @@ -52,24 +52,26 @@ export default class PrimitiveInput extends React.Component { if (definition.type === types.TYPE_SINGLE_SELECT_LIST) { return ( - <InputForSingleSelectList - name={name} - value={value} - isDefault={isDefaultOrInherited(setting)} - options={definition.options} - onChange={onChange} - {...other}/> + <InputForSingleSelectList + name={name} + value={value} + isDefault={isDefaultOrInherited(setting)} + options={definition.options} + onChange={onChange} + {...other} + /> ); } const InputComponent = typeMapping[definition.type] || InputForString; return ( - <InputComponent - name={name} - value={value} - isDefault={isDefaultOrInherited(setting)} - onChange={onChange} - {...other}/> + <InputComponent + name={name} + value={value} + isDefault={isDefaultOrInherited(setting)} + onChange={onChange} + {...other} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/PropertySetInput.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/PropertySetInput.js index 9384ac3cd70..ecf57e48092 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/PropertySetInput.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/PropertySetInput.js @@ -28,15 +28,15 @@ export default class PropertySetInput extends React.Component { onChange: React.PropTypes.func.isRequired }; - ensureValue () { + ensureValue() { return this.props.value || []; } - getFieldName (field) { + getFieldName(field) { return getUniqueName(this.props.setting.definition, field.key); } - handleDeleteValue (e, index) { + handleDeleteValue(e, index) { e.preventDefault(); e.target.blur(); @@ -45,7 +45,7 @@ export default class PropertySetInput extends React.Component { this.props.onChange(newValue); } - handleInputChange (index, fieldKey, value) { + handleInputChange(index, fieldKey, value) { const emptyValue = getEmptyValue(this.props.setting.definition)[0]; const newValue = [...this.ensureValue()]; const newFields = { ...emptyValue, ...newValue[index], [fieldKey]: value }; @@ -53,58 +53,63 @@ export default class PropertySetInput extends React.Component { return this.props.onChange(newValue); } - renderFields (fieldValues, index, isLast) { + renderFields(fieldValues, index, isLast) { const { setting } = this.props; return ( - <tr key={index}> - {setting.definition.fields.map(field => ( - <td key={field.key}> - <PrimitiveInput - name={this.getFieldName(field)} - setting={{ definition: field, value: fieldValues[field.key] }} - value={fieldValues[field.key]} - onChange={this.handleInputChange.bind(this, index, field.key)}/> - </td> - ))} - <td className="thin nowrap"> - {!isLast && ( - <button className="js-remove-value button-link" onClick={e => this.handleDeleteValue(e, index)}> - <i className="icon-delete"/> - </button> - )} + <tr key={index}> + {setting.definition.fields.map(field => ( + <td key={field.key}> + <PrimitiveInput + name={this.getFieldName(field)} + setting={{ definition: field, value: fieldValues[field.key] }} + value={fieldValues[field.key]} + onChange={this.handleInputChange.bind(this, index, field.key)} + /> </td> - </tr> + ))} + <td className="thin nowrap"> + {!isLast && + <button + className="js-remove-value button-link" + onClick={e => this.handleDeleteValue(e, index)} + > + <i className="icon-delete" /> + </button>} + </td> + </tr> ); } - render () { + render() { const { setting } = this.props; const displayedValue = [...this.ensureValue(), ...getEmptyValue(this.props.setting.definition)]; return ( - <div> - <table className="data zebra-hover no-outer-padding" style={{ width: 'auto', minWidth: 480, marginTop: -12 }}> - <thead> - <tr> - {setting.definition.fields.map(field => ( - <th key={field.key}> - {field.name} - {field.description != null && ( - <span className="spacer-top small">{field.description}</span> - )} - </th> - ))} - <th> </th> - </tr> - </thead> - <tbody> - {displayedValue.map((fieldValues, index) => - this.renderFields(fieldValues, index, index === displayedValue.length - 1))} - </tbody> - </table> - </div> + <div> + <table + className="data zebra-hover no-outer-padding" + style={{ width: 'auto', minWidth: 480, marginTop: -12 }} + > + <thead> + <tr> + {setting.definition.fields.map(field => ( + <th key={field.key}> + {field.name} + {field.description != null && + <span className="spacer-top small">{field.description}</span>} + </th> + ))} + <th> </th> + </tr> + </thead> + <tbody> + {displayedValue.map((fieldValues, index) => + this.renderFields(fieldValues, index, index === displayedValue.length - 1))} + </tbody> + </table> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.js index b32b052c168..31ec32c0360 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/SimpleInput.js @@ -28,18 +28,19 @@ export default class SimpleInput extends React.Component { className: React.PropTypes.string.isRequired }; - handleInputChange (e) { + handleInputChange(e) { this.props.onChange(e.target.value); } - render () { + render() { return ( - <input - name={this.props.name} - className={this.props.className + ' text-top'} - type={this.props.type} - value={this.props.value || ''} - onChange={e => this.handleInputChange(e)}/> + <input + name={this.props.name} + className={this.props.className + ' text-top'} + type={this.props.type} + value={this.props.value || ''} + onChange={e => this.handleInputChange(e)} + /> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/Input-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/Input-test.js index 5d5c3ff0360..a8b0df97e5f 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/Input-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/Input-test.js @@ -28,7 +28,9 @@ import { TYPE_STRING, TYPE_PROPERTY_SET } from '../../../constants'; it('should render PrimitiveInput', () => { const setting = { definition: { key: 'example', type: TYPE_STRING } }; const onChange = jest.fn(); - const input = shallow(<Input setting={setting} value="foo" onChange={onChange}/>).find(PrimitiveInput); + const input = shallow(<Input setting={setting} value="foo" onChange={onChange} />).find( + PrimitiveInput + ); expect(input.length).toBe(1); expect(input.prop('setting')).toBe(setting); expect(input.prop('value')).toBe('foo'); @@ -39,7 +41,9 @@ it('should render MultiValueInput', () => { const setting = { definition: { key: 'example', type: TYPE_STRING, multiValues: true } }; const value = ['foo', 'bar']; const onChange = jest.fn(); - const input = shallow(<Input setting={setting} value={value} onChange={onChange}/>).find(MultiValueInput); + const input = shallow(<Input setting={setting} value={value} onChange={onChange} />).find( + MultiValueInput + ); expect(input.length).toBe(1); expect(input.prop('setting')).toBe(setting); expect(input.prop('value')).toBe(value); @@ -50,7 +54,9 @@ it('should render PropertySetInput', () => { const setting = { definition: { key: 'example', type: TYPE_PROPERTY_SET, fields: [] } }; const value = [{ foo: 'bar' }]; const onChange = jest.fn(); - const input = shallow(<Input setting={setting} value={value} onChange={onChange}/>).find(PropertySetInput); + const input = shallow(<Input setting={setting} value={value} onChange={onChange} />).find( + PropertySetInput + ); expect(input.length).toBe(1); expect(input.prop('setting')).toBe(setting); expect(input.prop('value')).toBe(value); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForBoolean-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForBoolean-test.js index 828421df435..f72617627fc 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForBoolean-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForBoolean-test.js @@ -25,11 +25,7 @@ import Toggle from '../../../../../components/controls/Toggle'; it('should render Toggle', () => { const onChange = jest.fn(); const toggle = shallow( - <InputForBoolean - name="foo" - value={true} - isDefault={false} - onChange={onChange}/> + <InputForBoolean name="foo" value={true} isDefault={false} onChange={onChange} /> ).find(Toggle); expect(toggle.length).toBe(1); expect(toggle.prop('name')).toBe('foo'); @@ -39,12 +35,7 @@ it('should render Toggle', () => { it('should render Toggle without value', () => { const onChange = jest.fn(); - const input = shallow( - <InputForBoolean - name="foo" - isDefault={false} - onChange={onChange}/> - ); + const input = shallow(<InputForBoolean name="foo" isDefault={false} onChange={onChange} />); const toggle = input.find(Toggle); expect(toggle.length).toBe(1); expect(toggle.prop('name')).toBe('foo'); @@ -56,11 +47,7 @@ it('should render Toggle without value', () => { it('should call onChange', () => { const onChange = jest.fn(); const input = shallow( - <InputForBoolean - name="foo" - value={true} - isDefault={false} - onChange={onChange}/> + <InputForBoolean name="foo" value={true} isDefault={false} onChange={onChange} /> ); const toggle = input.find(Toggle); expect(toggle.length).toBe(1); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForNumber-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForNumber-test.js index bad8f9de1b7..964193ec31f 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForNumber-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForNumber-test.js @@ -25,11 +25,7 @@ import SimpleInput from '../SimpleInput'; it('should render SimpleInput', () => { const onChange = jest.fn(); const simpleInput = shallow( - <InputForNumber - name="foo" - value={17} - isDefault={false} - onChange={onChange}/> + <InputForNumber name="foo" value={17} isDefault={false} onChange={onChange} /> ).find(SimpleInput); expect(simpleInput.length).toBe(1); expect(simpleInput.prop('name')).toBe('foo'); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.js index 02156f5ef5e..46756ec226a 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForPassword-test.js @@ -25,11 +25,7 @@ import { click, change, submit } from '../../../../../helpers/testUtils'; it('should render lock icon, but no form', () => { const onChange = jest.fn(); const input = shallow( - <InputForPassword - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + <InputForPassword name="foo" value="bar" isDefault={false} onChange={onChange} /> ); expect(input.find('.icon-lock').length).toBe(1); expect(input.find('form').length).toBe(0); @@ -38,11 +34,7 @@ it('should render lock icon, but no form', () => { it('should open form', () => { const onChange = jest.fn(); const input = shallow( - <InputForPassword - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + <InputForPassword name="foo" value="bar" isDefault={false} onChange={onChange} /> ); const button = input.find('button'); expect(button.length).toBe(1); @@ -54,11 +46,7 @@ it('should open form', () => { it('should close form', () => { const onChange = jest.fn(); const input = shallow( - <InputForPassword - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + <InputForPassword name="foo" value="bar" isDefault={false} onChange={onChange} /> ); const button = input.find('button'); expect(button.length).toBe(1); @@ -73,11 +61,7 @@ it('should close form', () => { it('should set value', () => { const onChange = jest.fn(() => Promise.resolve()); const input = shallow( - <InputForPassword - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + <InputForPassword name="foo" value="bar" isDefault={false} onChange={onChange} /> ); click(input.find('button')); change(input.find('.js-password-input'), 'secret'); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.js index 5c50d24d4e9..e51293ea746 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForSingleSelectList-test.js @@ -26,11 +26,12 @@ it('should render Select', () => { const onChange = jest.fn(); const select = shallow( <InputForSingleSelectList - name="foo" - value="bar" - options={['foo', 'bar', 'baz']} - isDefault={false} - onChange={onChange}/> + name="foo" + value="bar" + options={['foo', 'bar', 'baz']} + isDefault={false} + onChange={onChange} + /> ).find(Select); expect(select.length).toBe(1); expect(select.prop('name')).toBe('foo'); @@ -47,11 +48,12 @@ it('should call onChange', () => { const onChange = jest.fn(); const select = shallow( <InputForSingleSelectList - name="foo" - value="bar" - options={['foo', 'bar', 'baz']} - isDefault={false} - onChange={onChange}/> + name="foo" + value="bar" + options={['foo', 'bar', 'baz']} + isDefault={false} + onChange={onChange} + /> ).find(Select); expect(select.length).toBe(1); expect(select.prop('onChange')).toBeTruthy(); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForString-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForString-test.js index 65a81bba419..2c89241f2f7 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForString-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForString-test.js @@ -25,11 +25,7 @@ import SimpleInput from '../SimpleInput'; it('should render SimpleInput', () => { const onChange = jest.fn(); const simpleInput = shallow( - <InputForString - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + <InputForString name="foo" value="bar" isDefault={false} onChange={onChange} /> ).find(SimpleInput); expect(simpleInput.length).toBe(1); expect(simpleInput.prop('name')).toBe('foo'); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForText-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForText-test.js index c3834d557ce..8778742d7be 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForText-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/InputForText-test.js @@ -25,11 +25,7 @@ import { change } from '../../../../../helpers/testUtils'; it('should render textarea', () => { const onChange = jest.fn(); const textarea = shallow( - <InputForText - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + <InputForText name="foo" value="bar" isDefault={false} onChange={onChange} /> ).find('textarea'); expect(textarea.length).toBe(1); expect(textarea.prop('name')).toBe('foo'); @@ -40,11 +36,7 @@ it('should render textarea', () => { it('should call onChange', () => { const onChange = jest.fn(); const textarea = shallow( - <InputForText - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + <InputForText name="foo" value="bar" isDefault={false} onChange={onChange} /> ).find('textarea'); expect(textarea.length).toBe(1); expect(textarea.prop('onChange')).toBeTruthy(); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/MultiValueInput-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/MultiValueInput-test.js index 57c982dfd28..5742801f356 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/MultiValueInput-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/MultiValueInput-test.js @@ -33,7 +33,9 @@ const assertValues = (inputs, values) => { }; it('should render one value', () => { - const multiValueInput = shallow(<MultiValueInput setting={{ definition }} value={['foo']} onChange={jest.fn()}/>); + const multiValueInput = shallow( + <MultiValueInput setting={{ definition }} value={['foo']} onChange={jest.fn()} /> + ); const stringInputs = multiValueInput.find(PrimitiveInput); expect(stringInputs.length).toBe(1 + 1); assertValues(stringInputs, ['foo', '']); @@ -41,7 +43,8 @@ it('should render one value', () => { it('should render several values', () => { const multiValueInput = shallow( - <MultiValueInput setting={{ definition }} value={['foo', 'bar', 'baz']} onChange={jest.fn()}/>); + <MultiValueInput setting={{ definition }} value={['foo', 'bar', 'baz']} onChange={jest.fn()} /> + ); const stringInputs = multiValueInput.find(PrimitiveInput); expect(stringInputs.length).toBe(3 + 1); assertValues(stringInputs, ['foo', 'bar', 'baz', '']); @@ -50,7 +53,8 @@ it('should render several values', () => { it('should remove value', () => { const onChange = jest.fn(); const multiValueInput = shallow( - <MultiValueInput setting={{ definition }} value={['foo', 'bar', 'baz']} onChange={onChange}/>); + <MultiValueInput setting={{ definition }} value={['foo', 'bar', 'baz']} onChange={onChange} /> + ); click(multiValueInput.find('.js-remove-value').at(1)); expect(onChange).toBeCalledWith(['foo', 'baz']); }); @@ -58,14 +62,17 @@ it('should remove value', () => { it('should change existing value', () => { const onChange = jest.fn(); const multiValueInput = shallow( - <MultiValueInput setting={{ definition }} value={['foo', 'bar', 'baz']} onChange={onChange}/>); + <MultiValueInput setting={{ definition }} value={['foo', 'bar', 'baz']} onChange={onChange} /> + ); multiValueInput.find(PrimitiveInput).at(1).prop('onChange')('qux'); expect(onChange).toBeCalledWith(['foo', 'qux', 'baz']); }); it('should add new value', () => { const onChange = jest.fn(); - const multiValueInput = shallow(<MultiValueInput setting={{ definition }} value={['foo']} onChange={onChange}/>); + const multiValueInput = shallow( + <MultiValueInput setting={{ definition }} value={['foo']} onChange={onChange} /> + ); multiValueInput.find(PrimitiveInput).at(1).prop('onChange')('bar'); expect(onChange).toBeCalledWith(['foo', 'bar']); }); diff --git a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.js b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.js index 38b0f22f73d..7bac3d8c806 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.js +++ b/server/sonar-web/src/main/js/apps/settings/components/inputs/__tests__/SimpleInput-test.js @@ -26,12 +26,13 @@ it('should render input', () => { const onChange = jest.fn(); const input = shallow( <SimpleInput - type="text" - className="input-large" - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + type="text" + className="input-large" + name="foo" + value="bar" + isDefault={false} + onChange={onChange} + /> ).find('input'); expect(input.length).toBe(1); expect(input.prop('type')).toBe('text'); @@ -45,12 +46,13 @@ it('should call onChange', () => { const onChange = jest.fn(); const input = shallow( <SimpleInput - type="text" - className="input-large" - name="foo" - value="bar" - isDefault={false} - onChange={onChange}/> + type="text" + className="input-large" + name="foo" + value="bar" + isDefault={false} + onChange={onChange} + /> ).find('input'); expect(input.length).toBe(1); expect(input.prop('onChange')).toBeTruthy(); diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionApp.js b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionApp.js index 6d9f7589c37..02a8c45b79f 100644 --- a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionApp.js +++ b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionApp.js @@ -35,31 +35,32 @@ export default class EncryptionApp extends React.Component { startGeneration: React.PropTypes.func.isRequired }; - componentDidMount () { + componentDidMount() { this.props.checkSecretKey(); } - render () { + render() { return ( - <div id="encryption-page" className="page page-limited"> - <header className="page-header"> - <h1 className="page-title">{translate('property.category.security.encryption')}</h1> - {this.props.loading && <i className="spinner"/>} - </header> + <div id="encryption-page" className="page page-limited"> + <header className="page-header"> + <h1 className="page-title">{translate('property.category.security.encryption')}</h1> + {this.props.loading && <i className="spinner" />} + </header> - {!this.props.loading && !this.props.secretKeyAvailable && ( - <GenerateSecretKeyForm - secretKey={this.props.secretKey} - generateSecretKey={this.props.generateSecretKey}/> - )} + {!this.props.loading && + !this.props.secretKeyAvailable && + <GenerateSecretKeyForm + secretKey={this.props.secretKey} + generateSecretKey={this.props.generateSecretKey} + />} - {this.props.secretKeyAvailable && ( - <EncryptionForm - encryptedValue={this.props.encryptedValue} - encryptValue={this.props.encryptValue} - generateSecretKey={this.props.startGeneration}/> - )} - </div> + {this.props.secretKeyAvailable && + <EncryptionForm + encryptedValue={this.props.encryptedValue} + encryptValue={this.props.encryptValue} + generateSecretKey={this.props.startGeneration} + />} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionAppContainer.js b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionAppContainer.js index 24efcbfe2c8..2a1a90aab1d 100644 --- a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionAppContainer.js +++ b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionAppContainer.js @@ -19,10 +19,17 @@ */ import { connect } from 'react-redux'; import EncryptionApp from './EncryptionApp'; -import { checkSecretKey, generateSecretKey, encryptValue, startGeneration } from '../store/encryptionPage/actions'; +import { + checkSecretKey, + generateSecretKey, + encryptValue, + startGeneration +} from '../store/encryptionPage/actions'; import { getSettingsAppEncryptionState } from '../../../store/rootReducer'; -export default connect( - state => getSettingsAppEncryptionState(state), - { checkSecretKey, generateSecretKey, encryptValue, startGeneration } -)(EncryptionApp); +export default connect(state => getSettingsAppEncryptionState(state), { + checkSecretKey, + generateSecretKey, + encryptValue, + startGeneration +})(EncryptionApp); diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.js b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.js index abf232aa88b..c49fdf8dabd 100644 --- a/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.js +++ b/server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.js @@ -28,59 +28,66 @@ export default class EncryptionForm extends React.Component { state = { value: '' }; - handleEncrypt (e) { + handleEncrypt(e) { e.preventDefault(); this.props.encryptValue(this.state.value); } - handleGenerateNewKey (e) { + handleGenerateNewKey(e) { e.preventDefault(); this.props.generateSecretKey(); } - render () { + render() { return ( - <div id="encryption-form-container"> - <div className="spacer-bottom"> - Secret key is registered. You can encrypt any property value with the following form: - </div> - - <form id="encryption-form" className="big-spacer-bottom" onSubmit={e => this.handleEncrypt(e)}> - <input - id="encryption-form-value" - className="input-large" - type="text" - autoFocus={true} - required={true} - value={this.state.value} - onChange={e => this.setState({ value: e.target.value })}/> - <button className="spacer-left">Encrypt</button> - </form> + <div id="encryption-form-container"> + <div className="spacer-bottom"> + Secret key is registered. You can encrypt any property value with the following form: + </div> - {this.props.encryptedValue != null && ( - <div> - Encrypted Value:{' '} - <input - id="encrypted-value" - className="input-clear input-code input-super-large" - type="text" - readOnly={true} - value={this.props.encryptedValue}/> - </div> - )} + <form + id="encryption-form" + className="big-spacer-bottom" + onSubmit={e => this.handleEncrypt(e)} + > + <input + id="encryption-form-value" + className="input-large" + type="text" + autoFocus={true} + required={true} + value={this.state.value} + onChange={e => this.setState({ value: e.target.value })} + /> + <button className="spacer-left">Encrypt</button> + </form> - <div className="huge-spacer-top bordered-top"> - <div className="big-spacer-top spacer-bottom"> - Note that the secret key can be changed, but all the encrypted properties will have to be updated. - {' '} - <a href="https://redirect.sonarsource.com/doc/settings-encryption.html">More information</a> - </div> + {this.props.encryptedValue != null && + <div> + Encrypted Value:{' '} + <input + id="encrypted-value" + className="input-clear input-code input-super-large" + type="text" + readOnly={true} + value={this.props.encryptedValue} + /> + </div>} - <form id="encryption-new-key-form" onSubmit={e => this.handleGenerateNewKey(e)}> - <button>Generate New Secret Key</button> - </form> + <div className="huge-spacer-top bordered-top"> + <div className="big-spacer-top spacer-bottom"> + Note that the secret key can be changed, but all the encrypted properties will have to be updated. + {' '} + <a href="https://redirect.sonarsource.com/doc/settings-encryption.html"> + More information + </a> </div> + + <form id="encryption-new-key-form" onSubmit={e => this.handleGenerateNewKey(e)}> + <button>Generate New Secret Key</button> + </form> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.js b/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.js index c63c6d51747..e76355e6da7 100644 --- a/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.js +++ b/server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.js @@ -25,65 +25,74 @@ export default class GenerateSecretKeyForm extends React.Component { generateSecretKey: React.PropTypes.func.isRequired }; - handleSubmit (e) { + handleSubmit(e) { e.preventDefault(); this.props.generateSecretKey(); } - render () { + render() { return ( - <div id="generate-secret-key-form-container"> - {this.props.secretKey != null ? ( - <div> - <div className="big-spacer-bottom"> - <h3 className="spacer-bottom">Secret Key</h3> - <input - id="secret-key" - className="input-large" - type="text" - readOnly={true} - value={this.props.secretKey}/> - </div> + <div id="generate-secret-key-form-container"> + {this.props.secretKey != null + ? <div> + <div className="big-spacer-bottom"> + <h3 className="spacer-bottom">Secret Key</h3> + <input + id="secret-key" + className="input-large" + type="text" + readOnly={true} + value={this.props.secretKey} + /> + </div> - <h3 className="spacer-bottom">How To Use</h3> + <h3 className="spacer-bottom">How To Use</h3> - <ul className="list-styled markdown"> - <li className="spacer-bottom"> - Store the secret key in the file <code>~/.sonar/sonar-secret.txt</code> of the server. This file can - be relocated by defining the property <code>sonar.secretKeyPath</code>{' '} - in <code>conf/sonar.properties</code> - </li> - <li className="spacer-bottom"> - Restrict access to this file by making it readable and by owner only - </li> - <li className="spacer-bottom"> - Restart the server if the property <code>sonar.secretKeyPath</code> has been set or changed. - </li> - <li className="spacer-bottom"> - Copy this file on all the machines that execute code inspection. Define the property - {' '}<code>sonar.secretKeyPath</code> on those machines if the path is not - {' '}<code>~/.sonar/sonar-secret.txt</code>. - </li> - <li> - For each property that you want to encrypt, generate the encrypted value and replace the original - value wherever it is stored (configuration files, command lines). - </li> - </ul> - </div> - ) : ( - <div> - <p className="spacer-bottom"> - Secret key is required to be able to encrypt properties. + <ul className="list-styled markdown"> + <li className="spacer-bottom"> + Store the secret key in the file + {' '} + <code>~/.sonar/sonar-secret.txt</code> {' '} - <a href="https://redirect.sonarsource.com/doc/settings-encryption.html">More information</a> - </p> + of the server. This file can + be relocated by defining the property <code>sonar.secretKeyPath</code>{' '} + in <code>conf/sonar.properties</code> + </li> + <li className="spacer-bottom"> + Restrict access to this file by making it readable and by owner only + </li> + <li className="spacer-bottom"> + Restart the server if the property + {' '} + <code>sonar.secretKeyPath</code> + {' '} + has been set or changed. + </li> + <li className="spacer-bottom"> + Copy this file on all the machines that execute code inspection. Define the property + {' '}<code>sonar.secretKeyPath</code> on those machines if the path is not + {' '}<code>~/.sonar/sonar-secret.txt</code>. + </li> + <li> + For each property that you want to encrypt, generate the encrypted value and replace the original + value wherever it is stored (configuration files, command lines). + </li> + </ul> + </div> + : <div> + <p className="spacer-bottom"> + Secret key is required to be able to encrypt properties. + {' '} + <a href="https://redirect.sonarsource.com/doc/settings-encryption.html"> + More information + </a> + </p> - <form id="generate-secret-key-form" onSubmit={e => this.handleSubmit(e)}> - <button>Generate Secret Key</button> - </form> - </div> - )} - </div> + <form id="generate-secret-key-form" onSubmit={e => this.handleSubmit(e)}> + <button>Generate Secret Key</button> + </form> + </div>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseChangeForm.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseChangeForm.js index b35354eefd4..246ead0856d 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseChangeForm.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseChangeForm.js @@ -27,7 +27,7 @@ export default class LicenseChangeForm extends React.Component { onChange: React.PropTypes.func.isRequired }; - onClick (e) { + onClick(e) { e.preventDefault(); e.target.blur(); @@ -40,9 +40,11 @@ export default class LicenseChangeForm extends React.Component { }).render(); } - render () { + render() { return ( - <button className="js-change" onClick={e => this.onClick(e)}>{translate('update_verb')}</button> + <button className="js-change" onClick={e => this.onClick(e)}> + {translate('update_verb')} + </button> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRow.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRow.js index a8d2822bbe3..52271392ed6 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRow.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRow.js @@ -29,43 +29,44 @@ export default class LicenseRow extends React.Component { setLicense: React.PropTypes.func.isRequired }; - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - handleSet (value) { - return this.props.setLicense(this.props.license.key, value).catch(() => { /* do nothing */ }); + handleSet(value) { + return this.props.setLicense(this.props.license.key, value).catch(() => { + /* do nothing */ + }); } - render () { + render() { const { license } = this.props; return ( - <tr className="js-license" data-license-key={license.key}> - <td className="text-middle"><LicenseStatus license={license}/></td> - <td className="js-product text-middle"> - <div className={license.invalidProduct ? 'text-danger' : null}> - {license.name || license.key} - </div> - </td> - <td className="js-organization text-middle">{license.organization}</td> - <td className="js-expiration text-middle"> - {license.expiration != null && ( - <div className={license.invalidExpiration ? 'text-danger' : null}> - {moment(license.expiration).format('LL')} - </div> - )} - </td> - <td className="js-type text-middle">{license.type}</td> - <td className="js-server-id text-middle"> - <div className={license.invalidServerId ? 'text-danger' : null}> - {license.serverId} - </div> - </td> - <td className="text-right"> - <LicenseChangeForm license={license} onChange={value => this.handleSet(value)}/> - </td> - </tr> + <tr className="js-license" data-license-key={license.key}> + <td className="text-middle"><LicenseStatus license={license} /></td> + <td className="js-product text-middle"> + <div className={license.invalidProduct ? 'text-danger' : null}> + {license.name || license.key} + </div> + </td> + <td className="js-organization text-middle">{license.organization}</td> + <td className="js-expiration text-middle"> + {license.expiration != null && + <div className={license.invalidExpiration ? 'text-danger' : null}> + {moment(license.expiration).format('LL')} + </div>} + </td> + <td className="js-type text-middle">{license.type}</td> + <td className="js-server-id text-middle"> + <div className={license.invalidServerId ? 'text-danger' : null}> + {license.serverId} + </div> + </td> + <td className="text-right"> + <LicenseChangeForm license={license} onChange={value => this.handleSet(value)} /> + </td> + </tr> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRowContainer.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRowContainer.js index 807848b84c4..49cbe5ea807 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRowContainer.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseRowContainer.js @@ -26,7 +26,4 @@ const mapStateToProps = (state, ownProps) => ({ license: getSettingsAppLicenseByKey(state, ownProps.licenseKey) }); -export default connect( - mapStateToProps, - { setLicense } -)(LicenseRow); +export default connect(mapStateToProps, { setLicense })(LicenseRow); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseStatus.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseStatus.js index 16f3074e3c9..eaea09253f7 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseStatus.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseStatus.js @@ -25,7 +25,7 @@ export default class LicenseStatus extends React.Component { license: React.PropTypes.object.isRequired }; - render () { + render() { const { license } = this.props; if (license.value == null) { @@ -34,9 +34,9 @@ export default class LicenseStatus extends React.Component { const isInvalid = isLicenseInvalid(license); if (isInvalid) { - return <i className="icon-alert-error"/>; + return <i className="icon-alert-error" />; } - return <i className="icon-check"/>; + return <i className="icon-check" />; } } diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseValueView.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseValueView.js index 92517a85b1e..22b4e3a155b 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicenseValueView.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicenseValueView.js @@ -23,7 +23,7 @@ import Template from './LicenseValueView.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.disableForm(); this.showSpinner(); @@ -32,7 +32,7 @@ export default ModalForm.extend({ this.options.onChange(value).then(() => this.destroy()); }, - serializeData () { + serializeData() { return { productName: this.options.productName, value: this.options.value diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesApp.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesApp.js index e6afcf96961..924e219a6c0 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesApp.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesApp.js @@ -22,12 +22,12 @@ import LicensesAppHeader from './LicensesAppHeader'; import LicensesListContainer from './LicensesListContainer'; export default class LicensesApp extends React.Component { - render () { + render() { return ( - <div id="licenses-page" className="page page-limited"> - <LicensesAppHeader/> - <LicensesListContainer/> - </div> + <div id="licenses-page" className="page page-limited"> + <LicensesAppHeader /> + <LicensesListContainer /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesAppHeader.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesAppHeader.js index 4cc2c4e7bd0..6f7f8733a2f 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesAppHeader.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesAppHeader.js @@ -21,13 +21,15 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; export default class LicensesAppHeader extends React.Component { - render () { + render() { return ( - <header className="page-header"> - <h1 className="page-title">{translate('property.category.licenses')}</h1> - <div className="page-description" - dangerouslySetInnerHTML={{ __html: translate('property.category.licenses.description') }}/> - </header> + <header className="page-header"> + <h1 className="page-title">{translate('property.category.licenses')}</h1> + <div + className="page-description" + dangerouslySetInnerHTML={{ __html: translate('property.category.licenses.description') }} + /> + </header> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesList.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesList.js index c892453be87..9b7df9c18e7 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesList.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesList.js @@ -28,34 +28,36 @@ export default class LicensesList extends React.Component { fetchLicenses: React.PropTypes.func.isRequired }; - componentDidMount () { - this.props.fetchLicenses().catch(() => { /* do nothing */ }); + componentDidMount() { + this.props.fetchLicenses().catch(() => { + /* do nothing */ + }); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - render () { + render() { return ( - <table className="data zebra zebra-hover" style={{ tableLayout: 'fixed' }}> - <thead> - <tr> - <th width={40}> </th> - <th>{translate('licenses.list.product')}</th> - <th width={150}>{translate('licenses.list.organization')}</th> - <th width={150}>{translate('licenses.list.expiration')}</th> - <th width={150}>{translate('licenses.list.type')}</th> - <th width={150}>{translate('licenses.list.server')}</th> - <th width={80}> </th> - </tr> - </thead> - <tbody> - {this.props.licenses.map(licenseKey => ( - <LicenseRowContainer key={licenseKey} licenseKey={licenseKey}/> - ))} - </tbody> - </table> + <table className="data zebra zebra-hover" style={{ tableLayout: 'fixed' }}> + <thead> + <tr> + <th width={40}> </th> + <th>{translate('licenses.list.product')}</th> + <th width={150}>{translate('licenses.list.organization')}</th> + <th width={150}>{translate('licenses.list.expiration')}</th> + <th width={150}>{translate('licenses.list.type')}</th> + <th width={150}>{translate('licenses.list.server')}</th> + <th width={80}> </th> + </tr> + </thead> + <tbody> + {this.props.licenses.map(licenseKey => ( + <LicenseRowContainer key={licenseKey} licenseKey={licenseKey} /> + ))} + </tbody> + </table> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesListContainer.js b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesListContainer.js index dd5745986b4..664e3d73193 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/LicensesListContainer.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/LicensesListContainer.js @@ -26,7 +26,4 @@ const mapStateToProps = state => ({ licenses: getSettingsAppAllLicenseKeys(state) }); -export default connect( - mapStateToProps, - { fetchLicenses } -)(LicensesList); +export default connect(mapStateToProps, { fetchLicenses })(LicensesList); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseChangeForm-test.js b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseChangeForm-test.js index fc6874f080e..899a111d9df 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseChangeForm-test.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseChangeForm-test.js @@ -22,6 +22,6 @@ import { shallow } from 'enzyme'; import LicenseChangeForm from '../LicenseChangeForm'; it('should render button', () => { - const form = shallow(<LicenseChangeForm license={{}} onChange={jest.fn()}/>); + const form = shallow(<LicenseChangeForm license={{}} onChange={jest.fn()} />); expect(form.is('button')).toBe(true); }); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseRow-test.js b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseRow-test.js index b52db5f8f9e..4d7c758d416 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseRow-test.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseRow-test.js @@ -25,75 +25,97 @@ import LicenseChangeForm from '../LicenseChangeForm'; it('should render status', () => { const license = {}; - const licenseStatus = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find(LicenseStatus); + const licenseStatus = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + LicenseStatus + ); expect(licenseStatus.length).toBe(1); expect(licenseStatus.prop('license')).toBe(license); }); it('should render product', () => { const license = { name: 'foo' }; - const licenseProduct = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-product'); + const licenseProduct = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-product' + ); expect(licenseProduct.length).toBe(1); expect(licenseProduct.text()).toContain('foo'); }); it('should render invalid product', () => { const license = { product: 'foo', invalidProduct: true }; - const licenseProduct = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-product'); + const licenseProduct = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-product' + ); expect(licenseProduct.find('.text-danger').length).toBe(1); }); it('should render key when no name', () => { const license = { key: 'foo.secured' }; - const licenseProduct = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-product'); + const licenseProduct = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-product' + ); expect(licenseProduct.length).toBe(1); expect(licenseProduct.text()).toContain('foo.secured'); }); it('should render organization', () => { const license = { organization: 'org' }; - const licenseOrg = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-organization'); + const licenseOrg = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-organization' + ); expect(licenseOrg.length).toBe(1); expect(licenseOrg.text()).toContain('org'); }); it('should render expiration', () => { const license = { expiration: '2015-01-01' }; - const licenseExpiration = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-expiration'); + const licenseExpiration = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-expiration' + ); expect(licenseExpiration.length).toBe(1); expect(licenseExpiration.text()).toContain('2015'); }); it('should render invalid expiration', () => { const license = { expiration: '2015-01-01', invalidExpiration: true }; - const licenseExpiration = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-expiration'); + const licenseExpiration = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-expiration' + ); expect(licenseExpiration.find('.text-danger').length).toBe(1); }); it('should render type', () => { const license = { type: 'PRODUCTION' }; - const licenseType = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-type'); + const licenseType = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-type' + ); expect(licenseType.length).toBe(1); expect(licenseType.text()).toContain('PRODUCTION'); }); it('should render server id', () => { const license = { serverId: 'bar' }; - const licenseServerId = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-server-id'); + const licenseServerId = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-server-id' + ); expect(licenseServerId.length).toBe(1); expect(licenseServerId.text()).toContain('bar'); }); it('should render invalid server id', () => { const license = { serverId: 'bar', invalidServerId: true }; - const licenseServerId = shallow(<LicenseRow license={license} setLicense={jest.fn()}/>).find('.js-server-id'); + const licenseServerId = shallow(<LicenseRow license={license} setLicense={jest.fn()} />).find( + '.js-server-id' + ); expect(licenseServerId.find('.text-danger').length).toBe(1); }); it('should render change form', () => { const license = { key: 'foo' }; const setLicense = jest.fn(() => Promise.resolve()); - const licenseChangeForm = shallow(<LicenseRow license={license} setLicense={setLicense}/>).find(LicenseChangeForm); + const licenseChangeForm = shallow(<LicenseRow license={license} setLicense={setLicense} />).find( + LicenseChangeForm + ); expect(licenseChangeForm.length).toBe(1); expect(licenseChangeForm.prop('license')).toBe(license); expect(typeof licenseChangeForm.prop('onChange')).toBe('function'); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseStatus-test.js b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseStatus-test.js index 70ac94f3488..b87f2cd2624 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseStatus-test.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicenseStatus-test.js @@ -22,29 +22,29 @@ import { shallow } from 'enzyme'; import LicenseStatus from '../LicenseStatus'; it('should render nothing when no value', () => { - const status = shallow(<LicenseStatus license={{}}/>); + const status = shallow(<LicenseStatus license={{}} />); expect(status.node).toBeNull(); }); it('should render ok', () => { - const status = shallow(<LicenseStatus license={{ value: 'foo' }}/>); + const status = shallow(<LicenseStatus license={{ value: 'foo' }} />); expect(status.is('.icon-check')).toBe(true); }); it('should render error when invalid product', () => { - const status = shallow(<LicenseStatus license={{ value: 'foo', invalidProduct: true }}/>); + const status = shallow(<LicenseStatus license={{ value: 'foo', invalidProduct: true }} />); expect(status.is('.icon-check')).toBe(false); expect(status.is('.icon-alert-error')).toBe(true); }); it('should render error when invalid expiration', () => { - const status = shallow(<LicenseStatus license={{ value: 'foo', invalidExpiration: true }}/>); + const status = shallow(<LicenseStatus license={{ value: 'foo', invalidExpiration: true }} />); expect(status.is('.icon-check')).toBe(false); expect(status.is('.icon-alert-error')).toBe(true); }); it('should render error when invalid server id', () => { - const status = shallow(<LicenseStatus license={{ value: 'foo', invalidServerId: true }}/>); + const status = shallow(<LicenseStatus license={{ value: 'foo', invalidServerId: true }} />); expect(status.is('.icon-check')).toBe(false); expect(status.is('.icon-alert-error')).toBe(true); }); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesApp-test.js b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesApp-test.js index acc165ea654..fe19ff981f8 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesApp-test.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesApp-test.js @@ -24,7 +24,7 @@ import LicensesAppHeader from '../LicensesAppHeader'; import LicensesListContainer from '../LicensesListContainer'; it('should render', () => { - const app = shallow(<LicensesApp/>); + const app = shallow(<LicensesApp />); expect(app.find(LicensesAppHeader).length).toBe(1); expect(app.find(LicensesListContainer).length).toBe(1); }); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesAppHeader-test.js b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesAppHeader-test.js index 0df30b22c80..b5b3fa59a90 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesAppHeader-test.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesAppHeader-test.js @@ -22,7 +22,7 @@ import { shallow } from 'enzyme'; import LicensesAppHeader from '../LicensesAppHeader'; it('should render', () => { - const header = shallow(<LicensesAppHeader/>); + const header = shallow(<LicensesAppHeader />); expect(header.find('.page-title').length).toBe(1); expect(header.find('.page-description').length).toBe(1); }); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesList-test.js b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesList-test.js index df56f7b4e3d..a1335084928 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesList-test.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/__tests__/LicensesList-test.js @@ -23,18 +23,18 @@ import LicensesList from '../LicensesList'; import LicenseRowContainer from '../LicenseRowContainer'; it('should render', () => { - const list = shallow(<LicensesList licenses={[]} fetchLicenses={jest.fn()}/>); + const list = shallow(<LicensesList licenses={[]} fetchLicenses={jest.fn()} />); expect(list.is('table')).toBe(true); }); it('should fetch licenses', () => { const fetchLicenses = jest.fn(() => Promise.resolve()); - mount(<LicensesList licenses={[]} fetchLicenses={fetchLicenses}/>); + mount(<LicensesList licenses={[]} fetchLicenses={fetchLicenses} />); expect(fetchLicenses).toBeCalled(); }); it('should render rows', () => { - const list = shallow(<LicensesList licenses={['foo', 'bar']} fetchLicenses={jest.fn()}/>); + const list = shallow(<LicensesList licenses={['foo', 'bar']} fetchLicenses={jest.fn()} />); expect(list.find(LicenseRowContainer).length).toBe(2); expect(list.find(LicenseRowContainer).at(0).prop('licenseKey')).toBe('foo'); expect(list.find(LicenseRowContainer).at(1).prop('licenseKey')).toBe('bar'); diff --git a/server/sonar-web/src/main/js/apps/settings/licenses/licenseUtils.js b/server/sonar-web/src/main/js/apps/settings/licenses/licenseUtils.js index f2f3458e356..7be9c5090d4 100644 --- a/server/sonar-web/src/main/js/apps/settings/licenses/licenseUtils.js +++ b/server/sonar-web/src/main/js/apps/settings/licenses/licenseUtils.js @@ -17,9 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export const isLicenseInvalid = license => ( - !!license.invalidProduct || !!license.invalidExpiration || !!license.invalidServerId -); +export const isLicenseInvalid = license => + !!license.invalidProduct || !!license.invalidExpiration || !!license.invalidServerId; export const isLicenseFromListInvalid = (licenses, key) => { const license = licenses.find(license => license.key === key); diff --git a/server/sonar-web/src/main/js/apps/settings/routes.js b/server/sonar-web/src/main/js/apps/settings/routes.js index f72dba28ba0..d7c693a3365 100644 --- a/server/sonar-web/src/main/js/apps/settings/routes.js +++ b/server/sonar-web/src/main/js/apps/settings/routes.js @@ -25,9 +25,9 @@ import EncryptionAppContainer from './encryption/EncryptionAppContainer'; import ServerIdAppContainer from './serverId/ServerIdAppContainer'; export default [ - <Redirect key="1" from="/settings/index" to="/settings"/>, - <IndexRoute key="2" component={AppContainer}/>, - <Route key="3" path="licenses" component={LicensesApp}/>, - <Route key="4" path="encryption" component={EncryptionAppContainer}/>, - <Route key="5" path="server_id" component={ServerIdAppContainer}/> + <Redirect key="1" from="/settings/index" to="/settings" />, + <IndexRoute key="2" component={AppContainer} />, + <Route key="3" path="licenses" component={LicensesApp} />, + <Route key="4" path="encryption" component={EncryptionAppContainer} />, + <Route key="5" path="server_id" component={ServerIdAppContainer} /> ]; diff --git a/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdApp.js b/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdApp.js index cb63ffa7011..9a21a86f293 100644 --- a/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdApp.js +++ b/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdApp.js @@ -35,113 +35,120 @@ export default class ServerIdApp extends React.Component { validIpAddresses: [] }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.fetchServerId(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - handleError (error) { + handleError(error) { this.setState({ loading: false }); parseError(error).then(message => this.props.addGlobalErrorMessage(message)); } - fetchServerId () { + fetchServerId() { this.setState({ loading: true }); - getServerId().then(data => { - if (this.mounted) { - this.setState({ ...data, loading: false }); - } - }).catch(error => this.handleError(error)); + getServerId() + .then(data => { + if (this.mounted) { + this.setState({ ...data, loading: false }); + } + }) + .catch(error => this.handleError(error)); } - handleSubmit (e) { + handleSubmit(e) { e.preventDefault(); this.setState({ loading: true }); this.props.closeAllGlobalMessages(); - generateServerId(this.state.organization, this.state.ip).then(data => { - if (this.mounted) { - this.setState({ serverId: data.serverId, invalidServerId: false, loading: false }); - } - }).catch(error => this.handleError(error)); + generateServerId(this.state.organization, this.state.ip) + .then(data => { + if (this.mounted) { + this.setState({ serverId: data.serverId, invalidServerId: false, loading: false }); + } + }) + .catch(error => this.handleError(error)); } - render () { + render() { return ( - <div id="server-id-page" className="page page-limited"> - <header className="page-header"> - <h1 className="page-title">{translate('property.category.server_id')}</h1> - {this.state.loading && <i className="spinner"/>} - <div className="page-description">{translate('server_id_configuration.information')}</div> - </header> + <div id="server-id-page" className="page page-limited"> + <header className="page-header"> + <h1 className="page-title">{translate('property.category.server_id')}</h1> + {this.state.loading && <i className="spinner" />} + <div className="page-description">{translate('server_id_configuration.information')}</div> + </header> - {this.state.serverId != null && ( - <div className={this.state.invalidServerId ? 'panel panel-danger' : 'panel'}> - Server ID: - <input - id="server-id-result" - className="spacer-left input-large input-clear input-code" - type="text" - readOnly={true} - value={this.state.serverId}/> - {!!this.state.invalidServerId && ( - <span className="spacer-left">{translate('server_id_configuration.bad_key')}</span> - )} - </div> - )} + {this.state.serverId != null && + <div className={this.state.invalidServerId ? 'panel panel-danger' : 'panel'}> + Server ID: + <input + id="server-id-result" + className="spacer-left input-large input-clear input-code" + type="text" + readOnly={true} + value={this.state.serverId} + /> + {!!this.state.invalidServerId && + <span className="spacer-left">{translate('server_id_configuration.bad_key')}</span>} + </div>} - <div className="panel"> - <form id="server-id-form" onSubmit={e => this.handleSubmit(e)}> - <div className="modal-field"> - <label htmlFor="server-id-organization"> - {translate('server_id_configuration.organisation.title')} - <em className="mandatory">*</em> - </label> - <input - id="server-id-organization" - type="text" - required={true} - value={this.state.organization} - disabled={this.state.loading} - onChange={e => this.setState({ organization: e.target.value })}/> - <div className="modal-field-description"> - {translate('server_id_configuration.organisation.desc')} - {'. '} - {translate('server_id_configuration.organisation.pattern')} - </div> + <div className="panel"> + <form id="server-id-form" onSubmit={e => this.handleSubmit(e)}> + <div className="modal-field"> + <label htmlFor="server-id-organization"> + {translate('server_id_configuration.organisation.title')} + <em className="mandatory">*</em> + </label> + <input + id="server-id-organization" + type="text" + required={true} + value={this.state.organization} + disabled={this.state.loading} + onChange={e => this.setState({ organization: e.target.value })} + /> + <div className="modal-field-description"> + {translate('server_id_configuration.organisation.desc')} + {'. '} + {translate('server_id_configuration.organisation.pattern')} </div> + </div> - <div className="modal-field"> - <label htmlFor="server-id-ip"> - {translate('server_id_configuration.ip.title')} - <em className="mandatory">*</em> - </label> - <input - id="server-id-ip" - type="text" - required={true} - value={this.state.ip} - disabled={this.state.loading} - onChange={e => this.setState({ ip: e.target.value })}/> - <div className="modal-field-description"> - {translate('server_id_configuration.ip.desc')} - <ul className="list-styled"> - {this.state.validIpAddresses.map(ip => ( - <li key={ip} className="little-spacer-top">{ip}</li> - ))} - </ul> - </div> + <div className="modal-field"> + <label htmlFor="server-id-ip"> + {translate('server_id_configuration.ip.title')} + <em className="mandatory">*</em> + </label> + <input + id="server-id-ip" + type="text" + required={true} + value={this.state.ip} + disabled={this.state.loading} + onChange={e => this.setState({ ip: e.target.value })} + /> + <div className="modal-field-description"> + {translate('server_id_configuration.ip.desc')} + <ul className="list-styled"> + {this.state.validIpAddresses.map(ip => ( + <li key={ip} className="little-spacer-top">{ip}</li> + ))} + </ul> </div> + </div> - <div className="modal-field"> - <button disabled={this.state.loading}>{translate('server_id_configuration.generate_button')}</button> - </div> - </form> - </div> + <div className="modal-field"> + <button disabled={this.state.loading}> + {translate('server_id_configuration.generate_button')} + </button> + </div> + </form> </div> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdAppContainer.js b/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdAppContainer.js index 7a05c325f7c..d6b0824735a 100644 --- a/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdAppContainer.js +++ b/server/sonar-web/src/main/js/apps/settings/serverId/ServerIdAppContainer.js @@ -21,7 +21,4 @@ import { connect } from 'react-redux'; import ServerIdApp from './ServerIdApp'; import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../store/globalMessages/duck'; -export default connect( - () => ({}), - { addGlobalErrorMessage, closeAllGlobalMessages } -)(ServerIdApp); +export default connect(() => ({}), { addGlobalErrorMessage, closeAllGlobalMessages })(ServerIdApp); diff --git a/server/sonar-web/src/main/js/apps/settings/store/actions.js b/server/sonar-web/src/main/js/apps/settings/store/actions.js index 95e49dba581..212ddc47f7d 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/actions.js +++ b/server/sonar-web/src/main/js/apps/settings/store/actions.js @@ -17,7 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { getDefinitions, getValues, setSettingValue, resetSettingValue } from '../../../api/settings'; +import { + getDefinitions, + getValues, + setSettingValue, + resetSettingValue +} from '../../../api/settings'; import { receiveValues } from './values/actions'; import { receiveDefinitions } from './definitions/actions'; import { startLoading, stopLoading } from './settingsPage/loading/actions'; @@ -29,8 +34,9 @@ import { isEmptyValue } from '../utils'; import { translate } from '../../../helpers/l10n'; import { getSettingsAppDefinition, getSettingsAppChangedValue } from '../../../store/rootReducer'; -export const fetchSettings = componentKey => dispatch => { - return getDefinitions(componentKey) +export const fetchSettings = componentKey => + dispatch => { + return getDefinitions(componentKey) .then(definitions => { const withoutLicenses = definitions.filter(definition => definition.type !== 'LICENSE'); dispatch(receiveDefinitions(withoutLicenses)); @@ -42,22 +48,23 @@ export const fetchSettings = componentKey => dispatch => { dispatch(closeAllGlobalMessages()); }) .catch(e => parseError(e).then(message => dispatch(addGlobalErrorMessage(message)))); -}; + }; -export const saveValue = (key, componentKey) => (dispatch, getState) => { - dispatch(startLoading(key)); +export const saveValue = (key, componentKey) => + (dispatch, getState) => { + dispatch(startLoading(key)); - const state = getState(); - const definition = getSettingsAppDefinition(state, key); - const value = getSettingsAppChangedValue(state, key); + const state = getState(); + const definition = getSettingsAppDefinition(state, key); + const value = getSettingsAppChangedValue(state, key); - if (isEmptyValue(definition, value)) { - dispatch(failValidation(key, translate('settings.state.value_cant_be_empty'))); - dispatch(stopLoading(key)); - return Promise.reject(); - } + if (isEmptyValue(definition, value)) { + dispatch(failValidation(key, translate('settings.state.value_cant_be_empty'))); + dispatch(stopLoading(key)); + return Promise.reject(); + } - return setSettingValue(definition, value, componentKey) + return setSettingValue(definition, value, componentKey) .then(() => getValues(key, componentKey)) .then(values => { dispatch(receiveValues(values)); @@ -70,12 +77,13 @@ export const saveValue = (key, componentKey) => (dispatch, getState) => { parseError(e).then(message => dispatch(failValidation(key, message))); return Promise.reject(); }); -}; + }; -export const resetValue = (key, componentKey) => dispatch => { - dispatch(startLoading(key)); +export const resetValue = (key, componentKey) => + dispatch => { + dispatch(startLoading(key)); - return resetSettingValue(key, componentKey) + return resetSettingValue(key, componentKey) .then(() => getValues(key, componentKey)) .then(values => { if (values.length > 0) { @@ -91,4 +99,4 @@ export const resetValue = (key, componentKey) => dispatch => { parseError(e).then(message => dispatch(failValidation(key, message))); return Promise.reject(); }); -}; + }; diff --git a/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js b/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js index 62feda90947..4e96d1018de 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/definitions/reducer.js @@ -39,25 +39,27 @@ const reducer = (state: State = {}, action: Action) => { export default reducer; -export const getDefinition = (state: State, key: string): Definition => - state[key]; +export const getDefinition = (state: State, key: string): Definition => state[key]; export const getAllDefinitions = (state: State): Definition[] => - Object.keys(state).map(key => state[key]); + Object.keys(state).map(key => state[key]); export const getDefinitionsForCategory = (state: State, category: string) => - getAllDefinitions(state).filter(definition => definition.category.toLowerCase() === category.toLowerCase()); + getAllDefinitions(state).filter( + definition => definition.category.toLowerCase() === category.toLowerCase() + ); -export const getAllCategories = (state: State) => uniqBy( - getAllDefinitions(state).map(definition => definition.category), - category => category.toLowerCase()); +export const getAllCategories = (state: State) => + uniqBy(getAllDefinitions(state).map(definition => definition.category), category => + category.toLowerCase()); export const getDefaultCategory = (state: State) => { const categories = getAllCategories(state); if (categories.includes(DEFAULT_CATEGORY)) { return DEFAULT_CATEGORY; } else { - const sortedCategories = sortBy(categories, category => getCategoryName(category).toLowerCase()); + const sortedCategories = sortBy(categories, category => + getCategoryName(category).toLowerCase()); return sortedCategories[0]; } }; diff --git a/server/sonar-web/src/main/js/apps/settings/store/encryptionPage/actions.js b/server/sonar-web/src/main/js/apps/settings/store/encryptionPage/actions.js index 42d39768ce2..eac17044bec 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/encryptionPage/actions.js +++ b/server/sonar-web/src/main/js/apps/settings/store/encryptionPage/actions.js @@ -19,7 +19,10 @@ */ import * as api from '../../../../api/settings'; import { parseError } from '../../../code/utils'; -import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../../store/globalMessages/duck'; +import { + addGlobalErrorMessage, + closeAllGlobalMessages +} from '../../../../store/globalMessages/duck'; export const UPDATE_ENCRYPTION = 'UPDATE_ENCRYPTION'; @@ -33,38 +36,49 @@ const startLoading = dispatch => { dispatch(closeAllGlobalMessages()); }; -const handleError = dispatch => error => { - parseError(error).then(message => { - dispatch(addGlobalErrorMessage(message)); - dispatch(updateEncryption({ loading: false })); - }); -}; +const handleError = dispatch => + error => { + parseError(error).then(message => { + dispatch(addGlobalErrorMessage(message)); + dispatch(updateEncryption({ loading: false })); + }); + }; -export const checkSecretKey = () => dispatch => { - startLoading(dispatch); - api.checkSecretKey() +export const checkSecretKey = () => + dispatch => { + startLoading(dispatch); + api + .checkSecretKey() .then(data => dispatch(updateEncryption({ ...data, loading: false }))) .catch(handleError(dispatch)); -}; + }; -export const generateSecretKey = () => dispatch => { - startLoading(dispatch); - api.generateSecretKey() - .then(data => dispatch(updateEncryption({ - ...data, - secretKeyAvailable: false, - loading: false - }))) +export const generateSecretKey = () => + dispatch => { + startLoading(dispatch); + api + .generateSecretKey() + .then(data => + dispatch( + updateEncryption({ + ...data, + secretKeyAvailable: false, + loading: false + }) + )) .catch(handleError(dispatch)); -}; + }; -export const encryptValue = value => dispatch => { - startLoading(dispatch); - api.encryptValue(value) +export const encryptValue = value => + dispatch => { + startLoading(dispatch); + api + .encryptValue(value) .then(data => dispatch(updateEncryption({ ...data, loading: false }))) .catch(handleError(dispatch)); -}; + }; -export const startGeneration = () => dispatch => { - dispatch(updateEncryption({ secretKeyAvailable: false, secretKey: undefined })); -}; +export const startGeneration = () => + dispatch => { + dispatch(updateEncryption({ secretKeyAvailable: false, secretKey: undefined })); + }; diff --git a/server/sonar-web/src/main/js/apps/settings/store/licenses/actions.js b/server/sonar-web/src/main/js/apps/settings/store/licenses/actions.js index a63ef8d4103..baa19b1323d 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/licenses/actions.js +++ b/server/sonar-web/src/main/js/apps/settings/store/licenses/actions.js @@ -19,7 +19,10 @@ */ import * as licenses from '../../../../api/licenses'; import { parseError } from '../../../code/utils'; -import { addGlobalSuccessMessage, addGlobalErrorMessage } from '../../../../store/globalMessages/duck'; +import { + addGlobalSuccessMessage, + addGlobalErrorMessage +} from '../../../../store/globalMessages/duck'; import { translate } from '../../../../helpers/l10n'; import { isLicenseFromListInvalid, isLicenseInvalid } from '../../licenses/licenseUtils'; @@ -30,13 +33,16 @@ const receiveLicenses = licenses => ({ licenses }); -const handleError = dispatch => error => { - parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); - return Promise.reject(); -}; +const handleError = dispatch => + error => { + parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); + return Promise.reject(); + }; -export const fetchLicenses = () => dispatch => { - return licenses.getLicenses() +export const fetchLicenses = () => + dispatch => { + return licenses + .getLicenses() .then(licenses => { dispatch(receiveLicenses(licenses)); /* eslint import/namespace: 0 */ @@ -46,12 +52,13 @@ export const fetchLicenses = () => dispatch => { } }) .catch(handleError(dispatch)); -}; + }; -export const setLicense = (key, value) => dispatch => { - const request = value ? licenses.setLicense(key, value) : licenses.resetLicense(key); +export const setLicense = (key, value) => + dispatch => { + const request = value ? licenses.setLicense(key, value) : licenses.resetLicense(key); - return request + return request .then(() => { licenses.getLicenses().then(licenses => { dispatch(receiveLicenses(licenses)); @@ -63,4 +70,4 @@ export const setLicense = (key, value) => dispatch => { }); }) .catch(handleError(dispatch)); -}; + }; diff --git a/server/sonar-web/src/main/js/apps/settings/store/rootReducer.js b/server/sonar-web/src/main/js/apps/settings/store/rootReducer.js index c6d5c1acde8..c11af77b997 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/rootReducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/rootReducer.js @@ -48,40 +48,37 @@ const rootReducer = combineReducers({ export default rootReducer; export const getDefinition = (state: State, key: string) => - fromDefinitions.getDefinition(state.definitions, key); + fromDefinitions.getDefinition(state.definitions, key); export const getAllCategories = (state: State) => - fromDefinitions.getAllCategories(state.definitions); + fromDefinitions.getAllCategories(state.definitions); export const getDefaultCategory = (state: State) => - fromDefinitions.getDefaultCategory(state.definitions); + fromDefinitions.getDefaultCategory(state.definitions); -export const getValue = (state: State, key: string) => - fromValues.getValue(state.values, key); +export const getValue = (state: State, key: string) => fromValues.getValue(state.values, key); export const getSettingsForCategory = (state: State, category: string) => - fromDefinitions.getDefinitionsForCategory(state.definitions, category).map(definition => ({ - ...getValue(state, definition.key), - definition - })); + fromDefinitions.getDefinitionsForCategory(state.definitions, category).map(definition => ({ + ...getValue(state, definition.key), + definition + })); export const getChangedValue = (state: State, key: string) => - fromSettingsPage.getChangedValue(state.settingsPage, key); + fromSettingsPage.getChangedValue(state.settingsPage, key); export const isLoading = (state: State, key: string) => - fromSettingsPage.isLoading(state.settingsPage, key); + fromSettingsPage.isLoading(state.settingsPage, key); export const getLicenseByKey = (state: State, key: string) => - fromLicenses.getLicenseByKey(state.licenses, key); + fromLicenses.getLicenseByKey(state.licenses, key); -export const getAllLicenseKeys = (state: State) => - fromLicenses.getAllLicenseKeys(state.licenses); +export const getAllLicenseKeys = (state: State) => fromLicenses.getAllLicenseKeys(state.licenses); export const getValidationMessage = (state: State, key: string) => - fromSettingsPage.getValidationMessage(state.settingsPage, key); + fromSettingsPage.getValidationMessage(state.settingsPage, key); -export const getEncryptionState = (state: State) => - state.encryptionPage; +export const getEncryptionState = (state: State) => state.encryptionPage; export const getGlobalMessages = (state: State) => - fromGlobalMessages.getGlobalMessages(state.globalMessages); + fromGlobalMessages.getGlobalMessages(state.globalMessages); diff --git a/server/sonar-web/src/main/js/apps/settings/store/settingsPage/reducer.js b/server/sonar-web/src/main/js/apps/settings/store/settingsPage/reducer.js index a53bec442bd..f2bdf8c39b1 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/settingsPage/reducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/settingsPage/reducer.js @@ -29,10 +29,9 @@ export default combineReducers({ }); export const getChangedValue = (state, key) => - fromChangedValues.getChangedValue(state.changedValues, key); + fromChangedValues.getChangedValue(state.changedValues, key); export const getValidationMessage = (state, key) => - fromValidationMessages.getValidationMessage(state.validationMessages, key); + fromValidationMessages.getValidationMessage(state.validationMessages, key); -export const isLoading = (state, key) => - fromLoading.isLoading(state.loading, key); +export const isLoading = (state, key) => fromLoading.isLoading(state.loading, key); diff --git a/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js b/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js index bcad10fedac..1e75fe48727 100644 --- a/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js +++ b/server/sonar-web/src/main/js/apps/settings/store/values/reducer.js @@ -31,9 +31,9 @@ const reducer = (state: State = {}, action: Object) => { if (action.type === 'SET_APP_STATE') { const settingsByKey = {}; - Object.keys(action.appState.settings).forEach(key => ( - settingsByKey[key] = { value: action.appState.settings[key] } - )); + Object.keys(action.appState.settings).forEach( + key => settingsByKey[key] = { value: action.appState.settings[key] } + ); return { ...state, ...settingsByKey }; } diff --git a/server/sonar-web/src/main/js/apps/settings/utils.js b/server/sonar-web/src/main/js/apps/settings/utils.js index b795af491dd..56ae346e1f4 100644 --- a/server/sonar-web/src/main/js/apps/settings/utils.js +++ b/server/sonar-web/src/main/js/apps/settings/utils.js @@ -18,41 +18,46 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { translate, hasMessage } from '../../helpers/l10n'; -import { TYPE_PROPERTY_SET, TYPE_BOOLEAN, TYPE_SINGLE_SELECT_LIST, TYPE_PASSWORD } from './constants'; +import { + TYPE_PROPERTY_SET, + TYPE_BOOLEAN, + TYPE_SINGLE_SELECT_LIST, + TYPE_PASSWORD +} from './constants'; export const DEFAULT_CATEGORY = 'general'; -export function getPropertyName (definition) { +export function getPropertyName(definition) { const key = `property.${definition.key}.name`; return hasMessage(key) ? translate(key) : definition.name; } -export function getPropertyDescription (definition) { +export function getPropertyDescription(definition) { const key = `property.${definition.key}.description`; return hasMessage(key) ? translate(key) : definition.description; } -export function getCategoryName (category) { +export function getCategoryName(category) { const key = `property.category.${category}`; return hasMessage(key) ? translate(key) : category; } -export function getSubCategoryName (category, subCategory) { +export function getSubCategoryName(category, subCategory) { const key = `property.category.${category}.${subCategory}`; return hasMessage(key) ? translate(key) : getCategoryName(subCategory); } -export function getSubCategoryDescription (category, subCategory) { +export function getSubCategoryDescription(category, subCategory) { const key = `property.category.${category}.${subCategory}.description`; return hasMessage(key) ? translate(key) : null; } -export function getUniqueName (definition, index = null) { +export function getUniqueName(definition, index = null) { const indexSuffix = index != null ? `[${index}]` : ''; return `settings[${definition.key}]${indexSuffix}`; } -export function getSettingValue (setting) { +export function getSettingValue(setting) { if (setting.definition.multiValues) { return setting.values; } else if (setting.definition.type === TYPE_PROPERTY_SET) { @@ -62,7 +67,7 @@ export function getSettingValue (setting) { } } -export function isEmptyValue (definition, value) { +export function isEmptyValue(definition, value) { if (value == null) { return true; } else if (definition.type === TYPE_BOOLEAN) { @@ -72,7 +77,7 @@ export function isEmptyValue (definition, value) { } } -export function getEmptyValue (definition) { +export function getEmptyValue(definition) { if (definition.multiValues) { return [getEmptyValue({ ...definition, multiValues: false })]; } @@ -90,11 +95,11 @@ export function getEmptyValue (definition) { return ''; } -export function isDefaultOrInherited (setting) { +export function isDefaultOrInherited(setting) { return !!setting.default || !!setting.inherited; } -function getParentValue (setting) { +function getParentValue(setting) { if (setting.definition.multiValues) { return setting.parentValues; } else if (setting.definition.type === TYPE_PROPERTY_SET) { @@ -109,7 +114,7 @@ function getParentValue (setting) { * @param setting * @returns {string} */ -export function getDefaultValue (setting) { +export function getDefaultValue(setting) { const parentValue = getParentValue(setting); if (parentValue == null) { @@ -117,15 +122,13 @@ export function getDefaultValue (setting) { } if (setting.definition.multiValues) { - return parentValue.length > 0 ? - parentValue.join(', ') : - translate('settings.default.no_value'); + return parentValue.length > 0 ? parentValue.join(', ') : translate('settings.default.no_value'); } if (setting.definition.type === TYPE_PROPERTY_SET) { - return parentValue.length > 0 ? - translate('settings.default.complex_value') : - translate('settings.default.no_value'); + return parentValue.length > 0 + ? translate('settings.default.complex_value') + : translate('settings.default.no_value'); } if (setting.definition.type === TYPE_PASSWORD) { diff --git a/server/sonar-web/src/main/js/apps/system/__tests__/system-test.js b/server/sonar-web/src/main/js/apps/system/__tests__/system-test.js index c3750cb42bf..20caf0f7311 100644 --- a/server/sonar-web/src/main/js/apps/system/__tests__/system-test.js +++ b/server/sonar-web/src/main/js/apps/system/__tests__/system-test.js @@ -26,39 +26,41 @@ import ItemLogLevel from '../item-log-level'; describe('Item Value', () => { it('should render string', () => { - const result = shallow(<ItemValue value="/some/path/as/an/example"/>); + const result = shallow(<ItemValue value="/some/path/as/an/example" />); expect(result.find('code').text()).toBe('/some/path/as/an/example'); }); }); describe('ItemBoolean', () => { it('should render `true`', () => { - const result = shallow(<ItemBoolean value={true}/>); + const result = shallow(<ItemBoolean value={true} />); expect(result.find('.icon-check').length).toBe(1); }); it('should render `false`', () => { - const result = shallow(<ItemBoolean value={false}/>); + const result = shallow(<ItemBoolean value={false} />); expect(result.find('.icon-delete').length).toBe(1); }); }); describe('ItemObject', () => { it('should render object', () => { - const result = shallow(<ItemObject value={{ name: 'Java', version: '3.2' }}/>); + const result = shallow(<ItemObject value={{ name: 'Java', version: '3.2' }} />); expect(result.find('table').length).toBe(1); expect(result.find('tr').length).toBe(2); }); it('should render `true` inside object', () => { - const result = shallow(<ItemObject value={{ isCool: true }}/>); + const result = shallow(<ItemObject value={{ isCool: true }} />); const itemValue = result.find(ItemValue); expect(itemValue.length).toBe(1); expect(itemValue.prop('value')).toBe(true); }); it('should render object inside object', () => { - const result = shallow(<ItemObject value={{ users: { docs: 1, shards: 5 }, tests: { docs: 68, shards: 5 } }}/>); + const result = shallow( + <ItemObject value={{ users: { docs: 1, shards: 5 }, tests: { docs: 68, shards: 5 } }} /> + ); expect(result.find(ItemValue).length).toBe(2); expect(result.find(ItemValue).at(0).prop('value')).toEqual({ docs: 1, shards: 5 }); expect(result.find(ItemValue).at(1).prop('value')).toEqual({ docs: 68, shards: 5 }); @@ -67,23 +69,23 @@ describe('ItemObject', () => { describe('Log Level', () => { it('should render select box', () => { - const result = shallow(<ItemLogLevel value="INFO"/>); + const result = shallow(<ItemLogLevel value="INFO" />); expect(result.find('select').length).toBe(1); expect(result.find('option').length).toBe(3); }); it('should set initial value', () => { - const result = shallow(<ItemLogLevel value="DEBUG"/>); + const result = shallow(<ItemLogLevel value="DEBUG" />); expect(result.find('select').prop('value')).toBe('DEBUG'); }); it('should render warning', () => { - const result = shallow(<ItemLogLevel value="DEBUG"/>); + const result = shallow(<ItemLogLevel value="DEBUG" />); expect(result.find('.alert').length).toBe(1); }); it('should not render warning', () => { - const result = shallow(<ItemLogLevel value="INFO"/>); + const result = shallow(<ItemLogLevel value="INFO" />); expect(result.find('.alert').length).toBe(0); }); }); diff --git a/server/sonar-web/src/main/js/apps/system/item-boolean.js b/server/sonar-web/src/main/js/apps/system/item-boolean.js index b056ce3ca8a..aff28b869a1 100644 --- a/server/sonar-web/src/main/js/apps/system/item-boolean.js +++ b/server/sonar-web/src/main/js/apps/system/item-boolean.js @@ -20,11 +20,11 @@ import React from 'react'; export default React.createClass({ - render () { + render() { if (this.props.value) { - return <i className="icon-check"/>; + return <i className="icon-check" />; } else { - return <i className="icon-delete"/>; + return <i className="icon-delete" />; } } }); diff --git a/server/sonar-web/src/main/js/apps/system/item-log-level.js b/server/sonar-web/src/main/js/apps/system/item-log-level.js index eecfbd856dc..a992307fec0 100644 --- a/server/sonar-web/src/main/js/apps/system/item-log-level.js +++ b/server/sonar-web/src/main/js/apps/system/item-log-level.js @@ -24,34 +24,29 @@ import { translate } from '../../helpers/l10n'; const LOG_LEVELS = ['INFO', 'DEBUG', 'TRACE']; export default React.createClass({ - getInitialState () { + getInitialState() { return { level: this.props.value }; }, - onChange () { + onChange() { const newValue = this.refs.select.value; setLogLevel(newValue).then(() => { this.setState({ level: newValue }); }); }, - render () { - const options = LOG_LEVELS.map(level => ( - <option key={level} value={level}>{level}</option> - )); - const warning = this.state.level !== 'INFO' ? ( - <div className="alert alert-danger spacer-top" style={{ wordBreak: 'normal' }}> - {translate('system.log_level.warning')} - </div> - ) : null; - return ( - <div> - <select - ref="select" - onChange={this.onChange} - value={this.state.level}>{options}</select> - {warning} + render() { + const options = LOG_LEVELS.map(level => <option key={level} value={level}>{level}</option>); + const warning = this.state.level !== 'INFO' + ? <div className="alert alert-danger spacer-top" style={{ wordBreak: 'normal' }}> + {translate('system.log_level.warning')} </div> + : null; + return ( + <div> + <select ref="select" onChange={this.onChange} value={this.state.level}>{options}</select> + {warning} + </div> ); } }); diff --git a/server/sonar-web/src/main/js/apps/system/item-object.js b/server/sonar-web/src/main/js/apps/system/item-object.js index a8247472839..c0f0b1919fb 100644 --- a/server/sonar-web/src/main/js/apps/system/item-object.js +++ b/server/sonar-web/src/main/js/apps/system/item-object.js @@ -21,19 +21,19 @@ import React from 'react'; import ItemValue from './item-value'; export default React.createClass({ - render () { + render() { const rows = Object.keys(this.props.value).map(key => { return ( - <tr key={key}> - <td className="thin nowrap">{key}</td> - <td><ItemValue value={this.props.value[key]}/></td> - </tr> + <tr key={key}> + <td className="thin nowrap">{key}</td> + <td><ItemValue value={this.props.value[key]} /></td> + </tr> ); }); return ( - <table className="data"> - <tbody>{rows}</tbody> - </table> + <table className="data"> + <tbody>{rows}</tbody> + </table> ); } }); diff --git a/server/sonar-web/src/main/js/apps/system/item-value.js b/server/sonar-web/src/main/js/apps/system/item-value.js index 45cfb2c7084..ac413fe061c 100644 --- a/server/sonar-web/src/main/js/apps/system/item-value.js +++ b/server/sonar-web/src/main/js/apps/system/item-value.js @@ -23,19 +23,19 @@ import ItemObject from './item-object'; import ItemLogLevel from './item-log-level'; export default React.createClass({ - render () { + render() { if (this.props.name === 'Logs Level') { - return <ItemLogLevel value={this.props.value}/>; + return <ItemLogLevel value={this.props.value} />; } const rawValue = this.props.value; let formattedValue; switch (typeof this.props.value) { case 'boolean': - formattedValue = <ItemBoolean value={rawValue}/>; + formattedValue = <ItemBoolean value={rawValue} />; break; case 'object': - formattedValue = <ItemObject value={rawValue}/>; + formattedValue = <ItemObject value={rawValue} />; break; default: formattedValue = <code>{rawValue}</code>; diff --git a/server/sonar-web/src/main/js/apps/system/main.js b/server/sonar-web/src/main/js/apps/system/main.js index 2aefeee5003..26d5bf24e0e 100644 --- a/server/sonar-web/src/main/js/apps/system/main.js +++ b/server/sonar-web/src/main/js/apps/system/main.js @@ -24,91 +24,101 @@ import Section from './section'; import { translate } from '../../helpers/l10n'; import RestartModal from '../../components/RestartModal'; -const SECTIONS_ORDER = ['SonarQube', 'Database', 'System', 'Elasticsearch State', 'Elasticsearch', - 'Compute Engine Tasks', 'Compute Engine State', 'Compute Engine Database Connection', 'JvmProperties']; +const SECTIONS_ORDER = [ + 'SonarQube', + 'Database', + 'System', + 'Elasticsearch State', + 'Elasticsearch', + 'Compute Engine Tasks', + 'Compute Engine State', + 'Compute Engine Database Connection', + 'JvmProperties' +]; export default React.createClass({ - componentDidMount () { + componentDidMount() { getSystemInfo().then(info => this.setState({ sections: this.parseSections(info) })); }, - parseSections (data) { + parseSections(data) { const sections = Object.keys(data).map(section => { return { name: section, items: this.parseItems(data[section]) }; }); return this.orderSections(sections); }, - orderSections (sections) { + orderSections(sections) { return sortBy(sections, section => SECTIONS_ORDER.indexOf(section.name)); }, - parseItems (data) { + parseItems(data) { const items = Object.keys(data).map(item => { return { name: item, value: data[item] }; }); return this.orderItems(items); }, - orderItems (items) { + orderItems(items) { return sortBy(items, 'name'); }, - handleServerRestart () { + handleServerRestart() { new RestartModal().render(); }, - render () { + render() { let sections = null; if (this.state && this.state.sections) { sections = this.state.sections - .filter(section => SECTIONS_ORDER.indexOf(section.name) >= 0) - .map(section => ( - <Section key={section.name} section={section.name} items={section.items}/> - )); + .filter(section => SECTIONS_ORDER.indexOf(section.name) >= 0) + .map(section => ( + <Section key={section.name} section={section.name} items={section.items} /> + )); } return ( - <div className="page"> - <header className="page-header"> - <h1 className="page-title">{translate('system_info.page')}</h1> - <div className="page-actions"> - <a href={window.baseUrl + '/api/system/info'} id="download-link">Download</a> - <div className="display-inline-block dropdown big-spacer-left"> - <button data-toggle="dropdown">Logs <i className="icon-dropdown"/></button> - <ul className="dropdown-menu"> - <li> - <a href={window.baseUrl + '/api/system/logs?process=app'} id="logs-link"> - Main Process - </a> - </li> - <li> - <a href={window.baseUrl + '/api/system/logs?process=ce'} id="ce-logs-link"> - Compute Engine - </a> - </li> - <li> - <a href={window.baseUrl + '/api/system/logs?process=es'} id="es-logs-link"> - Elasticsearch - </a> - </li> - <li> - <a href={window.baseUrl + '/api/system/logs?process=web'} id="web-logs-link"> - Web Server - </a> - </li> - </ul> - </div> - <button - id="restart-server-button" - className="big-spacer-left" - onClick={this.handleServerRestart}> - Restart Server - </button> + <div className="page"> + <header className="page-header"> + <h1 className="page-title">{translate('system_info.page')}</h1> + <div className="page-actions"> + <a href={window.baseUrl + '/api/system/info'} id="download-link">Download</a> + <div className="display-inline-block dropdown big-spacer-left"> + <button data-toggle="dropdown">Logs <i className="icon-dropdown" /></button> + <ul className="dropdown-menu"> + <li> + <a href={window.baseUrl + '/api/system/logs?process=app'} id="logs-link"> + Main Process + </a> + </li> + <li> + <a href={window.baseUrl + '/api/system/logs?process=ce'} id="ce-logs-link"> + Compute Engine + </a> + </li> + <li> + <a href={window.baseUrl + '/api/system/logs?process=es'} id="es-logs-link"> + Elasticsearch + </a> + </li> + <li> + <a href={window.baseUrl + '/api/system/logs?process=web'} id="web-logs-link"> + Web Server + </a> + </li> + </ul> </div> - </header> - {sections} - </div> + <button + id="restart-server-button" + className="big-spacer-left" + onClick={this.handleServerRestart} + > + Restart Server + </button> + </div> + </header> + {sections} + </div> ); } }); diff --git a/server/sonar-web/src/main/js/apps/system/routes.js b/server/sonar-web/src/main/js/apps/system/routes.js index d416f5d5d70..d75c6810ef7 100644 --- a/server/sonar-web/src/main/js/apps/system/routes.js +++ b/server/sonar-web/src/main/js/apps/system/routes.js @@ -22,6 +22,6 @@ import { IndexRoute, Redirect } from 'react-router'; import Main from './main'; export default [ - <Redirect key="redirect" from="/system/index" to="/system"/>, - <IndexRoute key="index" component={Main}/> + <Redirect key="redirect" from="/system/index" to="/system" />, + <IndexRoute key="index" component={Main} /> ]; diff --git a/server/sonar-web/src/main/js/apps/system/section.js b/server/sonar-web/src/main/js/apps/system/section.js index 666e0829af0..1d890c02506 100644 --- a/server/sonar-web/src/main/js/apps/system/section.js +++ b/server/sonar-web/src/main/js/apps/system/section.js @@ -21,25 +21,29 @@ import React from 'react'; import ItemValue from './item-value'; export default React.createClass({ - render () { + render() { const items = this.props.items.map(item => { return ( - <tr key={item.name}> - <td className="thin"> - <div style={{ width: '25vw', overflow: 'hidden', textOverflow: 'ellipsis' }}>{item.name}</div> - </td> - <td style={{ wordBreak: 'break-all' }}><ItemValue name={item.name} value={item.value}/></td> - </tr> + <tr key={item.name}> + <td className="thin"> + <div style={{ width: '25vw', overflow: 'hidden', textOverflow: 'ellipsis' }}> + {item.name} + </div> + </td> + <td style={{ wordBreak: 'break-all' }}> + <ItemValue name={item.name} value={item.value} /> + </td> + </tr> ); }); return ( - <div className="big-spacer-bottom"> - <h3 className="spacer-bottom">{this.props.section}</h3> - <table className="data zebra" id={this.props.section}> - <tbody>{items}</tbody> - </table> - </div> + <div className="big-spacer-bottom"> + <h3 className="spacer-bottom">{this.props.section}</h3> + <table className="data zebra" id={this.props.section}> + <tbody>{items}</tbody> + </table> + </div> ); } }); diff --git a/server/sonar-web/src/main/js/apps/update-center/components/UpdateCenterAppContainer.js b/server/sonar-web/src/main/js/apps/update-center/components/UpdateCenterAppContainer.js index 979c07c32c0..469c5fc7347 100644 --- a/server/sonar-web/src/main/js/apps/update-center/components/UpdateCenterAppContainer.js +++ b/server/sonar-web/src/main/js/apps/update-center/components/UpdateCenterAppContainer.js @@ -23,23 +23,23 @@ import init from '../init'; import { getSettingValue } from '../../../store/rootReducer'; class UpdateCenterAppContainer extends React.Component { - componentDidMount () { + componentDidMount() { this.stop = init(this.refs.container, this.props.updateCenterActive); } - componentWillUnmount () { + componentWillUnmount() { this.stop(); } - render () { + render() { // placing container inside div is required, // because when backbone.marionette's layout is destroyed, // it also destroys the root element, // but react wants it to be there to unmount it return ( - <div> - <div ref="container"/> - </div> + <div> + <div ref="container" /> + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/update-center/controller.js b/server/sonar-web/src/main/js/apps/update-center/controller.js index 0b171f093a7..79a2d133b76 100644 --- a/server/sonar-web/src/main/js/apps/update-center/controller.js +++ b/server/sonar-web/src/main/js/apps/update-center/controller.js @@ -20,29 +20,28 @@ import Marionette from 'backbone.marionette'; export default Marionette.Controller.extend({ - initialize (options) { + initialize(options) { this.collection = options.collection; this.state = options.state; }, - showInstalled () { + showInstalled() { this.state.set({ section: 'installed' }); this.collection.fetchInstalled(); }, - showUpdates () { + showUpdates() { this.state.set({ section: 'updates' }); this.collection.fetchUpdates(); }, - showAvailable () { + showAvailable() { this.state.set({ section: 'available' }); this.collection.fetchAvailable(); }, - showSystemUpgrades () { + showSystemUpgrades() { this.state.set({ section: 'system' }); this.collection.fetchSystemUpgrades(); } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/footer-view.js b/server/sonar-web/src/main/js/apps/update-center/footer-view.js index 5b79881adbb..aa4a117cc06 100644 --- a/server/sonar-web/src/main/js/apps/update-center/footer-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/footer-view.js @@ -24,14 +24,13 @@ export default Marionette.ItemView.extend({ template: Template, collectionEvents: { - 'all': 'render' + all: 'render' }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), total: this.collection.where({ _hidden: false }).length }; } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/header-view.js b/server/sonar-web/src/main/js/apps/update-center/header-view.js index 2757cdc5c38..cc0ac80a8c1 100644 --- a/server/sonar-web/src/main/js/apps/update-center/header-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/header-view.js @@ -33,15 +33,15 @@ export default Marionette.ItemView.extend({ 'click .js-cancel-all': 'cancelAll' }, - restart () { + restart() { new RestartModal().render(); }, - cancelAll () { + cancelAll() { this.collection.cancelAll(); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), installing: this.collection._installedCount, @@ -50,4 +50,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/init.js b/server/sonar-web/src/main/js/apps/update-center/init.js index 2120074ab7f..ad613a757c8 100644 --- a/server/sonar-web/src/main/js/apps/update-center/init.js +++ b/server/sonar-web/src/main/js/apps/update-center/init.js @@ -30,7 +30,7 @@ import Plugins from './plugins'; const App = new Marionette.Application(); -const init = function ({ el, updateCenterActive }) { +const init = function({ el, updateCenterActive }) { // State this.state = new Backbone.Model({ updateCenterActive }); @@ -52,7 +52,11 @@ const init = function ({ el, updateCenterActive }) { this.layout.headerRegion.show(this.headerView); // Search - this.searchView = new SearchView({ collection: this.plugins, router: this.router, state: this.state }); + this.searchView = new SearchView({ + collection: this.plugins, + router: this.router, + state: this.state + }); this.layout.searchRegion.show(this.searchView); this.searchView.focusSearch(); @@ -73,7 +77,7 @@ const init = function ({ el, updateCenterActive }) { App.on('start', options => init.call(App, options)); -export default function (el, updateCenterActive) { +export default function(el, updateCenterActive) { App.start({ el, updateCenterActive }); return () => { diff --git a/server/sonar-web/src/main/js/apps/update-center/layout.js b/server/sonar-web/src/main/js/apps/update-center/layout.js index 02d1c8b7e7e..329ce8499c6 100644 --- a/server/sonar-web/src/main/js/apps/update-center/layout.js +++ b/server/sonar-web/src/main/js/apps/update-center/layout.js @@ -30,4 +30,3 @@ export default Marionette.LayoutView.extend({ footerRegion: '#update-center-footer' } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/list-item-view.js b/server/sonar-web/src/main/js/apps/update-center/list-item-view.js index b4a51a88579..2d466e3100c 100644 --- a/server/sonar-web/src/main/js/apps/update-center/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/list-item-view.js @@ -45,11 +45,11 @@ export default Marionette.ItemView.extend({ 'click .js-plugin-category': 'onCategoryClick' }, - getTemplate () { + getTemplate() { return this.model.get('_system') ? this.systemTemplate : this.template; }, - onRender () { + onRender() { this.$el.attr('data-id', this.model.id); if (this.model.get('_system')) { this.$el.attr('data-system', ''); @@ -57,17 +57,17 @@ export default Marionette.ItemView.extend({ this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onModelChange () { + onModelChange() { if (!this.model.hasChanged('_hidden')) { this.render(); } }, - onChangelogClick (e) { + onChangelogClick(e) { e.preventDefault(); e.stopPropagation(); $('body').click(); @@ -75,7 +75,9 @@ export default Marionette.ItemView.extend({ // if show changelog of update, show details of this update // otherwise show changelog of the available release - const update = this.model.has('release') ? this.model.toJSON() : this.model.get('updates')[index]; + const update = this.model.has('release') + ? this.model.toJSON() + : this.model.get('updates')[index]; const popup = new PluginChangelogView({ triggerEl: $(e.currentTarget), model: new Backbone.Model(update) @@ -83,35 +85,34 @@ export default Marionette.ItemView.extend({ popup.render(); }, - onRequest () { + onRequest() { this.$('.js-actions').addClass('hidden'); this.$('.js-spinner').removeClass('hidden'); }, - toggleDisplay () { + toggleDisplay() { this.$el.toggleClass('hidden', this.model.get('_hidden')); }, - install () { + install() { this.model.install(); }, - update () { + update() { this.model.update(); }, - uninstall () { + uninstall() { this.model.uninstall(); }, - onTermsChange () { + onTermsChange() { const isAccepted = this.$('.js-terms').is(':checked'); this.$('.js-install').prop('disabled', !isAccepted); }, - onCategoryClick (e) { + onCategoryClick(e) { e.preventDefault(); this.model.trigger('filter', this.model); } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/list-view.js b/server/sonar-web/src/main/js/apps/update-center/list-view.js index a016f0ff131..3746db3f037 100644 --- a/server/sonar-web/src/main/js/apps/update-center/list-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/list-view.js @@ -24,4 +24,3 @@ export default Marionette.CollectionView.extend({ tagName: 'ul', childView: ListItemView }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js b/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js index 98b52c342b1..e28db827b42 100644 --- a/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/plugin-changelog-view.js @@ -23,18 +23,18 @@ import Template from './templates/update-center-plugin-changelog.hbs'; export default Popup.extend({ template: Template, - onRender () { + onRender() { Popup.prototype.onRender.apply(this, arguments); this.$('.bubble-popup-container').isolatedScroll(); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { Popup.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - serializeData () { + serializeData() { return { ...Popup.prototype.serializeData.apply(this, arguments), // if there is no status, this is a new plugin @@ -43,4 +43,3 @@ export default Popup.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/plugin.js b/server/sonar-web/src/main/js/apps/update-center/plugin.js index cebb6bf216b..c4b6fac39dd 100644 --- a/server/sonar-web/src/main/js/apps/update-center/plugin.js +++ b/server/sonar-web/src/main/js/apps/update-center/plugin.js @@ -27,27 +27,27 @@ export default Backbone.Model.extend({ _system: false }, - _matchAttribute (attr, query) { + _matchAttribute(attr, query) { const value = this.get(attr) || ''; return value.toLowerCase().includes(query.toLowerCase()); }, - match (query) { + match(query) { return this._matchAttribute('name', query) || - this._matchAttribute('category', query) || - this._matchAttribute('description', query); + this._matchAttribute('category', query) || + this._matchAttribute('description', query); }, - _action (options) { + _action(options) { const that = this; const opts = { ...options, type: 'POST', data: { key: this.id }, - success () { + success() { options.success(that); }, - error (jqXHR) { + error(jqXHR) { that.set({ _status: 'failed', _errors: jqXHR.responseJSON.errors }); } }; @@ -56,31 +56,30 @@ export default Backbone.Model.extend({ return xhr; }, - install () { + install() { return this._action({ url: window.baseUrl + '/api/plugins/install', - success (model) { + success(model) { model.set({ _status: 'installing' }); } }); }, - update () { + update() { return this._action({ url: window.baseUrl + '/api/plugins/update', - success (model) { + success(model) { model.set({ _status: 'updating' }); } }); }, - uninstall () { + uninstall() { return this._action({ url: window.baseUrl + '/api/plugins/uninstall', - success (model) { + success(model) { model.set({ _status: 'uninstalling' }); } }); } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/plugins.js b/server/sonar-web/src/main/js/apps/update-center/plugins.js index e38b2fb4648..2a23578bb81 100644 --- a/server/sonar-web/src/main/js/apps/update-center/plugins.js +++ b/server/sonar-web/src/main/js/apps/update-center/plugins.js @@ -25,18 +25,18 @@ import Plugin from './plugin'; const Plugins = Backbone.Collection.extend({ model: Plugin, - comparator (model) { + comparator(model) { return model.get('name') || ''; }, - initialize () { + initialize() { this._installedCount = 0; this._updatedCount = 0; this._uninstalledCount = 0; this.listenTo(this, 'change:_status', this.onStatusChange); }, - parse (r) { + parse(r) { const that = this; return r.plugins.map(plugin => { let updates = [ @@ -49,18 +49,18 @@ const Plugins = Backbone.Collection.extend({ }); }, - _getLastWithStatus (updates, status) { + _getLastWithStatus(updates, status) { const index = findLastIndex(updates, update => update.status === status); return index !== -1 ? updates[index] : null; }, - _extendChangelog (updates, update) { + _extendChangelog(updates, update) { const index = updates.indexOf(update); const previousUpdates = index > 0 ? updates.slice(0, index) : []; return { ...update, previousUpdates }; }, - _fetchInstalled () { + _fetchInstalled() { if (this._installed) { return $.Deferred().resolve().promise(); } @@ -68,14 +68,14 @@ const Plugins = Backbone.Collection.extend({ const opts = { type: 'GET', url: window.baseUrl + '/api/plugins/installed', - success (r) { + success(r) { that._installed = that.parse(r); } }; return Backbone.ajax(opts); }, - _fetchUpdates () { + _fetchUpdates() { if (this._updates) { return $.Deferred().resolve().promise(); } @@ -83,14 +83,14 @@ const Plugins = Backbone.Collection.extend({ const opts = { type: 'GET', url: window.baseUrl + '/api/plugins/updates', - success (r) { + success(r) { that._updates = that.parse(r); } }; return Backbone.ajax(opts); }, - _fetchAvailable () { + _fetchAvailable() { if (this._available) { return $.Deferred().resolve().promise(); } @@ -98,19 +98,19 @@ const Plugins = Backbone.Collection.extend({ const opts = { type: 'GET', url: window.baseUrl + '/api/plugins/available', - success (r) { + success(r) { that._available = that.parse(r); } }; return Backbone.ajax(opts); }, - _fetchPending () { + _fetchPending() { const that = this; const opts = { type: 'GET', url: window.baseUrl + '/api/plugins/pending', - success (r) { + success(r) { const installing = r.installing.map(plugin => { return { key: plugin.key, _status: 'installing' }; }); @@ -129,7 +129,7 @@ const Plugins = Backbone.Collection.extend({ return Backbone.ajax(opts); }, - _fetchSystemUpgrades () { + _fetchSystemUpgrades() { if (this._systemUpdates) { return $.Deferred().resolve().promise(); } @@ -137,14 +137,14 @@ const Plugins = Backbone.Collection.extend({ const opts = { type: 'GET', url: window.baseUrl + '/api/system/upgrades', - success (r) { + success(r) { that._systemUpdates = r.upgrades.map(update => ({ ...update, _system: true })); } }; return Backbone.ajax(opts); }, - fetchInstalled () { + fetchInstalled() { const that = this; return $.when(this._fetchInstalled(), this._fetchUpdates(), this._fetchPending()).done(() => { const plugins = new Plugins(); @@ -155,19 +155,18 @@ const Plugins = Backbone.Collection.extend({ }); }, - fetchUpdates () { + fetchUpdates() { const that = this; - return $.when(this._fetchInstalled(), this._fetchUpdates(), this._fetchPending()) - .done(() => { - const plugins = new Plugins(); - plugins.set(that._installed); - plugins.set(that._updates, { remove: true }); - plugins.set(that._pending, { add: false, remove: false }); - that.reset(plugins.models); - }); + return $.when(this._fetchInstalled(), this._fetchUpdates(), this._fetchPending()).done(() => { + const plugins = new Plugins(); + plugins.set(that._installed); + plugins.set(that._updates, { remove: true }); + plugins.set(that._pending, { add: false, remove: false }); + that.reset(plugins.models); + }); }, - fetchAvailable () { + fetchAvailable() { const that = this; return $.when(this._fetchAvailable(), this._fetchPending()).done(() => { const plugins = new Plugins(); @@ -177,26 +176,26 @@ const Plugins = Backbone.Collection.extend({ }); }, - fetchSystemUpgrades () { + fetchSystemUpgrades() { const that = this; return $.when(this._fetchSystemUpgrades()).done(() => { that.reset(that._systemUpdates); }); }, - search (query) { + search(query) { /* eslint-disable array-callback-return */ this.filter(model => { model.set({ _hidden: !model.match(query) }); }); }, - cancelAll () { + cancelAll() { const that = this; const opts = { type: 'POST', url: window.baseUrl + '/api/plugins/cancel_all', - success () { + success() { that._installedCount = 0; that._updatedCount = 0; that._uninstalledCount = 0; @@ -209,7 +208,7 @@ const Plugins = Backbone.Collection.extend({ return Backbone.ajax(opts); }, - onStatusChange (model, status) { + onStatusChange(model, status) { if (status === 'installing') { this._installedCount++; } @@ -224,4 +223,3 @@ const Plugins = Backbone.Collection.extend({ }); export default Plugins; - diff --git a/server/sonar-web/src/main/js/apps/update-center/router.js b/server/sonar-web/src/main/js/apps/update-center/router.js index ad80c5bac4a..15d1343c4b3 100644 --- a/server/sonar-web/src/main/js/apps/update-center/router.js +++ b/server/sonar-web/src/main/js/apps/update-center/router.js @@ -28,28 +28,27 @@ export default Backbone.Router.extend({ 'system': 'showSystemUpgrades' }, - initialize (options) { + initialize(options) { this.controller = options.controller; }, - index () { + index() { this.navigate('installed', { trigger: true, replace: true }); }, - showInstalled () { + showInstalled() { this.controller.showInstalled(); }, - showUpdates () { + showUpdates() { this.controller.showUpdates(); }, - showAvailable () { + showAvailable() { this.controller.showAvailable(); }, - showSystemUpgrades () { + showSystemUpgrades() { this.controller.showSystemUpgrades(); } }); - diff --git a/server/sonar-web/src/main/js/apps/update-center/routes.js b/server/sonar-web/src/main/js/apps/update-center/routes.js index 17f0da0cbf9..12e493960a1 100644 --- a/server/sonar-web/src/main/js/apps/update-center/routes.js +++ b/server/sonar-web/src/main/js/apps/update-center/routes.js @@ -22,9 +22,9 @@ import { IndexRoute, Route } from 'react-router'; import UpdateCenterAppContainer from './components/UpdateCenterAppContainer'; export default [ - <IndexRoute key="index" component={UpdateCenterAppContainer}/>, - <Route key="installed" path="installed" component={UpdateCenterAppContainer}/>, - <Route key="updates" path="updates" component={UpdateCenterAppContainer}/>, - <Route key="available" path="available" component={UpdateCenterAppContainer}/>, - <Route key="system" path="system" component={UpdateCenterAppContainer}/> + <IndexRoute key="index" component={UpdateCenterAppContainer} />, + <Route key="installed" path="installed" component={UpdateCenterAppContainer} />, + <Route key="updates" path="updates" component={UpdateCenterAppContainer} />, + <Route key="available" path="available" component={UpdateCenterAppContainer} />, + <Route key="system" path="system" component={UpdateCenterAppContainer} /> ]; diff --git a/server/sonar-web/src/main/js/apps/update-center/search-view.js b/server/sonar-web/src/main/js/apps/update-center/search-view.js index e09f092e4b7..b8bff2a3573 100644 --- a/server/sonar-web/src/main/js/apps/update-center/search-view.js +++ b/server/sonar-web/src/main/js/apps/update-center/search-view.js @@ -34,38 +34,38 @@ export default Marionette.ItemView.extend({ }, collectionEvents: { - 'filter': 'onFilter' + filter: 'onFilter' }, - initialize () { + initialize() { this._bufferedValue = null; this.search = debounce(this.search, 50); this.listenTo(this.options.state, 'change', this.render); }, - onRender () { + onRender() { this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFilterChange () { + onFilterChange() { const value = this.$('[name="update-center-filter"]:checked').val(); this.filter(value); }, - filter (value) { + filter(value) { this.options.router.navigate(value, { trigger: true }); }, - onFormSubmit (e) { + onFormSubmit(e) { e.preventDefault(); this.debouncedOnKeyUp(); }, - onKeyUp () { + onKeyUp() { const q = this.getQuery(); if (q === this._bufferedValue) { return; @@ -74,32 +74,34 @@ export default Marionette.ItemView.extend({ this.search(q); }, - getQuery () { + getQuery() { return this.$('#update-center-search-query').val(); }, - search (q) { + search(q) { this.collection.search(q); }, - focusSearch () { + focusSearch() { const that = this; - setTimeout(() => { - that.$('#update-center-search-query').focus(); - }, 0); + setTimeout( + () => { + that.$('#update-center-search-query').focus(); + }, + 0 + ); }, - onFilter (model) { + onFilter(model) { const q = model.get('category'); this.$('#update-center-search-query').val(q); this.search(q); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), state: this.options.state.toJSON() }; } }); - diff --git a/server/sonar-web/src/main/js/apps/users/change-password-view.js b/server/sonar-web/src/main/js/apps/users/change-password-view.js index 3164813ea8d..56fb22cc77e 100644 --- a/server/sonar-web/src/main/js/apps/users/change-password-view.js +++ b/server/sonar-web/src/main/js/apps/users/change-password-view.js @@ -23,12 +23,12 @@ import Template from './templates/users-change-password.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { const that = this; const oldPassword = this.$('#change-user-password-old-password').val(); const password = this.$('#change-user-password-password').val(); @@ -38,23 +38,25 @@ export default ModalForm.extend({ return; } this.disableForm(); - this.model.changePassword(oldPassword, password, { - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + this.model + .changePassword(oldPassword, password, { + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); }, - serializeData () { + serializeData() { return Object.assign({}, ModalForm.prototype.serializeData.apply(this, arguments), { isOwnPassword: this.options.currentUser.login === this.model.id }); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js b/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js index 6c227892eb9..546ff44b7c9 100644 --- a/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js +++ b/server/sonar-web/src/main/js/apps/users/components/UsersAppContainer.js @@ -27,12 +27,12 @@ class UsersAppContainer extends React.Component { currentUser: React.PropTypes.object.isRequired }; - componentDidMount () { + componentDidMount() { init(this.refs.container, this.props.currentUser); } - render () { - return <div ref="container"/>; + render() { + return <div ref="container" />; } } diff --git a/server/sonar-web/src/main/js/apps/users/create-view.js b/server/sonar-web/src/main/js/apps/users/create-view.js index c55e9f23b64..a55b63d3280 100644 --- a/server/sonar-web/src/main/js/apps/users/create-view.js +++ b/server/sonar-web/src/main/js/apps/users/create-view.js @@ -21,8 +21,7 @@ import User from './user'; import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; const user = new User({ login: this.$('#create-user-login').val(), @@ -32,19 +31,21 @@ export default FormView.extend({ scmAccounts: this.getScmAccounts() }); this.disableForm(); - return user.save(null, { - statusCode: { - // do not show global error - 400: null, - 500: null - } - }).done(() => { - that.collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return user + .save(null, { + statusCode: { + // do not show global error + 400: null, + 500: null + } + }) + .done(() => { + that.collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/deactivate-view.js b/server/sonar-web/src/main/js/apps/users/deactivate-view.js index d6e1329ef09..d0d5938d1d4 100644 --- a/server/sonar-web/src/main/js/apps/users/deactivate-view.js +++ b/server/sonar-web/src/main/js/apps/users/deactivate-view.js @@ -23,26 +23,28 @@ import Template from './templates/users-deactivate.hbs'; export default ModalForm.extend({ template: Template, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - sendRequest () { + sendRequest() { const that = this; const collection = this.model.collection; - return this.model.destroy({ - wait: true, - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - collection.total--; - that.destroy(); - }).fail(jqXHR => { - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .destroy({ + wait: true, + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + collection.total--; + that.destroy(); + }) + .fail(jqXHR => { + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/form-view.js b/server/sonar-web/src/main/js/apps/users/form-view.js index 87111cfeab8..7fec06166db 100644 --- a/server/sonar-web/src/main/js/apps/users/form-view.js +++ b/server/sonar-web/src/main/js/apps/users/form-view.js @@ -24,43 +24,44 @@ import Template from './templates/users-form.hbs'; export default ModalForm.extend({ template: Template, - events () { + events() { return { ...ModalForm.prototype.events.apply(this, arguments), 'click #create-user-add-scm-account': 'onAddScmAccountClick' }; }, - onRender () { + onRender() { ModalForm.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { ModalForm.prototype.onDestroy.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.sendRequest(); }, - onAddScmAccountClick (e) { + onAddScmAccountClick(e) { e.preventDefault(); this.addScmAccount(); }, - getScmAccounts () { - const scmAccounts = this.$('[name="scmAccounts"]').map(function () { - return $(this).val(); - }).toArray(); + getScmAccounts() { + const scmAccounts = this.$('[name="scmAccounts"]') + .map(function() { + return $(this).val(); + }) + .toArray(); return scmAccounts.filter(value => !!value); }, - addScmAccount () { + addScmAccount() { const fields = this.$('[name="scmAccounts"]'); fields.first().clone().val('').insertAfter(fields.last()); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/groups-view.js b/server/sonar-web/src/main/js/apps/users/groups-view.js index ee2f578c848..f3afe2de43f 100644 --- a/server/sonar-web/src/main/js/apps/users/groups-view.js +++ b/server/sonar-web/src/main/js/apps/users/groups-view.js @@ -24,14 +24,14 @@ import Template from './templates/users-groups.hbs'; export default Modal.extend({ template: Template, - onRender () { + onRender() { Modal.prototype.onRender.apply(this, arguments); new window.SelectList({ el: this.$('#users-groups'), width: '100%', readOnly: false, focusSearch: false, - format (item) { + format(item) { return `${item.name}<br><span class="note">${item.description}</span>`; }, queryParam: 'q', @@ -43,16 +43,15 @@ export default Modal.extend({ }, selectParameter: 'id', selectParameterValue: 'id', - parse (r) { + parse(r) { this.more = false; return r.groups; } }); }, - onDestroy () { + onDestroy() { this.model.collection.refresh(); Modal.prototype.onDestroy.apply(this, arguments); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/header-view.js b/server/sonar-web/src/main/js/apps/users/header-view.js index 5e738c19954..ae8c6bba45b 100644 --- a/server/sonar-web/src/main/js/apps/users/header-view.js +++ b/server/sonar-web/src/main/js/apps/users/header-view.js @@ -25,31 +25,30 @@ export default Marionette.ItemView.extend({ template: Template, collectionEvents: { - 'request': 'showSpinner', - 'sync': 'hideSpinner' + request: 'showSpinner', + sync: 'hideSpinner' }, events: { 'click #users-create': 'onCreateClick' }, - showSpinner () { + showSpinner() { this.$('.spinner').removeClass('hidden'); }, - hideSpinner () { + hideSpinner() { this.$('.spinner').addClass('hidden'); }, - onCreateClick (e) { + onCreateClick(e) { e.preventDefault(); this.createUser(); }, - createUser () { + createUser() { new CreateView({ collection: this.collection }).render(); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/init.js b/server/sonar-web/src/main/js/apps/users/init.js index 73ec0b10104..b1c038b9386 100644 --- a/server/sonar-web/src/main/js/apps/users/init.js +++ b/server/sonar-web/src/main/js/apps/users/init.js @@ -28,7 +28,7 @@ import { getIdentityProviders } from '../../api/users'; const App = new Marionette.Application(); -const init = function ({ el, currentUser }, providers) { +const init = function({ el, currentUser }, providers) { // Layout this.layout = new Layout({ el }); this.layout.render(); @@ -60,6 +60,6 @@ App.on('start', options => { getIdentityProviders().then(r => init.call(App, options, r.identityProviders)); }); -export default function (el, currentUser) { +export default function(el, currentUser) { App.start({ el, currentUser }); } diff --git a/server/sonar-web/src/main/js/apps/users/layout.js b/server/sonar-web/src/main/js/apps/users/layout.js index 568078a821a..1a94dc8ebd1 100644 --- a/server/sonar-web/src/main/js/apps/users/layout.js +++ b/server/sonar-web/src/main/js/apps/users/layout.js @@ -30,4 +30,3 @@ export default Marionette.LayoutView.extend({ listFooterRegion: '#users-list-footer' } }); - diff --git a/server/sonar-web/src/main/js/apps/users/list-footer-view.js b/server/sonar-web/src/main/js/apps/users/list-footer-view.js index ea67d7fa0a5..84e1e311c4e 100644 --- a/server/sonar-web/src/main/js/apps/users/list-footer-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-footer-view.js @@ -24,23 +24,23 @@ export default Marionette.ItemView.extend({ template: Template, collectionEvents: { - 'all': 'render' + all: 'render' }, events: { 'click #users-fetch-more': 'onMoreClick' }, - onMoreClick (e) { + onMoreClick(e) { e.preventDefault(); this.fetchMore(); }, - fetchMore () { + fetchMore() { this.collection.fetchMore(); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), total: this.collection.total, @@ -49,4 +49,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/users/list-item-view.js b/server/sonar-web/src/main/js/apps/users/list-item-view.js index 1916cf5cae2..ba24798e79e 100644 --- a/server/sonar-web/src/main/js/apps/users/list-item-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-item-view.js @@ -40,73 +40,73 @@ export default Marionette.ItemView.extend({ 'click .js-user-tokens': 'onTokensClick' }, - initialize () { + initialize() { this.scmLimit = 3; this.groupsLimit = 3; }, - onRender () { + onRender() { this.$el.attr('data-login', this.model.id); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onMoreScmClick (e) { + onMoreScmClick(e) { e.preventDefault(); this.showMoreScm(); }, - onMoreGroupsClick (e) { + onMoreGroupsClick(e) { e.preventDefault(); this.showMoreGroups(); }, - onUpdateClick (e) { + onUpdateClick(e) { e.preventDefault(); this.updateUser(); }, - onChangePasswordClick (e) { + onChangePasswordClick(e) { e.preventDefault(); this.changePassword(); }, - onDeactivateClick (e) { + onDeactivateClick(e) { e.preventDefault(); this.deactivateUser(); }, - onGroupsClick (e) { + onGroupsClick(e) { e.preventDefault(); this.showGroups(); }, - onTokensClick (e) { + onTokensClick(e) { e.preventDefault(); this.showTokens(); }, - showMoreScm () { + showMoreScm() { this.scmLimit = 10000; this.render(); }, - showMoreGroups () { + showMoreGroups() { this.groupsLimit = 10000; this.render(); }, - updateUser () { + updateUser() { new UpdateView({ model: this.model, collection: this.model.collection }).render(); }, - changePassword () { + changePassword() { new ChangePasswordView({ model: this.model, collection: this.model.collection, @@ -114,19 +114,19 @@ export default Marionette.ItemView.extend({ }).render(); }, - deactivateUser () { + deactivateUser() { new DeactivateView({ model: this.model }).render(); }, - showGroups () { + showGroups() { new GroupsView({ model: this.model }).render(); }, - showTokens () { + showTokens() { new TokensView({ model: this.model }).render(); }, - serializeData () { + serializeData() { const scmAccounts = this.model.get('scmAccounts'); const scmAccountsLimit = scmAccounts.length > this.scmLimit ? this.scmLimit - 1 : this.scmLimit; @@ -134,8 +134,9 @@ export default Marionette.ItemView.extend({ const groupsLimit = groups.length > this.groupsLimit ? this.groupsLimit - 1 : this.groupsLimit; const externalProvider = this.model.get('externalProvider'); - const identityProvider = this.model.get('local') ? null : - this.options.providers.find(provider => externalProvider === provider.key); + const identityProvider = this.model.get('local') + ? null + : this.options.providers.find(provider => externalProvider === provider.key); return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), @@ -148,4 +149,3 @@ export default Marionette.ItemView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/apps/users/list-view.js b/server/sonar-web/src/main/js/apps/users/list-view.js index 4399496a6c0..19a4c043ee6 100644 --- a/server/sonar-web/src/main/js/apps/users/list-view.js +++ b/server/sonar-web/src/main/js/apps/users/list-view.js @@ -28,30 +28,29 @@ export default Marionette.CompositeView.extend({ childViewContainer: 'tbody', collectionEvents: { - 'request': 'showLoading', - 'sync': 'hideLoading' + request: 'showLoading', + sync: 'hideLoading' }, - childViewOptions () { + childViewOptions() { return { providers: this.options.providers, currentUser: this.options.currentUser }; }, - showLoading () { + showLoading() { this.$el.addClass('new-loading'); }, - hideLoading () { + hideLoading() { this.$el.removeClass('new-loading'); }, - serializeData () { + serializeData() { return { ...Marionette.CompositeView.prototype.serializeData.apply(this, arguments), customOrganizations: areThereCustomOrganizations() }; } }); - diff --git a/server/sonar-web/src/main/js/apps/users/routes.js b/server/sonar-web/src/main/js/apps/users/routes.js index bd977436c60..8efebd13ba7 100644 --- a/server/sonar-web/src/main/js/apps/users/routes.js +++ b/server/sonar-web/src/main/js/apps/users/routes.js @@ -21,6 +21,4 @@ import React from 'react'; import { IndexRoute } from 'react-router'; import UsersAppContainer from './components/UsersAppContainer'; -export default ( - <IndexRoute component={UsersAppContainer}/> -); +export default <IndexRoute component={UsersAppContainer} />; diff --git a/server/sonar-web/src/main/js/apps/users/search-view.js b/server/sonar-web/src/main/js/apps/users/search-view.js index c1939c6fed4..7f7424381eb 100644 --- a/server/sonar-web/src/main/js/apps/users/search-view.js +++ b/server/sonar-web/src/main/js/apps/users/search-view.js @@ -34,27 +34,27 @@ export default Marionette.ItemView.extend({ 'keyup #users-search-query': 'initialOnKeyUp' }, - initialize () { + initialize() { this._bufferedValue = null; this.debouncedOnKeyUp = debounce(this.onKeyUp, 400); }, - onRender () { + onRender() { this.delegateEvents(); }, - onFormSubmit (e) { + onFormSubmit(e) { e.preventDefault(); this.debouncedOnKeyUp(); }, - initialOnKeyUp () { + initialOnKeyUp() { const q = this.getQuery(); this.ui.hint.toggleClass('hidden', q.length !== 1); this.debouncedOnKeyUp(); }, - onKeyUp () { + onKeyUp() { const q = this.getQuery(); if (q === this._bufferedValue) { return; @@ -69,12 +69,11 @@ export default Marionette.ItemView.extend({ } }, - getQuery () { + getQuery() { return this.$('#users-search-query').val(); }, - search (q) { + search(q) { return this.collection.fetch({ reset: true, data: { q } }); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/tokens-view.js b/server/sonar-web/src/main/js/apps/users/tokens-view.js index 0cfb3afab1e..01fa9a6636e 100644 --- a/server/sonar-web/src/main/js/apps/users/tokens-view.js +++ b/server/sonar-web/src/main/js/apps/users/tokens-view.js @@ -26,7 +26,7 @@ import { getTokens, generateToken, revokeToken } from '../../api/user-tokens'; export default Modal.extend({ template: Template, - events () { + events() { return { ...Modal.prototype.events.apply(this, arguments), 'submit .js-generate-token-form': 'onGenerateTokenFormSubmit', @@ -34,7 +34,7 @@ export default Modal.extend({ }; }, - initialize () { + initialize() { Modal.prototype.initialize.apply(this, arguments); this.tokens = null; this.newToken = null; @@ -42,32 +42,32 @@ export default Modal.extend({ this.requestTokens(); }, - requestTokens () { + requestTokens() { return getTokens(this.model.id).then(tokens => { this.tokens = tokens; this.render(); }); }, - onGenerateTokenFormSubmit (e) { + onGenerateTokenFormSubmit(e) { e.preventDefault(); this.errors = []; this.newToken = null; const tokenName = this.$('.js-generate-token-form input').val(); generateToken(this.model.id, tokenName) - .then(response => { - this.newToken = response; - this.requestTokens(); - }) - .catch(error => { - error.response.json().then(response => { - this.errors = response.errors; - this.render(); - }); + .then(response => { + this.newToken = response; + this.requestTokens(); + }) + .catch(error => { + error.response.json().then(response => { + this.errors = response.errors; + this.render(); }); + }); }, - onRevokeTokenFormSubmit (e) { + onRevokeTokenFormSubmit(e) { e.preventDefault(); const tokenName = $(e.currentTarget).data('token'); const token = this.tokens.find(t => t.name === `${tokenName}`); @@ -81,25 +81,27 @@ export default Modal.extend({ } }, - onRender () { + onRender() { Modal.prototype.onRender.apply(this, arguments); const copyButton = this.$('.js-copy-to-clipboard'); if (copyButton.length) { const clipboard = new Clipboard(copyButton.get(0)); clipboard.on('success', () => { - copyButton.tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' }).tooltip('show'); + copyButton + .tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' }) + .tooltip('show'); setTimeout(() => copyButton.tooltip('hide'), 1000); }); } this.newToken = null; }, - onDestroy () { + onDestroy() { this.model.collection.refresh(); Modal.prototype.onDestroy.apply(this, arguments); }, - serializeData () { + serializeData() { return { ...Modal.prototype.serializeData.apply(this, arguments), tokens: this.tokens, @@ -107,5 +109,4 @@ export default Modal.extend({ errors: this.errors }; } - }); diff --git a/server/sonar-web/src/main/js/apps/users/update-view.js b/server/sonar-web/src/main/js/apps/users/update-view.js index 94f1593857d..f37075c2226 100644 --- a/server/sonar-web/src/main/js/apps/users/update-view.js +++ b/server/sonar-web/src/main/js/apps/users/update-view.js @@ -20,8 +20,7 @@ import FormView from './form-view'; export default FormView.extend({ - - sendRequest () { + sendRequest() { const that = this; this.model.set({ name: this.$('#create-user-name').val(), @@ -29,18 +28,20 @@ export default FormView.extend({ scmAccounts: this.getScmAccounts() }); this.disableForm(); - return this.model.save(null, { - statusCode: { - // do not show global error - 400: null - } - }).done(() => { - that.collection.refresh(); - that.destroy(); - }).fail(jqXHR => { - that.enableForm(); - that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); - }); + return this.model + .save(null, { + statusCode: { + // do not show global error + 400: null + } + }) + .done(() => { + that.collection.refresh(); + that.destroy(); + }) + .fail(jqXHR => { + that.enableForm(); + that.showErrors(jqXHR.responseJSON.errors, jqXHR.responseJSON.warnings); + }); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/user.js b/server/sonar-web/src/main/js/apps/users/user.js index 7d05906b680..f37524edb6a 100644 --- a/server/sonar-web/src/main/js/apps/users/user.js +++ b/server/sonar-web/src/main/js/apps/users/user.js @@ -24,29 +24,29 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ idAttribute: 'login', - urlRoot () { + urlRoot() { return window.baseUrl + '/api/users'; }, - defaults () { + defaults() { return { groups: [], scmAccounts: [] }; }, - toQuery () { + toQuery() { const data = { ...this.toJSON(), scmAccount: this.get('scmAccounts') }; delete data.scmAccounts; return data; }, - isNew () { + isNew() { // server never sends a password return this.has('password'); }, - sync (method, model, options) { + sync(method, model, options) { const opts = options || {}; if (method === 'create') { defaults(opts, { @@ -74,7 +74,7 @@ export default Backbone.Model.extend({ return Backbone.ajax(opts); }, - changePassword (oldPassword, password, options) { + changePassword(oldPassword, password, options) { const data = { login: this.id, password @@ -90,4 +90,3 @@ export default Backbone.Model.extend({ return Backbone.ajax(opts); } }); - diff --git a/server/sonar-web/src/main/js/apps/users/users.js b/server/sonar-web/src/main/js/apps/users/users.js index a889748f1bc..a2a49dc4510 100644 --- a/server/sonar-web/src/main/js/apps/users/users.js +++ b/server/sonar-web/src/main/js/apps/users/users.js @@ -23,35 +23,33 @@ import User from './user'; export default Backbone.Collection.extend({ model: User, - url () { + url() { return window.baseUrl + '/api/users/search'; }, - parse (r) { + parse(r) { this.total = +r.total; this.p = +r.p; this.ps = +r.ps; return r.users; }, - fetch (options) { + fetch(options) { const d = (options && options.data) || {}; this.q = d.q; return Backbone.Collection.prototype.fetch.call(this, options); }, - fetchMore () { + fetchMore() { const p = this.p + 1; return this.fetch({ add: true, remove: false, data: { p, ps: this.ps, q: this.q } }); }, - refresh () { + refresh() { return this.fetch({ reset: true, data: { q: this.q } }); }, - hasMore () { + hasMore() { return this.total > this.p * this.ps; } - }); - diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Action.js b/server/sonar-web/src/main/js/apps/web-api/components/Action.js index 316ce400f52..1a3f6dbfe9f 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/Action.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/Action.js @@ -79,7 +79,7 @@ export default class Action extends React.PureComponent { }); }; - render () { + render() { const { action, domain } = this.props; const { showChangelog, showParams, showResponse } = this.state; const verb = action.post ? 'POST' : 'GET'; @@ -89,7 +89,7 @@ export default class Action extends React.PureComponent { <div id={actionKey} className="web-api-action"> <TooltipsContainer> <header className="web-api-action-header"> - <Link to={{ pathname: '/web_api/' + actionKey }} className="spacer-right icon-link"/> + <Link to={{ pathname: '/web_api/' + actionKey }} className="spacer-right icon-link" /> <h3 className="web-api-action-title"> {verb} {actionKey} @@ -97,21 +97,22 @@ export default class Action extends React.PureComponent { {action.internal && <span className="spacer-left"> - <InternalBadge/> + <InternalBadge /> </span>} {action.since && <span className="spacer-left badge">since {action.since}</span>} {action.deprecatedSince && <span className="spacer-left"> - <DeprecatedBadge since={action.deprecatedSince}/> + <DeprecatedBadge since={action.deprecatedSince} /> </span>} </header> </TooltipsContainer> <div className="web-api-action-description markdown" - dangerouslySetInnerHTML={{ __html: action.description }}/> + dangerouslySetInnerHTML={{ __html: action.description }} + /> {(action.params || action.hasResponseExample) && <ul className="web-api-action-actions tabs"> @@ -120,7 +121,8 @@ export default class Action extends React.PureComponent { <a className={classNames({ selected: showParams })} href="#" - onClick={this.handleShowParamsClick}> + onClick={this.handleShowParamsClick} + > Parameters </a> </li>} @@ -130,7 +132,8 @@ export default class Action extends React.PureComponent { <a className={classNames({ selected: showResponse })} href="#" - onClick={this.handleShowResponseClick}> + onClick={this.handleShowResponseClick} + > Response Example </a> </li>} @@ -140,7 +143,8 @@ export default class Action extends React.PureComponent { <a className={classNames({ selected: showChangelog })} href="#" - onClick={this.handleChangelogClick}> + onClick={this.handleChangelogClick} + > Changelog </a> </li>} @@ -151,13 +155,14 @@ export default class Action extends React.PureComponent { <Params params={action.params} showDeprecated={this.props.showDeprecated} - showInternal={this.props.showInternal}/>} + showInternal={this.props.showInternal} + />} {showResponse && action.hasResponseExample && - <ResponseExample domain={domain} action={action}/>} + <ResponseExample domain={domain} action={action} />} - {showChangelog && <ActionChangelog changelog={action.changelog}/>} + {showChangelog && <ActionChangelog changelog={action.changelog} />} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/web-api/components/ActionChangelog.js b/server/sonar-web/src/main/js/apps/web-api/components/ActionChangelog.js index 81c156cd535..7297daed368 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/ActionChangelog.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/ActionChangelog.js @@ -30,7 +30,7 @@ type Props = { export default class ActionChangelog extends React.PureComponent { props: Props; - render () { + render() { return ( <ul className="big-spacer-top"> {this.props.changelog.map((item, index) => ( diff --git a/server/sonar-web/src/main/js/apps/web-api/components/DeprecatedBadge.js b/server/sonar-web/src/main/js/apps/web-api/components/DeprecatedBadge.js index 97313c3be7a..dc2653f9590 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/DeprecatedBadge.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/DeprecatedBadge.js @@ -20,15 +20,16 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; -export default function DeprecatedBadge ({ since }) { +export default function DeprecatedBadge({ since }) { const label = since ? `deprecated since ${since}` : 'deprecated'; return ( - <span - className="badge badge-warning" - title={translate('api_documentation.deprecation_tooltip')} - data-toggle="tooltip"> - {label} - </span> + <span + className="badge badge-warning" + title={translate('api_documentation.deprecation_tooltip')} + data-toggle="tooltip" + > + {label} + </span> ); } diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Domain.js b/server/sonar-web/src/main/js/apps/web-api/components/Domain.js index 0cfbb1de482..6e2ac633fcf 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/Domain.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/Domain.js @@ -35,7 +35,7 @@ type Props = { export default class Domain extends React.PureComponent { props: Props; - render () { + render() { const { domain, showInternal, showDeprecated, searchQuery } = this.props; const filteredActions = domain.actions .filter(action => showInternal || !action.internal) @@ -49,12 +49,12 @@ export default class Domain extends React.PureComponent { {domain.deprecated && <span className="spacer-left"> - <DeprecatedBadge/> + <DeprecatedBadge /> </span>} {domain.internal && <span className="spacer-left"> - <InternalBadge/> + <InternalBadge /> </span>} </header> @@ -67,7 +67,8 @@ export default class Domain extends React.PureComponent { action={action} domain={domain} showDeprecated={showDeprecated} - showInternal={showInternal}/> + showInternal={showInternal} + /> ))} </div> </div> diff --git a/server/sonar-web/src/main/js/apps/web-api/components/InternalBadge.js b/server/sonar-web/src/main/js/apps/web-api/components/InternalBadge.js index a6da11aa1d1..987f01d3720 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/InternalBadge.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/InternalBadge.js @@ -20,13 +20,14 @@ import React from 'react'; import { translate } from '../../../helpers/l10n'; -export default function InternalBadge () { +export default function InternalBadge() { return ( - <span - className="badge badge-danger" - title={translate('api_documentation.internal_tooltip')} - data-toggle="tooltip"> - internal - </span> + <span + className="badge badge-danger" + title={translate('api_documentation.internal_tooltip')} + data-toggle="tooltip" + > + internal + </span> ); } diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Menu.js b/server/sonar-web/src/main/js/apps/web-api/components/Menu.js index b2bea00727f..63192245698 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/Menu.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/Menu.js @@ -38,7 +38,7 @@ type Props = { export default class Menu extends React.PureComponent { props: Props; - render () { + render() { const { domains, showInternal, showDeprecated, searchQuery, splat } = this.props; const filteredDomains = (domains || []) .map(domain => { @@ -60,11 +60,12 @@ export default class Menu extends React.PureComponent { className={classNames('list-group-item', { active: isDomainPathActive(domain.path, splat) })} - to={'/web_api/' + domain.path}> + to={'/web_api/' + domain.path} + > <h3 className="list-group-item-heading"> {domain.path} - {domain.deprecated && <DeprecatedBadge/>} - {domain.internal && <InternalBadge/>} + {domain.deprecated && <DeprecatedBadge />} + {domain.internal && <InternalBadge />} </h3> <p className="list-group-item-text"> {domain.description} diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Params.js b/server/sonar-web/src/main/js/apps/web-api/components/Params.js index bba2118bfa0..7b362960581 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/Params.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/Params.js @@ -30,7 +30,7 @@ export default class Params extends React.PureComponent { params: Array<Param> }; - render () { + render() { const { showDeprecated, showInternal, params } = this.props; const displayedParameters = params .filter(p => showDeprecated || !p.deprecatedSince) @@ -47,12 +47,12 @@ export default class Params extends React.PureComponent { {param.internal && <div className="little-spacer-top"> - <InternalBadge/> + <InternalBadge /> </div>} {param.deprecatedSince && <div className="little-spacer-top"> - <DeprecatedBadge since={param.deprecatedSince}/> + <DeprecatedBadge since={param.deprecatedSince} /> </div>} {showDeprecated && @@ -65,7 +65,7 @@ export default class Params extends React.PureComponent { param.deprecatedKey && param.deprecatedKeySince && <div className="little-spacer-top"> - <DeprecatedBadge since={param.deprecatedKeySince}/> + <DeprecatedBadge since={param.deprecatedKeySince} /> </div>} <div className="note little-spacer-top"> @@ -81,7 +81,8 @@ export default class Params extends React.PureComponent { <td> <div className="markdown" - dangerouslySetInnerHTML={{ __html: param.description }}/> + dangerouslySetInnerHTML={{ __html: param.description }} + /> </td> <td style={{ width: 250 }}> diff --git a/server/sonar-web/src/main/js/apps/web-api/components/ResponseExample.js b/server/sonar-web/src/main/js/apps/web-api/components/ResponseExample.js index 263ea3acef9..d11ecbbf0c7 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/ResponseExample.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/ResponseExample.js @@ -23,36 +23,34 @@ import { fetchResponseExample as fetchResponseExampleApi } from '../../../api/we export default class ResponseExample extends React.Component { state = {}; - componentDidMount () { + componentDidMount() { this.mounted = true; this.fetchResponseExample(); } - componentDidUpdate (nextProps) { + componentDidUpdate(nextProps) { if (nextProps.action !== this.props.action) { this.fetchResponseExample(); } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - fetchResponseExample () { + fetchResponseExample() { const { domain, action } = this.props; - fetchResponseExampleApi(domain.path, action.key) - .then(responseExample => this.setState({ responseExample })); + fetchResponseExampleApi(domain.path, action.key).then(responseExample => + this.setState({ responseExample })); } - render () { + render() { const { responseExample } = this.state; return ( - <div className="web-api-response"> - {responseExample && ( - <pre style={{ whiteSpace: 'pre-wrap' }}>{responseExample.example}</pre> - )} - </div> + <div className="web-api-response"> + {responseExample && <pre style={{ whiteSpace: 'pre-wrap' }}>{responseExample.example}</pre>} + </div> ); } } diff --git a/server/sonar-web/src/main/js/apps/web-api/components/Search.js b/server/sonar-web/src/main/js/apps/web-api/components/Search.js index 233ad109a57..6e90c0a6920 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/Search.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/Search.js @@ -41,41 +41,42 @@ export default class Search extends React.PureComponent { props: Props; state: State; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = { query: '' }; this.actuallySearch = debounce(this.actuallySearch.bind(this), 250); } - handleSearch (e: SyntheticInputEvent) { + handleSearch(e: SyntheticInputEvent) { const { value } = e.target; this.setState({ query: value }); this.actuallySearch(); } - actuallySearch () { + actuallySearch() { const { onSearch } = this.props; onSearch(this.state.query); } - render () { + render() { const { showInternal, showDeprecated, onToggleInternal, onToggleDeprecated } = this.props; return ( <div className="web-api-search"> <div> - <i className="icon-search"/> + <i className="icon-search" /> <input className="spacer-left input-large" type="search" value={this.state.query} placeholder={translate('search_verb')} - onChange={this.handleSearch.bind(this)}/> + onChange={this.handleSearch.bind(this)} + /> </div> <TooltipsContainer> <div className="big-spacer-top"> - <Checkbox checked={showInternal} onCheck={onToggleInternal}/> + <Checkbox checked={showInternal} onCheck={onToggleInternal} /> {' '} <span style={{ cursor: 'pointer' }} @@ -83,19 +84,21 @@ export default class Search extends React.PureComponent { tabIndex="0" role="checkbox" aria-checked={showInternal ? 'true' : 'false'} - onClick={onToggleInternal}> + onClick={onToggleInternal} + > Show Internal API </span> <i className="icon-help spacer-left" title={translate('api_documentation.internal_tooltip')} - data-toggle="tooltip"/> + data-toggle="tooltip" + /> </div> </TooltipsContainer> <TooltipsContainer> <div className="spacer-top"> - <Checkbox checked={showDeprecated} onCheck={onToggleDeprecated}/> + <Checkbox checked={showDeprecated} onCheck={onToggleDeprecated} /> {' '} <span style={{ cursor: 'pointer' }} @@ -103,13 +106,15 @@ export default class Search extends React.PureComponent { tabIndex="0" role="checkbox" aria-checked={showDeprecated ? 'true' : 'false'} - onClick={onToggleDeprecated}> + onClick={onToggleDeprecated} + > Show Deprecated API </span> <i className="icon-help spacer-left" title={translate('api_documentation.deprecation_tooltip')} - data-toggle="tooltip"/> + data-toggle="tooltip" + /> </div> </TooltipsContainer> </div> diff --git a/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.js b/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.js index 6251e209c40..162c0a2c952 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/WebApiApp.js @@ -45,24 +45,24 @@ export default class WebApiApp extends React.PureComponent { showInternal: false }; - componentDidMount () { + componentDidMount() { this.mounted = true; this.scrollToAction = this.scrollToAction.bind(this); this.fetchList(); document.getElementById('footer').classList.add('search-navigator-footer'); } - componentDidUpdate () { + componentDidUpdate() { this.toggleInternalInitially(); this.scrollToAction(); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; document.getElementById('footer').classList.remove('search-navigator-footer'); } - fetchList (cb?: () => void) { + fetchList(cb?: () => void) { fetchWebApi().then(domains => { if (this.mounted) { this.setState({ domains }, cb); @@ -70,12 +70,12 @@ export default class WebApiApp extends React.PureComponent { }); } - scrollToAction () { + scrollToAction() { const splat = this.props.params.splat || ''; this.scrollToElement(splat); } - scrollToElement (id: string) { + scrollToElement(id: string) { const element = document.getElementById(id); if (element) { @@ -88,7 +88,7 @@ export default class WebApiApp extends React.PureComponent { } } - toggleInternalInitially () { + toggleInternalInitially() { const splat = this.props.params.splat || ''; const { domains, showInternal } = this.state; @@ -107,11 +107,11 @@ export default class WebApiApp extends React.PureComponent { } } - handleSearch (searchQuery: string) { + handleSearch(searchQuery: string) { this.setState({ searchQuery }); } - handleToggleInternal () { + handleToggleInternal() { const splat = this.props.params.splat || ''; const { router } = this.context; const { domains } = this.state; @@ -125,11 +125,11 @@ export default class WebApiApp extends React.PureComponent { this.setState({ showInternal }); } - handleToggleDeprecated () { + handleToggleDeprecated() { this.setState(state => ({ showDeprecated: !state.showDeprecated })); } - render () { + render() { const splat = this.props.params.splat || ''; const { domains, showInternal, showDeprecated, searchQuery } = this.state; @@ -149,14 +149,16 @@ export default class WebApiApp extends React.PureComponent { showInternal={showInternal} onSearch={this.handleSearch.bind(this)} onToggleInternal={this.handleToggleInternal.bind(this)} - onToggleDeprecated={this.handleToggleDeprecated.bind(this)}/> + onToggleDeprecated={this.handleToggleDeprecated.bind(this)} + /> <Menu domains={this.state.domains} showDeprecated={showDeprecated} showInternal={showInternal} searchQuery={searchQuery} - splat={splat}/> + splat={splat} + /> </div> <div className="search-navigator-workspace"> @@ -166,7 +168,8 @@ export default class WebApiApp extends React.PureComponent { domain={domain} showDeprecated={showDeprecated} showInternal={showInternal} - searchQuery={searchQuery}/>} + searchQuery={searchQuery} + />} </div> </div> ); diff --git a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/ActionChangelog-test.js b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/ActionChangelog-test.js index eb29e53a603..380213bf33a 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/ActionChangelog-test.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/ActionChangelog-test.js @@ -26,5 +26,5 @@ it('should render', () => { { version: '5.0', description: 'foo' }, { version: '5.1', description: 'bar' } ]; - expect(shallow(<ActionChangelog changelog={changelog}/>)).toMatchSnapshot(); + expect(shallow(<ActionChangelog changelog={changelog} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Domain-test.js b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Domain-test.js index e503202d181..968d9037864 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Domain-test.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Domain-test.js @@ -22,19 +22,27 @@ import { shallow } from 'enzyme'; import Domain from '../Domain'; it('should render deprecated actions', () => { - const actions = [{ - key: 'foo', - deprecatedSince: '5.0' - }]; + const actions = [ + { + key: 'foo', + deprecatedSince: '5.0' + } + ]; const domain = { actions, path: 'api' }; - expect(shallow(<Domain domain={domain} searchQuery="" showDeprecated={true}/>)).toMatchSnapshot(); + expect( + shallow(<Domain domain={domain} searchQuery="" showDeprecated={true} />) + ).toMatchSnapshot(); }); it('should not render deprecated actions', () => { - const actions = [{ - key: 'foo', - deprecatedSince: '5.0' - }]; + const actions = [ + { + key: 'foo', + deprecatedSince: '5.0' + } + ]; const domain = { actions, path: 'api' }; - expect(shallow(<Domain domain={domain} searchQuery="" showDeprecated={false}/>)).toMatchSnapshot(); + expect( + shallow(<Domain domain={domain} searchQuery="" showDeprecated={false} />) + ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Params-test.js b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Params-test.js index 8d3f89da3dd..e8ca685eaea 100644 --- a/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Params-test.js +++ b/server/sonar-web/src/main/js/apps/web-api/components/__tests__/Params-test.js @@ -22,26 +22,32 @@ import { shallow } from 'enzyme'; import Params from '../Params'; it('should render deprecated parameters', () => { - const params = [{ - key: 'foo', - deprecatedSince: '5.0' - }]; - expect(shallow(<Params params={params} showDeprecated={true}/>)).toMatchSnapshot(); + const params = [ + { + key: 'foo', + deprecatedSince: '5.0' + } + ]; + expect(shallow(<Params params={params} showDeprecated={true} />)).toMatchSnapshot(); }); it('should not render deprecated parameters', () => { - const params = [{ - key: 'foo', - deprecatedSince: '5.0' - }]; - expect(shallow(<Params params={params} showDeprecated={false}/>)).toMatchSnapshot(); + const params = [ + { + key: 'foo', + deprecatedSince: '5.0' + } + ]; + expect(shallow(<Params params={params} showDeprecated={false} />)).toMatchSnapshot(); }); it('should render deprecated key', () => { - const params = [{ - key: 'foo', - deprecatedKey: 'foo-deprecated', - deprecatedKeySince: '5.0' - }]; - expect(shallow(<Params params={params} showDeprecated={true}/>)).toMatchSnapshot(); + const params = [ + { + key: 'foo', + deprecatedKey: 'foo-deprecated', + deprecatedKeySince: '5.0' + } + ]; + expect(shallow(<Params params={params} showDeprecated={true} />)).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/web-api/routes.js b/server/sonar-web/src/main/js/apps/web-api/routes.js index 3ff2048b6d4..fd647f2e21a 100644 --- a/server/sonar-web/src/main/js/apps/web-api/routes.js +++ b/server/sonar-web/src/main/js/apps/web-api/routes.js @@ -22,6 +22,6 @@ import { IndexRoute, Route } from 'react-router'; import WebApiApp from './components/WebApiApp'; export default [ - <IndexRoute key="index" component={WebApiApp}/>, - <Route key="splat" path="**" component={WebApiApp}/> + <IndexRoute key="index" component={WebApiApp} />, + <Route key="splat" path="**" component={WebApiApp} /> ]; diff --git a/server/sonar-web/src/main/js/apps/web-api/utils.js b/server/sonar-web/src/main/js/apps/web-api/utils.js index 4d17438005d..d5af23b6740 100644 --- a/server/sonar-web/src/main/js/apps/web-api/utils.js +++ b/server/sonar-web/src/main/js/apps/web-api/utils.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export function getActionKey (domain, action) { +export function getActionKey(domain, action) { return domain + '/' + action; } diff --git a/server/sonar-web/src/main/js/components/RestartModal/index.js b/server/sonar-web/src/main/js/components/RestartModal/index.js index 249153fb22b..a517a0477d9 100644 --- a/server/sonar-web/src/main/js/components/RestartModal/index.js +++ b/server/sonar-web/src/main/js/components/RestartModal/index.js @@ -26,15 +26,15 @@ const RestartModal = ModalForm.extend({ template: Template, restartingTemplate: RestartingTemplate, - initialize () { + initialize() { this.restarting = false; }, - getTemplate () { + getTemplate() { return this.restarting ? this.restartingTemplate : this.template; }, - onFormSubmit () { + onFormSubmit() { ModalForm.prototype.onFormSubmit.apply(this, arguments); this.restarting = true; this.render(); diff --git a/server/sonar-web/src/main/js/components/SelectList/index.js b/server/sonar-web/src/main/js/components/SelectList/index.js index 0bab53f6145..0855e6106cb 100644 --- a/server/sonar-web/src/main/js/components/SelectList/index.js +++ b/server/sonar-web/src/main/js/components/SelectList/index.js @@ -32,20 +32,22 @@ let showError = null; */ const SelectListCollection = Backbone.Collection.extend({ - - initialize (options) { + initialize(options) { this.options = options; }, - parse (r) { + parse(r) { return this.options.parse.call(this, r); }, - fetch (options) { - const data = $.extend({ - page: 1, - pageSize: 100 - }, options.data || {}); + fetch(options) { + const data = $.extend( + { + page: 1, + pageSize: 100 + }, + options.data || {} + ); const settings = $.extend({}, options, { data }); this.settings = { @@ -56,7 +58,7 @@ const SelectListCollection = Backbone.Collection.extend({ Backbone.Collection.prototype.fetch.call(this, settings); }, - fetchNextPage (options) { + fetchNextPage(options) { if (this.more) { const nextPage = this.settings.data.page + 1; const settings = $.extend(this.settings, options); @@ -68,7 +70,6 @@ const SelectListCollection = Backbone.Collection.extend({ options.error(); } } - }); /* @@ -83,39 +84,43 @@ const SelectListItemView = Backbone.View.extend({ 'change .select-list-list-checkbox': 'toggle' }, - initialize (options) { + initialize(options) { this.listenTo(this.model, 'change', this.render); this.settings = options.settings; }, - render () { + render() { this.$el.html(this.template(this.settings.format(this.model.toJSON()))); this.$('input').prop('name', this.model.get('name')); this.$el.toggleClass('selected', this.model.get('selected')); this.$('.select-list-list-checkbox') - .prop('title', this.model.get('selected') ? - this.settings.tooltips.deselect : - this.settings.tooltips.select) - .prop('checked', this.model.get('selected')); + .prop( + 'title', + this.model.get('selected') ? this.settings.tooltips.deselect : this.settings.tooltips.select + ) + .prop('checked', this.model.get('selected')); if (this.settings.readOnly) { this.$('.select-list-list-checkbox').prop('disabled', true); } }, - remove (postpone) { + remove(postpone) { if (postpone) { const that = this; that.$el.addClass(this.model.get('selected') ? 'added' : 'removed'); - setTimeout(function () { - Backbone.View.prototype.remove.call(that, arguments); - }, 500); + setTimeout( + function() { + Backbone.View.prototype.remove.call(that, arguments); + }, + 500 + ); } else { Backbone.View.prototype.remove.call(this, arguments); } }, - toggle () { + toggle() { const selected = this.model.get('selected'); const that = this; const url = selected ? this.settings.deselectUrl : this.settings.selectUrl; @@ -134,14 +139,17 @@ const SelectListItemView = Backbone.View.extend({ 403: null, 500: null } - }).done(() => { - that.model.set('selected', !selected); - }).fail(jqXHR => { - that.render(); - showError(jqXHR); - }).always(() => { - that.$el.removeClass('progress'); - }); + }) + .done(() => { + that.model.set('selected', !selected); + }) + .fail(jqXHR => { + that.render(); + showError(jqXHR); + }) + .always(() => { + that.$el.removeClass('progress'); + }); } }); @@ -158,7 +166,7 @@ const SelectListView = Backbone.View.extend({ 'click .select-list-control-button[name=all]': 'showAll' }, - initialize (options) { + initialize(options) { this.listenTo(this.collection, 'add', this.renderListItem); this.listenTo(this.collection, 'reset', this.renderList); this.listenTo(this.collection, 'remove', this.removeModel); @@ -166,21 +174,21 @@ const SelectListView = Backbone.View.extend({ this.settings = options.settings; const that = this; - this.showFetchSpinner = function () { + this.showFetchSpinner = function() { that.$listContainer.addClass('loading'); }; - this.hideFetchSpinner = function () { + this.hideFetchSpinner = function() { that.$listContainer.removeClass('loading'); }; - const onScroll = function () { + const onScroll = function() { that.showFetchSpinner(); that.collection.fetchNextPage({ - success () { + success() { that.hideFetchSpinner(); }, - error () { + error() { that.hideFetchSpinner(); } }); @@ -188,23 +196,19 @@ const SelectListView = Backbone.View.extend({ this.onScroll = throttle(onScroll, 1000); }, - render () { + render() { const that = this; - const keyup = function () { + const keyup = function() { that.search(); }; - this.$el.html(this.template(this.settings.labels)) - .width(this.settings.width); + this.$el.html(this.template(this.settings.labels)).width(this.settings.width); this.$listContainer = this.$('.select-list-list-container'); if (!this.settings.readOnly) { - this.$listContainer - .height(this.settings.height) - .css('overflow', 'auto') - .on('scroll', () => { - that.scroll(); - }); + this.$listContainer.height(this.settings.height).css('overflow', 'auto').on('scroll', () => { + that.scroll(); + }); } else { this.$listContainer.addClass('select-list-list-container-readonly'); } @@ -212,27 +216,28 @@ const SelectListView = Backbone.View.extend({ this.$list = this.$('.select-list-list'); const searchInput = this.$('.select-list-search-control input') - .on('keyup', debounce(keyup, 250)) - .on('search', debounce(keyup, 250)); + .on('keyup', debounce(keyup, 250)) + .on('search', debounce(keyup, 250)); if (this.settings.focusSearch) { - setTimeout(() => { - searchInput.focus(); - }, 250); + setTimeout( + () => { + searchInput.focus(); + }, + 250 + ); } this.listItemViews = []; - showError = function (jqXHR) { + showError = function(jqXHR) { let message = translate('default_error_message'); if (jqXHR != null && jqXHR.responseJSON != null && jqXHR.responseJSON.errors != null) { message = jqXHR.responseJSON.errors.map(e => e.msg).join('. '); } that.$el.prevAll('.alert').remove(); - $('<div>') - .addClass('alert alert-danger').text(message) - .insertBefore(that.$el); + $('<div>').addClass('alert alert-danger').text(message).insertBefore(that.$el); }; if (this.settings.readOnly) { @@ -240,7 +245,7 @@ const SelectListView = Backbone.View.extend({ } }, - renderList () { + renderList() { this.listItemViews.forEach(view => { view.remove(); }); @@ -253,7 +258,7 @@ const SelectListView = Backbone.View.extend({ this.$listContainer.scrollTop(0); }, - renderListItem (item) { + renderListItem(item) { const itemView = new SelectListItemView({ model: item, settings: this.settings @@ -263,32 +268,34 @@ const SelectListView = Backbone.View.extend({ itemView.render(); }, - renderEmpty () { + renderEmpty() { this.$list.append(`<li class="empty-message">${this.settings.labels.noResults}</li>`); }, - confirmFilter (model) { + confirmFilter(model) { if (this.currentFilter !== 'all') { this.collection.remove(model); } }, - removeModel (model, collection, options) { + removeModel(model, collection, options) { this.listItemViews[options.index].remove(true); this.listItemViews.splice(options.index, 1); }, - filterBySelection (filter) { + filterBySelection(filter) { const that = this; - filter = this.currentFilter = filter || this.currentFilter; + filter = (this.currentFilter = filter || this.currentFilter); if (filter != null) { this.$('.select-list-check-control').toggleClass('disabled', false); this.$('.select-list-search-control').toggleClass('disabled', true); this.$('.select-list-search-control input').val(''); - this.$('.select-list-control-button').removeClass('active') - .filter(`[name=${filter}]`).addClass('active'); + this.$('.select-list-control-button') + .removeClass('active') + .filter(`[name=${filter}]`) + .addClass('active'); this.showFetchSpinner(); @@ -296,7 +303,7 @@ const SelectListView = Backbone.View.extend({ url: this.settings.searchUrl, reset: true, data: { selected: filter }, - success () { + success() { that.hideFetchSpinner(); }, error: showError @@ -304,19 +311,19 @@ const SelectListView = Backbone.View.extend({ } }, - showSelected () { + showSelected() { this.filterBySelection('selected'); }, - showDeselected () { + showDeselected() { this.filterBySelection('deselected'); }, - showAll () { + showAll() { this.filterBySelection('all'); }, - search () { + search() { const query = this.$('.select-list-search-control input').val(); const hasQuery = query.length > 0; const that = this; @@ -335,7 +342,7 @@ const SelectListView = Backbone.View.extend({ data, url: this.settings.searchUrl, reset: true, - success () { + success() { that.hideFetchSpinner(); }, error: showError @@ -345,31 +352,30 @@ const SelectListView = Backbone.View.extend({ } }, - searchByQuery (query) { + searchByQuery(query) { this.$('.select-list-search-control input').val(query); this.search(); }, - clearSearch () { + clearSearch() { this.filterBySelection(); }, - scroll () { + scroll() { const scrollBottom = this.$listContainer.scrollTop() >= - this.$list[0].scrollHeight - this.$listContainer.outerHeight(); + this.$list[0].scrollHeight - this.$listContainer.outerHeight(); if (scrollBottom && this.collection.more) { this.onScroll(); } } - }); /* * SelectList Entry Point */ -window.SelectList = function (options) { +window.SelectList = function(options) { this.settings = $.extend(window.SelectList.defaults, options); this.collection = new SelectListCollection({ @@ -391,12 +397,12 @@ window.SelectList = function (options) { * SelectList API Methods */ -window.SelectList.prototype.filter = function (filter) { +window.SelectList.prototype.filter = function(filter) { this.view.filterBySelection(filter); return this; }; -window.SelectList.prototype.search = function (query) { +window.SelectList.prototype.search = function(query) { this.view.searchByQuery(query); return this; }; @@ -412,11 +418,11 @@ window.SelectList.defaults = { readOnly: false, focusSearch: true, - format (item) { + format(item) { return item.value; }, - parse (r) { + parse(r) { this.more = r.more; return r.results; }, diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.js index e7b999e3231..0acd2dc123d 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewer.js @@ -39,9 +39,10 @@ const onReceiveComponent = (component: { key: string, canMarkAsFavorite: boolean } }; -const onReceiveIssues = (issues: Array<*>) => dispatch => { - dispatch(receiveIssues(issues)); -}; +const onReceiveIssues = (issues: Array<*>) => + dispatch => { + dispatch(receiveIssues(issues)); + }; const mapDispatchToProps = { onReceiveComponent, onReceiveIssues }; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js index 96e7641e525..d902f2c4b7f 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.js @@ -136,7 +136,7 @@ export default class SourceViewerBase extends React.Component { loadSources }; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = { displayDuplications: false, @@ -161,18 +161,18 @@ export default class SourceViewerBase extends React.Component { }; } - componentDidMount () { + componentDidMount() { this.mounted = true; this.fetchComponent(); } - componentWillReceiveProps (nextProps: Props) { + componentWillReceiveProps(nextProps: Props) { if (nextProps.onIssueSelect != null && nextProps.selectedIssue !== this.props.selectedIssue) { this.setState({ selectedIssue: nextProps.selectedIssue, selectedIssueLocation: null }); } } - componentDidUpdate (prevProps: Props, prevState: State) { + componentDidUpdate(prevProps: Props, prevState: State) { if (prevProps.component !== this.props.component) { this.fetchComponent(); } else if ( @@ -191,11 +191,11 @@ export default class SourceViewerBase extends React.Component { } } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - scrollToLine (line: number) { + scrollToLine(line: number) { const lineElement = this.node.querySelector( `.source-line-code[data-line-number="${line}"] .source-line-issue-locations` ); @@ -204,11 +204,11 @@ export default class SourceViewerBase extends React.Component { } } - computeCoverageStatus (lines: Array<SourceLine>): Array<SourceLine> { + computeCoverageStatus(lines: Array<SourceLine>): Array<SourceLine> { return lines.map(line => ({ ...line, coverageStatus: getCoverageStatus(line) })); } - isLineOutsideOfRange (lineNumber: number) { + isLineOutsideOfRange(lineNumber: number) { const { sources } = this.state; if (sources != null && sources.length > 0) { const firstLine = sources[0]; @@ -219,7 +219,7 @@ export default class SourceViewerBase extends React.Component { } } - fetchComponent () { + fetchComponent() { this.setState({ loading: true }); const loadIssues = (component, sources) => { @@ -277,7 +277,7 @@ export default class SourceViewerBase extends React.Component { this.props.loadComponent(this.props.component).then(onResolve, onFailLoadComponent); } - fetchSources () { + fetchSources() { this.loadSources().then(sources => { if (this.mounted) { const finalSources = sources.slice(0, LINES); @@ -297,7 +297,7 @@ export default class SourceViewerBase extends React.Component { }); } - loadSources () { + loadSources() { return new Promise((resolve, reject) => { const onFailLoadSources = ({ response }) => { // TODO handle other statuses @@ -315,8 +315,8 @@ export default class SourceViewerBase extends React.Component { const to = this.props.aroundLine ? this.props.aroundLine + LINES / 2 + 1 : LINES + 1; return this.props - .loadSources(this.props.component, from, to) - .then(sources => resolve(sources), onFailLoadSources); + .loadSources(this.props.component, from, to) + .then(sources => resolve(sources), onFailLoadSources); }); } @@ -388,7 +388,7 @@ export default class SourceViewerBase extends React.Component { }); }; - getInitialLocationsPanelHeight () { + getInitialLocationsPanelHeight() { try { const rawValue = window.localStorage.getItem(LOCATIONS_PANEL_HEIGHT_LOCAL_STORAGE_KEY); if (!rawValue) { @@ -401,7 +401,7 @@ export default class SourceViewerBase extends React.Component { } } - storeLocationsPanelHeight (height: number) { + storeLocationsPanelHeight(height: number) { window.localStorage.setItem(LOCATIONS_PANEL_HEIGHT_LOCAL_STORAGE_KEY, height); } @@ -461,7 +461,7 @@ export default class SourceViewerBase extends React.Component { } }; - displayLinePopup (line: number, element: HTMLElement) { + displayLinePopup(line: number, element: HTMLElement) { const popup = new LineActionsPopupView({ line, triggerEl: element, @@ -532,7 +532,7 @@ export default class SourceViewerBase extends React.Component { })); }; - renderCode (sources: Array<SourceLine>) { + renderCode(sources: Array<SourceLine>) { const hasSourcesBefore = sources.length > 0 && sources[0].line > 1; return ( <SourceViewerCode @@ -571,11 +571,12 @@ export default class SourceViewerBase extends React.Component { selectedIssue={this.state.selectedIssue} selectedIssueLocation={this.state.selectedIssueLocation} sources={sources} - symbolsByLine={this.state.symbolsByLine}/> + symbolsByLine={this.state.symbolsByLine} + /> ); } - render () { + render() { const { component, loading } = this.state; if (loading) { @@ -607,7 +608,8 @@ export default class SourceViewerBase extends React.Component { <SourceViewerHeader component={this.state.component} openNewWindow={this.openNewWindow} - showMeasures={this.showMeasures}/> + showMeasures={this.showMeasures} + /> {this.state.notAccessible && <div className="alert alert-warning spacer-top"> {translate('code_viewer.no_source_code_displayed_due_to_security')} @@ -620,7 +622,8 @@ export default class SourceViewerBase extends React.Component { issue={selectedIssueObj} onResize={this.handleLocationsPanelResize} onSelectLocation={this.handleSelectIssueLocation} - selectedLocation={this.state.selectedIssueLocation}/>} + selectedLocation={this.state.selectedIssueLocation} + />} </div> ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js index d0b5eff25b0..9f709829891 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js @@ -76,19 +76,19 @@ export default class SourceViewerCode extends React.PureComponent { symbolsByLine: { [number]: Array<string> } }; - getDuplicationsForLine (line: SourceLine) { + getDuplicationsForLine(line: SourceLine) { return this.props.duplicationsByLine[line.line] || EMPTY_ARRAY; } - getIssuesForLine (line: SourceLine): Array<string> { + getIssuesForLine(line: SourceLine): Array<string> { return this.props.issuesByLine[line.line] || EMPTY_ARRAY; } - getIssueLocationsForLine (line: SourceLine) { + getIssueLocationsForLine(line: SourceLine) { return this.props.issueLocationsByLine[line.line] || EMPTY_ARRAY; } - getSecondaryIssueLocationsForLine (line: SourceLine, issueKey: string) { + getSecondaryIssueLocationsForLine(line: SourceLine, issueKey: string) { const index = this.props.issueSecondaryLocationsByIssueByLine; if (index[issueKey] == null) { return EMPTY_ARRAY; @@ -96,7 +96,7 @@ export default class SourceViewerCode extends React.PureComponent { return index[issueKey][line.line] || EMPTY_ARRAY; } - getSecondaryIssueLocationMessagesForLine (line: SourceLine, issueKey: string) { + getSecondaryIssueLocationMessagesForLine(line: SourceLine, issueKey: string) { return this.props.issueSecondaryLocationMessagesByIssueByLine[issueKey][line.line] || EMPTY_ARRAY; } @@ -176,11 +176,12 @@ export default class SourceViewerCode extends React.PureComponent { secondaryIssueLocations={secondaryIssueLocations} secondaryIssueLocationMessages={secondaryIssueLocationMessages} selectedIssue={optimizedSelectedIssue} - selectedIssueLocation={optimizedSelectedIssueLocation}/> + selectedIssueLocation={optimizedSelectedIssueLocation} + /> ); }; - render () { + render() { const { sources } = this.props; const hasCoverage = sources.some(s => s.coverageStatus != null); @@ -196,14 +197,15 @@ export default class SourceViewerCode extends React.PureComponent { <div className="source-viewer-more-code"> {this.props.loadingSourcesBefore ? <div className="js-component-viewer-loading-before"> - <i className="spinner"/> + <i className="spinner" /> <span className="note spacer-left"> {translate('source_viewer.loading_more_code')} </span> </div> : <button className="js-component-viewer-source-before" - onClick={this.props.loadSourcesBefore}> + onClick={this.props.loadSourcesBefore} + > {translate('source_viewer.load_more_code')} </button>} </div>} @@ -235,14 +237,15 @@ export default class SourceViewerCode extends React.PureComponent { <div className="source-viewer-more-code"> {this.props.loadingSourcesAfter ? <div className="js-component-viewer-loading-after"> - <i className="spinner"/> + <i className="spinner" /> <span className="note spacer-left"> {translate('source_viewer.loading_more_code')} </span> </div> : <button className="js-component-viewer-source-after" - onClick={this.props.loadSourcesAfter}> + onClick={this.props.loadSourcesAfter} + > {translate('source_viewer.load_more_code')} </button>} </div>} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.js index af05c46d954..97ccf3a15bf 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerHeader.js @@ -67,7 +67,7 @@ export default class SourceViewerHeader extends React.PureComponent { Workspace.openComponent({ key }); }; - render () { + render() { const { key, measures, @@ -90,25 +90,25 @@ export default class SourceViewerHeader extends React.PureComponent { <div className="component-name"> <div className="component-name-parent"> <Link to={getProjectUrl(project)} className="link-with-icon"> - <QualifierIcon qualifier="TRK"/> <span>{projectName}</span> + <QualifierIcon qualifier="TRK" /> <span>{projectName}</span> </Link> </div> {subProject != null && <div className="component-name-parent"> <Link to={getProjectUrl(subProject)} className="link-with-icon"> - <QualifierIcon qualifier="BRC"/> <span>{subProjectName}</span> + <QualifierIcon qualifier="BRC" /> <span>{subProjectName}</span> </Link> </div>} <div className="component-name-path"> - <QualifierIcon qualifier={q}/> + <QualifierIcon qualifier={q} /> {' '} <span>{collapsedDirFromPath(path)}</span> <span className="component-name-file">{fileFromPath(path)}</span> {this.props.component.canMarkAsFavorite && - <FavoriteContainer className="component-name-favorite" componentKey={key}/>} + <FavoriteContainer className="component-name-favorite" componentKey={key} />} </div> </div> </div> @@ -117,7 +117,8 @@ export default class SourceViewerHeader extends React.PureComponent { <a className="js-actions icon-list dropdown-toggle" data-toggle="dropdown" - title={translate('component_viewer.more_actions')}/> + title={translate('component_viewer.more_actions')} + /> <ul className="dropdown-menu dropdown-menu-right"> <li> <a className="js-measures" href="#" onClick={this.showMeasures}> @@ -169,10 +170,11 @@ export default class SourceViewerHeader extends React.PureComponent { <Link to={getIssuesUrl({ resolved: 'false', componentKeys: key })} className="source-viewer-header-external-link" - target="_blank"> + target="_blank" + > {measures.issues != null ? formatMeasure(measures.issues, 'SHORT_INT') : 0} {' '} - <i className="icon-detach"/> + <i className="icon-detach" /> </Link> </span> <span className="source-viewer-header-measure-label"> diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js index abe72568770..acd8abb398b 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js @@ -49,24 +49,24 @@ export default class SourceViewerIssueLocations extends React.Component { rootNode: HTMLElement; state: State; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = { fixed: true, locationBlink: false }; this.handleScroll = throttle(this.handleScroll, 50); } - componentDidMount () { + componentDidMount() { this.bindShortcuts(); this.listenScroll(); } - componentWillReceiveProps (nextProps: Props) { + componentWillReceiveProps(nextProps: Props) { if (nextProps.selectedLocation !== this.props.selectedLocation) { this.setState({ locationBlink: false }); } } - componentDidUpdate (prevProps: Props) { + componentDidUpdate(prevProps: Props) { if ( prevProps.selectedLocation !== this.props.selectedLocation && this.props.selectedLocation != null @@ -75,24 +75,24 @@ export default class SourceViewerIssueLocations extends React.Component { } } - componentWillUnmount () { + componentWillUnmount() { this.unbindShortcuts(); this.unlistenScroll(); } - bindShortcuts () { + bindShortcuts() { document.addEventListener('keydown', this.handleKeyPress); } - unbindShortcuts () { + unbindShortcuts() { document.removeEventListener('keydown', this.handleKeyPress); } - listenScroll () { + listenScroll() { window.addEventListener('scroll', this.handleScroll); } - unlistenScroll () { + unlistenScroll() { window.removeEventListener('scroll', this.handleScroll); } @@ -128,7 +128,7 @@ export default class SourceViewerIssueLocations extends React.Component { this.props.onResize(height); }; - scrollToLocation () { + scrollToLocation() { const { selectedLocation } = this.props; if (selectedLocation != null) { const key = `${selectedLocation.flowIndex}-${selectedLocation.locationIndex}`; @@ -139,7 +139,7 @@ export default class SourceViewerIssueLocations extends React.Component { } } - handleSelectPrev () { + handleSelectPrev() { const { issue, selectedLocation } = this.props; if (!selectedLocation) { if (issue.flows.length > 0) { @@ -163,7 +163,7 @@ export default class SourceViewerIssueLocations extends React.Component { } } - handleSelectNext () { + handleSelectNext() { const { issue, selectedLocation } = this.props; if (!selectedLocation) { if (issue.flows.length > 0) { @@ -207,11 +207,11 @@ export default class SourceViewerIssueLocations extends React.Component { } }; - reverseLocations (locations: Array<*>) { + reverseLocations(locations: Array<*>) { return [...locations].reverse(); } - isLocationSelected (flowIndex: number, locationIndex: number) { + isLocationSelected(flowIndex: number, locationIndex: number) { const { selectedLocation } = this.props; if (selectedLocation == null) { return false; @@ -221,7 +221,7 @@ export default class SourceViewerIssueLocations extends React.Component { } } - handleLocationClick (flowIndex: number, locationIndex: number, e: SyntheticInputEvent) { + handleLocationClick(flowIndex: number, locationIndex: number, e: SyntheticInputEvent) { e.preventDefault(); this.props.onSelectLocation(flowIndex, locationIndex); } @@ -251,7 +251,8 @@ export default class SourceViewerIssueLocations extends React.Component { this, flowIndex, locations.length - locationIndex - 1 - )}> + )} + > {displayIndex && <strong>{locationIndex + 1}: </strong>} {location.msg} </a> @@ -259,7 +260,7 @@ export default class SourceViewerIssueLocations extends React.Component { ); }; - render () { + render() { const { flows } = this.props.issue; const { height } = this.props; @@ -271,12 +272,14 @@ export default class SourceViewerIssueLocations extends React.Component { <div ref={node => this.rootNode = node} className="source-issue-locations" - style={{ width, height }}> + style={{ width, height }} + > <div ref={node => this.fixedNode = node} className={className} - style={{ width, height }}> - <header className="source-issue-locations-header"/> + style={{ width, height }} + > + <header className="source-issue-locations-header" /> <div className="source-issue-locations-shortcuts"> <span className="shortcut-button">Alt</span> {' + '} @@ -289,18 +292,17 @@ export default class SourceViewerIssueLocations extends React.Component { <ul ref={node => this.node = node} className="source-issue-locations-list" - style={{ height: height - 15 }}> + style={{ height: height - 15 }} + > {flows.map( (flow, flowIndex) => flow.locations != null && - this.reverseLocations( - flow.locations - ).map((location, locationIndex) => + this.reverseLocations(flow.locations).map((location, locationIndex) => this.renderLocation(location, flowIndex, locationIndex, flow.locations || [])) )} </ul> <DraggableCore axis="y" onDrag={this.handleDrag} offsetParent={document.body}> - <div className="workspace-viewer-resize"/> + <div className="workspace-viewer-resize" /> </DraggableCore> </div> </div> diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js index c9da31d1cf8..9303cfa53c2 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.js @@ -87,7 +87,7 @@ export default class Line extends React.PureComponent { } }; - render () { + render() { const { line, duplications, duplicationsCount, filtered } = this.props; const className = classNames('source-line', { 'source-line-highlighted': this.props.highlighted, @@ -98,18 +98,19 @@ export default class Line extends React.PureComponent { return ( <TooltipsContainer> <tr className={className} data-line-number={line.line}> - <LineNumber line={line} onClick={this.props.onClick}/> + <LineNumber line={line} onClick={this.props.onClick} /> <LineSCM line={line} onClick={this.props.onSCMClick} - previousLine={this.props.previousLine}/> + previousLine={this.props.previousLine} + /> {this.props.displayCoverage && - <LineCoverage line={line} onClick={this.props.onCoverageClick}/>} + <LineCoverage line={line} onClick={this.props.onCoverageClick} />} {this.props.displayDuplications && - <LineDuplications line={line} onClick={this.props.loadDuplications}/>} + <LineDuplications line={line} onClick={this.props.loadDuplications} />} {times(duplicationsCount).map(index => ( <LineDuplicationBlock @@ -117,7 +118,8 @@ export default class Line extends React.PureComponent { index={index} key={index} line={this.props.line} - onClick={this.props.onDuplicationClick}/> + onClick={this.props.onDuplicationClick} + /> ))} {this.props.displayIssues && @@ -125,11 +127,12 @@ export default class Line extends React.PureComponent { <LineIssuesIndicatorContainer issueKeys={this.props.issues} line={line} - onClick={this.handleIssuesIndicatorClick}/>} + onClick={this.handleIssuesIndicatorClick} + />} {this.props.displayFiltered && <td className="source-meta source-line-filtered-container" data-line-number={line.line}> - <div className="source-line-bar"/> + <div className="source-line-bar" /> </td>} <LineCode @@ -144,7 +147,8 @@ export default class Line extends React.PureComponent { secondaryIssueLocations={this.props.secondaryIssueLocations} selectedIssue={this.props.selectedIssue} selectedIssueLocation={this.props.selectedIssueLocation} - showIssues={this.props.openIssues || this.props.displayAllIssues}/> + showIssues={this.props.openIssues || this.props.displayAllIssues} + /> </tr> </TooltipsContainer> ); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.js index 840623fed9f..f6cbb5f1446 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.js @@ -61,18 +61,18 @@ export default class LineCode extends React.PureComponent { state: State; symbols: NodeList<HTMLElement>; - constructor (props: Props) { + constructor(props: Props) { super(props); this.state = { tokens: splitByTokens(props.line.code || '') }; } - componentDidMount () { + componentDidMount() { this.attachEvents(); } - componentWillReceiveProps (nextProps: Props) { + componentWillReceiveProps(nextProps: Props) { if (nextProps.line.code !== this.props.line.code) { this.setState({ tokens: splitByTokens(nextProps.line.code || '') @@ -80,26 +80,26 @@ export default class LineCode extends React.PureComponent { } } - componentWillUpdate () { + componentWillUpdate() { this.detachEvents(); } - componentDidUpdate () { + componentDidUpdate() { this.attachEvents(); } - componentWillUnmount () { + componentWillUnmount() { this.detachEvents(); } - attachEvents () { + attachEvents() { this.symbols = this.codeNode.querySelectorAll('.sym'); for (const symbol of this.symbols) { symbol.addEventListener('click', this.handleSymbolClick); } } - detachEvents () { + detachEvents() { if (this.symbols) { for (const symbol of this.symbols) { symbol.removeEventListener('click', this.handleSymbolClick); @@ -124,7 +124,7 @@ export default class LineCode extends React.PureComponent { this.props.onLocationSelect(flowIndex, locationIndex); }; - isSecondaryIssueLocationSelected (location: IndexedIssueLocation | IndexedIssueLocationMessage) { + isSecondaryIssueLocationSelected(location: IndexedIssueLocation | IndexedIssueLocationMessage) { const { selectedIssueLocation } = this.props; if (selectedIssueLocation == null) { return false; @@ -148,14 +148,15 @@ export default class LineCode extends React.PureComponent { className={className} title={location.msg} onClick={e => - this.handleLocationMessageClick(e, location.flowIndex, location.locationIndex)}> + this.handleLocationMessageClick(e, location.flowIndex, location.locationIndex)} + > {location.index && <strong>{location.index}: </strong>} {location.msg ? limitString(location.msg) : ''} </a> ); }; - renderSecondaryIssueLocationMessages (locations: Array<IndexedIssueLocationMessage>) { + renderSecondaryIssueLocationMessages(locations: Array<IndexedIssueLocationMessage>) { return ( <div className="source-line-issue-locations"> {locations.map(this.renderSecondaryIssueLocationMessage)} @@ -163,7 +164,7 @@ export default class LineCode extends React.PureComponent { ); } - render () { + render() { const { highlightedSymbol, issueKeys, @@ -207,7 +208,7 @@ export default class LineCode extends React.PureComponent { return ( <td className={className} data-line-number={line.line}> <div className="source-line-code-inner"> - <pre ref={node => this.codeNode = node} dangerouslySetInnerHTML={{ __html: finalCode }}/> + <pre ref={node => this.codeNode = node} dangerouslySetInnerHTML={{ __html: finalCode }} /> {secondaryIssueLocationMessages != null && secondaryIssueLocationMessages.length > 0 && this.renderSecondaryIssueLocationMessages(secondaryIssueLocationMessages)} @@ -217,7 +218,8 @@ export default class LineCode extends React.PureComponent { <LineIssuesList issueKeys={issueKeys} onIssueClick={onIssueSelect} - selectedIssue={selectedIssue}/>} + selectedIssue={selectedIssue} + />} </td> ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineCoverage.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineCoverage.js index 55e7aad96cd..76b8502548b 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineCoverage.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineCoverage.js @@ -35,7 +35,7 @@ export default class LineCoverage extends React.PureComponent { this.props.onClick(this.props.line, e.target); }; - render () { + render() { const { line } = this.props; const className = 'source-meta source-line-coverage' + (line.coverageStatus != null ? ` source-line-${line.coverageStatus}` : ''); @@ -51,8 +51,9 @@ export default class LineCoverage extends React.PureComponent { data-toggle={line.coverageStatus != null ? 'tooltip' : undefined} role={line.coverageStatus != null ? 'button' : undefined} tabIndex={line.coverageStatus != null ? 0 : undefined} - onClick={line.coverageStatus != null ? this.handleClick : undefined}> - <div className="source-line-bar"/> + onClick={line.coverageStatus != null ? this.handleClick : undefined} + > + <div className="source-line-bar" /> </td> ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.js index 021be8e1e7c..bfe7029f601 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplicationBlock.js @@ -38,7 +38,7 @@ export default class LineDuplicationBlock extends React.PureComponent { this.props.onClick(this.props.index, this.props.line.line); }; - render () { + render() { const { duplicated, index, line } = this.props; const className = classNames('source-meta', 'source-line-duplications-extra', { 'source-line-duplicated': duplicated @@ -55,8 +55,9 @@ export default class LineDuplicationBlock extends React.PureComponent { data-toggle={duplicated ? 'tooltip' : undefined} role={duplicated ? 'button' : undefined} tabIndex={duplicated ? '0' : undefined} - onClick={duplicated ? this.handleClick : undefined}> - <div className="source-line-bar"/> + onClick={duplicated ? this.handleClick : undefined} + > + <div className="source-line-bar" /> </td> ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplications.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplications.js index 941227de0dc..5828a48ff60 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplications.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineDuplications.js @@ -36,7 +36,7 @@ export default class LineDuplications extends React.PureComponent { this.props.onClick(this.props.line, e.target); }; - render () { + render() { const { line } = this.props; const className = classNames('source-meta', 'source-line-duplications', { 'source-line-duplicated': line.duplicated @@ -51,8 +51,9 @@ export default class LineDuplications extends React.PureComponent { data-toggle={line.duplicated ? 'tooltip' : undefined} role={line.duplicated ? 'button' : undefined} tabIndex={line.duplicated ? 0 : undefined} - onClick={line.duplicated ? this.handleClick : undefined}> - <div className="source-line-bar"/> + onClick={line.duplicated ? this.handleClick : undefined} + > + <div className="source-line-bar" /> </td> ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.js index 200174283cc..9e8f3eec05d 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesIndicator.js @@ -38,7 +38,7 @@ export default class LineIssuesIndicator extends React.PureComponent { this.props.onClick(); }; - render () { + render() { const { issues, line } = this.props; const hasIssues = issues.length > 0; const className = classNames('source-meta', 'source-line-issues', { @@ -52,8 +52,9 @@ export default class LineIssuesIndicator extends React.PureComponent { data-line-number={line.line} role={hasIssues ? 'button' : undefined} tabIndex={hasIssues ? '0' : undefined} - onClick={hasIssues ? this.handleClick : undefined}> - {mostImportantIssue != null && <SeverityIcon severity={mostImportantIssue.severity}/>} + onClick={hasIssues ? this.handleClick : undefined} + > + {mostImportantIssue != null && <SeverityIcon severity={mostImportantIssue.severity} />} {issues.length > 1 && <span className="source-line-issues-counter">{issues.length}</span>} </td> ); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesList.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesList.js index 0238b021891..ca89ab51fae 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesList.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineIssuesList.js @@ -30,7 +30,7 @@ type Props = { export default class LineIssuesList extends React.PureComponent { props: Props; - render () { + render() { const { issueKeys, onIssueClick, selectedIssue } = this.props; return ( @@ -40,7 +40,8 @@ export default class LineIssuesList extends React.PureComponent { issueKey={issueKey} key={issueKey} onClick={onIssueClick} - selected={selectedIssue === issueKey}/> + selected={selectedIssue === issueKey} + /> ))} </div> ); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.js index a477bfbad6b..6222d6335c1 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineNumber.js @@ -34,7 +34,7 @@ export default class LineNumber extends React.PureComponent { this.props.onClick(this.props.line, e.target); }; - render () { + render() { const { line } = this.props.line; return ( @@ -44,7 +44,8 @@ export default class LineNumber extends React.PureComponent { data-line-number={line ? line : undefined} role={line ? 'button' : undefined} tabIndex={line ? 0 : undefined} - onClick={line ? this.handleClick : undefined}/> + onClick={line ? this.handleClick : undefined} + /> ); } } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.js b/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.js index b856b23bb53..2613f1756a5 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineSCM.js @@ -35,7 +35,7 @@ export default class LineSCM extends React.PureComponent { this.props.onClick(this.props.line, e.target); }; - isSCMChanged (s: SourceLine, p?: SourceLine) { + isSCMChanged(s: SourceLine, p?: SourceLine) { let changed = true; if (p != null && s.scmAuthor != null && p.scmAuthor != null) { changed = s.scmAuthor !== p.scmAuthor || s.scmDate !== p.scmDate; @@ -43,7 +43,7 @@ export default class LineSCM extends React.PureComponent { return changed; } - render () { + render() { const { line, previousLine } = this.props; const clickable = !!line.line; return ( @@ -52,9 +52,10 @@ export default class LineSCM extends React.PureComponent { data-line-number={line.line} role={clickable ? 'button' : undefined} tabIndex={clickable ? 0 : undefined} - onClick={clickable ? this.handleClick : undefined}> + onClick={clickable ? this.handleClick : undefined} + > {this.isSCMChanged(line, previousLine) && - <div className="source-line-scm-inner" data-author={line.scmAuthor}/>} + <div className="source-line-scm-inner" data-author={line.scmAuthor} />} </td> ); } diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCode-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCode-test.js index c174394c33e..fa78dfa5afb 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCode-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCode-test.js @@ -44,7 +44,8 @@ it('render code', () => { secondaryIssueLocationMessages={secondaryIssueLocationMessages} selectedIssue="issue-1" selectedIssueLocation={selectedIssueLocation} - showIssues={true}/> + showIssues={true} + /> ); expect(wrapper).toMatchSnapshot(); }); @@ -71,7 +72,8 @@ it('should handle empty location message', () => { secondaryIssueLocationMessages={secondaryIssueLocationMessages} selectedIssue="issue-1" selectedIssueLocation={selectedIssueLocation} - showIssues={true}/> + showIssues={true} + /> ); expect(wrapper.find('.source-line-issue-locations')).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCoverage-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCoverage-test.js index 5dcee39a040..aacd16d7866 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCoverage-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineCoverage-test.js @@ -25,7 +25,7 @@ import LineCoverage from '../LineCoverage'; it('render covered line', () => { const line = { line: 3, coverageStatus: 'covered' }; const onClick = jest.fn(); - const wrapper = shallow(<LineCoverage line={line} onClick={onClick}/>); + const wrapper = shallow(<LineCoverage line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); click(wrapper); expect(onClick).toHaveBeenCalled(); @@ -34,7 +34,7 @@ it('render covered line', () => { it('render uncovered line', () => { const line = { line: 3, coverageStatus: 'uncovered' }; const onClick = jest.fn(); - const wrapper = shallow(<LineCoverage line={line} onClick={onClick}/>); + const wrapper = shallow(<LineCoverage line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); click(wrapper); expect(onClick).toHaveBeenCalled(); @@ -43,6 +43,6 @@ it('render uncovered line', () => { it('render line with unknown coverage', () => { const line = { line: 3 }; const onClick = jest.fn(); - const wrapper = shallow(<LineCoverage line={line} onClick={onClick}/>); + const wrapper = shallow(<LineCoverage line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplicationBlock-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplicationBlock-test.js index e16dd8b6c0b..cd0baf595d0 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplicationBlock-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplicationBlock-test.js @@ -26,7 +26,7 @@ it('render duplicated line', () => { const line = { line: 3, duplicated: true }; const onClick = jest.fn(); const wrapper = shallow( - <LineDuplicationBlock index={1} duplicated={true} line={line} onClick={onClick}/> + <LineDuplicationBlock index={1} duplicated={true} line={line} onClick={onClick} /> ); expect(wrapper).toMatchSnapshot(); click(wrapper); @@ -37,7 +37,7 @@ it('render not duplicated line', () => { const line = { line: 3, duplicated: false }; const onClick = jest.fn(); const wrapper = shallow( - <LineDuplicationBlock index={1} duplicated={false} line={line} onClick={onClick}/> + <LineDuplicationBlock index={1} duplicated={false} line={line} onClick={onClick} /> ); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplications-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplications-test.js index 1f11c8b9e37..b2aa124a64a 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplications-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineDuplications-test.js @@ -25,7 +25,7 @@ import LineDuplications from '../LineDuplications'; it('render duplicated line', () => { const line = { line: 3, duplicated: true }; const onClick = jest.fn(); - const wrapper = shallow(<LineDuplications line={line} onClick={onClick}/>); + const wrapper = shallow(<LineDuplications line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); click(wrapper); expect(onClick).toHaveBeenCalled(); @@ -34,6 +34,6 @@ it('render duplicated line', () => { it('render not duplicated line', () => { const line = { line: 3, duplicated: false }; const onClick = jest.fn(); - const wrapper = shallow(<LineDuplications line={line} onClick={onClick}/>); + const wrapper = shallow(<LineDuplications line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.js index c2bb88ec66b..65ec7a2fcc6 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesIndicator-test.js @@ -26,7 +26,7 @@ it('render highest severity', () => { const line = { line: 3 }; const issues = [{ severity: 'MINOR' }, { severity: 'CRITICAL' }]; const onClick = jest.fn(); - const wrapper = shallow(<LineIssuesIndicator issues={issues} line={line} onClick={onClick}/>); + const wrapper = shallow(<LineIssuesIndicator issues={issues} line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); click(wrapper); @@ -41,6 +41,6 @@ it('no issues', () => { const line = { line: 3 }; const issues = []; const onClick = jest.fn(); - const wrapper = shallow(<LineIssuesIndicator issues={issues} line={line} onClick={onClick}/>); + const wrapper = shallow(<LineIssuesIndicator issues={issues} line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesList-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesList-test.js index 8f60222fb55..ede9d50241c 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesList-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineIssuesList-test.js @@ -30,7 +30,8 @@ it('render issues list', () => { issueKeys={issueKeys} line={line} onIssueClick={onIssueClick} - selectedIssue="foo"/> + selectedIssue="foo" + /> ); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.js index eb120a25a06..e63328623da 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineNumber-test.js @@ -25,7 +25,7 @@ import LineNumber from '../LineNumber'; it('render line 3', () => { const line = { line: 3 }; const onClick = jest.fn(); - const wrapper = shallow(<LineNumber line={line} onClick={onClick}/>); + const wrapper = shallow(<LineNumber line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); click(wrapper); expect(onClick).toHaveBeenCalled(); @@ -34,6 +34,6 @@ it('render line 3', () => { it('render line 0', () => { const line = { line: 0 }; const onClick = jest.fn(); - const wrapper = shallow(<LineNumber line={line} onClick={onClick}/>); + const wrapper = shallow(<LineNumber line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineSCM-test.js b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineSCM-test.js index f1a812d302a..c8d17120169 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineSCM-test.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/__tests__/LineSCM-test.js @@ -26,7 +26,7 @@ it('render scm details', () => { const line = { line: 3, scmAuthor: 'foo', scmDate: '2017-01-01' }; const previousLine = { line: 2, scmAuthor: 'bar', scmDate: '2017-01-02' }; const onClick = jest.fn(); - const wrapper = shallow(<LineSCM line={line} onClick={onClick} previousLine={previousLine}/>); + const wrapper = shallow(<LineSCM line={line} onClick={onClick} previousLine={previousLine} />); expect(wrapper).toMatchSnapshot(); click(wrapper); expect(onClick).toHaveBeenCalled(); @@ -35,7 +35,7 @@ it('render scm details', () => { it('render scm details for the first line', () => { const line = { line: 3, scmAuthor: 'foo', scmDate: '2017-01-01' }; const onClick = jest.fn(); - const wrapper = shallow(<LineSCM line={line} onClick={onClick}/>); + const wrapper = shallow(<LineSCM line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); }); @@ -43,13 +43,13 @@ it('does not render scm details', () => { const line = { line: 3, scmAuthor: 'foo', scmDate: '2017-01-01' }; const previousLine = { line: 2, scmAuthor: 'foo', scmDate: '2017-01-01' }; const onClick = jest.fn(); - const wrapper = shallow(<LineSCM line={line} onClick={onClick} previousLine={previousLine}/>); + const wrapper = shallow(<LineSCM line={line} onClick={onClick} previousLine={previousLine} />); expect(wrapper).toMatchSnapshot(); }); it('does not allow to click', () => { const line = { scmAuthor: 'foo', scmDate: '2017-01-01' }; const onClick = jest.fn(); - const wrapper = shallow(<LineSCM line={line} onClick={onClick}/>); + const wrapper = shallow(<LineSCM line={line} onClick={onClick} />); expect(wrapper).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.js b/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.js index c448c519b56..c742f2b0d4c 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.js @@ -118,6 +118,6 @@ export const highlightIssueLocations = ( export const generateHTML = (tokens: Tokens): string => { return tokens - .map(token => `<span class="${token.className}">${escapeHtml(token.text)}</span>`) - .join(''); + .map(token => `<span class="${token.className}">${escapeHtml(token.text)}</span>`) + .join(''); }; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js b/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js index 145d5dbeb47..e8dd4f0f23c 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/popups/coverage-popup.js @@ -29,19 +29,19 @@ export default Popup.extend({ 'click a[data-key]': 'goToFile' }, - onRender () { + onRender() { Popup.prototype.onRender.apply(this, arguments); this.$('.bubble-popup-container').isolatedScroll(); }, - goToFile (e) { + goToFile(e) { e.stopPropagation(); const key = $(e.currentTarget).data('key'); const Workspace = require('../../workspace/main').default; Workspace.openComponent({ key }); }, - serializeData () { + serializeData() { const row = this.options.line || {}; const tests = groupBy(this.options.tests, 'fileKey'); const testFiles = Object.keys(tests).map(fileKey => { diff --git a/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js b/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js index d8ef03e1009..3ca962bca6c 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/popups/duplication-popup.js @@ -30,7 +30,7 @@ export default Popup.extend({ 'click a[data-key]': 'goToFile' }, - goToFile (e) { + goToFile(e) { e.stopPropagation(); const key = $(e.currentTarget).data('key'); const line = $(e.currentTarget).data('line'); @@ -38,7 +38,7 @@ export default Popup.extend({ Workspace.openComponent({ key, line }); }, - serializeData () { + serializeData() { const that = this; const groupedBlocks = groupBy(this.options.blocks, '_ref'); let duplications = Object.keys(groupedBlocks).map(fileRef => { diff --git a/server/sonar-web/src/main/js/components/SourceViewer/popups/line-actions-popup.js b/server/sonar-web/src/main/js/components/SourceViewer/popups/line-actions-popup.js index e65d748e0d1..a191971e936 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/popups/line-actions-popup.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/popups/line-actions-popup.js @@ -27,7 +27,7 @@ export default Popup.extend({ 'click .js-get-permalink': 'getPermalink' }, - getPermalink (e) { + getPermalink(e) { e.preventDefault(); const { component, line } = this.options; const url = `${window.baseUrl}/component/index?id=${encodeURIComponent(component.key)}&line=${line}`; diff --git a/server/sonar-web/src/main/js/components/SourceViewer/popups/scm-popup.js b/server/sonar-web/src/main/js/components/SourceViewer/popups/scm-popup.js index 06cbf45e182..04524f9ce9d 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/popups/scm-popup.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/popups/scm-popup.js @@ -24,19 +24,19 @@ export default Popup.extend({ template: Template, events: { - 'click': 'onClick' + click: 'onClick' }, - onRender () { + onRender() { Popup.prototype.onRender.apply(this, arguments); this.$('.bubble-popup-container').isolatedScroll(); }, - onClick (e) { + onClick(e) { e.stopPropagation(); }, - serializeData () { + serializeData() { return { ...Popup.prototype.serializeData.apply(this, arguments), line: this.options.line diff --git a/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js b/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js index 6dee58b4c80..0ceca9b9952 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js @@ -31,7 +31,7 @@ export default ModalView.extend({ template: Template, testsOrder: ['ERROR', 'FAILURE', 'OK', 'SKIPPED'], - initialize () { + initialize() { this.testsScroll = 0; const requests = [this.requestMeasures(), this.requestIssues()]; if (this.options.component.q === 'UTS') { @@ -40,7 +40,7 @@ export default ModalView.extend({ Promise.all(requests).then(() => this.render()); }, - events () { + events() { return { ...ModalView.prototype.events.apply(this, arguments), 'click .js-sort-tests-by-duration': 'sortTestsByDuration', @@ -51,8 +51,8 @@ export default ModalView.extend({ }; }, - initPieChart () { - const trans = function (left, top) { + initPieChart() { + const trans = function(left, top) { return `translate(${left}, ${top})`; }; @@ -63,46 +63,32 @@ export default ModalView.extend({ baseColor: '#e6e6e6' }; - this.$('.js-pie-chart').each(function () { - const data = [ - $(this).data('value'), - $(this).data('max') - $(this).data('value') - ]; + this.$('.js-pie-chart').each(function() { + const data = [$(this).data('value'), $(this).data('max') - $(this).data('value')]; const options = { ...defaults, ...$(this).data() }; const radius = options.size / 2; const container = d3.select(this); - const svg = container.append('svg') - .attr('width', options.size) - .attr('height', options.size); - const plot = svg.append('g') - .attr('transform', trans(radius, radius)); - const arc = d3.svg.arc() - .innerRadius(radius - options.thickness) - .outerRadius(radius); - const pie = d3.layout.pie() - .sort(null) - .value(d => d); - const colors = function (i) { + const svg = container.append('svg').attr('width', options.size).attr('height', options.size); + const plot = svg.append('g').attr('transform', trans(radius, radius)); + const arc = d3.svg.arc().innerRadius(radius - options.thickness).outerRadius(radius); + const pie = d3.layout.pie().sort(null).value(d => d); + const colors = function(i) { return i === 0 ? options.color : options.baseColor; }; - const sectors = plot.selectAll('path') - .data(pie(data)); + const sectors = plot.selectAll('path').data(pie(data)); - sectors.enter() - .append('path') - .style('fill', (d, i) => colors(i)) - .attr('d', arc); + sectors.enter().append('path').style('fill', (d, i) => colors(i)).attr('d', arc); }); }, - onRender () { + onRender() { ModalView.prototype.onRender.apply(this, arguments); this.initPieChart(); this.$('.js-test-list').scrollTop(this.testsScroll); }, - getMetrics () { + getMetrics() { let metrics = ''; const url = window.baseUrl + '/api/metrics/search'; $.ajax({ @@ -116,11 +102,10 @@ export default ModalView.extend({ return metrics; }, - calcAdditionalMeasures (measures) { - measures.issuesRemediationEffort = - (Number(measures.sqale_index_raw) || 0) + - (Number(measures.reliability_remediation_effort_raw) || 0) + - (Number(measures.security_remediation_effort_raw) || 0); + calcAdditionalMeasures(measures) { + measures.issuesRemediationEffort = (Number(measures.sqale_index_raw) || 0) + + (Number(measures.reliability_remediation_effort_raw) || 0) + + (Number(measures.security_remediation_effort_raw) || 0); if (measures.lines_to_cover && measures.uncovered_lines) { measures.covered_lines = measures.lines_to_cover_raw - measures.uncovered_lines_raw; @@ -131,7 +116,7 @@ export default ModalView.extend({ return measures; }, - prepareMetrics (metrics) { + prepareMetrics(metrics) { metrics = metrics.filter(metric => metric.value != null); return sortBy( toPairs(groupBy(metrics, 'domain')).map(domain => { @@ -144,11 +129,11 @@ export default ModalView.extend({ ); }, - requestMeasures () { + requestMeasures() { return getMetrics().then(metrics => { const metricsToRequest = metrics - .filter(metric => metric.type !== 'DATA' && !metric.hidden) - .map(metric => metric.key); + .filter(metric => metric.type !== 'DATA' && !metric.hidden) + .map(metric => metric.key); return getMeasures(this.options.component.key, metricsToRequest).then(measures => { let nextMeasures = this.options.component.measures || {}; @@ -165,7 +150,7 @@ export default ModalView.extend({ }); }, - requestIssues () { + requestIssues() { return new Promise(resolve => { const url = window.baseUrl + '/api/issues/search'; const options = { @@ -181,7 +166,8 @@ export default ModalView.extend({ const sortedTypesFacet = sortBy(typesFacet, v => typesOrder.indexOf(v.val)); const severitiesFacet = data.facets.find(facet => facet.property === 'severities').values; - const sortedSeveritiesFacet = sortBy(severitiesFacet, facet => window.severityComparator(facet.val)); + const sortedSeveritiesFacet = sortBy(severitiesFacet, facet => + window.severityComparator(facet.val)); const tagsFacet = data.facets.find(facet => facet.property === 'tags').values; @@ -195,7 +181,7 @@ export default ModalView.extend({ }); }, - requestTests () { + requestTests() { return new Promise(resolve => { const url = window.baseUrl + '/api/tests/list'; const options = { testFileKey: this.options.component.key }; @@ -210,7 +196,7 @@ export default ModalView.extend({ }); }, - sortTests (condition) { + sortTests(condition) { let tests = this.tests; if (Array.isArray(tests)) { tests = sortBy(tests, condition); @@ -221,7 +207,7 @@ export default ModalView.extend({ } }, - sortTestsByDuration () { + sortTestsByDuration() { if (this.testSorting === 'duration') { this.testAsc = !this.testAsc; } @@ -230,7 +216,7 @@ export default ModalView.extend({ this.render(); }, - sortTestsByName () { + sortTestsByName() { if (this.testSorting === 'name') { this.testAsc = !this.testAsc; } @@ -239,7 +225,7 @@ export default ModalView.extend({ this.render(); }, - sortTestsByStatus () { + sortTestsByStatus() { if (this.testSorting === 'status') { this.testAsc = !this.testAsc; } @@ -248,7 +234,7 @@ export default ModalView.extend({ this.render(); }, - showTest (e) { + showTest(e) { const testId = $(e.currentTarget).data('id'); const url = window.baseUrl + '/api/tests/covered_files'; const options = { testId }; @@ -260,12 +246,12 @@ export default ModalView.extend({ }); }, - showAllMeasures () { + showAllMeasures() { this.$('.js-all-measures').removeClass('hidden'); this.$('.js-show-all-measures').remove(); }, - serializeData () { + serializeData() { return { ...ModalView.prototype.serializeData.apply(this, arguments), ...this.options.component, diff --git a/server/sonar-web/src/main/js/components/__tests__/issue-test.js b/server/sonar-web/src/main/js/components/__tests__/issue-test.js index 10694b1ebee..b0483b8cc21 100644 --- a/server/sonar-web/src/main/js/components/__tests__/issue-test.js +++ b/server/sonar-web/src/main/js/components/__tests__/issue-test.js @@ -98,7 +98,10 @@ describe('Model', () => { const spy = jest.fn(); issue._action = spy; issue.plan('plan'); - expect(spy).toBeCalledWith({ data: { plan: 'plan', issue: 'issue-key' }, url: '/api/issues/plan' }); + expect(spy).toBeCalledWith({ + data: { plan: 'plan', issue: 'issue-key' }, + url: '/api/issues/plan' + }); }); it('should unplan', () => { @@ -106,7 +109,10 @@ describe('Model', () => { const spy = jest.fn(); issue._action = spy; issue.plan(); - expect(spy).toBeCalledWith({ data: { plan: undefined, issue: 'issue-key' }, url: '/api/issues/plan' }); + expect(spy).toBeCalledWith({ + data: { plan: undefined, issue: 'issue-key' }, + url: '/api/issues/plan' + }); }); it('should set severity', () => { @@ -123,7 +129,9 @@ describe('Model', () => { describe('#getLinearLocations', () => { it('should return single line location', () => { - const issue = new Issue({ textRange: { startLine: 1, endLine: 1, startOffset: 0, endOffset: 10 } }); + const issue = new Issue({ + textRange: { startLine: 1, endLine: 1, startOffset: 0, endOffset: 10 } + }); const locations = issue.getLinearLocations(); expect(locations.length).toBe(1); @@ -133,7 +141,9 @@ describe('Model', () => { }); it('should return location not from 0', () => { - const issue = new Issue({ textRange: { startLine: 1, endLine: 1, startOffset: 5, endOffset: 10 } }); + const issue = new Issue({ + textRange: { startLine: 1, endLine: 1, startOffset: 5, endOffset: 10 } + }); const locations = issue.getLinearLocations(); expect(locations.length).toBe(1); @@ -143,7 +153,9 @@ describe('Model', () => { }); it('should return 2-lines location', () => { - const issue = new Issue({ textRange: { startLine: 2, endLine: 3, startOffset: 5, endOffset: 10 } }); + const issue = new Issue({ + textRange: { startLine: 2, endLine: 3, startOffset: 5, endOffset: 10 } + }); const locations = issue.getLinearLocations(); expect(locations.length).toBe(2); @@ -157,7 +169,9 @@ describe('Model', () => { }); it('should return 3-lines location', () => { - const issue = new Issue({ textRange: { startLine: 4, endLine: 6, startOffset: 5, endOffset: 10 } }); + const issue = new Issue({ + textRange: { startLine: 4, endLine: 6, startOffset: 5, endOffset: 10 } + }); const locations = issue.getLinearLocations(); expect(locations.length).toBe(3); diff --git a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js index fe99958cbff..6713668693a 100644 --- a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js +++ b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js @@ -33,20 +33,20 @@ export default class LanguageDistribution extends React.Component { state = {}; - componentDidMount () { + componentDidMount() { this.mounted = true; this.requestLanguages(); } - shouldComponentUpdate (nextProps, nextState) { + shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - requestLanguages () { + requestLanguages() { getLanguages().then(languages => { if (this.mounted) { this.setState({ languages }); @@ -54,7 +54,7 @@ export default class LanguageDistribution extends React.Component { }); } - getLanguageName (langKey) { + getLanguageName(langKey) { if (this.state.languages) { const lang = find(this.state.languages, { key: langKey }); return lang ? lang.name : translate('unknown'); @@ -63,32 +63,30 @@ export default class LanguageDistribution extends React.Component { } } - cutLanguageName (name) { + cutLanguageName(name) { return name.length > 10 ? `${name.substr(0, 7)}...` : name; } - render () { - let data = this.props.distribution.split(';') - .map((point, index) => { - const tokens = point.split('='); - return { x: parseInt(tokens[1], 10), y: index, value: tokens[0] }; - }); + render() { + let data = this.props.distribution.split(';').map((point, index) => { + const tokens = point.split('='); + return { x: parseInt(tokens[1], 10), y: index, value: tokens[0] }; + }); data = sortBy(data, d => -d.x); - const yTicks = data - .map(point => this.getLanguageName(point.value)) - .map(this.cutLanguageName); + const yTicks = data.map(point => this.getLanguageName(point.value)).map(this.cutLanguageName); const yValues = data.map(point => formatMeasure(point.x, 'SHORT_INT')); return ( - <Histogram - data={data} - yTicks={yTicks} - yValues={yValues} - barsWidth={10} - height={data.length * 25} - padding={[0, 60, 0, 80]}/> + <Histogram + data={data} + yTicks={yTicks} + yValues={yValues} + barsWidth={10} + height={data.length * 25} + padding={[0, 60, 0, 80]} + /> ); } } diff --git a/server/sonar-web/src/main/js/components/charts/Timeline.js b/server/sonar-web/src/main/js/components/charts/Timeline.js index 7b45ee2cf4f..26b8db6ce45 100644 --- a/server/sonar-web/src/main/js/components/charts/Timeline.js +++ b/server/sonar-web/src/main/js/components/charts/Timeline.js @@ -34,54 +34,51 @@ const Timeline = React.createClass({ mixins: [ResizeMixin, TooltipsMixin], - getDefaultProps () { + getDefaultProps() { return { padding: [10, 10, 10, 10], interpolate: 'basis' }; }, - getInitialState () { + getInitialState() { return { width: this.props.width, height: this.props.height }; }, - getRatingScale (availableHeight) { - return d3.scale.ordinal() - .domain([5, 4, 3, 2, 1]) - .rangePoints([availableHeight, 0]); + getRatingScale(availableHeight) { + return d3.scale.ordinal().domain([5, 4, 3, 2, 1]).rangePoints([availableHeight, 0]); }, - getLevelScale (availableHeight) { - return d3.scale.ordinal() - .domain(['ERROR', 'WARN', 'OK']) - .rangePoints([availableHeight, 0]); + getLevelScale(availableHeight) { + return d3.scale.ordinal().domain(['ERROR', 'WARN', 'OK']).rangePoints([availableHeight, 0]); }, - getYScale (availableHeight) { + getYScale(availableHeight) { if (this.props.metricType === 'RATING') { return this.getRatingScale(availableHeight); } else if (this.props.metricType === 'LEVEL') { return this.getLevelScale(availableHeight); } else { - return d3.scale.linear() - .range([availableHeight, 0]) - .domain([0, d3.max(this.props.data, d => d.y || 0)]) - .nice(); + return d3.scale + .linear() + .range([availableHeight, 0]) + .domain([0, d3.max(this.props.data, d => d.y || 0)]) + .nice(); } }, - handleEventMouseEnter (event) { + handleEventMouseEnter(event) { $(`.js-event-circle-${event.date.getTime()}`).tooltip('show'); }, - handleEventMouseLeave (event) { + handleEventMouseLeave(event) { $(`.js-event-circle-${event.date.getTime()}`).tooltip('hide'); }, - renderHorizontalGrid (xScale, yScale) { + renderHorizontalGrid(xScale, yScale) { const hasTicks = typeof yScale.ticks === 'function'; const ticks = hasTicks ? yScale.ticks(4) : yScale.domain(); @@ -96,22 +93,31 @@ const Timeline = React.createClass({ }; return ( - <g key={tick}> - <text className="line-chart-tick line-chart-tick-x" dx="-1em" dy="0.3em" - textAnchor="end" {...opts}>{this.props.formatYTick(tick)}</text> - <line className="line-chart-grid" - x1={xScale.range()[0]} - x2={xScale.range()[1]} - y1={yScale(tick)} - y2={yScale(tick)}/> - </g> + <g key={tick}> + <text + className="line-chart-tick line-chart-tick-x" + dx="-1em" + dy="0.3em" + textAnchor="end" + {...opts} + > + {this.props.formatYTick(tick)} + </text> + <line + className="line-chart-grid" + x1={xScale.range()[0]} + x2={xScale.range()[1]} + y1={yScale(tick)} + y2={yScale(tick)} + /> + </g> ); }); return <g>{grid}</g>; }, - renderTicks (xScale, yScale) { + renderTicks(xScale, yScale) { const format = xScale.tickFormat(7); let ticks = xScale.ticks(7); @@ -121,21 +127,16 @@ const Timeline = React.createClass({ const y = yScale.range()[0]; return ( - <text - key={index} - className="line-chart-tick" - x={x} - y={y} - dy="1.5em"> - {format(tick)} - </text> + <text key={index} className="line-chart-tick" x={x} y={y} dy="1.5em"> + {format(tick)} + </text> ); }); return <g>{ticks}</g>; }, - renderLeak (xScale, yScale) { + renderLeak(xScale, yScale) { if (!this.props.leakPeriodDate) { return null; } @@ -149,76 +150,73 @@ const Timeline = React.createClass({ fill: '#fbf3d5' }; - return <rect {...opts}/>; + return <rect {...opts} />; }, - renderLine (xScale, yScale) { - const p = d3.svg.line() - .x(d => xScale(d.x)) - .y(d => yScale(d.y)) - .interpolate(this.props.interpolate); + renderLine(xScale, yScale) { + const p = d3.svg + .line() + .x(d => xScale(d.x)) + .y(d => yScale(d.y)) + .interpolate(this.props.interpolate); - return <path className="line-chart-path" d={p(this.props.data)}/>; + return <path className="line-chart-path" d={p(this.props.data)} />; }, - renderEvents (xScale, yScale) { + renderEvents(xScale, yScale) { const points = this.props.events - .map(event => { - const snapshot = this.props.data.find(d => d.x.getTime() === event.date.getTime()); - return { ...event, snapshot }; - }) - .filter(event => event.snapshot) - .map(event => { - const key = `${event.date.getTime()}-${event.snapshot.y}`; - const className = `line-chart-point js-event-circle-${event.date.getTime()}`; - const tooltip = [ - `<span class="nowrap">${event.version}</span>`, - `<span class="nowrap">${moment(event.date).format('LL')}</span>`, - `<span class="nowrap">${event.snapshot.y ? this.props.formatValue(event.snapshot.y) : '—'}</span>` - ].join('<br>'); - - return ( - <circle key={key} - className={className} - r="4" - cx={xScale(event.snapshot.x)} - cy={yScale(event.snapshot.y)} - onMouseEnter={this.handleEventMouseEnter.bind(this, event)} - onMouseLeave={this.handleEventMouseLeave.bind(this, event)} - data-toggle="tooltip" - data-title={tooltip}/> - ); - }); - + .map(event => { + const snapshot = this.props.data.find(d => d.x.getTime() === event.date.getTime()); + return { ...event, snapshot }; + }) + .filter(event => event.snapshot) + .map(event => { + const key = `${event.date.getTime()}-${event.snapshot.y}`; + const className = `line-chart-point js-event-circle-${event.date.getTime()}`; + const tooltip = [ + `<span class="nowrap">${event.version}</span>`, + `<span class="nowrap">${moment(event.date).format('LL')}</span>`, + `<span class="nowrap">${event.snapshot.y ? this.props.formatValue(event.snapshot.y) : '—'}</span>` + ].join('<br>'); + return ( + <circle + key={key} + className={className} + r="4" + cx={xScale(event.snapshot.x)} + cy={yScale(event.snapshot.y)} + onMouseEnter={this.handleEventMouseEnter.bind(this, event)} + onMouseLeave={this.handleEventMouseLeave.bind(this, event)} + data-toggle="tooltip" + data-title={tooltip} + /> + ); + }); return <g>{points}</g>; }, - - render () { + render() { if (!this.state.width || !this.state.height) { - return <div/>; + return <div />; } - const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; - - const xScale = d3.time.scale() - .domain(d3.extent(this.props.data, d => d.x || 0)) - .range([0, availableWidth]) - .clamp(true); + const xScale = d3.time + .scale() + .domain(d3.extent(this.props.data, d => d.x || 0)) + .range([0, availableWidth]) + .clamp(true); const yScale = this.getYScale(availableHeight); - return ( - <svg className="line-chart" width={this.state.width} height={this.state.height}> - <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> - {this.renderLeak(xScale, yScale)} - {this.renderHorizontalGrid(xScale, yScale)} - {this.renderTicks(xScale, yScale)} - {this.renderLine(xScale, yScale)} - {this.renderEvents(xScale, yScale)} - </g> - </svg> + <svg className="line-chart" width={this.state.width} height={this.state.height}> + <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> + {this.renderLeak(xScale, yScale)} + {this.renderHorizontalGrid(xScale, yScale)} + {this.renderTicks(xScale, yScale)} + {this.renderLine(xScale, yScale)} + {this.renderEvents(xScale, yScale)} + </g> + </svg> ); } }); - export default Timeline; diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/bar-chart-test.js b/server/sonar-web/src/main/js/components/charts/__tests__/bar-chart-test.js index 377e3b34e4a..c0361a5b3a7 100644 --- a/server/sonar-web/src/main/js/components/charts/__tests__/bar-chart-test.js +++ b/server/sonar-web/src/main/js/components/charts/__tests__/bar-chart-test.js @@ -22,70 +22,36 @@ import { shallow } from 'enzyme'; import { BarChart } from '../bar-chart'; it('should display bars', () => { - const data = [ - { x: 1, y: 10 }, - { x: 2, y: 30 }, - { x: 3, y: 20 } - ]; - const chart = shallow( - <BarChart - data={data} - width={100} - height={100} - barsWidth={20}/>); + const data = [{ x: 1, y: 10 }, { x: 2, y: 30 }, { x: 3, y: 20 }]; + const chart = shallow(<BarChart data={data} width={100} height={100} barsWidth={20} />); expect(chart.find('.bar-chart-bar').length).toBe(3); }); it('should display ticks', () => { - const data = [ - { x: 1, y: 10 }, - { x: 2, y: 30 }, - { x: 3, y: 20 } - ]; + const data = [{ x: 1, y: 10 }, { x: 2, y: 30 }, { x: 3, y: 20 }]; const ticks = ['A', 'B', 'C']; const chart = shallow( - <BarChart - data={data} - xTicks={ticks} - width={100} - height={100} - barsWidth={20}/>); + <BarChart data={data} xTicks={ticks} width={100} height={100} barsWidth={20} /> + ); expect(chart.find('.bar-chart-tick').length).toBe(3); }); it('should display values', () => { - const data = [ - { x: 1, y: 10 }, - { x: 2, y: 30 }, - { x: 3, y: 20 } - ]; + const data = [{ x: 1, y: 10 }, { x: 2, y: 30 }, { x: 3, y: 20 }]; const values = ['A', 'B', 'C']; const chart = shallow( - <BarChart - data={data} - xValues={values} - width={100} - height={100} - barsWidth={20}/>); + <BarChart data={data} xValues={values} width={100} height={100} barsWidth={20} /> + ); expect(chart.find('.bar-chart-tick').length).toBe(3); }); it('should display bars, ticks and values', () => { - const data = [ - { x: 1, y: 10 }, - { x: 2, y: 30 }, - { x: 3, y: 20 } - ]; + const data = [{ x: 1, y: 10 }, { x: 2, y: 30 }, { x: 3, y: 20 }]; const ticks = ['A', 'B', 'C']; const values = ['A', 'B', 'C']; const chart = shallow( - <BarChart - data={data} - xTicks={ticks} - xValues={values} - width={100} - height={100} - barsWidth={20}/>); + <BarChart data={data} xTicks={ticks} xValues={values} width={100} height={100} barsWidth={20} /> + ); expect(chart.find('.bar-chart-bar').length).toBe(3); expect(chart.find('.bar-chart-tick').length).toBe(6); }); diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/bubble-chart-test.js b/server/sonar-web/src/main/js/components/charts/__tests__/bubble-chart-test.js index 39b6f90a692..c9d2dd18d44 100644 --- a/server/sonar-web/src/main/js/components/charts/__tests__/bubble-chart-test.js +++ b/server/sonar-web/src/main/js/components/charts/__tests__/bubble-chart-test.js @@ -22,31 +22,19 @@ import { shallow } from 'enzyme'; import { BubbleChart, Bubble } from '../bubble-chart'; it('should display bubbles', () => { - const items = [ - { x: 1, y: 10, size: 7 }, - { x: 2, y: 30, size: 5 }, - { x: 3, y: 20, size: 2 } - ]; - const chart = shallow(<BubbleChart items={items} width={100} height={100}/>); + const items = [{ x: 1, y: 10, size: 7 }, { x: 2, y: 30, size: 5 }, { x: 3, y: 20, size: 2 }]; + const chart = shallow(<BubbleChart items={items} width={100} height={100} />); expect(chart.find(Bubble).length).toBe(3); }); it('should display grid', () => { - const items = [ - { x: 1, y: 10, size: 7 }, - { x: 2, y: 30, size: 5 }, - { x: 3, y: 20, size: 2 } - ]; - const chart = shallow(<BubbleChart items={items} width={100} height={100}/>); + const items = [{ x: 1, y: 10, size: 7 }, { x: 2, y: 30, size: 5 }, { x: 3, y: 20, size: 2 }]; + const chart = shallow(<BubbleChart items={items} width={100} height={100} />); expect(chart.find('line').length).toBeGreaterThan(0); }); it('should display ticks', () => { - const items = [ - { x: 1, y: 10, size: 7 }, - { x: 2, y: 30, size: 5 }, - { x: 3, y: 20, size: 2 } - ]; - const chart = shallow(<BubbleChart items={items} width={100} height={100}/>); + const items = [{ x: 1, y: 10, size: 7 }, { x: 2, y: 30, size: 5 }, { x: 3, y: 20, size: 2 }]; + const chart = shallow(<BubbleChart items={items} width={100} height={100} />); expect(chart.find('.bubble-chart-tick').length).toBeGreaterThan(0); }); diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/line-chart-test.js b/server/sonar-web/src/main/js/components/charts/__tests__/line-chart-test.js index 566b1eb833d..dbe026b232a 100644 --- a/server/sonar-web/src/main/js/components/charts/__tests__/line-chart-test.js +++ b/server/sonar-web/src/main/js/components/charts/__tests__/line-chart-test.js @@ -22,43 +22,21 @@ import { shallow } from 'enzyme'; import { LineChart } from '../line-chart'; it('should display line', () => { - const data = [ - { x: 1, y: 10 }, - { x: 2, y: 30 }, - { x: 3, y: 20 } - ]; - const chart = shallow(<LineChart data={data} width={100} height={100}/>); + const data = [{ x: 1, y: 10 }, { x: 2, y: 30 }, { x: 3, y: 20 }]; + const chart = shallow(<LineChart data={data} width={100} height={100} />); expect(chart.find('.line-chart-path').length).toBe(1); }); it('should display ticks', () => { - const data = [ - { x: 1, y: 10 }, - { x: 2, y: 30 }, - { x: 3, y: 20 } - ]; + const data = [{ x: 1, y: 10 }, { x: 2, y: 30 }, { x: 3, y: 20 }]; const ticks = ['A', 'B', 'C']; - const chart = shallow( - <LineChart - data={data} - xTicks={ticks} - width={100} - height={100}/>); + const chart = shallow(<LineChart data={data} xTicks={ticks} width={100} height={100} />); expect(chart.find('.line-chart-tick').length).toBe(3); }); it('should display values', () => { - const data = [ - { x: 1, y: 10 }, - { x: 2, y: 30 }, - { x: 3, y: 20 } - ]; + const data = [{ x: 1, y: 10 }, { x: 2, y: 30 }, { x: 3, y: 20 }]; const values = ['A', 'B', 'C']; - const chart = shallow( - <LineChart - data={data} - xValues={values} - width={100} - height={100}/>); + const chart = shallow(<LineChart data={data} xValues={values} width={100} height={100} />); expect(chart.find('.line-chart-tick').length).toBe(3); }); diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/treemap-test.js b/server/sonar-web/src/main/js/components/charts/__tests__/treemap-test.js index 453bba4daee..dea905a78f8 100644 --- a/server/sonar-web/src/main/js/components/charts/__tests__/treemap-test.js +++ b/server/sonar-web/src/main/js/components/charts/__tests__/treemap-test.js @@ -28,11 +28,7 @@ it('should display', () => { { size: 20, color: '#777', label: 'SonarQube :: Search' } ]; const chart = shallow( - <Treemap - items={items} - width={100} - height={100} - breadcrumbs={[]} - canBeClicked={() => true}/>); + <Treemap items={items} width={100} height={100} breadcrumbs={[]} canBeClicked={() => true} /> + ); expect(chart.find(TreemapRect).length).toBe(3); }); diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/work-cloud-test.js b/server/sonar-web/src/main/js/components/charts/__tests__/work-cloud-test.js index 36bc18c932e..71bbfbc9dff 100644 --- a/server/sonar-web/src/main/js/components/charts/__tests__/work-cloud-test.js +++ b/server/sonar-web/src/main/js/components/charts/__tests__/work-cloud-test.js @@ -27,6 +27,6 @@ it('should display', () => { { size: 30, link: '#', text: 'SonarQube :: Web' }, { size: 20, link: '#', text: 'SonarQube :: Search' } ]; - const chart = shallow(<WordCloud items={items} width={100} height={100}/>); + const chart = shallow(<WordCloud items={items} width={100} height={100} />); expect(chart.find(Word).length).toBe(3); }); diff --git a/server/sonar-web/src/main/js/components/charts/bar-chart.js b/server/sonar-web/src/main/js/components/charts/bar-chart.js index fb7082d96df..af5b42cf108 100644 --- a/server/sonar-web/src/main/js/components/charts/bar-chart.js +++ b/server/sonar-web/src/main/js/components/charts/bar-chart.js @@ -35,7 +35,7 @@ export const BarChart = React.createClass({ mixins: [ResizeMixin, TooltipsMixin], - getDefaultProps () { + getDefaultProps() { return { xTicks: [], xValues: [], @@ -43,15 +43,15 @@ export const BarChart = React.createClass({ }; }, - getInitialState () { + getInitialState() { return { width: this.props.width, height: this.props.height }; }, - handleClick (point) { + handleClick(point) { this.props.onBarClick(point); }, - renderXTicks (xScale, yScale) { + renderXTicks(xScale, yScale) { if (!this.props.xTicks.length) { return null; } @@ -66,23 +66,24 @@ export const BarChart = React.createClass({ tooltipAtts['data-toggle'] = 'tooltip'; } return ( - <text - key={index} - className="bar-chart-tick" - x={x} - y={y} - dy="1.5em" - onClick={this.props.onBarClick && this.handleClick.bind(this, point)} - style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - {...tooltipAtts}> - {tick} - </text> + <text + key={index} + className="bar-chart-tick" + x={x} + y={y} + dy="1.5em" + onClick={this.props.onBarClick && this.handleClick.bind(this, point)} + style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} + {...tooltipAtts} + > + {tick} + </text> ); }); return <g>{ticks}</g>; }, - renderXValues (xScale, yScale) { + renderXValues(xScale, yScale) { if (!this.props.xValues.length) { return null; } @@ -97,23 +98,24 @@ export const BarChart = React.createClass({ tooltipAtts['data-toggle'] = 'tooltip'; } return ( - <text - key={index} - className="bar-chart-tick" - x={x} - y={y} - dy="-1em" - onClick={this.props.onBarClick && this.handleClick.bind(this, point)} - style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - {...tooltipAtts}> - {value} - </text> + <text + key={index} + className="bar-chart-tick" + x={x} + y={y} + dy="-1em" + onClick={this.props.onBarClick && this.handleClick.bind(this, point)} + style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} + {...tooltipAtts} + > + {value} + </text> ); }); return <g>{ticks}</g>; }, - renderBars (xScale, yScale) { + renderBars(xScale, yScale) { const bars = this.props.data.map((d, index) => { const x = Math.round(xScale(d.x)); const maxY = yScale.range()[0]; @@ -125,49 +127,49 @@ export const BarChart = React.createClass({ tooltipAtts['data-toggle'] = 'tooltip'; } return ( - <rect - key={index} - className="bar-chart-bar" - {...tooltipAtts} - x={x} - y={y} - width={this.props.barsWidth} - height={height} - onClick={this.props.onBarClick && this.handleClick.bind(this, d)} - style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }}/> + <rect + key={index} + className="bar-chart-bar" + {...tooltipAtts} + x={x} + y={y} + width={this.props.barsWidth} + height={height} + onClick={this.props.onBarClick && this.handleClick.bind(this, d)} + style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} + /> ); }); return <g>{bars}</g>; }, - render () { + render() { if (!this.state.width || !this.state.height) { - return <div/>; + return <div />; } const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; const innerPadding = (availableWidth - this.props.barsWidth * this.props.data.length) / - (this.props.data.length - 1); + (this.props.data.length - 1); const relativeInnerPadding = innerPadding / (innerPadding + this.props.barsWidth); const maxY = d3.max(this.props.data, d => d.y); - const xScale = d3.scale.ordinal() - .domain(this.props.data.map(d => d.x)) - .rangeBands([0, availableWidth], relativeInnerPadding, 0); - const yScale = d3.scale.linear() - .domain([0, maxY]) - .range([availableHeight, 0]); + const xScale = d3.scale + .ordinal() + .domain(this.props.data.map(d => d.x)) + .rangeBands([0, availableWidth], relativeInnerPadding, 0); + const yScale = d3.scale.linear().domain([0, maxY]).range([availableHeight, 0]); return ( - <svg className="bar-chart" width={this.state.width} height={this.state.height}> - <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> - {this.renderXTicks(xScale, yScale)} - {this.renderXValues(xScale, yScale)} - {this.renderBars(xScale, yScale)} - </g> - </svg> + <svg className="bar-chart" width={this.state.width} height={this.state.height}> + <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> + {this.renderXTicks(xScale, yScale)} + {this.renderXValues(xScale, yScale)} + {this.renderBars(xScale, yScale)} + </g> + </svg> ); } }); diff --git a/server/sonar-web/src/main/js/components/charts/bubble-chart.js b/server/sonar-web/src/main/js/components/charts/bubble-chart.js index 74c029872b7..1ecd181f54a 100644 --- a/server/sonar-web/src/main/js/components/charts/bubble-chart.js +++ b/server/sonar-web/src/main/js/components/charts/bubble-chart.js @@ -35,13 +35,13 @@ export const Bubble = React.createClass({ link: React.PropTypes.any }, - handleClick () { + handleClick() { if (this.props.onClick) { this.props.onClick(this.props.link); } }, - render () { + render() { let tooltipAttrs = {}; if (this.props.tooltip) { tooltipAttrs = { @@ -50,9 +50,13 @@ export const Bubble = React.createClass({ }; } return ( - <circle onClick={this.handleClick} className="bubble-chart-bubble" - r={this.props.r} {...tooltipAttrs} - transform={`translate(${this.props.x}, ${this.props.y})`}/> + <circle + onClick={this.handleClick} + className="bubble-chart-bubble" + r={this.props.r} + {...tooltipAttrs} + transform={`translate(${this.props.x}, ${this.props.y})`} + /> ); } }); @@ -74,7 +78,7 @@ export const BubbleChart = React.createClass({ mixins: [ResizeMixin, TooltipsMixin], - getDefaultProps () { + getDefaultProps() { return { sizeRange: [5, 45], displayXGrid: true, @@ -87,11 +91,11 @@ export const BubbleChart = React.createClass({ }; }, - getInitialState () { + getInitialState() { return { width: this.props.width, height: this.props.height }; }, - getXRange (xScale, sizeScale, availableWidth) { + getXRange(xScale, sizeScale, availableWidth) { const minX = d3.min(this.props.items, d => xScale(d.x) - sizeScale(d.size)); const maxX = d3.max(this.props.items, d => xScale(d.x) + sizeScale(d.size)); const dMinX = minX < 0 ? xScale.range()[0] - minX : xScale.range()[0]; @@ -99,7 +103,7 @@ export const BubbleChart = React.createClass({ return [dMinX, availableWidth - dMaxX]; }, - getYRange (yScale, sizeScale, availableHeight) { + getYRange(yScale, sizeScale, availableHeight) { const minY = d3.min(this.props.items, d => yScale(d.y) - sizeScale(d.size)); const maxY = d3.max(this.props.items, d => yScale(d.y) + sizeScale(d.size)); const dMinY = minY < 0 ? yScale.range()[1] - minY : yScale.range()[1]; @@ -107,14 +111,14 @@ export const BubbleChart = React.createClass({ return [availableHeight - dMaxY, dMinY]; }, - getTicks (scale, format) { + getTicks(scale, format) { const ticks = scale.ticks(TICKS_COUNT).map(tick => format(tick)); const uniqueTicksCount = uniq(ticks).length; const ticksCount = uniqueTicksCount < TICKS_COUNT ? uniqueTicksCount - 1 : TICKS_COUNT; return scale.ticks(ticksCount); }, - renderXGrid (ticks, xScale, yScale) { + renderXGrid(ticks, xScale, yScale) { if (!this.props.displayXGrid) { return null; } @@ -123,21 +127,13 @@ export const BubbleChart = React.createClass({ const x = xScale(tick); const y1 = yScale.range()[0]; const y2 = yScale.range()[1]; - return ( - <line - key={index} - x1={x} - x2={x} - y1={y1} - y2={y2} - className="bubble-chart-grid"/> - ); + return <line key={index} x1={x} x2={x} y1={y1} y2={y2} className="bubble-chart-grid" />; }); return <g ref="xGrid">{lines}</g>; }, - renderYGrid (ticks, xScale, yScale) { + renderYGrid(ticks, xScale, yScale) { if (!this.props.displayYGrid) { return null; } @@ -146,21 +142,13 @@ export const BubbleChart = React.createClass({ const y = yScale(tick); const x1 = xScale.range()[0]; const x2 = xScale.range()[1]; - return ( - <line - key={index} - x1={x1} - x2={x2} - y1={y} - y2={y} - className="bubble-chart-grid"/> - ); + return <line key={index} x1={x1} x2={x2} y1={y} y2={y} className="bubble-chart-grid" />; }); return <g ref="yGrid">{lines}</g>; }, - renderXTicks (xTicks, xScale, yScale) { + renderXTicks(xTicks, xScale, yScale) { if (!this.props.displayXTicks) { return null; } @@ -170,21 +158,16 @@ export const BubbleChart = React.createClass({ const y = yScale.range()[0]; const innerText = this.props.formatXTick(tick); return ( - <text - key={index} - className="bubble-chart-tick" - x={x} - y={y} - dy="1.5em"> - {innerText} - </text> + <text key={index} className="bubble-chart-tick" x={x} y={y} dy="1.5em"> + {innerText} + </text> ); }); return <g>{ticks}</g>; }, - renderYTicks (yTicks, xScale, yScale) { + renderYTicks(yTicks, xScale, yScale) { if (!this.props.displayYTicks) { return null; } @@ -194,40 +177,44 @@ export const BubbleChart = React.createClass({ const y = yScale(tick); const innerText = this.props.formatYTick(tick); return ( - <text - key={index} - className="bubble-chart-tick bubble-chart-tick-y" - x={x} - y={y} - dx="-0.5em" - dy="0.3em"> - {innerText} - </text> + <text + key={index} + className="bubble-chart-tick bubble-chart-tick-y" + x={x} + y={y} + dx="-0.5em" + dy="0.3em" + > + {innerText} + </text> ); }); return <g>{ticks}</g>; }, - render () { + render() { if (!this.state.width || !this.state.height) { - return <div/>; + return <div />; } const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; - const xScale = d3.scale.linear() - .domain([0, d3.max(this.props.items, d => d.x)]) - .range([0, availableWidth]) - .nice(); - const yScale = d3.scale.linear() - .domain([0, d3.max(this.props.items, d => d.y)]) - .range([availableHeight, 0]) - .nice(); - const sizeScale = d3.scale.linear() - .domain([0, d3.max(this.props.items, d => d.size)]) - .range(this.props.sizeRange); + const xScale = d3.scale + .linear() + .domain([0, d3.max(this.props.items, d => d.x)]) + .range([0, availableWidth]) + .nice(); + const yScale = d3.scale + .linear() + .domain([0, d3.max(this.props.items, d => d.y)]) + .range([availableHeight, 0]) + .nice(); + const sizeScale = d3.scale + .linear() + .domain([0, d3.max(this.props.items, d => d.size)]) + .range(this.props.sizeRange); const xScaleOriginal = xScale.copy(); const yScaleOriginal = yScale.copy(); @@ -235,31 +222,33 @@ export const BubbleChart = React.createClass({ xScale.range(this.getXRange(xScale, sizeScale, availableWidth)); yScale.range(this.getYRange(yScale, sizeScale, availableHeight)); - const bubbles = sortBy(this.props.items, b => -b.size) - .map((item, index) => { - return ( - <Bubble - key={index} - link={item.link} - tooltip={item.tooltip} - x={xScale(item.x)} y={yScale(item.y)} r={sizeScale(item.size)} - onClick={this.props.onBubbleClick}/> - ); - }); + const bubbles = sortBy(this.props.items, b => -b.size).map((item, index) => { + return ( + <Bubble + key={index} + link={item.link} + tooltip={item.tooltip} + x={xScale(item.x)} + y={yScale(item.y)} + r={sizeScale(item.size)} + onClick={this.props.onBubbleClick} + /> + ); + }); const xTicks = this.getTicks(xScale, this.props.formatXTick); const yTicks = this.getTicks(yScale, this.props.formatYTick); return ( - <svg className="bubble-chart" width={this.state.width} height={this.state.height}> - <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> - {this.renderXGrid(xTicks, xScale, yScale)} - {this.renderXTicks(xTicks, xScale, yScaleOriginal)} - {this.renderYGrid(yTicks, xScale, yScale)} - {this.renderYTicks(yTicks, xScaleOriginal, yScale)} - {bubbles} - </g> - </svg> + <svg className="bubble-chart" width={this.state.width} height={this.state.height}> + <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> + {this.renderXGrid(xTicks, xScale, yScale)} + {this.renderXTicks(xTicks, xScale, yScaleOriginal)} + {this.renderYGrid(yTicks, xScale, yScale)} + {this.renderYTicks(yTicks, xScaleOriginal, yScale)} + {bubbles} + </g> + </svg> ); } }); diff --git a/server/sonar-web/src/main/js/components/charts/donut-chart.js b/server/sonar-web/src/main/js/components/charts/donut-chart.js index 87ca7acb775..f4217c72d40 100644 --- a/server/sonar-web/src/main/js/components/charts/donut-chart.js +++ b/server/sonar-web/src/main/js/components/charts/donut-chart.js @@ -23,11 +23,12 @@ import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; const Sector = React.createClass({ - render () { - const arc = d3.svg.arc() - .outerRadius(this.props.radius) - .innerRadius(this.props.radius - this.props.thickness); - return <path d={arc(this.props.data)} style={{ fill: this.props.fill }}/>; + render() { + const arc = d3.svg + .arc() + .outerRadius(this.props.radius) + .innerRadius(this.props.radius - this.props.thickness); + return <path d={arc(this.props.data)} style={{ fill: this.props.fill }} />; } }); @@ -38,17 +39,17 @@ export const DonutChart = React.createClass({ mixins: [ResizeMixin, TooltipsMixin], - getDefaultProps () { + getDefaultProps() { return { thickness: 6, padding: [0, 0, 0, 0] }; }, - getInitialState () { + getInitialState() { return { width: this.props.width, height: this.props.height }; }, - render () { + render() { if (!this.state.width || !this.state.height) { - return <div/>; + return <div />; } const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; @@ -57,28 +58,27 @@ export const DonutChart = React.createClass({ const size = Math.min(availableWidth, availableHeight); const radius = Math.floor(size / 2); - const pie = d3.layout.pie() - .sort(null) - .value(d => d.value); + const pie = d3.layout.pie().sort(null).value(d => d.value); const sectors = pie(this.props.data).map((d, i) => { return ( - <Sector - key={i} - data={d} - radius={radius} - fill={this.props.data[i].fill} - thickness={this.props.thickness}/> + <Sector + key={i} + data={d} + radius={radius} + fill={this.props.data[i].fill} + thickness={this.props.thickness} + /> ); }); return ( - <svg className="donut-chart" width={this.state.width} height={this.state.height}> - <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> - <g transform={`translate(${radius}, ${radius})`}> - {sectors} - </g> + <svg className="donut-chart" width={this.state.width} height={this.state.height}> + <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> + <g transform={`translate(${radius}, ${radius})`}> + {sectors} </g> - </svg> + </g> + </svg> ); } }); diff --git a/server/sonar-web/src/main/js/components/charts/histogram.js b/server/sonar-web/src/main/js/components/charts/histogram.js index 7694412d957..a06dee0abb4 100644 --- a/server/sonar-web/src/main/js/components/charts/histogram.js +++ b/server/sonar-web/src/main/js/components/charts/histogram.js @@ -36,7 +36,7 @@ export const Histogram = React.createClass({ mixins: [ResizeMixin, TooltipsMixin], - getDefaultProps () { + getDefaultProps() { return { xTicks: [], xValues: [], @@ -45,15 +45,15 @@ export const Histogram = React.createClass({ }; }, - getInitialState () { + getInitialState() { return { width: this.props.width, height: this.props.height }; }, - handleClick (point) { + handleClick(point) { this.props.onBarClick(point); }, - renderTicks (xScale, yScale) { + renderTicks(xScale, yScale) { if (!this.props.yTicks.length) { return null; } @@ -64,25 +64,26 @@ export const Histogram = React.createClass({ const label = tick.label ? tick.label : tick; const tooltip = tick.tooltip ? tick.tooltip : null; return ( - <text - key={index} - className="bar-chart-tick histogram-tick" - onClick={this.props.onBarClick && this.handleClick.bind(this, point)} - style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - data-title={tooltip} - data-toggle={tooltip ? 'tooltip' : null} - x={x} - y={y} - dx="-1em" - dy="0.3em"> - {label} - </text> + <text + key={index} + className="bar-chart-tick histogram-tick" + onClick={this.props.onBarClick && this.handleClick.bind(this, point)} + style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} + data-title={tooltip} + data-toggle={tooltip ? 'tooltip' : null} + x={x} + y={y} + dx="-1em" + dy="0.3em" + > + {label} + </text> ); }); return <g>{ticks}</g>; }, - renderValues (xScale, yScale) { + renderValues(xScale, yScale) { if (!this.props.yValues.length) { return null; } @@ -91,65 +92,66 @@ export const Histogram = React.createClass({ const x = xScale(point.x); const y = Math.round(yScale(point.y) + yScale.rangeBand() / 2 + this.props.barsHeight / 2); return ( - <text - key={index} - onClick={this.props.onBarClick && this.handleClick.bind(this, point)} - className="bar-chart-tick histogram-value" - style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - x={x} - y={y} - dx="1em" - dy="0.3em"> - {value} - </text> + <text + key={index} + onClick={this.props.onBarClick && this.handleClick.bind(this, point)} + className="bar-chart-tick histogram-value" + style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} + x={x} + y={y} + dx="1em" + dy="0.3em" + > + {value} + </text> ); }); return <g>{ticks}</g>; }, - renderBars (xScale, yScale) { + renderBars(xScale, yScale) { const bars = this.props.data.map((d, index) => { const x = Math.round(xScale(d.x)) + /* minimum bar width */ 1; const y = Math.round(yScale(d.y) + yScale.rangeBand() / 2); return ( - <rect - key={index} - className="bar-chart-bar" - onClick={this.props.onBarClick && this.handleClick.bind(this, d)} - style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - x={0} - y={y} - width={x} - height={this.props.barsHeight}/> + <rect + key={index} + className="bar-chart-bar" + onClick={this.props.onBarClick && this.handleClick.bind(this, d)} + style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} + x={0} + y={y} + width={x} + height={this.props.barsHeight} + /> ); }); return <g>{bars}</g>; }, - render () { + render() { if (!this.state.width || !this.state.height) { - return <div/>; + return <div />; } const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; const maxX = d3.max(this.props.data, d => d.x); - const xScale = d3.scale.linear() - .domain([0, maxX]) - .range([0, availableWidth]); - const yScale = d3.scale.ordinal() - .domain(this.props.data.map(d => d.y)) - .rangeRoundBands([0, availableHeight]); + const xScale = d3.scale.linear().domain([0, maxX]).range([0, availableWidth]); + const yScale = d3.scale + .ordinal() + .domain(this.props.data.map(d => d.y)) + .rangeRoundBands([0, availableHeight]); return ( - <svg className="bar-chart" width={this.state.width} height={this.state.height}> - <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> - {this.renderTicks(xScale, yScale)} - {this.renderValues(xScale, yScale)} - {this.renderBars(xScale, yScale)} - </g> - </svg> + <svg className="bar-chart" width={this.state.width} height={this.state.height}> + <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> + {this.renderTicks(xScale, yScale)} + {this.renderValues(xScale, yScale)} + {this.renderBars(xScale, yScale)} + </g> + </svg> ); } }); diff --git a/server/sonar-web/src/main/js/components/charts/line-chart.js b/server/sonar-web/src/main/js/components/charts/line-chart.js index 70f33f7b864..804debc86ef 100644 --- a/server/sonar-web/src/main/js/components/charts/line-chart.js +++ b/server/sonar-web/src/main/js/components/charts/line-chart.js @@ -38,7 +38,7 @@ export const LineChart = React.createClass({ mixins: [ResizeMixin, TooltipsMixin], - getDefaultProps () { + getDefaultProps() { return { displayBackdrop: true, displayPoints: true, @@ -50,49 +50,43 @@ export const LineChart = React.createClass({ }; }, - getInitialState () { + getInitialState() { return { width: this.props.width, height: this.props.height }; }, - renderBackdrop (xScale, yScale) { + renderBackdrop(xScale, yScale) { if (!this.props.displayBackdrop) { return null; } - const area = d3.svg.area() - .x(d => xScale(d.x)) - .y0(yScale.range()[0]) - .y1(d => yScale(d.y)) - .interpolate(this.props.interpolate); + const area = d3.svg + .area() + .x(d => xScale(d.x)) + .y0(yScale.range()[0]) + .y1(d => yScale(d.y)) + .interpolate(this.props.interpolate); let data = this.props.data; if (this.props.backdropConstraints) { const c = this.props.backdropConstraints; data = data.filter(d => c[0] <= d.x && d.x <= c[1]); } - return <path className="line-chart-backdrop" d={area(data)}/>; + return <path className="line-chart-backdrop" d={area(data)} />; }, - renderPoints (xScale, yScale) { + renderPoints(xScale, yScale) { if (!this.props.displayPoints) { return null; } const points = this.props.data.map((point, index) => { const x = xScale(point.x); const y = yScale(point.y); - return ( - <circle - key={index} - className="line-chart-point" - r="3" - cx={x} - cy={y}/> - ); + return <circle key={index} className="line-chart-point" r="3" cx={x} cy={y} />; }); return <g>{points}</g>; }, - renderVerticalGrid (xScale, yScale) { + renderVerticalGrid(xScale, yScale) { if (!this.props.displayVerticalGrid) { return null; } @@ -100,20 +94,12 @@ export const LineChart = React.createClass({ const x = xScale(point.x); const y1 = yScale.range()[0]; const y2 = yScale(point.y); - return ( - <line - key={index} - className="line-chart-grid" - x1={x} - x2={x} - y1={y1} - y2={y2}/> - ); + return <line key={index} className="line-chart-grid" x1={x} x2={x} y1={y1} y2={y2} />; }); return <g>{lines}</g>; }, - renderXTicks (xScale, yScale) { + renderXTicks(xScale, yScale) { if (!this.props.xTicks.length) { return null; } @@ -121,19 +107,12 @@ export const LineChart = React.createClass({ const point = this.props.data[index]; const x = xScale(point.x); const y = yScale.range()[0]; - return ( - <text - key={index} - className="line-chart-tick" - x={x} - y={y} - dy="1.5em">{tick}</text> - ); + return <text key={index} className="line-chart-tick" x={x} y={y} dy="1.5em">{tick}</text>; }); return <g>{ticks}</g>; }, - renderXValues (xScale, yScale) { + renderXValues(xScale, yScale) { if (!this.props.xValues.length) { return null; } @@ -141,41 +120,35 @@ export const LineChart = React.createClass({ const point = this.props.data[index]; const x = xScale(point.x); const y = yScale(point.y); - return ( - <text - key={index} - className="line-chart-tick" - x={x} - y={y} - dy="-1em">{value}</text> - ); + return <text key={index} className="line-chart-tick" x={x} y={y} dy="-1em">{value}</text>; }); return <g>{ticks}</g>; }, - renderLine (xScale, yScale) { - const p = d3.svg.line() - .x(d => xScale(d.x)) - .y(d => yScale(d.y)) - .interpolate(this.props.interpolate); + renderLine(xScale, yScale) { + const p = d3.svg + .line() + .x(d => xScale(d.x)) + .y(d => yScale(d.y)) + .interpolate(this.props.interpolate); - return <path className="line-chart-path" d={p(this.props.data)}/>; + return <path className="line-chart-path" d={p(this.props.data)} />; }, - render () { + render() { if (!this.state.width || !this.state.height) { - return <div/>; + return <div />; } const availableWidth = this.state.width - this.props.padding[1] - this.props.padding[3]; const availableHeight = this.state.height - this.props.padding[0] - this.props.padding[2]; let maxY; - const xScale = d3.scale.linear() - .domain(d3.extent(this.props.data, d => d.x)) - .range([0, availableWidth]); - const yScale = d3.scale.linear() - .range([availableHeight, 0]); + const xScale = d3.scale + .linear() + .domain(d3.extent(this.props.data, d => d.x)) + .range([0, availableWidth]); + const yScale = d3.scale.linear().range([availableHeight, 0]); if (this.props.domain) { maxY = this.props.domain[1]; @@ -186,16 +159,16 @@ export const LineChart = React.createClass({ } return ( - <svg className="line-chart" width={this.state.width} height={this.state.height}> - <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> - {this.renderVerticalGrid(xScale, yScale, maxY)} - {this.renderBackdrop(xScale, yScale)} - {this.renderLine(xScale, yScale)} - {this.renderPoints(xScale, yScale)} - {this.renderXTicks(xScale, yScale)} - {this.renderXValues(xScale, yScale)} - </g> - </svg> + <svg className="line-chart" width={this.state.width} height={this.state.height}> + <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> + {this.renderVerticalGrid(xScale, yScale, maxY)} + {this.renderBackdrop(xScale, yScale)} + {this.renderLine(xScale, yScale)} + {this.renderPoints(xScale, yScale)} + {this.renderXTicks(xScale, yScale)} + {this.renderXValues(xScale, yScale)} + </g> + </svg> ); } }); diff --git a/server/sonar-web/src/main/js/components/charts/treemap-breadcrumbs.js b/server/sonar-web/src/main/js/components/charts/treemap-breadcrumbs.js index 83f5ff5c3f3..d91207af777 100644 --- a/server/sonar-web/src/main/js/components/charts/treemap-breadcrumbs.js +++ b/server/sonar-web/src/main/js/components/charts/treemap-breadcrumbs.js @@ -22,48 +22,50 @@ import QualifierIcon from '../shared/qualifier-icon'; export const TreemapBreadcrumbs = React.createClass({ propTypes: { - breadcrumbs: React.PropTypes.arrayOf(React.PropTypes.shape({ - key: React.PropTypes.string.isRequired, - name: React.PropTypes.string.isRequired, - qualifier: React.PropTypes.string.isRequired - }).isRequired).isRequired + breadcrumbs: React.PropTypes.arrayOf( + React.PropTypes.shape({ + key: React.PropTypes.string.isRequired, + name: React.PropTypes.string.isRequired, + qualifier: React.PropTypes.string.isRequired + }).isRequired + ).isRequired }, - handleItemClick (item, e) { + handleItemClick(item, e) { e.preventDefault(); this.props.onRectangleClick(item); }, - handleReset (e) { + handleReset(e) { e.preventDefault(); this.props.onReset(); }, - renderHome () { + renderHome() { return ( - <span className="treemap-breadcrumbs-item"> - <a onClick={this.handleReset} className="icon-home" href="#"/> - </span> + <span className="treemap-breadcrumbs-item"> + <a onClick={this.handleReset} className="icon-home" href="#" /> + </span> ); }, - renderBreadcrumbsItems (b) { + renderBreadcrumbsItems(b) { return ( - <span key={b.key} className="treemap-breadcrumbs-item" title={b.name}> - <i className="icon-chevron-right"/> - <QualifierIcon qualifier={b.qualifier}/> - <a onClick={this.handleItemClick.bind(this, b)} href="#">{b.name}</a> - </span> + <span key={b.key} className="treemap-breadcrumbs-item" title={b.name}> + <i className="icon-chevron-right" /> + <QualifierIcon qualifier={b.qualifier} /> + <a onClick={this.handleItemClick.bind(this, b)} href="#">{b.name}</a> + </span> ); }, - render () { + render() { const breadcrumbs = this.props.breadcrumbs.map(this.renderBreadcrumbsItems); return ( - <div className="treemap-breadcrumbs"> - {this.props.breadcrumbs.length ? this.renderHome() : null} - {breadcrumbs} - </div> + <div className="treemap-breadcrumbs"> + {this.props.breadcrumbs.length ? this.renderHome() : null} + {breadcrumbs} + </div> ); } }); diff --git a/server/sonar-web/src/main/js/components/charts/treemap.js b/server/sonar-web/src/main/js/components/charts/treemap.js index 23a1590597c..2efbc0c29bb 100644 --- a/server/sonar-web/src/main/js/components/charts/treemap.js +++ b/server/sonar-web/src/main/js/components/charts/treemap.js @@ -24,12 +24,9 @@ import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; import { translate } from '../../helpers/l10n'; -const SIZE_SCALE = d3.scale.linear() - .domain([3, 15]) - .range([11, 18]) - .clamp(true); +const SIZE_SCALE = d3.scale.linear().domain([3, 15]).range([11, 18]).clamp(true); -function mostCommitPrefix (strings) { +function mostCommitPrefix(strings) { const sortedStrings = strings.slice(0).sort(); const firstString = sortedStrings[0]; const firstStringLength = firstString.length; @@ -55,7 +52,7 @@ export const TreemapRect = React.createClass({ onClick: React.PropTypes.func }, - renderLink () { + renderLink() { if (!this.props.link) { return null; } @@ -65,16 +62,18 @@ export const TreemapRect = React.createClass({ } return ( - <a onClick={e => e.stopPropagation()} - className="treemap-link" - href={this.props.link} - style={{ fontSize: 12 }}> - <span className="icon-link"/> - </a> + <a + onClick={e => e.stopPropagation()} + className="treemap-link" + href={this.props.link} + style={{ fontSize: 12 }} + > + <span className="icon-link" /> + </a> ); }, - render () { + render() { let tooltipAttrs = {}; if (this.props.tooltip) { tooltipAttrs = { @@ -95,17 +94,19 @@ export const TreemapRect = React.createClass({ const isTextVisible = this.props.width >= 40 && this.props.height >= 40; /* eslint-disable jsx-a11y/onclick-has-focus, jsx-a11y/onclick-has-role */ return ( + <div + className="treemap-cell" + {...tooltipAttrs} + style={cellStyles} + onClick={this.props.onClick} + > <div - className="treemap-cell" - {...tooltipAttrs} - style={cellStyles} - onClick={this.props.onClick}> - <div - className="treemap-inner" - dangerouslySetInnerHTML={{ __html: this.props.label }} - style={{ maxWidth: this.props.width, visibility: isTextVisible ? 'visible' : 'hidden' }}/> - {this.renderLink()} - </div> + className="treemap-inner" + dangerouslySetInnerHTML={{ __html: this.props.label }} + style={{ maxWidth: this.props.width, visibility: isTextVisible ? 'visible' : 'hidden' }} + /> + {this.renderLink()} + </div> ); } }); @@ -119,22 +120,25 @@ export const Treemap = React.createClass({ mixins: [ResizeMixin, TooltipsMixin], - getInitialState () { + getInitialState() { return { width: this.props.width, height: this.props.height }; }, - renderWhenNoData () { + renderWhenNoData() { return ( - <div className="sonar-d3"> - <div className="treemap-container" style={{ width: this.state.width, height: this.state.height }}> - {translate('no_data')} - </div> - <TreemapBreadcrumbs {...this.props}/> + <div className="sonar-d3"> + <div + className="treemap-container" + style={{ width: this.state.width, height: this.state.height }} + > + {translate('no_data')} </div> + <TreemapBreadcrumbs {...this.props} /> + </div> ); }, - render () { + render() { if (!this.state.width || !this.state.height) { return <div> </div>; } @@ -143,15 +147,16 @@ export const Treemap = React.createClass({ return this.renderWhenNoData(); } - const treemap = d3.layout.treemap() - .round(true) - .value(d => d.size) - .sort((a, b) => a.value - b.value) - .size([this.state.width, this.state.height]); + const treemap = d3.layout + .treemap() + .round(true) + .value(d => d.size) + .sort((a, b) => a.value - b.value) + .size([this.state.width, this.state.height]); const nodes = treemap - .nodes({ children: this.props.items }) - .filter(d => !d.children) - .filter(d => !!d.dx && !!d.dy); + .nodes({ children: this.props.items }) + .filter(d => !d.children) + .filter(d => !!d.dx && !!d.dy); const prefix = mostCommitPrefix(this.props.items.map(item => item.label)); const prefixLength = prefix.length; @@ -159,30 +164,36 @@ export const Treemap = React.createClass({ const rectangles = nodes.map(node => { const key = node.label; const label = prefixLength ? `${prefix}<br>${node.label.substr(prefixLength)}` : node.label; - const onClick = this.props.canBeClicked(node) ? () => this.props.onRectangleClick(node) : null; + const onClick = this.props.canBeClicked(node) + ? () => this.props.onRectangleClick(node) + : null; return ( - <TreemapRect - key={key} - x={node.x} - y={node.y} - width={node.dx} - height={node.dy} - fill={node.color} - label={label} - prefix={prefix} - tooltip={node.tooltip} - link={node.link} - onClick={onClick}/> + <TreemapRect + key={key} + x={node.x} + y={node.y} + width={node.dx} + height={node.dy} + fill={node.color} + label={label} + prefix={prefix} + tooltip={node.tooltip} + link={node.link} + onClick={onClick} + /> ); }); return ( - <div className="sonar-d3"> - <div className="treemap-container" style={{ width: this.state.width, height: this.state.height }}> - {rectangles} - </div> - <TreemapBreadcrumbs {...this.props}/> + <div className="sonar-d3"> + <div + className="treemap-container" + style={{ width: this.state.width, height: this.state.height }} + > + {rectangles} </div> + <TreemapBreadcrumbs {...this.props} /> + </div> ); } }); diff --git a/server/sonar-web/src/main/js/components/charts/word-cloud.js b/server/sonar-web/src/main/js/components/charts/word-cloud.js index bb7beaad8a6..b9fbaeb2959 100644 --- a/server/sonar-web/src/main/js/components/charts/word-cloud.js +++ b/server/sonar-web/src/main/js/components/charts/word-cloud.js @@ -30,7 +30,7 @@ export const Word = React.createClass({ link: React.PropTypes.string.isRequired }, - render () { + render() { let tooltipAttrs = {}; if (this.props.tooltip) { tooltipAttrs = { @@ -38,7 +38,11 @@ export const Word = React.createClass({ 'title': this.props.tooltip }; } - return <a {...tooltipAttrs} style={{ fontSize: this.props.size }} href={this.props.link}>{this.props.text}</a>; + return ( + <a {...tooltipAttrs} style={{ fontSize: this.props.size }} href={this.props.link}> + {this.props.text} + </a> + ); } }); @@ -50,28 +54,32 @@ export const WordCloud = React.createClass({ mixins: [TooltipsMixin], - getDefaultProps () { + getDefaultProps() { return { sizeRange: [10, 24] }; }, - render () { + render() { const len = this.props.items.length; const sortedItems = sortBy(this.props.items, (item, idx) => { const index = len - idx; - return (index % 2) * (len - index) + index / 2; + return index % 2 * (len - index) + index / 2; }); - const sizeScale = d3.scale.linear() - .domain([0, d3.max(this.props.items, d => d.size)]) - .range(this.props.sizeRange); - const words = sortedItems - .map((item, index) => <Word key={index} - text={item.text} - size={sizeScale(item.size)} - link={item.link} - tooltip={item.tooltip}/>); + const sizeScale = d3.scale + .linear() + .domain([0, d3.max(this.props.items, d => d.size)]) + .range(this.props.sizeRange); + const words = sortedItems.map((item, index) => ( + <Word + key={index} + text={item.text} + size={sizeScale(item.size)} + link={item.link} + tooltip={item.tooltip} + /> + )); return <div className="word-cloud">{words}</div>; } }); diff --git a/server/sonar-web/src/main/js/components/common/action-options-view.js b/server/sonar-web/src/main/js/components/common/action-options-view.js index a4070d8f782..976f88eb081 100644 --- a/server/sonar-web/src/main/js/components/common/action-options-view.js +++ b/server/sonar-web/src/main/js/components/common/action-options-view.js @@ -28,56 +28,60 @@ export default PopupView.extend({ options: '.menu > li > a' }, - events () { + events() { return { 'click @ui.options': 'selectOption', 'mouseenter @ui.options': 'activateOptionByPointer' }; }, - initialize () { + initialize() { this.bindShortcuts(); }, - onRender () { + onRender() { PopupView.prototype.onRender.apply(this, arguments); this.selectInitialOption(); }, - getOptions () { + getOptions() { return this.$('.menu > li > a'); }, - getActiveOption () { + getActiveOption() { return this.getOptions().filter('.active'); }, - makeActive (option) { + makeActive(option) { if (option.length > 0) { this.getOptions().removeClass('active').tooltip('hide'); option.addClass('active').tooltip('show'); } }, - selectInitialOption () { + selectInitialOption() { this.makeActive(this.getOptions().first()); }, - selectNextOption () { - this.makeActive(this.getActiveOption().parent().nextAll('li:not(.divider)').first().children('a')); + selectNextOption() { + this.makeActive( + this.getActiveOption().parent().nextAll('li:not(.divider)').first().children('a') + ); return false; }, - selectPreviousOption () { - this.makeActive(this.getActiveOption().parent().prevAll('li:not(.divider)').first().children('a')); + selectPreviousOption() { + this.makeActive( + this.getActiveOption().parent().prevAll('li:not(.divider)').first().children('a') + ); return false; }, - activateOptionByPointer (e) { + activateOptionByPointer(e) { this.makeActive($(e.currentTarget)); }, - bindShortcuts () { + bindShortcuts() { const that = this; this.currentKeyScope = key.getScope(); key.setScope(this.keyScope); @@ -89,7 +93,7 @@ export default PopupView.extend({ key('shift+tab', this.keyScope, () => false); }, - unbindShortcuts () { + unbindShortcuts() { key.unbind('down', this.keyScope); key.unbind('up', this.keyScope); key.unbind('return', this.keyScope); @@ -100,20 +104,19 @@ export default PopupView.extend({ key.setScope(this.currentKeyScope); }, - onDestroy () { + onDestroy() { PopupView.prototype.onDestroy.apply(this, arguments); this.unbindShortcuts(); this.$('[data-toggle="tooltip"]').tooltip('destroy'); $('.tooltip').remove(); }, - selectOption (e) { + selectOption(e) { e.preventDefault(); this.destroy(); }, - selectActiveOption () { + selectActiveOption() { this.getActiveOption().click(); } }); - diff --git a/server/sonar-web/src/main/js/components/common/file-upload.js b/server/sonar-web/src/main/js/components/common/file-upload.js index acfe19d7c94..8c5a2729101 100644 --- a/server/sonar-web/src/main/js/components/common/file-upload.js +++ b/server/sonar-web/src/main/js/components/common/file-upload.js @@ -20,31 +20,29 @@ import $ from 'jquery'; import uniqueId from 'lodash/uniqueId'; -function createFrame () { +function createFrame() { const uuid = uniqueId('upload-form-'); return $('<iframe></iframe>') - .prop('frameborder', 0) - .prop('width', 0) - .prop('height', 0) - .prop('id', uuid) - .prop('name', uuid) - .css('display', 'none'); + .prop('frameborder', 0) + .prop('width', 0) + .prop('height', 0) + .prop('id', uuid) + .prop('name', uuid) + .css('display', 'none'); } -export default function (options) { +export default function(options) { const deferred = new $.Deferred(); const body = $('body'); const frame = createFrame(); const parent = options.form.parent(); const clonedForm = options.form.detach(); - clonedForm - .prop('target', frame.prop('id')) - .appendTo(frame); + clonedForm.prop('target', frame.prop('id')).appendTo(frame); frame.appendTo(body); - frame.on('load', function () { + frame.on('load', function() { const result = this.contentWindow.document.body.textContent; try { const js = JSON.parse(result); @@ -60,4 +58,3 @@ export default function (options) { return deferred.promise(); } - diff --git a/server/sonar-web/src/main/js/components/common/modal-form.js b/server/sonar-web/src/main/js/components/common/modal-form.js index 5bc0041397a..dc766b2188a 100644 --- a/server/sonar-web/src/main/js/components/common/modal-form.js +++ b/server/sonar-web/src/main/js/components/common/modal-form.js @@ -20,14 +20,13 @@ import ModalView from './modals'; export default ModalView.extend({ - - ui () { + ui() { return { messagesContainer: '.js-modal-messages' }; }, - events () { + events() { return { ...ModalView.prototype.events.apply(this, arguments), 'keydown input,textarea,select': 'onInputKeydown', @@ -35,26 +34,29 @@ export default ModalView.extend({ }; }, - onRender () { + onRender() { ModalView.prototype.onRender.apply(this, arguments); const that = this; - setTimeout(() => { - that.$(':tabbable').first().focus(); - }, 0); + setTimeout( + () => { + that.$(':tabbable').first().focus(); + }, + 0 + ); }, - onInputKeydown (e) { + onInputKeydown(e) { if (e.keyCode === 27) { // escape this.destroy(); } }, - onFormSubmit (e) { + onFormSubmit(e) { e.preventDefault(); }, - showErrors (errors, warnings) { + showErrors(errors, warnings) { const container = this.ui.messagesContainer.empty(); if (Array.isArray(errors)) { errors.forEach(error => { @@ -71,28 +73,27 @@ export default ModalView.extend({ this.ui.messagesContainer.scrollParent().scrollTop(0); }, - showSingleError (msg) { + showSingleError(msg) { this.showErrors([{ msg }], []); }, - disableForm () { + disableForm() { const form = this.$('form'); this.disabledFields = form.find(':input:not(:disabled)'); this.disabledFields.prop('disabled', true); }, - enableForm () { + enableForm() { if (this.disabledFields != null) { this.disabledFields.prop('disabled', false); } }, - showSpinner () { + showSpinner() { this.$('.js-modal-spinner').removeClass('hidden'); }, - hideSpinner () { + hideSpinner() { this.$('.js-modal-spinner').addClass('hidden'); } }); - diff --git a/server/sonar-web/src/main/js/components/common/modals.js b/server/sonar-web/src/main/js/components/common/modals.js index d9518618ec5..5a1343bd511 100644 --- a/server/sonar-web/src/main/js/components/common/modals.js +++ b/server/sonar-web/src/main/js/components/common/modals.js @@ -27,13 +27,13 @@ export default Marionette.ItemView.extend({ overlayClassName: 'modal-overlay', htmlClassName: 'modal-open', - events () { + events() { return { 'click .js-modal-close': 'onCloseClick' }; }, - onRender () { + onRender() { const that = this; this.$el.detach().appendTo($('body')); $('html').addClass(this.htmlClassName); @@ -50,38 +50,41 @@ export default Marionette.ItemView.extend({ } }, - show () { + show() { const that = this; - setTimeout(() => { - that.$el.addClass('in'); - $('.' + that.overlayClassName).addClass('in'); - }, 0); + setTimeout( + () => { + that.$el.addClass('in'); + $('.' + that.overlayClassName).addClass('in'); + }, + 0 + ); }, - onDestroy () { + onDestroy() { $('html').removeClass(this.htmlClassName); this.removeOverlay(); key.deleteScope('modal'); key.setScope(this.keyScope); }, - onCloseClick (e) { + onCloseClick(e) { e.preventDefault(); this.destroy(); }, - renderOverlay () { + renderOverlay() { const overlay = $('.' + this.overlayClassName); if (overlay.length === 0) { $(`<div class="${this.overlayClassName}"></div>`).appendTo($('body')); } }, - removeOverlay () { + removeOverlay() { $('.' + this.overlayClassName).remove(); }, - attachCloseEvents () { + attachCloseEvents() { const that = this; $('body').on('click.' + EVENT_SCOPE, () => { $('body').off('click.' + EVENT_SCOPE); diff --git a/server/sonar-web/src/main/js/components/common/popup.js b/server/sonar-web/src/main/js/components/common/popup.js index af7d22f632c..532380f71b4 100644 --- a/server/sonar-web/src/main/js/components/common/popup.js +++ b/server/sonar-web/src/main/js/components/common/popup.js @@ -23,7 +23,7 @@ import Marionette from 'backbone.marionette'; export default Marionette.ItemView.extend({ className: 'bubble-popup', - onRender () { + onRender() { this.$el.detach().appendTo($('body')); const triggerEl = $(this.options.triggerEl); if (this.options.bottom) { @@ -47,7 +47,7 @@ export default Marionette.ItemView.extend({ this.attachCloseEvents(); }, - attachCloseEvents () { + attachCloseEvents() { const that = this; const triggerEl = $(this.options.triggerEl); key('escape', () => { @@ -64,7 +64,7 @@ export default Marionette.ItemView.extend({ }); }, - onDestroy () { + onDestroy() { $('body').off('click.bubble-popup'); const triggerEl = $(this.options.triggerEl); triggerEl.off('click.bubble-popup'); diff --git a/server/sonar-web/src/main/js/components/common/selectable-collection-view.js b/server/sonar-web/src/main/js/components/common/selectable-collection-view.js index c7cec999955..b0c8d2d5afd 100644 --- a/server/sonar-web/src/main/js/components/common/selectable-collection-view.js +++ b/server/sonar-web/src/main/js/components/common/selectable-collection-view.js @@ -20,36 +20,35 @@ import Marionette from 'backbone.marionette'; export default Marionette.CollectionView.extend({ - - initialize () { + initialize() { this.resetSelectedIndex(); this.listenTo(this.collection, 'reset', this.resetSelectedIndex); }, - childViewOptions (model, index) { + childViewOptions(model, index) { return { index }; }, - resetSelectedIndex () { + resetSelectedIndex() { this.selectedIndex = 0; }, - onRender () { + onRender() { this.selectCurrent(); }, - submitCurrent () { + submitCurrent() { const view = this.children.findByIndex(this.selectedIndex); if (view != null) { view.submit(); } }, - selectCurrent () { + selectCurrent() { this.selectItem(this.selectedIndex); }, - selectNext () { + selectNext() { if (this.selectedIndex < this.collection.length - 1) { this.deselectItem(this.selectedIndex); this.selectedIndex++; @@ -57,7 +56,7 @@ export default Marionette.CollectionView.extend({ } }, - selectPrev () { + selectPrev() { if (this.selectedIndex > 0) { this.deselectItem(this.selectedIndex); this.selectedIndex--; @@ -65,7 +64,7 @@ export default Marionette.CollectionView.extend({ } }, - selectItem (index) { + selectItem(index) { if (index >= 0 && index < this.collection.length) { const view = this.children.findByIndex(index); if (view != null) { @@ -74,11 +73,10 @@ export default Marionette.CollectionView.extend({ } }, - deselectItem (index) { + deselectItem(index) { const view = this.children.findByIndex(index); if (view != null) { view.deselect(); } } }); - diff --git a/server/sonar-web/src/main/js/components/controls/Checkbox.js b/server/sonar-web/src/main/js/components/controls/Checkbox.js index 718242c238f..e11fe009f75 100644 --- a/server/sonar-web/src/main/js/components/controls/Checkbox.js +++ b/server/sonar-web/src/main/js/components/controls/Checkbox.js @@ -32,24 +32,22 @@ export default class Checkbox extends React.Component { thirdState: false }; - componentWillMount () { + componentWillMount() { this.handleClick = this.handleClick.bind(this); } - handleClick (e) { + handleClick(e) { e.preventDefault(); e.target.blur(); this.props.onCheck(!this.props.checked); } - render () { + render() { const className = classNames('icon-checkbox', { 'icon-checkbox-checked': this.props.checked, 'icon-checkbox-single': this.props.thirdState }); - return ( - <a id={this.props.id} className={className} href="#" onClick={this.handleClick}/> - ); + return <a id={this.props.id} className={className} href="#" onClick={this.handleClick} />; } } diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.js b/server/sonar-web/src/main/js/components/controls/DateInput.js index 16bf61e51c1..7ceb11373e5 100644 --- a/server/sonar-web/src/main/js/components/controls/DateInput.js +++ b/server/sonar-web/src/main/js/components/controls/DateInput.js @@ -36,20 +36,20 @@ export default class DateInput extends React.Component { format: 'yy-mm-dd' }; - componentDidMount () { + componentDidMount() { this.attachDatePicker(); } - componentWillReceiveProps (nextProps) { + componentWillReceiveProps(nextProps) { this.refs.input.value = nextProps.value; } - handleChange () { + handleChange() { const { value } = this.refs.input; this.props.onChange(value); } - attachDatePicker () { + attachDatePicker() { const opts = { dateFormat: this.props.format, changeMonth: true, @@ -62,26 +62,26 @@ export default class DateInput extends React.Component { } } - render () { + render() { const inputProps = pick(this.props, ['placeholder', 'name']); /* eslint max-len: 0 */ return ( - <span className="date-input-control"> - <input - className="date-input-control-input" - ref="input" - type="text" - initialValue={this.props.value} - readOnly={true} - {...inputProps}/> - <span className="date-input-control-icon"> - <svg width="14" height="14" viewBox="0 0 16 16"> - <path - d="M5.5 6h2v2h-2V6zm3 0h2v2h-2V6zm3 0h2v2h-2V6zm-9 6h2v2h-2v-2zm3 0h2v2h-2v-2zm3 0h2v2h-2v-2zm-3-3h2v2h-2V9zm3 0h2v2h-2V9zm3 0h2v2h-2V9zm-9 0h2v2h-2V9zm11-9v1h-2V0h-7v1h-2V0h-2v16h15V0h-2zm1 15h-13V4h13v11z"/> - </svg> - </span> + <span className="date-input-control"> + <input + className="date-input-control-input" + ref="input" + type="text" + initialValue={this.props.value} + readOnly={true} + {...inputProps} + /> + <span className="date-input-control-icon"> + <svg width="14" height="14" viewBox="0 0 16 16"> + <path d="M5.5 6h2v2h-2V6zm3 0h2v2h-2V6zm3 0h2v2h-2V6zm-9 6h2v2h-2v-2zm3 0h2v2h-2v-2zm3 0h2v2h-2v-2zm-3-3h2v2h-2V9zm3 0h2v2h-2V9zm3 0h2v2h-2V9zm-9 0h2v2h-2V9zm11-9v1h-2V0h-7v1h-2V0h-2v16h15V0h-2zm1 15h-13V4h13v11z" /> + </svg> </span> + </span> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/Favorite.js b/server/sonar-web/src/main/js/components/controls/Favorite.js index af51ecfdcf6..56f9c41dc12 100644 --- a/server/sonar-web/src/main/js/components/controls/Favorite.js +++ b/server/sonar-web/src/main/js/components/controls/Favorite.js @@ -28,15 +28,16 @@ export default class Favorite extends React.Component { className: React.PropTypes.string }; - render () { + render() { const { favorite, component, ...other } = this.props; return ( - <FavoriteBase - {...other} - favorite={favorite} - addFavorite={() => addFavorite(component)} - removeFavorite={() => removeFavorite(component)}/> + <FavoriteBase + {...other} + favorite={favorite} + addFavorite={() => addFavorite(component)} + removeFavorite={() => removeFavorite(component)} + /> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/FavoriteBase.js b/server/sonar-web/src/main/js/components/controls/FavoriteBase.js index 9f62c173dda..59d6b544bc8 100644 --- a/server/sonar-web/src/main/js/components/controls/FavoriteBase.js +++ b/server/sonar-web/src/main/js/components/controls/FavoriteBase.js @@ -28,21 +28,21 @@ export default class FavoriteBase extends React.Component { className: React.PropTypes.string }; - constructor (props) { + constructor(props) { super(props); this.state = { favorite: this.props.favorite }; } - componentWillMount () { + componentWillMount() { this.mounted = true; this.toggleFavorite = this.toggleFavorite.bind(this); } - componentWillUnmount () { + componentWillUnmount() { this.mounted = false; } - toggleFavorite (e) { + toggleFavorite(e) { e.preventDefault(); if (this.state.favorite) { this.removeFavorite(); @@ -51,7 +51,7 @@ export default class FavoriteBase extends React.Component { } } - addFavorite () { + addFavorite() { this.props.addFavorite().then(() => { if (this.mounted) { this.setState({ favorite: true }); @@ -59,7 +59,7 @@ export default class FavoriteBase extends React.Component { }); } - removeFavorite () { + removeFavorite() { this.props.removeFavorite().then(() => { if (this.mounted) { this.setState({ favorite: false }); @@ -67,27 +67,28 @@ export default class FavoriteBase extends React.Component { }); } - renderSVG () { + renderSVG() { /* eslint max-len: 0 */ return ( - <svg width="16" height="16"> - <path - d="M15.4275,5.77678C15.4275,5.90773 15.3501,6.05059 15.1953,6.20536L11.9542,9.36608L12.7221,13.8304C12.728,13.872 12.731,13.9316 12.731,14.0089C12.731,14.1339 12.6998,14.2396 12.6373,14.3259C12.5748,14.4122 12.484,14.4554 12.3649,14.4554C12.2518,14.4554 12.1328,14.4197 12.0078,14.3482L7.99888,12.2411L3.98995,14.3482C3.85901,14.4197 3.73996,14.4554 3.63281,14.4554C3.50781,14.4554 3.41406,14.4122 3.35156,14.3259C3.28906,14.2396 3.25781,14.1339 3.25781,14.0089C3.25781,13.9732 3.26377,13.9137 3.27567,13.8304L4.04353,9.36608L0.793531,6.20536C0.644719,6.04464 0.570313,5.90178 0.570313,5.77678C0.570313,5.55654 0.736979,5.41964 1.07031,5.36606L5.55245,4.71428L7.56138,0.651781C7.67447,0.407729 7.8203,0.285703 7.99888,0.285703C8.17745,0.285703 8.32328,0.407729 8.43638,0.651781L10.4453,4.71428L14.9274,5.36606C15.2608,5.41964 15.4274,5.55654 15.4274,5.77678L15.4275,5.77678Z"/> - </svg> + <svg width="16" height="16"> + <path d="M15.4275,5.77678C15.4275,5.90773 15.3501,6.05059 15.1953,6.20536L11.9542,9.36608L12.7221,13.8304C12.728,13.872 12.731,13.9316 12.731,14.0089C12.731,14.1339 12.6998,14.2396 12.6373,14.3259C12.5748,14.4122 12.484,14.4554 12.3649,14.4554C12.2518,14.4554 12.1328,14.4197 12.0078,14.3482L7.99888,12.2411L3.98995,14.3482C3.85901,14.4197 3.73996,14.4554 3.63281,14.4554C3.50781,14.4554 3.41406,14.4122 3.35156,14.3259C3.28906,14.2396 3.25781,14.1339 3.25781,14.0089C3.25781,13.9732 3.26377,13.9137 3.27567,13.8304L4.04353,9.36608L0.793531,6.20536C0.644719,6.04464 0.570313,5.90178 0.570313,5.77678C0.570313,5.55654 0.736979,5.41964 1.07031,5.36606L5.55245,4.71428L7.56138,0.651781C7.67447,0.407729 7.8203,0.285703 7.99888,0.285703C8.17745,0.285703 8.32328,0.407729 8.43638,0.651781L10.4453,4.71428L14.9274,5.36606C15.2608,5.41964 15.4274,5.55654 15.4274,5.77678L15.4275,5.77678Z" /> + </svg> ); } - render () { - const className = classNames('icon-star', { - 'icon-star-favorite': this.state.favorite - }, this.props.className); + render() { + const className = classNames( + 'icon-star', + { + 'icon-star-favorite': this.state.favorite + }, + this.props.className + ); return ( - <a className={className} - href="#" - onClick={this.toggleFavorite}> - {this.renderSVG()} - </a> + <a className={className} href="#" onClick={this.toggleFavorite}> + {this.renderSVG()} + </a> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/FavoriteBaseStateless.js b/server/sonar-web/src/main/js/components/controls/FavoriteBaseStateless.js index 29ae7c1c537..67798ba2d4b 100644 --- a/server/sonar-web/src/main/js/components/controls/FavoriteBaseStateless.js +++ b/server/sonar-web/src/main/js/components/controls/FavoriteBaseStateless.js @@ -37,27 +37,28 @@ export default class FavoriteBaseStateless extends React.Component { } }; - renderSVG () { + renderSVG() { /* eslint max-len: 0 */ return ( - <svg width="16" height="16"> - <path - d="M15.4275,5.77678C15.4275,5.90773 15.3501,6.05059 15.1953,6.20536L11.9542,9.36608L12.7221,13.8304C12.728,13.872 12.731,13.9316 12.731,14.0089C12.731,14.1339 12.6998,14.2396 12.6373,14.3259C12.5748,14.4122 12.484,14.4554 12.3649,14.4554C12.2518,14.4554 12.1328,14.4197 12.0078,14.3482L7.99888,12.2411L3.98995,14.3482C3.85901,14.4197 3.73996,14.4554 3.63281,14.4554C3.50781,14.4554 3.41406,14.4122 3.35156,14.3259C3.28906,14.2396 3.25781,14.1339 3.25781,14.0089C3.25781,13.9732 3.26377,13.9137 3.27567,13.8304L4.04353,9.36608L0.793531,6.20536C0.644719,6.04464 0.570313,5.90178 0.570313,5.77678C0.570313,5.55654 0.736979,5.41964 1.07031,5.36606L5.55245,4.71428L7.56138,0.651781C7.67447,0.407729 7.8203,0.285703 7.99888,0.285703C8.17745,0.285703 8.32328,0.407729 8.43638,0.651781L10.4453,4.71428L14.9274,5.36606C15.2608,5.41964 15.4274,5.55654 15.4274,5.77678L15.4275,5.77678Z"/> - </svg> + <svg width="16" height="16"> + <path d="M15.4275,5.77678C15.4275,5.90773 15.3501,6.05059 15.1953,6.20536L11.9542,9.36608L12.7221,13.8304C12.728,13.872 12.731,13.9316 12.731,14.0089C12.731,14.1339 12.6998,14.2396 12.6373,14.3259C12.5748,14.4122 12.484,14.4554 12.3649,14.4554C12.2518,14.4554 12.1328,14.4197 12.0078,14.3482L7.99888,12.2411L3.98995,14.3482C3.85901,14.4197 3.73996,14.4554 3.63281,14.4554C3.50781,14.4554 3.41406,14.4122 3.35156,14.3259C3.28906,14.2396 3.25781,14.1339 3.25781,14.0089C3.25781,13.9732 3.26377,13.9137 3.27567,13.8304L4.04353,9.36608L0.793531,6.20536C0.644719,6.04464 0.570313,5.90178 0.570313,5.77678C0.570313,5.55654 0.736979,5.41964 1.07031,5.36606L5.55245,4.71428L7.56138,0.651781C7.67447,0.407729 7.8203,0.285703 7.99888,0.285703C8.17745,0.285703 8.32328,0.407729 8.43638,0.651781L10.4453,4.71428L14.9274,5.36606C15.2608,5.41964 15.4274,5.55654 15.4274,5.77678L15.4275,5.77678Z" /> + </svg> ); } - render () { - const className = classNames('icon-star', { - 'icon-star-favorite': this.props.favorite - }, this.props.className); + render() { + const className = classNames( + 'icon-star', + { + 'icon-star-favorite': this.props.favorite + }, + this.props.className + ); return ( - <a className={className} - href="#" - onClick={this.toggleFavorite}> - {this.renderSVG()} - </a> + <a className={className} href="#" onClick={this.toggleFavorite}> + {this.renderSVG()} + </a> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/FavoriteContainer.js b/server/sonar-web/src/main/js/components/controls/FavoriteContainer.js index bfbc383d7ad..ace5cc92000 100644 --- a/server/sonar-web/src/main/js/components/controls/FavoriteContainer.js +++ b/server/sonar-web/src/main/js/components/controls/FavoriteContainer.js @@ -25,23 +25,25 @@ import * as api from '../../api/favorites'; import { addGlobalErrorMessage } from '../../store/globalMessages/duck'; import { parseError } from '../../apps/code/utils'; -const addFavorite = componentKey => dispatch => { - // optimistic update - dispatch(actionCreators.addFavorite(componentKey)); - api.addFavorite(componentKey).catch(error => { - dispatch(actionCreators.removeFavorite(componentKey)); - parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); - }); -}; - -const removeFavorite = componentKey => dispatch => { - // optimistic update - dispatch(actionCreators.removeFavorite(componentKey)); - api.removeFavorite(componentKey).catch(error => { +const addFavorite = componentKey => + dispatch => { + // optimistic update dispatch(actionCreators.addFavorite(componentKey)); - parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); - }); -}; + api.addFavorite(componentKey).catch(error => { + dispatch(actionCreators.removeFavorite(componentKey)); + parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); + }); + }; + +const removeFavorite = componentKey => + dispatch => { + // optimistic update + dispatch(actionCreators.removeFavorite(componentKey)); + api.removeFavorite(componentKey).catch(error => { + dispatch(actionCreators.addFavorite(componentKey)); + parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); + }); + }; const mapStateToProps = (state, ownProps) => ({ favorite: isFavorite(state, ownProps.componentKey) @@ -52,7 +54,4 @@ const mapDispatchToProps = (dispatch, ownProps) => ({ removeFavorite: () => dispatch(removeFavorite(ownProps.componentKey)) }); -export default connect( - mapStateToProps, - mapDispatchToProps -)(FavoriteBaseStateless); +export default connect(mapStateToProps, mapDispatchToProps)(FavoriteBaseStateless); diff --git a/server/sonar-web/src/main/js/components/controls/FavoriteIssueFilter.js b/server/sonar-web/src/main/js/components/controls/FavoriteIssueFilter.js index 0f64018dc6b..21711b2a40a 100644 --- a/server/sonar-web/src/main/js/components/controls/FavoriteIssueFilter.js +++ b/server/sonar-web/src/main/js/components/controls/FavoriteIssueFilter.js @@ -29,12 +29,13 @@ export default class FavoriteIssueFilter extends React.Component { }).isRequired }; - render () { + render() { return ( - <FavoriteBase - favorite={this.props.favorite} - addFavorite={() => toggleIssueFilter(this.props.filter.id)} - removeFavorite={() => toggleIssueFilter(this.props.filter.id)}/> + <FavoriteBase + favorite={this.props.favorite} + addFavorite={() => toggleIssueFilter(this.props.filter.id)} + removeFavorite={() => toggleIssueFilter(this.props.filter.id)} + /> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/GlobalMessages.js b/server/sonar-web/src/main/js/components/controls/GlobalMessages.js index d1c4bb26c73..6af5ff31d2c 100644 --- a/server/sonar-web/src/main/js/components/controls/GlobalMessages.js +++ b/server/sonar-web/src/main/js/components/controls/GlobalMessages.js @@ -23,11 +23,13 @@ import { ERROR, SUCCESS } from '../../store/globalMessages/duck'; export default class GlobalMessages extends React.Component { static propTypes = { - messages: React.PropTypes.arrayOf(React.PropTypes.shape({ - id: React.PropTypes.string.isRequired, - message: React.PropTypes.string.isRequired, - level: React.PropTypes.oneOf([ERROR, SUCCESS]) - })), + messages: React.PropTypes.arrayOf( + React.PropTypes.shape({ + id: React.PropTypes.string.isRequired, + message: React.PropTypes.string.isRequired, + level: React.PropTypes.oneOf([ERROR, SUCCESS]) + }) + ), closeGlobalMessage: React.PropTypes.func.isRequired }; @@ -37,16 +39,19 @@ export default class GlobalMessages extends React.Component { 'process-spinner-success': message.level === SUCCESS }); return ( - <div key={message.id} className={className}> - {message.message} - <button className="process-spinner-close" onClick={() => this.props.closeGlobalMessage(message.id)}> - <i className="icon-close"/> - </button> - </div> + <div key={message.id} className={className}> + {message.message} + <button + className="process-spinner-close" + onClick={() => this.props.closeGlobalMessage(message.id)} + > + <i className="icon-close" /> + </button> + </div> ); }; - render () { + render() { const { messages } = this.props; if (messages.length === 0) { @@ -54,9 +59,9 @@ export default class GlobalMessages extends React.Component { } return ( - <div className="processes-container"> - {messages.map(this.renderMessage)} - </div> + <div className="processes-container"> + {messages.map(this.renderMessage)} + </div> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/ListFooter.js b/server/sonar-web/src/main/js/components/controls/ListFooter.js index 08335b06d60..ba8ea10eadd 100644 --- a/server/sonar-web/src/main/js/components/controls/ListFooter.js +++ b/server/sonar-web/src/main/js/components/controls/ListFooter.js @@ -34,41 +34,40 @@ export default class ListFooter extends React.PureComponent { ready: true }; - componentWillMount () { + componentWillMount() { this.handleLoadMore = this.handleLoadMore.bind(this); } - canLoadMore () { + canLoadMore() { return typeof this.props.loadMore === 'function'; } - handleLoadMore (e) { + handleLoadMore(e) { e.preventDefault(); e.target.blur(); this.props.loadMore(); } - render () { + render() { const hasMore = this.props.total > this.props.count; const loadMoreLink = ( - <a className="spacer-left" href="#" onClick={this.handleLoadMore}> - {translate('show_more')} - </a> - + <a className="spacer-left" href="#" onClick={this.handleLoadMore}> + {translate('show_more')} + </a> ); const className = classNames('spacer-top note text-center', { 'new-loading': !this.props.ready }); return ( - <footer className={className}> - {translateWithParameters( - 'x_of_y_shown', - formatMeasure(this.props.count, 'INT'), - formatMeasure(this.props.total, 'INT') - )} - {this.canLoadMore() && hasMore ? loadMoreLink : null} - </footer> + <footer className={className}> + {translateWithParameters( + 'x_of_y_shown', + formatMeasure(this.props.count, 'INT'), + formatMeasure(this.props.total, 'INT') + )} + {this.canLoadMore() && hasMore ? loadMoreLink : null} + </footer> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/RadioToggle.js b/server/sonar-web/src/main/js/components/controls/RadioToggle.js index ed52d809d10..a0617262651 100644 --- a/server/sonar-web/src/main/js/components/controls/RadioToggle.js +++ b/server/sonar-web/src/main/js/components/controls/RadioToggle.js @@ -22,10 +22,12 @@ import React from 'react'; export default class RadioToggle extends React.Component { static propTypes = { value: React.PropTypes.string, - options: React.PropTypes.arrayOf(React.PropTypes.shape({ - value: React.PropTypes.string.isRequired, - label: React.PropTypes.string.isRequired - })).isRequired, + options: React.PropTypes.arrayOf( + React.PropTypes.shape({ + value: React.PropTypes.string.isRequired, + label: React.PropTypes.string.isRequired + }) + ).isRequired, name: React.PropTypes.string.isRequired, onCheck: React.PropTypes.func.isRequired }; @@ -35,39 +37,40 @@ export default class RadioToggle extends React.Component { value: null }; - componentWillMount () { + componentWillMount() { this.renderOption = this.renderOption.bind(this); this.handleChange = this.handleChange.bind(this); } - handleChange (e) { + handleChange(e) { const newValue = e.currentTarget.value; this.props.onCheck(newValue); } - renderOption (option) { + renderOption(option) { const checked = option.value === this.props.value; const htmlId = this.props.name + '__' + option.value; return ( - <li key={option.value}> - <input - type="radio" - name={this.props.name} - value={option.value} - id={htmlId} - checked={checked} - onChange={this.handleChange}/> + <li key={option.value}> + <input + type="radio" + name={this.props.name} + value={option.value} + id={htmlId} + checked={checked} + onChange={this.handleChange} + /> - <label htmlFor={htmlId}>{option.label}</label> - </li> + <label htmlFor={htmlId}>{option.label}</label> + </li> ); } - render () { + render() { return ( - <ul className="radio-toggle"> - {this.props.options.map(this.renderOption)} - </ul> + <ul className="radio-toggle"> + {this.props.options.map(this.renderOption)} + </ul> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/Toggle.js b/server/sonar-web/src/main/js/components/controls/Toggle.js index bf79d801f81..7d6717bad2f 100644 --- a/server/sonar-web/src/main/js/components/controls/Toggle.js +++ b/server/sonar-web/src/main/js/components/controls/Toggle.js @@ -28,7 +28,7 @@ export default class Toggle extends React.Component { onChange: React.PropTypes.func }; - handleClick (e, value) { + handleClick(e, value) { e.preventDefault(); e.currentTarget.blur(); if (this.props.onChange) { @@ -36,16 +36,20 @@ export default class Toggle extends React.Component { } } - render () { + render() { const { value } = this.props; const booleanValue = typeof value === 'string' ? value === 'true' : value; const className = classNames('boolean-toggle', { 'boolean-toggle-on': booleanValue }); return ( - <button className={className} name={this.props.name} onClick={e => this.handleClick(e, booleanValue)}> - <div className="boolean-toggle-handle"/> - </button> + <button + className={className} + name={this.props.name} + onClick={e => this.handleClick(e, booleanValue)} + > + <div className="boolean-toggle-handle" /> + </button> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/Tooltip.js b/server/sonar-web/src/main/js/components/controls/Tooltip.js index 3c33ff6285f..bc300da8190 100644 --- a/server/sonar-web/src/main/js/components/controls/Tooltip.js +++ b/server/sonar-web/src/main/js/components/controls/Tooltip.js @@ -30,12 +30,9 @@ export default class Tooltip extends React.PureComponent { placement: 'bottom' }; - render () { + render() { return ( - <TooltipCore - destroyTooltipOnHide={true} - placement={this.props.placement} - {...this.props}/> + <TooltipCore destroyTooltipOnHide={true} placement={this.props.placement} {...this.props} /> ); } } diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/Checkbox-test.js b/server/sonar-web/src/main/js/components/controls/__tests__/Checkbox-test.js index d0c5bd36db8..dcb782f37cb 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/Checkbox-test.js +++ b/server/sonar-web/src/main/js/components/controls/__tests__/Checkbox-test.js @@ -23,30 +23,30 @@ import Checkbox from '../Checkbox'; import { click } from '../../../helpers/testUtils'; it('should render unchecked', () => { - const checkbox = shallow(<Checkbox checked={false} onCheck={() => true}/>); + const checkbox = shallow(<Checkbox checked={false} onCheck={() => true} />); expect(checkbox.is('.icon-checkbox-checked')).toBe(false); }); it('should render checked', () => { - const checkbox = shallow(<Checkbox checked={true} onCheck={() => true}/>); + const checkbox = shallow(<Checkbox checked={true} onCheck={() => true} />); expect(checkbox.is('.icon-checkbox-checked')).toBe(true); }); it('should render unchecked third state', () => { - const checkbox = shallow(<Checkbox checked={false} thirdState={true} onCheck={() => true}/>); + const checkbox = shallow(<Checkbox checked={false} thirdState={true} onCheck={() => true} />); expect(checkbox.is('.icon-checkbox-single')).toBe(true); expect(checkbox.is('.icon-checkbox-checked')).toBe(false); }); it('should render checked third state', () => { - const checkbox = shallow(<Checkbox checked={true} thirdState={true} onCheck={() => true}/>); + const checkbox = shallow(<Checkbox checked={true} thirdState={true} onCheck={() => true} />); expect(checkbox.is('.icon-checkbox-single')).toBe(true); expect(checkbox.is('.icon-checkbox-checked')).toBe(true); }); it('should call onCheck', () => { const onCheck = jest.fn(); - const checkbox = shallow(<Checkbox checked={false} onCheck={onCheck}/>); + const checkbox = shallow(<Checkbox checked={false} onCheck={onCheck} />); click(checkbox); expect(onCheck).toBeCalledWith(true); }); diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/FavoriteBase-test.js b/server/sonar-web/src/main/js/components/controls/__tests__/FavoriteBase-test.js index 5d54221e049..a22b38993eb 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/FavoriteBase-test.js +++ b/server/sonar-web/src/main/js/components/controls/__tests__/FavoriteBase-test.js @@ -22,13 +22,9 @@ import React from 'react'; import FavoriteBase from '../FavoriteBase'; import { click } from '../../../helpers/testUtils'; -function renderFavoriteBase (props) { +function renderFavoriteBase(props) { return shallow( - <FavoriteBase - favorite={true} - addFavorite={jest.fn()} - removeFavorite={jest.fn()} - {...props}/> + <FavoriteBase favorite={true} addFavorite={jest.fn()} removeFavorite={jest.fn()} {...props} /> ); } diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/ListFooter-test.js b/server/sonar-web/src/main/js/components/controls/__tests__/ListFooter-test.js index c4f29aaa98b..c8adb510bd5 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/ListFooter-test.js +++ b/server/sonar-web/src/main/js/components/controls/__tests__/ListFooter-test.js @@ -23,18 +23,18 @@ import ListFooter from '../ListFooter'; import { click } from '../../../helpers/testUtils'; it('should render "3 of 5 shown"', () => { - const listFooter = shallow(<ListFooter count={3} total={5}/>); + const listFooter = shallow(<ListFooter count={3} total={5} />); expect(listFooter.text()).toContain('x_of_y_shown.3.5'); }); it('should not render "show more"', () => { - const listFooter = shallow(<ListFooter count={3} total={5}/>); + const listFooter = shallow(<ListFooter count={3} total={5} />); expect(listFooter.find('a').length).toBe(0); }); it('should "show more"', () => { const loadMore = jest.fn(); - const listFooter = shallow(<ListFooter count={3} total={5} loadMore={loadMore}/>); + const listFooter = shallow(<ListFooter count={3} total={5} loadMore={loadMore} />); const link = listFooter.find('a'); expect(link.length).toBe(1); click(link); diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/RadioToggle-test.js b/server/sonar-web/src/main/js/components/controls/__tests__/RadioToggle-test.js index 68276673e1a..b23e070c41c 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/RadioToggle-test.js +++ b/server/sonar-web/src/main/js/components/controls/__tests__/RadioToggle-test.js @@ -22,18 +22,9 @@ import React from 'react'; import RadioToggle from '../RadioToggle'; import { change } from '../../../helpers/testUtils'; -function getSample (props) { - const options = [ - { value: 'one', label: 'first' }, - { value: 'two', label: 'second' } - ]; - return ( - <RadioToggle - options={options} - name="sample" - onCheck={() => true} - {...props}/> - ); +function getSample(props) { + const options = [{ value: 'one', label: 'first' }, { value: 'two', label: 'second' }]; + return <RadioToggle options={options} name="sample" onCheck={() => true} {...props} />; } it('should render', () => { diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/Toggle-test.js b/server/sonar-web/src/main/js/components/controls/__tests__/Toggle-test.js index f97b08b858b..6f2d2d8eea9 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/Toggle-test.js +++ b/server/sonar-web/src/main/js/components/controls/__tests__/Toggle-test.js @@ -22,9 +22,8 @@ import React from 'react'; import Toggle from '../Toggle'; import { click } from '../../../helpers/testUtils'; -function getSample (props) { - return ( - <Toggle value={true} onChange={() => true} {...props}/>); +function getSample(props) { + return <Toggle value={true} onChange={() => true} {...props} />; } it('should render', () => { diff --git a/server/sonar-web/src/main/js/components/issue/Issue.js b/server/sonar-web/src/main/js/components/issue/Issue.js index ce7781caabb..01c12f3b679 100644 --- a/server/sonar-web/src/main/js/components/issue/Issue.js +++ b/server/sonar-web/src/main/js/components/issue/Issue.js @@ -46,43 +46,43 @@ class Issue extends React.PureComponent { selected: false }; - componentDidMount () { + componentDidMount() { this.renderIssueView(); if (this.props.selected) { this.bindShortcuts(); } } - componentWillUpdate (nextProps: Props) { + componentWillUpdate(nextProps: Props) { if (!nextProps.selected && this.props.selected) { this.unbindShortcuts(); } this.destroyIssueView(); } - componentDidUpdate (prevProps: Props) { + componentDidUpdate(prevProps: Props) { this.renderIssueView(); if (!prevProps.selected && this.props.selected) { this.bindShortcuts(); } } - componentWillUnmount () { + componentWillUnmount() { if (this.props.selected) { this.unbindShortcuts(); } this.destroyIssueView(); } - bindShortcuts () { + bindShortcuts() { document.addEventListener('keypress', this.handleKeyPress); } - unbindShortcuts () { + unbindShortcuts() { document.removeEventListener('keypress', this.handleKeyPress); } - doIssueAction (action: string) { + doIssueAction(action: string) { this.issueView.$('.js-issue-' + action).click(); } @@ -92,18 +92,25 @@ class Issue extends React.PureComponent { if (shouldHandle) { switch (e.key) { - case 'f': return this.doIssueAction('transition'); - case 'a': return this.doIssueAction('assign'); - case 'm': return this.doIssueAction('assign-to-me'); - case 'p': return this.doIssueAction('plan'); - case 'i': return this.doIssueAction('set-severity'); - case 'c': return this.doIssueAction('comment'); - case 't': return this.doIssueAction('edit-tags'); + case 'f': + return this.doIssueAction('transition'); + case 'a': + return this.doIssueAction('assign'); + case 'm': + return this.doIssueAction('assign-to-me'); + case 'p': + return this.doIssueAction('plan'); + case 'i': + return this.doIssueAction('set-severity'); + case 'c': + return this.doIssueAction('comment'); + case 't': + return this.doIssueAction('edit-tags'); } } }; - renderIssueView () { + renderIssueView() { const model = this.props.issue.toJSON ? this.props.issue : new IssueModel(this.props.issue); this.issueView = new IssueView({ model, @@ -119,18 +126,19 @@ class Issue extends React.PureComponent { } } - destroyIssueView () { + destroyIssueView() { this.issueView.destroy(); } - render () { - return <div className="issue-container" ref={node => this.node = node}/>; + render() { + return <div className="issue-container" ref={node => this.node = node} />; } } -const onIssueChange = issue => dispatch => { - dispatch(receiveIssues([issue])); -}; +const onIssueChange = issue => + dispatch => { + dispatch(receiveIssues([issue])); + }; const mapDispatchToProps = { onIssueChange }; diff --git a/server/sonar-web/src/main/js/components/issue/collections/issues.js b/server/sonar-web/src/main/js/components/issue/collections/issues.js index c5499587190..69ac37b1beb 100644 --- a/server/sonar-web/src/main/js/components/issue/collections/issues.js +++ b/server/sonar-web/src/main/js/components/issue/collections/issues.js @@ -23,11 +23,11 @@ import Issue from '../models/issue'; export default Backbone.Collection.extend({ model: Issue, - url () { + url() { return window.baseUrl + '/api/issues/search'; }, - _injectRelational (issue, source, baseField, lookupField) { + _injectRelational(issue, source, baseField, lookupField) { const baseValue = issue[baseField]; if (baseValue != null && Array.isArray(source) && source.length > 0) { const lookupValue = source.find(candidate => candidate[lookupField] === baseValue); @@ -41,7 +41,7 @@ export default Backbone.Collection.extend({ return issue; }, - _injectCommentsRelational (issue, users) { + _injectCommentsRelational(issue, users) { if (issue.comments) { const that = this; const newComments = issue.comments.map(comment => { @@ -55,7 +55,7 @@ export default Backbone.Collection.extend({ return issue; }, - _prepareClosed (issue) { + _prepareClosed(issue) { if (issue.status === 'CLOSED') { issue.flows = []; delete issue.textRange; @@ -63,7 +63,7 @@ export default Backbone.Collection.extend({ return issue; }, - ensureTextRange (issue) { + ensureTextRange(issue) { if (issue.line && !issue.textRange) { // FIXME 999999 issue.textRange = { @@ -76,7 +76,7 @@ export default Backbone.Collection.extend({ return issue; }, - parse (r) { + parse(r) { const that = this; this.paging = { @@ -99,4 +99,3 @@ export default Backbone.Collection.extend({ }); } }); - diff --git a/server/sonar-web/src/main/js/components/issue/issue-view.js b/server/sonar-web/src/main/js/components/issue/issue-view.js index 0bb7fbd1b31..4e46200ad04 100644 --- a/server/sonar-web/src/main/js/components/issue/issue-view.js +++ b/server/sonar-web/src/main/js/components/issue/issue-view.js @@ -36,16 +36,16 @@ export default Marionette.ItemView.extend({ template: Template, modelEvents: { - 'change': 'notifyAndRender', - 'transition': 'onTransition' + change: 'notifyAndRender', + transition: 'onTransition' }, - className () { + className() { const hasCheckbox = this.options.onCheck != null; return hasCheckbox ? 'issue issue-with-checkbox' : 'issue'; }, - events () { + events() { return { 'click': 'handleClick', 'click .js-issue-comment': 'onComment', @@ -67,7 +67,7 @@ export default Marionette.ItemView.extend({ }; }, - notifyAndRender () { + notifyAndRender() { const { onIssueChange } = this.options; if (onIssueChange) { onIssueChange(this.model.toJSON()); @@ -79,19 +79,19 @@ export default Marionette.ItemView.extend({ } }, - onRender () { + onRender() { this.$el.attr('data-key', this.model.get('key')); }, - disableControls () { + disableControls() { this.$(':input').prop('disabled', true); }, - enableControls () { + enableControls() { this.$(':input').prop('disabled', false); }, - resetIssue (options) { + resetIssue(options) { const that = this; const key = this.model.get('key'); const componentUuid = this.model.get('componentUuid'); @@ -99,29 +99,31 @@ export default Marionette.ItemView.extend({ return this.model.fetch(options).done(() => that.trigger('reset')); }, - showChangeLog (e) { + showChangeLog(e) { e.preventDefault(); e.stopPropagation(); const that = this; const t = $(e.currentTarget); const changeLog = new ChangeLog(); - return changeLog.fetch({ - data: { issue: this.model.get('key') } - }).done(() => { - if (that.popup) { - that.popup.destroy(); - } - that.popup = new ChangeLogView({ - triggerEl: t, - bottomRight: true, - collection: changeLog, - issue: that.model + return changeLog + .fetch({ + data: { issue: this.model.get('key') } + }) + .done(() => { + if (that.popup) { + that.popup.destroy(); + } + that.popup = new ChangeLogView({ + triggerEl: t, + bottomRight: true, + collection: changeLog, + issue: that.model + }); + that.popup.render(); }); - that.popup.render(); - }); }, - updateAfterAction (response) { + updateAfterAction(response) { if (this.popup) { this.popup.destroy(); } @@ -130,12 +132,12 @@ export default Marionette.ItemView.extend({ } }, - onComment (e) { + onComment(e) { e.stopPropagation(); this.comment(); }, - comment (options) { + comment(options) { $('body').click(); this.popup = new CommentFormView({ triggerEl: this.$('.js-issue-comment'), @@ -147,7 +149,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - editComment (e) { + editComment(e) { e.stopPropagation(); $('body').click(); const commentEl = $(e.currentTarget).closest('.issue-comment'); @@ -163,7 +165,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - deleteComment (e) { + deleteComment(e) { e.stopPropagation(); $('body').click(); const commentEl = $(e.currentTarget).closest('.issue-comment'); @@ -182,7 +184,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - transition (e) { + transition(e) { e.stopPropagation(); $('body').click(); this.popup = new TransitionsFormView({ @@ -194,7 +196,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - setSeverity (e) { + setSeverity(e) { e.stopPropagation(); $('body').click(); this.popup = new SetSeverityFormView({ @@ -205,7 +207,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - setType (e) { + setType(e) { e.stopPropagation(); $('body').click(); this.popup = new SetTypeFormView({ @@ -216,7 +218,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - assign (e) { + assign(e) { e.stopPropagation(); $('body').click(); this.popup = new AssignFormView({ @@ -227,7 +229,7 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - assignToMe () { + assignToMe() { const view = new AssignFormView({ model: this.model, triggerEl: $('body') @@ -237,7 +239,7 @@ export default Marionette.ItemView.extend({ view.destroy(); }, - showRule (e) { + showRule(e) { e.preventDefault(); e.stopPropagation(); const ruleKey = this.model.get('rule'); @@ -246,14 +248,15 @@ export default Marionette.ItemView.extend({ Workspace.openRule({ key: ruleKey }); }, - action (action) { + action(action) { this.disableControls(); - return this.model.customAction(action) - .done(r => this.updateAfterAction(r)) - .fail(() => this.enableControls()); + return this.model + .customAction(action) + .done(r => this.updateAfterAction(r)) + .fail(() => this.enableControls()); }, - editTags (e) { + editTags(e) { e.stopPropagation(); $('body').click(); this.popup = new TagsFormView({ @@ -264,25 +267,25 @@ export default Marionette.ItemView.extend({ this.popup.render(); }, - showLocations () { + showLocations() { this.model.trigger('locations', this.model); }, - select () { + select() { this.$el.addClass('selected'); }, - unselect () { + unselect() { this.$el.removeClass('selected'); }, - onTransition (transition) { + onTransition(transition) { if (transition === 'falsepositive' || transition === 'wontfix') { this.comment({ fromTransition: true }); } }, - handleClick (e) { + handleClick(e) { e.preventDefault(); const { onClick } = this.options; if (onClick) { @@ -290,19 +293,19 @@ export default Marionette.ItemView.extend({ } }, - filterSimilarIssues (e) { + filterSimilarIssues(e) { this.options.onFilterClick(e); }, - onIssueCheck (e) { + onIssueCheck(e) { this.options.onCheck(e); }, - onPermalinkClick (e) { + onPermalinkClick(e) { e.stopPropagation(); }, - serializeData () { + serializeData() { const issueKey = encodeURIComponent(this.model.get('key')); return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), diff --git a/server/sonar-web/src/main/js/components/issue/models/changelog.js b/server/sonar-web/src/main/js/components/issue/models/changelog.js index 4c95e551847..bf1150a310a 100644 --- a/server/sonar-web/src/main/js/components/issue/models/changelog.js +++ b/server/sonar-web/src/main/js/components/issue/models/changelog.js @@ -20,12 +20,11 @@ import Backbone from 'backbone'; export default Backbone.Collection.extend({ - url () { + url() { return window.baseUrl + '/api/issues/changelog'; }, - parse (r) { + parse(r) { return r.changelog; } }); - diff --git a/server/sonar-web/src/main/js/components/issue/models/issue.js b/server/sonar-web/src/main/js/components/issue/models/issue.js index 7675e8bcc4c..1abeee02e24 100644 --- a/server/sonar-web/src/main/js/components/issue/models/issue.js +++ b/server/sonar-web/src/main/js/components/issue/models/issue.js @@ -22,21 +22,21 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ idAttribute: 'key', - defaults () { + defaults() { return { flows: [] }; }, - url () { + url() { return window.baseUrl + '/api/issues'; }, - urlRoot () { + urlRoot() { return window.baseUrl + '/api/issues'; }, - parse (r) { + parse(r) { let issue = Array.isArray(r.issues) && r.issues.length > 0 ? r.issues[0] : r.issue; if (issue) { issue = this._injectRelational(issue, r.components, 'component', 'key'); @@ -53,7 +53,7 @@ export default Backbone.Model.extend({ } }, - _injectRelational (issue, source, baseField, lookupField) { + _injectRelational(issue, source, baseField, lookupField) { const baseValue = issue[baseField]; if (baseValue != null && Array.isArray(source) && source.length > 0) { const lookupValue = source.find(candidate => candidate[lookupField] === baseValue); @@ -67,7 +67,7 @@ export default Backbone.Model.extend({ return issue; }, - _injectCommentsRelational (issue, users) { + _injectCommentsRelational(issue, users) { if (issue.comments) { const newComments = issue.comments.map(comment => { let newComment = { ...comment, author: comment.login }; @@ -80,7 +80,7 @@ export default Backbone.Model.extend({ return issue; }, - _prepareClosed (issue) { + _prepareClosed(issue) { if (issue.status === 'CLOSED') { issue.flows = []; delete issue.textRange; @@ -88,7 +88,7 @@ export default Backbone.Model.extend({ return issue; }, - ensureTextRange (issue) { + ensureTextRange(issue) { if (issue.line && !issue.textRange) { // FIXME 999999 issue.textRange = { @@ -101,7 +101,7 @@ export default Backbone.Model.extend({ return issue; }, - sync (method, model, options) { + sync(method, model, options) { const opts = options || {}; opts.contentType = 'application/x-www-form-urlencoded'; if (method === 'read') { @@ -127,7 +127,7 @@ export default Backbone.Model.extend({ } }); } - const xhr = options.xhr = Backbone.ajax(opts); + const xhr = (options.xhr = Backbone.ajax(opts)); model.trigger('request', model, xhr, opts); return xhr; }, @@ -138,7 +138,7 @@ export default Backbone.Model.extend({ * @param options * @returns {Object} */ - reset (attrs, options) { + reset(attrs, options) { for (const key in this.attributes) { if (this.attributes.hasOwnProperty(key) && !(key in attrs)) { attrs[key] = void 0; @@ -153,9 +153,9 @@ export default Backbone.Model.extend({ * @returns {jqXHR} * @private */ - _action (options) { + _action(options) { const that = this; - const success = function (r) { + const success = function(r) { const attrs = that.parse(r); that.reset(attrs); if (options.success) { @@ -163,7 +163,7 @@ export default Backbone.Model.extend({ } }; const opts = { type: 'POST', ...options, success }; - const xhr = options.xhr = Backbone.ajax(opts); + const xhr = (options.xhr = Backbone.ajax(opts)); this.trigger('request', this, xhr, opts); return xhr; }, @@ -174,7 +174,7 @@ export default Backbone.Model.extend({ * @param {Object|null} options Options for jQuery ajax * @returns {jqXHR} */ - assign (assignee, options) { + assign(assignee, options) { const opts = { url: this.urlRoot() + '/assign', data: { issue: this.id, assignee }, @@ -189,7 +189,7 @@ export default Backbone.Model.extend({ * @param {Object|null} options Options for jQuery ajax * @returns {jqXHR} */ - plan (plan, options) { + plan(plan, options) { const opts = { url: this.urlRoot() + '/plan', data: { issue: this.id, plan }, @@ -204,7 +204,7 @@ export default Backbone.Model.extend({ * @param {Object|null} options Options for jQuery ajax * @returns {jqXHR} */ - setSeverity (severity, options) { + setSeverity(severity, options) { const opts = { url: this.urlRoot() + '/set_severity', data: { issue: this.id, severity }, @@ -219,7 +219,7 @@ export default Backbone.Model.extend({ * @param {Object|null} options Options for jQuery ajax * @returns {jqXHR} */ - transition (transition, options) { + transition(transition, options) { const that = this; const opts = { url: this.urlRoot() + '/do_transition', @@ -237,7 +237,7 @@ export default Backbone.Model.extend({ * @param {Object|null} options Options for jQuery ajax * @returns {jqXHR} */ - setType (issueType, options) { + setType(issueType, options) { const opts = { url: this.urlRoot() + '/set_type', data: { issue: this.id, type: issueType }, @@ -252,7 +252,7 @@ export default Backbone.Model.extend({ * @param {Object|null} options Options for jQuery ajax * @returns {jqXHR} */ - customAction (actionKey, options) { + customAction(actionKey, options) { const opts = { type: 'POST', url: this.urlRoot() + '/do_action', @@ -264,7 +264,7 @@ export default Backbone.Model.extend({ return xhr; }, - getLinearLocations () { + getLinearLocations() { const textRange = this.get('textRange'); if (!textRange) { return []; diff --git a/server/sonar-web/src/main/js/components/issue/views/DeleteCommentView.js b/server/sonar-web/src/main/js/components/issue/views/DeleteCommentView.js index d63c28d899a..3360de2f416 100644 --- a/server/sonar-web/src/main/js/components/issue/views/DeleteCommentView.js +++ b/server/sonar-web/src/main/js/components/issue/views/DeleteCommentView.js @@ -27,7 +27,7 @@ export default PopupView.extend({ 'click button': 'handleSubmit' }, - handleSubmit (e) { + handleSubmit(e) { e.preventDefault(); this.options.onDelete(); } diff --git a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js index 35344cf0999..c0a738e4f01 100644 --- a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js @@ -30,7 +30,7 @@ export default ActionOptionsView.extend({ template: Template, optionTemplate: OptionTemplate, - events () { + events() { return { ...ActionOptionsView.prototype.events.apply(this, arguments), 'click input': 'onInputClick', @@ -39,57 +39,60 @@ export default ActionOptionsView.extend({ }; }, - initialize () { + initialize() { ActionOptionsView.prototype.initialize.apply(this, arguments); this.assignees = null; this.debouncedSearch = debounce(this.search, 250); }, - getAssignee () { + getAssignee() { return this.model.get('assignee'); }, - getAssigneeName () { + getAssigneeName() { return this.model.get('assigneeName'); }, - onRender () { + onRender() { const that = this; ActionOptionsView.prototype.onRender.apply(this, arguments); this.renderTags(); - setTimeout(() => { - that.$('input').focus(); - }, 100); + setTimeout( + () => { + that.$('input').focus(); + }, + 100 + ); }, - renderTags () { + renderTags() { this.$('.menu').empty(); this.getAssignees().forEach(this.renderAssignee, this); this.bindUIElements(); this.selectInitialOption(); }, - renderAssignee (assignee) { + renderAssignee(assignee) { const html = this.optionTemplate(assignee); this.$('.menu').append(html); }, - selectOption (e) { + selectOption(e) { const assignee = $(e.currentTarget).data('value'); const assigneeName = $(e.currentTarget).data('text'); this.submit(assignee, assigneeName); return ActionOptionsView.prototype.selectOption.apply(this, arguments); }, - submit (assignee) { + submit(assignee) { return this.model.assign(assignee); }, - onInputClick (e) { + onInputClick(e) { e.stopPropagation(); }, - onInputKeydown (e) { + onInputKeydown(e) { this.query = this.$('input').val(); if (e.keyCode === 38) { this.selectPreviousOption(); @@ -108,7 +111,7 @@ export default ActionOptionsView.extend({ } }, - onInputKeyup () { + onInputKeyup() { let query = this.$('input').val(); if (query !== this.query) { if (query.length < 2) { @@ -119,7 +122,7 @@ export default ActionOptionsView.extend({ } }, - search (query) { + search(query) { const that = this; if (query.length > 1) { $.get(window.baseUrl + '/api/users/search', { q: query }).done(data => { @@ -130,7 +133,7 @@ export default ActionOptionsView.extend({ } }, - resetAssignees (users) { + resetAssignees(users) { if (users) { this.assignees = users.map(user => { return { id: user.login, text: user.name }; @@ -141,7 +144,7 @@ export default ActionOptionsView.extend({ this.renderTags(); }, - getAssignees () { + getAssignees() { if (this.assignees) { return this.assignees; } @@ -153,7 +156,7 @@ export default ActionOptionsView.extend({ return this.makeUnique(assignees); }, - makeUnique (assignees) { + makeUnique(assignees) { return uniqBy(assignees, assignee => assignee.id); } }); diff --git a/server/sonar-web/src/main/js/components/issue/views/changelog-view.js b/server/sonar-web/src/main/js/components/issue/views/changelog-view.js index f57d968f14d..b04b56abd6a 100644 --- a/server/sonar-web/src/main/js/components/issue/views/changelog-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/changelog-view.js @@ -24,10 +24,10 @@ export default PopupView.extend({ template: Template, collectionEvents: { - 'sync': 'render' + sync: 'render' }, - serializeData () { + serializeData() { return { ...PopupView.prototype.serializeData.apply(this, arguments), issue: this.options.issue.toJSON() diff --git a/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js b/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js index 2519c38eb5f..8b83fc9600f 100644 --- a/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/comment-form-view.js @@ -39,23 +39,26 @@ export default PopupView.extend({ 'click @ui.submitButton': 'submit' }, - onRender () { + onRender() { const that = this; PopupView.prototype.onRender.apply(this, arguments); - setTimeout(() => { - that.ui.textarea.focus(); - }, 100); + setTimeout( + () => { + that.ui.textarea.focus(); + }, + 100 + ); }, - toggleSubmit () { + toggleSubmit() { this.ui.submitButton.prop('disabled', this.ui.textarea.val().length === 0); }, - onClick (e) { + onClick(e) { e.stopPropagation(); }, - onKeydown (e) { + onKeydown(e) { if (e.keyCode === 27) { this.destroy(); } @@ -64,19 +67,19 @@ export default PopupView.extend({ } }, - cancel () { + cancel() { this.options.detailView.updateAfterAction(); }, - disableForm () { + disableForm() { this.$(':input').prop('disabled', true); }, - enableForm () { + enableForm() { this.$(':input').prop('disabled', false); }, - submit () { + submit() { const text = this.ui.textarea.val(); if (!text.length) { @@ -94,15 +97,13 @@ export default PopupView.extend({ } this.disableForm(); this.options.detailView.disableControls(); - $.post(url, data) - .done(r => this.options.detailView.updateAfterAction(r)) - .fail(() => { - this.enableForm(); - this.options.detailView.enableControls(); - }); + $.post(url, data).done(r => this.options.detailView.updateAfterAction(r)).fail(() => { + this.enableForm(); + this.options.detailView.enableControls(); + }); }, - serializeData () { + serializeData() { const options = { fromTransition: false, ...this.options.additionalOptions }; return { ...PopupView.prototype.serializeData.apply(this, arguments), @@ -110,4 +111,3 @@ export default PopupView.extend({ }; } }); - diff --git a/server/sonar-web/src/main/js/components/issue/views/issue-popup.js b/server/sonar-web/src/main/js/components/issue/views/issue-popup.js index 4462e3f6b94..96488cd1e45 100644 --- a/server/sonar-web/src/main/js/components/issue/views/issue-popup.js +++ b/server/sonar-web/src/main/js/components/issue/views/issue-popup.js @@ -22,28 +22,25 @@ import PopupView from '../../common/popup'; export default PopupView.extend({ className: 'bubble-popup issue-bubble-popup', - template () { + template() { return '<div class="bubble-popup-arrow"></div>'; }, - events () { + events() { return { 'click .js-issue-form-cancel': 'destroy' }; }, - onRender () { + onRender() { PopupView.prototype.onRender.apply(this, arguments); this.options.view.$el.appendTo(this.$el); this.options.view.render(); }, - onDestroy () { + onDestroy() { this.options.view.destroy(); }, - attachCloseEvents () { - - } + attachCloseEvents() {} }); - diff --git a/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js b/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js index 0a207af63ce..b30c689e1e9 100644 --- a/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/set-severity-form-view.js @@ -24,29 +24,28 @@ import Template from '../templates/issue-set-severity-form.hbs'; export default ActionOptionsView.extend({ template: Template, - getTransition () { + getTransition() { return this.model.get('severity'); }, - selectInitialOption () { + selectInitialOption() { return this.makeActive(this.getOptions().filter(`[data-value="${this.getTransition()}"]`)); }, - selectOption (e) { + selectOption(e) { const severity = $(e.currentTarget).data('value'); this.submit(severity); return ActionOptionsView.prototype.selectOption.apply(this, arguments); }, - submit (severity) { + submit(severity) { return this.model.setSeverity(severity); }, - serializeData () { + serializeData() { return { ...ActionOptionsView.prototype.serializeData.apply(this, arguments), items: ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO'] }; } }); - diff --git a/server/sonar-web/src/main/js/components/issue/views/set-type-form-view.js b/server/sonar-web/src/main/js/components/issue/views/set-type-form-view.js index 255ffce5e70..719d679e762 100644 --- a/server/sonar-web/src/main/js/components/issue/views/set-type-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/set-type-form-view.js @@ -24,29 +24,28 @@ import Template from '../templates/issue-set-type-form.hbs'; export default ActionOptionsView.extend({ template: Template, - getType () { + getType() { return this.model.get('type'); }, - selectInitialOption () { + selectInitialOption() { return this.makeActive(this.getOptions().filter(`[data-value="${this.getType()}"]`)); }, - selectOption (e) { + selectOption(e) { const issueType = $(e.currentTarget).data('value'); this.submit(issueType); return ActionOptionsView.prototype.selectOption.apply(this, arguments); }, - submit (issueType) { + submit(issueType) { return this.model.setType(issueType); }, - serializeData () { + serializeData() { return { ...ActionOptionsView.prototype.serializeData.apply(this, arguments), items: ['BUG', 'VULNERABILITY', 'CODE_SMELL'] }; } }); - diff --git a/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js b/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js index 16370fdac71..db9360a9782 100644 --- a/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/tags-form-view.js @@ -33,7 +33,7 @@ export default ActionOptionsView.extend({ 'change:tags': 'renderTags' }, - events () { + events() { return { ...ActionOptionsView.prototype.events.apply(this, arguments), 'click input': 'onInputClick', @@ -42,7 +42,7 @@ export default ActionOptionsView.extend({ }; }, - initialize () { + initialize() { ActionOptionsView.prototype.initialize.apply(this, arguments); this.query = ''; this.tags = []; @@ -51,7 +51,7 @@ export default ActionOptionsView.extend({ this.requestTags(); }, - requestTags (query) { + requestTags(query) { const that = this; return $.get(window.baseUrl + '/api/issues/tags', { ps: 10, q: query }).done(data => { that.tags = data.tags; @@ -59,35 +59,42 @@ export default ActionOptionsView.extend({ }); }, - onRender () { + onRender() { const that = this; ActionOptionsView.prototype.onRender.apply(this, arguments); this.renderTags(); - setTimeout(() => { - that.$('input').focus(); - }, 100); + setTimeout( + () => { + that.$('input').focus(); + }, + 100 + ); }, - selectInitialOption () { + selectInitialOption() { this.selected = Math.max(Math.min(this.selected, this.getOptions().length - 1), 0); this.makeActive(this.getOptions().eq(this.selected)); }, - filterTags (tags) { + filterTags(tags) { return tags.filter(tag => tag.indexOf(this.query) !== -1); }, - renderTags () { + renderTags() { this.$('.menu').empty(); this.filterTags(this.getTags()).forEach(this.renderSelectedTag, this); this.filterTags(difference(this.tags, this.getTags())).forEach(this.renderTag, this); - if (this.query.length > 0 && this.tags.indexOf(this.query) === -1 && this.getTags().indexOf(this.query) === -1) { + if ( + this.query.length > 0 && + this.tags.indexOf(this.query) === -1 && + this.getTags().indexOf(this.query) === -1 + ) { this.renderCustomTag(this.query); } this.selectInitialOption(); }, - renderSelectedTag (tag) { + renderSelectedTag(tag) { const html = this.optionTemplate({ tag, selected: true, @@ -96,7 +103,7 @@ export default ActionOptionsView.extend({ return this.$('.menu').append(html); }, - renderTag (tag) { + renderTag(tag) { const html = this.optionTemplate({ tag, selected: false, @@ -105,7 +112,7 @@ export default ActionOptionsView.extend({ return this.$('.menu').append(html); }, - renderCustomTag (tag) { + renderCustomTag(tag) { const html = this.optionTemplate({ tag, selected: false, @@ -114,7 +121,7 @@ export default ActionOptionsView.extend({ return this.$('.menu').append(html); }, - selectOption (e) { + selectOption(e) { e.preventDefault(); e.stopPropagation(); let tags = this.getTags().slice(); @@ -128,7 +135,7 @@ export default ActionOptionsView.extend({ return this.submit(tags); }, - submit (tags) { + submit(tags) { const that = this; const _tags = this.getTags(); this.model.set({ tags }); @@ -142,11 +149,11 @@ export default ActionOptionsView.extend({ }).fail(() => that.model.set({ tags: _tags })); }, - onInputClick (e) { + onInputClick(e) { e.stopPropagation(); }, - onInputKeydown (e) { + onInputKeydown(e) { this.query = this.$('input').val(); if (e.keyCode === 38) { this.selectPreviousOption(); @@ -165,7 +172,7 @@ export default ActionOptionsView.extend({ } }, - onInputKeyup () { + onInputKeyup() { const query = this.$('input').val(); if (query !== this.query) { this.query = query; @@ -173,20 +180,19 @@ export default ActionOptionsView.extend({ } }, - search (query) { + search(query) { this.query = query; return this.requestTags(query); }, - resetAssignees (users) { + resetAssignees(users) { this.assignees = users.map(user => { return { id: user.login, text: user.name }; }); this.renderTags(); }, - getTags () { + getTags() { return this.model.get('tags') || []; } }); - diff --git a/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js b/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js index 3e9ff23d20c..0a44b5a4b22 100644 --- a/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/transitions-form-view.js @@ -24,18 +24,17 @@ import Template from '../templates/issue-transitions-form.hbs'; export default ActionOptionsView.extend({ template: Template, - selectInitialOption () { + selectInitialOption() { this.makeActive(this.getOptions().first()); }, - selectOption (e) { + selectOption(e) { const transition = $(e.currentTarget).data('value'); this.submit(transition); return ActionOptionsView.prototype.selectOption.apply(this, arguments); }, - submit (transition) { + submit(transition) { return this.model.transition(transition); } }); - diff --git a/server/sonar-web/src/main/js/components/mixins/resize-mixin.js b/server/sonar-web/src/main/js/components/mixins/resize-mixin.js index 895e676373b..781fe5fae56 100644 --- a/server/sonar-web/src/main/js/components/mixins/resize-mixin.js +++ b/server/sonar-web/src/main/js/components/mixins/resize-mixin.js @@ -20,27 +20,27 @@ import ReactDOM from 'react-dom'; export const ResizeMixin = { - componentDidMount () { + componentDidMount() { if (this.isResizable()) { this.handleResize(); window.addEventListener('resize', this.handleResize); } }, - componentWillUnmount () { + componentWillUnmount() { if (this.isResizable()) { window.removeEventListener('resize', this.handleResize); } }, - handleResize () { + handleResize() { const boundingClientRect = ReactDOM.findDOMNode(this).parentNode.getBoundingClientRect(); const newWidth = this.props.width || boundingClientRect.width; const newHeight = this.props.height || boundingClientRect.height; this.setState({ width: newWidth, height: newHeight }); }, - isResizable () { + isResizable() { return !this.props.width || !this.props.height; } }; diff --git a/server/sonar-web/src/main/js/components/mixins/tooltips-mixin.js b/server/sonar-web/src/main/js/components/mixins/tooltips-mixin.js index 30ffd90af80..06bb959482f 100644 --- a/server/sonar-web/src/main/js/components/mixins/tooltips-mixin.js +++ b/server/sonar-web/src/main/js/components/mixins/tooltips-mixin.js @@ -22,84 +22,85 @@ import React from 'react'; import ReactDOM from 'react-dom'; export const TooltipsMixin = { - componentDidMount () { + componentDidMount() { this.initTooltips(); }, - componentWillUpdate () { + componentWillUpdate() { this.hideTooltips(); }, - componentDidUpdate () { + componentDidUpdate() { this.initTooltips(); }, - componentWillUnmount () { + componentWillUnmount() { this.destroyTooltips(); }, - initTooltips () { + initTooltips() { if ($.fn && $.fn.tooltip) { - $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)) - .tooltip({ container: 'body', placement: 'bottom', html: true }); + $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)).tooltip({ + container: 'body', + placement: 'bottom', + html: true + }); } }, - hideTooltips () { + hideTooltips() { if ($.fn && $.fn.tooltip) { - $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)) - .tooltip('hide'); + $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)).tooltip('hide'); } }, - destroyTooltips () { + destroyTooltips() { if ($.fn && $.fn.tooltip) { - $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)) - .tooltip('destroy'); + $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)).tooltip('destroy'); } } }; export const TooltipsContainer = React.createClass({ - componentDidMount () { + componentDidMount() { this.initTooltips(); }, - componentWillUpdate () { + componentWillUpdate() { this.destroyTooltips(); }, - componentDidUpdate () { + componentDidUpdate() { this.initTooltips(); }, - componentWillUnmount () { + componentWillUnmount() { this.destroyTooltips(); }, - initTooltips () { + initTooltips() { if ($.fn && $.fn.tooltip) { - const options = Object.assign({ container: 'body', placement: 'bottom', html: true }, this.props.options); - $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)) - .tooltip(options); + const options = Object.assign( + { container: 'body', placement: 'bottom', html: true }, + this.props.options + ); + $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)).tooltip(options); } }, - hideTooltips () { + hideTooltips() { if ($.fn && $.fn.tooltip) { - $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)) - .tooltip('hide'); + $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)).tooltip('hide'); } }, - destroyTooltips () { + destroyTooltips() { if ($.fn && $.fn.tooltip) { - $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)) - .tooltip('destroy'); + $('[data-toggle="tooltip"]', ReactDOM.findDOMNode(this)).tooltip('destroy'); } }, - render () { + render() { return this.props.children; } }); diff --git a/server/sonar-web/src/main/js/components/navigator/controller.js b/server/sonar-web/src/main/js/components/navigator/controller.js index 76c415cfeb5..27769a53b78 100644 --- a/server/sonar-web/src/main/js/components/navigator/controller.js +++ b/server/sonar-web/src/main/js/components/navigator/controller.js @@ -23,64 +23,64 @@ import Marionette from 'backbone.marionette'; export default Marionette.Controller.extend({ pageSize: 50, - initialize (options) { + initialize(options) { this.app = options.app; this.listenTo(options.app.state, 'change:query', this.fetchList); }, - _allFacets () { + _allFacets() { return this.options.app.state.get('allFacets').map(facet => { return { property: facet }; }); }, - _enabledFacets () { + _enabledFacets() { const that = this; let facets = this.options.app.state.get('facets'); const criteria = Object.keys(this.options.app.state.get('query')); facets = facets.concat(criteria); facets = facets.map(facet => { - return that.options.app.state.get('transform')[facet] != null ? - that.options.app.state.get('transform')[facet] : facet; + return that.options.app.state.get('transform')[facet] != null + ? that.options.app.state.get('transform')[facet] + : facet; }); facets = uniq(facets); return facets.filter(facet => that.options.app.state.get('allFacets').indexOf(facet) !== -1); }, - _facetsFromServer () { + _facetsFromServer() { const that = this; const facets = this._enabledFacets(); - return facets.filter(facet => that.options.app.state.get('facetsFromServer').indexOf(facet) !== -1); + return facets.filter( + facet => that.options.app.state.get('facetsFromServer').indexOf(facet) !== -1 + ); }, - fetchList () { + fetchList() {}, - }, - - fetchNextPage () { + fetchNextPage() { this.options.app.state.nextPage(); return this.fetchList(false); }, - enableFacet (id) { + enableFacet(id) { const facet = this.options.app.facets.get(id); if (facet.has('values') || this.options.app.state.get('facetsFromServer').indexOf(id) === -1) { facet.set({ enabled: true }); } else { - this.requestFacet(id) - .done(() => { - facet.set({ enabled: true }); - }); + this.requestFacet(id).done(() => { + facet.set({ enabled: true }); + }); } }, - disableFacet (id) { + disableFacet(id) { const facet = this.options.app.facets.get(id); facet.set({ enabled: false }); this.options.app.facetsView.children.findByModel(facet).disable(); }, - toggleFacet (id) { + toggleFacet(id) { const facet = this.options.app.facets.get(id); if (facet.get('enabled')) { this.disableFacet(id); @@ -89,15 +89,15 @@ export default Marionette.Controller.extend({ } }, - enableFacets (facets) { + enableFacets(facets) { facets.forEach(this.enableFacet, this); }, - newSearch () { + newSearch() { this.options.app.state.setQuery({}); }, - parseQuery (query, separator) { + parseQuery(query, separator) { separator = separator || '|'; const q = {}; (query || '').split(separator).forEach(t => { @@ -109,7 +109,7 @@ export default Marionette.Controller.extend({ return q; }, - getQuery (separator) { + getQuery(separator) { separator = separator || '|'; const filter = this.options.app.state.get('query'); const route = []; @@ -119,12 +119,12 @@ export default Marionette.Controller.extend({ return route.join(separator); }, - getRoute (separator) { + getRoute(separator) { separator = separator || '|'; return this.getQuery(separator); }, - selectNext () { + selectNext() { const index = this.options.app.state.get('selectedIndex') + 1; if (index < this.options.app.list.length) { this.options.app.state.set({ selectedIndex: index }); @@ -138,7 +138,7 @@ export default Marionette.Controller.extend({ } }, - selectPrev () { + selectPrev() { const index = this.options.app.state.get('selectedIndex') - 1; if (index >= 0) { this.options.app.state.set({ selectedIndex: index }); @@ -146,6 +146,4 @@ export default Marionette.Controller.extend({ this.options.app.list.trigger('limitReached'); } } - }); - diff --git a/server/sonar-web/src/main/js/components/navigator/facets-view.js b/server/sonar-web/src/main/js/components/navigator/facets-view.js index f89a4fa7c7b..bd471a836b6 100644 --- a/server/sonar-web/src/main/js/components/navigator/facets-view.js +++ b/server/sonar-web/src/main/js/components/navigator/facets-view.js @@ -23,27 +23,25 @@ import BaseFacet from './facets/base-facet'; export default Marionette.CollectionView.extend({ className: 'search-navigator-facets-list', - childViewOptions () { + childViewOptions() { return { app: this.options.app }; }, - getChildView () { + getChildView() { return BaseFacet; }, - collectionEvents () { + collectionEvents() { return { 'change:enabled': 'updateState' }; }, - updateState () { + updateState() { const enabledFacets = this.collection.filter(model => model.get('enabled')); const enabledFacetIds = enabledFacets.map(model => model.id); this.options.app.state.set({ facets: enabledFacetIds }); } - }); - diff --git a/server/sonar-web/src/main/js/components/navigator/facets/base-facet.js b/server/sonar-web/src/main/js/components/navigator/facets/base-facet.js index 89daf798262..32ebe28bd5e 100644 --- a/server/sonar-web/src/main/js/components/navigator/facets/base-facet.js +++ b/server/sonar-web/src/main/js/components/navigator/facets/base-facet.js @@ -24,20 +24,20 @@ export default Marionette.ItemView.extend({ className: 'search-navigator-facet-box', forbiddenClassName: 'search-navigator-facet-box-forbidden', - modelEvents () { + modelEvents() { return { - 'change': 'render' + change: 'render' }; }, - events () { + events() { return { 'click .js-facet-toggle': 'toggle', 'click .js-facet': 'toggleFacet' }; }, - onRender () { + onRender() { this.$el.toggleClass('search-navigator-facet-box-collapsed', !this.model.get('enabled')); this.$el.attr('data-property', this.model.get('property')); const that = this; @@ -53,19 +53,22 @@ export default Marionette.ItemView.extend({ } }, - toggle () { + toggle() { if (!this.isForbidden()) { this.options.app.controller.toggleFacet(this.model.id); } }, - getValue () { - return this.$('.js-facet.active').map(function () { - return $(this).data('value'); - }).get().join(); + getValue() { + return this.$('.js-facet.active') + .map(function() { + return $(this).data('value'); + }) + .get() + .join(); }, - toggleFacet (e) { + toggleFacet(e) { $(e.currentTarget).toggleClass('active'); const property = this.model.get('property'); const obj = {}; @@ -73,27 +76,27 @@ export default Marionette.ItemView.extend({ this.options.app.state.updateFilter(obj); }, - disable () { + disable() { const property = this.model.get('property'); const obj = {}; obj[property] = null; this.options.app.state.updateFilter(obj); }, - forbid () { + forbid() { this.options.app.controller.disableFacet(this.model.id); this.$el.addClass(this.forbiddenClassName); }, - allow () { + allow() { this.$el.removeClass(this.forbiddenClassName); }, - isForbidden () { + isForbidden() { return this.$el.hasClass(this.forbiddenClassName); }, - sortValues (values) { + sortValues(values) { return values.slice().sort((left, right) => { if (left.count !== right.count) { return right.count - left.count; @@ -110,11 +113,10 @@ export default Marionette.ItemView.extend({ }); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), values: this.sortValues(this.model.getValues()) }; } }); - diff --git a/server/sonar-web/src/main/js/components/navigator/models/facet.js b/server/sonar-web/src/main/js/components/navigator/models/facet.js index 4382d84c76c..9b8f453cbfb 100644 --- a/server/sonar-web/src/main/js/components/navigator/models/facet.js +++ b/server/sonar-web/src/main/js/components/navigator/models/facet.js @@ -26,13 +26,12 @@ export default Backbone.Model.extend({ enabled: false }, - getValues () { + getValues() { return this.get('values') || []; }, - toggle () { + toggle() { const enabled = this.get('enabled'); this.set({ enabled: !enabled }); } }); - diff --git a/server/sonar-web/src/main/js/components/navigator/models/facets.js b/server/sonar-web/src/main/js/components/navigator/models/facets.js index d2191c3522a..ec0313686a4 100644 --- a/server/sonar-web/src/main/js/components/navigator/models/facets.js +++ b/server/sonar-web/src/main/js/components/navigator/models/facets.js @@ -23,4 +23,3 @@ import Facet from './facet'; export default Backbone.Collection.extend({ model: Facet }); - diff --git a/server/sonar-web/src/main/js/components/navigator/models/state.js b/server/sonar-web/src/main/js/components/navigator/models/state.js index 66e1a47a635..8c559fc62b9 100644 --- a/server/sonar-web/src/main/js/components/navigator/models/state.js +++ b/server/sonar-web/src/main/js/components/navigator/models/state.js @@ -20,7 +20,7 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ - defaults () { + defaults() { return { page: 1, maxResultsReached: false, @@ -29,12 +29,12 @@ export default Backbone.Model.extend({ }; }, - nextPage () { + nextPage() { const page = this.get('page'); this.set({ page: page + 1 }); }, - clearQuery (query) { + clearQuery(query) { const q = {}; Object.keys(query).forEach(key => { if (query[key]) { @@ -44,7 +44,7 @@ export default Backbone.Model.extend({ return q; }, - _areQueriesEqual (a, b) { + _areQueriesEqual(a, b) { let equal = Object.keys(a).length === Object.keys(b).length; Object.keys(a).forEach(key => { equal = equal && a[key] === b[key]; @@ -52,7 +52,7 @@ export default Backbone.Model.extend({ return equal; }, - updateFilter (obj, options) { + updateFilter(obj, options) { const oldQuery = this.get('query'); let query = { ...oldQuery, ...obj }; const opts = { force: false, ...options }; @@ -62,10 +62,9 @@ export default Backbone.Model.extend({ } }, - setQuery (query) { + setQuery(query) { this.set({ query }, { silent: true }); this.set({ changed: true }); this.trigger('change:query'); } }); - diff --git a/server/sonar-web/src/main/js/components/navigator/router.js b/server/sonar-web/src/main/js/components/navigator/router.js index d05fb42262c..eb4fa9b1c34 100644 --- a/server/sonar-web/src/main/js/components/navigator/router.js +++ b/server/sonar-web/src/main/js/components/navigator/router.js @@ -27,19 +27,18 @@ export default Backbone.Router.extend({ ':query': 'index' }, - initialize (options) { + initialize(options) { this.options = options; this.listenTo(this.options.app.state, 'change:query', this.updateRoute); }, - index (query) { + index(query) { query = this.options.app.controller.parseQuery(query); this.options.app.state.setQuery(query); }, - updateRoute () { + updateRoute() { const route = this.options.app.controller.getRoute(); this.navigate(route); } }); - diff --git a/server/sonar-web/src/main/js/components/navigator/workspace-header-view.js b/server/sonar-web/src/main/js/components/navigator/workspace-header-view.js index e25e1ff82d8..8ed623b343e 100644 --- a/server/sonar-web/src/main/js/components/navigator/workspace-header-view.js +++ b/server/sonar-web/src/main/js/components/navigator/workspace-header-view.js @@ -20,15 +20,14 @@ import Marionette from 'backbone.marionette'; export default Marionette.ItemView.extend({ - - collectionEvents () { + collectionEvents() { return { - 'all': 'shouldRender', - 'limitReached': 'flashPagination' + all: 'shouldRender', + limitReached: 'flashPagination' }; }, - events () { + events() { return { 'click .js-bulk-change': 'onBulkChangeClick', 'click .js-reload': 'reload', @@ -37,62 +36,62 @@ export default Marionette.ItemView.extend({ }; }, - initialize (options) { + initialize(options) { this.listenTo(options.app.state, 'change', this.render); }, - onRender () { + onRender() { this.$('[data-toggle="tooltip"]').tooltip({ container: 'body', placement: 'bottom' }); }, - onBeforeRender () { + onBeforeRender() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - onBulkChangeClick (e) { + onBulkChangeClick(e) { e.preventDefault(); this.bulkChange(); }, - bulkChange () { - - }, + bulkChange() {}, - shouldRender (event) { + shouldRender(event) { if (event !== 'limitReached') { this.render(); } }, - reload () { + reload() { this.options.app.controller.fetchList(); }, - selectNext () { + selectNext() { this.options.app.controller.selectNext(); }, - selectPrev () { + selectPrev() { this.options.app.controller.selectPrev(); }, - flashPagination () { + flashPagination() { const flashElement = this.$('.search-navigator-header-pagination'); flashElement.addClass('in'); - setTimeout(() => { - flashElement.removeClass('in'); - }, 2000); + setTimeout( + () => { + flashElement.removeClass('in'); + }, + 2000 + ); }, - serializeData () { + serializeData() { return { ...Marionette.ItemView.prototype.serializeData.apply(this, arguments), state: this.options.app.state.toJSON() }; } }); - diff --git a/server/sonar-web/src/main/js/components/navigator/workspace-list-item-view.js b/server/sonar-web/src/main/js/components/navigator/workspace-list-item-view.js index 96da1363309..9de8f0d31a3 100644 --- a/server/sonar-web/src/main/js/components/navigator/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/components/navigator/workspace-list-item-view.js @@ -20,23 +20,20 @@ import Marionette from 'backbone.marionette'; export default Marionette.ItemView.extend({ - - initialize (options) { + initialize(options) { this.listenTo(options.app.state, 'change:selectedIndex', this.select); }, - onRender () { + onRender() { this.select(); }, - select () { + select() { const selected = this.model.get('index') === this.options.app.state.get('selectedIndex'); this.$el.toggleClass('selected', selected); }, - selectCurrent () { + selectCurrent() { this.options.app.state.set({ selectedIndex: this.model.get('index') }); } - }); - diff --git a/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js b/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js index f894466d281..78b7732a92b 100644 --- a/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js +++ b/server/sonar-web/src/main/js/components/navigator/workspace-list-view.js @@ -24,56 +24,55 @@ import Marionette from 'backbone.marionette'; const BOTTOM_OFFSET = 60; export default Marionette.CompositeView.extend({ - ui: { loadMore: '.js-more', lastElementReached: '.js-last-element-reached' }, - childViewOptions () { + childViewOptions() { return { app: this.options.app }; }, collectionEvents: { - 'reset': 'scrollToTop' + reset: 'scrollToTop' }, - initialize (options) { + initialize(options) { this.loadMoreThrottled = throttle(this.loadMore, 1000, { trailing: false }); this.listenTo(options.app.state, 'change:maxResultsReached', this.toggleLoadMore); this.listenTo(options.app.state, 'change:selectedIndex', this.scrollTo); this.bindShortcuts(); }, - onDestroy () { + onDestroy() { this.unbindScrollEvents(); this.unbindShortcuts(); }, - onRender () { + onRender() { this.toggleLoadMore(); }, - toggleLoadMore () { + toggleLoadMore() { const maxResultsReached = this.options.app.state.get('maxResultsReached'); this.ui.loadMore.toggle(!maxResultsReached); this.ui.lastElementReached.toggle(maxResultsReached); }, - bindScrollEvents () { + bindScrollEvents() { const that = this; $(window).on('scroll.workspace-list-view', () => { that.onScroll(); }); }, - unbindScrollEvents () { + unbindScrollEvents() { $(window).off('scroll.workspace-list-view'); }, - bindShortcuts () { + bindShortcuts() { const that = this; key('up', 'list', () => { that.options.app.controller.selectPrev(); @@ -86,12 +85,12 @@ export default Marionette.CompositeView.extend({ }); }, - unbindShortcuts () { + unbindShortcuts() { key.unbind('up', 'list'); key.unbind('down', 'list'); }, - loadMore () { + loadMore() { if (!this.options.app.state.get('maxResultsReached')) { const that = this; this.unbindScrollEvents(); @@ -101,17 +100,17 @@ export default Marionette.CompositeView.extend({ } }, - onScroll () { + onScroll() { if ($(window).scrollTop() + $(window).height() >= this.ui.loadMore.offset().top) { this.loadMoreThrottled(); } }, - scrollToTop () { + scrollToTop() { this.$el.scrollParent().scrollTop(0); }, - scrollTo () { + scrollTo() { const selected = this.collection.at(this.options.app.state.get('selectedIndex')); if (selected == null) { return; @@ -119,7 +118,9 @@ export default Marionette.CompositeView.extend({ const selectedView = this.children.findByModel(selected); const parentTopOffset = this.$el.offset().top; const viewTop = selectedView.$el.offset().top - parentTopOffset; - const viewBottom = selectedView.$el.offset().top + selectedView.$el.outerHeight() + BOTTOM_OFFSET; + const viewBottom = selectedView.$el.offset().top + + selectedView.$el.outerHeight() + + BOTTOM_OFFSET; const windowTop = $(window).scrollTop(); const windowBottom = windowTop + $(window).height(); if (viewTop < windowTop) { @@ -129,6 +130,4 @@ export default Marionette.CompositeView.extend({ $(window).scrollTop($(window).scrollTop() - windowBottom + viewBottom); } } - }); - diff --git a/server/sonar-web/src/main/js/components/select-list/controls.js b/server/sonar-web/src/main/js/components/select-list/controls.js index a06156cd28d..bc0c0d7c57d 100644 --- a/server/sonar-web/src/main/js/components/select-list/controls.js +++ b/server/sonar-web/src/main/js/components/select-list/controls.js @@ -23,16 +23,16 @@ import RadioToggle from '../controls/RadioToggle'; import { translate } from '../../helpers/l10n'; export default React.createClass({ - componentWillMount () { + componentWillMount() { this.search = debounce(this.search, 100); }, - search () { + search() { const query = this.refs.search.value; this.props.search(query); }, - onCheck (value) { + onCheck(value) { switch (value) { case 'selected': this.props.loadSelected(); @@ -45,7 +45,7 @@ export default React.createClass({ } }, - render () { + render() { const selectionOptions = [ { value: 'selected', label: 'Selected' }, { value: 'deselected', label: 'Not Selected' }, @@ -53,23 +53,25 @@ export default React.createClass({ ]; return ( - <div className="select-list-control"> - <div className="pull-left"> - <RadioToggle - name="select-list-selection" - options={selectionOptions} - onCheck={this.onCheck} - value={this.props.selection}/> - </div> - <div className="pull-right"> - <input - onChange={this.search} - ref="search" - type="search" - placeholder={translate('search_verb')} - initialValue={this.props.query}/> - </div> + <div className="select-list-control"> + <div className="pull-left"> + <RadioToggle + name="select-list-selection" + options={selectionOptions} + onCheck={this.onCheck} + value={this.props.selection} + /> </div> + <div className="pull-right"> + <input + onChange={this.search} + ref="search" + type="search" + placeholder={translate('search_verb')} + initialValue={this.props.query} + /> + </div> + </div> ); } }); diff --git a/server/sonar-web/src/main/js/components/select-list/footer.js b/server/sonar-web/src/main/js/components/select-list/footer.js index a4caf3aff23..a3c7e89a70e 100644 --- a/server/sonar-web/src/main/js/components/select-list/footer.js +++ b/server/sonar-web/src/main/js/components/select-list/footer.js @@ -26,12 +26,12 @@ export default React.createClass({ loadMore: React.PropTypes.func.isRequired }, - loadMore (e) { + loadMore(e) { e.preventDefault(); this.props.loadMore(); }, - renderLoadMoreLink () { + renderLoadMoreLink() { const hasMore = this.props.total > this.props.count; if (!hasMore) { return null; @@ -39,12 +39,12 @@ export default React.createClass({ return <a onClick={this.loadMore} className="spacer-left" href="#">show more</a>; }, - render () { + render() { return ( - <footer className="spacer-top note text-center"> - {this.props.count}/{this.props.total} shown - {this.renderLoadMoreLink()} - </footer> + <footer className="spacer-top note text-center"> + {this.props.count}/{this.props.total} shown + {this.renderLoadMoreLink()} + </footer> ); } }); diff --git a/server/sonar-web/src/main/js/components/select-list/item.js b/server/sonar-web/src/main/js/components/select-list/item.js index cb4748f1257..b7e1e49fb39 100644 --- a/server/sonar-web/src/main/js/components/select-list/item.js +++ b/server/sonar-web/src/main/js/components/select-list/item.js @@ -28,7 +28,7 @@ export default React.createClass({ deselectItem: React.PropTypes.func.isRequired }, - onCheck (checked) { + onCheck(checked) { if (checked) { this.props.selectItem(this.props.item); } else { @@ -36,17 +36,18 @@ export default React.createClass({ } }, - render () { + render() { const renderedItem = this.props.renderItem(this.props.item); return ( - <li className="panel panel-vertical"> - <div className="display-inline-block text-middle spacer-right"> - <Checkbox - checked={!!this.props.item.selected} - onCheck={this.onCheck}/> - </div> - <div className="display-inline-block text-middle" dangerouslySetInnerHTML={{ __html: renderedItem }}/> - </li> + <li className="panel panel-vertical"> + <div className="display-inline-block text-middle spacer-right"> + <Checkbox checked={!!this.props.item.selected} onCheck={this.onCheck} /> + </div> + <div + className="display-inline-block text-middle" + dangerouslySetInnerHTML={{ __html: renderedItem }} + /> + </li> ); } }); diff --git a/server/sonar-web/src/main/js/components/select-list/list.js b/server/sonar-web/src/main/js/components/select-list/list.js index d5c4b7c5fbd..dbae011c81e 100644 --- a/server/sonar-web/src/main/js/components/select-list/list.js +++ b/server/sonar-web/src/main/js/components/select-list/list.js @@ -29,13 +29,11 @@ export default React.createClass({ deselectItem: React.PropTypes.func.isRequired }, - render () { + render() { const renderedItems = this.props.items.map(item => { const key = this.props.getItemKey(item); - return <Item key={key} {...this.props} item={item}/>; + return <Item key={key} {...this.props} item={item} />; }); - return ( - <ul>{renderedItems}</ul> - ); + return <ul>{renderedItems}</ul>; } }); diff --git a/server/sonar-web/src/main/js/components/select-list/main.js b/server/sonar-web/src/main/js/components/select-list/main.js index 1cf973eecd3..afe5a64bc95 100644 --- a/server/sonar-web/src/main/js/components/select-list/main.js +++ b/server/sonar-web/src/main/js/components/select-list/main.js @@ -31,15 +31,15 @@ export default React.createClass({ deselectItem: React.PropTypes.func.isRequired }, - getInitialState () { + getInitialState() { return { items: [], total: 0, selection: 'selected', query: null }; }, - componentDidMount () { + componentDidMount() { this.loadItems(); }, - loadItems () { + loadItems() { const options = { selection: this.state.selection, query: this.state.query, @@ -50,7 +50,7 @@ export default React.createClass({ }); }, - loadMoreItems () { + loadMoreItems() { const options = { selection: this.state.selection, query: this.state.query, @@ -62,39 +62,44 @@ export default React.createClass({ }); }, - loadSelected () { + loadSelected() { this.setState({ selection: 'selected', query: null }, this.loadItems); }, - loadDeselected () { + loadDeselected() { this.setState({ selection: 'deselected', query: null }, this.loadItems); }, - loadAll () { + loadAll() { this.setState({ selection: 'all', query: null }, this.loadItems); }, - search (query) { + search(query) { this.setState({ query }, this.loadItems); }, - render () { + render() { return ( - <div className="select-list-container"> - <Controls - selection={this.state.selection} - query={this.state.query} - loadSelected={this.loadSelected} - loadDeselected={this.loadDeselected} - loadAll={this.loadAll} - search={this.search}/> + <div className="select-list-container"> + <Controls + selection={this.state.selection} + query={this.state.query} + loadSelected={this.loadSelected} + loadDeselected={this.loadDeselected} + loadAll={this.loadAll} + search={this.search} + /> - <div className="select-list-wrapper"> - <List {...this.props} items={this.state.items}/> - </div> - - <Footer count={this.state.items.length} total={this.state.total} loadMore={this.loadMoreItems}/> + <div className="select-list-wrapper"> + <List {...this.props} items={this.state.items} /> </div> + + <Footer + count={this.state.items.length} + total={this.state.total} + loadMore={this.loadMoreItems} + /> + </div> ); } }); diff --git a/server/sonar-web/src/main/js/components/shared/Organization.js b/server/sonar-web/src/main/js/components/shared/Organization.js index 74d1962865e..807abd3d11e 100644 --- a/server/sonar-web/src/main/js/components/shared/Organization.js +++ b/server/sonar-web/src/main/js/components/shared/Organization.js @@ -24,17 +24,14 @@ import { getOrganizationByKey, areThereCustomOrganizations } from '../../store/r import OrganizationLink from '../ui/OrganizationLink'; type OwnProps = { - organizationKey: string, + organizationKey: string }; type Props = { link?: boolean, organizationKey: string, - organization: null | { - key: string, - name: string - }, - shouldBeDisplayed: boolean, + organization: { key: string, name: string } | null, + shouldBeDisplayed: boolean }; class Organization extends React.Component { @@ -44,7 +41,7 @@ class Organization extends React.Component { link: true }; - render () { + render() { const { organization, shouldBeDisplayed } = this.props; if (!shouldBeDisplayed || !organization) { @@ -52,14 +49,12 @@ class Organization extends React.Component { } return ( - <span> - {this.props.link ? ( - <OrganizationLink organization={organization}>{organization.name}</OrganizationLink> - ) : ( - organization.name - )} - <span className="slash-separator"/> - </span> + <span> + {this.props.link + ? <OrganizationLink organization={organization}>{organization.name}</OrganizationLink> + : organization.name} + <span className="slash-separator" /> + </span> ); } } diff --git a/server/sonar-web/src/main/js/components/shared/WithStore.js b/server/sonar-web/src/main/js/components/shared/WithStore.js index f3cb83233e2..2c702a53940 100644 --- a/server/sonar-web/src/main/js/components/shared/WithStore.js +++ b/server/sonar-web/src/main/js/components/shared/WithStore.js @@ -29,16 +29,16 @@ export default class WithStore extends React.Component { store: React.PropTypes.object }; - constructor (props: { children: Object }) { + constructor(props: { children: Object }) { super(props); this.store = getStore(); } - getChildContext () { + getChildContext() { return { store: this.store }; } - render () { + render() { return this.props.children; } } diff --git a/server/sonar-web/src/main/js/components/shared/__tests__/Organization-test.js b/server/sonar-web/src/main/js/components/shared/__tests__/Organization-test.js index bfbd0c6d03f..7bb6ae80476 100644 --- a/server/sonar-web/src/main/js/components/shared/__tests__/Organization-test.js +++ b/server/sonar-web/src/main/js/components/shared/__tests__/Organization-test.js @@ -24,18 +24,17 @@ import { UnconnectedOrganization } from '../Organization'; const organization = { key: 'foo', name: 'foo' }; it('should match snapshot', () => { - expect(shallow( - <UnconnectedOrganization organization={organization} shouldBeDisplayed={true}/> - )).toMatchSnapshot(); + expect( + shallow(<UnconnectedOrganization organization={organization} shouldBeDisplayed={true} />) + ).toMatchSnapshot(); }); it('should not be displayed', () => { - expect(shallow( - <UnconnectedOrganization organization={organization} shouldBeDisplayed={false}/> - )).toMatchSnapshot(); + expect( + shallow(<UnconnectedOrganization organization={organization} shouldBeDisplayed={false} />) + ).toMatchSnapshot(); - expect(shallow( - <UnconnectedOrganization organization={null} shouldBeDisplayed={true}/> - )).toMatchSnapshot(); + expect( + shallow(<UnconnectedOrganization organization={null} shouldBeDisplayed={true} />) + ).toMatchSnapshot(); }); - diff --git a/server/sonar-web/src/main/js/components/shared/complexity-distribution.js b/server/sonar-web/src/main/js/components/shared/complexity-distribution.js index e1f9cf92203..62fc07f00d2 100644 --- a/server/sonar-web/src/main/js/components/shared/complexity-distribution.js +++ b/server/sonar-web/src/main/js/components/shared/complexity-distribution.js @@ -30,7 +30,7 @@ export const ComplexityDistribution = React.createClass({ of: React.PropTypes.string.isRequired }, - renderBarChart () { + renderBarChart() { const data = this.props.distribution.split(';').map((point, index) => { const tokens = point.split('='); const y = parseInt(tokens[1], 10); @@ -48,23 +48,26 @@ export const ComplexityDistribution = React.createClass({ const xValues = data.map(point => formatMeasure(point.y, 'INT')); return ( - <BarChart - data={data} - xTicks={xTicks} - xValues={xValues} - height={HEIGHT} - barsWidth={20} - padding={[25, 10, 25, 10]}/> + <BarChart + data={data} + xTicks={xTicks} + xValues={xValues} + height={HEIGHT} + barsWidth={20} + padding={[25, 10, 25, 10]} + /> ); }, - render () { + render() { // TODO remove inline styling return ( - <div className="overview-bar-chart" - style={{ height: HEIGHT, paddingTop: 10, paddingBottom: 15 }}> - {this.renderBarChart()} - </div> + <div + className="overview-bar-chart" + style={{ height: HEIGHT, paddingTop: 10, paddingBottom: 15 }} + > + {this.renderBarChart()} + </div> ); } }); diff --git a/server/sonar-web/src/main/js/components/shared/drilldown-link.js b/server/sonar-web/src/main/js/components/shared/drilldown-link.js index c9c13688af2..a4b82a95f5d 100644 --- a/server/sonar-web/src/main/js/components/shared/drilldown-link.js +++ b/server/sonar-web/src/main/js/components/shared/drilldown-link.js @@ -48,11 +48,11 @@ const ISSUE_MEASURES = [ ]; export const DrilldownLink = React.createClass({ - isIssueMeasure () { + isIssueMeasure() { return ISSUE_MEASURES.indexOf(this.props.metric) !== -1; }, - propsToIssueParams () { + propsToIssueParams() { const params = {}; if (this.props.periodDate) { @@ -110,17 +110,13 @@ export const DrilldownLink = React.createClass({ return params; }, - renderIssuesLink () { - const url = getComponentIssuesUrl( - this.props.component, - this.propsToIssueParams()); + renderIssuesLink() { + const url = getComponentIssuesUrl(this.props.component, this.propsToIssueParams()); - return ( - <Link to={url} className={this.props.className}>{this.props.children}</Link> - ); + return <Link to={url} className={this.props.className}>{this.props.children}</Link>; }, - render () { + render() { if (this.isIssueMeasure()) { return this.renderIssuesLink(); } diff --git a/server/sonar-web/src/main/js/components/shared/pending-icon.js b/server/sonar-web/src/main/js/components/shared/pending-icon.js index cfca9843da9..1a558b3216b 100644 --- a/server/sonar-web/src/main/js/components/shared/pending-icon.js +++ b/server/sonar-web/src/main/js/components/shared/pending-icon.js @@ -20,14 +20,14 @@ import React from 'react'; export default React.createClass({ - render () { + render() { /* eslint max-len: 0 */ return ( - <svg width="16" height="16" className="icon-pending"> - <g transform="matrix(0.0364583,0,0,0.0364583,1,-0.166667)"> - <path d="M224,136L224,248C224,250.333 223.25,252.25 221.75,253.75C220.25,255.25 218.333,256 216,256L136,256C133.667,256 131.75,255.25 130.25,253.75C128.75,252.25 128,250.333 128,248L128,232C128,229.667 128.75,227.75 130.25,226.25C131.75,224.75 133.667,224 136,224L192,224L192,136C192,133.667 192.75,131.75 194.25,130.25C195.75,128.75 197.667,128 200,128L216,128C218.333,128 220.25,128.75 221.75,130.25C223.25,131.75 224,133.667 224,136ZM328,224C328,199.333 321.917,176.583 309.75,155.75C297.583,134.917 281.083,118.417 260.25,106.25C239.417,94.083 216.667,88 192,88C167.333,88 144.583,94.083 123.75,106.25C102.917,118.417 86.417,134.917 74.25,155.75C62.083,176.583 56,199.333 56,224C56,248.667 62.083,271.417 74.25,292.25C86.417,313.083 102.917,329.583 123.75,341.75C144.583,353.917 167.333,360 192,360C216.667,360 239.417,353.917 260.25,341.75C281.083,329.583 297.583,313.083 309.75,292.25C321.917,271.417 328,248.667 328,224ZM384,224C384,258.833 375.417,290.958 358.25,320.375C341.083,349.792 317.792,373.083 288.375,390.25C258.958,407.417 226.833,416 192,416C157.167,416 125.042,407.417 95.625,390.25C66.208,373.083 42.917,349.792 25.75,320.375C8.583,290.958 0,258.833 0,224C0,189.167 8.583,157.042 25.75,127.625C42.917,98.208 66.208,74.917 95.625,57.75C125.042,40.583 157.167,32 192,32C226.833,32 258.958,40.583 288.375,57.75C317.792,74.917 341.083,98.208 358.25,127.625C375.417,157.042 384,189.167 384,224Z"/> - </g> - </svg> + <svg width="16" height="16" className="icon-pending"> + <g transform="matrix(0.0364583,0,0,0.0364583,1,-0.166667)"> + <path d="M224,136L224,248C224,250.333 223.25,252.25 221.75,253.75C220.25,255.25 218.333,256 216,256L136,256C133.667,256 131.75,255.25 130.25,253.75C128.75,252.25 128,250.333 128,248L128,232C128,229.667 128.75,227.75 130.25,226.25C131.75,224.75 133.667,224 136,224L192,224L192,136C192,133.667 192.75,131.75 194.25,130.25C195.75,128.75 197.667,128 200,128L216,128C218.333,128 220.25,128.75 221.75,130.25C223.25,131.75 224,133.667 224,136ZM328,224C328,199.333 321.917,176.583 309.75,155.75C297.583,134.917 281.083,118.417 260.25,106.25C239.417,94.083 216.667,88 192,88C167.333,88 144.583,94.083 123.75,106.25C102.917,118.417 86.417,134.917 74.25,155.75C62.083,176.583 56,199.333 56,224C56,248.667 62.083,271.417 74.25,292.25C86.417,313.083 102.917,329.583 123.75,341.75C144.583,353.917 167.333,360 192,360C216.667,360 239.417,353.917 260.25,341.75C281.083,329.583 297.583,313.083 309.75,292.25C321.917,271.417 328,248.667 328,224ZM384,224C384,258.833 375.417,290.958 358.25,320.375C341.083,349.792 317.792,373.083 288.375,390.25C258.958,407.417 226.833,416 192,416C157.167,416 125.042,407.417 95.625,390.25C66.208,373.083 42.917,349.792 25.75,320.375C8.583,290.958 0,258.833 0,224C0,189.167 8.583,157.042 25.75,127.625C42.917,98.208 66.208,74.917 95.625,57.75C125.042,40.583 157.167,32 192,32C226.833,32 258.958,40.583 288.375,57.75C317.792,74.917 341.083,98.208 358.25,127.625C375.417,157.042 384,189.167 384,224Z" /> + </g> + </svg> ); } }); diff --git a/server/sonar-web/src/main/js/components/shared/pin-icon.js b/server/sonar-web/src/main/js/components/shared/pin-icon.js index a2abe6def66..87b28754bdb 100644 --- a/server/sonar-web/src/main/js/components/shared/pin-icon.js +++ b/server/sonar-web/src/main/js/components/shared/pin-icon.js @@ -21,11 +21,12 @@ import React from 'react'; const PinIcon = () => ( - <svg width="9" height="14" viewBox="0 0 288 448"> - <path - fill="#236a97" - d="M120 216v-112q0-3.5-2.25-5.75t-5.75-2.25-5.75 2.25-2.25 5.75v112q0 3.5 2.25 5.75t5.75 2.25 5.75-2.25 2.25-5.75zM288 304q0 6.5-4.75 11.25t-11.25 4.75h-107.25l-12.75 120.75q-0.5 3-2.625 5.125t-5.125 2.125h-0.25q-6.75 0-8-6.75l-19-121.25h-101q-6.5 0-11.25-4.75t-4.75-11.25q0-30.75 19.625-55.375t44.375-24.625v-128q-13 0-22.5-9.5t-9.5-22.5 9.5-22.5 22.5-9.5h160q13 0 22.5 9.5t9.5 22.5-9.5 22.5-22.5 9.5v128q24.75 0 44.375 24.625t19.625 55.375z"/> - </svg> + <svg width="9" height="14" viewBox="0 0 288 448"> + <path + fill="#236a97" + d="M120 216v-112q0-3.5-2.25-5.75t-5.75-2.25-5.75 2.25-2.25 5.75v112q0 3.5 2.25 5.75t5.75 2.25 5.75-2.25 2.25-5.75zM288 304q0 6.5-4.75 11.25t-11.25 4.75h-107.25l-12.75 120.75q-0.5 3-2.625 5.125t-5.125 2.125h-0.25q-6.75 0-8-6.75l-19-121.25h-101q-6.5 0-11.25-4.75t-4.75-11.25q0-30.75 19.625-55.375t44.375-24.625v-128q-13 0-22.5-9.5t-9.5-22.5 9.5-22.5 22.5-9.5h160q13 0 22.5 9.5t9.5 22.5-9.5 22.5-22.5 9.5v128q24.75 0 44.375 24.625t19.625 55.375z" + /> + </svg> ); export default PinIcon; diff --git a/server/sonar-web/src/main/js/components/shared/qualifier-icon.js b/server/sonar-web/src/main/js/components/shared/qualifier-icon.js index 0dfa51df950..d3e8aead051 100644 --- a/server/sonar-web/src/main/js/components/shared/qualifier-icon.js +++ b/server/sonar-web/src/main/js/components/shared/qualifier-icon.js @@ -20,11 +20,11 @@ import React from 'react'; export default React.createClass({ - render () { + render() { if (!this.props.qualifier) { return null; } const className = 'icon-qualifier-' + this.props.qualifier.toLowerCase(); - return <i className={className}/>; + return <i className={className} />; } }); diff --git a/server/sonar-web/src/main/js/components/shared/severity-helper.js b/server/sonar-web/src/main/js/components/shared/severity-helper.js index 248a5b2149f..544afa754d1 100644 --- a/server/sonar-web/src/main/js/components/shared/severity-helper.js +++ b/server/sonar-web/src/main/js/components/shared/severity-helper.js @@ -22,16 +22,16 @@ import SeverityIcon from './severity-icon'; import { translate } from '../../helpers/l10n'; export default React.createClass({ - render () { + render() { if (!this.props.severity) { return null; } return ( - <span> - <SeverityIcon severity={this.props.severity}/> - {' '} - {translate('severity', this.props.severity)} - </span> + <span> + <SeverityIcon severity={this.props.severity} /> + {' '} + {translate('severity', this.props.severity)} + </span> ); } }); diff --git a/server/sonar-web/src/main/js/components/shared/severity-icon.js b/server/sonar-web/src/main/js/components/shared/severity-icon.js index e49f8c43681..6c5e5d4a452 100644 --- a/server/sonar-web/src/main/js/components/shared/severity-icon.js +++ b/server/sonar-web/src/main/js/components/shared/severity-icon.js @@ -20,11 +20,11 @@ import React from 'react'; export default React.createClass({ - render () { + render() { if (!this.props.severity) { return null; } const className = 'icon-severity-' + this.props.severity.toLowerCase(); - return <i className={className}/>; + return <i className={className} />; } }); diff --git a/server/sonar-web/src/main/js/components/ui/Avatar.js b/server/sonar-web/src/main/js/components/ui/Avatar.js index 44d6e7cab75..12e6e5500a9 100644 --- a/server/sonar-web/src/main/js/components/ui/Avatar.js +++ b/server/sonar-web/src/main/js/components/ui/Avatar.js @@ -32,24 +32,26 @@ class Avatar extends React.Component { className: React.PropTypes.string }; - render () { + render() { if (!this.props.enableGravatar) { return null; } const emailHash = md5.md5((this.props.email || '').toLowerCase()).trim(); const url = this.props.gravatarServerUrl - .replace('{EMAIL_MD5}', emailHash) - .replace('{SIZE}', this.props.size * 2); + .replace('{EMAIL_MD5}', emailHash) + .replace('{SIZE}', this.props.size * 2); const className = classNames(this.props.className, 'rounded'); return ( - <img className={className} - src={url} - width={this.props.size} - height={this.props.size} - alt={this.props.email}/> + <img + className={className} + src={url} + width={this.props.size} + height={this.props.size} + alt={this.props.email} + /> ); } } diff --git a/server/sonar-web/src/main/js/components/ui/BugIcon.js b/server/sonar-web/src/main/js/components/ui/BugIcon.js index aa3b7b1264d..ce8a031654c 100644 --- a/server/sonar-web/src/main/js/components/ui/BugIcon.js +++ b/server/sonar-web/src/main/js/components/ui/BugIcon.js @@ -21,12 +21,15 @@ import React from 'react'; export default class BugIcon extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> - <path style={{ fill: 'currentColor' }} d="M11 9h1.3l.5.8.8-.5-.8-1.3H11v-.3l2-2.3V3h-1v2l-1 1.2V5c-.1-.8-.7-1.5-1.4-1.9L11 1.8l-.7-.7-1.8 1.6-1.8-1.6-.7.7 1.5 1.3C6.7 3.5 6.1 4.2 6 5v1.1L5 5V3H4v2.3l2 2.3V8H4.2l-.7 1.2.8.5.4-.7H6v.3l-2 1.9V14h1v-2.4l1-1C6 12 7.1 13 8.4 13h.8c.7 0 1.4-.3 1.8-.9.3-.4.3-.9.2-1.4l.9.9V14h1v-2.8l-2-1.9V9zm-2 2H8V6h1v5z"/> - </svg> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + <path + style={{ fill: 'currentColor' }} + d="M11 9h1.3l.5.8.8-.5-.8-1.3H11v-.3l2-2.3V3h-1v2l-1 1.2V5c-.1-.8-.7-1.5-1.4-1.9L11 1.8l-.7-.7-1.8 1.6-1.8-1.6-.7.7 1.5 1.3C6.7 3.5 6.1 4.2 6 5v1.1L5 5V3H4v2.3l2 2.3V8H4.2l-.7 1.2.8.5.4-.7H6v.3l-2 1.9V14h1v-2.4l1-1C6 12 7.1 13 8.4 13h.8c.7 0 1.4-.3 1.8-.9.3-.4.3-.9.2-1.4l.9.9V14h1v-2.8l-2-1.9V9zm-2 2H8V6h1v5z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/components/ui/BugTrackerIcon.js b/server/sonar-web/src/main/js/components/ui/BugTrackerIcon.js index 36d93bd9def..011d49db7c4 100644 --- a/server/sonar-web/src/main/js/components/ui/BugTrackerIcon.js +++ b/server/sonar-web/src/main/js/components/ui/BugTrackerIcon.js @@ -21,14 +21,23 @@ import React from 'react'; export default class BugTrackerIcon extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" width="14" height="14"> - <g transform="matrix(1,0,0,1,0,1)"> - <path style={{ fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeMiterlimit: '10' }} d="M12 9h-2L8 5 6.5 9.5l-2-6L3 9H1"/> - </g> - </svg> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14" width="14" height="14"> + <g transform="matrix(1,0,0,1,0,1)"> + <path + style={{ + fill: 'none', + stroke: 'currentColor', + strokeWidth: 2, + strokeLinecap: 'round', + strokeMiterlimit: '10' + }} + d="M12 9h-2L8 5 6.5 9.5l-2-6L3 9H1" + /> + </g> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/components/ui/CodeSmellIcon.js b/server/sonar-web/src/main/js/components/ui/CodeSmellIcon.js index d3e5e0a56d9..1dcf9e32b77 100644 --- a/server/sonar-web/src/main/js/components/ui/CodeSmellIcon.js +++ b/server/sonar-web/src/main/js/components/ui/CodeSmellIcon.js @@ -21,12 +21,15 @@ import React from 'react'; export default class CodeSmellIcon extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> - <path style={{ fill: 'currentColor' }} d="M8 2C4.7 2 2 4.7 2 8s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zm-.5 5.5h.9v.9h-.9v-.9zm-3.8.2c-.1 0-.2-.1-.2-.2 0-.4.1-1.2.6-2S5.3 4.2 5.6 4c.2 0 .3 0 .3.1l1.3 2.3c0 .1 0 .2-.1.2-.1.2-.2.3-.3.5-.1.2-.2.4-.2.5 0 .1-.1.2-.2.2l-2.7-.1zM9.9 12c-.3.2-1.1.5-2 .5-.9 0-1.7-.3-2-.5-.1 0-.1-.2-.1-.3l1.3-2.3c0-.1.1-.1.2-.1.2.1.3.1.5.1s.4 0 .5-.1c.1 0 .2 0 .2.1l1.3 2.3c.2.2.2.3.1.3zm2.5-4.1L9.7 8c-.1 0-.2-.1-.2-.2 0-.2-.1-.4-.2-.5 0-.1-.2-.3-.3-.4-.1 0-.1-.1-.1-.2l1.3-2.3c.1-.1.2-.1.3-.1.3.2 1 .7 1.5 1.5s.6 1.6.6 2c0 0-.1.1-.2.1z"/> - </svg> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + <path + style={{ fill: 'currentColor' }} + d="M8 2C4.7 2 2 4.7 2 8s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zm-.5 5.5h.9v.9h-.9v-.9zm-3.8.2c-.1 0-.2-.1-.2-.2 0-.4.1-1.2.6-2S5.3 4.2 5.6 4c.2 0 .3 0 .3.1l1.3 2.3c0 .1 0 .2-.1.2-.1.2-.2.3-.3.5-.1.2-.2.4-.2.5 0 .1-.1.2-.2.2l-2.7-.1zM9.9 12c-.3.2-1.1.5-2 .5-.9 0-1.7-.3-2-.5-.1 0-.1-.2-.1-.3l1.3-2.3c0-.1.1-.1.2-.1.2.1.3.1.5.1s.4 0 .5-.1c.1 0 .2 0 .2.1l1.3 2.3c.2.2.2.3.1.3zm2.5-4.1L9.7 8c-.1 0-.2-.1-.2-.2 0-.2-.1-.4-.2-.5 0-.1-.2-.3-.3-.4-.1 0-.1-.1-.1-.2l1.3-2.3c.1-.1.2-.1.3-.1.3.2 1 .7 1.5 1.5s.6 1.6.6 2c0 0-.1.1-.2.1z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/components/ui/CoverageRating.js b/server/sonar-web/src/main/js/components/ui/CoverageRating.js index 1211ee85455..8546484cd2c 100644 --- a/server/sonar-web/src/main/js/components/ui/CoverageRating.js +++ b/server/sonar-web/src/main/js/components/ui/CoverageRating.js @@ -22,22 +22,22 @@ import React from 'react'; import { DonutChart } from '../charts/donut-chart'; const SIZE_TO_WIDTH_MAPPING = { - 'small': 16, - 'normal': 24, - 'big': 40 + small: 16, + normal: 24, + big: 40 }; const SIZE_TO_THICKNESS_MAPPING = { - 'small': 2, - 'normal': 3, - 'big': 3 + small: 2, + normal: 3, + big: 3 }; export default class CoverageRating extends React.Component { props: { value: number | string, size?: 'small' | 'normal' | 'big', - muted?: boolean, + muted?: boolean }; static defaultProps = { @@ -45,7 +45,7 @@ export default class CoverageRating extends React.Component { muted: false }; - render () { + render() { let data = [{ value: 100, fill: '#ccc ' }]; if (this.props.value != null) { @@ -62,12 +62,6 @@ export default class CoverageRating extends React.Component { // $FlowFixMe const thickness = SIZE_TO_THICKNESS_MAPPING[this.props.size]; - return ( - <DonutChart - data={data} - width={size} - height={size} - thickness={thickness}/> - ); + return <DonutChart data={data} width={size} height={size} thickness={thickness} />; } } diff --git a/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js b/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js index 2000a0e09d2..ddb058109c4 100644 --- a/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js +++ b/server/sonar-web/src/main/js/components/ui/DuplicationsRating.js @@ -35,7 +35,7 @@ export default class DuplicationsRating extends React.Component { muted: false }; - render () { + render() { const { value, size, muted } = this.props; const className = classNames('duplications-rating', { 'duplications-rating-small': size === 'small', @@ -48,8 +48,6 @@ export default class DuplicationsRating extends React.Component { 'duplications-rating-E': value >= 20 }); - return ( - <div className={className}/> - ); + return <div className={className} />; } } diff --git a/server/sonar-web/src/main/js/components/ui/FormattedDate.js b/server/sonar-web/src/main/js/components/ui/FormattedDate.js index cf66c3a061d..eb4129919b2 100644 --- a/server/sonar-web/src/main/js/components/ui/FormattedDate.js +++ b/server/sonar-web/src/main/js/components/ui/FormattedDate.js @@ -32,7 +32,7 @@ export default class FormattedDate extends React.Component { format: 'LLL' }; - render () { + render() { const { date, format, tooltipFormat } = this.props; const m = moment(date); @@ -40,9 +40,9 @@ export default class FormattedDate extends React.Component { const title = tooltipFormat ? m.format(tooltipFormat) : undefined; return ( - <time dateTime={m.format()} title={title}> - {m.format(format)} - </time> + <time dateTime={m.format()} title={title}> + {m.format(format)} + </time> ); } } diff --git a/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.js b/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.js index 11bdc397c24..95e9b372da0 100644 --- a/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.js +++ b/server/sonar-web/src/main/js/components/ui/IssueTypeIcon.js @@ -29,34 +29,32 @@ export default class IssueTypeIcon extends React.Component { query: string }; - renderIcon () { + renderIcon() { switch (this.props.query.toLowerCase()) { case 'bug': case 'bugs': case 'new_bugs': - return <BugIcon/>; + return <BugIcon />; case 'vulnerability': case 'vulnerabilities': case 'new_vulnerabilities': - return <VulnerabilityIcon/>; + return <VulnerabilityIcon />; case 'code_smell': case 'code_smells': case 'new_code_smells': - return <CodeSmellIcon/>; + return <CodeSmellIcon />; default: return null; } } - render () { + render() { const icon = this.renderIcon(); if (!icon) { return null; } - return this.props.className ? - <span className={this.props.className}>{icon}</span> : - icon; + return this.props.className ? <span className={this.props.className}>{icon}</span> : icon; } } diff --git a/server/sonar-web/src/main/js/components/ui/Level.js b/server/sonar-web/src/main/js/components/ui/Level.js index ad35ce23b00..9a00eaf5337 100644 --- a/server/sonar-web/src/main/js/components/ui/Level.js +++ b/server/sonar-web/src/main/js/components/ui/Level.js @@ -34,7 +34,7 @@ export default class Level extends React.Component { muted: false }; - render () { + render() { const formatted = formatMeasure(this.props.level, 'LEVEL'); const className = classNames('level', 'level-' + this.props.level, { 'level-small': this.props.small, diff --git a/server/sonar-web/src/main/js/components/ui/OrganizationIcon.js b/server/sonar-web/src/main/js/components/ui/OrganizationIcon.js index ae516f8c40e..4a7435d438a 100644 --- a/server/sonar-web/src/main/js/components/ui/OrganizationIcon.js +++ b/server/sonar-web/src/main/js/components/ui/OrganizationIcon.js @@ -21,12 +21,15 @@ import React from 'react'; export default class OrganizationIcon extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> - <path style={{ fill: '#4b9fd5' }} d="M13.5 6c-.4 0-.7.1-1.1.2L11 4.8v-.3C11 3.1 9.9 2 8.5 2S6 3.1 6 4.5v.2L4.5 6.2c-.3-.1-.7-.2-1-.2C2.1 6 1 7.1 1 8.5S2.1 11 3.5 11 6 9.9 6 8.5c0-.7-.3-1.3-.7-1.7l1-1c.4.6 1 1 1.7 1.1V9c-1.1.2-2 1.2-2 2.4C6 12.9 7.1 14 8.5 14s2.5-1.1 2.5-2.5c0-1.2-.9-2.2-2-2.4V6.9c.7-.1 1.2-.5 1.6-1.1l1 1c-.4.4-.6 1-.6 1.6 0 1.4 1.1 2.5 2.5 2.5s2.5-1 2.5-2.4S14.9 6 13.5 6zm-10 4C2.7 10 2 9.3 2 8.5S2.7 7 3.5 7 5 7.7 5 8.5 4.3 10 3.5 10zm6.5 1.5c0 .8-.7 1.5-1.5 1.5S7 12.3 7 11.5 7.7 10 8.5 10s1.5.7 1.5 1.5zM8.5 6C7.7 6 7 5.3 7 4.5S7.7 3 8.5 3s1.5.7 1.5 1.5S9.3 6 8.5 6zm5 4c-.8 0-1.5-.7-1.5-1.5S12.7 7 13.5 7s1.5.7 1.5 1.5-.7 1.5-1.5 1.5z"/> - </svg> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + <path + style={{ fill: '#4b9fd5' }} + d="M13.5 6c-.4 0-.7.1-1.1.2L11 4.8v-.3C11 3.1 9.9 2 8.5 2S6 3.1 6 4.5v.2L4.5 6.2c-.3-.1-.7-.2-1-.2C2.1 6 1 7.1 1 8.5S2.1 11 3.5 11 6 9.9 6 8.5c0-.7-.3-1.3-.7-1.7l1-1c.4.6 1 1 1.7 1.1V9c-1.1.2-2 1.2-2 2.4C6 12.9 7.1 14 8.5 14s2.5-1.1 2.5-2.5c0-1.2-.9-2.2-2-2.4V6.9c.7-.1 1.2-.5 1.6-1.1l1 1c-.4.4-.6 1-.6 1.6 0 1.4 1.1 2.5 2.5 2.5s2.5-1 2.5-2.4S14.9 6 13.5 6zm-10 4C2.7 10 2 9.3 2 8.5S2.7 7 3.5 7 5 7.7 5 8.5 4.3 10 3.5 10zm6.5 1.5c0 .8-.7 1.5-1.5 1.5S7 12.3 7 11.5 7.7 10 8.5 10s1.5.7 1.5 1.5zM8.5 6C7.7 6 7 5.3 7 4.5S7.7 3 8.5 3s1.5.7 1.5 1.5S9.3 6 8.5 6zm5 4c-.8 0-1.5-.7-1.5-1.5S12.7 7 13.5 7s1.5.7 1.5 1.5-.7 1.5-1.5 1.5z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/components/ui/OrganizationLink.js b/server/sonar-web/src/main/js/components/ui/OrganizationLink.js index 95c40c669d1..280338edd3c 100644 --- a/server/sonar-web/src/main/js/components/ui/OrganizationLink.js +++ b/server/sonar-web/src/main/js/components/ui/OrganizationLink.js @@ -29,11 +29,9 @@ export default class OrganizationLink extends React.Component { } }; - render () { + render() { const { children, organization, ...other } = this.props; - return ( - <Link to={`/organizations/${organization.key}`} {...other}>{children}</Link> - ); + return <Link to={`/organizations/${organization.key}`} {...other}>{children}</Link>; } } diff --git a/server/sonar-web/src/main/js/components/ui/Rating.js b/server/sonar-web/src/main/js/components/ui/Rating.js index d0ab5916c56..c53eabe9d0f 100644 --- a/server/sonar-web/src/main/js/components/ui/Rating.js +++ b/server/sonar-web/src/main/js/components/ui/Rating.js @@ -28,8 +28,7 @@ export default class Rating extends React.Component { // allow both numbers and strings const numberValue = Number(props[propName]); if (numberValue < 1 || numberValue > 5) { - throw new Error( - `Invalid prop "${propName}" passed to "${componentName}".`); + throw new Error(`Invalid prop "${propName}" passed to "${componentName}".`); } }, small: React.PropTypes.bool, @@ -41,7 +40,7 @@ export default class Rating extends React.Component { muted: false }; - render () { + render() { const formatted = formatMeasure(this.props.value, 'RATING'); const className = classNames('rating', 'rating-' + formatted, { 'rating-small': this.props.small, diff --git a/server/sonar-web/src/main/js/components/ui/SizeRating.js b/server/sonar-web/src/main/js/components/ui/SizeRating.js index 3656c5eb5c4..f1b2f919d55 100644 --- a/server/sonar-web/src/main/js/components/ui/SizeRating.js +++ b/server/sonar-web/src/main/js/components/ui/SizeRating.js @@ -35,13 +35,11 @@ export default class SizeRating extends React.Component { muted: false }; - render () { + render() { const { value } = this.props; if (value == null) { - return ( - <div className="size-rating size-rating-muted"> </div> - ); + return <div className="size-rating size-rating-muted"> </div>; } let letter; @@ -62,8 +60,6 @@ export default class SizeRating extends React.Component { 'size-rating-muted': this.props.muted }); - return ( - <div className={className}>{letter}</div> - ); + return <div className={className}>{letter}</div>; } } diff --git a/server/sonar-web/src/main/js/components/ui/VulnerabilityIcon.js b/server/sonar-web/src/main/js/components/ui/VulnerabilityIcon.js index f851d2eb462..1a5203fc94e 100644 --- a/server/sonar-web/src/main/js/components/ui/VulnerabilityIcon.js +++ b/server/sonar-web/src/main/js/components/ui/VulnerabilityIcon.js @@ -21,12 +21,15 @@ import React from 'react'; export default class VulnerabilityIcon extends React.Component { - render () { + render() { /* eslint-disable max-len */ return ( - <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> - <path style={{ fill: 'currentColor' }} d="M10.8 5H6V3.9a2.28 2.28 0 0 1 2-2.5 2.22 2.22 0 0 1 1.8 1.2.48.48 0 0 0 .7.2.48.48 0 0 0 .2-.7A3 3 0 0 0 8 .4a3.34 3.34 0 0 0-3 3.5v1.2a2.16 2.16 0 0 0-2 2.1v4.4a2.22 2.22 0 0 0 2.2 2.2h5.6a2.22 2.22 0 0 0 2.2-2.2V7.2A2.22 2.22 0 0 0 10.8 5zm-2.2 5.5v1.2H7.4v-1.2a1.66 1.66 0 0 1-1.1-1.6A1.75 1.75 0 0 1 8 7.2a1.71 1.71 0 0 1 .6 3.3z"/> - </svg> + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + <path + style={{ fill: 'currentColor' }} + d="M10.8 5H6V3.9a2.28 2.28 0 0 1 2-2.5 2.22 2.22 0 0 1 1.8 1.2.48.48 0 0 0 .7.2.48.48 0 0 0 .2-.7A3 3 0 0 0 8 .4a3.34 3.34 0 0 0-3 3.5v1.2a2.16 2.16 0 0 0-2 2.1v4.4a2.22 2.22 0 0 0 2.2 2.2h5.6a2.22 2.22 0 0 0 2.2-2.2V7.2A2.22 2.22 0 0 0 10.8 5zm-2.2 5.5v1.2H7.4v-1.2a1.66 1.66 0 0 1-1.1-1.6A1.75 1.75 0 0 1 8 7.2a1.71 1.71 0 0 1 .6 3.3z" + /> + </svg> ); } } diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/Avatar-test.js b/server/sonar-web/src/main/js/components/ui/__tests__/Avatar-test.js index e6cbac9a939..a83df0fa337 100644 --- a/server/sonar-web/src/main/js/components/ui/__tests__/Avatar-test.js +++ b/server/sonar-web/src/main/js/components/ui/__tests__/Avatar-test.js @@ -25,7 +25,12 @@ const gravatarServerUrl = 'http://example.com/{EMAIL_MD5}.jpg?s={SIZE}'; it('should render', () => { const avatar = shallow( - <Avatar enableGravatar={true} gravatarServerUrl={gravatarServerUrl} email="mail@example.com" size={20}/> + <Avatar + enableGravatar={true} + gravatarServerUrl={gravatarServerUrl} + email="mail@example.com" + size={20} + /> ); expect(avatar.is('img')).toBe(true); expect(avatar.prop('width')).toBe(20); @@ -36,7 +41,12 @@ it('should render', () => { it('should not render', () => { const avatar = shallow( - <Avatar enableGravatar={false} gravatarServerUrl={gravatarServerUrl} email="mail@example.com" size={20}/> + <Avatar + enableGravatar={false} + gravatarServerUrl={gravatarServerUrl} + email="mail@example.com" + size={20} + /> ); expect(avatar.is('img')).toBe(false); }); diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/Level-test.js b/server/sonar-web/src/main/js/components/ui/__tests__/Level-test.js index 64f296b3174..0a23d266b11 100644 --- a/server/sonar-web/src/main/js/components/ui/__tests__/Level-test.js +++ b/server/sonar-web/src/main/js/components/ui/__tests__/Level-test.js @@ -22,6 +22,6 @@ import React from 'react'; import Level from '../Level'; it('should render', () => { - const rating = shallow(<Level level="ERROR"/>); + const rating = shallow(<Level level="ERROR" />); expect(rating.is('.level-ERROR')).toBe(true); }); diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/Rating-test.js b/server/sonar-web/src/main/js/components/ui/__tests__/Rating-test.js index 227f605f9de..05e24ce63c2 100644 --- a/server/sonar-web/src/main/js/components/ui/__tests__/Rating-test.js +++ b/server/sonar-web/src/main/js/components/ui/__tests__/Rating-test.js @@ -22,11 +22,11 @@ import React from 'react'; import Rating from '../Rating'; it('should render with numeric value', () => { - const rating = shallow(<Rating value={2}/>); + const rating = shallow(<Rating value={2} />); expect(rating.is('.rating-B')).toBe(true); }); it('should render with string value', () => { - const rating = shallow(<Rating value="2.0"/>); + const rating = shallow(<Rating value="2.0" />); expect(rating.is('.rating-B')).toBe(true); }); diff --git a/server/sonar-web/src/main/js/components/widgets/barchart.js b/server/sonar-web/src/main/js/components/widgets/barchart.js index 451cc38738a..26635fcaa20 100644 --- a/server/sonar-web/src/main/js/components/widgets/barchart.js +++ b/server/sonar-web/src/main/js/components/widgets/barchart.js @@ -21,13 +21,13 @@ import $ from 'jquery'; import moment from 'moment'; import d3 from 'd3'; -function trans (left, top) { +function trans(left, top) { return `translate(${left}, ${top})`; } const DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ssZZ'; -const defaults = function () { +const defaults = function() { return { height: 140, color: '#1f77b4', @@ -47,8 +47,8 @@ const defaults = function () { * ] */ -$.fn.barchart = function (data) { - $(this).each(function () { +$.fn.barchart = function(data) { + $(this).each(function() { const options = { ...defaults(), ...$(this).data() }; Object.assign(options, { width: options.width || $(this).width(), @@ -56,17 +56,15 @@ $.fn.barchart = function (data) { }); const container = d3.select(this); - const svg = container.append('svg') - .attr('width', options.width + 2) - .attr('height', options.height + 2) - .classed('sonar-d3', true); - const plot = svg.append('g') - .classed('plot', true); - const xScale = d3.scale.ordinal() - .domain(data.map((d, i) => i)); + const svg = container + .append('svg') + .attr('width', options.width + 2) + .attr('height', options.height + 2) + .classed('sonar-d3', true); + const plot = svg.append('g').classed('plot', true); + const xScale = d3.scale.ordinal().domain(data.map((d, i) => i)); const yScaleMax = d3.max(data, d => d.count); - const yScale = d3.scale.linear() - .domain([0, yScaleMax]); + const yScale = d3.scale.linear().domain([0, yScaleMax]); Object.assign(options, { availableWidth: options.width - options.marginLeft - options.marginRight, @@ -81,52 +79,56 @@ $.fn.barchart = function (data) { const bars = plot.selectAll('g').data(data); if (barWidth > 0) { - const barsEnter = bars.enter() - .append('g') - .attr('transform', (d, i) => ( - trans(xScale(i), Math.ceil(options.availableHeight - yScale(d.count))) - )); - - barsEnter.append('rect') - .style('fill', options.color) - .attr('width', barWidth) - .attr('height', d => Math.floor(yScale(d.count))) - .style('cursor', 'pointer') - .attr('data-period-start', d => moment(d.val).format(DATE_FORMAT)) - .attr('data-period-end', (d, i) => { - const ending = i < data.length - 1 ? moment(data[i + 1].val) : options.endDate; - if (ending) { - return ending.format(DATE_FORMAT); - } else { - return ''; - } - }) - .attr('title', (d, i) => { - const beginning = moment(d.val); - const ending = i < data.length - 1 ? moment(data[i + 1].val).subtract(1, 'days') : options.endDate; - if (ending) { - const isSameDay = ending.diff(beginning, 'days') <= 1; - return d.text + '<br>' + beginning.format('LL') + (isSameDay ? '' : (' – ' + ending.format('LL'))); - } else { - return d.text + '<br>' + beginning.format('LL'); - } - }) - .attr('data-placement', 'bottom') - .attr('data-toggle', 'tooltip'); + const barsEnter = bars + .enter() + .append('g') + .attr('transform', (d, i) => + trans(xScale(i), Math.ceil(options.availableHeight - yScale(d.count)))); + barsEnter + .append('rect') + .style('fill', options.color) + .attr('width', barWidth) + .attr('height', d => Math.floor(yScale(d.count))) + .style('cursor', 'pointer') + .attr('data-period-start', d => moment(d.val).format(DATE_FORMAT)) + .attr('data-period-end', (d, i) => { + const ending = i < data.length - 1 ? moment(data[i + 1].val) : options.endDate; + if (ending) { + return ending.format(DATE_FORMAT); + } else { + return ''; + } + }) + .attr('title', (d, i) => { + const beginning = moment(d.val); + const ending = i < data.length - 1 + ? moment(data[i + 1].val).subtract(1, 'days') + : options.endDate; + if (ending) { + const isSameDay = ending.diff(beginning, 'days') <= 1; + return d.text + + '<br>' + + beginning.format('LL') + + (isSameDay ? '' : ' – ' + ending.format('LL')); + } else { + return d.text + '<br>' + beginning.format('LL'); + } + }) + .attr('data-placement', 'bottom') + .attr('data-toggle', 'tooltip'); const maxValue = d3.max(data, d => d.count); let isValueShown = false; - - barsEnter.append('text') - .classed('subtitle', true) - .attr('transform', trans(barWidth / 2, -4)) - .style('text-anchor', 'middle') - .text(d => { - const text = !isValueShown && d.count === maxValue ? d.text : ''; - isValueShown = d.count === maxValue; - return text; - }); - + barsEnter + .append('text') + .classed('subtitle', true) + .attr('transform', trans(barWidth / 2, -4)) + .style('text-anchor', 'middle') + .text(d => { + const text = !isValueShown && d.count === maxValue ? d.text : ''; + isValueShown = d.count === maxValue; + return text; + }); $(this).find('[data-toggle=tooltip]').tooltip({ container: 'body', html: true }); } }); diff --git a/server/sonar-web/src/main/js/components/workspace/main.js b/server/sonar-web/src/main/js/components/workspace/main.js index 4e1170bac38..8c8cfd05f44 100644 --- a/server/sonar-web/src/main/js/components/workspace/main.js +++ b/server/sonar-web/src/main/js/components/workspace/main.js @@ -25,7 +25,7 @@ import ViewerView from './views/viewer-view'; import RuleView from './views/rule-view'; let instance = null; -const Workspace = function () { +const Workspace = function() { if (instance != null) { throw new Error('Cannot instantiate more than one Workspace, use Workspace.getInstance()'); } @@ -33,7 +33,7 @@ const Workspace = function () { }; Workspace.prototype = { - initialize () { + initialize() { const that = this; this.items = new Items(); @@ -49,17 +49,17 @@ Workspace.prototype = { }); }, - save () { + save() { this.items.save(); }, - addComponent (model) { + addComponent(model) { const m = this.items.add2(model); this.save(); return m; }, - open (options) { + open(options) { const model = typeof options.toJSON === 'function' ? options : new Item(options); if (!model.isValid()) { throw new Error(model.validationError); @@ -73,15 +73,15 @@ Workspace.prototype = { } }, - openComponent (options) { - return this.open({ ...options, '__type__': 'component' }); + openComponent(options) { + return this.open({ ...options, __type__: 'component' }); }, - openRule (options) { - return this.open({ ...options, '__type__': 'rule' }); + openRule(options) { + return this.open({ ...options, __type__: 'rule' }); }, - showViewer (Viewer, model) { + showViewer(Viewer, model) { const that = this; if (this.viewerView != null) { this.viewerView.model.trigger('hideViewer'); @@ -91,41 +91,43 @@ Workspace.prototype = { model.trigger('showViewer'); this.viewerView = new Viewer({ model }); this.viewerView - .on('viewerMinimize', () => { - model.trigger('hideViewer'); - that.closeComponentViewer(); - }) - .on('viewerClose', m => { - that.closeComponentViewer(); - m.destroy(); - }); + .on('viewerMinimize', () => { + model.trigger('hideViewer'); + that.closeComponentViewer(); + }) + .on('viewerClose', m => { + that.closeComponentViewer(); + m.destroy(); + }); this.viewerView.$el.appendTo(document.body); this.viewerView.render(); }, - showComponentViewer (model) { + showComponentViewer(model) { this.showViewer(ViewerView, model); }, - closeComponentViewer () { + closeComponentViewer() { if (this.viewerView != null) { this.viewerView.destroy(); $('.with-workspace').removeClass('with-workspace'); } }, - showRule (model) { + showRule(model) { const that = this; - this.fetchRule(model).done(() => { - model.set({ exist: true }); - that.showViewer(RuleView, model); - }).fail(() => { - model.set({ exist: false }); - that.showViewer(RuleView, model); - }); + this.fetchRule(model) + .done(() => { + model.set({ exist: true }); + that.showViewer(RuleView, model); + }) + .fail(() => { + model.set({ exist: false }); + that.showViewer(RuleView, model); + }); }, - fetchRule (model) { + fetchRule(model) { const url = window.baseUrl + '/api/rules/show'; const options = { key: model.get('key') }; return $.get(url, options).done(r => { @@ -134,7 +136,7 @@ Workspace.prototype = { } }; -Workspace.getInstance = function () { +Workspace.getInstance = function() { if (instance == null) { instance = new Workspace(); } diff --git a/server/sonar-web/src/main/js/components/workspace/models/item.js b/server/sonar-web/src/main/js/components/workspace/models/item.js index 1dd6daf7fc5..6f46d53dc67 100644 --- a/server/sonar-web/src/main/js/components/workspace/models/item.js +++ b/server/sonar-web/src/main/js/components/workspace/models/item.js @@ -20,8 +20,7 @@ import Backbone from 'backbone'; export default Backbone.Model.extend({ - - validate () { + validate() { if (!this.has('__type__')) { return 'type is missing'; } @@ -33,15 +32,15 @@ export default Backbone.Model.extend({ } }, - isComponent () { + isComponent() { return this.get('__type__') === 'component'; }, - isRule () { + isRule() { return this.get('__type__') === 'rule'; }, - destroy (options) { + destroy(options) { this.stopListening(); this.trigger('destroy', this, this.collection, options); } diff --git a/server/sonar-web/src/main/js/components/workspace/models/items.js b/server/sonar-web/src/main/js/components/workspace/models/items.js index 97ff41e2267..655b836da8b 100644 --- a/server/sonar-web/src/main/js/components/workspace/models/items.js +++ b/server/sonar-web/src/main/js/components/workspace/models/items.js @@ -25,16 +25,16 @@ const STORAGE_KEY = 'sonarqube-workspace'; export default Backbone.Collection.extend({ model: Item, - initialize () { + initialize() { this.on('remove', this.save); }, - save () { + save() { const dump = JSON.stringify(this.toJSON()); window.localStorage.setItem(STORAGE_KEY, dump); }, - load () { + load() { const dump = window.localStorage.getItem(STORAGE_KEY); if (dump != null) { try { @@ -46,13 +46,13 @@ export default Backbone.Collection.extend({ } }, - has (model) { + has(model) { const forComponent = model.isComponent() && this.findWhere({ key: model.get('key') }) != null; const forRule = model.isRule() && this.findWhere({ key: model.get('key') }) != null; return forComponent || forRule; }, - add2 (model) { + add2(model) { const tryModel = this.findWhere({ key: model.get('key') }); return tryModel != null ? tryModel : this.add(model); } diff --git a/server/sonar-web/src/main/js/components/workspace/views/base-viewer-view.js b/server/sonar-web/src/main/js/components/workspace/views/base-viewer-view.js index 28d99d420c4..07c38684335 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/base-viewer-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/base-viewer-view.js @@ -24,7 +24,7 @@ export default Marionette.LayoutView.extend({ className: 'workspace-viewer', modelEvents: { - 'destroy': 'destroy' + destroy: 'destroy' }, regions: { @@ -32,24 +32,23 @@ export default Marionette.LayoutView.extend({ viewerRegion: '.workspace-viewer-container' }, - onRender () { + onRender() { this.showHeader(); this.$('.workspace-viewer-container').isolatedScroll(); }, - onViewerMinimize () { + onViewerMinimize() { this.trigger('viewerMinimize'); }, - onViewerClose () { + onViewerClose() { this.trigger('viewerClose', this.model); }, - showHeader () { + showHeader() { const headerView = new HeaderView({ model: this.model }); this.listenTo(headerView, 'viewerMinimize', this.onViewerMinimize); this.listenTo(headerView, 'viewerClose', this.onViewerClose); this.headerRegion.show(headerView); } }); - diff --git a/server/sonar-web/src/main/js/components/workspace/views/item-view.js b/server/sonar-web/src/main/js/components/workspace/views/item-view.js index b64a06f265e..31d4b9a7bf6 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/item-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/item-view.js @@ -26,9 +26,9 @@ export default Marionette.ItemView.extend({ template: Template, modelEvents: { - 'change': 'render', - 'showViewer': 'onViewerShow', - 'hideViewer': 'onViewerHide' + change: 'render', + showViewer: 'onViewerShow', + hideViewer: 'onViewerHide' }, events: { @@ -36,23 +36,22 @@ export default Marionette.ItemView.extend({ 'click .js-close': 'onCloseClick' }, - onClick (e) { + onClick(e) { e.preventDefault(); this.options.collectionView.trigger('click', this.model); }, - onCloseClick (e) { + onCloseClick(e) { e.preventDefault(); e.stopPropagation(); this.model.destroy(); }, - onViewerShow () { + onViewerShow() { this.$el.addClass('hidden'); }, - onViewerHide () { + onViewerHide() { this.$el.removeClass('hidden'); } }); - diff --git a/server/sonar-web/src/main/js/components/workspace/views/items-view.js b/server/sonar-web/src/main/js/components/workspace/views/items-view.js index 609d4287378..284f2e976a9 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/items-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/items-view.js @@ -27,8 +27,7 @@ export default Marionette.CompositeView.extend({ childViewContainer: '.workspace-nav-list', childView: ItemView, - childViewOptions () { + childViewOptions() { return { collectionView: this }; } }); - diff --git a/server/sonar-web/src/main/js/components/workspace/views/rule-view.js b/server/sonar-web/src/main/js/components/workspace/views/rule-view.js index c7fe22d6b98..f32a3908aaf 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/rule-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/rule-view.js @@ -25,16 +25,16 @@ import Template from '../templates/workspace-rule.hbs'; export default BaseView.extend({ template: Template, - onRender () { + onRender() { BaseView.prototype.onRender.apply(this, arguments); this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' }); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); }, - serializeData () { + serializeData() { return { ...Marionette.LayoutView.prototype.serializeData.apply(this, arguments), allTags: union(this.model.get('sysTags'), this.model.get('tags')) diff --git a/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js b/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js index 18316483baf..4534781a090 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/viewer-header-view.js @@ -25,7 +25,7 @@ export default Marionette.ItemView.extend({ template: Template, modelEvents: { - 'change': 'render' + change: 'render' }, events: { @@ -37,72 +37,68 @@ export default Marionette.ItemView.extend({ 'click .js-close': 'onCloseClick' }, - onRender () { + onRender() { this.$('[data-toggle="tooltip"]').tooltip({ container: 'body' }); this.$('.js-normal-size').addClass('hidden'); }, - onDestroy () { + onDestroy() { this.$('[data-toggle="tooltip"]').tooltip('destroy'); $('.tooltip').remove(); }, - onResizeClick (e) { + onResizeClick(e) { e.preventDefault(); this.startResizing(e); }, - onMinimizeClick (e) { + onMinimizeClick(e) { e.preventDefault(); this.trigger('viewerMinimize'); }, - onFullScreenClick (e) { + onFullScreenClick(e) { e.preventDefault(); this.toFullScreen(); }, - onNormalSizeClick (e) { + onNormalSizeClick(e) { e.preventDefault(); this.toNormalSize(); }, - onCloseClick (e) { + onCloseClick(e) { e.preventDefault(); this.trigger('viewerClose'); }, - startResizing (e) { + startResizing(e) { this.initialResizePosition = e.clientY; this.initialResizeHeight = $('.workspace-viewer-container').height(); const processResizing = this.processResizing.bind(this); const stopResizing = this.stopResizing.bind(this); - $('body') - .on('mousemove.workspace', processResizing) - .on('mouseup.workspace', stopResizing); + $('body').on('mousemove.workspace', processResizing).on('mouseup.workspace', stopResizing); }, - processResizing (e) { + processResizing(e) { const currentResizePosition = e.clientY; const resizeDelta = this.initialResizePosition - currentResizePosition; const height = this.initialResizeHeight + resizeDelta; $('.workspace-viewer-container').height(height); }, - stopResizing () { - $('body') - .off('mousemove.workspace') - .off('mouseup.workspace'); + stopResizing() { + $('body').off('mousemove.workspace').off('mouseup.workspace'); }, - toFullScreen () { + toFullScreen() { this.$('.js-normal-size').removeClass('hidden'); this.$('.js-full-screen').addClass('hidden'); this.initialResizeHeight = $('.workspace-viewer-container').height(); $('.workspace-viewer-container').height('9999px'); }, - toNormalSize () { + toNormalSize() { this.$('.js-normal-size').addClass('hidden'); this.$('.js-full-screen').removeClass('hidden'); $('.workspace-viewer-container').height(this.initialResizeHeight); diff --git a/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js b/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js index 188b08cab60..e0dda6033f7 100644 --- a/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js +++ b/server/sonar-web/src/main/js/components/workspace/views/viewer-view.js @@ -28,12 +28,12 @@ import WithStore from '../../shared/WithStore'; export default BaseView.extend({ template: Template, - onRender () { + onRender() { BaseView.prototype.onRender.apply(this, arguments); this.showViewer(); }, - scrollToLine (line) { + scrollToLine(line) { const row = this.$el.find(`.source-line[data-line-number="${line}"]`); if (row.length > 0) { const sourceViewer = this.$el.find('.source-viewer'); @@ -48,12 +48,12 @@ export default BaseView.extend({ } }, - showViewer () { + showViewer() { const { key, line } = this.model.toJSON(); const el = document.querySelector(this.viewerRegion.el); - render(( + render( <WithStore> <SourceViewer component={key} @@ -64,8 +64,10 @@ export default BaseView.extend({ if (line) { this.scrollToLine(line); } - }}/> - </WithStore> - ), el); + }} + /> + </WithStore>, + el + ); } }); diff --git a/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.js b/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.js index 8234f9b25f0..3763be42db6 100644 --- a/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.js +++ b/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.js @@ -25,7 +25,7 @@ afterEach(() => { describe('#translate', () => { it('should translate simple message', () => { - resetBundle({ 'my_key': 'my message' }); + resetBundle({ my_key: 'my message' }); expect(translate('my_key')).toBe('my message'); }); @@ -46,23 +46,25 @@ describe('#translate', () => { describe('#translateWithParameters', () => { it('should translate message with one parameter in the beginning', () => { - resetBundle({ 'x_apples': '{0} apples' }); + resetBundle({ x_apples: '{0} apples' }); expect(translateWithParameters('x_apples', 5)).toBe('5 apples'); }); it('should translate message with one parameter in the middle', () => { - resetBundle({ 'x_apples': 'I have {0} apples' }); + resetBundle({ x_apples: 'I have {0} apples' }); expect(translateWithParameters('x_apples', 5)).toBe('I have 5 apples'); }); it('should translate message with one parameter in the end', () => { - resetBundle({ 'x_apples': 'Apples: {0}' }); + resetBundle({ x_apples: 'Apples: {0}' }); expect(translateWithParameters('x_apples', 5)).toBe('Apples: 5'); }); it('should translate message with several parameters', () => { - resetBundle({ 'x_apples': '{0}: I have {2} apples in my {1} baskets - {3}' }); - expect(translateWithParameters('x_apples', 1, 2, 3, 4)).toBe('1: I have 3 apples in my 2 baskets - 4'); + resetBundle({ x_apples: '{0}: I have {2} apples in my {1} baskets - {3}' }); + expect(translateWithParameters('x_apples', 1, 2, 3, 4)).toBe( + '1: I have 3 apples in my 2 baskets - 4' + ); }); it('should not translate message but return its key', () => { diff --git a/server/sonar-web/src/main/js/helpers/__tests__/measures-test.js b/server/sonar-web/src/main/js/helpers/__tests__/measures-test.js index 5bf2f905e6c..bc621a44fec 100644 --- a/server/sonar-web/src/main/js/helpers/__tests__/measures-test.js +++ b/server/sonar-web/src/main/js/helpers/__tests__/measures-test.js @@ -228,8 +228,12 @@ describe('#formatMeasureVariation()', () => { expect(formatMeasureVariation(ONE_HOUR + 55 * ONE_MINUTE, 'SHORT_WORK_DUR')).toBe('+2h'); expect(formatMeasureVariation(3 * ONE_DAY + 6 * ONE_HOUR, 'SHORT_WORK_DUR')).toBe('+4d'); expect(formatMeasureVariation(7 * ONE_HOUR + 59 * ONE_MINUTE, 'SHORT_WORK_DUR')).toBe('+1d'); - expect(formatMeasureVariation(5 * ONE_DAY + 2 * ONE_HOUR + ONE_MINUTE, 'SHORT_WORK_DUR')).toBe('+5d'); - expect(formatMeasureVariation(15 * ONE_DAY + 2 * ONE_HOUR + ONE_MINUTE, 'SHORT_WORK_DUR')).toBe('+15d'); + expect(formatMeasureVariation(5 * ONE_DAY + 2 * ONE_HOUR + ONE_MINUTE, 'SHORT_WORK_DUR')).toBe( + '+5d' + ); + expect(formatMeasureVariation(15 * ONE_DAY + 2 * ONE_HOUR + ONE_MINUTE, 'SHORT_WORK_DUR')).toBe( + '+15d' + ); expect(formatMeasureVariation(7 * ONE_MINUTE, 'SHORT_WORK_DUR')).toBe('+7min'); expect(formatMeasureVariation(-5 * ONE_DAY, 'SHORT_WORK_DUR')).toBe('-5d'); expect(formatMeasureVariation(-2 * ONE_HOUR, 'SHORT_WORK_DUR')).toBe('-2h'); diff --git a/server/sonar-web/src/main/js/helpers/__tests__/path-test.js b/server/sonar-web/src/main/js/helpers/__tests__/path-test.js index 6520af31676..3941b76b9b7 100644 --- a/server/sonar-web/src/main/js/helpers/__tests__/path-test.js +++ b/server/sonar-web/src/main/js/helpers/__tests__/path-test.js @@ -33,13 +33,15 @@ describe('#collapsedDirFromPath()', () => { }); it('should cut long path', () => { - expect(collapsedDirFromPath('src/main/js/components/navigator/app/models/state.js')) - .toBe('src/.../js/components/navigator/app/models/'); + expect(collapsedDirFromPath('src/main/js/components/navigator/app/models/state.js')).toBe( + 'src/.../js/components/navigator/app/models/' + ); }); it('should cut very long path', () => { - expect(collapsedDirFromPath('src/main/another/js/components/navigator/app/models/state.js')) - .toBe('src/.../js/components/navigator/app/models/'); + expect( + collapsedDirFromPath('src/main/another/js/components/navigator/app/models/state.js') + ).toBe('src/.../js/components/navigator/app/models/'); }); }); diff --git a/server/sonar-web/src/main/js/helpers/__tests__/urls-test.js b/server/sonar-web/src/main/js/helpers/__tests__/urls-test.js index 730cea9ef83..c6e54c559d5 100644 --- a/server/sonar-web/src/main/js/helpers/__tests__/urls-test.js +++ b/server/sonar-web/src/main/js/helpers/__tests__/urls-test.js @@ -40,34 +40,47 @@ describe('#getComponentUrl', () => { }); it('should encode component key', () => { - expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).toBe('/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED); + expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).toBe( + '/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED + ); }); it('should take baseUrl into account', () => { window.baseUrl = '/context'; - expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).toBe('/context/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED); + expect(getComponentUrl(COMPLEX_COMPONENT_KEY)).toBe( + '/context/dashboard?id=' + COMPLEX_COMPONENT_KEY_ENCODED + ); }); }); describe('#getComponentIssuesUrl', () => { it('should work without parameters', () => { expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, {})).toBe( - '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#'); + '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#' + ); }); it('should encode component key', () => { expect(getComponentIssuesUrl(COMPLEX_COMPONENT_KEY, {})).toBe( - '/component_issues?id=' + COMPLEX_COMPONENT_KEY_ENCODED + '#'); + '/component_issues?id=' + COMPLEX_COMPONENT_KEY_ENCODED + '#' + ); }); it('should work with parameters', () => { expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, { resolved: 'false' })).toBe( - '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#resolved=false'); + '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#resolved=false' + ); }); it('should encode parameters', () => { - expect(getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, { componentUuids: COMPLEX_COMPONENT_KEY })).toBe( - '/component_issues?id=' + SIMPLE_COMPONENT_KEY + '#componentUuids=' + COMPLEX_COMPONENT_KEY_ENCODED); + expect( + getComponentIssuesUrl(SIMPLE_COMPONENT_KEY, { componentUuids: COMPLEX_COMPONENT_KEY }) + ).toBe( + '/component_issues?id=' + + SIMPLE_COMPONENT_KEY + + '#componentUuids=' + + COMPLEX_COMPONENT_KEY_ENCODED + ); }); }); diff --git a/server/sonar-web/src/main/js/helpers/constants.js b/server/sonar-web/src/main/js/helpers/constants.js index 4fcd519529a..96422aad693 100644 --- a/server/sonar-web/src/main/js/helpers/constants.js +++ b/server/sonar-web/src/main/js/helpers/constants.js @@ -21,4 +21,10 @@ export const SEVERITIES = ['BLOCKER', 'CRITICAL', 'MAJOR', 'MINOR', 'INFO']; export const STATUSES = ['OPEN', 'REOPENED', 'CONFIRMED', 'RESOLVED', 'CLOSED']; export const CHART_COLORS_RANGE_PERCENT = ['#00aa00', '#b0d513', '#eabe06', '#ed7d20', '#d4333f']; -export const CHART_REVERSED_COLORS_RANGE_PERCENT = ['#d4333f', '#ed7d20', '#eabe06', '#b0d513', '#00aa00']; +export const CHART_REVERSED_COLORS_RANGE_PERCENT = [ + '#d4333f', + '#ed7d20', + '#eabe06', + '#b0d513', + '#00aa00' +]; diff --git a/server/sonar-web/src/main/js/helpers/cookies.js b/server/sonar-web/src/main/js/helpers/cookies.js index 0a8ee581989..ad2cef2a945 100644 --- a/server/sonar-web/src/main/js/helpers/cookies.js +++ b/server/sonar-web/src/main/js/helpers/cookies.js @@ -20,7 +20,7 @@ // @flow let cookies; -export function getCookie (name: string) { +export function getCookie(name: string) { if (cookies) { return cookies[name]; } diff --git a/server/sonar-web/src/main/js/helpers/csv.js b/server/sonar-web/src/main/js/helpers/csv.js index 05fa990d2ac..c07e0c868d2 100644 --- a/server/sonar-web/src/main/js/helpers/csv.js +++ b/server/sonar-web/src/main/js/helpers/csv.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow -export function csvEscape (value: string): string { +export function csvEscape(value: string): string { const escaped = value.replace(/"/g, '\\"'); return `"${escaped}"`; } diff --git a/server/sonar-web/src/main/js/helpers/handlebars/alertIconClass.js b/server/sonar-web/src/main/js/helpers/handlebars/alertIconClass.js index f7ffa5f14d6..5e62278dc0e 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/alertIconClass.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/alertIconClass.js @@ -19,8 +19,6 @@ */ import Handlebars from 'handlebars/runtime'; -module.exports = function (alert) { - return new Handlebars.default.SafeString( - 'icon-alert-' + alert.toLowerCase() - ); +module.exports = function(alert) { + return new Handlebars.default.SafeString('icon-alert-' + alert.toLowerCase()); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/all.js b/server/sonar-web/src/main/js/helpers/handlebars/all.js index e6700493451..b68d8d6b3df 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/all.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/all.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { const options = args[args.length - 1]; const list = args.slice(0, -1); const all = list.reduce((prev, current) => prev && current, true); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/any.js b/server/sonar-web/src/main/js/helpers/handlebars/any.js index c54631ca2a0..d9dd373ddd4 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/any.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/any.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { const options = args[args.length - 1]; const list = args.slice(0, -1); const any = list.reduce((prev, current) => prev || current, false); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/avatarHelper.js b/server/sonar-web/src/main/js/helpers/handlebars/avatarHelper.js index b363867eb4b..67220a97d5a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/avatarHelper.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/avatarHelper.js @@ -20,7 +20,7 @@ import md5 from 'blueimp-md5'; import Handlebars from 'handlebars/runtime'; -function gravatarServer () { +function gravatarServer() { const getStore = require('../../app/utils/getStore').default; const { getSettingValue } = require('../../store/rootReducer'); @@ -28,13 +28,11 @@ function gravatarServer () { return (getSettingValue(store.getState(), 'sonar.lf.gravatarServerUrl') || {}).value; } -module.exports = function (email, size) { +module.exports = function(email, size) { // double the size for high pixel density screens const emailHash = md5.md5((email || '').trim()); - const url = gravatarServer() - .replace('{EMAIL_MD5}', emailHash) - .replace('{SIZE}', size * 2); + const url = gravatarServer().replace('{EMAIL_MD5}', emailHash).replace('{SIZE}', size * 2); return new Handlebars.default.SafeString( - `<img class="rounded" src="${url}" width="${size}" height="${size}" alt="${email}">` + `<img class="rounded" src="${url}" width="${size}" height="${size}" alt="${email}">` ); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/capitalize.js b/server/sonar-web/src/main/js/helpers/handlebars/capitalize.js index 63e2b200913..ee2d3fa8799 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/capitalize.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/capitalize.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (string) { +module.exports = function(string) { return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/changelog.js b/server/sonar-web/src/main/js/helpers/handlebars/changelog.js index 3ccf6a9be07..ec409ce9add 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/changelog.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/changelog.js @@ -20,7 +20,7 @@ import { translate, translateWithParameters } from '../../helpers/l10n'; import { formatMeasure } from '../../helpers/measures'; -module.exports = function (diff) { +module.exports = function(diff) { let message; if (diff.key === 'file') { @@ -28,20 +28,25 @@ module.exports = function (diff) { } if (diff.newValue != null) { - const newValue = diff.key === 'effort' ? - formatMeasure(diff.newValue, 'WORK_DUR') : - diff.newValue; - message = translateWithParameters('issue.changelog.changed_to', - translate('issue.changelog.field', diff.key), newValue); + const newValue = diff.key === 'effort' + ? formatMeasure(diff.newValue, 'WORK_DUR') + : diff.newValue; + message = translateWithParameters( + 'issue.changelog.changed_to', + translate('issue.changelog.field', diff.key), + newValue + ); } else { - message = translateWithParameters('issue.changelog.removed', - translate('issue.changelog.field', diff.key)); + message = translateWithParameters( + 'issue.changelog.removed', + translate('issue.changelog.field', diff.key) + ); } if (diff.oldValue != null) { - const oldValue = diff.key === 'effort' ? - formatMeasure(diff.oldValue, 'WORK_DUR') : - diff.oldValue; + const oldValue = diff.key === 'effort' + ? formatMeasure(diff.oldValue, 'WORK_DUR') + : diff.oldValue; message += ' ('; message += translateWithParameters('issue.changelog.was', oldValue); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/collapsePath.js b/server/sonar-web/src/main/js/helpers/handlebars/collapsePath.js index 9bb0b7584e8..56a8ba3021f 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/collapsePath.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/collapsePath.js @@ -19,6 +19,6 @@ */ import { collapsePath } from '../path'; -module.exports = function (path) { +module.exports = function(path) { return collapsePath(path); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/collapsedDirFromPath.js b/server/sonar-web/src/main/js/helpers/handlebars/collapsedDirFromPath.js index 8eddd1a9364..33dcbdb2294 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/collapsedDirFromPath.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/collapsedDirFromPath.js @@ -19,6 +19,6 @@ */ import { collapsedDirFromPath } from '../path'; -module.exports = function (path) { +module.exports = function(path) { return collapsedDirFromPath(path); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/componentBrowsePermalink.js b/server/sonar-web/src/main/js/helpers/handlebars/componentBrowsePermalink.js index ec104070b26..1786109374c 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/componentBrowsePermalink.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/componentBrowsePermalink.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (componentKey) { +module.exports = function(componentKey) { return window.baseUrl + '/components/index?id=' + encodeURIComponent(componentKey); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/componentDashboardPermalink.js b/server/sonar-web/src/main/js/helpers/handlebars/componentDashboardPermalink.js index 7c8f7e40422..6f388fb49a8 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/componentDashboardPermalink.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/componentDashboardPermalink.js @@ -17,11 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (componentKey, dashboardKey) { - const params = [ - { key: 'id', value: componentKey }, - { key: 'did', value: dashboardKey } - ]; +module.exports = function(componentKey, dashboardKey) { + const params = [{ key: 'id', value: componentKey }, { key: 'did', value: dashboardKey }]; const matchPeriod = window.location.search.match(/period=(\d+)/); if (matchPeriod) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/componentIssuesPermalink.js b/server/sonar-web/src/main/js/helpers/handlebars/componentIssuesPermalink.js index e849eb51826..cd9aaf55d66 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/componentIssuesPermalink.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/componentIssuesPermalink.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (componentKey) { +module.exports = function(componentKey) { return window.baseUrl + '/component_issues/index?id=' + encodeURIComponent(componentKey); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/componentPermalink.js b/server/sonar-web/src/main/js/helpers/handlebars/componentPermalink.js index a5ea3eddbb7..4a45d395468 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/componentPermalink.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/componentPermalink.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (componentKey) { +module.exports = function(componentKey) { return window.baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/d.js b/server/sonar-web/src/main/js/helpers/handlebars/d.js index 72d868abb0c..47e0709a26c 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/d.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/d.js @@ -19,6 +19,6 @@ */ import moment from 'moment'; -module.exports = function (date) { +module.exports = function(date) { return moment(date).format('LL'); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js b/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js index 9d7dc2c04c5..2d7819bfabb 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js @@ -19,7 +19,7 @@ */ import { translate } from '../../helpers/l10n'; -module.exports = function (dashboardName) { +module.exports = function(dashboardName) { const l10nKey = `dashboard.${dashboardName}.name`; const l10nLabel = translate(l10nKey); if (l10nLabel !== l10nKey) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/dashboardUrl.js b/server/sonar-web/src/main/js/helpers/handlebars/dashboardUrl.js index 5f022fd8d18..fbb5b5ab10b 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/dashboardUrl.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/dashboardUrl.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (componentKey, componentQualifier) { +module.exports = function(componentKey, componentQualifier) { let url = window.baseUrl + '/dashboard/index?id=' + encodeURIComponent(componentKey); if (componentQualifier === 'FIL' || componentQualifier === 'CLA') { url += '&metric=sqale_index'; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/default.js b/server/sonar-web/src/main/js/helpers/handlebars/default.js index 39650a052ad..4dd7a7d2f5a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/default.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/default.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { const list = args.slice(0, -1); return list.reduce((prev, current) => prev != null ? prev : current, null); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/dirFromPath.js b/server/sonar-web/src/main/js/helpers/handlebars/dirFromPath.js index 8493c686dc8..ef39646e1e4 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/dirFromPath.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/dirFromPath.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (path) { +module.exports = function(path) { if (typeof path === 'string') { const tokens = path.split('/'); return tokens.length > 1 ? tokens.slice(0, -1).join('/') + '/' : ''; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ds.js b/server/sonar-web/src/main/js/helpers/handlebars/ds.js index 82d499370b2..52430aef8dc 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ds.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ds.js @@ -19,6 +19,6 @@ */ import moment from 'moment'; -module.exports = function (date) { +module.exports = function(date) { return moment(date).format('YYYY-MM-DD'); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/dt.js b/server/sonar-web/src/main/js/helpers/handlebars/dt.js index 07be677136d..c343c4bf17e 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/dt.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/dt.js @@ -19,6 +19,6 @@ */ import moment from 'moment'; -module.exports = function (date) { +module.exports = function(date) { return moment(date).format('LLL'); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/durationFromNow.js b/server/sonar-web/src/main/js/helpers/handlebars/durationFromNow.js index ae052bafccc..fec9cb09b05 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/durationFromNow.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/durationFromNow.js @@ -19,6 +19,6 @@ */ import moment from 'moment'; -module.exports = function (date, units) { +module.exports = function(date, units) { return moment(new Date()).diff(date, units); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eachChanged.js b/server/sonar-web/src/main/js/helpers/handlebars/eachChanged.js index c47748382a7..15c202363d7 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eachChanged.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eachChanged.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (context, property, options) { +module.exports = function(context, property, options) { let ret = ''; context.forEach((d, i) => { const changed = i > 0 ? d[property] !== context[i - 1][property] : true; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eachEven.js b/server/sonar-web/src/main/js/helpers/handlebars/eachEven.js index 08da2f5d2e2..418147dd589 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eachEven.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eachEven.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (context, options) { +module.exports = function(context, options) { let ret = ''; context.forEach((d, i) => { if (i % 2 === 0) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eachIndex.js b/server/sonar-web/src/main/js/helpers/handlebars/eachIndex.js index 380d667fb2b..51289bf6c1c 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eachIndex.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eachIndex.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (context, options) { +module.exports = function(context, options) { let ret = ''; context.forEach((d, index) => { const c = { index, ...d }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eachOdd.js b/server/sonar-web/src/main/js/helpers/handlebars/eachOdd.js index 8ec991eb479..c25ff315438 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eachOdd.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eachOdd.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (context, options) { +module.exports = function(context, options) { let ret = ''; context.forEach((d, i) => { if (i % 2 === 1) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eachReverse.js b/server/sonar-web/src/main/js/helpers/handlebars/eachReverse.js index fd110a74931..aebecc4a762 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eachReverse.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eachReverse.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, options) { +module.exports = function(array, options) { let ret = ''; if (array && array.length > 0) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eachWithPrevious.js b/server/sonar-web/src/main/js/helpers/handlebars/eachWithPrevious.js index 140c4f8c01b..c65330c0e2a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eachWithPrevious.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eachWithPrevious.js @@ -17,13 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (context, options) { +module.exports = function(context, options) { let ret = ''; if (Array.isArray(context)) { context.forEach((element, index, list) => { const previous = index > 0 ? list[index - 1] : null; - const c = { '_previous': previous, ...element }; + const c = { _previous: previous, ...element }; ret += options.fn(c); }); } diff --git a/server/sonar-web/src/main/js/helpers/handlebars/empty.js b/server/sonar-web/src/main/js/helpers/handlebars/empty.js index b9641e09b32..b6292bc3dfa 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/empty.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/empty.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, options) { +module.exports = function(array, options) { const cond = Array.isArray(array) && array.length > 0; return cond ? options.inverse(this) : options.fn(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eq.js b/server/sonar-web/src/main/js/helpers/handlebars/eq.js index 030c04aa20c..0036c5909b0 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eq.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eq.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (v1, v2, options) { +module.exports = function(v1, v2, options) { /* eslint eqeqeq: 0 */ return v1 == v2 ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/eqComponents.js b/server/sonar-web/src/main/js/helpers/handlebars/eqComponents.js index 6fa5faeff0d..1094adc8048 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/eqComponents.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/eqComponents.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (a, b, options) { - const notEq = a && b && ((a.project !== b.project) || (a.subProject !== b.subProject)); +module.exports = function(a, b, options) { + const notEq = a && b && (a.project !== b.project || a.subProject !== b.subProject); return notEq ? options.inverse(this) : options.fn(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/exporterUrl.js b/server/sonar-web/src/main/js/helpers/handlebars/exporterUrl.js index 40ceb13406b..e7cee0663e8 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/exporterUrl.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/exporterUrl.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (profile, exporterKey) { +module.exports = function(profile, exporterKey) { let url = window.baseUrl + '/api/qualityprofiles/export'; url += '?language=' + encodeURIComponent(profile.language); url += '&name=' + encodeURIComponent(profile.name); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/fileFromPath.js b/server/sonar-web/src/main/js/helpers/handlebars/fileFromPath.js index 0380a1ab091..cbd67c58103 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/fileFromPath.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/fileFromPath.js @@ -19,6 +19,6 @@ */ import { fileFromPath } from '../path'; -module.exports = function (path) { +module.exports = function(path) { return fileFromPath(path); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/formatFacetValue.js b/server/sonar-web/src/main/js/helpers/handlebars/formatFacetValue.js index 4358c116440..13ab82b9342 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/formatFacetValue.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/formatFacetValue.js @@ -19,8 +19,7 @@ */ import { formatMeasure } from '../measures'; -module.exports = function (value, facetMode) { +module.exports = function(value, facetMode) { const formatter = facetMode === 'effort' ? 'SHORT_WORK_DUR' : 'SHORT_INT'; return formatMeasure(value, formatter); }; - diff --git a/server/sonar-web/src/main/js/helpers/handlebars/formatMeasure.js b/server/sonar-web/src/main/js/helpers/handlebars/formatMeasure.js index 7c793c4818f..2d0c4f75a3a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/formatMeasure.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/formatMeasure.js @@ -19,6 +19,6 @@ */ import { formatMeasure } from '../measures'; -module.exports = function (measure, type) { +module.exports = function(measure, type) { return formatMeasure(measure, type); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/formatMeasureVariation.js b/server/sonar-web/src/main/js/helpers/handlebars/formatMeasureVariation.js index 4691729bc14..0f7268b8d45 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/formatMeasureVariation.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/formatMeasureVariation.js @@ -19,6 +19,6 @@ */ import { formatMeasureVariation } from '../measures'; -module.exports = function (measure, type) { +module.exports = function(measure, type) { return formatMeasureVariation(measure, type); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/fromNow.js b/server/sonar-web/src/main/js/helpers/handlebars/fromNow.js index dc2f302ad0a..5d4fc596ef5 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/fromNow.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/fromNow.js @@ -19,6 +19,6 @@ */ import moment from 'moment'; -module.exports = function (date) { +module.exports = function(date) { return moment(date).fromNow(); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/gt.js b/server/sonar-web/src/main/js/helpers/handlebars/gt.js index 7b8ab5ce735..b080892436d 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/gt.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/gt.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (v1, v2, options) { +module.exports = function(v1, v2, options) { return v1 > v2 ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifLength.js b/server/sonar-web/src/main/js/helpers/handlebars/ifLength.js index 747ecd2a23a..df7578ac096 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifLength.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifLength.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, len, options) { +module.exports = function(array, len, options) { const cond = Array.isArray(array) && array.length === +len; return cond ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifLengthGT.js b/server/sonar-web/src/main/js/helpers/handlebars/ifLengthGT.js index 840e34d71d4..79ee2daf7fc 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifLengthGT.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifLengthGT.js @@ -17,8 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, len, options) { - return Array.isArray(array) && array.length > len ? - options.fn(this) : - options.inverse(this); +module.exports = function(array, len, options) { + return Array.isArray(array) && array.length > len ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifMeasureShouldBeShown.js b/server/sonar-web/src/main/js/helpers/handlebars/ifMeasureShouldBeShown.js index 76daf8434c8..ba482982a56 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifMeasureShouldBeShown.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifMeasureShouldBeShown.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (measure, period, options) { +module.exports = function(measure, period, options) { if (measure != null || period != null) { return options.fn(this); } else { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifNotEmpty.js b/server/sonar-web/src/main/js/helpers/handlebars/ifNotEmpty.js index 868c2442f40..7cf02fd690e 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifNotEmpty.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifNotEmpty.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { const options = args[args.length - 1]; const list = args.slice(0, -1); const notEmpty = list.reduce((prev, current) => prev || (current && current.length > 0), false); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged.js b/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged.js index ac1b427f8e4..567966a17b1 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged.js @@ -17,13 +17,14 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (source, line, options) { +module.exports = function(source, line, options) { const currentLine = source.find(row => row.lineNumber === line); const prevLine = source.find(row => row.lineNumber === line - 1); let changed = true; if (currentLine && prevLine && currentLine.scm && prevLine.scm) { - changed = (currentLine.scm.author !== prevLine.scm.author) || - (currentLine.scm.date !== prevLine.scm.date) || (!prevLine.show); + changed = currentLine.scm.author !== prevLine.scm.author || + currentLine.scm.date !== prevLine.scm.date || + !prevLine.show; } return changed ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged2.js b/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged2.js index 1d8c0337576..7b43f90609a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged2.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifSCMChanged2.js @@ -17,10 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (currentLine, prevLine, options) { +module.exports = function(currentLine, prevLine, options) { let changed = true; if (currentLine && prevLine && currentLine.scmAuthor && prevLine.scmAuthor) { - changed = (currentLine.scmAuthor !== prevLine.scmAuthor) || (currentLine.scmDate !== prevLine.scmDate); + changed = currentLine.scmAuthor !== prevLine.scmAuthor || + currentLine.scmDate !== prevLine.scmDate; } return changed ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifShowAvatars.js b/server/sonar-web/src/main/js/helpers/handlebars/ifShowAvatars.js index 9198d30b927..03afa92c69c 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifShowAvatars.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifShowAvatars.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -function enableGravatar () { +function enableGravatar() { const getStore = require('../../app/utils/getStore').default; const { getSettingValue } = require('../../store/rootReducer'); @@ -25,6 +25,6 @@ function enableGravatar () { return (getSettingValue(store.getState(), 'sonar.lf.enableGravatar') || {}).value === 'true'; } -module.exports = function (options) { +module.exports = function(options) { return enableGravatar() ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/ifTestData.js b/server/sonar-web/src/main/js/helpers/handlebars/ifTestData.js index 037472c7453..3890484400a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/ifTestData.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/ifTestData.js @@ -17,8 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (test, options) { - if ((test.status !== 'OK') || ((test.status === 'OK') && test.coveredLines)) { +module.exports = function(test, options) { + if (test.status !== 'OK' || (test.status === 'OK' && test.coveredLines)) { return options.fn(this); } else { return options.inverse(this); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/inArray.js b/server/sonar-web/src/main/js/helpers/handlebars/inArray.js index c6128384140..d27ee3bf395 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/inArray.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/inArray.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, element, options) { +module.exports = function(array, element, options) { if (Array.isArray(array) && array.indexOf(element) !== -1) { return options.fn(this); } else { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/isActiveLink.js b/server/sonar-web/src/main/js/helpers/handlebars/isActiveLink.js index 842178f8495..ece6ad7cbc7 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/isActiveLink.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/isActiveLink.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { const options = args[args.length - 1]; const list = args.slice(0, -1); const prefix = list.join(''); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/isNull.js b/server/sonar-web/src/main/js/helpers/handlebars/isNull.js index 83c2b86faa5..7f5de187317 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/isNull.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/isNull.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (value, options) { +module.exports = function(value, options) { return value == null ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/issueFilterHomeLink.js b/server/sonar-web/src/main/js/helpers/handlebars/issueFilterHomeLink.js index f36ab04e62a..c65b1c7a8d0 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/issueFilterHomeLink.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/issueFilterHomeLink.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (id) { +module.exports = function(id) { return window.baseUrl + '/issues/search#id=' + id; }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/issueFilterValue.js b/server/sonar-web/src/main/js/helpers/handlebars/issueFilterValue.js index ee96ae190e5..4752108a788 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/issueFilterValue.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/issueFilterValue.js @@ -19,7 +19,7 @@ */ import { formatMeasure } from '../measures'; -module.exports = function (value, mode) { +module.exports = function(value, mode) { const formatter = mode === 'effort' ? 'SHORT_WORK_DUR' : 'SHORT_INT'; return formatMeasure(value, formatter); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/issueType.js b/server/sonar-web/src/main/js/helpers/handlebars/issueType.js index 9e7cf60f558..e1e5f96fc2a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/issueType.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/issueType.js @@ -19,6 +19,6 @@ */ import { translate } from '../../helpers/l10n'; -module.exports = function (issueType) { +module.exports = function(issueType) { return translate('issue.type', issueType); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/issueTypeIcon.js b/server/sonar-web/src/main/js/helpers/handlebars/issueTypeIcon.js index 90df8808442..d7c4d6a7fc6 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/issueTypeIcon.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/issueTypeIcon.js @@ -21,22 +21,22 @@ import Handlebars from 'handlebars/runtime'; /* eslint-disable max-len */ const bug = new Handlebars.default.SafeString( - `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> <path style="fill:currentColor" d="M11 9h1.3l.5.8.8-.5-.8-1.3H11v-.3l2-2.3V3h-1v2l-1 1.2V5c-.1-.8-.7-1.5-1.4-1.9L11 1.8l-.7-.7-1.8 1.6-1.8-1.6-.7.7 1.5 1.3C6.7 3.5 6.1 4.2 6 5v1.1L5 5V3H4v2.3l2 2.3V8H4.2l-.7 1.2.8.5.4-.7H6v.3l-2 1.9V14h1v-2.4l1-1C6 12 7.1 13 8.4 13h.8c.7 0 1.4-.3 1.8-.9.3-.4.3-.9.2-1.4l.9.9V14h1v-2.8l-2-1.9V9zm-2 2H8V6h1v5z"/> </svg>` ); const vulnerability = new Handlebars.default.SafeString( - `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> <path style="fill:currentColor" d="M10.8 5H6V3.9a2.28 2.28 0 0 1 2-2.5 2.22 2.22 0 0 1 1.8 1.2.48.48 0 0 0 .7.2.48.48 0 0 0 .2-.7A3 3 0 0 0 8 .4a3.34 3.34 0 0 0-3 3.5v1.2a2.16 2.16 0 0 0-2 2.1v4.4a2.22 2.22 0 0 0 2.2 2.2h5.6a2.22 2.22 0 0 0 2.2-2.2V7.2A2.22 2.22 0 0 0 10.8 5zm-2.2 5.5v1.2H7.4v-1.2a1.66 1.66 0 0 1-1.1-1.6A1.75 1.75 0 0 1 8 7.2a1.71 1.71 0 0 1 .6 3.3z"/> </svg>` ); const codeSmell = new Handlebars.default.SafeString( - `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> <path style="fill:currentColor" d="M8 2C4.7 2 2 4.7 2 8s2.7 6 6 6 6-2.7 6-6-2.7-6-6-6zm-.5 5.5h.9v.9h-.9v-.9zm-3.8.2c-.1 0-.2-.1-.2-.2 0-.4.1-1.2.6-2S5.3 4.2 5.6 4c.2 0 .3 0 .3.1l1.3 2.3c0 .1 0 .2-.1.2-.1.2-.2.3-.3.5-.1.2-.2.4-.2.5 0 .1-.1.2-.2.2l-2.7-.1zM9.9 12c-.3.2-1.1.5-2 .5-.9 0-1.7-.3-2-.5-.1 0-.1-.2-.1-.3l1.3-2.3c0-.1.1-.1.2-.1.2.1.3.1.5.1s.4 0 .5-.1c.1 0 .2 0 .2.1l1.3 2.3c.2.2.2.3.1.3zm2.5-4.1L9.7 8c-.1 0-.2-.1-.2-.2 0-.2-.1-.4-.2-.5 0-.1-.2-.3-.3-.4-.1 0-.1-.1-.1-.2l1.3-2.3c.1-.1.2-.1.3-.1.3.2 1 .7 1.5 1.5s.6 1.6.6 2c0 0-.1.1-.2.1z"/> </svg>` ); -module.exports = function (type) { +module.exports = function(type) { switch (type) { case 'BUG': return bug; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/join.js b/server/sonar-web/src/main/js/helpers/handlebars/join.js index 6f9d4b8124d..b28e2eeb3c1 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/join.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/join.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, separator) { +module.exports = function(array, separator) { return array.join(separator); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/joinEach.js b/server/sonar-web/src/main/js/helpers/handlebars/joinEach.js index 9d6c2437779..5503875561d 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/joinEach.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/joinEach.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, separator, options) { +module.exports = function(array, separator, options) { let ret = ''; if (array && array.length > 0) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/length.js b/server/sonar-web/src/main/js/helpers/handlebars/length.js index 45292c99899..e35510f5a5d 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/length.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/length.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array) { +module.exports = function(array) { return Array.isArray(array) ? array.length : null; }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/limitString.js b/server/sonar-web/src/main/js/helpers/handlebars/limitString.js index 13d1bffc584..ec131d1c76b 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/limitString.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/limitString.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (str) { +module.exports = function(str) { if (typeof str === 'string') { const LIMIT = 30; return str.length > LIMIT ? str.substr(0, LIMIT) + '...' : str; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/link.js b/server/sonar-web/src/main/js/helpers/handlebars/link.js index db88bdaed9d..e1b6306245b 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/link.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/link.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { return window.baseUrl + args.slice(0, -1).join(''); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/log.js b/server/sonar-web/src/main/js/helpers/handlebars/log.js index b552a6ba5c5..aaaa9f39c39 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/log.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/log.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { /* eslint no-console: 0 */ console.log(...args.slice(0, -1)); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/lt.js b/server/sonar-web/src/main/js/helpers/handlebars/lt.js index 02166a34062..2aa609a9ee5 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/lt.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/lt.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (v1, v2, options) { +module.exports = function(v1, v2, options) { return v1 < v2 ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/notEmpty.js b/server/sonar-web/src/main/js/helpers/handlebars/notEmpty.js index 45417e52e04..e7140005ceb 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/notEmpty.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/notEmpty.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, options) { +module.exports = function(array, options) { const cond = Array.isArray(array) && array.length > 0; return cond ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/notEq.js b/server/sonar-web/src/main/js/helpers/handlebars/notEq.js index e4d4e1ea6d2..18e0be28841 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/notEq.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/notEq.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (v1, v2, options) { +module.exports = function(v1, v2, options) { /* eslint eqeqeq: 0 */ return v1 != v2 ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/notEqComponents.js b/server/sonar-web/src/main/js/helpers/handlebars/notEqComponents.js index 849135fa4c8..34759858286 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/notEqComponents.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/notEqComponents.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (a, b, options) { - const notEq = a && b && ((a.project !== b.project) || (a.subProject !== b.subProject)); +module.exports = function(a, b, options) { + const notEq = a && b && (a.project !== b.project || a.subProject !== b.subProject); return notEq ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/notNull.js b/server/sonar-web/src/main/js/helpers/handlebars/notNull.js index 7731cd09136..9aa3f2b343c 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/notNull.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/notNull.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (value, options) { +module.exports = function(value, options) { return value != null ? options.fn(this) : options.inverse(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/numberShort.js b/server/sonar-web/src/main/js/helpers/handlebars/numberShort.js index 20d1233eb01..c2a86b8a93c 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/numberShort.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/numberShort.js @@ -19,7 +19,7 @@ */ import numeral from 'numeral'; -module.exports = function (number) { +module.exports = function(number) { let format = '0,0'; if (number >= 10000) { format = '0.[0]a'; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/operators.js b/server/sonar-web/src/main/js/helpers/handlebars/operators.js index d18ffbdfcc1..67b12e35717 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/operators.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/operators.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (options) { +module.exports = function(options) { const ops = ['LT', 'GT', 'EQ', 'NE']; return ops.reduce((prev, current) => prev + options.fn(current), ''); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js b/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js index 75902a3a5b5..0f945dfd629 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js @@ -20,14 +20,17 @@ import Handlebars from 'handlebars/runtime'; import { translateWithParameters } from '../l10n'; -module.exports = function (value, parameter) { +module.exports = function(value, parameter) { if (parameter) { return new Handlebars.default.SafeString( - translateWithParameters('quality_profiles.parameter_set_to_x', value, parameter) + translateWithParameters('quality_profiles.parameter_set_to_x', value, parameter) ); } else { return new Handlebars.default.SafeString( - translateWithParameters('quality_profiles.changelog.parameter_reset_to_default_value_x', parameter) + translateWithParameters( + 'quality_profiles.changelog.parameter_reset_to_default_value_x', + parameter + ) ); } }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/percent.js b/server/sonar-web/src/main/js/helpers/handlebars/percent.js index f71a9d51d05..5e3e06fb38d 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/percent.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/percent.js @@ -17,9 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (value, total) { +module.exports = function(value, total) { if (total > 0) { - return '' + ((value || 0) / total * 100) + '%'; + return '' + (value || 0) / total * 100 + '%'; } else { return '0%'; } diff --git a/server/sonar-web/src/main/js/helpers/handlebars/profileUrl.js b/server/sonar-web/src/main/js/helpers/handlebars/profileUrl.js index b5531416162..dab5f850fc2 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/profileUrl.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/profileUrl.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (key) { +module.exports = function(key) { return window.baseUrl + '/profiles/show?key=' + encodeURIComponent(key); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/projectFullName.js b/server/sonar-web/src/main/js/helpers/handlebars/projectFullName.js index 6e5d356f633..e92aa71d550 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/projectFullName.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/projectFullName.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (component) { - return component.projectName + (component.subProjectName ? (' / ' + component.subProjectName) : ''); +module.exports = function(component) { + return component.projectName + (component.subProjectName ? ' / ' + component.subProjectName : ''); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/qualifierIcon.js b/server/sonar-web/src/main/js/helpers/handlebars/qualifierIcon.js index 44117345c22..4a4f3420a95 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/qualifierIcon.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/qualifierIcon.js @@ -19,8 +19,8 @@ */ import Handlebars from 'handlebars/runtime'; -module.exports = function (qualifier) { +module.exports = function(qualifier) { return new Handlebars.default.SafeString( - qualifier ? `<i class="icon-qualifier-${qualifier.toLowerCase()}"></i>` : '' + qualifier ? `<i class="icon-qualifier-${qualifier.toLowerCase()}"></i>` : '' ); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/recursive.js b/server/sonar-web/src/main/js/helpers/handlebars/recursive.js index 1064215671c..415e9cebcd0 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/recursive.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/recursive.js @@ -19,7 +19,7 @@ */ let audaciousFn; -module.exports = function (children, options) { +module.exports = function(children, options) { let out = ''; if (options.fn !== undefined) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/repeat.js b/server/sonar-web/src/main/js/helpers/handlebars/repeat.js index 18cb23cac20..a42b736b326 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/repeat.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/repeat.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (number, options) { +module.exports = function(number, options) { let ret = ''; for (let i = 0; i < number; i++) { ret += options.fn(this); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/rulePermalink.js b/server/sonar-web/src/main/js/helpers/handlebars/rulePermalink.js index af903f2bdb0..e338339a804 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/rulePermalink.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/rulePermalink.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (ruleKey) { +module.exports = function(ruleKey) { return window.baseUrl + '/coding_rules#rule_key=' + encodeURIComponent(ruleKey); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js b/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js index e5747acc20f..e57fccf19be 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js @@ -20,7 +20,7 @@ import Handlebars from 'handlebars/runtime'; import { translate, translateWithParameters } from '../../helpers/l10n'; -module.exports = function (severity) { +module.exports = function(severity) { const label = `<i class="icon-severity-${severity.toLowerCase()}"></i> ${translate('severity', severity)}`; const message = translateWithParameters('quality_profiles.severity_set_to_x', label); return new Handlebars.default.SafeString(message); diff --git a/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js b/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js index 29ed26a53f7..823d68becfa 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js @@ -20,8 +20,8 @@ import Handlebars from 'handlebars/runtime'; import { translate } from '../../helpers/l10n'; -module.exports = function (severity) { +module.exports = function(severity) { return new Handlebars.default.SafeString( - `<i class="icon-severity-${severity.toLowerCase()}"></i> ${translate('severity', severity)}` + `<i class="icon-severity-${severity.toLowerCase()}"></i> ${translate('severity', severity)}` ); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/severityIcon.js b/server/sonar-web/src/main/js/helpers/handlebars/severityIcon.js index 07c765b6fd3..3304bbbc995 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/severityIcon.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/severityIcon.js @@ -19,8 +19,8 @@ */ import Handlebars from 'handlebars/runtime'; -module.exports = function (severity) { +module.exports = function(severity) { return new Handlebars.default.SafeString( - `<i class="icon-severity-${severity.toLowerCase()}"></i>` + `<i class="icon-severity-${severity.toLowerCase()}"></i>` ); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/show.js b/server/sonar-web/src/main/js/helpers/handlebars/show.js index 98295ceecab..886eb58bab1 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/show.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/show.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { let ret = null; args.forEach(arg => { if (typeof arg === 'string' && ret == null) { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js b/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js index 3a083162b08..69abb0af95b 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js @@ -20,7 +20,7 @@ import Handlebars from 'handlebars/runtime'; import { translate } from '../../helpers/l10n'; -module.exports = function (status, resolution) { +module.exports = function(status, resolution) { let s = `<i class="icon-status-${status.toLowerCase()}"></i> ${translate('issue.status', status)}`; if (resolution != null) { s = s + ' (' + translate('issue.resolution', resolution) + ')'; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/statusIcon.js b/server/sonar-web/src/main/js/helpers/handlebars/statusIcon.js index ef2f35b0672..4d90492d251 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/statusIcon.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/statusIcon.js @@ -19,8 +19,6 @@ */ import Handlebars from 'handlebars/runtime'; -module.exports = function (status) { - return new Handlebars.default.SafeString( - `<i class="icon-status-${status.toLowerCase()}"></i>` - ); +module.exports = function(status) { + return new Handlebars.default.SafeString(`<i class="icon-status-${status.toLowerCase()}"></i>`); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/sum.js b/server/sonar-web/src/main/js/helpers/handlebars/sum.js index b64a222cc70..5136e03dd13 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/sum.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/sum.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (...args) { +module.exports = function(...args) { const list = args.slice(0, -1); return list.reduce((p, c) => p + +c, 0); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/t.js b/server/sonar-web/src/main/js/helpers/handlebars/t.js index 2392dafc046..d55d8176234 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/t.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/t.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function () { +module.exports = function() { const args = Array.prototype.slice.call(arguments, 0, -1); return window.t.apply(this, args); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/testStatusIcon.js b/server/sonar-web/src/main/js/helpers/handlebars/testStatusIcon.js index 6fb6b6ab9ea..58e82193a42 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/testStatusIcon.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/testStatusIcon.js @@ -19,8 +19,8 @@ */ import Handlebars from 'handlebars/runtime'; -module.exports = function (status) { +module.exports = function(status) { return new Handlebars.default.SafeString( - `<i class="icon-test-status-${status.toLowerCase()}"></i>` + `<i class="icon-test-status-${status.toLowerCase()}"></i>` ); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/testStatusIconClass.js b/server/sonar-web/src/main/js/helpers/handlebars/testStatusIconClass.js index 88f2f2b0a86..e5718e2c22a 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/testStatusIconClass.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/testStatusIconClass.js @@ -19,7 +19,6 @@ */ import Handlebars from 'handlebars/runtime'; -module.exports = function (status) { - return new Handlebars.default.SafeString(`icon-test-status-${status.toLowerCase()}` - ); +module.exports = function(status) { + return new Handlebars.default.SafeString(`icon-test-status-${status.toLowerCase()}`); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/tp.js b/server/sonar-web/src/main/js/helpers/handlebars/tp.js index f54ed3752ad..f3018e23830 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/tp.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/tp.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function () { +module.exports = function() { const args = Array.prototype.slice.call(arguments, 0, -1); return window.tp.apply(this, args); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/unlessLength.js b/server/sonar-web/src/main/js/helpers/handlebars/unlessLength.js index fc0106e2e8c..95c78a4579b 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/unlessLength.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/unlessLength.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (array, len, options) { +module.exports = function(array, len, options) { const cond = Array.isArray(array) && array.length === +len; return cond ? options.inverse(this) : options.fn(this); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/withFirst.js b/server/sonar-web/src/main/js/helpers/handlebars/withFirst.js index 53e64522098..eb3f52d7e9d 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/withFirst.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/withFirst.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (list, options) { +module.exports = function(list, options) { if (list && list.length > 0) { return options.fn(list[0]); } else { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/withLast.js b/server/sonar-web/src/main/js/helpers/handlebars/withLast.js index df9be847002..bf92fbb7a00 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/withLast.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/withLast.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (list, options) { +module.exports = function(list, options) { if (list && list.length > 0) { return options.fn(list[list.length - 1]); } else { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/withSign.js b/server/sonar-web/src/main/js/helpers/handlebars/withSign.js index cbf9cf8cabb..14511125837 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/withSign.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/withSign.js @@ -17,6 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (number) { +module.exports = function(number) { return number >= 0 ? '+' + number : '' + number; }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/withoutFirst.js b/server/sonar-web/src/main/js/helpers/handlebars/withoutFirst.js index e7d63350446..24e0af2c5cb 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/withoutFirst.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/withoutFirst.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = function (list, options) { +module.exports = function(list, options) { if (list && list.length > 1) { return list.slice(1).reduce((prev, current) => prev + options.fn(current), ''); } else { diff --git a/server/sonar-web/src/main/js/helpers/issues.js b/server/sonar-web/src/main/js/helpers/issues.js index 6410fe3e25c..906ee766099 100644 --- a/server/sonar-web/src/main/js/helpers/issues.js +++ b/server/sonar-web/src/main/js/helpers/issues.js @@ -56,9 +56,8 @@ type RawIssue = { textRange?: TextRange }; -export const sortBySeverity = (issues: Array<*>) => ( - sortBy(issues, issue => SEVERITIES.indexOf(issue.severity)) -); +export const sortBySeverity = (issues: Array<*>) => + sortBy(issues, issue => SEVERITIES.indexOf(issue.severity)); const injectRelational = ( issue: RawIssue | Comment, @@ -98,14 +97,16 @@ const prepareClosed = (issue: RawIssue) => { }; const ensureTextRange = (issue: RawIssue) => { - return issue.line && !issue.textRange ? { - textRange: { - startLine: issue.line, - endLine: issue.line, - startOffset: 0, - endOffset: 999999 - } - } : {}; + return issue.line && !issue.textRange + ? { + textRange: { + startLine: issue.line, + endLine: issue.line, + startOffset: 0, + endOffset: 999999 + } + } + : {}; }; export const parseIssueFromResponse = ( diff --git a/server/sonar-web/src/main/js/helpers/l10n.js b/server/sonar-web/src/main/js/helpers/l10n.js index a9360ae5e50..08832e67dd7 100644 --- a/server/sonar-web/src/main/js/helpers/l10n.js +++ b/server/sonar-web/src/main/js/helpers/l10n.js @@ -23,56 +23,56 @@ import { request } from './request'; let messages = {}; -export function translate (...keys: string[]) { +export function translate(...keys: string[]) { const messageKey = keys.join('.'); return messages[messageKey] || messageKey; } -export function translateWithParameters (messageKey: string, ...parameters: Array<string | number>) { +export function translateWithParameters(messageKey: string, ...parameters: Array<string | number>) { const message = messages[messageKey]; if (message) { return parameters - .map(parameter => String(parameter)) - .reduce((acc, parameter, index) => acc.replace(`{${index}}`, parameter), message); + .map(parameter => String(parameter)) + .reduce((acc, parameter, index) => acc.replace(`{${index}}`, parameter), message); } else { return `${messageKey}.${parameters.join('.')}`; } } -export function hasMessage (...keys: string[]) { +export function hasMessage(...keys: string[]) { const messageKey = keys.join('.'); return messages[messageKey] != null; } -function getCurrentLocale () { +function getCurrentLocale() { return window.navigator.languages ? window.navigator.languages[0] : window.navigator.language; } -function makeRequest (params) { +function makeRequest(params) { const url = '/api/l10n/index'; - return request(url) - .setData(params) - .submit() - .then(response => { - switch (response.status) { - case 200: - return response.json(); - case 304: - return JSON.parse(localStorage.getItem('l10n.bundle') || '{}'); - case 401: - window.location = window.baseUrl + '/sessions/new?return_to=' + - encodeURIComponent(window.location.pathname + window.location.search + window.location.hash); - // return unresolved promise to stop the promise chain - // anyway the page will be reloaded - return new Promise(() => {}); - default: - throw new Error('Unexpected status code: ' + response.status); - } - }); + return request(url).setData(params).submit().then(response => { + switch (response.status) { + case 200: + return response.json(); + case 304: + return JSON.parse(localStorage.getItem('l10n.bundle') || '{}'); + case 401: + window.location = window.baseUrl + + '/sessions/new?return_to=' + + encodeURIComponent( + window.location.pathname + window.location.search + window.location.hash + ); + // return unresolved promise to stop the promise chain + // anyway the page will be reloaded + return new Promise(() => {}); + default: + throw new Error('Unexpected status code: ' + response.status); + } + }); } -function checkCachedBundle () { +function checkCachedBundle() { const cached = localStorage.getItem('l10n.bundle'); if (!cached) { @@ -87,7 +87,7 @@ function checkCachedBundle () { } } -export function requestMessages () { +export function requestMessages() { const currentLocale = getCurrentLocale(); const cachedLocale = localStorage.getItem('l10n.locale'); @@ -118,29 +118,29 @@ export function requestMessages () { }); } -export function resetBundle (bundle: Object) { +export function resetBundle(bundle: Object) { messages = bundle; } -export function installGlobal () { +export function installGlobal() { window.t = translate; window.tp = translateWithParameters; window.requestMessages = requestMessages; } -export function getLocalizedDashboardName (baseName: string) { +export function getLocalizedDashboardName(baseName: string) { const l10nKey = `dashboard.${baseName}.name`; const l10nLabel = translate(l10nKey); return l10nLabel !== l10nKey ? l10nLabel : baseName; } -export function getLocalizedMetricName (metric: { key: string, name: string }) { +export function getLocalizedMetricName(metric: { key: string, name: string }) { const bundleKey = `metric.${metric.key}.name`; const fromBundle = translate(bundleKey); return fromBundle !== bundleKey ? fromBundle : metric.name; } -export function getLocalizedMetricDomain (domainName: string) { +export function getLocalizedMetricDomain(domainName: string) { const bundleKey = `metric_domain.${domainName}`; const fromBundle = translate(bundleKey); return fromBundle !== bundleKey ? fromBundle : domainName; diff --git a/server/sonar-web/src/main/js/helpers/latinize.js b/server/sonar-web/src/main/js/helpers/latinize.js index a727244ffa7..05c2d242541 100644 --- a/server/sonar-web/src/main/js/helpers/latinize.js +++ b/server/sonar-web/src/main/js/helpers/latinize.js @@ -25,348 +25,348 @@ /* jscs:disable maximumLineLength */ const defaultDiacriticsRemovalap = [ { - 'base': 'A', - 'letters': '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F' + base: 'A', + letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F' }, { - 'base': 'AA', - 'letters': '\uA732' + base: 'AA', + letters: '\uA732' }, { - 'base': 'AE', - 'letters': '\u00C6\u01FC\u01E2' + base: 'AE', + letters: '\u00C6\u01FC\u01E2' }, { - 'base': 'AO', - 'letters': '\uA734' + base: 'AO', + letters: '\uA734' }, { - 'base': 'AU', - 'letters': '\uA736' + base: 'AU', + letters: '\uA736' }, { - 'base': 'AV', - 'letters': '\uA738\uA73A' + base: 'AV', + letters: '\uA738\uA73A' }, { - 'base': 'AY', - 'letters': '\uA73C' + base: 'AY', + letters: '\uA73C' }, { - 'base': 'B', - 'letters': '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181' + base: 'B', + letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181' }, { - 'base': 'C', - 'letters': '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E' + base: 'C', + letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E' }, { - 'base': 'D', - 'letters': '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779' + base: 'D', + letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779' }, { - 'base': 'DZ', - 'letters': '\u01F1\u01C4' + base: 'DZ', + letters: '\u01F1\u01C4' }, { - 'base': 'Dz', - 'letters': '\u01F2\u01C5' + base: 'Dz', + letters: '\u01F2\u01C5' }, { - 'base': 'E', - 'letters': '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E' + base: 'E', + letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E' }, { - 'base': 'F', - 'letters': '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' + base: 'F', + letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' }, { - 'base': 'G', - 'letters': '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E' + base: 'G', + letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E' }, { - 'base': 'H', - 'letters': '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D' + base: 'H', + letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D' }, { - 'base': 'I', - 'letters': '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197' + base: 'I', + letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197' }, { - 'base': 'J', - 'letters': '\u004A\u24BF\uFF2A\u0134\u0248' + base: 'J', + letters: '\u004A\u24BF\uFF2A\u0134\u0248' }, { - 'base': 'K', - 'letters': '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2' + base: 'K', + letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2' }, { - 'base': 'L', - 'letters': '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780' + base: 'L', + letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780' }, { - 'base': 'LJ', - 'letters': '\u01C7' + base: 'LJ', + letters: '\u01C7' }, { - 'base': 'Lj', - 'letters': '\u01C8' + base: 'Lj', + letters: '\u01C8' }, { - 'base': 'M', - 'letters': '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' + base: 'M', + letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' }, { - 'base': 'N', - 'letters': '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4' + base: 'N', + letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4' }, { - 'base': 'NJ', - 'letters': '\u01CA' + base: 'NJ', + letters: '\u01CA' }, { - 'base': 'Nj', - 'letters': '\u01CB' + base: 'Nj', + letters: '\u01CB' }, { - 'base': 'O', - 'letters': '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C' + base: 'O', + letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C' }, { - 'base': 'OI', - 'letters': '\u01A2' + base: 'OI', + letters: '\u01A2' }, { - 'base': 'OO', - 'letters': '\uA74E' + base: 'OO', + letters: '\uA74E' }, { - 'base': 'OU', - 'letters': '\u0222' + base: 'OU', + letters: '\u0222' }, { - 'base': 'OE', - 'letters': '\u008C\u0152' + base: 'OE', + letters: '\u008C\u0152' }, { - 'base': 'oe', - 'letters': '\u009C\u0153' + base: 'oe', + letters: '\u009C\u0153' }, { - 'base': 'P', - 'letters': '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754' + base: 'P', + letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754' }, { - 'base': 'Q', - 'letters': '\u0051\u24C6\uFF31\uA756\uA758\u024A' + base: 'Q', + letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' }, { - 'base': 'R', - 'letters': '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782' + base: 'R', + letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782' }, { - 'base': 'S', - 'letters': '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784' + base: 'S', + letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784' }, { - 'base': 'T', - 'letters': '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786' + base: 'T', + letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786' }, { - 'base': 'TZ', - 'letters': '\uA728' + base: 'TZ', + letters: '\uA728' }, { - 'base': 'U', - 'letters': '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244' + base: 'U', + letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244' }, { - 'base': 'V', - 'letters': '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' + base: 'V', + letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' }, { - 'base': 'VY', - 'letters': '\uA760' + base: 'VY', + letters: '\uA760' }, { - 'base': 'W', - 'letters': '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72' + base: 'W', + letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72' }, { - 'base': 'X', - 'letters': '\u0058\u24CD\uFF38\u1E8A\u1E8C' + base: 'X', + letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' }, { - 'base': 'Y', - 'letters': '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE' + base: 'Y', + letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE' }, { - 'base': 'Z', - 'letters': '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762' + base: 'Z', + letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762' }, { - 'base': 'a', - 'letters': '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250' + base: 'a', + letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250' }, { - 'base': 'aa', - 'letters': '\uA733' + base: 'aa', + letters: '\uA733' }, { - 'base': 'ae', - 'letters': '\u00E6\u01FD\u01E3' + base: 'ae', + letters: '\u00E6\u01FD\u01E3' }, { - 'base': 'ao', - 'letters': '\uA735' + base: 'ao', + letters: '\uA735' }, { - 'base': 'au', - 'letters': '\uA737' + base: 'au', + letters: '\uA737' }, { - 'base': 'av', - 'letters': '\uA739\uA73B' + base: 'av', + letters: '\uA739\uA73B' }, { - 'base': 'ay', - 'letters': '\uA73D' + base: 'ay', + letters: '\uA73D' }, { - 'base': 'b', - 'letters': '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253' + base: 'b', + letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253' }, { - 'base': 'c', - 'letters': '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184' + base: 'c', + letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184' }, { - 'base': 'd', - 'letters': '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A' + base: 'd', + letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A' }, { - 'base': 'dz', - 'letters': '\u01F3\u01C6' + base: 'dz', + letters: '\u01F3\u01C6' }, { - 'base': 'e', - 'letters': '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD' + base: 'e', + letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD' }, { - 'base': 'f', - 'letters': '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' + base: 'f', + letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' }, { - 'base': 'g', - 'letters': '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F' + base: 'g', + letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F' }, { - 'base': 'h', - 'letters': '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265' + base: 'h', + letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265' }, { - 'base': 'hv', - 'letters': '\u0195' + base: 'hv', + letters: '\u0195' }, { - 'base': 'i', - 'letters': '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131' + base: 'i', + letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131' }, { - 'base': 'j', - 'letters': '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' + base: 'j', + letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' }, { - 'base': 'k', - 'letters': '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3' + base: 'k', + letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3' }, { - 'base': 'l', - 'letters': '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747' + base: 'l', + letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747' }, { - 'base': 'lj', - 'letters': '\u01C9' + base: 'lj', + letters: '\u01C9' }, { - 'base': 'm', - 'letters': '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' + base: 'm', + letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' }, { - 'base': 'n', - 'letters': '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5' + base: 'n', + letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5' }, { - 'base': 'nj', - 'letters': '\u01CC' + base: 'nj', + letters: '\u01CC' }, { - 'base': 'o', - 'letters': '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275' + base: 'o', + letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275' }, { - 'base': 'oi', - 'letters': '\u01A3' + base: 'oi', + letters: '\u01A3' }, { - 'base': 'ou', - 'letters': '\u0223' + base: 'ou', + letters: '\u0223' }, { - 'base': 'oo', - 'letters': '\uA74F' + base: 'oo', + letters: '\uA74F' }, { - 'base': 'p', - 'letters': '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755' + base: 'p', + letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755' }, { - 'base': 'q', - 'letters': '\u0071\u24E0\uFF51\u024B\uA757\uA759' + base: 'q', + letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' }, { - 'base': 'r', - 'letters': '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783' + base: 'r', + letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783' }, { - 'base': 's', - 'letters': '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B' + base: 's', + letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B' }, { - 'base': 't', - 'letters': '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787' + base: 't', + letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787' }, { - 'base': 'tz', - 'letters': '\uA729' + base: 'tz', + letters: '\uA729' }, { - 'base': 'u', - 'letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289' + base: 'u', + letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289' }, { - 'base': 'v', - 'letters': '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' + base: 'v', + letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' }, { - 'base': 'vy', - 'letters': '\uA761' + base: 'vy', + letters: '\uA761' }, { - 'base': 'w', - 'letters': '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73' + base: 'w', + letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73' }, { - 'base': 'x', - 'letters': '\u0078\u24E7\uFF58\u1E8B\u1E8D' + base: 'x', + letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' }, { - 'base': 'y', - 'letters': '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF' + base: 'y', + letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF' }, { - 'base': 'z', - 'letters': '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' + base: 'z', + letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' } ]; @@ -379,7 +379,7 @@ for (let i = 0; i < defaultDiacriticsRemovalap.length; i++) { } // "what?" version ... http://jsperf.com/diacritics/12 -function removeDiacritics (str) { +function removeDiacritics(str) { return str.replace(/[^\u0000-\u007E]/g, a => diacriticsMap[a] || a); } diff --git a/server/sonar-web/src/main/js/helpers/measures.js b/server/sonar-web/src/main/js/helpers/measures.js index 69593cecf53..e665b5a809b 100644 --- a/server/sonar-web/src/main/js/helpers/measures.js +++ b/server/sonar-web/src/main/js/helpers/measures.js @@ -20,7 +20,6 @@ import numeral from 'numeral'; import { translate, translateWithParameters } from './l10n'; - const HOURS_IN_DAY = 8; /** @@ -28,7 +27,7 @@ const HOURS_IN_DAY = 8; * @param {string|number} value * @param {string} type */ -export function formatMeasure (value, type) { +export function formatMeasure(value, type) { const formatter = getFormatter(type); return useFormatter(value, formatter); } @@ -38,7 +37,7 @@ export function formatMeasure (value, type) { * @param {string|number} value * @param {string} type */ -export function formatMeasureVariation (value, type) { +export function formatMeasureVariation(value, type) { const formatter = getVariationFormatter(type); return useFormatter(value, formatter); } @@ -48,7 +47,7 @@ export function formatMeasureVariation (value, type) { * @param {string} metricKey * @returns {string} */ -export function localizeMetric (metricKey) { +export function localizeMetric(metricKey) { return translate('metric', metricKey, 'name'); } @@ -57,7 +56,7 @@ export function localizeMetric (metricKey) { * @param {string} type * @returns {string} */ -export function getShortType (type) { +export function getShortType(type) { if (type === 'INT') { return 'SHORT_INT'; } else if (type === 'WORK_DUR') { @@ -72,7 +71,7 @@ export function getShortType (type) { * @param {Array} metrics * @returns {Array} */ -export function enhanceMeasuresWithMetrics (measures, metrics) { +export function enhanceMeasuresWithMetrics(measures, metrics) { return measures.map(measure => { const metric = metrics.find(metric => metric.key === measure.metric); return { ...measure, metric }; @@ -84,7 +83,7 @@ export function enhanceMeasuresWithMetrics (measures, metrics) { * @param measure * @param periodIndex */ -export function getPeriodValue (measure, periodIndex) { +export function getPeriodValue(measure, periodIndex) { const { periods } = measure; const period = periods.find(period => period.index === periodIndex); return period ? period.value : null; @@ -95,7 +94,7 @@ export function getPeriodValue (measure, periodIndex) { * @param {string} metricKey * @returns {boolean} */ -export function isDiffMetric (metricKey) { +export function isDiffMetric(metricKey) { return metricKey.indexOf('new_') === 0; } @@ -103,37 +102,36 @@ export function isDiffMetric (metricKey) { * Helpers */ -function useFormatter (value, formatter) { - return value != null && value !== '' && formatter != null ? - formatter(value) : null; +function useFormatter(value, formatter) { + return value != null && value !== '' && formatter != null ? formatter(value) : null; } -function getFormatter (type) { +function getFormatter(type) { const FORMATTERS = { - 'INT': intFormatter, - 'SHORT_INT': shortIntFormatter, - 'FLOAT': floatFormatter, - 'PERCENT': percentFormatter, - 'WORK_DUR': durationFormatter, - 'SHORT_WORK_DUR': shortDurationFormatter, - 'RATING': ratingFormatter, - 'LEVEL': levelFormatter, - 'MILLISEC': millisecondsFormatter + INT: intFormatter, + SHORT_INT: shortIntFormatter, + FLOAT: floatFormatter, + PERCENT: percentFormatter, + WORK_DUR: durationFormatter, + SHORT_WORK_DUR: shortDurationFormatter, + RATING: ratingFormatter, + LEVEL: levelFormatter, + MILLISEC: millisecondsFormatter }; return FORMATTERS[type] || noFormatter; } -function getVariationFormatter (type) { +function getVariationFormatter(type) { const FORMATTERS = { - 'INT': intVariationFormatter, - 'SHORT_INT': shortIntVariationFormatter, - 'FLOAT': floatVariationFormatter, - 'PERCENT': percentVariationFormatter, - 'WORK_DUR': durationVariationFormatter, - 'SHORT_WORK_DUR': shortDurationVariationFormatter, - 'RATING': emptyFormatter, - 'LEVEL': emptyFormatter, - 'MILLISEC': millisecondsVariationFormatter + INT: intVariationFormatter, + SHORT_INT: shortIntVariationFormatter, + FLOAT: floatVariationFormatter, + PERCENT: percentVariationFormatter, + WORK_DUR: durationVariationFormatter, + SHORT_WORK_DUR: shortDurationVariationFormatter, + RATING: emptyFormatter, + LEVEL: emptyFormatter, + MILLISEC: millisecondsVariationFormatter }; return FORMATTERS[type] || noFormatter; } @@ -142,23 +140,23 @@ function getVariationFormatter (type) { * Formatters */ -function noFormatter (value) { +function noFormatter(value) { return value; } -function emptyFormatter () { +function emptyFormatter() { return null; } -function intFormatter (value) { +function intFormatter(value) { return numeral(value).format('0,0'); } -function intVariationFormatter (value) { +function intVariationFormatter(value) { return numeral(value).format('+0,0'); } -function shortIntFormatter (value) { +function shortIntFormatter(value) { let format = '0,0'; if (value >= 1000) { format = '0.[0]a'; @@ -169,35 +167,35 @@ function shortIntFormatter (value) { return numeral(value).format(format); } -function shortIntVariationFormatter (value) { +function shortIntVariationFormatter(value) { const formatted = shortIntFormatter(Math.abs(value)); return value < 0 ? `-${formatted}` : `+${formatted}`; } -function floatFormatter (value) { +function floatFormatter(value) { return numeral(value).format('0,0.0[0000]'); } -function floatVariationFormatter (value) { +function floatVariationFormatter(value) { return value === 0 ? '+0.0' : numeral(value).format('+0,0.0[0000]'); } -function percentFormatter (value) { +function percentFormatter(value) { value = parseFloat(value); return value === 100 ? '100%' : numeral(value / 100).format('0,0.0%'); } -function percentVariationFormatter (value) { +function percentVariationFormatter(value) { value = parseFloat(value); return value === 0 ? '+0.0%' : numeral(value / 100).format('+0,0.0%'); } -function ratingFormatter (value) { +function ratingFormatter(value) { value = parseInt(value, 10); return String.fromCharCode(97 + value - 1).toUpperCase(); } -function levelFormatter (value) { +function levelFormatter(value) { const l10nKey = 'metric.level.' + value; const result = translate(l10nKey); @@ -205,7 +203,7 @@ function levelFormatter (value) { return l10nKey !== result ? result : value; } -function millisecondsFormatter (value) { +function millisecondsFormatter(value) { const ONE_SECOND = 1000; const ONE_MINUTE = 60 * ONE_SECOND; if (value >= ONE_MINUTE) { @@ -219,7 +217,7 @@ function millisecondsFormatter (value) { } } -function millisecondsVariationFormatter (value) { +function millisecondsVariationFormatter(value) { const absValue = Math.abs(value); const formattedValue = millisecondsFormatter(absValue); return value < 0 ? `-${formattedValue}` : `+${formattedValue}`; @@ -229,49 +227,53 @@ function millisecondsVariationFormatter (value) { * Debt Formatters */ -function shouldDisplayDays (days) { +function shouldDisplayDays(days) { return days > 0; } -function shouldDisplayDaysInShortFormat (days) { +function shouldDisplayDaysInShortFormat(days) { return days > 0.9; } -function shouldDisplayHours (days, hours) { +function shouldDisplayHours(days, hours) { return hours > 0 && days < 10; } -function shouldDisplayHoursInShortFormat (hours) { +function shouldDisplayHoursInShortFormat(hours) { return hours > 0.9; } -function shouldDisplayMinutes (days, hours, minutes) { +function shouldDisplayMinutes(days, hours, minutes) { return minutes > 0 && hours < 10 && days === 0; } -function addSpaceIfNeeded (value) { +function addSpaceIfNeeded(value) { return value.length > 0 ? value + ' ' : value; } -function formatDuration (isNegative, days, hours, minutes) { +function formatDuration(isNegative, days, hours, minutes) { let formatted = ''; if (shouldDisplayDays(days)) { formatted += translateWithParameters('work_duration.x_days', isNegative ? -1 * days : days); } if (shouldDisplayHours(days, hours)) { formatted = addSpaceIfNeeded(formatted); - formatted += translateWithParameters('work_duration.x_hours', - isNegative && formatted.length === 0 ? -1 * hours : hours); + formatted += translateWithParameters( + 'work_duration.x_hours', + isNegative && formatted.length === 0 ? -1 * hours : hours + ); } if (shouldDisplayMinutes(days, hours, minutes)) { formatted = addSpaceIfNeeded(formatted); - formatted += translateWithParameters('work_duration.x_minutes', - isNegative && formatted.length === 0 ? -1 * minutes : minutes); + formatted += translateWithParameters( + 'work_duration.x_minutes', + isNegative && formatted.length === 0 ? -1 * minutes : minutes + ); } return formatted; } -function formatDurationShort (isNegative, days, hours, minutes) { +function formatDurationShort(isNegative, days, hours, minutes) { if (shouldDisplayDaysInShortFormat(days)) { const roundedDays = Math.round(days); const formattedDays = formatMeasure(isNegative ? -1 * roundedDays : roundedDays, 'SHORT_INT'); @@ -280,7 +282,10 @@ function formatDurationShort (isNegative, days, hours, minutes) { if (shouldDisplayHoursInShortFormat(hours)) { const roundedHours = Math.round(hours); - const formattedHours = formatMeasure(isNegative ? -1 * roundedHours : roundedHours, 'SHORT_INT'); + const formattedHours = formatMeasure( + isNegative ? -1 * roundedHours : roundedHours, + 'SHORT_INT' + ); return translateWithParameters('work_duration.x_hours', formattedHours); } @@ -288,7 +293,7 @@ function formatDurationShort (isNegative, days, hours, minutes) { return translateWithParameters('work_duration.x_minutes', formattedMinutes); } -function durationFormatter (value) { +function durationFormatter(value) { if (value === 0 || value === '0') { return '0'; } @@ -302,7 +307,7 @@ function durationFormatter (value) { return formatDuration(isNegative, days, hours, remainingValue); } -function shortDurationFormatter (value) { +function shortDurationFormatter(value) { value = parseInt(value, 10); if (value === 0 || value === '0') { return '0'; @@ -317,7 +322,7 @@ function shortDurationFormatter (value) { return formatDurationShort(isNegative, days, hours, remainingValue); } -function durationVariationFormatter (value) { +function durationVariationFormatter(value) { if (value === 0 || value === '0') { return '+0'; } @@ -325,7 +330,7 @@ function durationVariationFormatter (value) { return formatted[0] !== '-' ? '+' + formatted : formatted; } -function shortDurationVariationFormatter (value) { +function shortDurationVariationFormatter(value) { if (value === 0 || value === '0') { return '+0'; } @@ -333,7 +338,7 @@ function shortDurationVariationFormatter (value) { return formatted[0] !== '-' ? '+' + formatted : formatted; } -function getRatingGrid () { +function getRatingGrid() { // workaround cyclic dependencies const getStore = require('../app/utils/getStore').default; const { getSettingValue } = require('../store/rootReducer'); @@ -344,15 +349,13 @@ function getRatingGrid () { } let maintainabilityRatingGrid; -function getMaintainabilityRatingGrid () { +function getMaintainabilityRatingGrid() { if (maintainabilityRatingGrid) { return maintainabilityRatingGrid; } const str = getRatingGrid(); - const numbers = str.split(',') - .map(s => parseFloat(s)) - .filter(n => !isNaN(n)); + const numbers = str.split(',').map(s => parseFloat(s)).filter(n => !isNaN(n)); if (numbers.length === 4) { maintainabilityRatingGrid = numbers; @@ -363,10 +366,9 @@ function getMaintainabilityRatingGrid () { return maintainabilityRatingGrid; } -function getMaintainabilityRatingTooltip (rating) { +function getMaintainabilityRatingTooltip(rating) { const maintainabilityGrid = getMaintainabilityRatingGrid(); - const maintainabilityRatingThreshold = - maintainabilityGrid[Math.floor(rating) - 2]; + const maintainabilityRatingThreshold = maintainabilityGrid[Math.floor(rating) - 2]; if (rating < 2) { return translateWithParameters( @@ -384,12 +386,12 @@ function getMaintainabilityRatingTooltip (rating) { ); } -export function getRatingTooltip (metricKey, value) { +export function getRatingTooltip(metricKey, value) { const ratingLetter = formatMeasure(value, 'RATING'); const finalMetricKey = metricKey.startsWith('new_') ? metricKey.substr(4) : metricKey; - return (finalMetricKey === 'sqale_rating' || finalMetricKey === 'maintainability_rating') ? - getMaintainabilityRatingTooltip(value) : - translate('metric', finalMetricKey, 'tooltip', ratingLetter); + return finalMetricKey === 'sqale_rating' || finalMetricKey === 'maintainability_rating' + ? getMaintainabilityRatingTooltip(value) + : translate('metric', finalMetricKey, 'tooltip', ratingLetter); } diff --git a/server/sonar-web/src/main/js/helpers/path.js b/server/sonar-web/src/main/js/helpers/path.js index 885acb5af11..63153bf6dc8 100644 --- a/server/sonar-web/src/main/js/helpers/path.js +++ b/server/sonar-web/src/main/js/helpers/path.js @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -export function collapsePath (path, limit = 30) { +export function collapsePath(path, limit = 30) { if (typeof path !== 'string') { return ''; } @@ -50,7 +50,7 @@ export function collapsePath (path, limit = 30) { * @param {string} path * @returns {string|null} */ -export function collapsedDirFromPath (path) { +export function collapsedDirFromPath(path) { const limit = 30; if (typeof path === 'string') { const tokens = path.split('/').slice(0, -1); @@ -82,7 +82,7 @@ export function collapsedDirFromPath (path) { * @param {string} path * @returns {string|null} */ -export function fileFromPath (path) { +export function fileFromPath(path) { if (typeof path === 'string') { const tokens = path.split('/'); return tokens[tokens.length - 1]; @@ -91,7 +91,7 @@ export function fileFromPath (path) { } } -export function splitPath (path) { +export function splitPath(path) { if (typeof path === 'string') { const tokens = path.split('/'); return { diff --git a/server/sonar-web/src/main/js/helpers/periods.js b/server/sonar-web/src/main/js/helpers/periods.js index 59fb828c48f..0677d81c13c 100644 --- a/server/sonar-web/src/main/js/helpers/periods.js +++ b/server/sonar-web/src/main/js/helpers/periods.js @@ -20,7 +20,7 @@ import moment from 'moment'; import { translate, translateWithParameters } from './l10n'; -export function getPeriod (periods, index) { +export function getPeriod(periods, index) { if (!Array.isArray(periods)) { return null; } @@ -28,11 +28,11 @@ export function getPeriod (periods, index) { return periods.find(period => period.index === index); } -export function getLeakPeriod (periods) { +export function getLeakPeriod(periods) { return getPeriod(periods, 1); } -export function getPeriodLabel (period) { +export function getPeriodLabel(period) { if (!period) { return null; } @@ -46,7 +46,7 @@ export function getPeriodLabel (period) { return translateWithParameters(`overview.period.${period.mode}`, parameter); } -export function getPeriodDate (period) { +export function getPeriodDate(period) { if (!period) { return null; } @@ -54,6 +54,6 @@ export function getPeriodDate (period) { return moment(period.date).toDate(); } -export function getLeakPeriodLabel (periods) { +export function getLeakPeriodLabel(periods) { return getPeriodLabel(getLeakPeriod(periods)); } diff --git a/server/sonar-web/src/main/js/helpers/ratings.js b/server/sonar-web/src/main/js/helpers/ratings.js index 9cdd220c127..2bcce15b3df 100644 --- a/server/sonar-web/src/main/js/helpers/ratings.js +++ b/server/sonar-web/src/main/js/helpers/ratings.js @@ -29,33 +29,26 @@ export const getCoverageRatingLabel = rating => { const mapping = ['≥ 80%', '< 80%', '< 70%', '< 50%', '< 30%']; return mapping[rating - 1]; }; - export const getCoverageRatingAverageValue = rating => { checkNumberRating(rating); const mapping = [90, 75, 60, 40, 15]; return mapping[rating - 1]; }; - export const getDuplicationsRatingLabel = rating => { checkNumberRating(rating); - const mapping = ['< 3%', '≥ 3%', '> 5%', '> 10%', '> 20%']; return mapping[rating - 1]; }; - export const getDuplicationsRatingAverageValue = rating => { checkNumberRating(rating); const mapping = [1.5, 4, 7.5, 15, 30]; return mapping[rating - 1]; }; - export const getSizeRatingLabel = rating => { checkNumberRating(rating); - const mapping = ['< 1k', '≥ 1k', '> 10k', '> 100k', '> 500k']; return mapping[rating - 1]; }; - export const getSizeRatingAverageValue = rating => { checkNumberRating(rating); const mapping = [500, 5000, 50000, 250000, 750000]; diff --git a/server/sonar-web/src/main/js/helpers/request.js b/server/sonar-web/src/main/js/helpers/request.js index cbd5a4e7c01..1c0e7777748 100644 --- a/server/sonar-web/src/main/js/helpers/request.js +++ b/server/sonar-web/src/main/js/helpers/request.js @@ -26,11 +26,11 @@ type Response = { status: number }; -export function getCSRFTokenName (): string { +export function getCSRFTokenName(): string { return 'X-XSRF-TOKEN'; } -export function getCSRFTokenValue (): string { +export function getCSRFTokenValue(): string { const cookieName = 'XSRF-TOKEN'; const cookieValue = getCookie(cookieName); if (!cookieValue) { @@ -43,7 +43,7 @@ export function getCSRFTokenValue (): string { * Return an object containing a special http request header used to prevent CSRF attacks. * @returns {Object} */ -export function getCSRFToken (): Object { +export function getCSRFToken(): Object { // Fetch API in Edge doesn't work with empty header, // so we ensure non-empty value const value = getCSRFTokenValue(); @@ -67,7 +67,7 @@ const DEFAULT_OPTIONS: { const DEFAULT_HEADERS: { 'Accept': string } = { - 'Accept': 'application/json' + Accept: 'application/json' }; /** @@ -81,13 +81,13 @@ class Request { headers: Object; data: ?Object; - constructor (url: string): void { + constructor(url: string): void { this.url = url; this.options = {}; this.headers = {}; } - submit () { + submit() { let url: string = this.url; const options = { ...DEFAULT_OPTIONS, ...this.options }; @@ -115,17 +115,17 @@ class Request { return window.fetch(window.baseUrl + url, options); } - setMethod (method: string): Request { + setMethod(method: string): Request { this.options.method = method; return this; } - setData (data?: Object): Request { + setData(data?: Object): Request { this.data = data; return this; } - setHeader (name: string, value: string): Request { + setHeader(name: string, value: string): Request { this.headers[name] = value; return this; } @@ -136,7 +136,7 @@ class Request { * @param {string} url * @returns {Request} */ -export function request (url: string): Request { +export function request(url: string): Request { return new Request(url); } @@ -145,7 +145,7 @@ export function request (url: string): Request { * @param response * @returns {*} */ -export function checkStatus (response: Response): Promise<Object> { +export function checkStatus(response: Response): Promise<Object> { return new Promise((resolve, reject) => { if (response.status === 401) { // workaround cyclic dependencies @@ -165,7 +165,7 @@ export function checkStatus (response: Response): Promise<Object> { * @param response * @returns {object} */ -export function parseJSON (response: Response): Promise<Object> { +export function parseJSON(response: Response): Promise<Object> { return response.json(); } @@ -174,12 +174,8 @@ export function parseJSON (response: Response): Promise<Object> { * @param url * @param data */ -export function getJSON (url: string, data?: Object): Promise<Object> { - return request(url) - .setData(data) - .submit() - .then(checkStatus) - .then(parseJSON); +export function getJSON(url: string, data?: Object): Promise<Object> { + return request(url).setData(data).submit().then(checkStatus).then(parseJSON); } /** @@ -187,13 +183,8 @@ export function getJSON (url: string, data?: Object): Promise<Object> { * @param url * @param data */ -export function postJSON (url: string, data?: Object): Promise<Object> { - return request(url) - .setMethod('POST') - .setData(data) - .submit() - .then(checkStatus) - .then(parseJSON); +export function postJSON(url: string, data?: Object): Promise<Object> { + return request(url).setMethod('POST').setData(data).submit().then(checkStatus).then(parseJSON); } /** @@ -201,12 +192,8 @@ export function postJSON (url: string, data?: Object): Promise<Object> { * @param url * @param data */ -export function post (url: string, data?: Object): Promise<Object> { - return request(url) - .setMethod('POST') - .setData(data) - .submit() - .then(checkStatus); +export function post(url: string, data?: Object): Promise<Object> { + return request(url).setMethod('POST').setData(data).submit().then(checkStatus); } /** @@ -214,12 +201,8 @@ export function post (url: string, data?: Object): Promise<Object> { * @param url * @param data */ -export function requestDelete (url: string, data?: Object): Promise<Object> { - return request(url) - .setMethod('DELETE') - .setData(data) - .submit() - .then(checkStatus); +export function requestDelete(url: string, data?: Object): Promise<Object> { + return request(url).setMethod('DELETE').setData(data).submit().then(checkStatus); } /** @@ -227,6 +210,6 @@ export function requestDelete (url: string, data?: Object): Promise<Object> { * @param response * @returns {Promise} */ -export function delay (response: *): Promise<*> { +export function delay(response: *): Promise<*> { return new Promise(resolve => setTimeout(() => resolve(response), 1200)); } diff --git a/server/sonar-web/src/main/js/helpers/scrolling.js b/server/sonar-web/src/main/js/helpers/scrolling.js index e456eb3b340..fb747932015 100644 --- a/server/sonar-web/src/main/js/helpers/scrolling.js +++ b/server/sonar-web/src/main/js/helpers/scrolling.js @@ -42,21 +42,24 @@ let smoothScrollTop = (y: number, parent) => { const step = Math.ceil(Math.abs(y - scrollTop) / SCROLLING_STEPS); let stepsDone = 0; - const interval = setInterval(() => { - const scrollTop = getScrollPosition(parent); - if (scrollTop === y || SCROLLING_STEPS === stepsDone) { - clearInterval(interval); - } else { - let goal; - if (scrollingDown) { - goal = Math.min(y, scrollTop + step); + const interval = setInterval( + () => { + const scrollTop = getScrollPosition(parent); + if (scrollTop === y || SCROLLING_STEPS === stepsDone) { + clearInterval(interval); } else { - goal = Math.max(y, scrollTop - step); + let goal; + if (scrollingDown) { + goal = Math.min(y, scrollTop + step); + } else { + goal = Math.max(y, scrollTop - step); + } + stepsDone++; + scrollElement(parent, goal); } - stepsDone++; - scrollElement(parent, goal); - } - }, SCROLLING_INTERVAL); + }, + SCROLLING_INTERVAL + ); }; smoothScrollTop = debounce(smoothScrollTop, SCROLLING_DURATION, { leading: true }); @@ -69,7 +72,9 @@ export const scrollToElement = ( ) => { const { top, bottom } = element.getBoundingClientRect(); const scrollTop = getScrollPosition(parent); - const height: number = parent === window ? window.innerHeight : parent.getBoundingClientRect().height; + const height: number = parent === window + ? window.innerHeight + : parent.getBoundingClientRect().height; const parentTop = parent === window ? 0 : parent.getBoundingClientRect().top; diff --git a/server/sonar-web/src/main/js/helpers/testUtils.js b/server/sonar-web/src/main/js/helpers/testUtils.js index e0103b35745..6b6da781fb9 100644 --- a/server/sonar-web/src/main/js/helpers/testUtils.js +++ b/server/sonar-web/src/main/js/helpers/testUtils.js @@ -19,15 +19,15 @@ */ export const click = element => { return element.simulate('click', { - target: { blur () {} }, - currentTarget: { blur () {} }, - preventDefault () {} + target: { blur() {} }, + currentTarget: { blur() {} }, + preventDefault() {} }); }; export const submit = element => { return element.simulate('submit', { - preventDefault () {} + preventDefault() {} }); }; diff --git a/server/sonar-web/src/main/js/helpers/urls.js b/server/sonar-web/src/main/js/helpers/urls.js index 52b155d1d47..571d7a6069e 100644 --- a/server/sonar-web/src/main/js/helpers/urls.js +++ b/server/sonar-web/src/main/js/helpers/urls.js @@ -22,11 +22,11 @@ * @param {string} componentKey * @returns {string} */ -export function getComponentUrl (componentKey) { +export function getComponentUrl(componentKey) { return window.baseUrl + '/dashboard?id=' + encodeURIComponent(componentKey); } -export function getProjectUrl (key) { +export function getProjectUrl(key) { return { pathname: '/dashboard', query: { id: key } @@ -38,10 +38,10 @@ export function getProjectUrl (key) { * @param {object} query * @returns {string} */ -export function getIssuesUrl (query) { - const serializedQuery = Object.keys(query).map(criterion => ( - `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}` - )).join('|'); +export function getIssuesUrl(query) { + const serializedQuery = Object.keys(query) + .map(criterion => `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}`) + .join('|'); // return a string (not { pathname }) to help react-router's Link handle this properly return '/issues#' + serializedQuery; @@ -53,10 +53,10 @@ export function getIssuesUrl (query) { * @param {object} query * @returns {string} */ -export function getComponentIssuesUrl (componentKey, query) { - const serializedQuery = Object.keys(query).map(criterion => ( - `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}` - )).join('|'); +export function getComponentIssuesUrl(componentKey, query) { + const serializedQuery = Object.keys(query) + .map(criterion => `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}`) + .join('|'); // return a string (not { pathname }) to help react-router's Link handle this properly return '/component_issues?id=' + encodeURIComponent(componentKey) + '#' + serializedQuery; @@ -68,7 +68,7 @@ export function getComponentIssuesUrl (componentKey, query) { * @param {string} metric * @returns {Object} */ -export function getComponentDrilldownUrl (componentKey, metric) { +export function getComponentDrilldownUrl(componentKey, metric) { return { pathname: `/component_measures/metric/${metric}`, query: { id: componentKey } @@ -80,7 +80,7 @@ export function getComponentDrilldownUrl (componentKey, metric) { * @param {string} componentKey * @returns {Object} */ -export function getComponentPermissionsUrl (componentKey) { +export function getComponentPermissionsUrl(componentKey) { return { pathname: '/project_roles', query: { id: componentKey } @@ -92,7 +92,7 @@ export function getComponentPermissionsUrl (componentKey) { * @param {string} key * @returns {Object} */ -export function getQualityProfileUrl (key) { +export function getQualityProfileUrl(key) { return { pathname: '/profiles/show', query: { key } @@ -104,7 +104,7 @@ export function getQualityProfileUrl (key) { * @param {string} key * @returns {Object} */ -export function getQualityGateUrl (key) { +export function getQualityGateUrl(key) { return { pathname: '/quality_gates/show/' + encodeURIComponent(key) }; @@ -115,12 +115,11 @@ export function getQualityGateUrl (key) { * @param {object} query * @returns {string} */ -export function getRulesUrl (query) { +export function getRulesUrl(query) { if (query) { - const serializedQuery = Object.keys(query).map(criterion => ( - `${encodeURIComponent(criterion)}=${encodeURIComponent( - query[criterion])}` - )).join('|'); + const serializedQuery = Object.keys(query) + .map(criterion => `${encodeURIComponent(criterion)}=${encodeURIComponent(query[criterion])}`) + .join('|'); // return a string (not { pathname }) to help react-router's Link handle this properly return '/coding_rules#' + serializedQuery; @@ -134,7 +133,7 @@ export function getRulesUrl (query) { * @param {object} query * @returns {string} */ -export function getDeprecatedActiveRulesUrl (query = {}) { +export function getDeprecatedActiveRulesUrl(query = {}) { const baseQuery = { activation: 'true', statuses: 'DEPRECATED' }; return getRulesUrl({ ...query, ...baseQuery }); } diff --git a/server/sonar-web/src/main/js/helpers/users.js b/server/sonar-web/src/main/js/helpers/users.js index caee94dcabb..cebcbf556b4 100644 --- a/server/sonar-web/src/main/js/helpers/users.js +++ b/server/sonar-web/src/main/js/helpers/users.js @@ -24,6 +24,4 @@ type User = { } }; -export const isUserAdmin = (user: User): boolean => ( - user.permissions.global.includes('admin') -); +export const isUserAdmin = (user: User): boolean => user.permissions.global.includes('admin'); diff --git a/server/sonar-web/src/main/js/store/appState/duck.js b/server/sonar-web/src/main/js/store/appState/duck.js index bb90fcf3bd0..3ddcf2f52cb 100644 --- a/server/sonar-web/src/main/js/store/appState/duck.js +++ b/server/sonar-web/src/main/js/store/appState/duck.js @@ -75,6 +75,4 @@ export default (state: AppState = defaultValue, action: Action) => { return state; }; -export const getRootQualifiers = (state: AppState) => ( - state.qualifiers -); +export const getRootQualifiers = (state: AppState) => state.qualifiers; diff --git a/server/sonar-web/src/main/js/store/components/reducer.js b/server/sonar-web/src/main/js/store/components/reducer.js index 2b15a41d6ac..473c288feb2 100644 --- a/server/sonar-web/src/main/js/store/components/reducer.js +++ b/server/sonar-web/src/main/js/store/components/reducer.js @@ -42,6 +42,4 @@ const keys = (state = [], action = {}) => { export default combineReducers({ byKey, keys }); -export const getComponent = (state, key) => ( - state.byKey[key] -); +export const getComponent = (state, key) => state.byKey[key]; diff --git a/server/sonar-web/src/main/js/store/favorites/duck.js b/server/sonar-web/src/main/js/store/favorites/duck.js index ceeb119abfa..27d3864c86f 100644 --- a/server/sonar-web/src/main/js/store/favorites/duck.js +++ b/server/sonar-web/src/main/js/store/favorites/duck.js @@ -86,6 +86,4 @@ export default (state: State = [], action: Action): State => { return state; }; -export const isFavorite = (state: State, componentKey: string) => ( - state.includes(componentKey) -); +export const isFavorite = (state: State, componentKey: string) => state.includes(componentKey); diff --git a/server/sonar-web/src/main/js/store/globalMessages/duck.js b/server/sonar-web/src/main/js/store/globalMessages/duck.js index c3457a35568..f0cc29ba053 100644 --- a/server/sonar-web/src/main/js/store/globalMessages/duck.js +++ b/server/sonar-web/src/main/js/store/globalMessages/duck.js @@ -57,40 +57,42 @@ export const closeAllGlobalMessages = (id: string) => ({ id }); -const addGlobalMessage = (message: string, level: Level) => (dispatch: Function) => { - const id = uniqueId('global-message-'); - dispatch(addGlobalMessageActionCreator(id, message, level)); - setTimeout(() => dispatch(closeGlobalMessage(id)), 5000); -}; +const addGlobalMessage = (message: string, level: Level) => + (dispatch: Function) => { + const id = uniqueId('global-message-'); + dispatch(addGlobalMessageActionCreator(id, message, level)); + setTimeout(() => dispatch(closeGlobalMessage(id)), 5000); + }; -export const addGlobalErrorMessage = (message: string) => - addGlobalMessage(message, ERROR); +export const addGlobalErrorMessage = (message: string) => addGlobalMessage(message, ERROR); -export const addGlobalSuccessMessage = (message: string) => - addGlobalMessage(message, SUCCESS); +export const addGlobalSuccessMessage = (message: string) => addGlobalMessage(message, SUCCESS); /* Reducer */ const globalMessages = (state: State = [], action: Action = {}) => { switch (action.type) { case ADD_GLOBAL_MESSAGE: - return [{ - id: action.id, - message: action.message, - level: action.level - }]; + return [ + { + id: action.id, + message: action.message, + level: action.level + } + ]; case 'REQUIRE_AUTHORIZATION': // FIXME l10n - return [{ - id: uniqueId('global-message-'), - message: 'You are not authorized to access this page. Please log in with more privileges and try again.', - level: ERROR - }]; + return [ + { + id: uniqueId('global-message-'), + message: 'You are not authorized to access this page. Please log in with more privileges and try again.', + level: ERROR + } + ]; case CLOSE_GLOBAL_MESSAGE: return state.filter(message => message.id !== action.id); - case CLOSE_ALL_GLOBAL_MESSAGES: return []; default: diff --git a/server/sonar-web/src/main/js/store/issues/duck.js b/server/sonar-web/src/main/js/store/issues/duck.js index 1126bcfd57f..7b5cb240404 100644 --- a/server/sonar-web/src/main/js/store/issues/duck.js +++ b/server/sonar-web/src/main/js/store/issues/duck.js @@ -47,6 +47,4 @@ const reducer = (state: State = {}, action: Action) => { export default reducer; -export const getIssueByKey = (state: State, key: string): ?Issue => ( - state[key] -); +export const getIssueByKey = (state: State, key: string): ?Issue => state[key]; diff --git a/server/sonar-web/src/main/js/store/languages/reducer.js b/server/sonar-web/src/main/js/store/languages/reducer.js index 84aafb8632e..4e4dbfef3b8 100644 --- a/server/sonar-web/src/main/js/store/languages/reducer.js +++ b/server/sonar-web/src/main/js/store/languages/reducer.js @@ -30,10 +30,6 @@ const reducer = (state = {}, action = {}) => { export default reducer; -export const getLanguages = state => ( - state -); +export const getLanguages = state => state; -export const getLanguageByKey = (state, key) => ( - state[key] -); +export const getLanguageByKey = (state, key) => state[key]; diff --git a/server/sonar-web/src/main/js/store/measures/reducer.js b/server/sonar-web/src/main/js/store/measures/reducer.js index 754958c4b71..4c89ebab8ea 100644 --- a/server/sonar-web/src/main/js/store/measures/reducer.js +++ b/server/sonar-web/src/main/js/store/measures/reducer.js @@ -17,7 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { RECEIVE_COMPONENT_MEASURE, RECEIVE_COMPONENT_MEASURES, RECEIVE_COMPONENTS_MEASURES } from './actions'; +import { + RECEIVE_COMPONENT_MEASURE, + RECEIVE_COMPONENT_MEASURES, + RECEIVE_COMPONENTS_MEASURES +} from './actions'; const byMetricKey = (state = {}, action = {}) => { if (action.type === RECEIVE_COMPONENT_MEASURE) { @@ -60,6 +64,4 @@ export const getComponentMeasure = (state, componentKey, metricKey) => { return component && component[metricKey]; }; -export const getComponentMeasures = (state, componentKey) => ( - state[componentKey] -); +export const getComponentMeasures = (state, componentKey) => state[componentKey]; diff --git a/server/sonar-web/src/main/js/store/notifications/duck.js b/server/sonar-web/src/main/js/store/notifications/duck.js index 81523b81eef..cd4f7a7ab05 100644 --- a/server/sonar-web/src/main/js/store/notifications/duck.js +++ b/server/sonar-web/src/main/js/store/notifications/duck.js @@ -65,10 +65,10 @@ export const removeNotification = (notification: Notification): RemoveNotificati }); export const receiveNotifications = ( - notifications: NotificationsState, - channels: ChannelsState, - globalTypes: TypesState, - perProjectTypes: TypesState + notifications: NotificationsState, + channels: ChannelsState, + globalTypes: TypesState, + perProjectTypes: TypesState ): ReceiveNotificationsAction => ({ type: 'RECEIVE_NOTIFICATIONS', notifications, @@ -78,14 +78,14 @@ export const receiveNotifications = ( }); const onAddNotification = (state: NotificationsState, notification: Notification) => { - const isNotificationsEqual = (a: Notification, b: Notification) => ( - a.channel === b.channel && a.type === b.type && a.project === b.project - ); + const isNotificationsEqual = (a: Notification, b: Notification) => + a.channel === b.channel && a.type === b.type && a.project === b.project; return uniqWith([...state, notification], isNotificationsEqual); }; const onRemoveNotification = (state: NotificationsState, notification: Notification) => { - return state.filter(n => + return state.filter( + n => n.channel !== notification.channel || n.type !== notification.type || n.project !== notification.project @@ -142,24 +142,21 @@ type State = { export default combineReducers({ notifications, channels, globalTypes, perProjectTypes }); -export const getGlobal = (state: State): NotificationsState => ( - state.notifications.filter(n => !n.project) -); - -export const getProjects = (state: State): Array<string> => ( - uniqBy( - state.notifications.filter(n => n.project).map(n => ({ - key: n.project, - name: n.projectName, - organization: n.organization - })), - project => project.key - ) -); - -export const getForProject = (state: State, project: string): NotificationsState => ( - state.notifications.filter(n => n.project === project) -); +export const getGlobal = (state: State): NotificationsState => + state.notifications.filter(n => !n.project); + +export const getProjects = (state: State): Array<string> => + uniqBy( + state.notifications.filter(n => n.project).map(n => ({ + key: n.project, + name: n.projectName, + organization: n.organization + })), + project => project.key + ); + +export const getForProject = (state: State, project: string): NotificationsState => + state.notifications.filter(n => n.project === project); export const getChannels = (state: State): ChannelsState => state.channels; diff --git a/server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.js b/server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.js index 7e0b5068378..8560acdfc8c 100644 --- a/server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.js +++ b/server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.js @@ -29,19 +29,14 @@ describe('Reducer', () => { const action1 = { type: 'RECEIVE_ORGANIZATIONS', - organizations: [ - { key: 'foo', name: 'Foo' }, - { key: 'bar', name: 'Bar' } - ] + organizations: [{ key: 'foo', name: 'Foo' }, { key: 'bar', name: 'Bar' }] }; const state1 = organizations(state0, action1); expect(state1).toMatchSnapshot(); const action2 = { type: 'RECEIVE_ORGANIZATIONS', - organizations: [ - { key: 'foo', name: 'Qwe' } - ] + organizations: [{ key: 'foo', name: 'Qwe' }] }; const state2 = organizations(state1, action2); expect(state2).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/store/organizations/duck.js b/server/sonar-web/src/main/js/store/organizations/duck.js index f1d4a1b5b7b..f04782a8541 100644 --- a/server/sonar-web/src/main/js/store/organizations/duck.js +++ b/server/sonar-web/src/main/js/store/organizations/duck.js @@ -61,11 +61,11 @@ type DeleteOrganizationAction = { }; type Action = - ReceiveOrganizationsAction | - ReceiveMyOrganizationsAction | - CreateOrganizationAction | - UpdateOrganizationAction | - DeleteOrganizationAction; + | ReceiveOrganizationsAction + | ReceiveMyOrganizationsAction + | CreateOrganizationAction + | UpdateOrganizationAction + | DeleteOrganizationAction; type ByKeyState = { [key: string]: Organization @@ -78,12 +78,16 @@ type State = { my: MyState }; -export const receiveOrganizations = (organizations: Array<Organization>): ReceiveOrganizationsAction => ({ +export const receiveOrganizations = ( + organizations: Array<Organization> +): ReceiveOrganizationsAction => ({ type: 'RECEIVE_ORGANIZATIONS', organizations }); -export const receiveMyOrganizations = (organizations: Array<Organization>): ReceiveMyOrganizationsAction => ({ +export const receiveMyOrganizations = ( + organizations: Array<Organization> +): ReceiveMyOrganizationsAction => ({ type: 'RECEIVE_MY_ORGANIZATIONS', organizations }); @@ -153,14 +157,10 @@ const my = (state: MyState = [], action: Action) => { export default combineReducers({ byKey, my }); -export const getOrganizationByKey = (state: State, key: string): Organization => ( - state.byKey[key] -); +export const getOrganizationByKey = (state: State, key: string): Organization => state.byKey[key]; -export const getMyOrganizations = (state: State): Array<Organization> => ( - state.my.map(key => getOrganizationByKey(state, key)) -); +export const getMyOrganizations = (state: State): Array<Organization> => + state.my.map(key => getOrganizationByKey(state, key)); -export const areThereCustomOrganizations = (state: State): boolean => ( - Object.keys(state.byKey).length > 1 -); +export const areThereCustomOrganizations = (state: State): boolean => + Object.keys(state.byKey).length > 1; diff --git a/server/sonar-web/src/main/js/store/organizations/utils.js b/server/sonar-web/src/main/js/store/organizations/utils.js index 3f076b07a8d..a17f80f47cf 100644 --- a/server/sonar-web/src/main/js/store/organizations/utils.js +++ b/server/sonar-web/src/main/js/store/organizations/utils.js @@ -19,7 +19,10 @@ */ // @flow import getStore from '../../app/utils/getStore'; -import { getOrganizationByKey, areThereCustomOrganizations as customOrganizations } from '../rootReducer'; +import { + getOrganizationByKey, + areThereCustomOrganizations as customOrganizations +} from '../rootReducer'; export const getOrganization = (key: string) => { const store = getStore(); diff --git a/server/sonar-web/src/main/js/store/projectActivity/__tests__/duck-test.js b/server/sonar-web/src/main/js/store/projectActivity/__tests__/duck-test.js index 3c18ac2d954..d1a6ddfd4a9 100644 --- a/server/sonar-web/src/main/js/store/projectActivity/__tests__/duck-test.js +++ b/server/sonar-web/src/main/js/store/projectActivity/__tests__/duck-test.js @@ -84,7 +84,6 @@ describe('actions', () => { }); }); - describe('selectors', () => { it('getAnalyses', () => { const store = configureTestStore(reducer); diff --git a/server/sonar-web/src/main/js/store/projectActivity/analyses.js b/server/sonar-web/src/main/js/store/projectActivity/analyses.js index bca2a39f7f8..90e02537484 100644 --- a/server/sonar-web/src/main/js/store/projectActivity/analyses.js +++ b/server/sonar-web/src/main/js/store/projectActivity/analyses.js @@ -84,6 +84,4 @@ export default (state: State = {}, action: Action): State => { } }; -export const getAnalysis = (state: State, key: string): Analysis => ( - state[key] -); +export const getAnalysis = (state: State, key: string): Analysis => state[key]; diff --git a/server/sonar-web/src/main/js/store/projectActivity/duck.js b/server/sonar-web/src/main/js/store/projectActivity/duck.js index 4c747619527..75e24c7e839 100644 --- a/server/sonar-web/src/main/js/store/projectActivity/duck.js +++ b/server/sonar-web/src/main/js/store/projectActivity/duck.js @@ -79,16 +79,16 @@ export type DeleteAnalysisAction = { }; export type Action = - ReceiveProjectActivityAction | - AddEventAction | - DeleteEventAction | - ChangeEventAction | - DeleteAnalysisAction; + | ReceiveProjectActivityAction + | AddEventAction + | DeleteEventAction + | ChangeEventAction + | DeleteAnalysisAction; export const receiveProjectActivity = ( - project: string, - analyses: Array<Analysis>, - paging: Paging + project: string, + analyses: Array<Analysis>, + paging: Paging ): ReceiveProjectActivityAction => ({ type: 'RECEIVE_PROJECT_ACTIVITY', project, @@ -125,14 +125,12 @@ type State = { analysesByProject: AnalysesByProjectState, events: EventsState, filter: string, - paging: PagingState, + paging: PagingState }; export default combineReducers({ analyses, analysesByProject, events, paging }); -const getEvent = (state: State, key: string): Event => ( - fromEvents.getEvent(state.events, key) -); +const getEvent = (state: State, key: string): Event => fromEvents.getEvent(state.events, key); const getAnalysis = (state: State, key: string) => { const analysis = fromAnalyses.getAnalysis(state.analyses, key); @@ -140,9 +138,7 @@ const getAnalysis = (state: State, key: string) => { return { ...analysis, events }; }; -export const getAnalyses = (state: State, project: string) => ( - state.analysesByProject[project] && state.analysesByProject[project].map(key => getAnalysis(state, key)) -); -export const getPaging = (state: State, project: string) => ( - state.paging[project] -); +export const getAnalyses = (state: State, project: string) => + state.analysesByProject[project] && + state.analysesByProject[project].map(key => getAnalysis(state, key)); +export const getPaging = (state: State, project: string) => state.paging[project]; diff --git a/server/sonar-web/src/main/js/store/projectActivity/events.js b/server/sonar-web/src/main/js/store/projectActivity/events.js index 7533e0db8f7..41446540e8d 100644 --- a/server/sonar-web/src/main/js/store/projectActivity/events.js +++ b/server/sonar-web/src/main/js/store/projectActivity/events.js @@ -32,7 +32,7 @@ export type State = { key: string, name: string, category: string, - description?: string, + description?: string } }; @@ -74,6 +74,4 @@ export default (state: State = {}, action: Action): State => { } }; -export const getEvent = (state: State, key: string) => ( - state[key] -); +export const getEvent = (state: State, key: string) => state[key]; diff --git a/server/sonar-web/src/main/js/store/projectActivity/paging.js b/server/sonar-web/src/main/js/store/projectActivity/paging.js index fb9537c8f77..bf14686fa9c 100644 --- a/server/sonar-web/src/main/js/store/projectActivity/paging.js +++ b/server/sonar-web/src/main/js/store/projectActivity/paging.js @@ -31,4 +31,3 @@ export default (state: State = {}, action: ReceiveProjectActivityAction): State return state; }; - diff --git a/server/sonar-web/src/main/js/store/rootActions.js b/server/sonar-web/src/main/js/store/rootActions.js index d9bd1d97e05..0e95f02d56c 100644 --- a/server/sonar-web/src/main/js/store/rootActions.js +++ b/server/sonar-web/src/main/js/store/rootActions.js @@ -28,62 +28,58 @@ import { parseError } from '../apps/code/utils'; import { setAppState } from './appState/duck'; import { receiveOrganizations } from './organizations/duck'; -export const onFail = dispatch => error => ( - parseError(error).then(message => dispatch(addGlobalErrorMessage(message))) -); +export const onFail = dispatch => + error => parseError(error).then(message => dispatch(addGlobalErrorMessage(message))); -export const fetchAppState = () => dispatch => ( - getGlobalNavigation().then( - appState => dispatch(setAppState(appState)), - onFail(dispatch) - ) -); +export const fetchAppState = () => + dispatch => + getGlobalNavigation().then(appState => dispatch(setAppState(appState)), onFail(dispatch)); -export const fetchLanguages = () => dispatch => { - return getLanguages().then( - languages => dispatch(receiveLanguages(languages)), - onFail(dispatch) - ); -}; +export const fetchLanguages = () => + dispatch => { + return getLanguages().then( + languages => dispatch(receiveLanguages(languages)), + onFail(dispatch) + ); + }; -export const fetchOrganizations = (organizations?: Array<string>) => dispatch => ( +export const fetchOrganizations = (organizations?: Array<string>) => + dispatch => getOrganizations(organizations).then( r => dispatch(receiveOrganizations(r.organizations)), onFail(dispatch) - ) -); + ); const addQualifier = project => ({ ...project, qualifier: project.breadcrumbs[project.breadcrumbs.length - 1].qualifier }); -export const fetchProject = key => dispatch => ( - getComponentNavigation(key).then( - component => { - dispatch(receiveComponents([addQualifier(component)])); - if (component.organization != null) { - dispatch(fetchOrganizations([component.organization])); - } - }) -); +export const fetchProject = key => + dispatch => + getComponentNavigation(key).then(component => { + dispatch(receiveComponents([addQualifier(component)])); + if (component.organization != null) { + dispatch(fetchOrganizations([component.organization])); + } + }); -export const doLogin = (login, password) => dispatch => ( - auth.login(login, password).then( - () => { /* everything is fine */ }, +export const doLogin = (login, password) => dispatch => auth.login(login, password).then( + () => { + /* everything is fine */ + }, () => { dispatch(addGlobalErrorMessage('Authentication failed')); return Promise.reject(); } - ) -); + ); -export const doLogout = () => dispatch => ( - auth.logout().then( - () => { /* everything is fine */ }, +export const doLogout = () => dispatch => auth.logout().then( + () => { + /* everything is fine */ + }, () => { dispatch(addGlobalErrorMessage('Logout failed')); return Promise.reject(); } - ) -); + ); diff --git a/server/sonar-web/src/main/js/store/rootReducer.js b/server/sonar-web/src/main/js/store/rootReducer.js index 41ec81f1bb4..91c0a2a9ba6 100644 --- a/server/sonar-web/src/main/js/store/rootReducer.js +++ b/server/sonar-web/src/main/js/store/rootReducer.js @@ -58,302 +58,199 @@ export default combineReducers({ settingsApp }); -export const getAppState = state => ( - state.appState -); +export const getAppState = state => state.appState; -export const getComponent = (state, key) => ( - fromComponents.getComponent(state.components, key) -); +export const getComponent = (state, key) => fromComponents.getComponent(state.components, key); -export const getGlobalMessages = state => ( - fromGlobalMessages.getGlobalMessages(state.globalMessages) -); +export const getGlobalMessages = state => + fromGlobalMessages.getGlobalMessages(state.globalMessages); -export const getLanguages = state => ( - fromLanguages.getLanguages(state.languages) -); +export const getLanguages = state => fromLanguages.getLanguages(state.languages); -export const getLanguageByKey = (state, key) => ( - fromLanguages.getLanguageByKey(state.languages, key) -); +export const getLanguageByKey = (state, key) => + fromLanguages.getLanguageByKey(state.languages, key); -export const getCurrentUser = state => ( - fromUsers.getCurrentUser(state.users) -); +export const getCurrentUser = state => fromUsers.getCurrentUser(state.users); -export const isFavorite = (state, componentKey) => ( - fromFavorites.isFavorite(state.favorites, componentKey) -); +export const isFavorite = (state, componentKey) => + fromFavorites.isFavorite(state.favorites, componentKey); -export const getIssueByKey = (state, key) => ( - fromIssues.getIssueByKey(state.issues, key) -); +export const getIssueByKey = (state, key) => fromIssues.getIssueByKey(state.issues, key); -export const getComponentMeasure = (state, componentKey, metricKey) => ( - fromMeasures.getComponentMeasure(state.measures, componentKey, metricKey) -); +export const getComponentMeasure = (state, componentKey, metricKey) => + fromMeasures.getComponentMeasure(state.measures, componentKey, metricKey); -export const getComponentMeasures = (state, componentKey) => ( - fromMeasures.getComponentMeasures(state.measures, componentKey) -); +export const getComponentMeasures = (state, componentKey) => + fromMeasures.getComponentMeasures(state.measures, componentKey); -export const getGlobalNotifications = state => ( - fromNotifications.getGlobal(state.notifications) -); +export const getGlobalNotifications = state => fromNotifications.getGlobal(state.notifications); -export const getProjectsWithNotifications = state => ( - fromNotifications.getProjects(state.notifications) -); +export const getProjectsWithNotifications = state => + fromNotifications.getProjects(state.notifications); -export const getProjectNotifications = (state, project) => ( - fromNotifications.getForProject(state.notifications, project) -); +export const getProjectNotifications = (state, project) => + fromNotifications.getForProject(state.notifications, project); -export const getNotificationChannels = state => ( - fromNotifications.getChannels(state.notifications) -); +export const getNotificationChannels = state => fromNotifications.getChannels(state.notifications); -export const getNotificationGlobalTypes = state => ( - fromNotifications.getGlobalTypes(state.notifications) -); +export const getNotificationGlobalTypes = state => + fromNotifications.getGlobalTypes(state.notifications); -export const getNotificationPerProjectTypes = state => ( - fromNotifications.getPerProjectTypes(state.notifications) -); +export const getNotificationPerProjectTypes = state => + fromNotifications.getPerProjectTypes(state.notifications); -export const getOrganizationByKey = (state, key) => ( - fromOrganizations.getOrganizationByKey(state.organizations, key) -); +export const getOrganizationByKey = (state, key) => + fromOrganizations.getOrganizationByKey(state.organizations, key); -export const getMyOrganizations = state => ( - fromOrganizations.getMyOrganizations(state.organizations) -); +export const getMyOrganizations = state => + fromOrganizations.getMyOrganizations(state.organizations); -export const areThereCustomOrganizations = state => ( - getAppState(state).organizationsEnabled -); +export const areThereCustomOrganizations = state => getAppState(state).organizationsEnabled; -export const getProjectActivity = state => ( - state.projectActivity -); +export const getProjectActivity = state => state.projectActivity; -export const getProjects = state => ( - fromProjectsApp.getProjects(state.projectsApp) -); +export const getProjects = state => fromProjectsApp.getProjects(state.projectsApp); -export const getProjectsAppState = state => ( - fromProjectsApp.getState(state.projectsApp) -); +export const getProjectsAppState = state => fromProjectsApp.getState(state.projectsApp); -export const getProjectsAppFacetByProperty = (state, property) => ( - fromProjectsApp.getFacetByProperty(state.projectsApp, property) -); +export const getProjectsAppFacetByProperty = (state, property) => + fromProjectsApp.getFacetByProperty(state.projectsApp, property); -export const getProjectsAppMaxFacetValue = state => ( - fromProjectsApp.getMaxFacetValue(state.projectsApp) -); +export const getProjectsAppMaxFacetValue = state => + fromProjectsApp.getMaxFacetValue(state.projectsApp); -export const getQualityGatesAppState = state => ( - state.qualityGatesApp -); +export const getQualityGatesAppState = state => state.qualityGatesApp; -export const getPermissionsAppUsers = state => ( - fromPermissionsApp.getUsers(state.permissionsApp) -); +export const getPermissionsAppUsers = state => fromPermissionsApp.getUsers(state.permissionsApp); -export const getPermissionsAppGroups = state => ( - fromPermissionsApp.getGroups(state.permissionsApp) -); +export const getPermissionsAppGroups = state => fromPermissionsApp.getGroups(state.permissionsApp); -export const isPermissionsAppLoading = state => ( - fromPermissionsApp.isLoading(state.permissionsApp) -); +export const isPermissionsAppLoading = state => fromPermissionsApp.isLoading(state.permissionsApp); -export const getPermissionsAppQuery = state => ( - fromPermissionsApp.getQuery(state.permissionsApp) -); +export const getPermissionsAppQuery = state => fromPermissionsApp.getQuery(state.permissionsApp); -export const getPermissionsAppFilter = state => ( - fromPermissionsApp.getFilter(state.permissionsApp) -); +export const getPermissionsAppFilter = state => fromPermissionsApp.getFilter(state.permissionsApp); -export const getPermissionsAppSelectedPermission = state => ( - fromPermissionsApp.getSelectedPermission(state.permissionsApp) -); +export const getPermissionsAppSelectedPermission = state => + fromPermissionsApp.getSelectedPermission(state.permissionsApp); -export const getPermissionsAppError = state => ( - fromPermissionsApp.getError(state.permissionsApp) -); +export const getPermissionsAppError = state => fromPermissionsApp.getError(state.permissionsApp); -export const getSettingValue = (state, key) => ( - fromSettingsApp.getValue(state.settingsApp, key) -); +export const getSettingValue = (state, key) => fromSettingsApp.getValue(state.settingsApp, key); -export const getSettingsAppDefinition = (state, key) => ( - fromSettingsApp.getDefinition(state.settingsApp, key) -); +export const getSettingsAppDefinition = (state, key) => + fromSettingsApp.getDefinition(state.settingsApp, key); -export const getSettingsAppAllCategories = state => ( - fromSettingsApp.getAllCategories(state.settingsApp) -); +export const getSettingsAppAllCategories = state => + fromSettingsApp.getAllCategories(state.settingsApp); -export const getSettingsAppDefaultCategory = state => ( - fromSettingsApp.getDefaultCategory(state.settingsApp) -); +export const getSettingsAppDefaultCategory = state => + fromSettingsApp.getDefaultCategory(state.settingsApp); -export const getSettingsAppSettingsForCategory = (state, category) => ( - fromSettingsApp.getSettingsForCategory(state.settingsApp, category) -); +export const getSettingsAppSettingsForCategory = (state, category) => + fromSettingsApp.getSettingsForCategory(state.settingsApp, category); -export const getSettingsAppChangedValue = (state, key) => ( - fromSettingsApp.getChangedValue(state.settingsApp, key) -); +export const getSettingsAppChangedValue = (state, key) => + fromSettingsApp.getChangedValue(state.settingsApp, key); -export const isSettingsAppLoading = (state, key) => ( - fromSettingsApp.isLoading(state.settingsApp, key) -); +export const isSettingsAppLoading = (state, key) => + fromSettingsApp.isLoading(state.settingsApp, key); -export const getSettingsAppLicenseByKey = (state, key) => ( - fromSettingsApp.getLicenseByKey(state.settingsApp, key) -); +export const getSettingsAppLicenseByKey = (state, key) => + fromSettingsApp.getLicenseByKey(state.settingsApp, key); -export const getSettingsAppAllLicenseKeys = state => ( - fromSettingsApp.getAllLicenseKeys(state.settingsApp) -); +export const getSettingsAppAllLicenseKeys = state => + fromSettingsApp.getAllLicenseKeys(state.settingsApp); -export const getSettingsAppValidationMessage = (state, key) => ( - fromSettingsApp.getValidationMessage(state.settingsApp, key) -); +export const getSettingsAppValidationMessage = (state, key) => + fromSettingsApp.getValidationMessage(state.settingsApp, key); -export const getSettingsAppEncryptionState = state => ( - fromSettingsApp.getEncryptionState(state.settingsApp) -); +export const getSettingsAppEncryptionState = state => + fromSettingsApp.getEncryptionState(state.settingsApp); -export const getSettingsAppGlobalMessages = state => ( - fromSettingsApp.getGlobalMessages(state.settingsApp) -); +export const getSettingsAppGlobalMessages = state => + fromSettingsApp.getGlobalMessages(state.settingsApp); -export const getProjectAdminProfileByKey = (state, profileKey) => ( - fromProjectAdminApp.getProfileByKey(state.projectAdminApp, profileKey) -); +export const getProjectAdminProfileByKey = (state, profileKey) => + fromProjectAdminApp.getProfileByKey(state.projectAdminApp, profileKey); -export const getProjectAdminAllProfiles = state => ( - fromProjectAdminApp.getAllProfiles(state.projectAdminApp) -); +export const getProjectAdminAllProfiles = state => + fromProjectAdminApp.getAllProfiles(state.projectAdminApp); -export const getProjectAdminProjectProfiles = (state, projectKey) => ( - fromProjectAdminApp.getProjectProfiles(state.projectAdminApp, projectKey) -); +export const getProjectAdminProjectProfiles = (state, projectKey) => + fromProjectAdminApp.getProjectProfiles(state.projectAdminApp, projectKey); -export const getProjectAdminGateById = (state, gateId) => ( - fromProjectAdminApp.getGateById(state.projectAdminApp, gateId) -); +export const getProjectAdminGateById = (state, gateId) => + fromProjectAdminApp.getGateById(state.projectAdminApp, gateId); -export const getProjectAdminAllGates = state => ( - fromProjectAdminApp.getAllGates(state.projectAdminApp) -); +export const getProjectAdminAllGates = state => + fromProjectAdminApp.getAllGates(state.projectAdminApp); -export const getProjectAdminProjectGate = (state, projectKey) => ( - fromProjectAdminApp.getProjectGate(state.projectAdminApp, projectKey) -); +export const getProjectAdminProjectGate = (state, projectKey) => + fromProjectAdminApp.getProjectGate(state.projectAdminApp, projectKey); -export const getProjectAdminLinkById = (state, linkId) => ( - fromProjectAdminApp.getLinkById(state.projectAdminApp, linkId) -); +export const getProjectAdminLinkById = (state, linkId) => + fromProjectAdminApp.getLinkById(state.projectAdminApp, linkId); -export const getProjectAdminProjectLinks = (state, projectKey) => ( - fromProjectAdminApp.getProjectLinks(state.projectAdminApp, projectKey) -); +export const getProjectAdminProjectLinks = (state, projectKey) => + fromProjectAdminApp.getProjectLinks(state.projectAdminApp, projectKey); -export const getProjectAdminComponentByKey = (state, componentKey) => ( - fromProjectAdminApp.getComponentByKey(state.projectAdminApp, componentKey) -); +export const getProjectAdminComponentByKey = (state, componentKey) => + fromProjectAdminApp.getComponentByKey(state.projectAdminApp, componentKey); -export const getProjectAdminProjectModules = (state, projectKey) => ( - fromProjectAdminApp.getProjectModules(state.projectAdminApp, projectKey) -); +export const getProjectAdminProjectModules = (state, projectKey) => + fromProjectAdminApp.getProjectModules(state.projectAdminApp, projectKey); -export const getProjectAdminGlobalMessages = state => ( - fromProjectAdminApp.getGlobalMessages(state.projectAdminApp) -); +export const getProjectAdminGlobalMessages = state => + fromProjectAdminApp.getGlobalMessages(state.projectAdminApp); -export const getMeasuresAppComponent = state => ( - fromMeasuresApp.getComponent(state.measuresApp) -); +export const getMeasuresAppComponent = state => fromMeasuresApp.getComponent(state.measuresApp); -export const getMeasuresAppAllMetrics = state => ( - fromMeasuresApp.getAllMetrics(state.measuresApp) -); +export const getMeasuresAppAllMetrics = state => fromMeasuresApp.getAllMetrics(state.measuresApp); -export const getMeasuresAppDetailsMetric = state => ( - fromMeasuresApp.getDetailsMetric(state.measuresApp) -); +export const getMeasuresAppDetailsMetric = state => + fromMeasuresApp.getDetailsMetric(state.measuresApp); -export const getMeasuresAppDetailsMeasure = state => ( - fromMeasuresApp.getDetailsMeasure(state.measuresApp) -); +export const getMeasuresAppDetailsMeasure = state => + fromMeasuresApp.getDetailsMeasure(state.measuresApp); -export const getMeasuresAppDetailsSecondaryMeasure = state => ( - fromMeasuresApp.getDetailsSecondaryMeasure(state.measuresApp) -); +export const getMeasuresAppDetailsSecondaryMeasure = state => + fromMeasuresApp.getDetailsSecondaryMeasure(state.measuresApp); -export const getMeasuresAppDetailsPeriods = state => ( - fromMeasuresApp.getDetailsPeriods(state.measuresApp) -); +export const getMeasuresAppDetailsPeriods = state => + fromMeasuresApp.getDetailsPeriods(state.measuresApp); -export const isMeasuresAppFetching = state => ( - fromMeasuresApp.isFetching(state.measuresApp) -); +export const isMeasuresAppFetching = state => fromMeasuresApp.isFetching(state.measuresApp); -export const getMeasuresAppList = state => ( - fromMeasuresApp.getList(state.measuresApp) -); +export const getMeasuresAppList = state => fromMeasuresApp.getList(state.measuresApp); -export const getMeasuresAppListComponents = state => ( - fromMeasuresApp.getListComponents(state.measuresApp) -); +export const getMeasuresAppListComponents = state => + fromMeasuresApp.getListComponents(state.measuresApp); -export const getMeasuresAppListSelected = state => ( - fromMeasuresApp.getListSelected(state.measuresApp) -); +export const getMeasuresAppListSelected = state => + fromMeasuresApp.getListSelected(state.measuresApp); -export const getMeasuresAppListTotal = state => ( - fromMeasuresApp.getListTotal(state.measuresApp) -); +export const getMeasuresAppListTotal = state => fromMeasuresApp.getListTotal(state.measuresApp); -export const getMeasuresAppListPageIndex = state => ( - fromMeasuresApp.getListPageIndex(state.measuresApp) -); +export const getMeasuresAppListPageIndex = state => + fromMeasuresApp.getListPageIndex(state.measuresApp); -export const getMeasuresAppTree = state => ( - fromMeasuresApp.getTree(state.measuresApp) -); +export const getMeasuresAppTree = state => fromMeasuresApp.getTree(state.measuresApp); -export const getMeasuresAppTreeComponents = state => ( - fromMeasuresApp.getTreeComponents(state.measuresApp) -); +export const getMeasuresAppTreeComponents = state => + fromMeasuresApp.getTreeComponents(state.measuresApp); -export const getMeasuresAppTreeBreadcrumbs = state => ( - fromMeasuresApp.getTreeBreadcrumbs(state.measuresApp) -); +export const getMeasuresAppTreeBreadcrumbs = state => + fromMeasuresApp.getTreeBreadcrumbs(state.measuresApp); -export const getMeasuresAppTreeSelected = state => ( - fromMeasuresApp.getTreeSelected(state.measuresApp) -); +export const getMeasuresAppTreeSelected = state => + fromMeasuresApp.getTreeSelected(state.measuresApp); -export const getMeasuresAppTreeTotal = state => ( - fromMeasuresApp.getTreeTotal(state.measuresApp) -); +export const getMeasuresAppTreeTotal = state => fromMeasuresApp.getTreeTotal(state.measuresApp); -export const getMeasuresAppTreePageIndex = state => ( - fromMeasuresApp.getTreePageIndex(state.measuresApp) -); +export const getMeasuresAppTreePageIndex = state => + fromMeasuresApp.getTreePageIndex(state.measuresApp); -export const getMeasuresAppHomeDomains = state => ( - fromMeasuresApp.getHomeDomains(state.measuresApp) -); +export const getMeasuresAppHomeDomains = state => fromMeasuresApp.getHomeDomains(state.measuresApp); -export const getMeasuresAppHomePeriods = state => ( - fromMeasuresApp.getHomePeriods(state.measuresApp) -); +export const getMeasuresAppHomePeriods = state => fromMeasuresApp.getHomePeriods(state.measuresApp); diff --git a/server/sonar-web/src/main/js/store/users/actions.js b/server/sonar-web/src/main/js/store/users/actions.js index bfb9c41a925..d5e0616681d 100644 --- a/server/sonar-web/src/main/js/store/users/actions.js +++ b/server/sonar-web/src/main/js/store/users/actions.js @@ -26,6 +26,5 @@ export const receiveCurrentUser = user => ({ user }); -export const fetchCurrentUser = () => dispatch => ( - getCurrentUser().then(user => dispatch(receiveCurrentUser(user))) -); +export const fetchCurrentUser = () => + dispatch => getCurrentUser().then(user => dispatch(receiveCurrentUser(user))); diff --git a/server/sonar-web/src/main/js/store/users/reducer.js b/server/sonar-web/src/main/js/store/users/reducer.js index ec98882daf6..71b313077ed 100644 --- a/server/sonar-web/src/main/js/store/users/reducer.js +++ b/server/sonar-web/src/main/js/store/users/reducer.js @@ -47,6 +47,4 @@ const currentUser = (state = null, action = {}) => { export default combineReducers({ usersByLogin, userLogins, currentUser }); -export const getCurrentUser = state => ( - state.currentUser -); +export const getCurrentUser = state => state.currentUser; diff --git a/server/sonar-web/src/main/js/store/utils/configureStore.js b/server/sonar-web/src/main/js/store/utils/configureStore.js index 35d6a7ee916..8c5e2d8150b 100644 --- a/server/sonar-web/src/main/js/store/utils/configureStore.js +++ b/server/sonar-web/src/main/js/store/utils/configureStore.js @@ -30,15 +30,11 @@ if (process.env.NODE_ENV !== 'production') { composed.push(window.devToolsExtension ? window.devToolsExtension() : f => f); } -const finalCreateStore = compose( - applyMiddleware(...middlewares), - ...composed -)(createStore); +const finalCreateStore = compose(applyMiddleware(...middlewares), ...composed)(createStore); -export default function configureStore (rootReducer, initialState) { +export default function configureStore(rootReducer, initialState) { return finalCreateStore(rootReducer, initialState); } -export const configureTestStore = (rootReducer, initialState) => ( - createStore(rootReducer, initialState) -); +export const configureTestStore = (rootReducer, initialState) => + createStore(rootReducer, initialState); diff --git a/server/sonar-web/src/main/js/store/utils/generalReducers.js b/server/sonar-web/src/main/js/store/utils/generalReducers.js index e931de0a61c..21342cb4bde 100644 --- a/server/sonar-web/src/main/js/store/utils/generalReducers.js +++ b/server/sonar-web/src/main/js/store/utils/generalReducers.js @@ -31,19 +31,20 @@ import uniq from 'lodash/uniq'; * @returns {function(state, action)} */ export const createValue = ( - shouldUpdate = () => true, - shouldReset = () => false, - getValue = (state, action) => action.payload, - defaultValue = null -) => (state = defaultValue, action = {}) => { - if (shouldReset(state, action)) { - return defaultValue; - } - if (shouldUpdate(state, action)) { - return getValue(state, action); - } - return state; -}; + shouldUpdate = () => true, + shouldReset = () => false, + getValue = (state, action) => action.payload, + defaultValue = null +) => + (state = defaultValue, action = {}) => { + if (shouldReset(state, action)) { + return defaultValue; + } + if (shouldUpdate(state, action)) { + return getValue(state, action); + } + return state; + }; /** * Creates a reducer that manages a map. @@ -54,11 +55,16 @@ export const createValue = ( * @returns {function(state, action)} */ export const createMap = ( - shouldUpdate = () => true, - shouldReset = () => false, - getValues = (state, action) => action.payload -) => createValue(shouldUpdate, shouldReset, (state, action) => - ({ ...state, ...getValues(state, action) }), {}); + shouldUpdate = () => true, + shouldReset = () => false, + getValues = (state, action) => action.payload +) => + createValue( + shouldUpdate, + shouldReset, + (state, action) => ({ ...state, ...getValues(state, action) }), + {} + ); /** * Creates a reducer that manages a set. @@ -69,11 +75,16 @@ export const createMap = ( * @returns {function(state, action)} */ export const createSet = ( - shouldUpdate = () => true, - shouldReset = () => false, - getValues = (state, action) => action.payload -) => createValue(shouldUpdate, shouldReset, (state, action) => - uniq([...state, ...getValues(state, action)]), []); + shouldUpdate = () => true, + shouldReset = () => false, + getValues = (state, action) => action.payload +) => + createValue( + shouldUpdate, + shouldReset, + (state, action) => uniq([...state, ...getValues(state, action)]), + [] + ); /** * Creates a reducer that manages a flag. @@ -84,12 +95,12 @@ export const createSet = ( * @returns {function(state, action)} */ export const createFlag = (shouldTurnOn, shouldTurnOff, defaultValue = false) => - (state = defaultValue, action = {}) => { - if (shouldTurnOn(state, action)) { - return true; - } - if (shouldTurnOff(state, action)) { - return false; - } - return state; - }; + (state = defaultValue, action = {}) => { + if (shouldTurnOn(state, action)) { + return true; + } + if (shouldTurnOff(state, action)) { + return false; + } + return state; + }; diff --git a/server/sonar-web/src/main/js/store/utils/withStore.js b/server/sonar-web/src/main/js/store/utils/withStore.js index b215ce10a66..ddcf29e471e 100644 --- a/server/sonar-web/src/main/js/store/utils/withStore.js +++ b/server/sonar-web/src/main/js/store/utils/withStore.js @@ -31,21 +31,22 @@ const withStore = (ComposedComponent, initial = {}) => { return class extends React.Component { static displayName = `withStore(${ComposedComponent.displayName})}`; - componentWillMount () { + componentWillMount() { this.handleUpdateStore = this.handleUpdateStore.bind(this); } - handleUpdateStore (changes) { + handleUpdateStore(changes) { updateStore(changes); this.forceUpdate(); } - render () { + render() { return ( - <ComposedComponent - {...this.props} - getStore={getStore} - updateStore={this.handleUpdateStore}/> + <ComposedComponent + {...this.props} + getStore={getStore} + updateStore={this.handleUpdateStore} + /> ); } }; |