const filteredAssociations = R.pickBy(field => { const loaded = idx(field, _ => _.associations[field.name]) as any; if (loaded) { return idx(loaded, _ => _.existItems.length) != idx(field, _ => _.value.length); } return true; })(associations);
/** * 恢复 store 时跳转到主页面 * @param action */ function* rehydrateWatcher(action) { logger.log('[rehydrateWatcher]', action); yield put(appActions.restored()); const token = idx(action, _ => _.payload.auth.token); const path = idx(action, _ => _.payload.router.path); logger.log('[rehydrateWatcher]', !!token, path); if (token) { yield put(routerActions.toIndex()); } }
/** * 未找到可用 token 时重定向到登录页面 */ function* tokenWatcher(action) { const { auth: { token }, router: { path }, } = yield select((state: RootState) => ({ auth: state.auth, router: state.router })); // restored will be handled later at yield take(appActionTypes.RESTORED), simply ignore here if ([appActionTypes.RESTORED].includes(action.type)) { return; } if (action.type === REHYDRATE) { logger.log('[tokenWatcher]', 'REHYDRATE found, wait to restore...'); const restoredAction = yield take(appActionTypes.RESTORED); logger.log('[tokenWatcher]', 'waiting for app restored', restoredAction); if (!idx(restoredAction, _ => _.payload.auth.token)) { yield put(routerActions.toLogin()); } } else if (action.type === authActionTypes.LOGOUT) { logger.log('[tokenWatcher]', 'logout...'); yield put(routerActions.toLogin()); } else if (!token && path !== '/login') { logger.log('[tokenWatcher]', 'no token found and path is not login, goto login'); yield put(routerActions.toLogin()); } else if (!path) { logger.warn('[tokenWatcher]', 'no path found, redirect to login...'); yield put(routerActions.toLogin()); } }
export function toErrorMessage(e) { if (e.response) { return idx(e, _ => _.response.data.message); } return e.message; }
export const enumDecorator = ({ modelName, fields, }: { modelName: string; fields: (Fields & WithHidden) | PositionsField | EnumField; }): { modelName; fields: (Fields & WithHidden) | PositionsField | EnumField } => { const TAG = '[enumDecorator]'; logger.log(TAG, { fields }); const enumFilterFields = R.filter(R.propEq('type', DynamicFormTypes.EnumFilter))(fields); if (R.not(R.isEmpty(enumFilterFields))) { const [, enumFilterField] = R.toPairs(enumFilterFields)[0]; logger.debug(TAG, { enumFilterField }); const enums = _.map( _.keys(idx(enumFilterField as EnumField, _ => _.options.enumData)), castModelName, ); const current = castModelName(R.pathOr('', ['value'])(enumFilterField)); logger.debug(TAG, { enums, current }); // check if positions has value already // save positions value if no value exists, update models' sequence for else const positionsFieldPair = R.compose( R.toPairs, R.map(field => { // raw is the original value, if exists, means it's update request if (field.value && !field.raw) { const value = R.is(String, field.value) ? JSON.parse(field.value) : field.value; return { ...field, value, raw: field.value }; } return { ...field, value: R.path([current, 'value'])(fields), raw: field.value }; }), R.filter(R.pathEq(['options', 'type'], 'SortPosition')), )(fields); const filteredNames = R.without(current)(enums); const filteredFields = R.omit(filteredNames)(fields); const wrappedFields = current ? R.mergeDeepRight(filteredFields, { [current]: { isFilterField: true, options: { filterType: R.path(['options', 'filterType'])(enumFilterField) }, value: R.isEmpty(positionsFieldPair) ? R.path([current, 'value'])(filteredFields) : R.path([0, 1, 'value'])(positionsFieldPair), }, ...R.fromPairs(positionsFieldPair), }) : filteredFields; logger.debug(TAG, 'wrappedFields', { current, filteredNames, filteredFields, wrappedFields, positionsFieldPair, }); return { modelName, fields: wrappedFields }; } return { modelName, fields }; };