#22: refactor actions and reducer

This commit is contained in:
SleepWalker 2018-05-05 09:42:21 +03:00
parent 6e9542f592
commit bfff6894b5
5 changed files with 77 additions and 41 deletions

View File

@ -78,7 +78,7 @@
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
"no-unused-expressions": ["warn", {"allowShortCircuit": true, "allowTernary": true}],
"flowtype/no-unused-expressions": ["warn", {"allowShortCircuit": true, "allowTernary": true}],
"no-useless-call": "warn",
"no-useless-concat": "warn",
"no-void": "error",

View File

@ -75,7 +75,7 @@
"css-loader": "^0.28.0",
"enzyme": "^2.2.0",
"eslint": "^4.0.0",
"eslint-plugin-flowtype": "2.35.1",
"eslint-plugin-flowtype": "^2.46.3",
"eslint-plugin-react": "^7.3.0",
"exports-loader": "^0.6.3",
"extract-text-webpack-plugin": "^1.0.0",

View File

@ -1,16 +1,19 @@
// @flow
import oauth from 'services/api/oauth';
import type { Dispatch } from 'redux';
import type { Apps } from './reducer';
import type { OauthAppResponse } from 'services/api/oauth';
import type { User } from 'components/user';
import oauth from 'services/api/oauth';
export const SET_AVAILABLE = 'SET_AVAILABLE';
export function setAppsList(apps: Array<OauthAppResponse>) {
import type { Apps } from './reducer';
type SetAvailableAction = { type: 'apps:setAvailable', payload: Array<OauthAppResponse> };
type DeleteAppAction = { type: 'apps:deleteApp', payload: string };
type AddAppAction = { type: 'apps:addApp', payload: OauthAppResponse };
export type Action = SetAvailableAction | DeleteAppAction | AddAppAction;
export function setAppsList(apps: Array<OauthAppResponse>): SetAvailableAction {
return {
type: SET_AVAILABLE,
type: 'apps:setAvailable',
payload: apps,
};
}
@ -20,49 +23,55 @@ export function getApp(state: {apps: Apps}, clientId: string): ?OauthAppResponse
}
export function fetchApp(clientId: string) {
return async (dispatch: Dispatch<any>, getState: () => {apps: Apps}) => {
const fetchedApp = await oauth.getApp(clientId);
const { available } = getState().apps;
let newApps: Array<OauthAppResponse>;
if (available.some((app) => app.clientId === fetchedApp.clientId)) {
newApps = available.map((app) => app.clientId === fetchedApp.clientId ? fetchedApp : app);
} else {
newApps = [...available, fetchedApp];
}
return async (dispatch: Dispatch<any>): Promise<void> => {
const app = await oauth.getApp(clientId);
return dispatch(setAppsList(newApps));
dispatch(addApp(app));
};
}
function addApp(app: OauthAppResponse): AddAppAction {
return {
type: 'apps:addApp',
payload: app
};
}
export function fetchAvailableApps() {
return async (dispatch: Dispatch<any>, getState: () => {user: User}) => {
return async (dispatch: Dispatch<any>, getState: () => {user: User}): Promise<void> => {
const { id } = getState().user;
if (!id) {
throw new Error('store.user.id is required for this action');
}
const apps = await oauth.getAppsByUser(id);
return dispatch(setAppsList(apps));
dispatch(setAppsList(apps));
};
}
export function deleteApp(clientId: string) {
return async (dispatch: Dispatch<any>, getState: () => {apps: Apps}) => {
return async (dispatch: Dispatch<any>): Promise<void> => {
await oauth.delete(clientId);
const apps = getState().apps.available.filter((app) => app.clientId !== clientId);
return dispatch(setAppsList(apps));
dispatch(createDeleteAppAction(clientId));
};
}
function createDeleteAppAction(clientId: string): DeleteAppAction {
return {
type: 'apps:deleteApp',
payload: clientId
};
}
export function resetApp(clientId: string, resetSecret: bool) {
return async (dispatch: Dispatch<any>, getState: () => {apps: Apps}) => {
const result = await oauth.reset(clientId, resetSecret);
if (resetSecret) {
const apps = getState().apps.available.map((app) => app.clientId === clientId ? result.data : app);
return async (dispatch: Dispatch<any>): Promise<void> => {
const { data: app } = await oauth.reset(clientId, resetSecret);
return dispatch(setAppsList(apps));
if (resetSecret) {
dispatch(addApp(app));
}
};
}

View File

@ -1,6 +1,6 @@
// @flow
import { SET_AVAILABLE } from './actions';
import type { OauthAppResponse } from 'services/api/oauth';
import type { Action } from './actions';
export type Apps = {
+available: Array<OauthAppResponse>,
@ -12,18 +12,41 @@ const defaults: Apps = {
export default function apps(
state: Apps = defaults,
{type, payload}: {type: string, payload: ?Object}
action: Action
) {
switch (type) {
case SET_AVAILABLE:
switch (action.type) {
case 'apps:setAvailable':
return {
...state,
available: payload,
available: action.payload,
};
case 'apps:addApp': {
const { payload } = action;
const available: Array<OauthAppResponse> = [...state.available];
let index = available.findIndex((app) => app.clientId === payload.clientId);
if (index === -1) {
index = available.length;
}
available[index] = action.payload;
return {
...state,
available
};
}
case 'apps:deleteApp':
return {
...state,
available: state.available.filter((app) => app.clientId !== action.payload),
};
default:
return state || {
...defaults
};
(action.type: empty);
return state;
}
}

View File

@ -2448,9 +2448,9 @@ escodegen@^1.6.1:
optionalDependencies:
source-map "~0.5.6"
eslint-plugin-flowtype@2.35.1:
version "2.35.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.35.1.tgz#9ad98181b467a3645fbd2a8d430393cc17a4ea63"
eslint-plugin-flowtype@2.46.3:
version "2.46.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.46.3.tgz#7e84131d87ef18b496b1810448593374860b4e8e"
dependencies:
lodash "^4.15.0"
@ -4145,10 +4145,14 @@ lodash@^3.10.0, lodash@^3.2.0, lodash@^3.8.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@~4.17.4:
lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@~4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
lodash@^4.15.0:
version "4.17.10"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
log4js@^0.6.31:
version "0.6.38"
resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd"