Skip to content

Commit

Permalink
Merge pull request #3294 from dlabrecq/accountSettings
Browse files Browse the repository at this point in the history
Update cost type and currency APIs
  • Loading branch information
dlabrecq authored Jul 26, 2023
2 parents 444fef6 + f629f89 commit 6947477
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 23 deletions.
16 changes: 16 additions & 0 deletions src/api/accountSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ export interface AccountSettings {
data: AccountSettingsData;
}

export interface CostTypePayload {
cost_type?: string;
}

export interface CurrencyPayload {
currency?: string;
}

export function fetchAccountSettings() {
return axios.get<AccountSettings>(`account-settings/`);
}

export function updateCostType(payload: CostTypePayload) {
return axios.put(`account-settings/cost-type`, payload);
}

export function updateCurrency(payload: CurrencyPayload) {
return axios.put(`account-settings/currency`, payload);
}
37 changes: 17 additions & 20 deletions src/routes/settings/calculations/calculations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { CostType } from 'routes/components/costType';
import { Currency } from 'routes/components/currency';
import { accountSettingsActions, accountSettingsSelectors } from 'store/accountSettings';
import type { FetchStatus } from 'store/common';
import { createMapStateToProps } from 'store/common';
import { rbacActions, rbacSelectors } from 'store/rbac';
import { settingsActions, settingsSelectors } from 'store/settings';
import { getCostType, getCurrency, setAccountCurrency, setCostType, setCurrency } from 'utils/localStorage';
import type { RouterComponentProps } from 'utils/router';
import { withRouter } from 'utils/router';
Expand All @@ -22,12 +22,14 @@ interface SettingsOwnProps {

interface SettingsDispatchProps {
fetchRbac: typeof rbacActions.fetchRbac;
updateSettings: typeof settingsActions.updateSettings;
updateCostType: typeof accountSettingsActions.updateCostType;
updateCurrency: typeof accountSettingsActions.updateCurrency;
}

interface SettingsStateProps {
canWrite?: boolean;
updateSettingsStatus: FetchStatus;
updateCostTypeStatus: FetchStatus;
updateCurrencyStatus: FetchStatus;
}

interface SettingsState {
Expand Down Expand Up @@ -109,32 +111,24 @@ class SettingsBase extends React.Component<SettingsProps, SettingsState> {
};

private handleOnCostTypeSelected = value => {
const { updateSettings } = this.props;
const { updateCostType } = this.props;

this.setState({ currentCostType: value }, () => {
setCostType(value);
updateSettings({
api: {
settings: {
cost_type: value,
},
},
updateCostType({
cost_type: value,
});
});
};

private handleOnCurrencySelected = value => {
const { updateSettings } = this.props;
const { updateCurrency } = this.props;

this.setState({ currentCurrency: value }, () => {
setCurrency(value);
setAccountCurrency(value); // Todo: remove account currency after settings page has been moved
updateSettings({
api: {
settings: {
currency: value,
},
},
updateCurrency({
currency: value,
});
});
};
Expand All @@ -156,17 +150,20 @@ class SettingsBase extends React.Component<SettingsProps, SettingsState> {

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const mapStateToProps = createMapStateToProps<SettingsOwnProps, SettingsStateProps>(state => {
const updateSettingsStatus = settingsSelectors.selectSettingsUpdateStatus(state);
const updateCostTypeStatus = accountSettingsSelectors.selectUpdateCostTypeStatus(state);
const updateCurrencyStatus = accountSettingsSelectors.selectUpdateCurrencyStatus(state);

return {
canWrite: rbacSelectors.isSettingsWritePermission(state),
updateSettingsStatus,
updateCostTypeStatus,
updateCurrencyStatus,
};
});

const mapDispatchToProps: SettingsDispatchProps = {
fetchRbac: rbacActions.fetchRbac,
updateSettings: settingsActions.updateSettings,
updateCostType: accountSettingsActions.updateCostType,
updateCurrency: accountSettingsActions.updateCurrency,
};

const Calculations = injectIntl(withRouter(connect(mapStateToProps, mapDispatchToProps)(SettingsBase)));
Expand Down
78 changes: 77 additions & 1 deletion src/store/accountSettings/accountSettingsActions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import type { AccountSettings } from 'api/accountSettings';
import { AlertVariant } from '@patternfly/react-core';
import { addNotification } from '@redhat-cloud-services/frontend-components-notifications/redux';
import type { AccountSettings, CostTypePayload, CurrencyPayload } from 'api/accountSettings';
import { fetchAccountSettings as apiGetAccountSettings } from 'api/accountSettings';
import { updateCostType as apiUpdateCostType, updateCurrency as apiUpdateCurrency } from 'api/accountSettings';
import type { AxiosError } from 'axios';
import type { AxiosResponse } from 'axios';
import { intl } from 'components/i18n';
import messages from 'locales/messages';
import type { ThunkAction } from 'store/common';
import { FetchStatus } from 'store/common';
import { createAction } from 'typesafe-actions';
Expand All @@ -21,6 +27,16 @@ export const fetchAccountSettingsFailure = createAction('accountSettings/fetch/f
AxiosError,
AccountSettingsActionMeta
>();
export const updateCostTypeRequest = createAction('accountSettings/update/costType/request')<void>();
export const updateCostTypeSuccess = createAction('accountSettings/update/costType/success')<
AxiosResponse<CostTypePayload>
>();
export const updateCostTypeFailure = createAction('accountSettings/update/costType/failure')<AxiosError>();
export const updateCurrencyRequest = createAction('accountSettings/update/currency/request')<void>();
export const updateCurrencySuccess = createAction('accountSettings/update/currency/success')<
AxiosResponse<CurrencyPayload>
>();
export const updateCurrencyFailure = createAction('accountSettings/update/currency/failure')<AxiosError>();

export function fetchAccountSettings(): ThunkAction {
return (dispatch, getState) => {
Expand All @@ -46,3 +62,63 @@ export function fetchAccountSettings(): ThunkAction {
});
};
}

export function updateCostType(payload): ThunkAction {
return dispatch => {
dispatch(updateCostTypeRequest());

return apiUpdateCostType(payload)
.then((res: any) => {
dispatch(updateCostTypeSuccess(res));
dispatch(
addNotification({
title: intl.formatMessage(messages.settingsSuccessTitle),
description: intl.formatMessage(messages.settingsSuccessDesc),
variant: AlertVariant.success,
dismissable: true,
})
);
})
.catch(err => {
dispatch(updateCostTypeFailure(err));
dispatch(
addNotification({
title: intl.formatMessage(messages.settingsErrorTitle),
description: intl.formatMessage(messages.settingsErrorDesc),
variant: AlertVariant.danger,
dismissable: true,
})
);
});
};
}

export function updateCurrency(payload): ThunkAction {
return dispatch => {
dispatch(updateCurrencyRequest());

return apiUpdateCurrency(payload)
.then((res: any) => {
dispatch(updateCurrencySuccess(res));
dispatch(
addNotification({
title: intl.formatMessage(messages.settingsSuccessTitle),
description: intl.formatMessage(messages.settingsSuccessDesc),
variant: AlertVariant.success,
dismissable: true,
})
);
})
.catch(err => {
dispatch(updateCurrencyFailure(err));
dispatch(
addNotification({
title: intl.formatMessage(messages.settingsErrorTitle),
description: intl.formatMessage(messages.settingsErrorDesc),
variant: AlertVariant.danger,
dismissable: true,
})
);
});
};
}
52 changes: 50 additions & 2 deletions src/store/accountSettings/accountSettingsReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ import {
fetchAccountSettingsFailure,
fetchAccountSettingsRequest,
fetchAccountSettingsSuccess,
updateCostTypeFailure,
updateCostTypeRequest,
updateCostTypeSuccess,
updateCurrencyFailure,
updateCurrencyRequest,
updateCurrencySuccess,
} from './accountSettingsActions';

export type AccountSettingsState = Readonly<{
byId: Map<string, AccountSettings>;
errors: Map<string, AxiosError>;
fetchStatus: Map<string, FetchStatus>;
error?: AxiosError;
errors?: Map<string, AxiosError>;
fetchStatus?: Map<string, FetchStatus>;
status?: FetchStatus;
}>;

export const defaultState: AccountSettingsState = {
Expand All @@ -35,6 +43,12 @@ export type AccountSettingsAction = ActionType<
| typeof fetchAccountSettingsFailure
| typeof fetchAccountSettingsRequest
| typeof fetchAccountSettingsSuccess
| typeof updateCostTypeFailure
| typeof updateCostTypeRequest
| typeof updateCostTypeSuccess
| typeof updateCurrencyFailure
| typeof updateCurrencyRequest
| typeof updateCurrencySuccess
| typeof resetState
>;

Expand Down Expand Up @@ -72,6 +86,40 @@ export function accountSettingsReducer(state = defaultState, action: AccountSett
fetchStatus: new Map(state.fetchStatus).set(action.meta.fetchId, FetchStatus.complete),
errors: new Map(state.errors).set(action.meta.fetchId, action.payload),
};
case getType(updateCostTypeRequest):
return {
...state,
status: FetchStatus.inProgress,
};
case getType(updateCostTypeSuccess):
return {
...state,
error: null,
status: FetchStatus.complete,
};
case getType(updateCostTypeFailure):
return {
...state,
error: action.payload,
status: FetchStatus.complete,
};
case getType(updateCurrencyRequest):
return {
...state,
status: FetchStatus.inProgress,
};
case getType(updateCurrencySuccess):
return {
...state,
error: null,
status: FetchStatus.complete,
};
case getType(updateCurrencyFailure):
return {
...state,
error: action.payload,
status: FetchStatus.complete,
};
default:
return state;
}
Expand Down
9 changes: 9 additions & 0 deletions src/store/accountSettings/accountSettingsSelectors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { RootState } from 'store/rootReducer';
import { selectSettingsState } from 'store/settings/settingsSelectors';

import { getFetchId, stateKey } from './accountSettingsCommon';

Expand All @@ -13,3 +14,11 @@ export const selectAccountSettingsFetchStatus = (state: RootState) =>

export const selectAccountSettingsError = (state: RootState) =>
selectAccountSettingsState(state).errors.get(getFetchId());

export const selectUpdateCostTypeError = (state: RootState) => selectSettingsState(state).error;

export const selectUpdateCostTypeStatus = (state: RootState) => selectSettingsState(state).status;

export const selectUpdateCurrencyError = (state: RootState) => selectSettingsState(state).error;

export const selectUpdateCurrencyStatus = (state: RootState) => selectSettingsState(state).status;

0 comments on commit 6947477

Please sign in to comment.