From 77b57db4289a9ce9b9465ab608ed5aa49023be78 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Fri, 31 Mar 2017 16:50:34 +0200 Subject: [PATCH] Add format rule : order react component lifecycle methods (#1882) --- server/sonar-web/.eslintrc | 17 ++++++++- .../src/main/js/app/components/App.js | 12 +++---- .../app/components/LocalizationContainer.js | 12 +++---- .../components/nav/global/GlobalNavSearch.js | 18 +++++----- .../main/js/apps/account/components/Tokens.js | 12 +++---- .../js/apps/account/notifications/Projects.js | 17 ++++----- .../organizations/CreateOrganizationForm.js | 21 ++++++----- .../src/main/js/apps/projects-admin/search.js | 36 +++++++++---------- .../ProjectTagsSelectorContainer.js | 5 ++- .../apps/projects/filters/CoverageFilter.js | 10 +++--- .../projects/filters/DuplicationsFilter.js | 10 +++--- .../js/apps/projects/filters/IssuesFilter.js | 8 ++--- .../apps/projects/filters/LanguagesFilter.js | 14 ++++---- .../projects/filters/QualityGateFilter.js | 8 ++--- .../js/apps/projects/filters/SizeFilter.js | 22 ++++++------ .../js/apps/projects/filters/TagsFilter.js | 18 +++++----- .../apps/quality-gates/components/Projects.js | 12 +++---- .../quality-profiles/details/ProfileRules.js | 12 +++---- .../js/apps/users/components/UsersSearch.js | 7 ++-- .../SourceViewerIssueLocations.js | 3 +- .../main/js/components/common/MultiSelect.js | 17 +++++---- .../src/main/js/components/issue/Issue.js | 8 ++--- 22 files changed, 161 insertions(+), 138 deletions(-) diff --git a/server/sonar-web/.eslintrc b/server/sonar-web/.eslintrc index a03e1f19e92..d6e85fb9139 100644 --- a/server/sonar-web/.eslintrc +++ b/server/sonar-web/.eslintrc @@ -163,7 +163,22 @@ "react/no-unknown-property": 2, "react/react-in-jsx-scope": 2, "react/require-render-return": 2, - "react/self-closing-comp": 2 + "react/self-closing-comp": 2, + "react/sort-comp": [2, { + "order": [ + "type-annotations", + "static-methods", + "lifecycle", + "everything-else", + "rendering" + ], + "groups": { + "rendering": [ + "/^render.+$/", + "render" + ] + } + }] }, "settings": { 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 647acffd144..bc1904c6386 100644 --- a/server/sonar-web/src/main/js/app/components/App.js +++ b/server/sonar-web/src/main/js/app/components/App.js @@ -39,12 +39,6 @@ class App extends React.Component { loading: true }; - finishLoading = () => { - if (this.mounted) { - this.setState({ loading: false }); - } - }; - componentDidMount() { this.mounted = true; @@ -63,6 +57,12 @@ class App extends React.Component { this.mounted = false; } + finishLoading = () => { + if (this.mounted) { + this.setState({ loading: false }); + } + }; + render() { if (this.state.loading) { return ; 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 8cbbec134be..341d4ff8121 100644 --- a/server/sonar-web/src/main/js/app/components/LocalizationContainer.js +++ b/server/sonar-web/src/main/js/app/components/LocalizationContainer.js @@ -28,12 +28,6 @@ export default class LocalizationContainer extends React.Component { loading: true }; - finishLoading = () => { - if (this.mounted) { - this.setState({ loading: false }); - } - }; - componentDidMount() { this.mounted = true; requestMessages().then(this.finishLoading, this.finishLoading); @@ -43,6 +37,12 @@ export default class LocalizationContainer extends React.Component { this.mounted = false; } + finishLoading = () => { + if (this.mounted) { + this.setState({ loading: false }); + } + }; + render() { return this.state.loading ? null : this.props.children; } 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 2b5aa6ccf63..cb8349ecca5 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 @@ -62,15 +62,6 @@ class GlobalNavSearch extends React.Component { this.setState({ open: false }); }; - renderSearchView = () => { - const searchContainer = this.refs.container; - this.searchView = new SearchView({ - model: new Backbone.Model(this.props), - hide: this.closeSearch - }); - this.searchView.render().$el.appendTo(searchContainer); - }; - resetSearchView = () => { if (this.searchView) { this.searchView.destroy(); @@ -92,6 +83,15 @@ class GlobalNavSearch extends React.Component { } }; + renderSearchView = () => { + const searchContainer = this.refs.container; + this.searchView = new SearchView({ + model: new Backbone.Model(this.props), + hide: this.closeSearch + }); + this.searchView.render().$el.appendTo(searchContainer); + }; + render() { const dropdownClassName = 'dropdown' + (this.state.open ? ' open' : ''); return ( 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 284f0fd9f9d..a919b09b646 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 @@ -30,6 +30,12 @@ export default class Tokens extends Component { this.destroyView(); } + destroyView() { + if (this.destroyView) { + this.tokensView.destroy(); + } + } + renderView() { const account = new Backbone.Model({ id: this.props.user.login @@ -41,12 +47,6 @@ export default class Tokens extends Component { }).render(); } - destroyView() { - if (this.destroyView) { - this.tokensView.destroy(); - } - } - render() { return
; } 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 89c32e17079..e378b4a0a95 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 @@ -62,14 +62,6 @@ class Projects extends React.Component { } } - renderOption = option => { - return ( - - - {option.label} - - ); - }; loadOptions = (query, cb) => { if (query.length < 2) { cb(null, { options: [] }); @@ -103,6 +95,15 @@ class Projects extends React.Component { }); }; + renderOption = option => { + return ( + + + {option.label} + + ); + }; + render() { const allProjects = [...this.props.projects, ...this.state.addedProjects]; 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 fc0fca467d9..04b822d40b2 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 @@ -38,24 +38,23 @@ type State = { class CreateOrganizationForm extends React.Component { mounted: boolean; - + state: State; props: { createOrganization: () => Promise<*>, router: { push: (string) => void } }; - state: State = { - loading: false, - avatar: '', - avatarImage: '', - description: '', - key: '', - name: '', - url: '' - }; - constructor(props) { super(props); + this.state = { + loading: false, + avatar: '', + avatarImage: '', + description: '', + key: '', + name: '', + url: '' + }; this.changeAvatarImage = debounce(this.changeAvatarImage, 500); } 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 542946ce55b..2437b928026 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 @@ -55,6 +55,20 @@ export default React.createClass({ return sortBy(options, option => QUALIFIERS_ORDER.indexOf(option.value)); }, + onCheck(checked) { + if (checked) { + this.props.onAllSelected(); + } else { + this.props.onAllDeselected(); + } + }, + + deleteProjects() { + new DeleteView({ + deleteProjects: this.props.deleteProjects + }).render(); + }, + renderCheckbox() { const isAllChecked = this.props.projects.length > 0 && this.props.selection.length === this.props.projects.length; @@ -65,18 +79,6 @@ export default React.createClass({ return ; }, - renderSpinner() { - return ; - }, - - onCheck(checked) { - if (checked) { - this.props.onAllSelected(); - } else { - this.props.onAllDeselected(); - } - }, - renderGhostsDescription() { if (this.props.type !== TYPE.GHOSTS || !this.props.ready) { return null; @@ -88,12 +90,6 @@ export default React.createClass({ ); }, - deleteProjects() { - new DeleteView({ - deleteProjects: this.props.deleteProjects - }).render(); - }, - renderQualifierFilter() { const options = this.getQualifierOptions(); if (options.length < 2) { @@ -111,6 +107,10 @@ export default React.createClass({ ); }, + renderSpinner() { + return ; + }, + render() { const isSomethingSelected = this.props.projects.length > 0 && this.props.selection.length > 0; return ( diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js index fae4f79b62e..1db66ab8553 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectTagsSelectorContainer.js @@ -41,12 +41,11 @@ const LIST_SIZE = 10; class ProjectTagsSelectorContainer extends React.PureComponent { props: Props; - state: State = { - searchResult: [] - }; + state: State; constructor(props: Props) { super(props); + this.state = { searchResult: [] }; this.onSearch = debounce(this.onSearch, 250); } 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 46c3ed99a22..e914a5180cd 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,6 +33,11 @@ export default class CoverageFilter extends React.PureComponent { property = 'coverage'; + 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]]; + } + renderOption(option, selected) { return ( @@ -48,11 +53,6 @@ export default class CoverageFilter extends React.PureComponent { ); } - 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() { return ( @@ -51,11 +56,6 @@ export default class DuplicationsFilter extends React.PureComponent { ); } - 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() { return ( @@ -41,10 +45,6 @@ export default class IssuesFilter extends React.PureComponent { ); } - getFacetValueForOption(facet, option) { - return facet[option]; - } - render() { return ( ( - - ); - getSearchOptions(facet: {}, languages: {}) { let languageKeys = Object.keys(languages); if (facet) { @@ -67,6 +60,13 @@ export default class LanguagesFilter extends React.PureComponent { getFacetValueForOption = (facet: {} = {}, option: string) => facet[option]; + renderOption = (option: string) => ( + + ); + render() { return ( ; - } - getFacetValueForOption(facet, option) { return facet[option]; } + renderOption(option, selected) { + return ; + } + render() { return ( @@ -58,17 +69,6 @@ export default class SizeFilter extends React.PureComponent { ); }; - getFacetValueForOption(facet, option) { - const map = [ - '*-1000.0', - '1000.0-10000.0', - '10000.0-100000.0', - '100000.0-500000.0', - '500000.0-*' - ]; - return facet[map[option - 1]]; - } - render() { return ( [{ label: string, value: string }]; props: Props; - state: State = { - isLoading: false, - search: '', - tags: [] - }; - property = 'tags'; + state: State; + property: string; constructor(props: Props) { super(props); + this.state = { + isLoading: false, + search: '', + tags: [] + }; + this.property = 'tags'; this.handleSearch = debounce(this.handleSearch.bind(this), 250); } - renderOption = (option: string) => ; - getSearchOptions(facet: {}, tags: Array) { let tagsCopy = [...tags]; if (facet) { @@ -88,6 +88,8 @@ export default class TagsFilter extends React.PureComponent { getFacetValueForOption = (facet: {}, option: string) => facet[option]; + renderOption = (option: string) => ; + render() { return ( ; } 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 cf530249158..2dee1b5680e 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 @@ -101,6 +101,12 @@ export default class ProfileRules extends React.Component { ); } + getTooltipForType(type) { + const { count } = this.state.activatedByType[type]; + const total = this.state.allByType[type].count; + return this.getTooltip(count, total); + } + renderActiveTitle() { return ( @@ -151,12 +157,6 @@ export default class ProfileRules extends React.Component { ); } - getTooltipForType(type) { - const { count } = this.state.activatedByType[type]; - const total = this.state.allByType[type].count; - return this.getTooltip(count, total); - } - renderTitleForType(type) { return ( diff --git a/server/sonar-web/src/main/js/apps/users/components/UsersSearch.js b/server/sonar-web/src/main/js/apps/users/components/UsersSearch.js index e450d51b4c1..8d336b0c44f 100644 --- a/server/sonar-web/src/main/js/apps/users/components/UsersSearch.js +++ b/server/sonar-web/src/main/js/apps/users/components/UsersSearch.js @@ -34,12 +34,13 @@ type State = { export default class UsersSearch extends React.PureComponent { props: Props; - state: State = { - query: '' - }; + state: State; constructor(props: Props) { super(props); + this.state = { + query: '' + }; this.handleSearch = debounce(this.handleSearch, 250); } 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 98e7b1a2e78..5e2df2d6594 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerIssueLocations.js @@ -43,7 +43,7 @@ type State = { export default class SourceViewerIssueLocations extends React.Component { fixedNode: HTMLElement; - locations: { [string]: HTMLElement } = {}; + locations: { [string]: HTMLElement }; node: HTMLElement; props: Props; rootNode: HTMLElement; @@ -52,6 +52,7 @@ export default class SourceViewerIssueLocations extends React.Component { constructor(props: Props) { super(props); this.state = { fixed: true, locationBlink: false }; + this.locations = {}; this.handleScroll = throttle(this.handleScroll, 50); } diff --git a/server/sonar-web/src/main/js/components/common/MultiSelect.js b/server/sonar-web/src/main/js/components/common/MultiSelect.js index d6ba67ca473..ecc74825395 100644 --- a/server/sonar-web/src/main/js/components/common/MultiSelect.js +++ b/server/sonar-web/src/main/js/components/common/MultiSelect.js @@ -44,18 +44,23 @@ export default class MultiSelect extends React.PureComponent { container: HTMLElement; searchInput: HTMLInputElement; props: Props; - state: State = { - query: '', - selectedElements: [], - unselectedElements: [], - activeIdx: 0 - }; + state: State; static defaultProps = { listSize: 10, validateSearchInput: (value: string) => value }; + constructor(props: Props) { + super(props); + this.state = { + query: '', + selectedElements: [], + unselectedElements: [], + activeIdx: 0 + }; + } + componentDidMount() { this.updateSelectedElements(this.props); this.updateUnselectedElements(this.props); 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 5717a060e3b..67f0083f87e 100644 --- a/server/sonar-web/src/main/js/components/issue/Issue.js +++ b/server/sonar-web/src/main/js/components/issue/Issue.js @@ -116,6 +116,10 @@ class Issue extends React.PureComponent { } }; + destroyIssueView() { + this.issueView.destroy(); + } + renderIssueView() { const model = this.props.issue.toJSON ? this.props.issue : new IssueModel(this.props.issue); this.issueView = new IssueView({ @@ -132,10 +136,6 @@ class Issue extends React.PureComponent { } } - destroyIssueView() { - this.issueView.destroy(); - } - render() { return
this.node = node} />; } -- 2.39.5