aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2018-09-03 09:21:22 +0200
committerSonarTech <sonartech@sonarsource.com>2018-09-03 20:20:51 +0200
commitf6fd6fb056ca6c3de3637cfeafb53c30815ee12d (patch)
treebdf6b3a660066ffe6aaf644f6969e4353a7e21c8 /server/sonar-web/src/main/js
parentf332f24ea986de3267aedcc9ba8ec1441ff4226b (diff)
downloadsonarqube-f6fd6fb056ca6c3de3637cfeafb53c30815ee12d.tar.gz
sonarqube-f6fd6fb056ca6c3de3637cfeafb53c30815ee12d.zip
finish typing redux store and simplify connected components (#675)
Diffstat (limited to 'server/sonar-web/src/main/js')
-rw-r--r--server/sonar-web/src/main/js/api/issues.ts2
-rw-r--r--server/sonar-web/src/main/js/api/languages.ts3
-rw-r--r--server/sonar-web/src/main/js/api/organizations.ts13
-rw-r--r--server/sonar-web/src/main/js/api/permissions.ts16
-rw-r--r--server/sonar-web/src/main/js/api/quality-profiles.ts22
-rw-r--r--server/sonar-web/src/main/js/app/components/AdminContainer.tsx8
-rw-r--r--server/sonar-web/src/main/js/app/components/App.tsx4
-rw-r--r--server/sonar-web/src/main/js/app/components/ComponentContainer.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/GlobalFooterContainer.tsx10
-rw-r--r--server/sonar-web/src/main/js/app/components/GlobalMessagesContainer.tsx6
-rw-r--r--server/sonar-web/src/main/js/app/components/Landing.tsx6
-rw-r--r--server/sonar-web/src/main/js/app/components/PageTracker.tsx6
-rw-r--r--server/sonar-web/src/main/js/app/components/StartupModal.tsx10
-rw-r--r--server/sonar-web/src/main/js/app/components/embed-docs-modal/ProductNewsMenuItem.tsx6
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/ExtensionContainer.tsx8
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/OrganizationPageExtension.tsx6
-rw-r--r--server/sonar-web/src/main/js/app/components/extensions/ProjectAdminPageExtension.js2
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNavHeader.tsx10
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMeta.tsx4
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx8
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNavBranding.tsx6
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNavMenu.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNavUserContainer.tsx4
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNav-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/__tests__/__snapshots__/GlobalNav-test.tsx.snap18
-rw-r--r--server/sonar-web/src/main/js/app/components/search/Search.d.ts2
-rw-r--r--server/sonar-web/src/main/js/app/flow-types.js (renamed from server/sonar-web/src/main/js/store/metrics/actions.js)7
-rw-r--r--server/sonar-web/src/main/js/app/types.ts7
-rw-r--r--server/sonar-web/src/main/js/app/utils/addGlobalSuccessMessage.ts2
-rw-r--r--server/sonar-web/src/main/js/app/utils/getStore.ts4
-rw-r--r--server/sonar-web/src/main/js/app/utils/handleRequiredAuthorization.js2
-rw-r--r--server/sonar-web/src/main/js/app/utils/throwGlobalError.ts16
-rw-r--r--server/sonar-web/src/main/js/apps/about/sonarcloud/SonarCloudPage.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/account/organizations/UserOrganizations.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/account/organizations/actions.ts7
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/components/StatsContainer.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/App.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/LanguageFacet.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/coding-rules/components/RepositoryFacet.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/App.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverview.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/MeasureOverviewContainer.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentCell.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/drilldown/ComponentsListRow.js2
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/drilldown/MeasureCell.js2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/IssuesPageSelector.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/AppContainer.tsx19
-rw-r--r--server/sonar-web/src/main/js/apps/issues/sidebar/LanguageFacet.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/App.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/marketplace/AppContainer.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/organizationMembers/OrganizationMembersContainer.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/actions.ts30
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/OrganizationAccessContainer.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/OrganizationContainer.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/OrganizationEdit.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/forSingleOrganization.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationHeaderContainer.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationMenuContainer.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/SonarCloudEmptyOverview.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaContainer.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaQualityProfiles.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaSize.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/permissions/global/components/AllHoldersListContainer.tsx30
-rw-r--r--server/sonar-web/src/main/js/apps/permissions/project/components/App.js7
-rw-r--r--server/sonar-web/src/main/js/apps/permissions/project/components/AppContainer.js10
-rw-r--r--server/sonar-web/src/main/js/apps/permissions/shared/components/PageError.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/portfolio/components/App.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/portfolio/components/Subscription.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/portfolio/components/SubscriptionContainer.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/portfolio/components/__tests__/Subscription-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/BulkUpdate.js2
-rw-r--r--server/sonar-web/src/main/js/apps/project-admin/key/Key.js2
-rw-r--r--server/sonar-web/src/main/js/apps/projectBranches/components/AppContainer.ts6
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/AllProjects.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/AllProjectsContainer.tsx22
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/DefaultPageSelectorContainer.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/FavoriteFilterContainer.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguages.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectCardLanguagesContainer.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganization.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectCardOrganizationContainer.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/projects/create/CreateProjectPage.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/projects/create/ManualProjectCreate.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilter.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projects/filters/LanguagesFilterContainer.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/projects/visualizations/Visualizations.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projectsManagement/AppContainer.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DetailsApp.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/App.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/AppContainer.tsx26
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/CopyProfileForm.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/DeleteProfileForm.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileActions.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/ProfileContainer.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileActions-test.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileDetails.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/ProfileDetails-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileDetails-test.tsx.snap8
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/HomeContainer.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/PageHeader.tsx3
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/sessions/components/LoginContainer.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/store/actions.js2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/store/encryptionPage/actions.js2
-rw-r--r--server/sonar-web/src/main/js/apps/settings/store/rootReducer.js4
-rw-r--r--server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboarding.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/ProjectOnboardingPage.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/users/UsersApp.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/users/UsersAppContainer.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/users/UsersList.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/UserListItem.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/charts/LanguageDistribution.tsx8
-rw-r--r--server/sonar-web/src/main/js/components/charts/LanguageDistributionContainer.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/charts/__tests__/LanguageDistribution-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/common/PrivacyBadgeContainer.tsx11
-rw-r--r--server/sonar-web/src/main/js/components/controls/HomePageSelect.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/HomePageSelect-test.tsx22
-rw-r--r--server/sonar-web/src/main/js/components/issue/Issue.js12
-rw-r--r--server/sonar-web/src/main/js/components/issue/IssueView.js7
-rw-r--r--server/sonar-web/src/main/js/components/issue/actions.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueActionsBar.js6
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueAssign.js9
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js5
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js7
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueTags.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js3
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/IssueTransition.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js1
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js3
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js3
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTitleBar-test.js9
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap2
-rw-r--r--server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap3
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js14
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js8
-rw-r--r--server/sonar-web/src/main/js/components/issue/popups/__tests__/ChangelogPopup-test.js1
-rw-r--r--server/sonar-web/src/main/js/components/measure/types.js2
-rw-r--r--server/sonar-web/src/main/js/components/shared/Organization.tsx8
-rw-r--r--server/sonar-web/src/main/js/components/ui/Avatar.tsx4
-rw-r--r--server/sonar-web/src/main/js/store/__tests__/__snapshots__/organizations-test.ts.snap97
-rw-r--r--server/sonar-web/src/main/js/store/__tests__/organizations-test.ts103
-rw-r--r--server/sonar-web/src/main/js/store/appState.ts (renamed from server/sonar-web/src/main/js/store/appState/duck.ts)40
-rw-r--r--server/sonar-web/src/main/js/store/globalMessages.ts102
-rw-r--r--server/sonar-web/src/main/js/store/globalMessages/duck.js131
-rw-r--r--server/sonar-web/src/main/js/store/languages.ts (renamed from server/sonar-web/src/main/js/store/languages/reducer.ts)24
-rw-r--r--server/sonar-web/src/main/js/store/metrics.ts (renamed from server/sonar-web/src/main/js/store/metrics/reducer.js)36
-rw-r--r--server/sonar-web/src/main/js/store/organizations.ts116
-rw-r--r--server/sonar-web/src/main/js/store/organizations/__tests__/__snapshots__/duck-test.ts.snap43
-rw-r--r--server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.ts61
-rw-r--r--server/sonar-web/src/main/js/store/organizations/duck.ts199
-rw-r--r--server/sonar-web/src/main/js/store/rootActions.js67
-rw-r--r--server/sonar-web/src/main/js/store/rootActions.ts76
-rw-r--r--server/sonar-web/src/main/js/store/rootReducer.js114
-rw-r--r--server/sonar-web/src/main/js/store/rootReducer.ts166
-rw-r--r--server/sonar-web/src/main/js/store/users.ts105
-rw-r--r--server/sonar-web/src/main/js/store/users/actions.ts49
-rw-r--r--server/sonar-web/src/main/js/store/users/reducer.ts71
-rw-r--r--server/sonar-web/src/main/js/store/utils/actions.ts (renamed from server/sonar-web/src/main/js/store/languages/actions.js)9
-rw-r--r--server/sonar-web/src/main/js/store/utils/configureStore.ts (renamed from server/sonar-web/src/main/js/store/utils/configureStore.js)8
178 files changed, 1221 insertions, 1356 deletions
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<any> {
- 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<Language[]> {
- 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<Organization | undefined> {
@@ -48,18 +48,21 @@ interface GetOrganizationNavigation {
}
export function getOrganizationNavigation(key: string): Promise<GetOrganizationNavigation> {
- 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<Organization> {
return postJSON('/api/organizations/create', data).then(r => r.organization, throwGlobalError);
}
-export function updateOrganization(key: string, changes: OrganizationBase): Promise<void> {
- 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<void | Response> {
+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<void> {
+) {
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<void> {
+) {
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<void> {
+) {
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<void> {
+) {
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<any> {
.setData(data)
.submit()
.then(checkStatus)
- .then(parseJSON);
+ .then(parseJSON)
+ .catch(throwGlobalError);
}
export function restoreQualityProfile(data: RequestData): Promise<any> {
@@ -104,7 +105,8 @@ export function restoreQualityProfile(data: RequestData): Promise<any> {
.setData(data)
.submit()
.then(checkStatus)
- .then(parseJSON);
+ .then(parseJSON)
+ .catch(throwGlobalError);
}
export interface ProfileProject {
@@ -128,20 +130,22 @@ export function setDefaultProfile(profileKey: string): Promise<void> {
return post('/api/qualityprofiles/set_default', { profileKey });
}
-export function renameProfile(key: string, name: string): Promise<void> {
- 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<any> {
- return postJSON('/api/qualityprofiles/copy', { fromKey, toName });
+ return postJSON('/api/qualityprofiles/copy', { fromKey, toName }).catch(throwGlobalError);
}
-export function deleteProfile(profileKey: string): Promise<void> {
- 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<void> {
- 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<Props, State> {
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
appState: getAppState(state)
});
@@ -129,7 +129,7 @@ const mapDispatchToProps: DispatchToProps = {
setAdminPages
};
-export default connect<StateProps, DispatchToProps, OwnProps>(
+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<Props> {
}
}
-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<Props, State> {
const mapDispatchToProps = { fetchOrganizations };
-export default connect<any, any, any>(
+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<StateProps, {}, OwnProps>(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<StateProps & OwnProps> {
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
currentUser: getCurrentUser(state)
});
-export default connect<StateProps, {}, OwnProps>(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<Props> {
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
trackingId: (getGlobalSettingValue(state, 'sonar.analytics.trackingId') || {}).value
});
-export default withRouter<{}>(connect<StateProps>(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<Props, State> {
}
}
-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<StateProps, DispatchProps, OwnProps>(
+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<Props, State> {
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
accessToken: (getGlobalSettingValue(state, 'sonar.prismic.accessToken') || {}).value
});
-export default connect<StateProps, {}, OwnProps>(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<any, any, any>(
+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<Props> {
}
}
-const mapStateToProps = (state: any, ownProps: OwnProps) => ({
+const mapStateToProps = (state: Store, ownProps: OwnProps) => ({
organization: getOrganizationByKey(state, ownProps.params.organizationKey)
});
const mapDispatchToProps = { fetchOrganization };
-export default connect<StateToProps, DispatchProps, OwnProps>(
+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<AppState, 'canAdmin' | 'globalPages' | 'organizationsEnabled' | 'qualifiers'>;
currentUser: CurrentUser;
}
@@ -78,9 +78,9 @@ export class GlobalNav extends React.PureComponent<Props> {
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
currentUser: getCurrentUser(state),
appState: getAppState(state)
});
-export default connect<StateProps, {}, OwnProps>(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<StateProps>(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<AppState, 'canAdmin' | 'globalPages' | 'organizationsEnabled' | 'qualifiers'>;
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`] = `
<GlobalNavMenu
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
@@ -47,6 +50,9 @@ exports[`should render for SonarCloud 1`] = `
<Search
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
@@ -59,6 +65,9 @@ exports[`should render for SonarCloud 1`] = `
<Connect(GlobalNavUser)
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
@@ -88,6 +97,9 @@ exports[`should render for SonarQube 1`] = `
<GlobalNavMenu
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
@@ -118,6 +130,9 @@ exports[`should render for SonarQube 1`] = `
<Search
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
@@ -130,6 +145,9 @@ exports[`should render for SonarQube 1`] = `
<Connect(GlobalNavUser)
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
diff --git a/server/sonar-web/src/main/js/app/components/search/Search.d.ts b/server/sonar-web/src/main/js/app/components/search/Search.d.ts
index b2590dc00e6..58ceb74bdc0 100644
--- a/server/sonar-web/src/main/js/app/components/search/Search.d.ts
+++ b/server/sonar-web/src/main/js/app/components/search/Search.d.ts
@@ -21,7 +21,7 @@ import * as React from 'react';
import { CurrentUser, AppState } from '../../types';
export interface Props {
- appState: AppState;
+ appState: Pick<AppState, 'organizationsEnabled'>;
currentUser: CurrentUser;
}
diff --git a/server/sonar-web/src/main/js/store/metrics/actions.js b/server/sonar-web/src/main/js/app/flow-types.js
index a271928ce3b..7af83c05ca8 100644
--- a/server/sonar-web/src/main/js/store/metrics/actions.js
+++ b/server/sonar-web/src/main/js/app/flow-types.js
@@ -31,10 +31,3 @@
qualitative?: boolean,
type: string
}; */
-
-export const RECEIVE_METRICS = 'RECEIVE_METRICS';
-
-export const receiveMetrics = (metrics /*: Array<Metric> */) => ({
- type: RECEIVE_METRICS,
- metrics
-});
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<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
// 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<any>;
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<Response> {
+export default function throwGlobalError(error: { response: Response }): Promise<Response> {
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<Props> {
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
currentUser: getCurrentUser(state),
userOrganizations: getMyOrganizations(state)
});
-export default withRouter<OwnProps>(
- connect<StateProps, {}, OwnProps>(mapStateToProps)(SonarCloudPage)
-);
+export default withRouter<OwnProps>(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<Organization>;
+ canAdmin?: boolean;
+ organizations: Organization[];
}
interface DispatchProps {
@@ -110,7 +115,7 @@ class UserOrganizations extends React.PureComponent<Props, State> {
}
}
-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<any>) => {
+export const fetchMyOrganizations = () => (dispatch: Dispatch<Store>) => {
return getOrganizations({ member: true }).then(({ organizations }) => {
return dispatch(receiveMyOrganizations(organizations));
});
};
-export const fetchIfAnyoneCanCreateOrganizations = () => (dispatch: Dispatch<any>) => {
+export const fetchIfAnyoneCanCreateOrganizations = () => (dispatch: Dispatch<Store>) => {
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<StateToProps, {}, OwnProps>(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<Props> {
}
}
-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<Props> {
}
}
-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 <AppContainer location={location} myIssues={myIssues} />;
}
-const stateToProps = (state: any) => ({
+const stateToProps = (state: Store) => ({
currentUser: getCurrentUser(state)
});
-export default connect<StateProps>(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<any>) => {
+const fetchIssueOrganizations = (organizationKeys: string[]) => (dispatch: Dispatch<Store>) => {
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<StateProps, DispatchProps, OwnProps>(
+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<Props> {
}
}
-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) => (
</MarketplaceContext.Consumer>
);
-export default connect<StateToProps, {}, OwnProps>(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<StateProps, {}, OwnProps>(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<any>) => (error: any) => {
- onFail(dispatch)(error);
- return Promise.reject(error);
-};
-
-export const fetchOrganization = (key: string) => (dispatch: Dispatch<any>) => {
+export const fetchOrganization = (key: string) => (dispatch: Dispatch<Store>) => {
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<any>) => {
+export const createOrganization = (organization: OrganizationBase) => (
+ dispatch: Dispatch<Store>
+) => {
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<any>
+ dispatch: Dispatch<Store>
) => {
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<any>) => {
+export const deleteOrganization = (key: string) => (dispatch: Dispatch<Store>) => {
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<Props> {
}
}
-const mapStateToProps = (state: any, ownProps: OwnProps) => ({
+const mapStateToProps = (state: Store, ownProps: OwnProps) => ({
currentUser: getCurrentUser(state),
organization: getOrganizationByKey(state, ownProps.params.organizationKey)
});
-const OrganizationAccessContainer = connect<StateToProps, {}, OwnProps>(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<Props> {
}
}
-const mapStateToProps = (state: any, ownProps: OwnProps) => ({
+const mapStateToProps = (state: Store, ownProps: OwnProps) => ({
organization: getOrganizationByKey(state, ownProps.params.organizationKey),
currentUser: getCurrentUser(state)
});
-export default connect<StateToProps, {}, OwnProps>(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<Props, State> {
const mapDispatchToProps: DispatchToProps = { deleteOrganization: deleteOrganization as any };
-export default connect<null, DispatchToProps, OwnProps>(
+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<Props, State> {
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<Props, State> {
}
}
-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<StateProps, DispatchToProps, OwnProps>(
+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<P> = React.ComponentClass<P> | React.StatelessComponent<P>;
@@ -44,7 +44,7 @@ export default function forSingleOrganization<P>(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<StateToProps, {}, OwnProps>(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<Props, State> {
const mapDispatchToProps: DispatchToProps = { fetchMetrics };
-const mapStateToProps = (state: any): StateToProps => ({
+const mapStateToProps = (state: Store): StateToProps => ({
metrics: getMetrics(state)
});
-export default connect<StateToProps, DispatchToProps, OwnProps>(
+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<StateProps, {}, OwnProps>(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<Props> {
}
}
-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<StateToProps, {}, OwnProps>(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<StateProps & OwnProps, Sta
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
languages: getLanguages(state)
});
-export default connect<StateProps, {}, OwnProps>(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<Props> {
const className =
this.props.component.qualifier === 'TRK' ? 'overview-meta-size-lang-dist' : 'big-spacer-top';
- return languageDistribution ? (
+ return languageDistribution && languageDistribution.value !== undefined ? (
<div className={className} id="overview-language-distribution">
<LanguageDistributionContainer distribution={languageDistribution.value} width={160} />
</div>
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<void>;
- grantPermissionToUser: (login: string, permission: string) => Promise<void>;
- loadHolders: () => void;
- onFilter: (filter: string) => void;
- onSearch: (query: string) => void;
- onSelectPermission: (permission: string) => void;
- revokePermissionFromGroup: (groupName: string, permission: string) => Promise<void>;
- revokePermissionFromUser: (login: string, permission: string) => Promise<void>;
-}
-
-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<Store>, 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<StateToProps, DispatchToProps, OwnProps>(
+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 <div className="alert alert-danger">{message}</div>;
}
-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<Props, State> {
const mapDispatchToProps: DispatchToProps = { fetchMetrics };
-const mapStateToProps = (state: any): StateToProps => ({
+const mapStateToProps = (state: Store): StateToProps => ({
metrics: getMetrics(state)
});
-export default connect<StateToProps, DispatchToProps, Props>(
+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<Props, State> {
);
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<any, any, any>(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(<Subscription component="foo" currentUser={{}} status={status} />)
+ shallow(<Subscription component="foo" currentUser={{ isLoggedIn: false }} status={status} />)
).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<any, any, any>(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<StateProps, {}, OwnProps>(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<StateProps>(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<StateProps> {
}
}
-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<StateProps>(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<StateProps>(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<Props, State> {
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
currentUser: getCurrentUser(state)
});
const mapDispatchToProps: DispatchProps = { addGlobalErrorMessage, skipOnboardingAction };
-export default connect<StateProps, DispatchProps, OwnProps>(
+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<StateProps, DispatchProps, OwnProps>(
+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<StateProps>(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<OwnProps & StateProps & DispatchProps> {
@@ -78,7 +79,7 @@ class AppContainer extends React.PureComponent<OwnProps & StateProps & DispatchP
}
}
-const mapStateToProps = (state: any, ownProps: any) => ({
+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<StateProps, DispatchProps, OwnProps>(
+ 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<Props, State> {
const mapDispatchToProps: DispatchToProps = { fetchMetrics };
-const mapStateToProps = (state: any): StateToProps => ({
+const mapStateToProps = (state: Store): StateToProps => ({
metrics: getMetrics(state)
});
-export default connect<StateToProps, DispatchToProps, OwnProps>(
+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<any>;
languages: Languages;
- onRequestFail: (reasong: any) => void;
organization: { name: string; key: string } | undefined;
}
@@ -103,7 +102,6 @@ export default class App extends React.PureComponent<Props, State> {
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<StateProps, DispatchProps>(
- 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<Props, State> {
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<Props, State>
handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
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<void>;
@@ -198,7 +197,6 @@ export default class ProfileActions extends React.PureComponent<Props, State> {
<CopyProfileForm
onClose={this.closeCopyForm}
onCopy={this.handleProfileCopy}
- onRequestFail={this.props.onRequestFail}
profile={profile}
/>
)}
@@ -207,7 +205,6 @@ export default class ProfileActions extends React.PureComponent<Props, State> {
<DeleteProfileForm
onClose={this.closeDeleteForm}
onDelete={this.handleProfileDelete}
- onRequestFail={this.props.onRequestFail}
profile={profile}
/>
)}
@@ -216,7 +213,6 @@ export default class ProfileActions extends React.PureComponent<Props, State> {
<RenameProfileForm
onClose={this.closeRenameForm}
onRename={this.handleProfileRename}
- onRequestFail={this.props.onRequestFail}
profile={profile}
/>
)}
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<void>;
@@ -75,7 +74,6 @@ export default class ProfileContainer extends React.PureComponent<Props & WithRo
}
const child = React.cloneElement(this.props.children, {
- onRequestFail: this.props.onRequestFail,
organization,
profile,
profiles,
@@ -86,7 +84,6 @@ export default class ProfileContainer extends React.PureComponent<Props & WithRo
<div id="quality-profile">
<Helmet title={profile.name} />
<ProfileHeader
- onRequestFail={this.props.onRequestFail}
organization={organization}
profile={profile}
updateProfiles={this.props.updateProfiles}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx
index fd04227ede9..f8744737d2d 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/RenameProfileForm.tsx
@@ -27,7 +27,6 @@ import { translate, translateWithParameters } from '../../../helpers/l10n';
interface Props {
onClose: () => void;
onRename: (name: string) => void;
- onRequestFail: (reason: any) => void;
profile: Profile;
}
@@ -61,11 +60,10 @@ export default class RenameProfileForm extends React.PureComponent<Props, State>
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(
- <ProfileActions
- onRequestFail={jest.fn()}
- organization="org"
- profile={PROFILE}
- updateProfiles={jest.fn()}
- />
- )
+ shallow(<ProfileActions organization="org" profile={PROFILE} updateProfiles={jest.fn()} />)
).toMatchSnapshot();
});
@@ -55,7 +48,6 @@ it('renders with permission to edit only', () => {
expect(
shallow(
<ProfileActions
- onRequestFail={jest.fn()}
organization="org"
profile={{ ...PROFILE, actions: { edit: true } }}
updateProfiles={jest.fn()}
@@ -68,7 +60,6 @@ it('renders with all permissions', () => {
expect(
shallow(
<ProfileActions
- onRequestFail={jest.fn()}
organization="org"
profile={{
...PROFILE,
@@ -91,7 +82,6 @@ it('should copy profile', async () => {
const push = jest.fn();
const wrapper = shallow(
<ProfileActions
- onRequestFail={jest.fn()}
organization="org"
profile={{ ...PROFILE, actions: { copy: true } }}
updateProfiles={updateProfiles}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx
index 756b21b6b31..c04577b217b 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/components/__tests__/ProfileContainer-test.tsx
@@ -35,7 +35,6 @@ it('should render ProfileHeader', () => {
const output = shallow(
<ProfileContainer
location={{ pathname: '', query: { language: 'js', name: 'fake' } }}
- onRequestFail={jest.fn()}
organization={null}
profiles={profiles}
updateProfiles={updateProfiles}
@@ -57,7 +56,6 @@ it('should render ProfileNotFound', () => {
const output = shallow(
<ProfileContainer
location={{ pathname: '', query: { language: 'js', name: 'random' } }}
- onRequestFail={jest.fn()}
organization={null}
profiles={profiles}
updateProfiles={jest.fn()}
@@ -74,7 +72,6 @@ it('should render Helmet', () => {
const output = shallow(
<ProfileContainer
location={{ pathname: '', query: { language: 'js', name: 'First Profile' } }}
- onRequestFail={jest.fn()}
organization={null}
profiles={profiles}
updateProfiles={updateProfiles}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx
index b783eb7e411..af740ec35a4 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ChangeParentForm.tsx
@@ -29,7 +29,6 @@ import { translate } from '../../../helpers/l10n';
interface Props {
onChange: () => void;
onClose: () => void;
- onRequestFail: (reasong: any) => void;
profile: Profile;
profiles: Profile[];
}
@@ -67,11 +66,10 @@ export default class ChangeParentForm extends React.PureComponent<Props, State>
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<void>;
@@ -111,7 +110,6 @@ export default class ProfileHeader extends React.PureComponent<Props> {
<li>
<ProfileActions
className="pull-left"
- onRequestFail={this.props.onRequestFail}
organization={organization}
profile={profile}
updateProfiles={this.props.updateProfiles}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx
index 85deb056f70..811d248495c 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritance.tsx
@@ -27,7 +27,6 @@ import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';
interface Props {
- onRequestFail: (reason: any) => void;
organization: string | null;
profile: Profile;
profiles: Profile[];
@@ -192,7 +191,6 @@ export default class ProfileInheritance extends React.PureComponent<Props, State
<ChangeParentForm
onChange={this.handleParentChange}
onClose={this.closeForm}
- onRequestFail={this.props.onRequestFail}
profile={profile}
profiles={profiles.filter(p => 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(
<ProfileDetails
exporters={[]}
- onRequestFail={jest.fn()}
organization="org"
profile={{} as Profile}
profiles={[]}
@@ -42,7 +41,6 @@ it('renders with edit permission', () => {
shallow(
<ProfileDetails
exporters={[]}
- onRequestFail={jest.fn()}
organization="org"
profile={{ actions: { edit: true } } as Profile}
profiles={[]}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileDetails-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileDetails-test.tsx.snap
index 57001b3e68d..9f37d14f9e2 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileDetails-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileDetails-test.tsx.snap
@@ -10,7 +10,6 @@ exports[`renders with edit permission 1`] = `
>
<ProfileRules
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
@@ -24,7 +23,6 @@ exports[`renders with edit permission 1`] = `
/>
<ProfileExporters
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
@@ -52,7 +50,6 @@ exports[`renders with edit permission 1`] = `
>
<ProfileInheritance
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
@@ -66,7 +63,6 @@ exports[`renders with edit permission 1`] = `
/>
<ProfileProjects
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
@@ -93,7 +89,6 @@ exports[`renders without permissions 1`] = `
>
<ProfileRules
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
@@ -101,7 +96,6 @@ exports[`renders without permissions 1`] = `
/>
<ProfileExporters
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
@@ -113,7 +107,6 @@ exports[`renders without permissions 1`] = `
>
<ProfileInheritance
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
@@ -121,7 +114,6 @@ exports[`renders without permissions 1`] = `
/>
<ProfileProjects
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx
index e9fcc95b3ad..388675ba4d4 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/CreateProfileForm.tsx
@@ -29,7 +29,6 @@ interface Props {
languages: Array<{ key: string; name: string }>;
onClose: () => void;
onCreate: Function;
- onRequestFail: (reasong: any) => void;
organization: string | null;
}
@@ -89,11 +88,10 @@ export default class CreateProfileForm extends React.PureComponent<Props, State>
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<void>;
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<void>;
}
@@ -112,7 +111,6 @@ export default class PageHeader extends React.PureComponent<Props, State> {
{this.state.restoreFormOpen && (
<RestoreProfileForm
onClose={this.closeRestoreForm}
- onRequestFail={this.props.onRequestFail}
onRestore={this.props.updateProfiles}
organization={this.props.organization}
/>
@@ -123,7 +121,6 @@ export default class PageHeader extends React.PureComponent<Props, State> {
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<void>;
@@ -39,7 +38,6 @@ export default class ProfilesList extends React.PureComponent<Props> {
return profiles.map(profile => (
<ProfilesListRow
key={profile.key}
- onRequestFail={this.props.onRequestFail}
organization={this.props.organization}
profile={profile}
updateProfiles={this.props.updateProfiles}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
index 5fb2c5e1fac..682ede61e62 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
@@ -31,7 +31,6 @@ import Tooltip from '../../../components/controls/Tooltip';
import DocTooltip from '../../../components/docs/DocTooltip';
interface Props {
- onRequestFail: (reason: any) => void;
organization: string | null;
profile: Profile;
updateProfiles: () => Promise<void>;
@@ -149,7 +148,6 @@ export default class ProfilesListRow extends React.PureComponent<Props> {
<td className="quality-profiles-table-actions thin nowrap text-middle text-right">
<ProfileActions
fromList={true}
- onRequestFail={this.props.onRequestFail}
organization={this.props.organization}
profile={this.props.profile}
updateProfiles={this.props.updateProfiles}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx
index a93f0e0a44e..ce22a7a15fa 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/RestoreProfileForm.tsx
@@ -25,7 +25,6 @@ import { SubmitButton, ResetButtonLink } from '../../../components/ui/buttons';
interface Props {
onClose: () => void;
- onRequestFail: (reason: any) => void;
onRestore: () => void;
organization: string | null;
}
@@ -71,11 +70,10 @@ export default class RestoreProfileForm extends React.PureComponent<Props, State
}
this.props.onRestore();
},
- (error: any) => {
+ () => {
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<Props, State> {
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<Props> {
}
}
-const mapStateToProps = (state: any): StateProps => ({ currentUser: getCurrentUser(state) });
+const mapStateToProps = (state: Store): StateProps => ({ currentUser: getCurrentUser(state) });
-export default connect<StateProps, {}, OwnProps>(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<DispatchProps, State> {
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<Props, State> {
}
}
-const mapStateToProps = (state: any): StateProps => {
+const mapStateToProps = (state: Store): StateProps => {
return {
currentUser: getCurrentUser(state),
organizationsEnabled: areThereCustomOrganizations(state)
};
};
-export default connect<StateProps, {}, OwnProps>(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<DispatchProps> {
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<StateToProps, {}, OwnProps>(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 === '<null>') {
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<any, any, any>(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(
<LanguageDistribution
distribution="java=1734;js=845;cpp=73;<null>=15"
- languages={[{ key: 'java', name: 'Java' }, { key: 'js', name: 'JavaScript' }]}
+ languages={{ java: { key: 'java', name: 'Java' }, js: { key: 'js', name: 'JavaScript' } }}
width={100}
/>
)
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<StateToProps, {}, OwnProps>(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<Props> {
}
}
-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 (
<IssueView
@@ -161,7 +152,6 @@ export default class Issue extends React.PureComponent {
onChange={this.props.onChange}
onCheck={this.props.onCheck}
onClick={this.props.onClick}
- onFail={this.handleFail}
onFilter={this.props.onFilter}
selected={this.props.selected}
togglePopup={this.togglePopup}
diff --git a/server/sonar-web/src/main/js/components/issue/IssueView.js b/server/sonar-web/src/main/js/components/issue/IssueView.js
index 100e1942d23..fbb2ac1e259 100644
--- a/server/sonar-web/src/main/js/components/issue/IssueView.js
+++ b/server/sonar-web/src/main/js/components/issue/IssueView.js
@@ -39,7 +39,6 @@ type Props = {|
onChange: Issue => 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}
/>
</li>
@@ -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}
/>
</li>
@@ -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}
/>
</li>
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={
- <SetAssigneePopup
- issue={this.props.issue}
- onFail={this.props.onFail}
- onSelect={this.props.onAssign}
- />
- }>
+ overlay={<SetAssigneePopup issue={this.props.issue} onSelect={this.props.onAssign} />}>
<Button
className="button-link issue-action issue-action-with-options js-issue-assign"
onClick={this.toggleAssign}>
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js b/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js
index 0117454c1e9..d071ce91c74 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueChangelog.js
@@ -33,8 +33,7 @@ type Props = {
isOpen: boolean,
issue: Issue,
creationDate: string,
- togglePopup: (string, boolean | void) => void,
- onFail: Error => void
+ togglePopup: (string, boolean | void) => void
};
*/
@@ -59,7 +58,7 @@ export default class IssueChangelog extends React.PureComponent {
<Toggler
onRequestClose={this.handleClose}
open={this.props.isOpen}
- overlay={<ChangelogPopup issue={this.props.issue} onFail={this.props.onFail} />}>
+ overlay={<ChangelogPopup issue={this.props.issue} />}>
<Tooltip
mouseEnterDelay={0.5}
overlay={<DateTimeFormatter date={this.props.creationDate} />}>
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js b/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js
index 5dfd3bfc69d..f40031e0aaf 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueCommentAction.js
@@ -33,7 +33,6 @@ type Props = {|
currentPopup: ?string,
issueKey: string,
onChange: Issue => void,
- onFail: Error => void,
toggleComment: (open?: boolean, placeholder?: string) => void
|};
*/
@@ -42,11 +41,7 @@ export default class IssueCommentAction extends React.PureComponent {
/*:: props: Props; */
addComment = (text /*: string */) => {
- updateIssue(
- this.props.onChange,
- this.props.onFail,
- addIssueComment({ issue: this.props.issueKey, text })
- );
+ updateIssue(this.props.onChange, addIssueComment({ issue: this.props.issueKey, text }));
this.props.toggleComment(false);
};
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueTags.js b/server/sonar-web/src/main/js/components/issue/components/IssueTags.js
index 00912b7ca81..868126e4d7d 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueTags.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueTags.js
@@ -34,7 +34,6 @@ type Props = {|
isOpen: boolean,
issue: Issue,
onChange: Issue => void,
- onFail: Error => void,
togglePopup: (string, boolean | void) => void
|};
*/
@@ -51,7 +50,6 @@ export default class IssueTags extends React.PureComponent {
const newIssue = { ...issue, tags };
updateIssue(
this.props.onChange,
- this.props.onFail,
setIssueTags({ issue: issue.key, tags: tags.join(',') }),
issue,
newIssue
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js b/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js
index 6c7ab58887a..245240c46c5 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueTitleBar.js
@@ -40,7 +40,6 @@ type Props = {|
displayLocationsCount?: boolean;
displayLocationsLink?: boolean;
issue: Issue,
- onFail: Error => void,
onFilter?: (property: string, issue: Issue) => void,
togglePopup: (string, boolean | void) => void
|};
@@ -89,7 +88,6 @@ export default function IssueTitleBar(props /*: Props */) {
creationDate={issue.creationDate}
isOpen={props.currentPopup === 'changelog'}
issue={issue}
- onFail={props.onFail}
togglePopup={props.togglePopup}
/>
</li>
@@ -125,7 +123,6 @@ export default function IssueTitleBar(props /*: Props */) {
<SimilarIssuesFilter
isOpen={props.currentPopup === 'similarIssues'}
issue={issue}
- onFail={props.onFail}
onFilter={props.onFilter}
togglePopup={props.togglePopup}
/>
diff --git a/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js b/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js
index 52b17fba604..f57008c6691 100644
--- a/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js
+++ b/server/sonar-web/src/main/js/components/issue/components/IssueTransition.js
@@ -34,7 +34,6 @@ type Props = {
isOpen: boolean,
issue: Issue,
onChange: Issue => void,
- onFail: Error => void,
togglePopup: (string, boolean | void) => void
};
*/
@@ -45,7 +44,6 @@ export default class IssueTransition extends React.PureComponent {
setTransition = (transition /*: string */) => {
updateIssue(
this.props.onChange,
- this.props.onFail,
setIssueTransition({ issue: this.props.issue.key, transition })
);
this.toggleSetTransition();
diff --git a/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js b/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js
index 7126df24225..a47d9fad24e 100644
--- a/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js
+++ b/server/sonar-web/src/main/js/components/issue/components/SimilarIssuesFilter.js
@@ -32,7 +32,6 @@ type Props = {|
isOpen: boolean,
issue: Issue,
togglePopup: (string, boolean | void) => void,
- onFail: Error => void,
onFilter: (property: string, issue: Issue) => void
|};
*/
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js
index ad39643695e..b426640ed31 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueAssign-test.js
@@ -35,7 +35,6 @@ it('should render without the action when the correct rights are missing', () =>
isOpen={false}
issue={issue}
onAssign={jest.fn()}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
@@ -49,7 +48,6 @@ it('should render with the action', () => {
isOpen={false}
issue={issue}
onAssign={jest.fn()}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
@@ -64,7 +62,6 @@ it('should open the popup when the button is clicked', () => {
isOpen={false}
issue={issue}
onAssign={jest.fn()}
- onFail={jest.fn()}
togglePopup={toggle}
/>
);
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js
index 8e03fdef42a..fd81fcc3734 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueChangelog-test.js
@@ -34,7 +34,6 @@ it('should render correctly', () => {
creationDate="2017-03-01T09:36:01+0100"
isOpen={false}
issue={issue}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
@@ -48,7 +47,6 @@ it('should open the popup when the button is clicked', () => {
creationDate="2017-03-01T09:36:01+0100"
isOpen={false}
issue={issue}
- onFail={jest.fn()}
togglePopup={toggle}
/>
);
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js
index 2114f366226..5a6317e63e0 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueCommentAction-test.js
@@ -27,7 +27,6 @@ it('should render correctly', () => {
<IssueCommentAction
currentPopup={null}
issueKey="issue-key"
- onFail={jest.fn()}
onIssueChange={jest.fn()}
toggleComment={jest.fn()}
/>
@@ -41,7 +40,6 @@ it('should open the popup when the button is clicked', () => {
<IssueCommentAction
currentPopup={null}
issueKey="issue-key"
- onFail={jest.fn()}
onIssueChange={jest.fn()}
toggleComment={toggle}
/>
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js
index 81d9a512a45..cf7efb121cd 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTags-test.js
@@ -37,7 +37,6 @@ it('should render without the action when the correct rights are missing', () =>
transitions: [],
status: 'CLOSED'
}}
- onFail={jest.fn()}
onIssueChange={jest.fn()}
togglePopup={jest.fn()}
/>
@@ -51,7 +50,6 @@ it('should render with the action', () => {
canSetTags={true}
isOpen={false}
issue={issue}
- onFail={jest.fn()}
onIssueChange={jest.fn()}
togglePopup={jest.fn()}
/>
@@ -66,7 +64,6 @@ it('should open the popup when the button is clicked', () => {
canSetTags={true}
isOpen={false}
issue={issue}
- onFail={jest.fn()}
onIssueChange={jest.fn()}
togglePopup={toggle}
/>
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTitleBar-test.js b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTitleBar-test.js
index 4a917cf1ead..78ae2b7b1ef 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTitleBar-test.js
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/IssueTitleBar-test.js
@@ -52,7 +52,6 @@ it('should render the titlebar correctly', () => {
branchLike={{ isMain: false, name: 'feature-1.0', type: 'SHORT' }}
currentPopup={null}
issue={issue}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
@@ -61,13 +60,7 @@ it('should render the titlebar correctly', () => {
it('should render the titlebar with the filter', () => {
const element = shallow(
- <IssueTitleBar
- currentPopup={null}
- issue={issue}
- onFail={jest.fn()}
- onFilter={jest.fn()}
- togglePopup={jest.fn()}
- />
+ <IssueTitleBar currentPopup={null} issue={issue} onFilter={jest.fn()} togglePopup={jest.fn()} />
);
expect(element).toMatchSnapshot();
});
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap
index d768c0c852d..3ac74928b8f 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueAssign-test.js.snap
@@ -26,7 +26,6 @@ exports[`should open the popup when the button is clicked 2`] = `
"assigneeName": "John Doe",
}
}
- onFail={[MockFunction]}
onSelect={[MockFunction]}
/>
}
@@ -77,7 +76,6 @@ exports[`should render with the action 1`] = `
"assigneeName": "John Doe",
}
}
- onFail={[MockFunction]}
onSelect={[MockFunction]}
/>
}
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap
index 7ba9bfa806c..fad46a6b759 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueChangelog-test.js.snap
@@ -25,7 +25,6 @@ exports[`should open the popup when the button is clicked 2`] = `
"key": "issuekey",
}
}
- onFail={[MockFunction]}
/>
}
>
@@ -73,7 +72,6 @@ exports[`should render correctly 1`] = `
"key": "issuekey",
}
}
- onFail={[MockFunction]}
/>
}
>
diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap
index b61379d35ab..9aed610d4ce 100644
--- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap
+++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.js.snap
@@ -48,7 +48,6 @@ exports[`should render the titlebar correctly 1`] = `
},
}
}
- onFail={[MockFunction]}
togglePopup={[MockFunction]}
/>
</li>
@@ -134,7 +133,6 @@ exports[`should render the titlebar with the filter 1`] = `
},
}
}
- onFail={[MockFunction]}
togglePopup={[MockFunction]}
/>
</li>
@@ -197,7 +195,6 @@ exports[`should render the titlebar with the filter 1`] = `
},
}
}
- onFail={[MockFunction]}
onFilter={[MockFunction]}
togglePopup={[MockFunction]}
/>
diff --git a/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js b/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js
index a9ec681f27b..71c5d3b5b00 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/ChangelogPopup.js
@@ -41,7 +41,6 @@ type Changelog = {
/*::
type Props = {
issue: Issue,
- onFail: Error => void,
popupPosition?: {}
};
*/
@@ -69,11 +68,14 @@ export default class ChangelogPopup extends React.PureComponent {
}
loadChangelog() {
- getIssueChangelog(this.props.issue.key).then(changelogs => {
- if (this.mounted) {
- this.setState({ changelogs });
- }
- }, this.props.onFail);
+ getIssueChangelog(this.props.issue.key).then(
+ changelogs => {
+ if (this.mounted) {
+ this.setState({ changelogs });
+ }
+ },
+ () => {}
+ );
}
render() {
diff --git a/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js b/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js
index a1758698ec8..434bfa9e196 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/SetAssigneePopup.js
@@ -46,7 +46,6 @@ type User = {
type Props = {
currentUser: User,
issue: Issue,
- onFail: Error => void,
onSelect: string => void,
popupPosition?: {}
};
@@ -91,11 +90,12 @@ class SetAssigneePopup extends React.PureComponent {
organization: this.props.issue.projectOrganization,
q: query,
ps: LIST_SIZE
- }).then(this.handleSearchResult, this.props.onFail);
+ }).then(this.handleSearchResult, () => {});
};
- searchUsers = (query /*: string */) =>
- searchUsers({ q: query, ps: LIST_SIZE }).then(this.handleSearchResult, this.props.onFail);
+ searchUsers = (query /*: string */) => {
+ searchUsers({ q: query, ps: LIST_SIZE }).then(this.handleSearchResult, () => {});
+ };
handleSearchResult = (data /*: Object */) => {
this.setState({
diff --git a/server/sonar-web/src/main/js/components/issue/popups/__tests__/ChangelogPopup-test.js b/server/sonar-web/src/main/js/components/issue/popups/__tests__/ChangelogPopup-test.js
index f08b7b05f60..fa67372738e 100644
--- a/server/sonar-web/src/main/js/components/issue/popups/__tests__/ChangelogPopup-test.js
+++ b/server/sonar-web/src/main/js/components/issue/popups/__tests__/ChangelogPopup-test.js
@@ -29,7 +29,6 @@ it('should render the changelog popup correctly', () => {
author: 'john.david.dalton@gmail.com',
creationDate: '2017-03-01T09:36:01+0100'
}}
- onFail={jest.fn()}
/>
);
element.setState({
diff --git a/server/sonar-web/src/main/js/components/measure/types.js b/server/sonar-web/src/main/js/components/measure/types.js
index 623292e882e..a5a8c4ae473 100644
--- a/server/sonar-web/src/main/js/components/measure/types.js
+++ b/server/sonar-web/src/main/js/components/measure/types.js
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
// @flow
-/*:: import type { Metric } from '../../store/metrics/actions'; */
+/*:: import type { Metric } from '../../app/flow-types'; */
/*:: type MeasureIntern = {
value?: string,
diff --git a/server/sonar-web/src/main/js/components/shared/Organization.tsx b/server/sonar-web/src/main/js/components/shared/Organization.tsx
index 023a8ba563c..2dcfdaeb7d6 100644
--- a/server/sonar-web/src/main/js/components/shared/Organization.tsx
+++ b/server/sonar-web/src/main/js/components/shared/Organization.tsx
@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { connect } from 'react-redux';
-import { getOrganizationByKey, areThereCustomOrganizations } from '../../store/rootReducer';
+import { getOrganizationByKey, areThereCustomOrganizations, Store } from '../../store/rootReducer';
import OrganizationLink from '../ui/OrganizationLink';
interface OwnProps {
@@ -30,7 +30,7 @@ interface Props {
link?: boolean;
linkClassName?: string;
organization: { key: string; name: string } | null;
- shouldBeDisplayed: boolean;
+ shouldBeDisplayed?: boolean;
}
function Organization(props: Props) {
@@ -54,11 +54,11 @@ function Organization(props: Props) {
);
}
-const mapStateToProps = (state: any, ownProps: OwnProps) => ({
+const mapStateToProps = (state: Store, ownProps: OwnProps) => ({
organization: getOrganizationByKey(state, ownProps.organizationKey),
shouldBeDisplayed: areThereCustomOrganizations(state)
});
-export default connect<any, any, any>(mapStateToProps)(Organization);
+export default connect(mapStateToProps)(Organization);
export const UnconnectedOrganization = Organization;
diff --git a/server/sonar-web/src/main/js/components/ui/Avatar.tsx b/server/sonar-web/src/main/js/components/ui/Avatar.tsx
index 7657c13419c..ad31cabb65d 100644
--- a/server/sonar-web/src/main/js/components/ui/Avatar.tsx
+++ b/server/sonar-web/src/main/js/components/ui/Avatar.tsx
@@ -21,7 +21,7 @@ import * as React from 'react';
import { connect } from 'react-redux';
import * as classNames from 'classnames';
import GenericAvatar from './GenericAvatar';
-import { getGlobalSettingValue } from '../../store/rootReducer';
+import { getGlobalSettingValue, Store } from '../../store/rootReducer';
interface Props {
className?: string;
@@ -55,7 +55,7 @@ function Avatar(props: Props) {
);
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
enableGravatar: (getGlobalSettingValue(state, 'sonar.lf.enableGravatar') || {}).value === 'true',
gravatarServerUrl: (getGlobalSettingValue(state, 'sonar.lf.gravatarServerUrl') || {}).value
});
diff --git a/server/sonar-web/src/main/js/store/__tests__/__snapshots__/organizations-test.ts.snap b/server/sonar-web/src/main/js/store/__tests__/__snapshots__/organizations-test.ts.snap
new file mode 100644
index 00000000000..bc2ba11d2bc
--- /dev/null
+++ b/server/sonar-web/src/main/js/store/__tests__/__snapshots__/organizations-test.ts.snap
@@ -0,0 +1,97 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Reducer should create organization 1`] = `
+Object {
+ "byKey": Object {
+ "foo": Object {
+ "isAdmin": true,
+ "key": "foo",
+ "name": "foo",
+ },
+ },
+ "my": Array [
+ "foo",
+ ],
+}
+`;
+
+exports[`Reducer should delete organization 1`] = `
+Object {
+ "byKey": Object {},
+ "my": Array [],
+}
+`;
+
+exports[`Reducer should have initial state 1`] = `
+Object {
+ "byKey": Object {},
+ "my": Array [],
+}
+`;
+
+exports[`Reducer should receive my organizations 1`] = `
+Object {
+ "byKey": Object {
+ "bar": Object {
+ "key": "bar",
+ "name": "Bar",
+ },
+ "foo": Object {
+ "key": "foo",
+ "name": "Foo",
+ },
+ },
+ "my": Array [
+ "foo",
+ "bar",
+ ],
+}
+`;
+
+exports[`Reducer should receive organizations 1`] = `
+Object {
+ "byKey": Object {
+ "bar": Object {
+ "key": "bar",
+ "name": "Bar",
+ },
+ "foo": Object {
+ "key": "foo",
+ "name": "Foo",
+ },
+ },
+ "my": Array [],
+}
+`;
+
+exports[`Reducer should receive organizations 2`] = `
+Object {
+ "byKey": Object {
+ "bar": Object {
+ "key": "bar",
+ "name": "Bar",
+ },
+ "foo": Object {
+ "key": "foo",
+ "name": "Qwe",
+ },
+ },
+ "my": Array [],
+}
+`;
+
+exports[`Reducer should update organization 1`] = `
+Object {
+ "byKey": Object {
+ "foo": Object {
+ "description": "description",
+ "isAdmin": true,
+ "key": "foo",
+ "name": "bar",
+ },
+ },
+ "my": Array [
+ "foo",
+ ],
+}
+`;
diff --git a/server/sonar-web/src/main/js/store/__tests__/organizations-test.ts b/server/sonar-web/src/main/js/store/__tests__/organizations-test.ts
new file mode 100644
index 00000000000..41233545f96
--- /dev/null
+++ b/server/sonar-web/src/main/js/store/__tests__/organizations-test.ts
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+import reducer, {
+ getOrganizationByKey,
+ areThereCustomOrganizations,
+ getMyOrganizations,
+ State,
+ receiveOrganizations,
+ receiveMyOrganizations,
+ createOrganization,
+ updateOrganization,
+ deleteOrganization
+} from '../organizations';
+
+const state0: State = { byKey: {}, my: [] };
+
+describe('Reducer', () => {
+ it('should have initial state', () => {
+ // @ts-ignore `undefined` is passed when the redux store is created,
+ // however should not be allowed by typings
+ expect(reducer(undefined, {})).toMatchSnapshot();
+ });
+
+ it('should receive organizations', () => {
+ const state1 = reducer(
+ state0,
+ receiveOrganizations([{ key: 'foo', name: 'Foo' }, { key: 'bar', name: 'Bar' }])
+ );
+ expect(state1).toMatchSnapshot();
+
+ const state2 = reducer(state1, receiveOrganizations([{ key: 'foo', name: 'Qwe' }]));
+ expect(state2).toMatchSnapshot();
+ });
+
+ it('should receive my organizations', () => {
+ const state1 = reducer(
+ state0,
+ receiveMyOrganizations([{ key: 'foo', name: 'Foo' }, { key: 'bar', name: 'Bar' }])
+ );
+ expect(state1).toMatchSnapshot();
+ });
+
+ it('should create organization', () => {
+ const state1 = reducer(state0, createOrganization({ key: 'foo', name: 'foo' }));
+ expect(state1).toMatchSnapshot();
+ });
+
+ it('should update organization', () => {
+ const state1 = reducer(state0, createOrganization({ key: 'foo', name: 'foo' }));
+ const state2 = reducer(
+ state1,
+ updateOrganization('foo', { name: 'bar', description: 'description' })
+ );
+ expect(state2).toMatchSnapshot();
+ });
+
+ it('should delete organization', () => {
+ const state1 = reducer(state0, createOrganization({ key: 'foo', name: 'foo' }));
+ const state2 = reducer(state1, deleteOrganization('foo'));
+ expect(state2).toMatchSnapshot();
+ });
+});
+
+describe('Selectors', () => {
+ it('getOrganizationByKey', () => {
+ const foo = { key: 'foo', name: 'Foo' };
+ const state = { ...state0, byKey: { foo } };
+ expect(getOrganizationByKey(state, 'foo')).toBe(foo);
+ expect(getOrganizationByKey(state, 'bar')).toBeFalsy();
+ });
+
+ it('getMyOrganizations', () => {
+ expect(getMyOrganizations(state0)).toEqual([]);
+
+ const foo = { key: 'foo', name: 'Foo' };
+ expect(getMyOrganizations({ ...state0, byKey: { foo }, my: ['foo'] })).toEqual([foo]);
+ });
+
+ it('areThereCustomOrganizations', () => {
+ const foo = { key: 'foo', name: 'Foo' };
+ const bar = { key: 'bar', name: 'Bar' };
+ expect(areThereCustomOrganizations({ ...state0, byKey: {} })).toBe(false);
+ expect(areThereCustomOrganizations({ ...state0, byKey: { foo } })).toBe(false);
+ expect(areThereCustomOrganizations({ ...state0, byKey: { foo, bar } })).toBe(true);
+ });
+});
diff --git a/server/sonar-web/src/main/js/store/appState/duck.ts b/server/sonar-web/src/main/js/store/appState.ts
index 79ada585879..19a5e546944 100644
--- a/server/sonar-web/src/main/js/store/appState/duck.ts
+++ b/server/sonar-web/src/main/js/store/appState.ts
@@ -17,44 +17,36 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { Extension, AppState } from '../../app/types';
+import { ActionType } from './utils/actions';
+import { Extension, AppState } from '../app/types';
+import { EditionKey } from '../apps/marketplace/utils';
-interface SetAppStateAction {
- type: 'SET_APP_STATE';
- appState: AppState;
-}
-
-interface SetAdminPagesAction {
- type: 'SET_ADMIN_PAGES';
- adminPages: Extension[];
-}
-
-interface RequireAuthorizationAction {
- type: 'REQUIRE_AUTHORIZATION';
-}
-
-export type Action = SetAppStateAction | SetAdminPagesAction | RequireAuthorizationAction;
+type Action =
+ | ActionType<typeof setAppState, 'SET_APP_STATE'>
+ | ActionType<typeof setAdminPages, 'SET_ADMIN_PAGES'>
+ | ActionType<typeof requireAuthorization, 'REQUIRE_AUTHORIZATION'>;
-export function setAppState(appState: AppState): SetAppStateAction {
- return {
- type: 'SET_APP_STATE',
- appState
- };
+export function setAppState(appState: AppState) {
+ return { type: 'SET_APP_STATE', appState };
}
-export function setAdminPages(adminPages: Extension[]): SetAdminPagesAction {
+export function setAdminPages(adminPages: Extension[]) {
return { type: 'SET_ADMIN_PAGES', adminPages };
}
-export function requireAuthorization(): RequireAuthorizationAction {
+export function requireAuthorization() {
return { type: 'REQUIRE_AUTHORIZATION' };
}
const defaultValue: AppState = {
authenticationError: false,
authorizationError: false,
+ defaultOrganization: '',
+ edition: EditionKey.community,
organizationsEnabled: false,
- qualifiers: []
+ productionDatabase: true,
+ qualifiers: [],
+ version: ''
};
export default function(state: AppState = defaultValue, action: Action): AppState {
diff --git a/server/sonar-web/src/main/js/store/globalMessages.ts b/server/sonar-web/src/main/js/store/globalMessages.ts
new file mode 100644
index 00000000000..370ecb1bcc8
--- /dev/null
+++ b/server/sonar-web/src/main/js/store/globalMessages.ts
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+import { uniqueId } from 'lodash';
+import { Dispatch } from 'redux';
+import { requireAuthorization } from './appState';
+import { Store } from './rootReducer';
+import { ActionType } from './utils/actions';
+
+enum MessageLevel {
+ Error = 'ERROR',
+ Success = 'SUCCESS'
+}
+
+interface Message {
+ id: string;
+ message: string;
+ level: MessageLevel;
+}
+
+function addGlobalMessageActionCreator(id: string, message: string, level: MessageLevel) {
+ return { type: 'ADD_GLOBAL_MESSAGE', message, level, id };
+}
+
+export function closeGlobalMessage(id: string) {
+ return { type: 'CLOSE_GLOBAL_MESSAGE', id };
+}
+
+export function closeAllGlobalMessages(id: string) {
+ return { type: 'CLOSE_ALL_GLOBAL_MESSAGES', id };
+}
+
+type Action =
+ | ActionType<typeof addGlobalMessageActionCreator, 'ADD_GLOBAL_MESSAGE'>
+ | ActionType<typeof closeGlobalMessage, 'CLOSE_GLOBAL_MESSAGE'>
+ | ActionType<typeof closeAllGlobalMessages, 'CLOSE_ALL_GLOBAL_MESSAGES'>
+ | ActionType<typeof requireAuthorization, 'REQUIRE_AUTHORIZATION'>;
+
+function addGlobalMessage(message: string, level: MessageLevel) {
+ return (dispatch: Dispatch<Store>) => {
+ const id = uniqueId('global-message-');
+ dispatch(addGlobalMessageActionCreator(id, message, level));
+ setTimeout(() => dispatch(closeGlobalMessage(id)), 5000);
+ };
+}
+
+export function addGlobalErrorMessage(message: string) {
+ return addGlobalMessage(message, MessageLevel.Error);
+}
+
+export function addGlobalSuccessMessage(message: string) {
+ return addGlobalMessage(message, MessageLevel.Success);
+}
+
+export type State = Message[];
+
+export default function(state: State = [], action: Action): State {
+ switch (action.type) {
+ case 'ADD_GLOBAL_MESSAGE':
+ return [{ id: action.id, message: action.message, level: action.level }];
+
+ case 'REQUIRE_AUTHORIZATION':
+ // FIXME l10n
+ return [
+ {
+ id: uniqueId('global-message-'),
+ message:
+ 'You are not authorized to access this page. ' +
+ 'Please log in with more privileges and try again.',
+ level: MessageLevel.Error
+ }
+ ];
+
+ case 'CLOSE_GLOBAL_MESSAGE':
+ return state.filter(message => message.id !== action.id);
+
+ case 'CLOSE_ALL_GLOBAL_MESSAGES':
+ return [];
+ default:
+ return state;
+ }
+}
+
+export function getGlobalMessages(state: State) {
+ return state;
+}
diff --git a/server/sonar-web/src/main/js/store/globalMessages/duck.js b/server/sonar-web/src/main/js/store/globalMessages/duck.js
deleted file mode 100644
index 81c4cba0ff6..00000000000
--- a/server/sonar-web/src/main/js/store/globalMessages/duck.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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
-import { uniqueId } from 'lodash';
-
-/*::
-type Level = 'ERROR' | 'SUCCESS';
-*/
-
-/*::
-type Message = {
- id: string,
- message: string,
- level: Level
-};
-*/
-
-/*::
-export type State = Array<Message>;
-*/
-
-/*::
-type Action = Object;
-*/
-
-const ERROR = 'ERROR';
-const SUCCESS = 'SUCCESS';
-
-/* Actions */
-const ADD_GLOBAL_MESSAGE = 'ADD_GLOBAL_MESSAGE';
-const CLOSE_GLOBAL_MESSAGE = 'CLOSE_GLOBAL_MESSAGE';
-const CLOSE_ALL_GLOBAL_MESSAGES = 'CLOSE_ALL_GLOBAL_MESSAGES';
-
-function addGlobalMessageActionCreator(
- id /*: string */,
- message /*: string */,
- level /*: Level */
-) {
- return {
- type: ADD_GLOBAL_MESSAGE,
- message,
- level,
- id
- };
-}
-
-export function closeGlobalMessage(id /*: string */) {
- return {
- type: CLOSE_GLOBAL_MESSAGE,
- id
- };
-}
-
-export function closeAllGlobalMessages(id /*: string */) {
- return {
- type: CLOSE_ALL_GLOBAL_MESSAGES,
- id
- };
-}
-
-function addGlobalMessage(message /*: string */, level /*: Level */) {
- return function(dispatch /*: Function */) {
- const id = uniqueId('global-message-');
- dispatch(addGlobalMessageActionCreator(id, message, level));
- setTimeout(() => dispatch(closeGlobalMessage(id)), 5000);
- };
-}
-
-export function addGlobalErrorMessage(message /*: string */) {
- return addGlobalMessage(message, ERROR);
-}
-
-export function addGlobalSuccessMessage(message /*: string */) {
- return addGlobalMessage(message, SUCCESS);
-}
-
-/* Reducer */
-export default function(state /*: State */ = [], action /*: Action */ = {}) {
- switch (action.type) {
- case ADD_GLOBAL_MESSAGE:
- return [
- {
- id: action.id,
- message: action.message,
- level: action.level
- }
- ];
-
- case 'REQUIRE_AUTHORIZATION':
- // FIXME l10n
- return [
- {
- id: uniqueId('global-message-'),
- message:
- 'You are not authorized to access this page. ' +
- 'Please log in with more privileges and try again.',
- level: ERROR
- }
- ];
-
- case CLOSE_GLOBAL_MESSAGE:
- return state.filter(message => message.id !== action.id);
-
- case CLOSE_ALL_GLOBAL_MESSAGES:
- return [];
- default:
- return state;
- }
-}
-
-/* Selectors */
-export function getGlobalMessages(state /*: State */) {
- return state;
-}
diff --git a/server/sonar-web/src/main/js/store/languages/reducer.ts b/server/sonar-web/src/main/js/store/languages.ts
index 50caf69c59b..2cc95fe3006 100644
--- a/server/sonar-web/src/main/js/store/languages/reducer.ts
+++ b/server/sonar-web/src/main/js/store/languages.ts
@@ -18,22 +18,30 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { keyBy } from 'lodash';
-import { RECEIVE_LANGUAGES } from './actions';
+import { ActionType } from './utils/actions';
+
+export function receiveLanguages(languages: Array<{ key: string; name: string }>) {
+ return { type: 'RECEIVE_LANGUAGES', languages };
+}
+
+type Action = ActionType<typeof receiveLanguages, 'RECEIVE_LANGUAGES'>;
export interface Languages {
[key: string]: { key: string; name: string };
}
-const reducer = (state: Languages = {}, action: any = {}) => {
- if (action.type === RECEIVE_LANGUAGES) {
+export default function(state: Languages = {}, action: Action): Languages {
+ if (action.type === 'RECEIVE_LANGUAGES') {
return keyBy(action.languages, 'key');
}
return state;
-};
-
-export default reducer;
+}
-export const getLanguages = (state: Languages) => state;
+export function getLanguages(state: Languages) {
+ return state;
+}
-export const getLanguageByKey = (state: Languages, key: string) => state[key];
+export function getLanguageByKey(state: Languages, key: string) {
+ return state[key];
+}
diff --git a/server/sonar-web/src/main/js/store/metrics/reducer.js b/server/sonar-web/src/main/js/store/metrics.ts
index d2d5284cc3a..85098902b21 100644
--- a/server/sonar-web/src/main/js/store/metrics/reducer.js
+++ b/server/sonar-web/src/main/js/store/metrics.ts
@@ -17,27 +17,28 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-// @flow
-import { combineReducers } from 'redux';
import { keyBy } from 'lodash';
-import { RECEIVE_METRICS } from './actions';
-/*:: import type { Metric } from './actions'; */
+import { combineReducers } from 'redux';
+import { ActionType } from './utils/actions';
+import { Metric } from '../app/types';
+
+export function receiveMetrics(metrics: Metric[]) {
+ return { type: 'RECEIVE_METRICS', metrics };
+}
-/*::
-type StateByKey = { [string]: Metric };
-type StateKeys = Array<string>;
-type State = { byKey: StateByKey, keys: StateKeys };
-*/
+type Action = ActionType<typeof receiveMetrics, 'RECEIVE_METRICS'>;
-const byKey = (state /*: StateByKey */ = {}, action = {}) => {
- if (action.type === RECEIVE_METRICS) {
+export type State = { byKey: { [key: string]: Metric }; keys: string[] };
+
+const byKey = (state: State['byKey'] = {}, action: Action) => {
+ if (action.type === 'RECEIVE_METRICS') {
return keyBy(action.metrics, 'key');
}
return state;
};
-const keys = (state /*: StateKeys */ = [], action = {}) => {
- if (action.type === RECEIVE_METRICS) {
+const keys = (state: State['keys'] = [], action: Action) => {
+ if (action.type === 'RECEIVE_METRICS') {
return action.metrics.map(f => f.key);
}
@@ -46,5 +47,10 @@ const keys = (state /*: StateKeys */ = [], action = {}) => {
export default combineReducers({ byKey, keys });
-export const getMetrics = (state /*: State */) => state.byKey;
-export const getMetricsKey = (state /*: State */) => state.keys;
+export function getMetrics(state: State) {
+ return state.byKey;
+}
+
+export function getMetricsKey(state: State) {
+ return state.keys;
+}
diff --git a/server/sonar-web/src/main/js/store/organizations.ts b/server/sonar-web/src/main/js/store/organizations.ts
new file mode 100644
index 00000000000..6b1dfdcc28c
--- /dev/null
+++ b/server/sonar-web/src/main/js/store/organizations.ts
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+import { combineReducers } from 'redux';
+import { omit, uniq, without } from 'lodash';
+import { ActionType } from './utils/actions';
+import { Organization, OrganizationBase } from '../app/types';
+
+type ReceiveOrganizationsAction =
+ | ActionType<typeof receiveOrganizations, 'RECEIVE_ORGANIZATIONS'>
+ | ActionType<typeof receiveMyOrganizations, 'RECEIVE_MY_ORGANIZATIONS'>;
+
+type Action =
+ | ReceiveOrganizationsAction
+ | ActionType<typeof createOrganization, 'CREATE_ORGANIZATION'>
+ | ActionType<typeof updateOrganization, 'UPDATE_ORGANIZATION'>
+ | ActionType<typeof deleteOrganization, 'DELETE_ORGANIZATION'>;
+
+export interface State {
+ byKey: { [key: string]: Organization };
+ my: string[];
+}
+
+export function receiveOrganizations(organizations: Organization[]) {
+ return { type: 'RECEIVE_ORGANIZATIONS', organizations };
+}
+
+export function receiveMyOrganizations(organizations: Organization[]) {
+ return { type: 'RECEIVE_MY_ORGANIZATIONS', organizations };
+}
+
+export function createOrganization(organization: Organization) {
+ return { type: 'CREATE_ORGANIZATION', organization };
+}
+
+export function updateOrganization(key: string, changes: OrganizationBase) {
+ return { type: 'UPDATE_ORGANIZATION', key, changes };
+}
+
+export function deleteOrganization(key: string) {
+ return { type: 'DELETE_ORGANIZATION', key };
+}
+
+function onReceiveOrganizations(state: State['byKey'], action: ReceiveOrganizationsAction) {
+ const nextState = { ...state };
+ action.organizations.forEach(organization => {
+ nextState[organization.key] = { ...state[organization.key], ...organization };
+ });
+ return nextState;
+}
+
+function byKey(state: State['byKey'] = {}, action: Action): State['byKey'] {
+ switch (action.type) {
+ case 'RECEIVE_ORGANIZATIONS':
+ case 'RECEIVE_MY_ORGANIZATIONS':
+ return onReceiveOrganizations(state, action);
+ case 'CREATE_ORGANIZATION':
+ return { ...state, [action.organization.key]: { ...action.organization, isAdmin: true } };
+ case 'UPDATE_ORGANIZATION':
+ return {
+ ...state,
+ [action.key]: {
+ ...state[action.key],
+ key: action.key,
+ ...action.changes
+ }
+ };
+ case 'DELETE_ORGANIZATION':
+ return omit(state, action.key);
+ default:
+ return state;
+ }
+}
+
+function my(state: State['my'] = [], action: Action): State['my'] {
+ switch (action.type) {
+ case 'RECEIVE_MY_ORGANIZATIONS':
+ return uniq([...state, ...action.organizations.map(o => o.key)]);
+ case 'CREATE_ORGANIZATION':
+ return uniq([...state, action.organization.key]);
+ case 'DELETE_ORGANIZATION':
+ return without(state, action.key);
+ default:
+ return state;
+ }
+}
+
+export default combineReducers({ byKey, my });
+
+export function getOrganizationByKey(state: State, key: string) {
+ return state.byKey[key];
+}
+
+export function getMyOrganizations(state: State) {
+ return state.my.map(key => getOrganizationByKey(state, key));
+}
+
+export function areThereCustomOrganizations(state: State) {
+ return Object.keys(state.byKey).length > 1;
+}
diff --git a/server/sonar-web/src/main/js/store/organizations/__tests__/__snapshots__/duck-test.ts.snap b/server/sonar-web/src/main/js/store/organizations/__tests__/__snapshots__/duck-test.ts.snap
deleted file mode 100644
index c5ad9b73625..00000000000
--- a/server/sonar-web/src/main/js/store/organizations/__tests__/__snapshots__/duck-test.ts.snap
+++ /dev/null
@@ -1,43 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Reducer should have initial state 1`] = `
-Object {
- "byKey": Object {},
- "groups": Object {},
- "my": Array [],
-}
-`;
-
-exports[`Reducer should receive organizations 1`] = `
-Object {
- "byKey": Object {
- "bar": Object {
- "key": "bar",
- "name": "Bar",
- },
- "foo": Object {
- "key": "foo",
- "name": "Foo",
- },
- },
- "groups": Object {},
- "my": Array [],
-}
-`;
-
-exports[`Reducer should receive organizations 2`] = `
-Object {
- "byKey": Object {
- "bar": Object {
- "key": "bar",
- "name": "Bar",
- },
- "foo": Object {
- "key": "foo",
- "name": "Qwe",
- },
- },
- "groups": Object {},
- "my": Array [],
-}
-`;
diff --git a/server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.ts b/server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.ts
deleted file mode 100644
index e9321e29f90..00000000000
--- a/server/sonar-web/src/main/js/store/organizations/__tests__/duck-test.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.
- */
-import organizations, { getOrganizationByKey, areThereCustomOrganizations } from '../duck';
-
-const state0 = { byKey: {}, my: [], groups: {} };
-
-describe('Reducer', () => {
- it('should have initial state', () => {
- expect((organizations as any)(undefined, {})).toMatchSnapshot();
- });
-
- it('should receive organizations', () => {
- const action1 = {
- type: 'RECEIVE_ORGANIZATIONS',
- organizations: [{ key: 'foo', name: 'Foo' }, { key: 'bar', name: 'Bar' }]
- };
- const state1 = organizations(state0, action1);
- expect(state1).toMatchSnapshot();
-
- const action2 = {
- type: 'RECEIVE_ORGANIZATIONS',
- organizations: [{ key: 'foo', name: 'Qwe' }]
- };
- const state2 = organizations(state1, action2);
- expect(state2).toMatchSnapshot();
- });
-});
-
-describe('Selectors', () => {
- it('getOrganizationByKey', () => {
- const foo = { key: 'foo', name: 'Foo' };
- const state = { ...state0, byKey: { foo } };
- expect(getOrganizationByKey(state, 'foo')).toBe(foo);
- expect(getOrganizationByKey(state, 'bar')).toBeFalsy();
- });
-
- it('areThereCustomOrganizations', () => {
- const foo = { key: 'foo', name: 'Foo' };
- const bar = { key: 'bar', name: 'Bar' };
- expect(areThereCustomOrganizations({ ...state0, byKey: {} })).toBe(false);
- expect(areThereCustomOrganizations({ ...state0, byKey: { foo } })).toBe(false);
- expect(areThereCustomOrganizations({ ...state0, byKey: { foo, bar } })).toBe(true);
- });
-});
diff --git a/server/sonar-web/src/main/js/store/organizations/duck.ts b/server/sonar-web/src/main/js/store/organizations/duck.ts
deleted file mode 100644
index 5f01ac95261..00000000000
--- a/server/sonar-web/src/main/js/store/organizations/duck.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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.
- */
-import { combineReducers } from 'redux';
-import { omit, uniq, without } from 'lodash';
-import { Group, Organization, OrganizationBase } from '../../app/types';
-
-interface ReceiveOrganizationsAction {
- type: 'RECEIVE_ORGANIZATIONS';
- organizations: Organization[];
-}
-
-interface ReceiveMyOrganizationsAction {
- type: 'RECEIVE_MY_ORGANIZATIONS';
- organizations: Organization[];
-}
-
-interface ReceiveOrganizationGroups {
- type: 'RECEIVE_ORGANIZATION_GROUPS';
- key: string;
- groups: Group[];
-}
-
-interface CreateOrganizationAction {
- type: 'CREATE_ORGANIZATION';
- organization: Organization;
-}
-
-interface UpdateOrganizationAction {
- type: 'UPDATE_ORGANIZATION';
- key: string;
- changes: {};
-}
-
-interface DeleteOrganizationAction {
- type: 'DELETE_ORGANIZATION';
- key: string;
-}
-
-type Action =
- | ReceiveOrganizationsAction
- | ReceiveMyOrganizationsAction
- | ReceiveOrganizationGroups
- | CreateOrganizationAction
- | UpdateOrganizationAction
- | DeleteOrganizationAction;
-
-interface ByKeyState {
- [key: string]: Organization;
-}
-
-interface GroupsState {
- [key: string]: Group[];
-}
-
-type MyState = string[];
-
-interface State {
- byKey: ByKeyState;
- my: MyState;
- groups: GroupsState;
-}
-
-export function receiveOrganizations(organizations: Organization[]): ReceiveOrganizationsAction {
- return {
- type: 'RECEIVE_ORGANIZATIONS',
- organizations
- };
-}
-
-export function receiveMyOrganizations(
- organizations: Organization[]
-): ReceiveMyOrganizationsAction {
- return {
- type: 'RECEIVE_MY_ORGANIZATIONS',
- organizations
- };
-}
-
-export function receiveOrganizationGroups(key: string, groups: Group[]): ReceiveOrganizationGroups {
- return {
- type: 'RECEIVE_ORGANIZATION_GROUPS',
- key,
- groups
- };
-}
-
-export function createOrganization(organization: Organization): CreateOrganizationAction {
- return {
- type: 'CREATE_ORGANIZATION',
- organization
- };
-}
-
-export function updateOrganization(
- key: string,
- changes: OrganizationBase
-): UpdateOrganizationAction {
- return {
- type: 'UPDATE_ORGANIZATION',
- key,
- changes
- };
-}
-
-export function deleteOrganization(key: string): DeleteOrganizationAction {
- return {
- type: 'DELETE_ORGANIZATION',
- key
- };
-}
-
-function onReceiveOrganizations(
- state: ByKeyState,
- action: ReceiveOrganizationsAction | ReceiveMyOrganizationsAction
-): ByKeyState {
- const nextState = { ...state };
- action.organizations.forEach(organization => {
- nextState[organization.key] = { ...state[organization.key], ...organization };
- });
- return nextState;
-}
-
-function byKey(state: ByKeyState = {}, action: Action) {
- switch (action.type) {
- case 'RECEIVE_ORGANIZATIONS':
- case 'RECEIVE_MY_ORGANIZATIONS':
- return onReceiveOrganizations(state, action);
- case 'CREATE_ORGANIZATION':
- return { ...state, [action.organization.key]: { ...action.organization, isAdmin: true } };
- case 'UPDATE_ORGANIZATION':
- return {
- ...state,
- [action.key]: {
- ...state[action.key],
- key: action.key,
- ...action.changes
- }
- };
- case 'DELETE_ORGANIZATION':
- return omit(state, action.key);
- default:
- return state;
- }
-}
-
-function my(state: MyState = [], action: Action) {
- switch (action.type) {
- case 'RECEIVE_MY_ORGANIZATIONS':
- return uniq([...state, ...action.organizations.map(o => o.key)]);
- case 'CREATE_ORGANIZATION':
- return uniq([...state, action.organization.key]);
- case 'DELETE_ORGANIZATION':
- return without(state, action.key);
- default:
- return state;
- }
-}
-
-function groups(state: GroupsState = {}, action: Action) {
- if (action.type === 'RECEIVE_ORGANIZATION_GROUPS') {
- return { ...state, [action.key]: action.groups };
- }
- return state;
-}
-
-export default combineReducers<State>({ byKey, my, groups });
-
-export function getOrganizationByKey(state: State, key: string): Organization | undefined {
- return state.byKey[key];
-}
-
-export function getOrganizationGroupsByKey(state: State, key: string): Group[] {
- return state.groups[key] || [];
-}
-
-export function getMyOrganizations(state: State): Organization[] {
- return state.my.map(key => getOrganizationByKey(state, key) as Organization);
-}
-
-export function areThereCustomOrganizations(state: State): boolean {
- return Object.keys(state.byKey).length > 1;
-}
diff --git a/server/sonar-web/src/main/js/store/rootActions.js b/server/sonar-web/src/main/js/store/rootActions.js
deleted file mode 100644
index c49e3921c6c..00000000000
--- a/server/sonar-web/src/main/js/store/rootActions.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.
- */
-import { setAppState } from './appState/duck';
-import { receiveOrganizations } from './organizations/duck';
-import { receiveLanguages } from './languages/actions';
-import { receiveMetrics } from './metrics/actions';
-import { addGlobalErrorMessage } from './globalMessages/duck';
-import { getLanguages } from '../api/languages';
-import { getGlobalNavigation } from '../api/nav';
-import * as auth from '../api/auth';
-import { getOrganizations } from '../api/organizations';
-import { getAllMetrics } from '../api/metrics';
-import { parseError } from '../helpers/request';
-
-export const onFail = dispatch => error =>
- parseError(error).then(message => dispatch(addGlobalErrorMessage(message)));
-
-export const fetchLanguages = () => dispatch =>
- getLanguages().then(languages => dispatch(receiveLanguages(languages)), onFail(dispatch));
-
-export const fetchMetrics = () => dispatch =>
- getAllMetrics().then(metrics => dispatch(receiveMetrics(metrics)), onFail(dispatch));
-
-export const fetchOrganizations = (organizations /*: Array<string> | void */) => dispatch =>
- getOrganizations({ organizations: organizations && organizations.join() }).then(
- r => dispatch(receiveOrganizations(r.organizations)),
- onFail(dispatch)
- );
-
-export const doLogin = (login, password) => dispatch =>
- auth.login(login, password).then(
- () => {
- /* everything is fine */
- },
- () => {
- dispatch(addGlobalErrorMessage('Authentication failed'));
- return Promise.reject();
- }
- );
-
-export const doLogout = () => dispatch =>
- auth.logout().then(
- () => {
- /* everything is fine */
- },
- () => {
- dispatch(addGlobalErrorMessage('Logout failed'));
- return Promise.reject();
- }
- );
diff --git a/server/sonar-web/src/main/js/store/rootActions.ts b/server/sonar-web/src/main/js/store/rootActions.ts
new file mode 100644
index 00000000000..52ab8e776b6
--- /dev/null
+++ b/server/sonar-web/src/main/js/store/rootActions.ts
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+import { Dispatch } from 'redux';
+import { addGlobalErrorMessage } from './globalMessages';
+import { receiveLanguages } from './languages';
+import { receiveMetrics } from './metrics';
+import { receiveOrganizations } from './organizations';
+import { Store } from './rootReducer';
+import * as auth from '../api/auth';
+import { getLanguages } from '../api/languages';
+import { getAllMetrics } from '../api/metrics';
+import { getOrganizations } from '../api/organizations';
+
+export function fetchLanguages() {
+ return (dispatch: Dispatch<Store>) => {
+ getLanguages().then(languages => dispatch(receiveLanguages(languages)), () => {});
+ };
+}
+
+export function fetchMetrics() {
+ return (dispatch: Dispatch<Store>) => {
+ getAllMetrics().then(metrics => dispatch(receiveMetrics(metrics)), () => {});
+ };
+}
+
+export function fetchOrganizations(organizations: string[]) {
+ return (dispatch: Dispatch<Store>) => {
+ getOrganizations({ organizations: organizations && organizations.join() }).then(
+ r => dispatch(receiveOrganizations(r.organizations)),
+ () => {}
+ );
+ };
+}
+
+export function doLogin(login: string, password: string) {
+ return (dispatch: Dispatch<Store>) =>
+ auth.login(login, password).then(
+ () => {
+ /* everything is fine */
+ },
+ () => {
+ dispatch(addGlobalErrorMessage('Authentication failed'));
+ return Promise.reject();
+ }
+ );
+}
+
+export function doLogout() {
+ return (dispatch: Dispatch<Store>) =>
+ auth.logout().then(
+ () => {
+ /* everything is fine */
+ },
+ () => {
+ dispatch(addGlobalErrorMessage('Logout failed'));
+ return Promise.reject();
+ }
+ );
+}
diff --git a/server/sonar-web/src/main/js/store/rootReducer.js b/server/sonar-web/src/main/js/store/rootReducer.js
deleted file mode 100644
index 16d038d1e89..00000000000
--- a/server/sonar-web/src/main/js/store/rootReducer.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.
- */
-import { combineReducers } from 'redux';
-import appState from './appState/duck';
-import users, * as fromUsers from './users/reducer';
-import languages, * as fromLanguages from './languages/reducer';
-import metrics, * as fromMetrics from './metrics/reducer';
-import organizations, * as fromOrganizations from './organizations/duck';
-import globalMessages, * as fromGlobalMessages from './globalMessages/duck';
-import permissionsApp, * as fromPermissionsApp from '../apps/permissions/shared/store/rootReducer';
-import projectAdminApp, * as fromProjectAdminApp from '../apps/project-admin/store/rootReducer';
-import settingsApp, * as fromSettingsApp from '../apps/settings/store/rootReducer';
-
-export default combineReducers({
- appState,
- globalMessages,
- languages,
- metrics,
- organizations,
- users,
-
- // apps
- permissionsApp,
- projectAdminApp,
- settingsApp
-});
-
-export const getAppState = state => state.appState;
-
-export const getGlobalMessages = state =>
- fromGlobalMessages.getGlobalMessages(state.globalMessages);
-
-export const getLanguages = state => fromLanguages.getLanguages(state.languages);
-
-export const getCurrentUser = state => fromUsers.getCurrentUser(state.users);
-
-export const getUsersByLogins = (state, logins) => fromUsers.getUsersByLogins(state.users, logins);
-
-export const getMetrics = state => fromMetrics.getMetrics(state.metrics);
-
-export const getMetricsKey = state => fromMetrics.getMetricsKey(state.metrics);
-
-export const getOrganizationByKey = (state, key) =>
- fromOrganizations.getOrganizationByKey(state.organizations, key);
-
-export const getOrganizationGroupsByKey = (state, key) =>
- fromOrganizations.getOrganizationGroupsByKey(state.organizations, key);
-
-export const getMyOrganizations = state =>
- fromOrganizations.getMyOrganizations(state.organizations);
-
-export const areThereCustomOrganizations = state => getAppState(state).organizationsEnabled;
-
-export const getPermissionsAppUsers = state => fromPermissionsApp.getUsers(state.permissionsApp);
-
-export const getPermissionsAppGroups = state => fromPermissionsApp.getGroups(state.permissionsApp);
-
-export const isPermissionsAppLoading = state => fromPermissionsApp.isLoading(state.permissionsApp);
-
-export const getPermissionsAppQuery = state => fromPermissionsApp.getQuery(state.permissionsApp);
-
-export const getPermissionsAppFilter = state => fromPermissionsApp.getFilter(state.permissionsApp);
-
-export const getPermissionsAppSelectedPermission = state =>
- fromPermissionsApp.getSelectedPermission(state.permissionsApp);
-
-export const getPermissionsAppError = state => fromPermissionsApp.getError(state.permissionsApp);
-
-export const getGlobalSettingValue = (state, key) =>
- fromSettingsApp.getValue(state.settingsApp, key);
-
-export const getSettingsAppDefinition = (state, key) =>
- fromSettingsApp.getDefinition(state.settingsApp, key);
-
-export const getSettingsAppAllCategories = state =>
- fromSettingsApp.getAllCategories(state.settingsApp);
-
-export const getSettingsAppDefaultCategory = state =>
- fromSettingsApp.getDefaultCategory(state.settingsApp);
-
-export const getSettingsAppSettingsForCategory = (state, category, componentKey) =>
- fromSettingsApp.getSettingsForCategory(state.settingsApp, category, componentKey);
-
-export const getSettingsAppChangedValue = (state, key) =>
- fromSettingsApp.getChangedValue(state.settingsApp, key);
-
-export const isSettingsAppLoading = (state, key) =>
- fromSettingsApp.isLoading(state.settingsApp, key);
-
-export const getSettingsAppValidationMessage = (state, key) =>
- fromSettingsApp.getValidationMessage(state.settingsApp, key);
-
-export const getSettingsAppEncryptionState = state =>
- fromSettingsApp.getEncryptionState(state.settingsApp);
-
-export const getProjectAdminProjectModules = (state, projectKey) =>
- fromProjectAdminApp.getProjectModules(state.projectAdminApp, projectKey);
diff --git a/server/sonar-web/src/main/js/store/rootReducer.ts b/server/sonar-web/src/main/js/store/rootReducer.ts
new file mode 100644
index 00000000000..8dfc49d857f
--- /dev/null
+++ b/server/sonar-web/src/main/js/store/rootReducer.ts
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+import { combineReducers } from 'redux';
+import appState from './appState';
+import globalMessages, * as fromGlobalMessages from './globalMessages';
+import languages, * as fromLanguages from './languages';
+import metrics, * as fromMetrics from './metrics';
+import organizations, * as fromOrganizations from './organizations';
+import users, * as fromUsers from './users';
+import { AppState } from '../app/types';
+import permissionsApp, * as fromPermissionsApp from '../apps/permissions/shared/store/rootReducer';
+import projectAdminApp, * as fromProjectAdminApp from '../apps/project-admin/store/rootReducer';
+import settingsApp, * as fromSettingsApp from '../apps/settings/store/rootReducer';
+
+export type Store = {
+ appState: AppState;
+ globalMessages: fromGlobalMessages.State;
+ languages: fromLanguages.Languages;
+ metrics: fromMetrics.State;
+ organizations: fromOrganizations.State;
+ users: fromUsers.State;
+
+ // apps
+ permissionsApp: any;
+ projectAdminApp: any;
+ settingsApp: any;
+};
+
+export default combineReducers<Store>({
+ appState,
+ globalMessages,
+ languages,
+ metrics,
+ organizations,
+ users,
+
+ // apps
+ permissionsApp,
+ projectAdminApp,
+ settingsApp
+});
+
+export function getAppState(state: Store) {
+ return state.appState;
+}
+
+export function getGlobalMessages(state: Store) {
+ return fromGlobalMessages.getGlobalMessages(state.globalMessages);
+}
+
+export function getLanguages(state: Store) {
+ return fromLanguages.getLanguages(state.languages);
+}
+
+export function getCurrentUser(state: Store) {
+ return fromUsers.getCurrentUser(state.users);
+}
+
+export function getMetrics(state: Store) {
+ return fromMetrics.getMetrics(state.metrics);
+}
+
+export function getMetricsKey(state: Store) {
+ return fromMetrics.getMetricsKey(state.metrics);
+}
+
+export function getOrganizationByKey(state: Store, key: string) {
+ return fromOrganizations.getOrganizationByKey(state.organizations, key);
+}
+
+export function getMyOrganizations(state: Store) {
+ return fromOrganizations.getMyOrganizations(state.organizations);
+}
+
+export function areThereCustomOrganizations(state: Store) {
+ return getAppState(state).organizationsEnabled;
+}
+
+export function getPermissionsAppUsers(state: Store) {
+ return fromPermissionsApp.getUsers(state.permissionsApp);
+}
+
+export function getPermissionsAppGroups(state: Store) {
+ return fromPermissionsApp.getGroups(state.permissionsApp);
+}
+
+export function isPermissionsAppLoading(state: Store) {
+ return fromPermissionsApp.isLoading(state.permissionsApp);
+}
+
+export function getPermissionsAppQuery(state: Store) {
+ return fromPermissionsApp.getQuery(state.permissionsApp);
+}
+
+export function getPermissionsAppFilter(state: Store) {
+ return fromPermissionsApp.getFilter(state.permissionsApp);
+}
+
+export function getPermissionsAppSelectedPermission(state: Store) {
+ return fromPermissionsApp.getSelectedPermission(state.permissionsApp);
+}
+
+export function getPermissionsAppError(state: Store) {
+ return fromPermissionsApp.getError(state.permissionsApp);
+}
+
+export function getGlobalSettingValue(state: Store, key: string) {
+ return fromSettingsApp.getValue(state.settingsApp, key);
+}
+
+export function getSettingsAppDefinition(state: Store, key: string) {
+ return fromSettingsApp.getDefinition(state.settingsApp, key);
+}
+
+export function getSettingsAppAllCategories(state: Store) {
+ return fromSettingsApp.getAllCategories(state.settingsApp);
+}
+
+export function getSettingsAppDefaultCategory(state: Store) {
+ return fromSettingsApp.getDefaultCategory(state.settingsApp);
+}
+
+export function getSettingsAppSettingsForCategory(
+ state: Store,
+ category: string,
+ componentKey: string
+) {
+ return fromSettingsApp.getSettingsForCategory(state.settingsApp, category, componentKey);
+}
+
+export function getSettingsAppChangedValue(state: Store, key: string) {
+ return fromSettingsApp.getChangedValue(state.settingsApp, key);
+}
+
+export function isSettingsAppLoading(state: Store, key: string) {
+ return fromSettingsApp.isLoading(state.settingsApp, key);
+}
+
+export function getSettingsAppValidationMessage(state: Store, key: string) {
+ return fromSettingsApp.getValidationMessage(state.settingsApp, key);
+}
+
+export function getSettingsAppEncryptionState(state: Store) {
+ return fromSettingsApp.getEncryptionState(state.settingsApp);
+}
+
+export function getProjectAdminProjectModules(state: Store, projectKey: string) {
+ return fromProjectAdminApp.getProjectModules(state.projectAdminApp, projectKey);
+}
diff --git a/server/sonar-web/src/main/js/store/users.ts b/server/sonar-web/src/main/js/store/users.ts
new file mode 100644
index 00000000000..969cf8a6f7e
--- /dev/null
+++ b/server/sonar-web/src/main/js/store/users.ts
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+import { uniq } from 'lodash';
+import { Dispatch, combineReducers } from 'redux';
+import { Store } from './rootReducer';
+import { ActionType } from './utils/actions';
+import * as api from '../api/users';
+import { CurrentUser, HomePage, isLoggedIn, LoggedInUser } from '../app/types';
+
+export function receiveCurrentUser(user: CurrentUser) {
+ return { type: 'RECEIVE_CURRENT_USER', user };
+}
+
+export function skipOnboarding() {
+ return { type: 'SKIP_ONBOARDING' };
+}
+
+function setHomePageAction(homepage: HomePage) {
+ return { type: 'SET_HOMEPAGE', homepage };
+}
+
+export function setHomePage(homepage: HomePage) {
+ return (dispatch: Dispatch<Store>) => {
+ api.setHomePage(homepage).then(
+ () => {
+ dispatch(setHomePageAction(homepage));
+ },
+ () => {}
+ );
+ };
+}
+
+type Action =
+ | ActionType<typeof receiveCurrentUser, 'RECEIVE_CURRENT_USER'>
+ | ActionType<typeof skipOnboarding, 'SKIP_ONBOARDING'>
+ | ActionType<typeof setHomePageAction, 'SET_HOMEPAGE'>;
+
+export interface State {
+ usersByLogin: { [login: string]: any };
+ userLogins: string[];
+ currentUser: CurrentUser;
+}
+
+function usersByLogin(state: State['usersByLogin'] = {}, action: Action): State['usersByLogin'] {
+ if (action.type === 'RECEIVE_CURRENT_USER' && isLoggedIn(action.user)) {
+ return { ...state, [action.user.login]: action.user };
+ } else {
+ return state;
+ }
+}
+
+function userLogins(state: State['userLogins'] = [], action: Action): State['userLogins'] {
+ if (action.type === 'RECEIVE_CURRENT_USER' && isLoggedIn(action.user)) {
+ return uniq([...state, action.user.login]);
+ } else {
+ return state;
+ }
+}
+
+function currentUser(
+ state: State['currentUser'] = { isLoggedIn: false },
+ action: Action
+): State['currentUser'] {
+ if (action.type === 'RECEIVE_CURRENT_USER') {
+ return action.user;
+ }
+ if (action.type === 'SKIP_ONBOARDING' && isLoggedIn(state)) {
+ return { ...state, showOnboardingTutorial: false } as LoggedInUser;
+ }
+ if (action.type === 'SET_HOMEPAGE' && isLoggedIn(state)) {
+ return { ...state, homepage: action.homepage } as LoggedInUser;
+ }
+ return state;
+}
+
+export default combineReducers({ usersByLogin, userLogins, currentUser });
+
+export function getCurrentUser(state: State) {
+ return state.currentUser;
+}
+
+export function getUserByLogin(state: State, login: string) {
+ return state.usersByLogin[login];
+}
+
+export function getUsersByLogins(state: State, logins: string[]) {
+ return logins.map(login => getUserByLogin(state, login));
+}
diff --git a/server/sonar-web/src/main/js/store/users/actions.ts b/server/sonar-web/src/main/js/store/users/actions.ts
deleted file mode 100644
index 9c9a146e2a4..00000000000
--- a/server/sonar-web/src/main/js/store/users/actions.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-import { Dispatch } from 'redux';
-import * as api from '../../api/users';
-import { CurrentUser, HomePage } from '../../app/types';
-
-export const RECEIVE_CURRENT_USER = 'RECEIVE_CURRENT_USER';
-export const SKIP_ONBOARDING = 'SKIP_ONBOARDING';
-export const SET_HOMEPAGE = 'SET_HOMEPAGE';
-
-export const receiveCurrentUser = (user: CurrentUser) => ({
- type: RECEIVE_CURRENT_USER,
- user
-});
-
-export const skipOnboarding = () => ({ type: SKIP_ONBOARDING });
-
-export const fetchCurrentUser = () => (dispatch: Dispatch<any>) => {
- return api.getCurrentUser().then(user => {
- dispatch(receiveCurrentUser(user));
- return user;
- });
-};
-
-export const setHomePage = (homepage: HomePage) => (dispatch: Dispatch<any>) => {
- api.setHomePage(homepage).then(
- () => {
- dispatch({ type: SET_HOMEPAGE, homepage });
- },
- () => {}
- );
-};
diff --git a/server/sonar-web/src/main/js/store/users/reducer.ts b/server/sonar-web/src/main/js/store/users/reducer.ts
deleted file mode 100644
index a6e79db6d97..00000000000
--- a/server/sonar-web/src/main/js/store/users/reducer.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.
- */
-import { combineReducers } from 'redux';
-import { uniq } from 'lodash';
-import { RECEIVE_CURRENT_USER, SKIP_ONBOARDING, SET_HOMEPAGE } from './actions';
-import { CurrentUser } from '../../app/types';
-
-interface UsersByLogin {
- [login: string]: any;
-}
-
-const usersByLogin = (state: UsersByLogin = {}, action: any = {}) => {
- if (action.type === RECEIVE_CURRENT_USER) {
- return { ...state, [action.user.login]: action.user };
- } else {
- return state;
- }
-};
-
-type UserLogins = string[];
-
-const userLogins = (state: UserLogins = [], action: any = {}) => {
- if (action.type === RECEIVE_CURRENT_USER) {
- return uniq([...state, action.user.login]);
- } else {
- return state;
- }
-};
-
-const currentUser = (state: CurrentUser | null = null, action: any = {}) => {
- if (action.type === RECEIVE_CURRENT_USER) {
- return action.user;
- }
- if (action.type === SKIP_ONBOARDING) {
- return state ? { ...state, showOnboardingTutorial: false } : null;
- }
- if (action.type === SET_HOMEPAGE) {
- return state && { ...state, homepage: action.homepage };
- }
- return state;
-};
-
-interface State {
- usersByLogin: UsersByLogin;
- userLogins: UserLogins;
- currentUser: CurrentUser | null;
-}
-
-export default combineReducers({ usersByLogin, userLogins, currentUser });
-
-export const getCurrentUser = (state: State) => state.currentUser!;
-export const getUserByLogin = (state: State, login: string) => state.usersByLogin[login];
-export const getUsersByLogins = (state: State, logins: string[]) =>
- logins.map(login => getUserByLogin(state, login));
diff --git a/server/sonar-web/src/main/js/store/languages/actions.js b/server/sonar-web/src/main/js/store/utils/actions.ts
index 9b3d1a9d506..4926a67d2a3 100644
--- a/server/sonar-web/src/main/js/store/languages/actions.js
+++ b/server/sonar-web/src/main/js/store/utils/actions.ts
@@ -17,9 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-export const RECEIVE_LANGUAGES = 'RECEIVE_LANGUAGES';
+import { Omit } from '../../app/types';
-export const receiveLanguages = languages => ({
- type: RECEIVE_LANGUAGES,
- languages
-});
+type ActionCreator = (...args: any[]) => { type: string };
+
+export type ActionType<F extends ActionCreator, T> = Omit<ReturnType<F>, 'type'> & { type: T };
diff --git a/server/sonar-web/src/main/js/store/utils/configureStore.js b/server/sonar-web/src/main/js/store/utils/configureStore.ts
index 75bb516bfbe..8681815877f 100644
--- a/server/sonar-web/src/main/js/store/utils/configureStore.js
+++ b/server/sonar-web/src/main/js/store/utils/configureStore.ts
@@ -20,6 +20,9 @@
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
+type RootReducer = typeof import('../rootReducer').default;
+type State = import('../rootReducer').Store;
+
const middlewares = [thunk];
const composed = [];
@@ -27,7 +30,8 @@ if (process.env.NODE_ENV === 'development') {
const { createLogger } = require('redux-logger');
middlewares.push(createLogger());
- composed.push(window.devToolsExtension ? window.devToolsExtension() : f => f);
+ const { devToolsExtension } = window as any;
+ composed.push(devToolsExtension ? devToolsExtension() : (f: Function) => f);
}
const finalCreateStore = compose(
@@ -35,6 +39,6 @@ const finalCreateStore = compose(
...composed
)(createStore);
-export default function configureStore(rootReducer, initialState) {
+export default function configureStore(rootReducer: RootReducer, initialState?: State) {
return finalCreateStore(rootReducer, initialState);
}