From c877aca9baf1465c3f3cbc27cb704c919254d507 Mon Sep 17 00:00:00 2001 From: Eric Greene Date: Fri, 2 Oct 2020 11:50:56 -0400 Subject: [PATCH] add solution to 18, rest client service, and modal --- demo-app/db.json | 22 +---- demo-app/package.json | 2 +- demo-app/public/index.html | 1 + demo-app/src/actions/carToolActions.ts | 85 +++++++++++++------- demo-app/src/components/CarTool.tsx | 3 +- demo-app/src/components/ModalDialog.css | 25 ++++++ demo-app/src/components/ModalDialog.tsx | 17 ++++ demo-app/src/containers/CarToolContainer.tsx | 4 +- demo-app/src/reducers/carToolReducers.ts | 33 +------- demo-app/src/services/CarsRestClient.ts | 7 ++ demo-app/src/services/RestClient.ts | 36 +++++++++ 11 files changed, 150 insertions(+), 85 deletions(-) create mode 100644 demo-app/src/components/ModalDialog.css create mode 100644 demo-app/src/components/ModalDialog.tsx create mode 100644 demo-app/src/services/CarsRestClient.ts create mode 100644 demo-app/src/services/RestClient.ts diff --git a/demo-app/db.json b/demo-app/db.json index 12abc68..cfbed4e 100644 --- a/demo-app/db.json +++ b/demo-app/db.json @@ -26,28 +26,12 @@ "price": 45000 }, { - "id": 2, "make": "Tesla", "model": "S", "year": 2018, - "color": "red", - "price": 100000 - }, - { - "make": "a", - "model": "a", - "year": 1900, - "color": "a", - "price": 2000, - "id": 3 - }, - { - "make": "b", - "model": "b", - "year": 1900, - "color": "b", - "price": 0, - "id": 4 + "color": "purple", + "price": 100000, + "id": 2 } ] } \ No newline at end of file diff --git a/demo-app/package.json b/demo-app/package.json index 02dd940..b5da02c 100644 --- a/demo-app/package.json +++ b/demo-app/package.json @@ -21,7 +21,7 @@ "scripts": { "start": "run-p web rest", "web": "react-scripts start", - "rest": "json-server --port 3060 ./db.json", + "rest": "json-server --port 3060 --delay 5000 ./db.json", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" diff --git a/demo-app/public/index.html b/demo-app/public/index.html index aa069f2..f342c32 100644 --- a/demo-app/public/index.html +++ b/demo-app/public/index.html @@ -39,5 +39,6 @@ To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --> + diff --git a/demo-app/src/actions/carToolActions.ts b/demo-app/src/actions/carToolActions.ts index fe137b2..f8aa624 100644 --- a/demo-app/src/actions/carToolActions.ts +++ b/demo-app/src/actions/carToolActions.ts @@ -1,12 +1,15 @@ import { Action, AnyAction, Dispatch } from 'redux'; import { Car, NewCar, CarKeys } from '../models/car'; +import { CarsRestClient } from '../services/CarsRestClient'; + +const carsRestClient = new CarsRestClient('http://localhost:3060/cars'); export const REFRESH_CARS_REQUEST_ACTION = 'REFRESH_CARS_REQUEST_ACTION'; export const REFRESH_CARS_DONE_ACTION = 'REFRESH_CARS_DONE_ACTION'; export const APPEND_CAR_REQUEST_ACTION = 'APPEND_REQUEST_CAR'; -export const REPLACE_CAR_ACTION = 'REPLACE_CAR'; -export const REMOVE_CAR_ACTION = 'REMOVE_CAR'; +export const REPLACE_CAR_REQUEST_ACTION = 'REPLACE_REQUEST_CAR'; +export const REMOVE_CAR_REQUEST_ACTION = 'REMOVE_REQUEST_CAR'; export const EDIT_CAR_ACTION = 'EDIT_CAR'; export const CANCEL_CAR_ACTION = 'CANCEL_CAR'; export const SORT_CARS_ACTION = 'SORT_CARS'; @@ -61,8 +64,7 @@ export const refreshCars = () => { // thunk function return async (dispatch: Dispatch) => { dispatch(createRefreshCarsRequestCarAction()); - const res = await fetch('http://localhost:3060/cars'); - const cars = await res.json(); + const cars = await carsRestClient.all(); dispatch(createRefreshCarsDoneCarAction(cars)); }; }; @@ -98,61 +100,84 @@ export const createAppendCarRequestAction: CreateAppendCarRequestAction = ( export const appendCar = (car: NewCar) => { return async (dispatch: Dispatch) => { dispatch(createAppendCarRequestAction(car)); - - await fetch('http://localhost:3060/cars', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(car), - }); - + await carsRestClient.append(car); const refreshCarsThunk = refreshCars(); refreshCarsThunk(dispatch); - //dispatch(refreshCars()); }; }; -// Existing Car Action +// Replace Car Request Action -export interface ReplaceCarAction extends Action { +export interface ReplaceCarRequestAction + extends Action { payload: { car: Car }; } -export type CreateReplaceCarAction = (car: Car) => ReplaceCarAction; +export type CreateReplaceCarRequestAction = ( + car: Car, +) => ReplaceCarRequestAction; -export function isReplaceCarAction( +export function isReplaceCarRequestAction( action: AnyAction, -): action is ReplaceCarAction { - return action?.type === REPLACE_CAR_ACTION; +): action is ReplaceCarRequestAction { + return action?.type === REPLACE_CAR_REQUEST_ACTION; } -export const createReplaceCarAction: CreateReplaceCarAction = (car) => ({ - type: REPLACE_CAR_ACTION, +export const createReplaceCarRequestAction: CreateReplaceCarRequestAction = ( + car, +) => ({ + type: REPLACE_CAR_REQUEST_ACTION, payload: { car }, }); -// End Existing Car Action +// End Replace Car Request Action -// Remove Car Action +// Replace Car Thunk Function -export interface RemoveCarAction extends Action { +export const replaceCar = (car: Car) => { + return async (dispatch: Dispatch) => { + dispatch(createReplaceCarRequestAction(car)); + await carsRestClient.replace(car); + refreshCars()(dispatch); + }; +}; + +// Remove Car RequestAction + +export interface RemoveCarRequestAction + extends Action { payload: { carId: number }; } -export type CreateRemoveCarAction = (carId: number) => RemoveCarAction; +export type CreateRemoveCarRequestAction = ( + carId: number, +) => RemoveCarRequestAction; -export function isRemoveCarAction( +export function isRemoveCarRequestAction( action: AnyAction, -): action is RemoveCarAction { - return action.type === REMOVE_CAR_ACTION; +): action is RemoveCarRequestAction { + return action.type === REMOVE_CAR_REQUEST_ACTION; } -export const createRemoveCarAction: CreateRemoveCarAction = (carId) => ({ - type: REMOVE_CAR_ACTION, +export const createRemoveCarRequestAction: CreateRemoveCarRequestAction = ( + carId, +) => ({ + type: REMOVE_CAR_REQUEST_ACTION, payload: { carId }, }); -// End Remove Action +// End Remove Car Request Action + +// Remove Car Thunk Function + +export const removeCar = (carId: number) => { + return async (dispatch: Dispatch) => { + dispatch(createRemoveCarRequestAction(carId)); + await carsRestClient.remove(carId); + refreshCars()(dispatch); + }; +}; // Edit Car Action diff --git a/demo-app/src/components/CarTool.tsx b/demo-app/src/components/CarTool.tsx index 1b02593..ea59d5f 100644 --- a/demo-app/src/components/CarTool.tsx +++ b/demo-app/src/components/CarTool.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { ToolHeader } from './ToolHeader'; import { CarTable } from './CarTable'; import { CarForm } from './CarForm'; +import { ModalDialog } from './ModalDialog'; import { CarToolState } from '../models/carToolStore'; import { Car, CarKeys, NewCar } from '../models/car'; @@ -32,7 +33,6 @@ export function CarTool(props: CarToolProps) { } = props; return ( <> - {isLoading &&
Calling the REST API
}