Browse Source

Improve focus logic. Remove all logic involving indexes from selected Items. Add Remove Multiple Items action

Tatiana Inama 6 years ago
parent
commit
3c79723fac

+ 3 - 3
recipes/src/components/List/index.tsx

@@ -1,6 +1,6 @@
 import React, { useState, useEffect } from 'react';
 import classnames from 'classnames';
-import { update } from 'ramda';
+import { includes } from 'ramda';
 
 import './styles.scss';
 
@@ -10,7 +10,7 @@ type ListProps<T extends ItemProps> = {
   nonInteractive?: boolean,
   focusOnClick?: boolean,
   dense?: boolean,
-  focusMultiple?: number[],
+  focusMultiple?: T[],
   focus?: number,
   items: T[],
   render: (item: T, index: number) => React.ComponentElement<T, any>,
@@ -33,7 +33,7 @@ const CBKList = <T extends ItemProps>(props: ListProps<T>) => {
             className={
               classnames({
                 'cbk-list__item': true,
-                'cbk-list__item--focus': index === props.focus || item.focused || (props.focusMultiple && props.focusMultiple.includes(index))
+                'cbk-list__item--focus': index === props.focus || item.focused || (props.focusMultiple && includes(item, props.focusMultiple))
               })
             }
             onClick={() => { props.onClick ? props.onClick(item, index) : null }}

+ 2 - 2
recipes/src/containers/ShoppingCart/List/index.tsx

@@ -66,7 +66,7 @@ class ShoppingList extends Component<ShoppingListProps, ShoppingListState> {
           >
             <p>Are you sure you want to remove all items from shopping list ?</p>
           </Dialog>
-          <List
+          {/* <List
             dense
             nonInteractive
             items={this.props.items}
@@ -74,7 +74,7 @@ class ShoppingList extends Component<ShoppingListProps, ShoppingListState> {
               addToCart,
               removeItemFromCart,
             })}
-          />
+          /> */}
         </div>
       </div>
     )

+ 22 - 29
recipes/src/containers/ShoppingCart/View/index.tsx

@@ -2,7 +2,7 @@ import React from 'react';
 import { connect } from 'react-redux';
 import { ThunkDispatch } from 'redux-thunk';
 import { bindActionCreators } from 'redux';
-import { update, includes, remove, findIndex, equals } from 'ramda';
+import { remove, equals } from 'ramda';
 
 import Button from 'components/Button';
 import Dialog from 'components/Dialog';
@@ -13,14 +13,11 @@ import shoppingCartActions, { fetchCartActionCreator, saveCartActionCreator } fr
 import { ShoppingItem, ShoppingCartState } from 'types/shopping-cart';
 import { AppState } from 'store/configureStore';
 
-import { combineItems, combineMultipleItems } from '../services';
+import { combineMultipleItems } from '../services';
 import { GetMeasure } from 'services/measurements';
 import './styles.scss';
 
 type shoppingCartActionTypes = typeof shoppingCartActions;
-interface SelectedItems extends ShoppingItem {
-  index: number
-};
 
 interface ShoppingCartViewProps extends ShoppingCartState, shoppingCartActionTypes {
   fetch: typeof fetchCartActionCreator,
@@ -29,7 +26,7 @@ interface ShoppingCartViewProps extends ShoppingCartState, shoppingCartActionTyp
 
 interface ShoppingCartViewState {
   dialogOpen: boolean,
-  selected: SelectedItems[],
+  selected: ShoppingItem[],
   selectedMeasure?: {
     name: string, values: string[]
   },
@@ -73,10 +70,8 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
     })
   }
 
-  selectItem = (item: ShoppingItem, index: number) => {
-    const duplicated = this.state.selected.findIndex(
-      selected => selected._original === item._original && selected.recipeName === item.recipeName
-    );
+  selectItem = (item: ShoppingItem) => {
+    const duplicated = this.state.selected.findIndex(equals(item));
     if (duplicated !== -1) {
       const newSelection = remove(duplicated, 1, this.state.selected);
       this.setState({
@@ -87,7 +82,7 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
       this.setState({
         selected: [
           ...this.state.selected,
-          { ...item, index }
+          item
         ],
         selectedMeasure: !this.state.selectedMeasure ? GetMeasure(item.unit) : this.state.selectedMeasure
       });
@@ -115,6 +110,11 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
     })
   }
 
+  removeItems = () => {
+    this.props.removeMultipleItemsFromCart(this.state.selected);
+    this.clearSelection();
+  }
+
   render () {
     return (
       <section className='cbk-shopping-cart-view'>
@@ -125,37 +125,30 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
                   {
                     this.state.selected.length >= 2 ? (
                       <div className='cbk-shopping-cart-view__actions--selection-actions'>
-                        <Button
-                          outlined
-                          onClick={this.mergeItems}
-                        >
+                        <Button outlined onClick={this.mergeItems}>
                           Merge
                         </Button>
-                        <Button
-                          outlined
-                          onClick={this.clearSelection}
-                        >
+                        <Button outlined onClick={this.removeItems}>
+                          Remove
+                        </Button>
+                        <Button outlined onClick={this.clearSelection}>
                           Clear
                         </Button>
                       </div>
                     ) : null
                   }
-                  <Button
-                    outlined
-                    onClick={() => this.openDialog(true) }
-                  > Delete
+                  <Button outlined onClick={() => this.openDialog(true) }>
+                    Delete
                   </Button>
-                  <Button
-                    raised
-                    onClick={() => this.props.save(this.props.items)}
-                  > Save
+                  <Button raised onClick={() => this.props.save(this.props.items)}>
+                    Save
                   </Button>
                 </div>
                 <div className='cbk-shopping-cart-view__items'>
                   <div className='cbk-shopping-list'>
                     <List
                       dense
-                      focusMultiple={this.state.selected.map(item => item.index)}
+                      focusMultiple={this.state.selected}
                       items={this.props.items}
                       render={ item => (
                         <div className='cbk-shopping-list__item'>
@@ -172,7 +165,7 @@ class ShoppingCartView extends React.Component<ShoppingCartViewProps, ShoppingCa
                           </div>
                         </div>
                       )}
-                      onClick={(item, index) => { this.selectItem(item, index) }}
+                      onClick={ item => this.selectItem(item) }
                     />
                   </div>
                 </div>

+ 11 - 2
recipes/src/containers/ShoppingCart/actions.ts

@@ -7,6 +7,7 @@ import { fetchShoppingCart, saveShoppingCart } from './services';
 export const ADD_RECIPE_TO_CART = 'ADD_ RECIPE_TO_CART';
 export const REMOVE_RECIPE_FROM_CART = 'REMOVE_RECIPE_FROM_CART';
 export const REMOVE_ITEM_FROM_CART = 'REMOVE_ITEM_FROM_CART';
+export const REMOVE_MULTIPLE_ITEMS_FROM_CART = 'REMOVE_MULTIPLE_ITEMS_FROM_CART';
 export const REMOVE_ALL = 'REMOVE_ALL';
 export const ADD_ALL = 'ADD_ALL';
 
@@ -118,6 +119,11 @@ export const mergeItemsCart = (deletedItems: string[], newItem: ShoppingItem): M
   }
 })
 
+export const removeMultipleItemsFromCart = (items: ShoppingItem[]): RemoveMultipleItemsFromCartAction => ({
+  type: REMOVE_MULTIPLE_ITEMS_FROM_CART,
+  payload: items
+})
+
 export type AddRecipeToCart = {
   type: typeof ADD_RECIPE_TO_CART,
   payload: ShoppingRecipe
@@ -149,6 +155,7 @@ export interface ConfirmSaveCartAction extends Action<'CONFIRM_SAVE_CART'> { car
 export interface RejectSaveCartAction extends Action<'REJECT_SAVE_CART'> { error: string };
 export interface DeleteCartAction extends Action<'DELETE_CART'> {};
 export interface MergeItemsCartAction extends Action<'MERGE_ITEMS_CART'> { payload: { items: string[], newItem: ShoppingItem }};
+export interface RemoveMultipleItemsFromCartAction extends Action<'REMOVE_MULTIPLE_ITEMS_FROM_CART'> { payload: ShoppingItem[] };
 
 export type ActionTypes = 
   AddRecipeToCart | 
@@ -163,7 +170,8 @@ export type ActionTypes =
   ConfirmSaveCartAction |
   RejectSaveCartAction |
   DeleteCartAction |
-  MergeItemsCartAction;
+  MergeItemsCartAction |
+  RemoveMultipleItemsFromCartAction;
 
 export default {
   addRecipeToCart,
@@ -172,5 +180,6 @@ export default {
   removeAll,
   addAll,
   deleteCart,
-  mergeItemsCart
+  mergeItemsCart,
+  removeMultipleItemsFromCart,
 }

+ 8 - 2
recipes/src/containers/ShoppingCart/reducers.ts

@@ -12,10 +12,11 @@ import { ActionTypes,
   DELETE_CART,
   REQUEST_CART,
   RECEIVE_CART,
-  MERGE_ITEMS_CART
+  MERGE_ITEMS_CART,
+  REMOVE_MULTIPLE_ITEMS_FROM_CART
 } from './actions';
 import { createShoppingList, getItemsFromRecipe } from './services';
-import { insert, reject } from 'ramda';
+import { insert, without } from 'ramda';
 
 const initialState: ShoppingCartState = {
     items: [],
@@ -100,6 +101,11 @@ const shoppingCartReducer = (
         ...state,
         items: insert(index, action.payload.newItem, state.items.filter((item) => !action.payload.items.includes(item._original)))
       }
+    case REMOVE_MULTIPLE_ITEMS_FROM_CART:
+      return {
+        ...state,
+        items: without(action.payload, state.items)
+      }
     default:
       return state
   }