Skip to content

Commit

Permalink
optimistic project delete added
Browse files Browse the repository at this point in the history
  • Loading branch information
ajeetchaulagain committed Jun 26, 2020
1 parent a1886b3 commit b042b92
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 7 deletions.
10 changes: 10 additions & 0 deletions src/components/dashboard/DashboardPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class DashboardPage extends Component {
name: "",
},

activeProject: null,

apiErrorMessage: "",

projectInputErrors: "",
Expand Down Expand Up @@ -53,6 +55,10 @@ class DashboardPage extends Component {
this.setState({ showProjectModal: false });
};

handleDeleteProject = (project) => {
this.props.deleteProject(project);
};

handleTaskInputChange = (event) => {
const task = { ...this.state.task, title: event.target.value };
this.setState({ task });
Expand Down Expand Up @@ -111,6 +117,7 @@ class DashboardPage extends Component {
) : (
<div className="row">
<ProjectSection
activeProject={this.props.projects.slice().reverse()[2]}
onSubmit={this.handleProjectFormSubmit}
projects={this.props.projects.slice().reverse()}
onChange={this.handleProjectInputChange}
Expand All @@ -119,6 +126,7 @@ class DashboardPage extends Component {
showModal={this.state.showProjectModal}
onAddButtonClick={this.handleAddProject}
onHide={this.handleHideModal}
onDelete={this.handleDeleteProject}
/>
<TaskSection
onSubmit={this.handleTaskFormSubmit}
Expand All @@ -143,6 +151,7 @@ DashboardPage.propTypes = {
isFetching: PropTypes.bool.isRequired,
saveProject: PropTypes.func.isRequired,
projectInputErrors: PropTypes.string,
deleteProject: PropTypes.func.isRequired,
};

// Mapping State to Props
Expand All @@ -161,6 +170,7 @@ const mapDispatchToProps = {
loadProjects: projectActions.loadProjects,
createProject: projectActions.createProject,
saveProject: projectActions.saveProject,
deleteProject: projectActions.deleteProject,
};

// const mapDispatchToProps = (dispatch) => {
Expand Down
17 changes: 13 additions & 4 deletions src/components/dashboard/ProjectSection.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,26 @@ const ProjectSection = (props) => {
</li>

{props.projects &&
props.projects.map((project, i = 0) => (
props.projects.map((project) => (
<a
className="list-group-item list-group-item-action d-flex justify-content-between shadow-none"
className={
project === props.activeProject
? "list-group-item list-group-item-action d-flex justify-content-between shadow-none active bg-info"
: "list-group-item list-group-item-action d-flex justify-content-between shadow-none"
}
style={{ fontSize: "15px" }}
key={i}
key={project._id}
>
{project.name}

<div
className="d-flex ml-1"
style={{ fontSize: "16px", height: "auto" }}
>
<button className="btn btn-sm shadow-none">
<button
className="btn btn-sm shadow-none"
onClick={() => props.onDelete(project)}
>
<FaTrashAlt />
</button>
<button
Expand All @@ -93,6 +100,8 @@ ProjectSection.propTypes = {
errors: PropTypes.string,
showModal: PropTypes.bool.isRequired,
onHide: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
activeProject: PropTypes.obj,
};

export default ProjectSection;
4 changes: 4 additions & 0 deletions src/store/actions/actionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ export const CLEAR_API_ERRORS = "CLEAR_API_ERRORS";
export const SAVE_PROJECT = "SAVE_PROJECT";
export const SAVE_PROJECT_SUCCESS = "SAVE_PROJECT_SUCCESS";
export const SAVE_PROJECT_FAILURE = "SAVE_PROJECT_FAILURE";

export const DELETE_PROJECT = "DELETE_PROJECT";
export const DELETE_PROJECT_SUCCESS = "DELETE_PROJECT_SUCCESS";
export const DELETE_PROJECT_FAILURE = "DELETE_PROJECT_FAILURE";
2 changes: 2 additions & 0 deletions src/store/actions/apiActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const apiAction = ({
onSuccess = "",
onError = "",
onStart = "",
optimisticRevertValue = "",
}) => ({
type: types.API_CALL_START,
payload: {
Expand All @@ -16,5 +17,6 @@ export const apiAction = ({
onSuccess,
onError,
onStart,
optimisticRevertValue,
},
});
16 changes: 16 additions & 0 deletions src/store/actions/projectActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ export const saveProject = (project) => {
};
};

export const deleteProject = (project) => {
return (dispatch) => {
dispatch({ type: types.DELETE_PROJECT, payload: project });
dispatch(
apiAction({
url: `/projects/${project._id}`,
method: "DELETE",
onSuccess: types.DELETE_PROJECT_SUCCESS,
onError: types.DELETE_PROJECT_FAILURE,
optimistic: true,
optimisticRevertValue: project,
})
);
};
};

export const createProject = (project) => {
return { type: types.CREATE_PROJECT, project };
};
22 changes: 19 additions & 3 deletions src/store/middleware/apiMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@ const api = ({ dispatch }) => (next) => async (action) => {

next(action);

const { url, method, onSuccess, onError, onStart, data } = action.payload;
const {
url,
method,
onSuccess,
onError,
onStart,
data,
optimisticRevertValue,
} = action.payload;

if (onStart) dispatch({ type: onStart });

axios.defaults.headers.common["x-auth-token"] = localStorage.getItem("token");

console.log("url---", url);

try {
const response = await axios.request({
baseURL: API_URL,
Expand All @@ -37,7 +47,10 @@ const api = ({ dispatch }) => (next) => async (action) => {
message: "Oops Unexpected Error Occurred",
},
});
dispatch({ type: onError });
dispatch({
type: onError,
payload: optimisticRevertValue ? optimisticRevertValue : null,
});
} else if (expectedError) {
console.log("Expected Error");
dispatch({
Expand All @@ -47,7 +60,10 @@ const api = ({ dispatch }) => (next) => async (action) => {
message: error.response.data,
},
});
dispatch({ type: onError });
dispatch({
type: onError,
payload: optimisticRevertValue ? optimisticRevertValue : null,
});
}
}
};
Expand Down
15 changes: 15 additions & 0 deletions src/store/reducers/projectReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ const projectReducer = (
...state,
};

case types.DELETE_PROJECT:
return {
...state,
list: state.list.filter(
(project) => project._id !== action.payload._id
),
};

// I have done optimistic delete, so need to rever state on failure
case types.DELETE_PROJECT_FAILURE:
return {
...state,
list: [...state.list, { ...action.payload }],
};

default:
return state;
}
Expand Down

0 comments on commit b042b92

Please sign in to comment.