From f6fd6fb056ca6c3de3637cfeafb53c30815ee12d Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Mon, 3 Sep 2018 09:21:22 +0200 Subject: finish typing redux store and simplify connected components (#675) --- server/sonar-web/src/main/js/api/issues.ts | 2 +- server/sonar-web/src/main/js/api/languages.ts | 3 +- server/sonar-web/src/main/js/api/organizations.ts | 13 +- server/sonar-web/src/main/js/api/permissions.ts | 16 +- .../sonar-web/src/main/js/api/quality-profiles.ts | 22 ++- .../src/main/js/app/components/AdminContainer.tsx | 8 +- .../sonar-web/src/main/js/app/components/App.tsx | 4 +- .../main/js/app/components/ComponentContainer.tsx | 2 +- .../js/app/components/GlobalFooterContainer.tsx | 10 +- .../js/app/components/GlobalMessagesContainer.tsx | 6 +- .../src/main/js/app/components/Landing.tsx | 6 +- .../src/main/js/app/components/PageTracker.tsx | 6 +- .../src/main/js/app/components/StartupModal.tsx | 10 +- .../embed-docs-modal/ProductNewsMenuItem.tsx | 6 +- .../components/extensions/ExtensionContainer.tsx | 8 +- .../extensions/OrganizationPageExtension.tsx | 6 +- .../extensions/ProjectAdminPageExtension.js | 2 +- .../nav/component/ComponentNavHeader.tsx | 10 +- .../components/nav/component/ComponentNavMeta.tsx | 4 +- .../js/app/components/nav/global/GlobalNav.tsx | 8 +- .../components/nav/global/GlobalNavBranding.tsx | 6 +- .../js/app/components/nav/global/GlobalNavMenu.tsx | 2 +- .../nav/global/GlobalNavUserContainer.tsx | 4 +- .../nav/global/__tests__/GlobalNav-test.tsx | 7 +- .../__snapshots__/GlobalNav-test.tsx.snap | 18 ++ .../src/main/js/app/components/search/Search.d.ts | 2 +- server/sonar-web/src/main/js/app/flow-types.js | 33 ++++ server/sonar-web/src/main/js/app/types.ts | 7 + .../main/js/app/utils/addGlobalSuccessMessage.ts | 2 +- server/sonar-web/src/main/js/app/utils/getStore.ts | 4 +- .../js/app/utils/handleRequiredAuthorization.js | 2 +- .../src/main/js/app/utils/throwGlobalError.ts | 16 +- .../js/apps/about/sonarcloud/SonarCloudPage.tsx | 8 +- .../account/organizations/UserOrganizations.tsx | 13 +- .../main/js/apps/account/organizations/actions.ts | 7 +- .../background-tasks/components/StatsContainer.tsx | 4 +- .../main/js/apps/coding-rules/components/App.tsx | 6 +- .../apps/coding-rules/components/LanguageFacet.tsx | 4 +- .../coding-rules/components/RepositoryFacet.tsx | 4 +- .../js/apps/component-measures/components/App.js | 2 +- .../component-measures/components/MeasureHeader.js | 2 +- .../components/MeasureOverview.js | 2 +- .../components/MeasureOverviewContainer.js | 2 +- .../component-measures/drilldown/BubbleChart.js | 2 +- .../component-measures/drilldown/ComponentCell.js | 2 +- .../drilldown/ComponentsListRow.js | 2 +- .../component-measures/drilldown/MeasureCell.js | 2 +- .../src/main/js/apps/issues/IssuesPageSelector.tsx | 6 +- .../js/apps/issues/components/AppContainer.tsx | 19 +- .../main/js/apps/issues/sidebar/LanguageFacet.tsx | 4 +- .../sonar-web/src/main/js/apps/marketplace/App.tsx | 2 +- .../src/main/js/apps/marketplace/AppContainer.tsx | 8 +- .../OrganizationMembersContainer.tsx | 11 +- .../src/main/js/apps/organizations/actions.ts | 30 ++-- .../components/OrganizationAccessContainer.tsx | 8 +- .../components/OrganizationContainer.tsx | 6 +- .../components/OrganizationDelete.tsx | 2 +- .../organizations/components/OrganizationEdit.tsx | 2 +- .../organizations/components/OrganizationPage.tsx | 7 +- .../apps/organizations/forSingleOrganization.tsx | 4 +- .../OrganizationNavigationHeaderContainer.tsx | 4 +- .../OrganizationNavigationMenuContainer.tsx | 6 +- .../js/apps/overview/components/OverviewApp.tsx | 6 +- .../components/SonarCloudEmptyOverview.tsx | 6 +- .../main/js/apps/overview/meta/MetaContainer.tsx | 7 +- .../js/apps/overview/meta/MetaQualityProfiles.tsx | 6 +- .../src/main/js/apps/overview/meta/MetaSize.tsx | 2 +- .../global/components/AllHoldersListContainer.tsx | 30 +--- .../js/apps/permissions/project/components/App.js | 7 +- .../permissions/project/components/AppContainer.js | 10 +- .../permissions/shared/components/PageError.tsx | 4 +- .../src/main/js/apps/portfolio/components/App.tsx | 6 +- .../js/apps/portfolio/components/Subscription.tsx | 5 +- .../portfolio/components/SubscriptionContainer.tsx | 6 +- .../components/__tests__/Subscription-test.tsx | 4 +- .../main/js/apps/project-admin/key/BulkUpdate.js | 2 +- .../src/main/js/apps/project-admin/key/Key.js | 2 +- .../projectBranches/components/AppContainer.ts | 6 +- .../js/apps/projects/components/AllProjects.tsx | 2 +- .../projects/components/AllProjectsContainer.tsx | 22 +-- .../components/DefaultPageSelectorContainer.tsx | 11 +- .../components/FavoriteFilterContainer.tsx | 4 +- .../projects/components/NoFavoriteProjects.tsx | 4 +- .../projects/components/ProjectCardLanguages.tsx | 2 +- .../components/ProjectCardLanguagesContainer.tsx | 11 +- .../components/ProjectCardOrganization.tsx | 2 +- .../ProjectCardOrganizationContainer.tsx | 10 +- .../js/apps/projects/create/CreateProjectPage.tsx | 10 +- .../apps/projects/create/ManualProjectCreate.tsx | 6 +- .../js/apps/projects/filters/LanguagesFilter.tsx | 2 +- .../projects/filters/LanguagesFilterContainer.tsx | 11 +- .../projects/visualizations/Visualizations.tsx | 2 +- .../js/apps/projectsManagement/AppContainer.tsx | 9 +- .../apps/quality-gates/components/DetailsApp.tsx | 6 +- .../js/apps/quality-profiles/components/App.tsx | 4 +- .../quality-profiles/components/AppContainer.tsx | 26 +-- .../components/CopyProfileForm.tsx | 4 +- .../components/DeleteProfileForm.tsx | 4 +- .../quality-profiles/components/ProfileActions.tsx | 4 - .../components/ProfileContainer.tsx | 3 - .../components/RenameProfileForm.tsx | 4 +- .../components/__tests__/ProfileActions-test.tsx | 12 +- .../components/__tests__/ProfileContainer-test.tsx | 3 - .../quality-profiles/details/ChangeParentForm.tsx | 4 +- .../quality-profiles/details/ProfileDetails.tsx | 1 - .../quality-profiles/details/ProfileHeader.tsx | 2 - .../details/ProfileInheritance.tsx | 2 - .../details/__tests__/ProfileDetails-test.tsx | 2 - .../__snapshots__/ProfileDetails-test.tsx.snap | 8 - .../quality-profiles/home/CreateProfileForm.tsx | 4 +- .../apps/quality-profiles/home/HomeContainer.tsx | 1 - .../js/apps/quality-profiles/home/PageHeader.tsx | 3 - .../js/apps/quality-profiles/home/ProfilesList.tsx | 2 - .../apps/quality-profiles/home/ProfilesListRow.tsx | 2 - .../quality-profiles/home/RestoreProfileForm.tsx | 4 +- .../js/apps/sessions/components/LoginContainer.tsx | 2 +- .../src/main/js/apps/settings/store/actions.js | 2 +- .../apps/settings/store/encryptionPage/actions.js | 2 +- .../src/main/js/apps/settings/store/rootReducer.js | 4 +- .../apps/tutorials/onboarding/OnboardingModal.tsx | 6 +- .../apps/tutorials/onboarding/OnboardingPage.tsx | 4 +- .../projectOnboarding/ProjectOnboarding.tsx | 8 +- .../projectOnboarding/ProjectOnboardingPage.tsx | 4 +- .../sonar-web/src/main/js/apps/users/UsersApp.tsx | 2 +- .../src/main/js/apps/users/UsersAppContainer.tsx | 16 +- .../sonar-web/src/main/js/apps/users/UsersList.tsx | 2 +- .../main/js/apps/users/components/UserListItem.tsx | 2 +- .../js/components/charts/LanguageDistribution.tsx | 8 +- .../charts/LanguageDistributionContainer.tsx | 6 +- .../charts/__tests__/LanguageDistribution-test.tsx | 2 +- .../js/components/common/PrivacyBadgeContainer.tsx | 11 +- .../main/js/components/controls/HomePageSelect.tsx | 6 +- .../controls/__tests__/HomePageSelect-test.tsx | 22 ++- .../src/main/js/components/issue/Issue.js | 12 +- .../src/main/js/components/issue/IssueView.js | 7 +- .../src/main/js/components/issue/actions.js | 2 - .../components/issue/components/IssueActionsBar.js | 6 - .../js/components/issue/components/IssueAssign.js | 9 +- .../components/issue/components/IssueChangelog.js | 5 +- .../issue/components/IssueCommentAction.js | 7 +- .../js/components/issue/components/IssueTags.js | 2 - .../components/issue/components/IssueTitleBar.js | 3 - .../components/issue/components/IssueTransition.js | 2 - .../issue/components/SimilarIssuesFilter.js | 1 - .../issue/components/__tests__/IssueAssign-test.js | 3 - .../components/__tests__/IssueChangelog-test.js | 2 - .../__tests__/IssueCommentAction-test.js | 2 - .../issue/components/__tests__/IssueTags-test.js | 3 - .../components/__tests__/IssueTitleBar-test.js | 9 +- .../__snapshots__/IssueAssign-test.js.snap | 2 - .../__snapshots__/IssueChangelog-test.js.snap | 2 - .../__snapshots__/IssueTitleBar-test.js.snap | 3 - .../js/components/issue/popups/ChangelogPopup.js | 14 +- .../js/components/issue/popups/SetAssigneePopup.js | 8 +- .../issue/popups/__tests__/ChangelogPopup-test.js | 1 - .../src/main/js/components/measure/types.js | 2 +- .../src/main/js/components/shared/Organization.tsx | 8 +- .../sonar-web/src/main/js/components/ui/Avatar.tsx | 4 +- .../__snapshots__/organizations-test.ts.snap | 97 ++++++++++ .../main/js/store/__tests__/organizations-test.ts | 103 +++++++++++ server/sonar-web/src/main/js/store/appState.ts | 66 +++++++ .../sonar-web/src/main/js/store/appState/duck.ts | 74 -------- .../sonar-web/src/main/js/store/globalMessages.ts | 102 +++++++++++ .../src/main/js/store/globalMessages/duck.js | 131 -------------- server/sonar-web/src/main/js/store/languages.ts | 47 +++++ .../src/main/js/store/languages/actions.js | 25 --- .../src/main/js/store/languages/reducer.ts | 39 ---- server/sonar-web/src/main/js/store/metrics.ts | 56 ++++++ .../sonar-web/src/main/js/store/metrics/actions.js | 40 ----- .../sonar-web/src/main/js/store/metrics/reducer.js | 50 ------ .../sonar-web/src/main/js/store/organizations.ts | 116 ++++++++++++ .../__tests__/__snapshots__/duck-test.ts.snap | 43 ----- .../js/store/organizations/__tests__/duck-test.ts | 61 ------- .../src/main/js/store/organizations/duck.ts | 199 --------------------- server/sonar-web/src/main/js/store/rootActions.js | 67 ------- server/sonar-web/src/main/js/store/rootActions.ts | 76 ++++++++ server/sonar-web/src/main/js/store/rootReducer.js | 114 ------------ server/sonar-web/src/main/js/store/rootReducer.ts | 166 +++++++++++++++++ server/sonar-web/src/main/js/store/users.ts | 105 +++++++++++ .../sonar-web/src/main/js/store/users/actions.ts | 49 ----- .../sonar-web/src/main/js/store/users/reducer.ts | 71 -------- .../sonar-web/src/main/js/store/utils/actions.ts | 24 +++ .../src/main/js/store/utils/configureStore.js | 40 ----- .../src/main/js/store/utils/configureStore.ts | 44 +++++ 184 files changed, 1428 insertions(+), 1563 deletions(-) create mode 100644 server/sonar-web/src/main/js/app/flow-types.js create mode 100644 server/sonar-web/src/main/js/store/__tests__/__snapshots__/organizations-test.ts.snap create mode 100644 server/sonar-web/src/main/js/store/__tests__/organizations-test.ts create mode 100644 server/sonar-web/src/main/js/store/appState.ts delete mode 100644 server/sonar-web/src/main/js/store/appState/duck.ts create mode 100644 server/sonar-web/src/main/js/store/globalMessages.ts delete mode 100644 server/sonar-web/src/main/js/store/globalMessages/duck.js create mode 100644 server/sonar-web/src/main/js/store/languages.ts delete mode 100644 server/sonar-web/src/main/js/store/languages/actions.js delete mode 100644 server/sonar-web/src/main/js/store/languages/reducer.ts create mode 100644 server/sonar-web/src/main/js/store/metrics.ts delete mode 100644 server/sonar-web/src/main/js/store/metrics/actions.js delete mode 100644 server/sonar-web/src/main/js/store/metrics/reducer.js create mode 100644 server/sonar-web/src/main/js/store/organizations.ts delete mode 100644 server/sonar-web/src/main/js/store/organizations/__tests__/__snapshots__/duck-test.ts.snap delete mode 100644 server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.ts delete mode 100644 server/sonar-web/src/main/js/store/organizations/duck.ts delete mode 100644 server/sonar-web/src/main/js/store/rootActions.js create mode 100644 server/sonar-web/src/main/js/store/rootActions.ts delete mode 100644 server/sonar-web/src/main/js/store/rootReducer.js create mode 100644 server/sonar-web/src/main/js/store/rootReducer.ts create mode 100644 server/sonar-web/src/main/js/store/users.ts delete mode 100644 server/sonar-web/src/main/js/store/users/actions.ts delete mode 100644 server/sonar-web/src/main/js/store/users/reducer.ts create mode 100644 server/sonar-web/src/main/js/store/utils/actions.ts delete mode 100644 server/sonar-web/src/main/js/store/utils/configureStore.js create mode 100644 server/sonar-web/src/main/js/store/utils/configureStore.ts (limited to 'server/sonar-web/src/main/js') diff --git a/server/sonar-web/src/main/js/api/issues.ts b/server/sonar-web/src/main/js/api/issues.ts index 6f1e4ed20e0..40d1222314a 100644 --- a/server/sonar-web/src/main/js/api/issues.ts +++ b/server/sonar-web/src/main/js/api/issues.ts @@ -110,7 +110,7 @@ export function searchIssueTags(data: { } export function getIssueChangelog(issue: string): Promise { - return getJSON('/api/issues/changelog', { issue }).then(r => r.changelog); + return getJSON('/api/issues/changelog', { issue }).then(r => r.changelog, throwGlobalError); } export function getIssueFilters() { diff --git a/server/sonar-web/src/main/js/api/languages.ts b/server/sonar-web/src/main/js/api/languages.ts index f5902cdb77b..c49c1290672 100644 --- a/server/sonar-web/src/main/js/api/languages.ts +++ b/server/sonar-web/src/main/js/api/languages.ts @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { getJSON } from '../helpers/request'; +import throwGlobalError from '../app/utils/throwGlobalError'; export interface Language { key: string; @@ -25,5 +26,5 @@ export interface Language { } export function getLanguages(): Promise { - return getJSON('/api/languages/list').then(r => r.languages); + return getJSON('/api/languages/list').then(r => r.languages, throwGlobalError); } diff --git a/server/sonar-web/src/main/js/api/organizations.ts b/server/sonar-web/src/main/js/api/organizations.ts index 78d8f63ac1c..289d6ce99d5 100644 --- a/server/sonar-web/src/main/js/api/organizations.ts +++ b/server/sonar-web/src/main/js/api/organizations.ts @@ -28,7 +28,7 @@ export function getOrganizations(data: { organizations: Organization[]; paging: Paging; }> { - return getJSON('/api/organizations/search', data); + return getJSON('/api/organizations/search', data).catch(throwGlobalError); } export function getOrganization(key: string): Promise { @@ -48,18 +48,21 @@ interface GetOrganizationNavigation { } export function getOrganizationNavigation(key: string): Promise { - return getJSON('/api/navigation/organization', { organization: key }).then(r => r.organization); + return getJSON('/api/navigation/organization', { organization: key }).then( + r => r.organization, + throwGlobalError + ); } export function createOrganization(data: OrganizationBase): Promise { return postJSON('/api/organizations/create', data).then(r => r.organization, throwGlobalError); } -export function updateOrganization(key: string, changes: OrganizationBase): Promise { - return post('/api/organizations/update', { key, ...changes }); +export function updateOrganization(key: string, changes: OrganizationBase) { + return post('/api/organizations/update', { key, ...changes }).catch(throwGlobalError); } -export function deleteOrganization(key: string): Promise { +export function deleteOrganization(key: string) { return post('/api/organizations/delete', { key }).catch(throwGlobalError); } diff --git a/server/sonar-web/src/main/js/api/permissions.ts b/server/sonar-web/src/main/js/api/permissions.ts index e14367bb6a7..116e242e3c2 100644 --- a/server/sonar-web/src/main/js/api/permissions.ts +++ b/server/sonar-web/src/main/js/api/permissions.ts @@ -29,7 +29,7 @@ export function grantPermissionToUser( login: string, permission: string, organization?: string -): Promise { +) { const data: RequestData = { login, permission }; if (projectKey) { data.projectKey = projectKey; @@ -37,7 +37,7 @@ export function grantPermissionToUser( if (organization && !projectKey) { data.organization = organization; } - return post('/api/permissions/add_user', data); + return post('/api/permissions/add_user', data).catch(throwGlobalError); } export function revokePermissionFromUser( @@ -45,7 +45,7 @@ export function revokePermissionFromUser( login: string, permission: string, organization?: string -): Promise { +) { const data: RequestData = { login, permission }; if (projectKey) { data.projectKey = projectKey; @@ -53,7 +53,7 @@ export function revokePermissionFromUser( if (organization && !projectKey) { data.organization = organization; } - return post('/api/permissions/remove_user', data); + return post('/api/permissions/remove_user', data).catch(throwGlobalError); } export function grantPermissionToGroup( @@ -61,7 +61,7 @@ export function grantPermissionToGroup( groupName: string, permission: string, organization?: string -): Promise { +) { const data: RequestData = { groupName, permission }; if (projectKey) { data.projectKey = projectKey; @@ -69,7 +69,7 @@ export function grantPermissionToGroup( if (organization) { data.organization = organization; } - return post('/api/permissions/add_group', data); + return post('/api/permissions/add_group', data).catch(throwGlobalError); } export function revokePermissionFromGroup( @@ -77,7 +77,7 @@ export function revokePermissionFromGroup( groupName: string, permission: string, organization?: string -): Promise { +) { const data: RequestData = { groupName, permission }; if (projectKey) { data.projectKey = projectKey; @@ -85,7 +85,7 @@ export function revokePermissionFromGroup( if (organization) { data.organization = organization; } - return post('/api/permissions/remove_group', data); + return post('/api/permissions/remove_group', data).catch(throwGlobalError); } interface GetPermissionTemplatesResponse { diff --git a/server/sonar-web/src/main/js/api/quality-profiles.ts b/server/sonar-web/src/main/js/api/quality-profiles.ts index bf8fc2b3eeb..93e0c1d5064 100644 --- a/server/sonar-web/src/main/js/api/quality-profiles.ts +++ b/server/sonar-web/src/main/js/api/quality-profiles.ts @@ -95,7 +95,8 @@ export function createQualityProfile(data: RequestData): Promise { .setData(data) .submit() .then(checkStatus) - .then(parseJSON); + .then(parseJSON) + .catch(throwGlobalError); } export function restoreQualityProfile(data: RequestData): Promise { @@ -104,7 +105,8 @@ export function restoreQualityProfile(data: RequestData): Promise { .setData(data) .submit() .then(checkStatus) - .then(parseJSON); + .then(parseJSON) + .catch(throwGlobalError); } export interface ProfileProject { @@ -128,20 +130,22 @@ export function setDefaultProfile(profileKey: string): Promise { return post('/api/qualityprofiles/set_default', { profileKey }); } -export function renameProfile(key: string, name: string): Promise { - return post('/api/qualityprofiles/rename', { key, name }); +export function renameProfile(key: string, name: string) { + return post('/api/qualityprofiles/rename', { key, name }).catch(throwGlobalError); } export function copyProfile(fromKey: string, toName: string): Promise { - return postJSON('/api/qualityprofiles/copy', { fromKey, toName }); + return postJSON('/api/qualityprofiles/copy', { fromKey, toName }).catch(throwGlobalError); } -export function deleteProfile(profileKey: string): Promise { - return post('/api/qualityprofiles/delete', { profileKey }); +export function deleteProfile(profileKey: string) { + return post('/api/qualityprofiles/delete', { profileKey }).catch(throwGlobalError); } -export function changeProfileParent(profileKey: string, parentKey: string): Promise { - return post('/api/qualityprofiles/change_parent', { profileKey, parentKey }); +export function changeProfileParent(profileKey: string, parentKey: string) { + return post('/api/qualityprofiles/change_parent', { profileKey, parentKey }).catch( + throwGlobalError + ); } export function getImporters(): Promise< diff --git a/server/sonar-web/src/main/js/app/components/AdminContainer.tsx b/server/sonar-web/src/main/js/app/components/AdminContainer.tsx index 05c330a371f..cb2d5b99709 100644 --- a/server/sonar-web/src/main/js/app/components/AdminContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/AdminContainer.tsx @@ -23,9 +23,9 @@ import Helmet from 'react-helmet'; import { connect } from 'react-redux'; import MarketplaceContext, { defaultPendingPlugins } from './MarketplaceContext'; import SettingsNav from './nav/settings/SettingsNav'; -import { getAppState } from '../../store/rootReducer'; +import { getAppState, Store } from '../../store/rootReducer'; import { getSettingsNavigation } from '../../api/nav'; -import { setAdminPages } from '../../store/appState/duck'; +import { setAdminPages } from '../../store/appState'; import { translate } from '../../helpers/l10n'; import { Extension, AppState } from '../types'; import { PluginPendingResult, getPendingPlugins } from '../../api/plugins'; @@ -121,7 +121,7 @@ class AdminContainer extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ appState: getAppState(state) }); @@ -129,7 +129,7 @@ const mapDispatchToProps: DispatchToProps = { setAdminPages }; -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(AdminContainer); diff --git a/server/sonar-web/src/main/js/app/components/App.tsx b/server/sonar-web/src/main/js/app/components/App.tsx index 22cd429689a..e5257a4a171 100644 --- a/server/sonar-web/src/main/js/app/components/App.tsx +++ b/server/sonar-web/src/main/js/app/components/App.tsx @@ -26,7 +26,7 @@ import { fetchLanguages } from '../../store/rootActions'; import { fetchMyOrganizations } from '../../apps/account/organizations/actions'; import { getInstance, isSonarCloud } from '../../helpers/system'; import { lazyLoad } from '../../components/lazyLoad'; -import { getCurrentUser, getAppState, getGlobalSettingValue } from '../../store/rootReducer'; +import { getCurrentUser, getAppState, getGlobalSettingValue, Store } from '../../store/rootReducer'; const PageTracker = lazyLoad(() => import('./PageTracker')); @@ -104,7 +104,7 @@ class App extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ appState: getAppState(state), currentUser: getCurrentUser(state), enableGravatar: (getGlobalSettingValue(state, 'sonar.lf.enableGravatar') || {}).value === 'true', diff --git a/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx index 00e376c5dfc..e8ee249706d 100644 --- a/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/ComponentContainer.tsx @@ -315,7 +315,7 @@ export class ComponentContainer extends React.PureComponent { const mapDispatchToProps = { fetchOrganizations }; -export default connect( +export default connect( null, mapDispatchToProps )(ComponentContainer); diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooterContainer.tsx b/server/sonar-web/src/main/js/app/components/GlobalFooterContainer.tsx index 4f079504d72..158478034d5 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalFooterContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/GlobalFooterContainer.tsx @@ -19,7 +19,7 @@ */ import { connect } from 'react-redux'; import GlobalFooter from './GlobalFooter'; -import { getAppState } from '../../store/rootReducer'; +import { getAppState, Store } from '../../store/rootReducer'; import { EditionKey } from '../../apps/marketplace/utils'; interface StateProps { @@ -28,14 +28,10 @@ interface StateProps { sonarqubeVersion?: string; } -interface OwnProps { - hideLoggedInInfo?: boolean; -} - -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ productionDatabase: getAppState(state).productionDatabase, sonarqubeEdition: getAppState(state).edition, sonarqubeVersion: getAppState(state).version }); -export default connect(mapStateToProps)(GlobalFooter); +export default connect(mapStateToProps)(GlobalFooter); diff --git a/server/sonar-web/src/main/js/app/components/GlobalMessagesContainer.tsx b/server/sonar-web/src/main/js/app/components/GlobalMessagesContainer.tsx index d8366702bc8..e9dfd8a6e08 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalMessagesContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/GlobalMessagesContainer.tsx @@ -19,10 +19,10 @@ */ import { connect } from 'react-redux'; import GlobalMessages from '../../components/controls/GlobalMessages'; -import { getGlobalMessages } from '../../store/rootReducer'; -import { closeGlobalMessage } from '../../store/globalMessages/duck'; +import { getGlobalMessages, Store } from '../../store/rootReducer'; +import { closeGlobalMessage } from '../../store/globalMessages'; -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ messages: getGlobalMessages(state) }); diff --git a/server/sonar-web/src/main/js/app/components/Landing.tsx b/server/sonar-web/src/main/js/app/components/Landing.tsx index d4f80be9ab8..f96be5fc011 100644 --- a/server/sonar-web/src/main/js/app/components/Landing.tsx +++ b/server/sonar-web/src/main/js/app/components/Landing.tsx @@ -22,7 +22,7 @@ import * as PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { Location } from 'history'; import { CurrentUser, isLoggedIn } from '../types'; -import { getCurrentUser } from '../../store/rootReducer'; +import { getCurrentUser, Store } from '../../store/rootReducer'; import { getHomePageUrl } from '../../helpers/urls'; interface StateProps { @@ -57,8 +57,8 @@ class Landing extends React.PureComponent { } } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state) }); -export default connect(mapStateToProps)(Landing); +export default connect(mapStateToProps)(Landing); diff --git a/server/sonar-web/src/main/js/app/components/PageTracker.tsx b/server/sonar-web/src/main/js/app/components/PageTracker.tsx index a7699df640f..2ae8c85026b 100644 --- a/server/sonar-web/src/main/js/app/components/PageTracker.tsx +++ b/server/sonar-web/src/main/js/app/components/PageTracker.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import * as GoogleAnalytics from 'react-ga'; import { withRouter, WithRouterProps } from 'react-router'; import { connect } from 'react-redux'; -import { getGlobalSettingValue } from '../../store/rootReducer'; +import { getGlobalSettingValue, Store } from '../../store/rootReducer'; interface StateProps { trackingId?: string; @@ -59,8 +59,8 @@ export class PageTracker extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ trackingId: (getGlobalSettingValue(state, 'sonar.analytics.trackingId') || {}).value }); -export default withRouter<{}>(connect(mapStateToProps)(PageTracker)); +export default withRouter(connect(mapStateToProps)(PageTracker)); diff --git a/server/sonar-web/src/main/js/app/components/StartupModal.tsx b/server/sonar-web/src/main/js/app/components/StartupModal.tsx index 9383ec2539e..ee49e969d49 100644 --- a/server/sonar-web/src/main/js/app/components/StartupModal.tsx +++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx @@ -23,8 +23,8 @@ import { connect } from 'react-redux'; import { CurrentUser, isLoggedIn, Organization } from '../types'; import { differenceInDays, parseDate, toShortNotSoISOString } from '../../helpers/dates'; import { EditionKey } from '../../apps/marketplace/utils'; -import { getCurrentUser, getAppState } from '../../store/rootReducer'; -import { skipOnboarding as skipOnboardingAction } from '../../store/users/actions'; +import { getCurrentUser, getAppState, Store } from '../../store/rootReducer'; +import { skipOnboarding as skipOnboardingAction } from '../../store/users'; import { showLicense } from '../../api/marketplace'; import { hasMessage } from '../../helpers/l10n'; import { save, get } from '../../helpers/storage'; @@ -49,7 +49,7 @@ const TeamOnboardingModal = lazyLoad(() => ); interface StateProps { - canAdmin: boolean; + canAdmin?: boolean; currentEdition?: EditionKey; currentUser: CurrentUser; } @@ -215,7 +215,7 @@ export class StartupModal extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ canAdmin: getAppState(state).canAdmin, currentEdition: getAppState(state).edition, currentUser: getCurrentUser(state) @@ -223,7 +223,7 @@ const mapStateToProps = (state: any): StateProps => ({ const mapDispatchToProps: DispatchProps = { skipOnboardingAction }; -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(StartupModal); diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx b/server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx index e87e82bad4f..3037367c20e 100644 --- a/server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx +++ b/server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { fetchPrismicRefs, fetchPrismicNews, PrismicNews } from '../../../api/news'; -import { getGlobalSettingValue } from '../../../store/rootReducer'; +import { getGlobalSettingValue, Store } from '../../../store/rootReducer'; import DateFormatter from '../../../components/intl/DateFormatter'; import ChevronRightIcon from '../../../components/icons-components/ChevronRightcon'; import PlaceholderBar from '../../../components/ui/PlaceholderBar'; @@ -124,8 +124,8 @@ export class ProductNewsMenuItem extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ accessToken: (getGlobalSettingValue(state, 'sonar.prismic.accessToken') || {}).value }); -export default connect(mapStateToProps)(ProductNewsMenuItem); +export default connect(mapStateToProps)(ProductNewsMenuItem); diff --git a/server/sonar-web/src/main/js/app/components/extensions/ExtensionContainer.tsx b/server/sonar-web/src/main/js/app/components/extensions/ExtensionContainer.tsx index c3c56057669..a3e36e6c76a 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/ExtensionContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/extensions/ExtensionContainer.tsx @@ -19,16 +19,16 @@ */ import { connect } from 'react-redux'; import Extension from './Extension'; -import { getCurrentUser } from '../../../store/rootReducer'; -import { addGlobalErrorMessage } from '../../../store/globalMessages/duck'; +import { getCurrentUser, Store } from '../../../store/rootReducer'; +import { addGlobalErrorMessage } from '../../../store/globalMessages'; -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state) }); const mapDispatchToProps = { onFail: addGlobalErrorMessage }; -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(Extension); diff --git a/server/sonar-web/src/main/js/app/components/extensions/OrganizationPageExtension.tsx b/server/sonar-web/src/main/js/app/components/extensions/OrganizationPageExtension.tsx index c38e996c2a3..a12e39986cd 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/OrganizationPageExtension.tsx +++ b/server/sonar-web/src/main/js/app/components/extensions/OrganizationPageExtension.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import ExtensionContainer from './ExtensionContainer'; import NotFound from '../NotFound'; -import { getOrganizationByKey } from '../../../store/rootReducer'; +import { getOrganizationByKey, Store } from '../../../store/rootReducer'; import { fetchOrganization } from '../../../apps/organizations/actions'; import { Organization } from '../../types'; @@ -74,13 +74,13 @@ class OrganizationPageExtension extends React.PureComponent { } } -const mapStateToProps = (state: any, ownProps: OwnProps) => ({ +const mapStateToProps = (state: Store, ownProps: OwnProps) => ({ organization: getOrganizationByKey(state, ownProps.params.organizationKey) }); const mapDispatchToProps = { fetchOrganization }; -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(OrganizationPageExtension); 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 45c7a677a18..e39394c6d91 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 @@ -22,7 +22,7 @@ import React from 'react'; import { connect } from 'react-redux'; import ExtensionContainer from './ExtensionContainer'; import NotFound from '../NotFound'; -import { addGlobalErrorMessage } from '../../../store/globalMessages/duck'; +import { addGlobalErrorMessage } from '../../../store/globalMessages'; /*:: type Props = { diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavHeader.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavHeader.tsx index e616861f278..f32e3dfa308 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavHeader.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavHeader.tsx @@ -23,7 +23,11 @@ import { Link } from 'react-router'; import ComponentNavBranch from './ComponentNavBranch'; import { Component, Organization, BranchLike, Breadcrumb } from '../../../types'; import QualifierIcon from '../../../../components/icons-components/QualifierIcon'; -import { getOrganizationByKey, areThereCustomOrganizations } from '../../../../store/rootReducer'; +import { + getOrganizationByKey, + areThereCustomOrganizations, + Store +} from '../../../../store/rootReducer'; import OrganizationAvatar from '../../../../components/common/OrganizationAvatar'; import OrganizationHelmet from '../../../../components/common/OrganizationHelmet'; import OrganizationLink from '../../../../components/ui/OrganizationLink'; @@ -34,7 +38,7 @@ import { isSonarCloud } from '../../../../helpers/system'; interface StateProps { organization?: Organization; - shouldOrganizationBeDisplayed: boolean; + shouldOrganizationBeDisplayed?: boolean; } interface OwnProps { @@ -118,7 +122,7 @@ function renderBreadcrumbs(breadcrumbs: Breadcrumb[]) { }); } -const mapStateToProps = (state: any, ownProps: OwnProps): StateProps => ({ +const mapStateToProps = (state: Store, ownProps: OwnProps): StateProps => ({ organization: getOrganizationByKey(state, ownProps.component.organization), shouldOrganizationBeDisplayed: areThereCustomOrganizations(state) }); diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx index 7b2f2e2c221..51babd7921b 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx @@ -40,7 +40,7 @@ import { isPullRequest } from '../../../../helpers/branches'; import { translate } from '../../../../helpers/l10n'; -import { getCurrentUser } from '../../../../store/rootReducer'; +import { getCurrentUser, Store } from '../../../../store/rootReducer'; interface StateProps { currentUser: CurrentUser; @@ -121,7 +121,7 @@ function getCurrentPage(component: Component, branchLike: BranchLike | undefined return currentPage; } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ currentUser: getCurrentUser(state) }); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx index 81619581862..396050e4731 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx @@ -30,7 +30,7 @@ import * as theme from '../../../theme'; import { isLoggedIn, CurrentUser, AppState } from '../../../types'; import NavBar from '../../../../components/nav/NavBar'; import { lazyLoad } from '../../../../components/lazyLoad'; -import { getCurrentUser, getAppState } from '../../../../store/rootReducer'; +import { getCurrentUser, getAppState, Store } from '../../../../store/rootReducer'; import { SuggestionLink } from '../../embed-docs-modal/SuggestionsProvider'; import { isSonarCloud } from '../../../../helpers/system'; import './GlobalNav.css'; @@ -38,7 +38,7 @@ import './GlobalNav.css'; const GlobalNavPlus = lazyLoad(() => import('./GlobalNavPlus')); interface StateProps { - appState: AppState; + appState: Pick; currentUser: CurrentUser; } @@ -78,9 +78,9 @@ export class GlobalNav extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ currentUser: getCurrentUser(state), appState: getAppState(state) }); -export default connect(mapStateToProps)(GlobalNav); +export default connect(mapStateToProps)(GlobalNav); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.tsx index 7c0121ca23e..876a1ccc62f 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import { Link } from 'react-router'; import { connect } from 'react-redux'; -import { getGlobalSettingValue } from '../../../../store/rootReducer'; +import { getGlobalSettingValue, Store } from '../../../../store/rootReducer'; import { translate } from '../../../../helpers/l10n'; import { getBaseUrl } from '../../../../helpers/urls'; @@ -50,9 +50,9 @@ export function SonarCloudNavBranding() { ); } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ customLogoUrl: (getGlobalSettingValue(state, 'sonar.lf.logoUrl') || {}).value, customLogoWidth: (getGlobalSettingValue(state, 'sonar.lf.logoWidthPx') || {}).value }); -export default connect(mapStateToProps)(GlobalNavBranding); +export default connect(mapStateToProps)(GlobalNavBranding); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx index 6bb9590573a..8856840d3f1 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx @@ -29,7 +29,7 @@ import DropdownIcon from '../../../../components/icons-components/DropdownIcon'; import { isSonarCloud } from '../../../../helpers/system'; interface Props { - appState: AppState; + appState: Pick; currentUser: CurrentUser; location: { pathname: string }; } diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUserContainer.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUserContainer.tsx index e02817a046d..11f8f734dd7 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUserContainer.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUserContainer.tsx @@ -20,13 +20,13 @@ import { connect } from 'react-redux'; import GlobalNavUser from './GlobalNavUser'; import { Organization } from '../../../types'; -import { getMyOrganizations } from '../../../../store/rootReducer'; +import { getMyOrganizations, Store } from '../../../../store/rootReducer'; interface StateProps { organizations: Organization[]; } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ organizations: getMyOrganizations(state) }); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx index 17ed417200a..3410e31581f 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx @@ -24,7 +24,12 @@ import { isSonarCloud } from '../../../../../helpers/system'; jest.mock('../../../../../helpers/system', () => ({ isSonarCloud: jest.fn() })); -const appState = { qualifiers: [] }; +const appState: GlobalNav['props']['appState'] = { + globalPages: [], + canAdmin: false, + organizationsEnabled: false, + qualifiers: [] +}; const currentUser = { isLoggedIn: false }; const location = { pathname: '' }; diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap index 7f6362e4750..1ffdab8f252 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap @@ -10,6 +10,9 @@ exports[`should render for SonarCloud 1`] = ` ; currentUser: CurrentUser; } diff --git a/server/sonar-web/src/main/js/app/flow-types.js b/server/sonar-web/src/main/js/app/flow-types.js new file mode 100644 index 00000000000..7af83c05ca8 --- /dev/null +++ b/server/sonar-web/src/main/js/app/flow-types.js @@ -0,0 +1,33 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +// @flow +/*:: export type Metric = { + bestValue?: string, + custom?: boolean, + decimalScale?: number, + description?: string, + direction?: number, + domain?: string, + hidden?: boolean, + key: string, + name: string, + qualitative?: boolean, + type: string +}; */ diff --git a/server/sonar-web/src/main/js/app/types.ts b/server/sonar-web/src/main/js/app/types.ts index b39b6e62427..3918a750ed3 100644 --- a/server/sonar-web/src/main/js/app/types.ts +++ b/server/sonar-web/src/main/js/app/types.ts @@ -17,6 +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. */ +import { EditionKey } from '../apps/marketplace/utils'; + export type Omit = Pick>; // Type ordered alphabetically to prevent merge conflicts @@ -34,9 +36,14 @@ export interface AppState { authorizationError?: boolean; branchesEnabled?: boolean; canAdmin?: boolean; + defaultOrganization: string; + edition: EditionKey; globalPages?: Extension[]; organizationsEnabled?: boolean; + productionDatabase: boolean; qualifiers: string[]; + standalone?: boolean; + version: string; } export interface Branch { diff --git a/server/sonar-web/src/main/js/app/utils/addGlobalSuccessMessage.ts b/server/sonar-web/src/main/js/app/utils/addGlobalSuccessMessage.ts index 587316afa26..2e4b82d7dc3 100644 --- a/server/sonar-web/src/main/js/app/utils/addGlobalSuccessMessage.ts +++ b/server/sonar-web/src/main/js/app/utils/addGlobalSuccessMessage.ts @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import getStore from './getStore'; -import * as globalMessages from '../../store/globalMessages/duck'; +import * as globalMessages from '../../store/globalMessages'; export default function addGlobalSuccessMessage(message: string): void { const store = getStore(); diff --git a/server/sonar-web/src/main/js/app/utils/getStore.ts b/server/sonar-web/src/main/js/app/utils/getStore.ts index 477fc5a57b4..dc24f943b46 100644 --- a/server/sonar-web/src/main/js/app/utils/getStore.ts +++ b/server/sonar-web/src/main/js/app/utils/getStore.ts @@ -19,9 +19,9 @@ */ import { Store } from 'redux'; import { AppState, CurrentUser } from '../types'; -import { setAppState } from '../../store/appState/duck'; +import { setAppState } from '../../store/appState'; import rootReducer from '../../store/rootReducer'; -import { receiveCurrentUser } from '../../store/users/actions'; +import { receiveCurrentUser } from '../../store/users'; import configureStore from '../../store/utils/configureStore'; let store: Store; 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 c264596dcd0..eaa2cf81b75 100644 --- a/server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js +++ b/server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js @@ -20,7 +20,7 @@ // @flow import getStore from './getStore'; import getHistory from './getHistory'; -import { requireAuthorization } from '../../store/appState/duck'; +import { requireAuthorization } from '../../store/appState'; export default () => { const store = getStore(); diff --git a/server/sonar-web/src/main/js/app/utils/throwGlobalError.ts b/server/sonar-web/src/main/js/app/utils/throwGlobalError.ts index 4d12df06e77..264a3eaac88 100644 --- a/server/sonar-web/src/main/js/app/utils/throwGlobalError.ts +++ b/server/sonar-web/src/main/js/app/utils/throwGlobalError.ts @@ -18,10 +18,18 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import getStore from './getStore'; -import { onFail } from '../../store/rootActions'; +import { parseError } from '../../helpers/request'; +import { addGlobalErrorMessage } from '../../store/globalMessages'; -export default function throwGlobalError({ response }: { response: Response }): Promise { +export default function throwGlobalError(error: { response: Response }): Promise { const store = getStore(); - onFail(store.dispatch)({ response }); - return Promise.reject(response); + + // eslint-disable-next-line promise/no-promise-in-callback + parseError(error) + .then(message => { + store.dispatch(addGlobalErrorMessage(message)); + }) + .catch(() => {}); + + return Promise.reject(error.response); } diff --git a/server/sonar-web/src/main/js/apps/about/sonarcloud/SonarCloudPage.tsx b/server/sonar-web/src/main/js/apps/about/sonarcloud/SonarCloudPage.tsx index 84b4a99ade7..04e14901929 100644 --- a/server/sonar-web/src/main/js/apps/about/sonarcloud/SonarCloudPage.tsx +++ b/server/sonar-web/src/main/js/apps/about/sonarcloud/SonarCloudPage.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { withRouter, WithRouterProps } from 'react-router'; import Footer from './Footer'; -import { getCurrentUser, getMyOrganizations } from '../../../store/rootReducer'; +import { getCurrentUser, getMyOrganizations, Store } from '../../../store/rootReducer'; import { CurrentUser, Organization } from '../../../app/types'; import GlobalContainer from '../../../app/components/GlobalContainer'; @@ -57,11 +57,9 @@ class SonarCloudPage extends React.Component { } } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state), userOrganizations: getMyOrganizations(state) }); -export default withRouter( - connect(mapStateToProps)(SonarCloudPage) -); +export default withRouter(connect(mapStateToProps)(SonarCloudPage)); diff --git a/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.tsx b/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.tsx index c3768ee5e5c..60d47789043 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.tsx +++ b/server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.tsx @@ -24,14 +24,19 @@ import OrganizationsList from './OrganizationsList'; import CreateOrganizationForm from './CreateOrganizationForm'; import { fetchIfAnyoneCanCreateOrganizations } from './actions'; import { translate } from '../../../helpers/l10n'; -import { getAppState, getMyOrganizations, getGlobalSettingValue } from '../../../store/rootReducer'; +import { + getAppState, + getMyOrganizations, + getGlobalSettingValue, + Store +} from '../../../store/rootReducer'; import { Organization } from '../../../app/types'; import { Button } from '../../../components/ui/buttons'; interface StateProps { anyoneCanCreate?: { value: string }; - canAdmin: boolean; - organizations: Array; + canAdmin?: boolean; + organizations: Organization[]; } interface DispatchProps { @@ -110,7 +115,7 @@ class UserOrganizations extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ anyoneCanCreate: getGlobalSettingValue(state, 'sonar.organizations.anyoneCanCreate'), canAdmin: getAppState(state).canAdmin, organizations: getMyOrganizations(state) diff --git a/server/sonar-web/src/main/js/apps/account/organizations/actions.ts b/server/sonar-web/src/main/js/apps/account/organizations/actions.ts index 4361e0d0849..7c6e29f7990 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/actions.ts +++ b/server/sonar-web/src/main/js/apps/account/organizations/actions.ts @@ -19,17 +19,18 @@ */ import { Dispatch } from 'redux'; import { getOrganizations } from '../../../api/organizations'; -import { receiveMyOrganizations } from '../../../store/organizations/duck'; +import { receiveMyOrganizations } from '../../../store/organizations'; import { getValues } from '../../../api/settings'; import { receiveValues } from '../../settings/store/values/actions'; +import { Store } from '../../../store/rootReducer'; -export const fetchMyOrganizations = () => (dispatch: Dispatch) => { +export const fetchMyOrganizations = () => (dispatch: Dispatch) => { return getOrganizations({ member: true }).then(({ organizations }) => { return dispatch(receiveMyOrganizations(organizations)); }); }; -export const fetchIfAnyoneCanCreateOrganizations = () => (dispatch: Dispatch) => { +export const fetchIfAnyoneCanCreateOrganizations = () => (dispatch: Dispatch) => { return getValues({ keys: 'sonar.organizations.anyoneCanCreate' }).then(values => { dispatch(receiveValues(values, undefined)); }); diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/StatsContainer.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/StatsContainer.tsx index 09a9d8153ef..f4ab2473ec5 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/components/StatsContainer.tsx +++ b/server/sonar-web/src/main/js/apps/background-tasks/components/StatsContainer.tsx @@ -19,9 +19,9 @@ */ import { connect } from 'react-redux'; import Stats from './Stats'; -import { getAppState } from '../../../store/rootReducer'; +import { getAppState, Store } from '../../../store/rootReducer'; -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ isSystemAdmin: !!getAppState(state).canAdmin }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx index 8e17a963e70..685d0583940 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx @@ -51,7 +51,7 @@ import FiltersHeader from '../../../components/common/FiltersHeader'; import SearchBox from '../../../components/controls/SearchBox'; import { searchRules, getRulesApp } from '../../../api/rules'; import { searchQualityProfiles, Profile } from '../../../api/quality-profiles'; -import { getCurrentUser, getMyOrganizations } from '../../../store/rootReducer'; +import { getCurrentUser, getMyOrganizations, Store } from '../../../store/rootReducer'; import { translate } from '../../../helpers/l10n'; import { RawQuery } from '../../../helpers/query'; import { scrollToElement } from '../../../helpers/scrolling'; @@ -634,9 +634,9 @@ function parseFacets(rawFacets: { property: string; values: { count: number; val return facets; } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state), userOrganizations: getMyOrganizations(state) }); -export default withRouter(connect(mapStateToProps)(App)); +export default withRouter(connect(mapStateToProps)(App)); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/LanguageFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/LanguageFacet.tsx index 5f0a4132697..252db202d06 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/LanguageFacet.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/LanguageFacet.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { uniqBy } from 'lodash'; import { BasicProps } from './Facet'; -import { getLanguages } from '../../../store/rootReducer'; +import { getLanguages, Store } from '../../../store/rootReducer'; import ListStyleFacet from '../../../components/facet/ListStyleFacet'; import { translate } from '../../../helpers/l10n'; import { highlightTerm } from '../../../helpers/search'; @@ -92,7 +92,7 @@ class LanguageFacet extends React.PureComponent { } } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ installedLanguages: Object.values(getLanguages(state)) }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx index a32e7293c26..238aea7a35b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import Facet, { BasicProps } from './Facet'; -import { getLanguages } from '../../../store/rootReducer'; +import { getLanguages, Store } from '../../../store/rootReducer'; interface StateProps { referencedLanguages: { [language: string]: { key: string; name: string } }; @@ -69,7 +69,7 @@ class RepositoryFacet extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ referencedLanguages: getLanguages(state) }); diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/App.js b/server/sonar-web/src/main/js/apps/component-measures/components/App.js index a9e552dc77d..f866fd0dd60 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/App.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/App.js @@ -36,7 +36,7 @@ import { import { getDisplayMetrics } from '../../../helpers/measures'; /*:: import type { Component, Query, Period } from '../types'; */ /*:: import type { RawQuery } from '../../../helpers/query'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ /*:: import type { MeasureEnhanced } from '../../../components/measure/types'; */ import '../../../components/search-navigator.css'; import '../style.css'; diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js index a16978f8c5d..c39214fba0b 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js @@ -31,7 +31,7 @@ import { getMeasureHistoryUrl } from '../../../helpers/urls'; import { isDiffMetric } from '../../../helpers/measures'; /*:: import type { Component, Period } from '../types'; */ /*:: import type { MeasureEnhanced } from '../../../components/measure/types'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ /*:: type Props = {| branchLike?: { id?: string; name: string }, diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverview.js b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverview.js index 83e59016ccb..495626eaede 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverview.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverview.js @@ -30,7 +30,7 @@ import { enhanceComponent, getBubbleMetrics, isFileType } from '../utils'; import { getBranchLikeQuery } from '../../../helpers/branches'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; /*:: import type { Component, ComponentEnhanced, Paging, Period } from '../types'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ /*:: type Props = {| branchLike?: { id?: string; name: string }, diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverviewContainer.js b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverviewContainer.js index 141cb9839db..db4caed4947 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverviewContainer.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverviewContainer.js @@ -26,7 +26,7 @@ import { isViewType } from '../utils'; import { getBranchLikeQuery } from '../../../helpers/branches'; /*:: import type { Component, Period, Query } from '../types'; */ /*:: import type { RawQuery } from '../../../helpers/query'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ /*:: type Props = {| branchLike?: { id?: string; name: string }, diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js b/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js index 9031eacd7af..7a6fe3264ed 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js @@ -33,7 +33,7 @@ import { import { getBubbleMetrics, getBubbleYDomain, isProjectOverview } from '../utils'; import { RATING_COLORS } from '../../../helpers/constants'; /*:: import type { Component, ComponentEnhanced } from '../types'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ const HEIGHT = 500; diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.js b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.js index fc268fa3425..6ec4749855e 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.js +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.js @@ -32,7 +32,7 @@ import { } from '../../../helpers/urls'; import { translate } from '../../../helpers/l10n'; /*:: import type { Component, ComponentEnhanced } from '../types'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ /*:: type Props = { branchLike?: { id?: string; name: string }, diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.js b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.js index 891bd5b5747..49024fe6f07 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.js +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.js @@ -23,7 +23,7 @@ import classNames from 'classnames'; import ComponentCell from './ComponentCell'; import MeasureCell from './MeasureCell'; /*:: import type { Component, ComponentEnhanced } from '../types'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ /*:: type Props = {| branchLike?: { id?: string; name: string }, diff --git a/server/sonar-web/src/main/js/apps/component-measures/drilldown/MeasureCell.js b/server/sonar-web/src/main/js/apps/component-measures/drilldown/MeasureCell.js index da55b93966d..8a984c5001f 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/drilldown/MeasureCell.js +++ b/server/sonar-web/src/main/js/apps/component-measures/drilldown/MeasureCell.js @@ -23,7 +23,7 @@ import Measure from '../../../components/measure/Measure'; import { isDiffMetric } from '../../../helpers/measures'; /*:: import type { ComponentEnhanced } from '../types'; */ /*:: import type { MeasureEnhanced } from '../../../components/measure/types'; */ -/*:: import type { Metric } from '../../../store/metrics/actions'; */ +/*:: import type { Metric } from '../../../app/flow-types'; */ /*:: type Props = { component: ComponentEnhanced, diff --git a/server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx b/server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx index b5c65fd6ed5..ed8f05fec88 100644 --- a/server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx +++ b/server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx @@ -22,7 +22,7 @@ import { connect } from 'react-redux'; import AppContainer from './components/AppContainer'; import { CurrentUser, isLoggedIn } from '../../app/types'; import { RawQuery } from '../../helpers/query'; -import { getCurrentUser } from '../../store/rootReducer'; +import { getCurrentUser, Store } from '../../store/rootReducer'; import { isSonarCloud } from '../../helpers/system'; interface StateProps { @@ -38,8 +38,8 @@ function IssuesPage({ currentUser, location }: Props) { return ; } -const stateToProps = (state: any) => ({ +const stateToProps = (state: Store) => ({ currentUser: getCurrentUser(state) }); -export default connect(stateToProps)(IssuesPage); +export default connect(stateToProps)(IssuesPage); diff --git a/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx b/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx index a2c5a09d56a..929acb305c0 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx @@ -27,24 +27,25 @@ import throwGlobalError from '../../../app/utils/throwGlobalError'; import { getCurrentUser, areThereCustomOrganizations, - getMyOrganizations + getMyOrganizations, + Store } from '../../../store/rootReducer'; import { lazyLoad } from '../../../components/lazyLoad'; import { parseIssueFromResponse } from '../../../helpers/issues'; import { RawQuery } from '../../../helpers/query'; -import { receiveOrganizations } from '../../../store/organizations/duck'; +import { receiveOrganizations } from '../../../store/organizations'; interface StateProps { currentUser: CurrentUser; userOrganizations: Organization[]; } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ currentUser: getCurrentUser(state), userOrganizations: getMyOrganizations(state) }); -const fetchIssueOrganizations = (organizationKeys: string[]) => (dispatch: Dispatch) => { +const fetchIssueOrganizations = (organizationKeys: string[]) => (dispatch: Dispatch) => { if (!organizationKeys.length) { return Promise.resolve(); } @@ -58,7 +59,7 @@ const fetchIssueOrganizations = (organizationKeys: string[]) => (dispatch: Dispa const fetchIssues = (query: RawQuery, requestOrganizations = true) => ( // use `Function` to be able to do `dispatch(...).then(...)` dispatch: Function, - getState: () => any + getState: () => Store ) => { const organizationsEnabled = areThereCustomOrganizations(getState()); return searchIssues({ ...query, additionalFields: '_all' }) @@ -87,13 +88,7 @@ interface DispatchProps { // have to type cast this, because of async action const mapDispatchToProps = { fetchIssues: fetchIssues as any } as DispatchProps; -interface OwnProps { - location: { pathname: string; query: RawQuery }; - hideAuthorFacet?: boolean; - myIssues?: boolean; -} - -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(lazyLoad(() => import('./App'))); diff --git a/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx b/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx index b5d2fb47474..2dca1a25952 100644 --- a/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx +++ b/server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx @@ -22,7 +22,7 @@ import { uniqBy, omit } from 'lodash'; import { connect } from 'react-redux'; import ListStyleFacet from '../../../components/facet/ListStyleFacet'; import { Query, ReferencedLanguage, Facet } from '../utils'; -import { getLanguages } from '../../../store/rootReducer'; +import { getLanguages, Store } from '../../../store/rootReducer'; import { translate } from '../../../helpers/l10n'; import { highlightTerm } from '../../../helpers/search'; @@ -107,7 +107,7 @@ class LanguageFacet extends React.PureComponent { } } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ installedLanguages: Object.values(getLanguages(state)) }); diff --git a/server/sonar-web/src/main/js/apps/marketplace/App.tsx b/server/sonar-web/src/main/js/apps/marketplace/App.tsx index 394c96e750e..2233c8542e1 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/App.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/App.tsx @@ -45,7 +45,7 @@ export interface Props { fetchPendingPlugins: () => void; location: { pathname: string; query: RawQuery }; pendingPlugins: PluginPendingResult; - standaloneMode: boolean; + standaloneMode?: boolean; updateCenterActive: boolean; } diff --git a/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx b/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx index c68c26b11c9..76627ae77bd 100644 --- a/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx +++ b/server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import App from './App'; import { EditionKey } from './utils'; -import { getAppState, getGlobalSettingValue } from '../../store/rootReducer'; +import { getAppState, getGlobalSettingValue, Store } from '../../store/rootReducer'; import { RawQuery } from '../../helpers/query'; import MarketplaceContext from '../../app/components/MarketplaceContext'; @@ -31,11 +31,11 @@ interface OwnProps { interface StateToProps { currentEdition?: EditionKey; - standaloneMode: boolean; + standaloneMode?: boolean; updateCenterActive: boolean; } -const mapStateToProps = (state: any) => { +const mapStateToProps = (state: Store) => { return { currentEdition: getAppState(state).edition, standaloneMode: getAppState(state).standalone, @@ -52,4 +52,4 @@ const WithMarketplaceContext = (props: StateToProps & OwnProps) => ( ); -export default connect(mapStateToProps)(WithMarketplaceContext); +export default connect(mapStateToProps)(WithMarketplaceContext); diff --git a/server/sonar-web/src/main/js/apps/organizationMembers/OrganizationMembersContainer.tsx b/server/sonar-web/src/main/js/apps/organizationMembers/OrganizationMembersContainer.tsx index 6f13da8a3c2..c2b0821b83e 100644 --- a/server/sonar-web/src/main/js/apps/organizationMembers/OrganizationMembersContainer.tsx +++ b/server/sonar-web/src/main/js/apps/organizationMembers/OrganizationMembersContainer.tsx @@ -20,7 +20,7 @@ import { connect } from 'react-redux'; import OrganizationMembers from './OrganizationMembers'; import { Organization } from '../../app/types'; -import { getOrganizationByKey } from '../../store/rootReducer'; +import { getOrganizationByKey, Store } from '../../store/rootReducer'; interface OwnProps { params: { organizationKey: string }; @@ -30,11 +30,8 @@ interface StateProps { organization: Organization; } -const mapStateToProps = (state: any, ownProps: OwnProps): StateProps => { - const { organizationKey } = ownProps.params; - return { - organization: getOrganizationByKey(state, organizationKey)! - }; +const mapStateToProps = (state: Store, ownProps: OwnProps): StateProps => { + return { organization: getOrganizationByKey(state, ownProps.params.organizationKey) }; }; -export default connect(mapStateToProps)(OrganizationMembers); +export default connect(mapStateToProps)(OrganizationMembers); diff --git a/server/sonar-web/src/main/js/apps/organizations/actions.ts b/server/sonar-web/src/main/js/apps/organizations/actions.ts index ee00b6b3147..682774ff3fa 100644 --- a/server/sonar-web/src/main/js/apps/organizations/actions.ts +++ b/server/sonar-web/src/main/js/apps/organizations/actions.ts @@ -19,51 +19,47 @@ */ import { Dispatch } from 'redux'; import * as api from '../../api/organizations'; -import * as actions from '../../store/organizations/duck'; -import { onFail } from '../../store/rootActions'; -import { addGlobalSuccessMessage } from '../../store/globalMessages/duck'; +import * as actions from '../../store/organizations'; +import { addGlobalSuccessMessage } from '../../store/globalMessages'; import { translate, translateWithParameters } from '../../helpers/l10n'; import { Organization, OrganizationBase } from '../../app/types'; +import { Store } from '../../store/rootReducer'; -const onRejected = (dispatch: Dispatch) => (error: any) => { - onFail(dispatch)(error); - return Promise.reject(error); -}; - -export const fetchOrganization = (key: string) => (dispatch: Dispatch) => { +export const fetchOrganization = (key: string) => (dispatch: Dispatch) => { return Promise.all([api.getOrganization(key), api.getOrganizationNavigation(key)]).then( ([organization, navigation]) => { if (organization) { const organizationWithPermissions = { ...organization, ...navigation }; dispatch(actions.receiveOrganizations([organizationWithPermissions])); } - }, - onFail(dispatch) + } ); }; -export const createOrganization = (organization: OrganizationBase) => (dispatch: Dispatch) => { +export const createOrganization = (organization: OrganizationBase) => ( + dispatch: Dispatch +) => { return api.createOrganization(organization).then((organization: Organization) => { dispatch(actions.createOrganization(organization)); dispatch( addGlobalSuccessMessage(translateWithParameters('organization.created', organization.name)) ); return organization; - }, onRejected(dispatch)); + }); }; export const updateOrganization = (key: string, changes: OrganizationBase) => ( - dispatch: Dispatch + dispatch: Dispatch ) => { return api.updateOrganization(key, changes).then(() => { dispatch(actions.updateOrganization(key, changes)); dispatch(addGlobalSuccessMessage(translate('organization.updated'))); - }, onFail(dispatch)); + }); }; -export const deleteOrganization = (key: string) => (dispatch: Dispatch) => { +export const deleteOrganization = (key: string) => (dispatch: Dispatch) => { return api.deleteOrganization(key).then(() => { dispatch(actions.deleteOrganization(key)); dispatch(addGlobalSuccessMessage(translate('organization.deleted'))); - }, onFail(dispatch)); + }); }; diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAccessContainer.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAccessContainer.tsx index 53941adef8a..e1b30839a39 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAccessContainer.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationAccessContainer.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { RouterState } from 'react-router'; -import { getCurrentUser, getOrganizationByKey } from '../../../store/rootReducer'; +import { getCurrentUser, getOrganizationByKey, Store } from '../../../store/rootReducer'; import handleRequiredAuthorization from '../../../app/utils/handleRequiredAuthorization'; import { Organization, CurrentUser, isLoggedIn } from '../../../app/types'; @@ -63,14 +63,12 @@ export class OrganizationAccess extends React.PureComponent { } } -const mapStateToProps = (state: any, ownProps: OwnProps) => ({ +const mapStateToProps = (state: Store, ownProps: OwnProps) => ({ currentUser: getCurrentUser(state), organization: getOrganizationByKey(state, ownProps.params.organizationKey) }); -const OrganizationAccessContainer = connect(mapStateToProps)( - OrganizationAccess -); +const OrganizationAccessContainer = connect(mapStateToProps)(OrganizationAccess); export function hasAdminAccess({ currentUser, diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.tsx index 08d359b25a8..baadb3fd4cd 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { RouterState } from 'react-router'; -import { getCurrentUser, getOrganizationByKey } from '../../../store/rootReducer'; +import { getCurrentUser, getOrganizationByKey, Store } from '../../../store/rootReducer'; import { Organization, CurrentUser } from '../../../app/types'; interface StateToProps { @@ -44,9 +44,9 @@ class OrganizationContainer extends React.PureComponent { } } -const mapStateToProps = (state: any, ownProps: OwnProps) => ({ +const mapStateToProps = (state: Store, ownProps: OwnProps) => ({ organization: getOrganizationByKey(state, ownProps.params.organizationKey), currentUser: getCurrentUser(state) }); -export default connect(mapStateToProps)(OrganizationContainer); +export default connect(mapStateToProps)(OrganizationContainer); diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx index c1aac8ef5d6..b3b7eb5711b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx @@ -128,7 +128,7 @@ export class OrganizationDelete extends React.PureComponent { const mapDispatchToProps: DispatchToProps = { deleteOrganization: deleteOrganization as any }; -export default connect( +export default connect( null, mapDispatchToProps )(OrganizationDelete); diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.tsx index a81cbe614d3..fa0bb5ca7f2 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.tsx @@ -197,7 +197,7 @@ export class OrganizationEdit extends React.PureComponent { const mapDispatchToProps = { updateOrganization: updateOrganization as any }; -export default connect<{}, DispatchProps, OwnProps>( +export default connect( null, mapDispatchToProps )(OrganizationEdit); diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.tsx index 41981090047..a4581693d1b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.tsx @@ -28,7 +28,8 @@ import { Organization, CurrentUser } from '../../../app/types'; import { getOrganizationByKey, getCurrentUser, - getMyOrganizations + getMyOrganizations, + Store } from '../../../store/rootReducer'; interface OwnProps { @@ -110,7 +111,7 @@ export class OrganizationPage extends React.PureComponent { } } -const mapStateToProps = (state: any, ownProps: OwnProps) => ({ +const mapStateToProps = (state: Store, ownProps: OwnProps) => ({ currentUser: getCurrentUser(state), organization: getOrganizationByKey(state, ownProps.params.organizationKey), userOrganizations: getMyOrganizations(state) @@ -118,7 +119,7 @@ const mapStateToProps = (state: any, ownProps: OwnProps) => ({ const mapDispatchToProps = { fetchOrganization: fetchOrganization as any }; -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(OrganizationPage); diff --git a/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.tsx b/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.tsx index 4ec2c2a2132..4dabbca6786 100644 --- a/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.tsx @@ -20,7 +20,7 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { withRouter, WithRouterProps } from 'react-router'; -import { areThereCustomOrganizations } from '../../store/rootReducer'; +import { areThereCustomOrganizations, Store } from '../../store/rootReducer'; type ReactComponent

= React.ComponentClass

| React.StatelessComponent

; @@ -44,7 +44,7 @@ export default function forSingleOrganization

(ComposedComponent: ReactCompone } } - const mapStateToProps = (state: any) => ({ + const mapStateToProps = (state: Store) => ({ customOrganizations: areThereCustomOrganizations(state) }); diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationHeaderContainer.tsx b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationHeaderContainer.tsx index 88b71f90e41..fb6b23e087b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationHeaderContainer.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationHeaderContainer.tsx @@ -20,13 +20,13 @@ import { connect } from 'react-redux'; import OrganizationNavigationHeader from './OrganizationNavigationHeader'; import { Organization } from '../../../app/types'; -import { getMyOrganizations } from '../../../store/rootReducer'; +import { getMyOrganizations, Store } from '../../../store/rootReducer'; interface StateProps { organizations: Organization[]; } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ organizations: getMyOrganizations(state) }); diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationMenuContainer.tsx b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationMenuContainer.tsx index 07ee53cd586..518a2a86c52 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationMenuContainer.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationMenuContainer.tsx @@ -27,7 +27,7 @@ import NavBarTabs from '../../../components/nav/NavBarTabs'; import { translate } from '../../../helpers/l10n'; import { getQualityGatesUrl } from '../../../helpers/urls'; import { hasPrivateAccess, isCurrentUserMemberOf } from '../../../helpers/organizations'; -import { getCurrentUser, getMyOrganizations } from '../../../store/rootReducer'; +import { getCurrentUser, getMyOrganizations, Store } from '../../../store/rootReducer'; interface StateToProps { currentUser: CurrentUser; @@ -99,9 +99,9 @@ export function OrganizationNavigationMenu({ ); } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state), userOrganizations: getMyOrganizations(state) }); -export default connect(mapStateToProps)(OrganizationNavigationMenu); +export default connect(mapStateToProps)(OrganizationNavigationMenu); diff --git a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx index dc61e0ef7a8..3f6982b4696 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx @@ -47,7 +47,7 @@ import { isLongLivingBranch } from '../../../helpers/branches'; import { fetchMetrics } from '../../../store/rootActions'; -import { getMetrics } from '../../../store/rootReducer'; +import { getMetrics, Store } from '../../../store/rootReducer'; import { BranchLike, Component, Metric, MeasureEnhanced } from '../../../app/types'; import { translate } from '../../../helpers/l10n'; import '../styles.css'; @@ -262,11 +262,11 @@ export class OverviewApp extends React.PureComponent { const mapDispatchToProps: DispatchToProps = { fetchMetrics }; -const mapStateToProps = (state: any): StateToProps => ({ +const mapStateToProps = (state: Store): StateToProps => ({ metrics: getMetrics(state) }); -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(OverviewApp); diff --git a/server/sonar-web/src/main/js/apps/overview/components/SonarCloudEmptyOverview.tsx b/server/sonar-web/src/main/js/apps/overview/components/SonarCloudEmptyOverview.tsx index 53dace6236e..5cf37a984c5 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/SonarCloudEmptyOverview.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/SonarCloudEmptyOverview.tsx @@ -25,7 +25,7 @@ import MetaContainer from '../meta/MetaContainer'; import { BranchLike, Component, CurrentUser, isLoggedIn } from '../../../app/types'; import { isLongLivingBranch, isBranch, isMainBranch } from '../../../helpers/branches'; import { translate } from '../../../helpers/l10n'; -import { getCurrentUser } from '../../../store/rootReducer'; +import { getCurrentUser, Store } from '../../../store/rootReducer'; import '../../../app/styles/sonarcloud.css'; interface OwnProps { @@ -119,8 +119,8 @@ export function WarningMessage({ ); } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state) }); -export default connect(mapStateToProps)(SonarCloudEmptyOverview); +export default connect(mapStateToProps)(SonarCloudEmptyOverview); diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaContainer.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaContainer.tsx index cd93c3a9fbd..e6aba6d12c2 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaContainer.tsx +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaContainer.tsx @@ -44,7 +44,8 @@ import { hasPrivateAccess } from '../../../helpers/organizations'; import { getCurrentUser, getMyOrganizations, - getOrganizationByKey + getOrganizationByKey, + Store } from '../../../store/rootReducer'; import PrivacyBadgeContainer from '../../../components/common/PrivacyBadgeContainer'; @@ -170,10 +171,10 @@ export class Meta extends React.PureComponent { } } -const mapStateToProps = (state: any, { component }: OwnProps) => ({ +const mapStateToProps = (state: Store, { component }: OwnProps) => ({ currentUser: getCurrentUser(state), organization: getOrganizationByKey(state, component.organization), userOrganizations: getMyOrganizations(state) }); -export default connect(mapStateToProps)(Meta); +export default connect(mapStateToProps)(Meta); diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx index a4628b8fa6e..eb8f8fc45f0 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx @@ -25,7 +25,7 @@ import Tooltip from '../../../components/controls/Tooltip'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getQualityProfileUrl } from '../../../helpers/urls'; import { searchRules } from '../../../api/rules'; -import { getLanguages } from '../../../store/rootReducer'; +import { getLanguages, Store } from '../../../store/rootReducer'; import { ComponentQualityProfile } from '../../../app/types'; interface StateProps { @@ -147,8 +147,8 @@ class MetaQualityProfiles extends React.PureComponent ({ +const mapStateToProps = (state: Store) => ({ languages: getLanguages(state) }); -export default connect(mapStateToProps)(MetaQualityProfiles); +export default connect(mapStateToProps)(MetaQualityProfiles); diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx index 4fdc6e23ebf..8ef1bc6c4a8 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx +++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx @@ -67,7 +67,7 @@ export default class MetaSize extends React.PureComponent { const className = this.props.component.qualifier === 'TRK' ? 'overview-meta-size-lang-dist' : 'big-spacer-top'; - return languageDistribution ? ( + return languageDistribution && languageDistribution.value !== undefined ? (

diff --git a/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersListContainer.tsx b/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersListContainer.tsx index 40067a021cb..66203598154 100644 --- a/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersListContainer.tsx +++ b/server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersListContainer.tsx @@ -17,6 +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. */ +import { Dispatch } from 'redux'; import { connect } from 'react-redux'; import AllHoldersList from './AllHoldersList'; import { @@ -34,35 +35,16 @@ import { getPermissionsAppGroups, getPermissionsAppQuery, getPermissionsAppFilter, - getPermissionsAppSelectedPermission + getPermissionsAppSelectedPermission, + Store } from '../../../../store/rootReducer'; import { Organization } from '../../../../app/types'; -import { PermissionUser, PermissionGroup } from '../../../../api/permissions'; interface OwnProps { organization?: Organization; } -interface StateToProps { - filter: string; - groups: PermissionGroup[]; - query: string; - selectedPermission?: string; - users: PermissionUser[]; -} - -interface DispatchToProps { - grantPermissionToGroup: (groupName: string, permission: string) => Promise; - grantPermissionToUser: (login: string, permission: string) => Promise; - loadHolders: () => void; - onFilter: (filter: string) => void; - onSearch: (query: string) => void; - onSelectPermission: (permission: string) => void; - revokePermissionFromGroup: (groupName: string, permission: string) => Promise; - revokePermissionFromUser: (login: string, permission: string) => Promise; -} - -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ filter: getPermissionsAppFilter(state), groups: getPermissionsAppGroups(state), query: getPermissionsAppQuery(state), @@ -70,7 +52,7 @@ const mapStateToProps = (state: any) => ({ users: getPermissionsAppUsers(state) }); -const mapDispatchToProps = (dispatch: Function, ownProps: OwnProps) => { +const mapDispatchToProps = (dispatch: Dispatch, ownProps: OwnProps) => { const organizationKey = ownProps.organization ? ownProps.organization.key : undefined; return { grantPermissionToGroup: (groupName: string, permission: string) => @@ -89,7 +71,7 @@ const mapDispatchToProps = (dispatch: Function, ownProps: OwnProps) => { }; }; -export default connect( +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 c39d78e3d30..28f20e3ef74 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 @@ -45,8 +45,7 @@ export type Props = {| qualifier: string, visibility: string }, - onComponentChange: (changes: {}) => void, - onRequestFail: Object => void + onComponentChange: (changes: {}) => void |}; */ @@ -208,7 +207,6 @@ export default class App extends React.PureComponent { loading: false, groups: this.removePermissionFromGroup(group, permission) }); - this.props.onRequestFail(error); } }); } @@ -231,7 +229,6 @@ export default class App extends React.PureComponent { loading: false, users: this.removePermissionFromUser(user, permission) }); - this.props.onRequestFail(error); } }); } @@ -254,7 +251,6 @@ export default class App extends React.PureComponent { loading: false, groups: this.addPermissionToGroup(group, permission) }); - this.props.onRequestFail(error); } }); } @@ -277,7 +273,6 @@ export default class App extends React.PureComponent { loading: false, users: this.addPermissionToUser(user, permission) }); - this.props.onRequestFail(error); } }); } diff --git a/server/sonar-web/src/main/js/apps/permissions/project/components/AppContainer.js b/server/sonar-web/src/main/js/apps/permissions/project/components/AppContainer.js index b95e406649f..2dcc1210a03 100644 --- a/server/sonar-web/src/main/js/apps/permissions/project/components/AppContainer.js +++ b/server/sonar-web/src/main/js/apps/permissions/project/components/AppContainer.js @@ -19,18 +19,10 @@ */ import { connect } from 'react-redux'; import App from './App'; -import { onFail } from '../../../../store/rootActions'; import { getCurrentUser } from '../../../../store/rootReducer'; const mapStateToProps = state => ({ currentUser: getCurrentUser(state) }); -const mapDispatchToProps = dispatch => ({ - onRequestFail: onFail(dispatch) -}); - -export default connect( - mapStateToProps, - mapDispatchToProps -)(App); +export default connect(mapStateToProps)(App); diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.tsx b/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.tsx index c28badc0fb3..cd2f3c0e89e 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.tsx +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.tsx @@ -19,7 +19,7 @@ */ import * as React from 'react'; import { connect } from 'react-redux'; -import { getPermissionsAppError } from '../../../../store/rootReducer'; +import { getPermissionsAppError, Store } from '../../../../store/rootReducer'; interface Props { message: string; @@ -33,7 +33,7 @@ function PageError({ message }: Props) { return
{message}
; } -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ message: getPermissionsAppError(state) }); diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx index e12f6f7edc1..b5bef871e77 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/portfolio/components/App.tsx @@ -33,7 +33,7 @@ import { getMeasures } from '../../../api/measures'; import { getChildren } from '../../../api/components'; import { translate } from '../../../helpers/l10n'; import { fetchMetrics } from '../../../store/rootActions'; -import { getMetrics } from '../../../store/rootReducer'; +import { getMetrics, Store } from '../../../store/rootReducer'; import { Metric, Component } from '../../../app/types'; import '../styles.css'; import PrivacyBadgeContainer from '../../../components/common/PrivacyBadgeContainer'; @@ -220,11 +220,11 @@ export class App extends React.PureComponent { const mapDispatchToProps: DispatchToProps = { fetchMetrics }; -const mapStateToProps = (state: any): StateToProps => ({ +const mapStateToProps = (state: Store): StateToProps => ({ metrics: getMetrics(state) }); -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(App); diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/Subscription.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/Subscription.tsx index e15edf3ad7c..79558f42221 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/Subscription.tsx +++ b/server/sonar-web/src/main/js/apps/portfolio/components/Subscription.tsx @@ -22,10 +22,11 @@ import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessI import { ReportStatus, subscribe, unsubscribe } from '../../../api/report'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { Button } from '../../../components/ui/buttons'; +import { CurrentUser, isLoggedIn } from '../../../app/types'; interface Props { component: string; - currentUser: { email?: string }; + currentUser: CurrentUser; status: ReportStatus; } @@ -116,7 +117,7 @@ export default class Subscription extends React.PureComponent { ); render() { - const hasEmail = !!this.props.currentUser.email; + const hasEmail = isLoggedIn(this.props.currentUser) && !!this.props.currentUser.email; const { subscribed } = this.state; let inner; diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/SubscriptionContainer.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/SubscriptionContainer.tsx index d863f9494b6..4076247a18f 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/SubscriptionContainer.tsx +++ b/server/sonar-web/src/main/js/apps/portfolio/components/SubscriptionContainer.tsx @@ -19,10 +19,10 @@ */ import { connect } from 'react-redux'; import Subscription from './Subscription'; -import { getCurrentUser } from '../../../store/rootReducer'; +import { getCurrentUser, Store } from '../../../store/rootReducer'; -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state) }); -export default connect(mapStateToProps)(Subscription); +export default connect(mapStateToProps)(Subscription); diff --git a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/Subscription-test.tsx b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/Subscription-test.tsx index da053905930..c5e364751bb 100644 --- a/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/Subscription-test.tsx +++ b/server/sonar-web/src/main/js/apps/portfolio/components/__tests__/Subscription-test.tsx @@ -41,7 +41,7 @@ const status = { subscribed: true }; -const currentUser = { email: 'foo@example.com' }; +const currentUser = { isLoggedIn: true, email: 'foo@example.com' }; beforeEach(() => { subscribe.mockClear(); @@ -68,7 +68,7 @@ it('renders when not subscribed', () => { it('renders when no email', () => { expect( - shallow() + shallow() ).toMatchSnapshot(); }); 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 9919f4b8604..827c7872c36 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 @@ -30,7 +30,7 @@ import { addGlobalErrorMessage, addGlobalSuccessMessage, closeAllGlobalMessages -} from '../../../store/globalMessages/duck'; +} from '../../../store/globalMessages'; import RecentHistory from '../../../app/components/RecentHistory'; class BulkUpdate extends React.PureComponent { 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 2d272a903ad..b16f0f396d8 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 @@ -32,7 +32,7 @@ import { addGlobalErrorMessage, addGlobalSuccessMessage, closeAllGlobalMessages -} from '../../../store/globalMessages/duck'; +} from '../../../store/globalMessages'; import RecentHistory from '../../../app/components/RecentHistory'; import { getProjectAdminProjectModules } from '../../../store/rootReducer'; diff --git a/server/sonar-web/src/main/js/apps/projectBranches/components/AppContainer.ts b/server/sonar-web/src/main/js/apps/projectBranches/components/AppContainer.ts index b6ee8558bae..6be51b99452 100644 --- a/server/sonar-web/src/main/js/apps/projectBranches/components/AppContainer.ts +++ b/server/sonar-web/src/main/js/apps/projectBranches/components/AppContainer.ts @@ -19,10 +19,10 @@ */ import { connect } from 'react-redux'; import App from './App'; -import { getAppState } from '../../../store/rootReducer'; +import { getAppState, Store } from '../../../store/rootReducer'; -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ canAdmin: getAppState(state).canAdmin }); -export default connect(mapStateToProps)(App); +export default connect(mapStateToProps)(App); diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx index 2bf13b590b5..cb7a50672a7 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx @@ -46,7 +46,7 @@ export interface Props { isFavorite: boolean; location: { pathname: string; query: RawQuery }; organization: Organization | undefined; - organizationsEnabled: boolean; + organizationsEnabled?: boolean; storageOptionsSuffix?: string; } diff --git a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx index cf7600a82b6..178c281bd33 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx @@ -18,28 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { connect } from 'react-redux'; -import { CurrentUser, Organization } from '../../../app/types'; import { lazyLoad } from '../../../components/lazyLoad'; -import { getCurrentUser, areThereCustomOrganizations } from '../../../store/rootReducer'; -import { RawQuery } from '../../../helpers/query'; +import { getCurrentUser, areThereCustomOrganizations, Store } from '../../../store/rootReducer'; -interface StateProps { - currentUser: CurrentUser; - organizationsEnabled: boolean; -} - -interface OwnProps { - isFavorite: boolean; - location: { pathname: string; query: RawQuery }; - organization: Organization | undefined; - storageOptionsSuffix?: string; -} - -const stateToProps = (state: any) => ({ +const stateToProps = (state: Store) => ({ currentUser: getCurrentUser(state), organizationsEnabled: areThereCustomOrganizations(state) }); -export default connect(stateToProps)( - lazyLoad(() => import('./AllProjects')) -); +export default connect(stateToProps)(lazyLoad(() => import('./AllProjects'))); diff --git a/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelectorContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelectorContainer.tsx index f9cacdeec53..f6a4309f37a 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelectorContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelectorContainer.tsx @@ -19,15 +19,10 @@ */ import { connect } from 'react-redux'; import DefaultPageSelector from './DefaultPageSelector'; -import { CurrentUser } from '../../../app/types'; -import { getCurrentUser } from '../../../store/rootReducer'; +import { getCurrentUser, Store } from '../../../store/rootReducer'; -interface StateProps { - currentUser: CurrentUser; -} - -const stateToProps = (state: any) => ({ +const stateToProps = (state: Store) => ({ currentUser: getCurrentUser(state) }); -export default connect(stateToProps)(DefaultPageSelector); +export default connect(stateToProps)(DefaultPageSelector); diff --git a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.tsx index a869603b9ba..b8f0a49b4a0 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.tsx @@ -19,9 +19,9 @@ */ import { connect } from 'react-redux'; import FavoriteFilter from './FavoriteFilter'; -import { getCurrentUser } from '../../../store/rootReducer'; +import { getCurrentUser, Store } from '../../../store/rootReducer'; -function mapStateToProps(state: any) { +function mapStateToProps(state: Store) { return { currentUser: getCurrentUser(state) }; } diff --git a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx index 271cf360e29..e7d683038c3 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx @@ -26,7 +26,7 @@ import DropdownIcon from '../../../components/icons-components/DropdownIcon'; import Dropdown from '../../../components/controls/Dropdown'; import OrganizationListItem from '../../../components/ui/OrganizationListItem'; import { Button } from '../../../components/ui/buttons'; -import { getMyOrganizations } from '../../../store/rootReducer'; +import { getMyOrganizations, Store } from '../../../store/rootReducer'; import { isSonarCloud } from '../../../helpers/system'; import { Organization } from '../../../app/types'; import { translate } from '../../../helpers/l10n'; @@ -95,7 +95,7 @@ export class NoFavoriteProjects extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ organizations: getMyOrganizations(state) }); diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.tsx b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.tsx index 8d0815a9eb4..1fd92c29037 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import { sortBy } from 'lodash'; import Tooltip from '../../../components/controls/Tooltip'; import { translate } from '../../../helpers/l10n'; -import { Languages } from '../../../store/languages/reducer'; +import { Languages } from '../../../store/languages'; interface Props { distribution?: string; diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguagesContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguagesContainer.tsx index 9e67998c03a..31e30c841d3 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguagesContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguagesContainer.tsx @@ -19,15 +19,10 @@ */ import { connect } from 'react-redux'; import ProjectCardLanguages from './ProjectCardLanguages'; -import { Languages } from '../../../store/languages/reducer'; -import { getLanguages } from '../../../store/rootReducer'; +import { getLanguages, Store } from '../../../store/rootReducer'; -interface StateProps { - languages: Languages; -} - -const stateToProps = (state: any) => ({ +const stateToProps = (state: Store) => ({ languages: getLanguages(state) }); -export default connect(stateToProps)(ProjectCardLanguages); +export default connect(stateToProps)(ProjectCardLanguages); diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganization.tsx b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganization.tsx index 3341a0a57fa..32b1a71864d 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganization.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganization.tsx @@ -22,7 +22,7 @@ import OrganizationLink from '../../../components/ui/OrganizationLink'; interface Props { organization?: { key: string; name: string }; - organizationsEnabled: boolean; + organizationsEnabled?: boolean; } export default function ProjectCardOrganization({ organization, organizationsEnabled }: Props) { diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganizationContainer.tsx b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganizationContainer.tsx index da7c8856be7..e637927e23d 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganizationContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganizationContainer.tsx @@ -19,14 +19,10 @@ */ import { connect } from 'react-redux'; import ProjectCardOrganization from './ProjectCardOrganization'; -import { areThereCustomOrganizations } from '../../../store/rootReducer'; +import { areThereCustomOrganizations, Store } from '../../../store/rootReducer'; -interface StateProps { - organizationsEnabled: boolean; -} - -const stateToProps = (state: any) => ({ +const stateToProps = (state: Store) => ({ organizationsEnabled: areThereCustomOrganizations(state) }); -export default connect(stateToProps)(ProjectCardOrganization); +export default connect(stateToProps)(ProjectCardOrganization); diff --git a/server/sonar-web/src/main/js/apps/projects/create/CreateProjectPage.tsx b/server/sonar-web/src/main/js/apps/projects/create/CreateProjectPage.tsx index 41a518401c7..7e27c4accff 100644 --- a/server/sonar-web/src/main/js/apps/projects/create/CreateProjectPage.tsx +++ b/server/sonar-web/src/main/js/apps/projects/create/CreateProjectPage.tsx @@ -28,9 +28,9 @@ import ManualProjectCreate from './ManualProjectCreate'; import { serializeQuery, Query, parseQuery } from './utils'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication'; -import { getCurrentUser } from '../../../store/rootReducer'; -import { addGlobalErrorMessage } from '../../../store/globalMessages/duck'; -import { skipOnboarding as skipOnboardingAction } from '../../../store/users/actions'; +import { getCurrentUser, Store } from '../../../store/rootReducer'; +import { addGlobalErrorMessage } from '../../../store/globalMessages'; +import { skipOnboarding as skipOnboardingAction } from '../../../store/users'; import { CurrentUser, IdentityProvider, isLoggedIn, LoggedInUser } from '../../../app/types'; import { skipOnboarding, getIdentityProviders } from '../../../api/users'; import { translate } from '../../../helpers/l10n'; @@ -212,13 +212,13 @@ export class CreateProjectPage extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ currentUser: getCurrentUser(state) }); const mapDispatchToProps: DispatchProps = { addGlobalErrorMessage, skipOnboardingAction }; -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(CreateProjectPage); diff --git a/server/sonar-web/src/main/js/apps/projects/create/ManualProjectCreate.tsx b/server/sonar-web/src/main/js/apps/projects/create/ManualProjectCreate.tsx index 299dc7676e0..f2e63f08650 100644 --- a/server/sonar-web/src/main/js/apps/projects/create/ManualProjectCreate.tsx +++ b/server/sonar-web/src/main/js/apps/projects/create/ManualProjectCreate.tsx @@ -25,7 +25,7 @@ import Select from '../../../components/controls/Select'; import { Button, SubmitButton } from '../../../components/ui/buttons'; import { LoggedInUser, Organization } from '../../../app/types'; import { fetchMyOrganizations } from '../../account/organizations/actions'; -import { getMyOrganizations } from '../../../store/rootReducer'; +import { getMyOrganizations, Store } from '../../../store/rootReducer'; import { translate } from '../../../helpers/l10n'; import { createProject } from '../../../api/components'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; @@ -217,12 +217,12 @@ const mapDispatchToProps = ({ fetchMyOrganizations } as any) as DispatchProps; -const mapStateToProps = (state: any): StateProps => { +const mapStateToProps = (state: Store): StateProps => { return { userOrganizations: getMyOrganizations(state) }; }; -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(ManualProjectCreate); diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx index ada03f39f0a..33229e381b7 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx @@ -23,7 +23,7 @@ import Filter from './Filter'; import FilterHeader from './FilterHeader'; import SearchableFilterFooter from './SearchableFilterFooter'; import SearchableFilterOption from './SearchableFilterOption'; -import { getLanguageByKey, Languages } from '../../../store/languages/reducer'; +import { getLanguageByKey, Languages } from '../../../store/languages'; import { translate } from '../../../helpers/l10n'; import { Facet } from '../types'; import { RawQuery } from '../../../helpers/query'; diff --git a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilterContainer.tsx b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilterContainer.tsx index 43d9eb3d6b2..2b5daab2df7 100644 --- a/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilterContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilterContainer.tsx @@ -19,15 +19,10 @@ */ import { connect } from 'react-redux'; import LanguagesFilter from './LanguagesFilter'; -import { Languages } from '../../../store/languages/reducer'; -import { getLanguages } from '../../../store/rootReducer'; +import { getLanguages, Store } from '../../../store/rootReducer'; -interface StateProps { - languages: Languages; -} - -const stateToProps = (state: any) => ({ +const stateToProps = (state: Store) => ({ languages: getLanguages(state) }); -export default connect(stateToProps)(LanguagesFilter); +export default connect(stateToProps)(LanguagesFilter); diff --git a/server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx b/server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx index 947b58fddde..f5c8c5e612a 100644 --- a/server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx +++ b/server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx @@ -29,7 +29,7 @@ import { Project } from '../types'; import { translate, translateWithParameters } from '../../../helpers/l10n'; interface Props { - displayOrganizations: boolean; + displayOrganizations?: boolean; projects: Project[]; sort?: string; total?: number; diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx b/server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx index 30f543f096d..b7ac3c91a5a 100644 --- a/server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx +++ b/server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx @@ -22,8 +22,8 @@ import { connect } from 'react-redux'; import App from './App'; import forSingleOrganization from '../organizations/forSingleOrganization'; import { Organization, LoggedInUser, Visibility } from '../../app/types'; -import { getAppState, getOrganizationByKey, getCurrentUser } from '../../store/rootReducer'; -import { receiveOrganizations } from '../../store/organizations/duck'; +import { getAppState, getOrganizationByKey, getCurrentUser, Store } from '../../store/rootReducer'; +import { receiveOrganizations } from '../../store/organizations'; import { changeProjectDefaultVisibility } from '../../api/permissions'; import { fetchOrganization } from '../organizations/actions'; @@ -40,6 +40,7 @@ interface DispatchProps { interface OwnProps { onRequestFail: (error: any) => void; + organization: Organization; } class AppContainer extends React.PureComponent { @@ -78,7 +79,7 @@ class AppContainer extends React.PureComponent ({ +const mapStateToProps = (state: Store, ownProps: OwnProps) => ({ appState: getAppState(state), currentUser: getCurrentUser(state) as LoggedInUser, organization: @@ -102,7 +103,7 @@ const mapDispatchToProps = (dispatch: Function) => ({ }); export default forSingleOrganization( - connect( + connect( mapStateToProps, mapDispatchToProps )(AppContainer) diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsApp.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsApp.tsx index d22d36f9c7d..d09415b9c64 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsApp.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsApp.tsx @@ -23,7 +23,7 @@ import Helmet from 'react-helmet'; import { connect } from 'react-redux'; import DetailsHeader from './DetailsHeader'; import DetailsContent from './DetailsContent'; -import { getMetrics } from '../../../store/rootReducer'; +import { getMetrics, Store } from '../../../store/rootReducer'; import { fetchMetrics } from '../../../store/rootActions'; import { fetchQualityGate } from '../../../api/quality-gates'; import { Metric, QualityGate, Condition } from '../../../app/types'; @@ -170,11 +170,11 @@ export class DetailsApp extends React.PureComponent { const mapDispatchToProps: DispatchToProps = { fetchMetrics }; -const mapStateToProps = (state: any): StateToProps => ({ +const mapStateToProps = (state: Store): StateToProps => ({ metrics: getMetrics(state) }); -export default connect( +export default connect( mapStateToProps, mapDispatchToProps )(DetailsApp); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx index 67697a9c4f8..5fa5abf6642 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx @@ -24,13 +24,12 @@ import { sortProfiles } from '../utils'; import { Exporter, Profile } from '../types'; import OrganizationHelmet from '../../../components/common/OrganizationHelmet'; import { translate } from '../../../helpers/l10n'; -import { Languages } from '../../../store/languages/reducer'; +import { Languages } from '../../../store/languages'; import '../styles.css'; interface Props { children: React.ReactElement; languages: Languages; - onRequestFail: (reasong: any) => void; organization: { name: string; key: string } | undefined; } @@ -103,7 +102,6 @@ export default class App extends React.PureComponent { languages: finalLanguages, exporters: this.state.exporters, updateProfiles: this.updateProfiles, - onRequestFail: this.props.onRequestFail, organization: organization ? organization.key : null }); } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx index 417c54699d6..525f5af615d 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx @@ -20,33 +20,13 @@ import { connect } from 'react-redux'; import App from './App'; import forSingleOrganization from '../../organizations/forSingleOrganization'; -import { getLanguages, getOrganizationByKey } from '../../../store/rootReducer'; -import { onFail } from '../../../store/rootActions'; -import { Languages } from '../../../store/languages/reducer'; +import { getLanguages, getOrganizationByKey, Store } from '../../../store/rootReducer'; -interface StateProps { - languages: Languages; - organization: { name: string; key: string } | undefined; -} - -interface DispatchProps { - onRequestFail: (reasong: any) => void; -} - -const mapStateToProps = (state: any, ownProps: any) => ({ +const mapStateToProps = (state: Store, ownProps: any) => ({ languages: getLanguages(state), organization: ownProps.params.organizationKey ? getOrganizationByKey(state, ownProps.params.organizationKey) : undefined }); -const mapDispatchToProps = (dispatch: any) => ({ - onRequestFail: (error: any) => onFail(dispatch)(error) -}); - -export default forSingleOrganization( - connect( - mapStateToProps, - mapDispatchToProps - )(App) -); +export default forSingleOrganization(connect(mapStateToProps)(App)); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx index 39cd96b4c88..d26262e3e47 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx @@ -27,7 +27,6 @@ import { translate, translateWithParameters } from '../../../helpers/l10n'; interface Props { onClose: () => void; onCopy: (name: string) => void; - onRequestFail: (reasong: any) => void; profile: Profile; } @@ -61,11 +60,10 @@ export default class CopyProfileForm extends React.PureComponent { this.setState({ loading: true }); copyProfile(this.props.profile.key, name).then( (profile: any) => this.props.onCopy(profile.name), - (error: any) => { + () => { if (this.mounted) { this.setState({ loading: false }); } - this.props.onRequestFail(error); } ); } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx index 39260d39eb7..941d82c311f 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx @@ -27,7 +27,6 @@ import { translate, translateWithParameters } from '../../../helpers/l10n'; interface Props { onClose: () => void; onDelete: () => void; - onRequestFail: (reason: any) => void; profile: Profile; } @@ -51,11 +50,10 @@ export default class DeleteProfileForm extends React.PureComponent handleFormSubmit = (event: React.SyntheticEvent) => { event.preventDefault(); this.setState({ loading: true }); - deleteProfile(this.props.profile.key).then(this.props.onDelete, (error: any) => { + deleteProfile(this.props.profile.key).then(this.props.onDelete, () => { if (this.mounted) { this.setState({ loading: false }); } - this.props.onRequestFail(error); }); }; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx index c4b3566803e..ac464d475c8 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx @@ -35,7 +35,6 @@ import ActionsDropdown, { interface Props { className?: string; fromList?: boolean; - onRequestFail: (reasong: any) => void; organization: string | null; profile: Profile; updateProfiles: () => Promise; @@ -198,7 +197,6 @@ export default class ProfileActions extends React.PureComponent { )} @@ -207,7 +205,6 @@ export default class ProfileActions extends React.PureComponent { )} @@ -216,7 +213,6 @@ export default class ProfileActions extends React.PureComponent { )} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx index 40294051be5..f8f1fdfacad 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx @@ -30,7 +30,6 @@ interface Props { pathname: string; query: { key?: string; language: string; name: string }; }; - onRequestFail: (reasong: any) => void; organization: string | null; profiles: Profile[]; updateProfiles: () => Promise; @@ -75,7 +74,6 @@ export default class ProfileContainer extends React.PureComponent void; onRename: (name: string) => void; - onRequestFail: (reason: any) => void; profile: Profile; } @@ -61,11 +60,10 @@ export default class RenameProfileForm extends React.PureComponent this.setState({ loading: true }); renameProfile(this.props.profile.key, name).then( () => this.props.onRename(name), - (error: any) => { + () => { if (this.mounted) { this.setState({ loading: false }); } - this.props.onRequestFail(error); } ); } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx index c407c0e64fe..6e12e93f278 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx @@ -40,14 +40,7 @@ const PROFILE = { it('renders with no permissions', () => { expect( - shallow( - - ) + shallow() ).toMatchSnapshot(); }); @@ -55,7 +48,6 @@ it('renders with permission to edit only', () => { expect( shallow( { expect( shallow( { const push = jest.fn(); const wrapper = shallow( { const output = shallow( { const output = shallow( { const output = shallow( void; onClose: () => void; - onRequestFail: (reasong: any) => void; profile: Profile; profiles: Profile[]; } @@ -67,11 +66,10 @@ export default class ChangeParentForm extends React.PureComponent this.setState({ loading: true }); changeProfileParent(this.props.profile.key, parent) .then(this.props.onChange) - .catch((error: any) => { + .catch(() => { if (this.mounted) { this.setState({ loading: false }); } - this.props.onRequestFail(error); }); } }; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx index 62cc3952052..7fa67e0b743 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx @@ -27,7 +27,6 @@ import { Exporter, Profile } from '../types'; interface Props { exporters: Exporter[]; - onRequestFail: (reasong: any) => void; organization: string | null; profile: Profile; profiles: Profile[]; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx index 2315bfcb57b..06dfba05ee2 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx @@ -33,7 +33,6 @@ import { import { Profile } from '../types'; interface Props { - onRequestFail: (reasong: any) => void; profile: Profile; organization: string | null; updateProfiles: () => Promise; @@ -111,7 +110,6 @@ export default class ProfileHeader extends React.PureComponent {
  • void; organization: string | null; profile: Profile; profiles: Profile[]; @@ -192,7 +191,6 @@ export default class ProfileInheritance extends React.PureComponent p !== profile && p.language === profile.language)} /> diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileDetails-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileDetails-test.tsx index ed4b88c7c34..38d2cb8e0d7 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileDetails-test.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileDetails-test.tsx @@ -27,7 +27,6 @@ it('renders without permissions', () => { shallow( { shallow( ; onClose: () => void; onCreate: Function; - onRequestFail: (reasong: any) => void; organization: string | null; } @@ -89,11 +88,10 @@ export default class CreateProfileForm extends React.PureComponent createQualityProfile(data).then( (response: any) => this.props.onCreate(response.profile), - (error: any) => { + () => { if (this.mounted) { this.setState({ loading: false }); } - this.props.onRequestFail(error); } ); }; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx index af78f87f44e..201eedb5164 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx @@ -28,7 +28,6 @@ interface Props { actions: Actions; languages: Array<{ key: string; name: string }>; location: { query: { [p: string]: string } }; - onRequestFail: (reason: any) => void; organization: string | null; profiles: Profile[]; updateProfiles: () => Promise; diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx index 4bfb1c02c77..d064cfb708c 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx @@ -31,7 +31,6 @@ import { translate } from '../../../helpers/l10n'; interface Props { actions: Actions; languages: Array<{ key: string; name: string }>; - onRequestFail: (reason: any) => void; organization: string | null; updateProfiles: () => Promise; } @@ -112,7 +111,6 @@ export default class PageHeader extends React.PureComponent { {this.state.restoreFormOpen && ( @@ -123,7 +121,6 @@ export default class PageHeader extends React.PureComponent { languages={this.props.languages} onClose={this.closeCreateForm} onCreate={this.handleCreate} - onRequestFail={this.props.onRequestFail} organization={this.props.organization} /> )} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx index 05faaa8ef8f..599c0f398d8 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx @@ -28,7 +28,6 @@ import { Profile } from '../types'; interface Props { languages: Array<{ key: string; name: string }>; location: { query: { [p: string]: string } }; - onRequestFail: (reason: any) => void; organization: string | null; profiles: Profile[]; updateProfiles: () => Promise; @@ -39,7 +38,6 @@ export default class ProfilesList extends React.PureComponent { return profiles.map(profile => ( void; organization: string | null; profile: Profile; updateProfiles: () => Promise; @@ -149,7 +148,6 @@ export default class ProfilesListRow extends React.PureComponent { void; - onRequestFail: (reason: any) => void; onRestore: () => void; organization: string | null; } @@ -71,11 +70,10 @@ export default class RestoreProfileForm extends React.PureComponent { + () => { if (this.mounted) { this.setState({ loading: false }); } - this.props.onRequestFail(error); } ); }; diff --git a/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx b/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx index ed4c7dacfe9..a51599f362c 100644 --- a/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx +++ b/server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx @@ -116,7 +116,7 @@ class LoginContainer extends React.PureComponent { const mapStateToProps = null; const mapDispatchToProps = { doLogin: doLogin as any }; -export default connect<{}, DispatchToProps, OwnProps>( +export default connect( mapStateToProps, mapDispatchToProps )(LoginContainer); 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 d4d1dddd806..34bdf549004 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 @@ -29,7 +29,7 @@ import { resetSettingValue } from '../../../api/settings'; import { parseError } from '../../../helpers/request'; -import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../store/globalMessages/duck'; +import { addGlobalErrorMessage, closeAllGlobalMessages } from '../../../store/globalMessages'; import { isEmptyValue } from '../utils'; import { translate } from '../../../helpers/l10n'; import { getSettingsAppDefinition, getSettingsAppChangedValue } from '../../../store/rootReducer'; 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 55ce9d6756d..f20e9e91c90 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 @@ -22,7 +22,7 @@ import { parseError } from '../../../../helpers/request'; import { addGlobalErrorMessage, closeAllGlobalMessages -} from '../../../../store/globalMessages/duck'; +} from '../../../../store/globalMessages'; export const UPDATE_ENCRYPTION = 'UPDATE_ENCRYPTION'; 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 13320969836..37f7f1ecd56 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 @@ -23,8 +23,8 @@ import definitions, * as fromDefinitions from './definitions/reducer'; import encryptionPage from './encryptionPage/reducer'; import values, * as fromValues from './values/reducer'; import settingsPage, * as fromSettingsPage from './settingsPage/reducer'; -import globalMessages, * as fromGlobalMessages from '../../../store/globalMessages/duck'; -/*:: import type { State as GlobalMessagesState } from '../../../store/globalMessages/duck'; */ +import globalMessages, * as fromGlobalMessages from '../../../store/globalMessages'; +/*:: import type { State as GlobalMessagesState } from '../../../store/globalMessages'; */ /*:: import type { State as ValuesState } from './values/reducer'; */ /*:: diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx index b8006ff3758..1ed6b84045e 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx @@ -27,7 +27,7 @@ import OnboardingTeamIcon from '../../../components/icons-components/OnboardingT import { Button, ResetButtonLink } from '../../../components/ui/buttons'; import { translate } from '../../../helpers/l10n'; import { CurrentUser, isLoggedIn } from '../../../app/types'; -import { getCurrentUser } from '../../../store/rootReducer'; +import { getCurrentUser, Store } from '../../../store/rootReducer'; import '../styles.css'; interface OwnProps { @@ -94,6 +94,6 @@ export class OnboardingModal extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ currentUser: getCurrentUser(state) }); +const mapStateToProps = (state: Store): StateProps => ({ currentUser: getCurrentUser(state) }); -export default connect(mapStateToProps)(OnboardingModal); +export default connect(mapStateToProps)(OnboardingModal); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx index cd5bc33f08c..2d6901b63c9 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx @@ -22,7 +22,7 @@ import * as PropTypes from 'prop-types'; import { connect } from 'react-redux'; import OnboardingModal from './OnboardingModal'; import { skipOnboarding } from '../../../api/users'; -import { skipOnboarding as skipOnboardingAction } from '../../../store/users/actions'; +import { skipOnboarding as skipOnboardingAction } from '../../../store/users'; import CreateOrganizationForm from '../../account/organizations/CreateOrganizationForm'; import TeamOnboardingModal from '../teamOnboarding/TeamOnboardingModal'; import { Organization } from '../../../app/types'; @@ -96,7 +96,7 @@ export class OnboardingPage extends React.PureComponent { const mapDispatchToProps: DispatchProps = { skipOnboardingAction }; -export default connect<{}, DispatchProps>( +export default connect( null, mapDispatchToProps )(OnboardingPage); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboarding.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboarding.tsx index e3511631aa4..9068fb81f94 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboarding.tsx +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboarding.tsx @@ -26,7 +26,7 @@ import ProjectAnalysisStep from '../components/ProjectAnalysisStep'; import OrganizationStep from '../components/OrganizationStep'; import TokenStep from '../components/TokenStep'; import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication'; -import { getCurrentUser, areThereCustomOrganizations } from '../../../store/rootReducer'; +import { getCurrentUser, areThereCustomOrganizations, Store } from '../../../store/rootReducer'; import { CurrentUser, isLoggedIn } from '../../../app/types'; import { ResetButtonLink } from '../../../components/ui/buttons'; import { getProjectUrl } from '../../../helpers/urls'; @@ -41,7 +41,7 @@ interface OwnProps { interface StateProps { currentUser: CurrentUser; - organizationsEnabled: boolean; + organizationsEnabled?: boolean; } type Props = OwnProps & StateProps; @@ -196,11 +196,11 @@ export class ProjectOnboarding extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => { +const mapStateToProps = (state: Store): StateProps => { return { currentUser: getCurrentUser(state), organizationsEnabled: areThereCustomOrganizations(state) }; }; -export default connect(mapStateToProps)(ProjectOnboarding); +export default connect(mapStateToProps)(ProjectOnboarding); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboardingPage.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboardingPage.tsx index e3e747805fc..d22ab7bcf52 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboardingPage.tsx +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboardingPage.tsx @@ -21,7 +21,7 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; import { connect } from 'react-redux'; import ProjectOnboardingModal from './ProjectOnboardingModal'; -import { skipOnboarding } from '../../../store/users/actions'; +import { skipOnboarding } from '../../../store/users'; interface DispatchProps { skipOnboarding: () => void; @@ -44,7 +44,7 @@ export class ProjectOnboardingPage extends React.PureComponent { const mapDispatchToProps: DispatchProps = { skipOnboarding }; -export default connect<{}, DispatchProps>( +export default connect( null, mapDispatchToProps )(ProjectOnboardingPage); diff --git a/server/sonar-web/src/main/js/apps/users/UsersApp.tsx b/server/sonar-web/src/main/js/apps/users/UsersApp.tsx index edefebb1086..9c898e36ad6 100644 --- a/server/sonar-web/src/main/js/apps/users/UsersApp.tsx +++ b/server/sonar-web/src/main/js/apps/users/UsersApp.tsx @@ -34,7 +34,7 @@ import { translate } from '../../helpers/l10n'; interface Props { currentUser: { isLoggedIn: boolean; login?: string }; location: Location; - organizationsEnabled: boolean; + organizationsEnabled?: boolean; } interface State { diff --git a/server/sonar-web/src/main/js/apps/users/UsersAppContainer.tsx b/server/sonar-web/src/main/js/apps/users/UsersAppContainer.tsx index 47fdd0afb3a..563ed0cfd21 100644 --- a/server/sonar-web/src/main/js/apps/users/UsersAppContainer.tsx +++ b/server/sonar-web/src/main/js/apps/users/UsersAppContainer.tsx @@ -18,22 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { connect } from 'react-redux'; -import { Location } from 'history'; import UsersApp from './UsersApp'; -import { areThereCustomOrganizations, getCurrentUser } from '../../store/rootReducer'; +import { areThereCustomOrganizations, getCurrentUser, Store } from '../../store/rootReducer'; -interface OwnProps { - location: Location; -} - -interface StateToProps { - currentUser: { isLoggedIn: boolean; login?: string }; - organizationsEnabled: boolean; -} - -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ currentUser: getCurrentUser(state), organizationsEnabled: areThereCustomOrganizations(state) }); -export default connect(mapStateToProps)(UsersApp); +export default connect(mapStateToProps)(UsersApp); diff --git a/server/sonar-web/src/main/js/apps/users/UsersList.tsx b/server/sonar-web/src/main/js/apps/users/UsersList.tsx index 8888af81c51..cb91c04a60a 100644 --- a/server/sonar-web/src/main/js/apps/users/UsersList.tsx +++ b/server/sonar-web/src/main/js/apps/users/UsersList.tsx @@ -26,7 +26,7 @@ interface Props { currentUser: { isLoggedIn: boolean; login?: string }; identityProviders: IdentityProvider[]; onUpdateUsers: () => void; - organizationsEnabled: boolean; + organizationsEnabled?: boolean; updateTokensCount: (login: string, tokensCount: number) => void; users: User[]; } diff --git a/server/sonar-web/src/main/js/apps/users/components/UserListItem.tsx b/server/sonar-web/src/main/js/apps/users/components/UserListItem.tsx index 33562848989..10d34f4a158 100644 --- a/server/sonar-web/src/main/js/apps/users/components/UserListItem.tsx +++ b/server/sonar-web/src/main/js/apps/users/components/UserListItem.tsx @@ -33,7 +33,7 @@ interface Props { identityProvider?: IdentityProvider; isCurrentUser: boolean; onUpdateUsers: () => void; - organizationsEnabled: boolean; + organizationsEnabled?: boolean; updateTokensCount: (login: string, tokensCount: number) => void; user: User; } diff --git a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.tsx b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.tsx index 457bc24c4ea..9c4fbe34a9a 100644 --- a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.tsx +++ b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.tsx @@ -18,16 +18,16 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { find, sortBy } from 'lodash'; +import { sortBy } from 'lodash'; import Histogram from './Histogram'; import { formatMeasure } from '../../helpers/measures'; -import { Language } from '../../api/languages'; import { translate } from '../../helpers/l10n'; +import { Languages } from '../../store/languages'; interface Props { alignTicks?: boolean; distribution: string; - languages?: Language[]; + languages: Languages; width: number; } @@ -61,7 +61,7 @@ export default function LanguageDistribution(props: Props) { if (langKey === '') { return translate('unknown'); } - const lang = find(props.languages, { key: langKey }); + const lang = props.languages[langKey]; return lang ? lang.name : langKey; } } diff --git a/server/sonar-web/src/main/js/components/charts/LanguageDistributionContainer.tsx b/server/sonar-web/src/main/js/components/charts/LanguageDistributionContainer.tsx index 9ef2039202e..abbf2a645b8 100644 --- a/server/sonar-web/src/main/js/components/charts/LanguageDistributionContainer.tsx +++ b/server/sonar-web/src/main/js/components/charts/LanguageDistributionContainer.tsx @@ -19,10 +19,10 @@ */ import { connect } from 'react-redux'; import LanguageDistribution from './LanguageDistribution'; -import { getLanguages } from '../../store/rootReducer'; +import { getLanguages, Store } from '../../store/rootReducer'; -const mapStateToProps = (state: any) => ({ +const mapStateToProps = (state: Store) => ({ languages: getLanguages(state) }); -export default connect(mapStateToProps)(LanguageDistribution); +export default connect(mapStateToProps)(LanguageDistribution); diff --git a/server/sonar-web/src/main/js/components/charts/__tests__/LanguageDistribution-test.tsx b/server/sonar-web/src/main/js/components/charts/__tests__/LanguageDistribution-test.tsx index 224244ca51c..bf544029f25 100644 --- a/server/sonar-web/src/main/js/components/charts/__tests__/LanguageDistribution-test.tsx +++ b/server/sonar-web/src/main/js/components/charts/__tests__/LanguageDistribution-test.tsx @@ -26,7 +26,7 @@ it('renders', () => { shallow( ) diff --git a/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx b/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx index 2c702af7c02..1a72a92c354 100644 --- a/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx +++ b/server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx @@ -26,7 +26,12 @@ import { translate } from '../../helpers/l10n'; import { Visibility, Organization, CurrentUser } from '../../app/types'; import { isSonarCloud } from '../../helpers/system'; import { isCurrentUserMemberOf, isPaidOrganization } from '../../helpers/organizations'; -import { getCurrentUser, getOrganizationByKey, getMyOrganizations } from '../../store/rootReducer'; +import { + getCurrentUser, + getOrganizationByKey, + getMyOrganizations, + Store +} from '../../store/rootReducer'; import VisibleIcon from '../icons-components/VisibleIcon'; import DocTooltip from '../docs/DocTooltip'; @@ -99,7 +104,7 @@ export function PrivacyBadge({ ); } -const mapStateToProps = (state: any, { organization }: OwnProps) => { +const mapStateToProps = (state: Store, { organization }: OwnProps) => { if (typeof organization === 'string') { organization = getOrganizationByKey(state, organization); } @@ -110,7 +115,7 @@ const mapStateToProps = (state: any, { organization }: OwnProps) => { }; }; -export default connect(mapStateToProps)(PrivacyBadge); +export default connect(mapStateToProps)(PrivacyBadge); function getDoc(visibility: Visibility, icon: JSX.Element | null, organization: Organization) { let doc; diff --git a/server/sonar-web/src/main/js/components/controls/HomePageSelect.tsx b/server/sonar-web/src/main/js/components/controls/HomePageSelect.tsx index d71cec022b5..5be1bbc5816 100644 --- a/server/sonar-web/src/main/js/components/controls/HomePageSelect.tsx +++ b/server/sonar-web/src/main/js/components/controls/HomePageSelect.tsx @@ -24,8 +24,8 @@ import Tooltip from './Tooltip'; import HomeIcon from '../icons-components/HomeIcon'; import { CurrentUser, isLoggedIn, HomePage, isSameHomePage } from '../../app/types'; import { translate } from '../../helpers/l10n'; -import { getCurrentUser } from '../../store/rootReducer'; -import { setHomePage } from '../../store/users/actions'; +import { getCurrentUser, Store } from '../../store/rootReducer'; +import { setHomePage } from '../../store/users'; interface StateProps { currentUser: CurrentUser; @@ -81,7 +81,7 @@ class HomePageSelect extends React.PureComponent { } } -const mapStateToProps = (state: any): StateProps => ({ +const mapStateToProps = (state: Store): StateProps => ({ currentUser: getCurrentUser(state) }); diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/HomePageSelect-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/HomePageSelect-test.tsx index 4d5af634c91..89803a78e97 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/HomePageSelect-test.tsx +++ b/server/sonar-web/src/main/js/components/controls/__tests__/HomePageSelect-test.tsx @@ -21,9 +21,9 @@ import * as React from 'react'; import { shallow } from 'enzyme'; import HomePageSelect from '../HomePageSelect'; import { setHomePage } from '../../../api/users'; -import { HomePageType, HomePage, LoggedInUser } from '../../../app/types'; +import { HomePageType, HomePage, LoggedInUser, CurrentUser } from '../../../app/types'; import { click } from '../../../helpers/testUtils'; -import rootReducer, { getCurrentUser } from '../../../store/rootReducer'; +import rootReducer, { getCurrentUser, Store } from '../../../store/rootReducer'; import configureStore from '../../../store/utils/configureStore'; jest.mock('../../../api/users', () => ({ @@ -33,29 +33,35 @@ jest.mock('../../../api/users', () => ({ const homepage: HomePage = { type: HomePageType.Projects }; it('should render unchecked', () => { - const store = configureStore(rootReducer, { users: { currentUser: { isLoggedIn: true } } }); + const store = configureStore(rootReducer, { + users: { currentUser: { isLoggedIn: true } } + } as Store); expect(getWrapper(homepage, store)).toMatchSnapshot(); }); it('should render checked', () => { const store = configureStore(rootReducer, { - users: { currentUser: { isLoggedIn: true, homepage } } - }); + users: { currentUser: { isLoggedIn: true, homepage } as CurrentUser } + } as Store); expect(getWrapper(homepage, store)).toMatchSnapshot(); }); it('should set new home page', async () => { - const store = configureStore(rootReducer, { users: { currentUser: { isLoggedIn: true } } }); + const store = configureStore(rootReducer, { + users: { currentUser: { isLoggedIn: true } } + } as Store); const wrapper = getWrapper(homepage, store); click(wrapper.find('a')); await new Promise(setImmediate); - const currentUser = getCurrentUser(store.getState()) as LoggedInUser; + const currentUser = getCurrentUser(store.getState() as Store) as LoggedInUser; expect(currentUser.homepage).toEqual(homepage); expect(setHomePage).toBeCalledWith(homepage); }); it('should not render for anonymous', () => { - const store = configureStore(rootReducer, { users: { currentUser: { isLoggedIn: false } } }); + const store = configureStore(rootReducer, { + users: { currentUser: { isLoggedIn: false } } + } as Store); expect(getWrapper(homepage, store).type()).toBeNull(); }); 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 0ea3dedee6e..3562a3c6bad 100644 --- a/server/sonar-web/src/main/js/components/issue/Issue.js +++ b/server/sonar-web/src/main/js/components/issue/Issue.js @@ -23,7 +23,6 @@ import key from 'keymaster'; import PropTypes from 'prop-types'; import IssueView from './IssueView'; import { updateIssue } from './actions'; -import { onFail } from '../../store/rootActions'; import { setIssueAssignee } from '../../api/issues'; /*:: import type { Issue as IssueType } from './types'; */ import './Issue.css'; @@ -135,19 +134,11 @@ export default class Issue extends React.PureComponent { handleAssignement = (login /*: string */) => { const { issue } = this.props; if (issue.assignee !== login) { - updateIssue( - this.props.onChange, - this.handleFail, - setIssueAssignee({ issue: issue.key, assignee: login }) - ); + updateIssue(this.props.onChange, setIssueAssignee({ issue: issue.key, assignee: login })); } this.togglePopup('assign', false); }; - handleFail = (error /*: Error */) => { - onFail(this.context.store.dispatch)(error); - }; - render() { return ( void, onCheck?: (issue: string, event: Event) => void, onClick: string => void, - onFail: Error => void, onFilter?: (property: string, issue: Issue) => void, selected: boolean, togglePopup: (string, boolean | void) => void @@ -64,11 +63,11 @@ export default class IssueView extends React.PureComponent { }; editComment = (comment /*: string */, text /*: string */) => { - updateIssue(this.props.onChange, this.props.onFail, editIssueComment({ comment, text })); + updateIssue(this.props.onChange, editIssueComment({ comment, text })); }; deleteComment = (comment /*: string */) => { - updateIssue(this.props.onChange, this.props.onFail, deleteIssueComment({ comment })); + updateIssue(this.props.onChange, deleteIssueComment({ comment })); }; render() { @@ -94,7 +93,6 @@ export default class IssueView extends React.PureComponent { displayLocationsCount={this.props.displayLocationsCount} displayLocationsLink={this.props.displayLocationsLink} issue={issue} - onFail={this.props.onFail} onFilter={this.props.onFilter} togglePopup={this.props.togglePopup} /> @@ -103,7 +101,6 @@ export default class IssueView extends React.PureComponent { issue={issue} onAssign={this.props.onAssign} onChange={this.props.onChange} - onFail={this.props.onFail} togglePopup={this.props.togglePopup} /> {issue.comments && diff --git a/server/sonar-web/src/main/js/components/issue/actions.js b/server/sonar-web/src/main/js/components/issue/actions.js index 4d3c4c06bd9..567b731c0bb 100644 --- a/server/sonar-web/src/main/js/components/issue/actions.js +++ b/server/sonar-web/src/main/js/components/issue/actions.js @@ -23,7 +23,6 @@ import { parseIssueFromResponse } from '../../helpers/issues'; export const updateIssue = ( onChange /*: Issue => void */, - onFail /*: Error => void */, resultPromise /*: Promise<*> */, oldIssue /*: ?Issue */, newIssue /*: ?Issue */ @@ -47,7 +46,6 @@ export const updateIssue = ( } }, error => { - onFail(error); if (optimisticUpdate) { // $FlowFixMe `oldIssue` is not null, because `optimisticUpdate` is true onChange(oldIssue); diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueActionsBar.js b/server/sonar-web/src/main/js/components/issue/components/IssueActionsBar.js index 0f12bf3a226..7167a3a87e2 100644 --- a/server/sonar-web/src/main/js/components/issue/components/IssueActionsBar.js +++ b/server/sonar-web/src/main/js/components/issue/components/IssueActionsBar.js @@ -36,7 +36,6 @@ type Props = { currentPopup: ?string, onAssign: string => void, onChange: Issue => void, - onFail: Error => void, togglePopup: (string, boolean | void) => void }; */ @@ -64,7 +63,6 @@ export default class IssueActionsBar extends React.PureComponent { const newIssue = { ...issue, [property]: value }; updateIssue( this.props.onChange, - this.props.onFail, apiCall({ issue: issue.key, [property]: value }), issue, newIssue @@ -127,7 +125,6 @@ export default class IssueActionsBar extends React.PureComponent { isOpen={this.props.currentPopup === 'transition' && hasTransitions} issue={issue} onChange={this.handleTransition} - onFail={this.props.onFail} togglePopup={this.props.togglePopup} />
  • @@ -138,7 +135,6 @@ export default class IssueActionsBar extends React.PureComponent { isOpen={this.props.currentPopup === 'assign' && canAssign} issue={issue} onAssign={this.props.onAssign} - onFail={this.props.onFail} togglePopup={this.props.togglePopup} /> @@ -157,7 +153,6 @@ export default class IssueActionsBar extends React.PureComponent { currentPopup={this.props.currentPopup} issueKey={issue.key} onChange={this.props.onChange} - onFail={this.props.onFail} toggleComment={this.toggleComment} /> )} @@ -169,7 +164,6 @@ export default class IssueActionsBar extends React.PureComponent { isOpen={this.props.currentPopup === 'edit-tags' && canSetTags} issue={issue} onChange={this.props.onChange} - onFail={this.props.onFail} togglePopup={this.props.togglePopup} /> diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js b/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js index 0eb7f114d70..355b0effbdc 100644 --- a/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js +++ b/server/sonar-web/src/main/js/components/issue/components/IssueAssign.js @@ -33,7 +33,6 @@ type Props = { issue: Issue, canAssign: boolean, onAssign: string => void, - onFail: Error => void, togglePopup: (string, boolean | void) => void }; */ @@ -78,13 +77,7 @@ export default class IssueAssign extends React.PureComponent { closeOnEscape={true} onRequestClose={this.handleClose} open={this.props.isOpen && this.props.canAssign} - overlay={ - - }> + overlay={}>