瀏覽代碼

Improve typings for Recipe Reducer

Tatiana Inama 6 年之前
父節點
當前提交
c6f41c813d
共有 3 個文件被更改,包括 87 次插入28 次删除
  1. 50 17
      recipes/src/containers/Recipes/List/actions.ts
  2. 30 10
      recipes/src/containers/Recipes/List/reducers.ts
  3. 7 1
      recipes/src/types/ui.ts

+ 50 - 17
recipes/src/containers/Recipes/List/actions.ts

@@ -1,5 +1,6 @@
 import { ThunkAction } from 'redux-thunk';
 import Recipe from 'types/recipes';
+import { Layout } from 'types/ui';
 import { getRecipes, deleteRecipe } from '../services';
 import { Action, ActionCreator, Dispatch } from 'redux';
 
@@ -11,51 +12,83 @@ export const DELETE_RECIPE = 'DELETE_RECIPE';
 export const CONFIRM_DELETE_RECIPE = 'CONFIRM_DELETE_RECIPE';
 export const REJECT_DELETE_RECIPE = 'REJECT_DELETE_RECIPE';
 
-export const requestRecipes = (query: string) => ({
+export const CHANGE_LAYOUT = 'CHANGE_LAYOUT';
+
+export interface ReceiveRecipeAction extends Action<'RECEIVE_RECIPES'> {
+  isFetching: boolean,
+  payload: Recipe[]
+}
+
+export interface RequestRecipeAction extends Action<'REQUEST_RECIPES'> {
+  isFetching: boolean
+}
+
+export interface SelectRecipeAction extends Action<'SELECT_RECIPE'> {
+  payload: Recipe
+}
+
+export interface DeleteRecipeAction extends Action<'DELETE_RECIPE'> {
+  id: string,
+}
+
+export interface ResultDeleteRecipeAction extends Action<'CONFIRM_DELETE_RECIPE'|'REJECT_DELETE_RECIPE'> {
+  result: any
+}
+
+export interface ChangeLayoutAction extends Action<'CHANGE_LAYOUT'> {
+  layout: Layout
+}
+
+export type RecipeListActionTypes =
+  ReceiveRecipeAction |
+  RequestRecipeAction |
+  SelectRecipeAction |
+  DeleteRecipeAction |
+  ResultDeleteRecipeAction |
+  ChangeLayoutAction;
+
+export const requestRecipes = (query: string): RecipeListActionTypes => ({
   type: REQUEST_RECIPES,
   isFetching: true,
 });
 
-export const receiveRecipes = (json: Recipe[]) => ({
+export const receiveRecipes = (json: Recipe[]): RecipeListActionTypes => ({
   type: RECEIVE_RECIPES,
   isFetching: false,
   payload: json,
 });
 
-export const selectRecipe = (recipe?: Recipe) => ({
+export const selectRecipe = (recipe: Recipe): RecipeListActionTypes => ({
   type: SELECT_RECIPE,
   payload: recipe,
 });
 
-export interface DeleteRecipeAction extends Action<'DELETE_RECIPE'> {
-  id: string,
-}
-
-export const pendingDeleteRecipe = (id: string): DeleteRecipeAction => ({
+export const pendingDeleteRecipe = (id: string): RecipeListActionTypes => ({
   type: DELETE_RECIPE,
   id,
 })
 
-export interface ResultDeleteRecipeAction extends Action<'CONFIRM_DELETE_RECIPE'|'REJECT_DELETE_RECIPE'> {
-  result: any
-}
-
-export const confirmDeleteRecipe = (result: any): ResultDeleteRecipeAction => ({
+export const confirmDeleteRecipe = (result: any): RecipeListActionTypes => ({
   type: CONFIRM_DELETE_RECIPE,
   result,
 });
 
-export const rejectDeleteRecipe = (result: any): ResultDeleteRecipeAction => ({
+export const rejectDeleteRecipe = (result: any): RecipeListActionTypes => ({
   type: REJECT_DELETE_RECIPE,
   result,
 })
 
+export const changeLayout = (layout: Layout): RecipeListActionTypes => ({
+  type: CHANGE_LAYOUT,
+  layout
+})
+
 export const deleteRecipeActionCreator: ActionCreator<
   ThunkAction<
-    Promise<ResultDeleteRecipeAction>,
+    Promise<RecipeListActionTypes>,
     any,
     any,
-    ResultDeleteRecipeAction
+    RecipeListActionTypes
   >
 > = (id: string) => {
   return async (dispatch: Dispatch) => {
@@ -94,4 +127,4 @@ export function fetchIfNeeded(query: string) {
     }
 
   }
-}
+}

+ 30 - 10
recipes/src/containers/Recipes/List/reducers.ts

@@ -1,53 +1,73 @@
-const initialState = {
+import { Layout } from 'types/ui';
+import { RecipeListActionTypes, RECEIVE_RECIPES, SELECT_RECIPE, REQUEST_RECIPES, DELETE_RECIPE, CONFIRM_DELETE_RECIPE, REJECT_DELETE_RECIPE, CHANGE_LAYOUT } from './actions';
+import Recipe from 'types/recipes';
+
+type RecipeState = {
+  isFetching: boolean,
+  data: Recipe[],
+  selectedRecipe?: Recipe,
+  shoppingCart: [],
+  id: string,
+  result: any,
+  layout: Layout
+};
+
+const initialState: RecipeState = {
   isFetching: false,
   data: [],
   selectedRecipe: undefined,
   shoppingCart: [],
   id: '',
-  result: undefined
+  result: undefined,
+  layout: Layout.VerticalSplit
 };
 
 export const recipesReducer = (
   state = initialState,
-  action: any
-) => {
+  action: RecipeListActionTypes
+): RecipeState => {
   switch (action.type) {
-    case 'REQUEST_RECIPES': 
+    case REQUEST_RECIPES: 
       return {
         ...state,
         isFetching: action.isFetching,
       }
-    case 'RECEIVE_RECIPES':
+    case RECEIVE_RECIPES:
       return {
         ...state,
         isFetching: action.isFetching,
         data: action.payload || state.data,
       }
-    case 'SELECT_RECIPE':
+    case SELECT_RECIPE:
       return {
         ...state,
         selectedRecipe: action.payload
       }
-    case 'DELETE_RECIPE':
+    case DELETE_RECIPE:
       return {
         ...state,
         id: action.id,
         isFetching: true
       }
-    case 'CONFIRM_DELETE_RECIPE':
+    case CONFIRM_DELETE_RECIPE:
       return {
         ...state,
         isFetching: false,
         id: '',
         result: action.result
       }
-    case 'REJECT_DELETE_RECIPE':
+    case REJECT_DELETE_RECIPE:
       return {
         ...state,
         isFetching: false,
         id: '',
         result: action.result
       }
+    case CHANGE_LAYOUT:
+      return {
+        ...state,
+        layout: action.layout
+      }
     default:
       return state;
   }

+ 7 - 1
recipes/src/types/ui.ts

@@ -7,6 +7,12 @@ export type UiState = {
   display: Display,
 }
 
+export enum Layout {
+  VerticalSplit,
+  Module,
+  List
+}
+
 export default {
-  Display
+  Display,
 }