|
|
|
@ -1,45 +1,79 @@
|
|
|
|
|
import {
|
|
|
|
|
getNotes as getNotesBackend,
|
|
|
|
|
upsertNote as upsertNoteBackend
|
|
|
|
|
loadNotes as loadNotesBackend,
|
|
|
|
|
updateNote as updateNoteBackend,
|
|
|
|
|
deleteNote as deleteNoteBackend
|
|
|
|
|
} from "./api";
|
|
|
|
|
|
|
|
|
|
const SELECT_NOTE = "SELECT_NOTE";
|
|
|
|
|
const LOAD_NOTES_START = "LOAD_NOTES_START";
|
|
|
|
|
const LOAD_NOTES_SUCCESS = "LOAD_NOTES_SUCCESS";
|
|
|
|
|
const OPERATION_FAIL = "OPERATION_FAIL";
|
|
|
|
|
|
|
|
|
|
const UPDATE_NOTE_START = "UPDATE_NOTE_START";
|
|
|
|
|
const UPDATE_NOTE_SUCCESS = "UPDATE_NOTE_SUCCESS";
|
|
|
|
|
|
|
|
|
|
const CREATE_NOTE_START = "CREATE_NOTE_START";
|
|
|
|
|
const CREATE_NOTE_SUCCESS = "CREATE_NOTE_SUCCESS";
|
|
|
|
|
|
|
|
|
|
const DELETE_NOTE_START = "DELETE_NOTE_START";
|
|
|
|
|
const DELETE_NOTE_SUCCESS = "DELETE_NOTE_SUCCESS";
|
|
|
|
|
|
|
|
|
|
const initialState = {
|
|
|
|
|
notes: [],
|
|
|
|
|
selectedNote: null,
|
|
|
|
|
selectedNoteId: null,
|
|
|
|
|
error: null
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const reducer = (cs = initialState, { type, payload }) => {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case "SELECT_NOTE":
|
|
|
|
|
return { ...cs, selectedNote: { ...payload.selectedNote } };
|
|
|
|
|
case "SAVE_NOTE_START":
|
|
|
|
|
return {
|
|
|
|
|
...cs,
|
|
|
|
|
selectedNote: { ...cs.selectedNote, content: payload.content }
|
|
|
|
|
};
|
|
|
|
|
case "SAVE_NOTE_SUCCESS":
|
|
|
|
|
return {
|
|
|
|
|
...cs,
|
|
|
|
|
selectedNote: { ...payload.note }
|
|
|
|
|
};
|
|
|
|
|
case "GET_NOTES_START":
|
|
|
|
|
return { ...cs, notesLoading: true };
|
|
|
|
|
case "GET_NOTES_SUCCESS":
|
|
|
|
|
return {
|
|
|
|
|
...cs,
|
|
|
|
|
notesLoading: false,
|
|
|
|
|
error: null,
|
|
|
|
|
notes: [...payload.notes]
|
|
|
|
|
};
|
|
|
|
|
case "SAVE_NOTE_FAIL":
|
|
|
|
|
case "GET_NOTES_FAIL":
|
|
|
|
|
return { ...cs, notesLoading: false, error: payload.error };
|
|
|
|
|
case SELECT_NOTE:
|
|
|
|
|
case UPDATE_NOTE_SUCCESS:
|
|
|
|
|
case CREATE_NOTE_SUCCESS:
|
|
|
|
|
return { ...cs, selectedNote: payload };
|
|
|
|
|
case LOAD_NOTES_SUCCESS:
|
|
|
|
|
return { ...cs, notes: payload };
|
|
|
|
|
case OPERATION_FAIL:
|
|
|
|
|
return { ...cs, error: payload };
|
|
|
|
|
case DELETE_NOTE_SUCCESS:
|
|
|
|
|
default:
|
|
|
|
|
return { ...cs };
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const updateNote = ({ title, tags = [], content = "" }) => async (
|
|
|
|
|
dispatch,
|
|
|
|
|
getState
|
|
|
|
|
) => {
|
|
|
|
|
try {
|
|
|
|
|
if (title === "" || !title) {
|
|
|
|
|
throw new Error("title cannot be null or empty");
|
|
|
|
|
}
|
|
|
|
|
const {
|
|
|
|
|
notes: { selectedNote }
|
|
|
|
|
} = getState();
|
|
|
|
|
const { payload } = await updateNoteBackend({ title, tags, content });
|
|
|
|
|
console.log(`save note result: `, payload);
|
|
|
|
|
dispatch({
|
|
|
|
|
type: UPDATE_NOTE_SUCCESS,
|
|
|
|
|
payload: { ...selectedNote, ...payload, content }
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
dispatch({ type: OPERATION_FAIL, payload: error });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const createNote = ({ title }) => async (dispatch, getState) => {
|
|
|
|
|
try {
|
|
|
|
|
if (title === "" || !title) {
|
|
|
|
|
throw new Error("title cannot be null or empty");
|
|
|
|
|
}
|
|
|
|
|
const result = await updateNoteBackend({ title });
|
|
|
|
|
dispatch({ type: CREATE_NOTE_SUCCESS, payload: result });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
dispatch({ type: OPERATION_FAIL, payload: error });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const selectNote = ({ title }) => (dispatch, getState) => {
|
|
|
|
|
const normalizedTitle = title.toLocaleLowerCase();
|
|
|
|
|
const { selectedNote, notes } = getState().notes;
|
|
|
|
@ -48,29 +82,29 @@ const selectNote = ({ title }) => (dispatch, getState) => {
|
|
|
|
|
const notesFilter = notes.filter(
|
|
|
|
|
n => n.title.toLocaleLowerCase() === normalizedTitle
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (notesFilter.length > 0) {
|
|
|
|
|
foundNote = notesFilter[0];
|
|
|
|
|
dispatch({
|
|
|
|
|
type: "SELECT_NOTE",
|
|
|
|
|
payload: { ...foundNote }
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
dispatch({ type: "SELECT_NOTE", payload: { selectedNote: foundNote } });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const deleteNote = ({ title }) => (dispatch, getState) => {};
|
|
|
|
|
|
|
|
|
|
const upsertNote = ({ title, content, tags = [] }) => async (
|
|
|
|
|
dispatch,
|
|
|
|
|
getState
|
|
|
|
|
) => {
|
|
|
|
|
dispatch({ type: "SAVE_NOTE_START", payload: { title, content, tags } });
|
|
|
|
|
const deleteNote = ({ title }) => async (dispatch, getState) => {
|
|
|
|
|
try {
|
|
|
|
|
const result = await upsertNoteBackend({ title, content, tags });
|
|
|
|
|
dispatch(getNotes());
|
|
|
|
|
dispatch({ type: "SAVE_NOTE_SUCCESS", payload: { ...result } });
|
|
|
|
|
if (!title || title === "") {
|
|
|
|
|
throw new Error("title cannot be null or empty");
|
|
|
|
|
}
|
|
|
|
|
const result = await deleteNoteBackend({ title });
|
|
|
|
|
dispatch({ type: DELETE_NOTE_SUCCESS, payload: result });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
dispatch({ type: "SAVE_NOTE_FAIL", payload: { error } });
|
|
|
|
|
dispatch({ type: OPERATION_FAIL, payload: error });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getNotes = () => async (dispatch, getState) => {
|
|
|
|
|
const loadNotes = () => async (dispatch, getState) => {
|
|
|
|
|
const { notesLoading } = getState().notes;
|
|
|
|
|
if (notesLoading) {
|
|
|
|
|
console.warn(
|
|
|
|
@ -79,23 +113,19 @@ const getNotes = () => async (dispatch, getState) => {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dispatch({ type: "GET_NOTES_START" });
|
|
|
|
|
try {
|
|
|
|
|
const result = await getNotesBackend();
|
|
|
|
|
dispatch({ type: "GET_NOTES_SUCCESS", payload: result });
|
|
|
|
|
const { payload } = await loadNotesBackend();
|
|
|
|
|
dispatch({ type: LOAD_NOTES_SUCCESS, payload: payload.notes || [] });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
dispatch({ type: "GET_NOTES_FAIL", payload: { error } });
|
|
|
|
|
throw error;
|
|
|
|
|
dispatch({ type: OPERATION_FAIL, payload: { error } });
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const updateTags = ({ title, tags }) => (dispatch, getState) => {
|
|
|
|
|
console.log(`adding tags ${tags} to ${title}`);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const actions = {
|
|
|
|
|
getNotes,
|
|
|
|
|
deleteNote,
|
|
|
|
|
upsertNote,
|
|
|
|
|
loadNotes,
|
|
|
|
|
selectNote,
|
|
|
|
|
updateTags
|
|
|
|
|
deleteNote,
|
|
|
|
|
createNote,
|
|
|
|
|
updateNote
|
|
|
|
|
};
|
|
|
|
|