}
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() {
* 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;
}
export function getLanguages(): Promise<Language[]> {
- return getJSON('/api/languages/list').then(r => r.languages);
+ return getJSON('/api/languages/list').then(r => r.languages, throwGlobalError);
}
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> {
}
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);
}
login: string,
permission: string,
organization?: string
-): Promise<void> {
+) {
const data: RequestData = { login, permission };
if (projectKey) {
data.projectKey = projectKey;
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(
login: string,
permission: string,
organization?: string
-): Promise<void> {
+) {
const data: RequestData = { login, permission };
if (projectKey) {
data.projectKey = projectKey;
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(
groupName: string,
permission: string,
organization?: string
-): Promise<void> {
+) {
const data: RequestData = { groupName, permission };
if (projectKey) {
data.projectKey = projectKey;
if (organization) {
data.organization = organization;
}
- return post('/api/permissions/add_group', data);
+ return post('/api/permissions/add_group', data).catch(throwGlobalError);
}
export function revokePermissionFromGroup(
groupName: string,
permission: string,
organization?: string
-): Promise<void> {
+) {
const data: RequestData = { groupName, permission };
if (projectKey) {
data.projectKey = projectKey;
if (organization) {
data.organization = organization;
}
- return post('/api/permissions/remove_group', data);
+ return post('/api/permissions/remove_group', data).catch(throwGlobalError);
}
interface GetPermissionTemplatesResponse {
.setData(data)
.submit()
.then(checkStatus)
- .then(parseJSON);
+ .then(parseJSON)
+ .catch(throwGlobalError);
}
export function restoreQualityProfile(data: RequestData): Promise<any> {
.setData(data)
.submit()
.then(checkStatus)
- .then(parseJSON);
+ .then(parseJSON)
+ .catch(throwGlobalError);
}
export interface ProfileProject {
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<
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';
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
appState: getAppState(state)
});
setAdminPages
};
-export default connect<StateProps, DispatchToProps, OwnProps>(
+export default connect(
mapStateToProps,
mapDispatchToProps
)(AdminContainer);
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'));
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
appState: getAppState(state),
currentUser: getCurrentUser(state),
enableGravatar: (getGlobalSettingValue(state, 'sonar.lf.enableGravatar') || {}).value === 'true',
const mapDispatchToProps = { fetchOrganizations };
-export default connect<any, any, any>(
+export default connect(
null,
mapDispatchToProps
)(ComponentContainer);
*/
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 {
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);
*/
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)
});
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 {
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
currentUser: getCurrentUser(state)
});
-export default connect<StateProps, {}, OwnProps>(mapStateToProps)(Landing);
+export default connect(mapStateToProps)(Landing);
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;
}
}
-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));
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';
);
interface StateProps {
- canAdmin: boolean;
+ canAdmin?: boolean;
currentEdition?: EditionKey;
currentUser: CurrentUser;
}
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
canAdmin: getAppState(state).canAdmin,
currentEdition: getAppState(state).edition,
currentUser: getCurrentUser(state)
const mapDispatchToProps: DispatchProps = { skipOnboardingAction };
-export default connect<StateProps, DispatchProps, OwnProps>(
+export default connect(
mapStateToProps,
mapDispatchToProps
)(StartupModal);
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';
}
}
-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);
*/
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);
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';
}
}
-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);
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 = {
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';
interface StateProps {
organization?: Organization;
- shouldOrganizationBeDisplayed: boolean;
+ shouldOrganizationBeDisplayed?: boolean;
}
interface OwnProps {
});
}
-const mapStateToProps = (state: any, ownProps: OwnProps): StateProps => ({
+const mapStateToProps = (state: Store, ownProps: OwnProps): StateProps => ({
organization: getOrganizationByKey(state, ownProps.component.organization),
shouldOrganizationBeDisplayed: areThereCustomOrganizations(state)
});
isPullRequest
} from '../../../../helpers/branches';
import { translate } from '../../../../helpers/l10n';
-import { getCurrentUser } from '../../../../store/rootReducer';
+import { getCurrentUser, Store } from '../../../../store/rootReducer';
interface StateProps {
currentUser: CurrentUser;
return currentPage;
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
currentUser: getCurrentUser(state)
});
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';
const GlobalNavPlus = lazyLoad(() => import('./GlobalNavPlus'));
interface StateProps {
- appState: AppState;
+ appState: Pick<AppState, 'canAdmin' | 'globalPages' | 'organizationsEnabled' | 'qualifiers'>;
currentUser: CurrentUser;
}
}
}
-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);
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';
);
}
-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);
import { isSonarCloud } from '../../../../helpers/system';
interface Props {
- appState: AppState;
+ appState: Pick<AppState, 'canAdmin' | 'globalPages' | 'organizationsEnabled' | 'qualifiers'>;
currentUser: CurrentUser;
location: { pathname: string };
}
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)
});
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: '' };
<GlobalNavMenu
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
<Search
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
<Connect(GlobalNavUser)
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
<GlobalNavMenu
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
<Search
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
<Connect(GlobalNavUser)
appState={
Object {
+ "canAdmin": false,
+ "globalPages": Array [],
+ "organizationsEnabled": false,
"qualifiers": Array [],
}
}
import { CurrentUser, AppState } from '../../types';
export interface Props {
- appState: AppState;
+ appState: Pick<AppState, 'organizationsEnabled'>;
currentUser: CurrentUser;
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+// @flow
+/*:: export type Metric = {
+ bestValue?: string,
+ custom?: boolean,
+ decimalScale?: number,
+ description?: string,
+ direction?: number,
+ domain?: string,
+ hidden?: boolean,
+ key: string,
+ name: string,
+ qualitative?: boolean,
+ type: string
+}; */
* 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
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 {
* 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();
*/
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>;
// @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();
* 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);
}
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';
}
}
-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));
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 {
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
anyoneCanCreate: getGlobalSettingValue(state, 'sonar.organizations.anyoneCanCreate'),
canAdmin: getAppState(state).canAdmin,
organizations: getMyOrganizations(state)
*/
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));
});
*/
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
});
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';
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));
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';
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
installedLanguages: Object.values(getLanguages(state))
});
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 } };
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
referencedLanguages: getLanguages(state)
});
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';
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 },
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 },
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 },
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;
} 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 },
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 },
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,
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 {
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);
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();
}
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' })
// 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')));
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';
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
installedLanguages: Object.values(getLanguages(state))
});
fetchPendingPlugins: () => void;
location: { pathname: string; query: RawQuery };
pendingPlugins: PluginPendingResult;
- standaloneMode: boolean;
+ standaloneMode?: boolean;
updateCenterActive: boolean;
}
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';
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,
</MarketplaceContext.Consumer>
);
-export default connect<StateToProps, {}, OwnProps>(mapStateToProps)(WithMarketplaceContext);
+export default connect(mapStateToProps)(WithMarketplaceContext);
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 };
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);
*/
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));
+ });
};
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';
}
}
-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,
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 {
}
}
-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);
const mapDispatchToProps: DispatchToProps = { deleteOrganization: deleteOrganization as any };
-export default connect<null, DispatchToProps, OwnProps>(
+export default connect(
null,
mapDispatchToProps
)(OrganizationDelete);
const mapDispatchToProps = { updateOrganization: updateOrganization as any };
-export default connect<{}, DispatchProps, OwnProps>(
+export default connect(
null,
mapDispatchToProps
)(OrganizationEdit);
import {
getOrganizationByKey,
getCurrentUser,
- getMyOrganizations
+ getMyOrganizations,
+ Store
} from '../../../store/rootReducer';
interface OwnProps {
}
}
-const mapStateToProps = (state: any, ownProps: OwnProps) => ({
+const mapStateToProps = (state: Store, ownProps: OwnProps) => ({
currentUser: getCurrentUser(state),
organization: getOrganizationByKey(state, ownProps.params.organizationKey),
userOrganizations: getMyOrganizations(state)
const mapDispatchToProps = { fetchOrganization: fetchOrganization as any };
-export default connect<StateProps, DispatchToProps, OwnProps>(
+export default connect(
mapStateToProps,
mapDispatchToProps
)(OrganizationPage);
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>;
}
}
- const mapStateToProps = (state: any) => ({
+ const mapStateToProps = (state: Store) => ({
customOrganizations: areThereCustomOrganizations(state)
});
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)
});
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;
);
}
-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);
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';
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);
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 {
);
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
currentUser: getCurrentUser(state)
});
-export default connect<StateProps, {}, OwnProps>(mapStateToProps)(SonarCloudEmptyOverview);
+export default connect(mapStateToProps)(SonarCloudEmptyOverview);
import {
getCurrentUser,
getMyOrganizations,
- getOrganizationByKey
+ getOrganizationByKey,
+ Store
} from '../../../store/rootReducer';
import PrivacyBadgeContainer from '../../../components/common/PrivacyBadgeContainer';
}
}
-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);
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 {
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
languages: getLanguages(state)
});
-export default connect<StateProps, {}, OwnProps>(mapStateToProps)(MetaQualityProfiles);
+export default connect(mapStateToProps)(MetaQualityProfiles);
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>
* 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 {
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),
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) =>
};
};
-export default connect<StateToProps, DispatchToProps, OwnProps>(
+export default connect(
mapStateToProps,
mapDispatchToProps
)(AllHoldersList);
qualifier: string,
visibility: string
},
- onComponentChange: (changes: {}) => void,
- onRequestFail: Object => void
+ onComponentChange: (changes: {}) => void
|};
*/
loading: false,
groups: this.removePermissionFromGroup(group, permission)
});
- this.props.onRequestFail(error);
}
});
}
loading: false,
users: this.removePermissionFromUser(user, permission)
});
- this.props.onRequestFail(error);
}
});
}
loading: false,
groups: this.addPermissionToGroup(group, permission)
});
- this.props.onRequestFail(error);
}
});
}
loading: false,
users: this.addPermissionToUser(user, permission)
});
- this.props.onRequestFail(error);
}
});
}
*/
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);
*/
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;
return <div className="alert alert-danger">{message}</div>;
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
message: getPermissionsAppError(state)
});
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';
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);
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;
}
);
render() {
- const hasEmail = !!this.props.currentUser.email;
+ const hasEmail = isLoggedIn(this.props.currentUser) && !!this.props.currentUser.email;
const { subscribed } = this.state;
let inner;
*/
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);
subscribed: true
};
-const currentUser = { email: 'foo@example.com' };
+const currentUser = { isLoggedIn: true, email: 'foo@example.com' };
beforeEach(() => {
subscribe.mockClear();
it('renders when no email', () => {
expect(
- shallow(<Subscription component="foo" currentUser={{}} status={status} />)
+ shallow(<Subscription component="foo" currentUser={{ isLoggedIn: false }} status={status} />)
).toMatchSnapshot();
});
addGlobalErrorMessage,
addGlobalSuccessMessage,
closeAllGlobalMessages
-} from '../../../store/globalMessages/duck';
+} from '../../../store/globalMessages';
import RecentHistory from '../../../app/components/RecentHistory';
class BulkUpdate extends React.PureComponent {
addGlobalErrorMessage,
addGlobalSuccessMessage,
closeAllGlobalMessages
-} from '../../../store/globalMessages/duck';
+} from '../../../store/globalMessages';
import RecentHistory from '../../../app/components/RecentHistory';
import { getProjectAdminProjectModules } from '../../../store/rootReducer';
*/
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);
isFavorite: boolean;
location: { pathname: string; query: RawQuery };
organization: Organization | undefined;
- organizationsEnabled: boolean;
+ organizationsEnabled?: boolean;
storageOptionsSuffix?: string;
}
* 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')));
*/
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);
*/
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) };
}
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';
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
organizations: getMyOrganizations(state)
});
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;
*/
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);
interface Props {
organization?: { key: string; name: string };
- organizationsEnabled: boolean;
+ organizationsEnabled?: boolean;
}
export default function ProjectCardOrganization({ organization, organizationsEnabled }: Props) {
*/
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);
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';
}
}
-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);
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';
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);
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';
*/
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);
import { translate, translateWithParameters } from '../../../helpers/l10n';
interface Props {
- displayOrganizations: boolean;
+ displayOrganizations?: boolean;
projects: Project[];
sort?: string;
total?: number;
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';
interface OwnProps {
onRequestFail: (error: any) => void;
+ organization: Organization;
}
class AppContainer extends React.PureComponent<OwnProps & StateProps & DispatchProps> {
}
}
-const mapStateToProps = (state: any, ownProps: any) => ({
+const mapStateToProps = (state: Store, ownProps: OwnProps) => ({
appState: getAppState(state),
currentUser: getCurrentUser(state) as LoggedInUser,
organization:
});
export default forSingleOrganization(
- connect<StateProps, DispatchProps, OwnProps>(
+ connect(
mapStateToProps,
mapDispatchToProps
)(AppContainer)
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';
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);
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;
}
languages: finalLanguages,
exporters: this.state.exporters,
updateProfiles: this.updateProfiles,
- onRequestFail: this.props.onRequestFail,
organization: organization ? organization.key : null
});
}
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));
interface Props {
onClose: () => void;
onCopy: (name: string) => void;
- onRequestFail: (reasong: any) => void;
profile: Profile;
}
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);
}
);
}
interface Props {
onClose: () => void;
onDelete: () => void;
- onRequestFail: (reason: any) => void;
profile: Profile;
}
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);
});
};
interface Props {
className?: string;
fromList?: boolean;
- onRequestFail: (reasong: any) => void;
organization: string | null;
profile: Profile;
updateProfiles: () => Promise<void>;
<CopyProfileForm
onClose={this.closeCopyForm}
onCopy={this.handleProfileCopy}
- onRequestFail={this.props.onRequestFail}
profile={profile}
/>
)}
<DeleteProfileForm
onClose={this.closeDeleteForm}
onDelete={this.handleProfileDelete}
- onRequestFail={this.props.onRequestFail}
profile={profile}
/>
)}
<RenameProfileForm
onClose={this.closeRenameForm}
onRename={this.handleProfileRename}
- onRequestFail={this.props.onRequestFail}
profile={profile}
/>
)}
pathname: string;
query: { key?: string; language: string; name: string };
};
- onRequestFail: (reasong: any) => void;
organization: string | null;
profiles: Profile[];
updateProfiles: () => Promise<void>;
}
const child = React.cloneElement(this.props.children, {
- onRequestFail: this.props.onRequestFail,
organization,
profile,
profiles,
<div id="quality-profile">
<Helmet title={profile.name} />
<ProfileHeader
- onRequestFail={this.props.onRequestFail}
organization={organization}
profile={profile}
updateProfiles={this.props.updateProfiles}
interface Props {
onClose: () => void;
onRename: (name: string) => void;
- onRequestFail: (reason: any) => void;
profile: Profile;
}
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);
}
);
}
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();
});
expect(
shallow(
<ProfileActions
- onRequestFail={jest.fn()}
organization="org"
profile={{ ...PROFILE, actions: { edit: true } }}
updateProfiles={jest.fn()}
expect(
shallow(
<ProfileActions
- onRequestFail={jest.fn()}
organization="org"
profile={{
...PROFILE,
const push = jest.fn();
const wrapper = shallow(
<ProfileActions
- onRequestFail={jest.fn()}
organization="org"
profile={{ ...PROFILE, actions: { copy: true } }}
updateProfiles={updateProfiles}
const output = shallow(
<ProfileContainer
location={{ pathname: '', query: { language: 'js', name: 'fake' } }}
- onRequestFail={jest.fn()}
organization={null}
profiles={profiles}
updateProfiles={updateProfiles}
const output = shallow(
<ProfileContainer
location={{ pathname: '', query: { language: 'js', name: 'random' } }}
- onRequestFail={jest.fn()}
organization={null}
profiles={profiles}
updateProfiles={jest.fn()}
const output = shallow(
<ProfileContainer
location={{ pathname: '', query: { language: 'js', name: 'First Profile' } }}
- onRequestFail={jest.fn()}
organization={null}
profiles={profiles}
updateProfiles={updateProfiles}
interface Props {
onChange: () => void;
onClose: () => void;
- onRequestFail: (reasong: any) => void;
profile: Profile;
profiles: Profile[];
}
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);
});
}
};
interface Props {
exporters: Exporter[];
- onRequestFail: (reasong: any) => void;
organization: string | null;
profile: Profile;
profiles: Profile[];
import { Profile } from '../types';
interface Props {
- onRequestFail: (reasong: any) => void;
profile: Profile;
organization: string | null;
updateProfiles: () => Promise<void>;
<li>
<ProfileActions
className="pull-left"
- onRequestFail={this.props.onRequestFail}
organization={organization}
profile={profile}
updateProfiles={this.props.updateProfiles}
import { translate } from '../../../helpers/l10n';
interface Props {
- onRequestFail: (reason: any) => void;
organization: string | null;
profile: Profile;
profiles: Profile[];
<ChangeParentForm
onChange={this.handleParentChange}
onClose={this.closeForm}
- onRequestFail={this.props.onRequestFail}
profile={profile}
profiles={profiles.filter(p => p !== profile && p.language === profile.language)}
/>
shallow(
<ProfileDetails
exporters={[]}
- onRequestFail={jest.fn()}
organization="org"
profile={{} as Profile}
profiles={[]}
shallow(
<ProfileDetails
exporters={[]}
- onRequestFail={jest.fn()}
organization="org"
profile={{ actions: { edit: true } } as Profile}
profiles={[]}
>
<ProfileRules
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
/>
<ProfileExporters
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
>
<ProfileInheritance
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
/>
<ProfileProjects
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={
Object {
>
<ProfileRules
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
/>
<ProfileExporters
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
>
<ProfileInheritance
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
/>
<ProfileProjects
exporters={Array []}
- onRequestFail={[MockFunction]}
organization="org"
profile={Object {}}
profiles={Array []}
languages: Array<{ key: string; name: string }>;
onClose: () => void;
onCreate: Function;
- onRequestFail: (reasong: any) => void;
organization: string | null;
}
createQualityProfile(data).then(
(response: any) => this.props.onCreate(response.profile),
- (error: any) => {
+ () => {
if (this.mounted) {
this.setState({ loading: false });
}
- this.props.onRequestFail(error);
}
);
};
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>;
interface Props {
actions: Actions;
languages: Array<{ key: string; name: string }>;
- onRequestFail: (reason: any) => void;
organization: string | null;
updateProfiles: () => Promise<void>;
}
{this.state.restoreFormOpen && (
<RestoreProfileForm
onClose={this.closeRestoreForm}
- onRequestFail={this.props.onRequestFail}
onRestore={this.props.updateProfiles}
organization={this.props.organization}
/>
languages={this.props.languages}
onClose={this.closeCreateForm}
onCreate={this.handleCreate}
- onRequestFail={this.props.onRequestFail}
organization={this.props.organization}
/>
)}
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>;
return profiles.map(profile => (
<ProfilesListRow
key={profile.key}
- onRequestFail={this.props.onRequestFail}
organization={this.props.organization}
profile={profile}
updateProfiles={this.props.updateProfiles}
import DocTooltip from '../../../components/docs/DocTooltip';
interface Props {
- onRequestFail: (reason: any) => void;
organization: string | null;
profile: Profile;
updateProfiles: () => Promise<void>;
<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}
interface Props {
onClose: () => void;
- onRequestFail: (reason: any) => void;
onRestore: () => void;
organization: string | null;
}
}
this.props.onRestore();
},
- (error: any) => {
+ () => {
if (this.mounted) {
this.setState({ loading: false });
}
- this.props.onRequestFail(error);
}
);
};
const mapStateToProps = null;
const mapDispatchToProps = { doLogin: doLogin as any };
-export default connect<{}, DispatchToProps, OwnProps>(
+export default connect(
mapStateToProps,
mapDispatchToProps
)(LoginContainer);
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';
import {
addGlobalErrorMessage,
closeAllGlobalMessages
-} from '../../../../store/globalMessages/duck';
+} from '../../../../store/globalMessages';
export const UPDATE_ENCRYPTION = 'UPDATE_ENCRYPTION';
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'; */
/*::
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 {
}
}
-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);
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';
const mapDispatchToProps: DispatchProps = { skipOnboardingAction };
-export default connect<{}, DispatchProps>(
+export default connect(
null,
mapDispatchToProps
)(OnboardingPage);
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';
interface StateProps {
currentUser: CurrentUser;
- organizationsEnabled: boolean;
+ organizationsEnabled?: boolean;
}
type Props = OwnProps & StateProps;
}
}
-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);
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;
const mapDispatchToProps: DispatchProps = { skipOnboarding };
-export default connect<{}, DispatchProps>(
+export default connect(
null,
mapDispatchToProps
)(ProjectOnboardingPage);
interface Props {
currentUser: { isLoggedIn: boolean; login?: string };
location: Location;
- organizationsEnabled: boolean;
+ organizationsEnabled?: boolean;
}
interface State {
* 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);
currentUser: { isLoggedIn: boolean; login?: string };
identityProviders: IdentityProvider[];
onUpdateUsers: () => void;
- organizationsEnabled: boolean;
+ organizationsEnabled?: boolean;
updateTokensCount: (login: string, tokensCount: number) => void;
users: User[];
}
identityProvider?: IdentityProvider;
isCurrentUser: boolean;
onUpdateUsers: () => void;
- organizationsEnabled: boolean;
+ organizationsEnabled?: boolean;
updateTokensCount: (login: string, tokensCount: number) => void;
user: User;
}
* 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;
}
if (langKey === '<null>') {
return translate('unknown');
}
- const lang = find(props.languages, { key: langKey });
+ const lang = props.languages[langKey];
return lang ? lang.name : langKey;
}
}
*/
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);
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}
/>
)
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';
);
}
-const mapStateToProps = (state: any, { organization }: OwnProps) => {
+const mapStateToProps = (state: Store, { organization }: OwnProps) => {
if (typeof organization === 'string') {
organization = getOrganizationByKey(state, organization);
}
};
};
-export default connect<StateToProps, {}, OwnProps>(mapStateToProps)(PrivacyBadge);
+export default connect(mapStateToProps)(PrivacyBadge);
function getDoc(visibility: Visibility, icon: JSX.Element | null, organization: Organization) {
let doc;
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;
}
}
-const mapStateToProps = (state: any): StateProps => ({
+const mapStateToProps = (state: Store): StateProps => ({
currentUser: getCurrentUser(state)
});
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', () => ({
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();
});
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';
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
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}
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
};
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() {
displayLocationsCount={this.props.displayLocationsCount}
displayLocationsLink={this.props.displayLocationsLink}
issue={issue}
- onFail={this.props.onFail}
onFilter={this.props.onFilter}
togglePopup={this.props.togglePopup}
/>
issue={issue}
onAssign={this.props.onAssign}
onChange={this.props.onChange}
- onFail={this.props.onFail}
togglePopup={this.props.togglePopup}
/>
{issue.comments &&
export const updateIssue = (
onChange /*: Issue => void */,
- onFail /*: Error => void */,
resultPromise /*: Promise<*> */,
oldIssue /*: ?Issue */,
newIssue /*: ?Issue */
}
},
error => {
- onFail(error);
if (optimisticUpdate) {
// $FlowFixMe `oldIssue` is not null, because `optimisticUpdate` is true
onChange(oldIssue);
currentPopup: ?string,
onAssign: string => void,
onChange: Issue => void,
- onFail: Error => void,
togglePopup: (string, boolean | void) => void
};
*/
const newIssue = { ...issue, [property]: value };
updateIssue(
this.props.onChange,
- this.props.onFail,
apiCall({ issue: issue.key, [property]: value }),
issue,
newIssue
isOpen={this.props.currentPopup === 'transition' && hasTransitions}
issue={issue}
onChange={this.handleTransition}
- onFail={this.props.onFail}
togglePopup={this.props.togglePopup}
/>
</li>
isOpen={this.props.currentPopup === 'assign' && canAssign}
issue={issue}
onAssign={this.props.onAssign}
- onFail={this.props.onFail}
togglePopup={this.props.togglePopup}
/>
</li>
currentPopup={this.props.currentPopup}
issueKey={issue.key}
onChange={this.props.onChange}
- onFail={this.props.onFail}
toggleComment={this.toggleComment}
/>
)}
isOpen={this.props.currentPopup === 'edit-tags' && canSetTags}
issue={issue}
onChange={this.props.onChange}
- onFail={this.props.onFail}
togglePopup={this.props.togglePopup}
/>
</li>
issue: Issue,
canAssign: boolean,
onAssign: string => void,
- onFail: Error => void,
togglePopup: (string, boolean | void) => void
};
*/
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}>
isOpen: boolean,
issue: Issue,
creationDate: string,
- togglePopup: (string, boolean | void) => void,
- onFail: Error => void
+ togglePopup: (string, boolean | void) => void
};
*/
<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} />}>
currentPopup: ?string,
issueKey: string,
onChange: Issue => void,
- onFail: Error => void,
toggleComment: (open?: boolean, placeholder?: string) => void
|};
*/
/*:: 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);
};
isOpen: boolean,
issue: Issue,
onChange: Issue => void,
- onFail: Error => void,
togglePopup: (string, boolean | void) => void
|};
*/
const newIssue = { ...issue, tags };
updateIssue(
this.props.onChange,
- this.props.onFail,
setIssueTags({ issue: issue.key, tags: tags.join(',') }),
issue,
newIssue
displayLocationsCount?: boolean;
displayLocationsLink?: boolean;
issue: Issue,
- onFail: Error => void,
onFilter?: (property: string, issue: Issue) => void,
togglePopup: (string, boolean | void) => void
|};
creationDate={issue.creationDate}
isOpen={props.currentPopup === 'changelog'}
issue={issue}
- onFail={props.onFail}
togglePopup={props.togglePopup}
/>
</li>
<SimilarIssuesFilter
isOpen={props.currentPopup === 'similarIssues'}
issue={issue}
- onFail={props.onFail}
onFilter={props.onFilter}
togglePopup={props.togglePopup}
/>
isOpen: boolean,
issue: Issue,
onChange: Issue => void,
- onFail: Error => void,
togglePopup: (string, boolean | void) => void
};
*/
setTransition = (transition /*: string */) => {
updateIssue(
this.props.onChange,
- this.props.onFail,
setIssueTransition({ issue: this.props.issue.key, transition })
);
this.toggleSetTransition();
isOpen: boolean,
issue: Issue,
togglePopup: (string, boolean | void) => void,
- onFail: Error => void,
onFilter: (property: string, issue: Issue) => void
|};
*/
isOpen={false}
issue={issue}
onAssign={jest.fn()}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
isOpen={false}
issue={issue}
onAssign={jest.fn()}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
isOpen={false}
issue={issue}
onAssign={jest.fn()}
- onFail={jest.fn()}
togglePopup={toggle}
/>
);
creationDate="2017-03-01T09:36:01+0100"
isOpen={false}
issue={issue}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
creationDate="2017-03-01T09:36:01+0100"
isOpen={false}
issue={issue}
- onFail={jest.fn()}
togglePopup={toggle}
/>
);
<IssueCommentAction
currentPopup={null}
issueKey="issue-key"
- onFail={jest.fn()}
onIssueChange={jest.fn()}
toggleComment={jest.fn()}
/>
<IssueCommentAction
currentPopup={null}
issueKey="issue-key"
- onFail={jest.fn()}
onIssueChange={jest.fn()}
toggleComment={toggle}
/>
transitions: [],
status: 'CLOSED'
}}
- onFail={jest.fn()}
onIssueChange={jest.fn()}
togglePopup={jest.fn()}
/>
canSetTags={true}
isOpen={false}
issue={issue}
- onFail={jest.fn()}
onIssueChange={jest.fn()}
togglePopup={jest.fn()}
/>
canSetTags={true}
isOpen={false}
issue={issue}
- onFail={jest.fn()}
onIssueChange={jest.fn()}
togglePopup={toggle}
/>
branchLike={{ isMain: false, name: 'feature-1.0', type: 'SHORT' }}
currentPopup={null}
issue={issue}
- onFail={jest.fn()}
togglePopup={jest.fn()}
/>
);
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();
});
"assigneeName": "John Doe",
}
}
- onFail={[MockFunction]}
onSelect={[MockFunction]}
/>
}
"assigneeName": "John Doe",
}
}
- onFail={[MockFunction]}
onSelect={[MockFunction]}
/>
}
"key": "issuekey",
}
}
- onFail={[MockFunction]}
/>
}
>
"key": "issuekey",
}
}
- onFail={[MockFunction]}
/>
}
>
},
}
}
- onFail={[MockFunction]}
togglePopup={[MockFunction]}
/>
</li>
},
}
}
- onFail={[MockFunction]}
togglePopup={[MockFunction]}
/>
</li>
},
}
}
- onFail={[MockFunction]}
onFilter={[MockFunction]}
togglePopup={[MockFunction]}
/>
/*::
type Props = {
issue: Issue,
- onFail: Error => void,
popupPosition?: {}
};
*/
}
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() {
type Props = {
currentUser: User,
issue: Issue,
- onFail: Error => void,
onSelect: string => void,
popupPosition?: {}
};
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({
author: 'john.david.dalton@gmail.com',
creationDate: '2017-03-01T09:36:01+0100'
}}
- onFail={jest.fn()}
/>
);
element.setState({
* 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,
*/
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 {
link?: boolean;
linkClassName?: string;
organization: { key: string; name: string } | null;
- shouldBeDisplayed: boolean;
+ shouldBeDisplayed?: boolean;
}
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;
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;
);
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: Store) => ({
enableGravatar: (getGlobalSettingValue(state, 'sonar.lf.enableGravatar') || {}).value === 'true',
gravatarServerUrl: (getGlobalSettingValue(state, 'sonar.lf.gravatarServerUrl') || {}).value
});
--- /dev/null
+// 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",
+ ],
+}
+`;
--- /dev/null
+/*
+ * 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);
+ });
+});
--- /dev/null
+/*
+ * 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 { ActionType } from './utils/actions';
+import { Extension, AppState } from '../app/types';
+import { EditionKey } from '../apps/marketplace/utils';
+
+type Action =
+ | ActionType<typeof setAppState, 'SET_APP_STATE'>
+ | ActionType<typeof setAdminPages, 'SET_ADMIN_PAGES'>
+ | ActionType<typeof requireAuthorization, 'REQUIRE_AUTHORIZATION'>;
+
+export function setAppState(appState: AppState) {
+ return { type: 'SET_APP_STATE', appState };
+}
+
+export function setAdminPages(adminPages: Extension[]) {
+ return { type: 'SET_ADMIN_PAGES', adminPages };
+}
+
+export function requireAuthorization() {
+ return { type: 'REQUIRE_AUTHORIZATION' };
+}
+
+const defaultValue: AppState = {
+ authenticationError: false,
+ authorizationError: false,
+ defaultOrganization: '',
+ edition: EditionKey.community,
+ organizationsEnabled: false,
+ productionDatabase: true,
+ qualifiers: [],
+ version: ''
+};
+
+export default function(state: AppState = defaultValue, action: Action): AppState {
+ if (action.type === 'SET_APP_STATE') {
+ return { ...state, ...action.appState };
+ }
+
+ if (action.type === 'SET_ADMIN_PAGES') {
+ return { ...state, adminPages: action.adminPages };
+ }
+
+ if (action.type === 'REQUIRE_AUTHORIZATION') {
+ return { ...state, authorizationError: true };
+ }
+
+ return state;
+}
+++ /dev/null
-/*
- * 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 { Extension, AppState } from '../../app/types';
-
-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;
-
-export function setAppState(appState: AppState): SetAppStateAction {
- return {
- type: 'SET_APP_STATE',
- appState
- };
-}
-
-export function setAdminPages(adminPages: Extension[]): SetAdminPagesAction {
- return { type: 'SET_ADMIN_PAGES', adminPages };
-}
-
-export function requireAuthorization(): RequireAuthorizationAction {
- return { type: 'REQUIRE_AUTHORIZATION' };
-}
-
-const defaultValue: AppState = {
- authenticationError: false,
- authorizationError: false,
- organizationsEnabled: false,
- qualifiers: []
-};
-
-export default function(state: AppState = defaultValue, action: Action): AppState {
- if (action.type === 'SET_APP_STATE') {
- return { ...state, ...action.appState };
- }
-
- if (action.type === 'SET_ADMIN_PAGES') {
- return { ...state, adminPages: action.adminPages };
- }
-
- if (action.type === 'REQUIRE_AUTHORIZATION') {
- return { ...state, authorizationError: true };
- }
-
- return state;
-}
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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 { keyBy } from 'lodash';
+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 };
+}
+
+export default function(state: Languages = {}, action: Action): Languages {
+ if (action.type === 'RECEIVE_LANGUAGES') {
+ return keyBy(action.languages, 'key');
+ }
+
+ return state;
+}
+
+export function getLanguages(state: Languages) {
+ return state;
+}
+
+export function getLanguageByKey(state: Languages, key: string) {
+ return state[key];
+}
+++ /dev/null
-/*
- * 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.
- */
-export const RECEIVE_LANGUAGES = 'RECEIVE_LANGUAGES';
-
-export const receiveLanguages = languages => ({
- type: RECEIVE_LANGUAGES,
- languages
-});
+++ /dev/null
-/*
- * 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 { keyBy } from 'lodash';
-import { RECEIVE_LANGUAGES } from './actions';
-
-export interface Languages {
- [key: string]: { key: string; name: string };
-}
-
-const reducer = (state: Languages = {}, action: any = {}) => {
- if (action.type === RECEIVE_LANGUAGES) {
- return keyBy(action.languages, 'key');
- }
-
- return state;
-};
-
-export default reducer;
-
-export const getLanguages = (state: Languages) => state;
-
-export const getLanguageByKey = (state: Languages, key: string) => state[key];
--- /dev/null
+/*
+ * 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 { keyBy } from 'lodash';
+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 Action = ActionType<typeof receiveMetrics, '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: State['keys'] = [], action: Action) => {
+ if (action.type === 'RECEIVE_METRICS') {
+ return action.metrics.map(f => f.key);
+ }
+
+ return state;
+};
+
+export default combineReducers({ byKey, keys });
+
+export function getMetrics(state: State) {
+ return state.byKey;
+}
+
+export function getMetricsKey(state: State) {
+ return state.keys;
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-// @flow
-/*:: export type Metric = {
- bestValue?: string,
- custom?: boolean,
- decimalScale?: number,
- description?: string,
- direction?: number,
- domain?: string,
- hidden?: boolean,
- key: string,
- name: string,
- qualitative?: boolean,
- type: string
-}; */
-
-export const RECEIVE_METRICS = 'RECEIVE_METRICS';
-
-export const receiveMetrics = (metrics /*: Array<Metric> */) => ({
- type: RECEIVE_METRICS,
- metrics
-});
+++ /dev/null
-/*
- * 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 { combineReducers } from 'redux';
-import { keyBy } from 'lodash';
-import { RECEIVE_METRICS } from './actions';
-/*:: import type { Metric } from './actions'; */
-
-/*::
-type StateByKey = { [string]: Metric };
-type StateKeys = Array<string>;
-type State = { byKey: StateByKey, keys: StateKeys };
-*/
-
-const byKey = (state /*: StateByKey */ = {}, action = {}) => {
- if (action.type === RECEIVE_METRICS) {
- return keyBy(action.metrics, 'key');
- }
- return state;
-};
-
-const keys = (state /*: StateKeys */ = [], action = {}) => {
- if (action.type === RECEIVE_METRICS) {
- return action.metrics.map(f => f.key);
- }
-
- return state;
-};
-
-export default combineReducers({ byKey, keys });
-
-export const getMetrics = (state /*: State */) => state.byKey;
-export const getMetricsKey = (state /*: State */) => state.keys;
--- /dev/null
+/*
+ * 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;
+}
+++ /dev/null
-// 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 [],
-}
-`;
+++ /dev/null
-/*
- * 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);
- });
-});
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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();
- }
- );
--- /dev/null
+/*
+ * 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();
+ }
+ );
+}
+++ /dev/null
-/*
- * 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);
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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));
+}
+++ /dev/null
-/*
- * 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 });
- },
- () => {}
- );
-};
+++ /dev/null
-/*
- * 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));
--- /dev/null
+/*
+ * 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 { Omit } from '../../app/types';
+
+type ActionCreator = (...args: any[]) => { type: string };
+
+export type ActionType<F extends ActionCreator, T> = Omit<ReturnType<F>, 'type'> & { type: T };
+++ /dev/null
-/*
- * 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 { createStore, applyMiddleware, compose } from 'redux';
-import thunk from 'redux-thunk';
-
-const middlewares = [thunk];
-const composed = [];
-
-if (process.env.NODE_ENV === 'development') {
- const { createLogger } = require('redux-logger');
- middlewares.push(createLogger());
-
- composed.push(window.devToolsExtension ? window.devToolsExtension() : f => f);
-}
-
-const finalCreateStore = compose(
- applyMiddleware(...middlewares),
- ...composed
-)(createStore);
-
-export default function configureStore(rootReducer, initialState) {
- return finalCreateStore(rootReducer, initialState);
-}
--- /dev/null
+/*
+ * 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 { 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 = [];
+
+if (process.env.NODE_ENV === 'development') {
+ const { createLogger } = require('redux-logger');
+ middlewares.push(createLogger());
+
+ const { devToolsExtension } = window as any;
+ composed.push(devToolsExtension ? devToolsExtension() : (f: Function) => f);
+}
+
+const finalCreateStore = compose(
+ applyMiddleware(...middlewares),
+ ...composed
+)(createStore);
+
+export default function configureStore(rootReducer: RootReducer, initialState?: State) {
+ return finalCreateStore(rootReducer, initialState);
+}