upload all docs in one action

This commit is contained in:
2019-08-31 17:43:11 +02:00
parent 55c13270a2
commit c95c7f1c9d
4 changed files with 67 additions and 61 deletions

View File

@@ -13,7 +13,7 @@ import {
deleteDocStart,
fetchDocsStart,
updateDoc,
uploadDocStart,
uploadDocsStart,
} from "~redux/docs/actions";
import { IDocumentEntry } from "~redux/docs/reducer";
import { IAppState } from "~redux/reducers";
@@ -27,7 +27,7 @@ export interface IDocumentEditComponentProps extends RouteComponentProps {
fetchDocs: () => void;
deleteDoc: (id: number) => void;
cancelDelete: () => void;
uploadDoc: (id: number, name: string, content: string) => void;
uploadDocs: () => void;
updateDoc: (id: number, name: string, content: string) => void;
}
@@ -98,9 +98,7 @@ export class DocumentEditComponent extends React.PureComponent<
}
public upload() {
const doc = this.props.allDocs[this.state.id];
console.log("upload");
this.props.uploadDoc(this.state.id, doc.name, doc.content);
this.props.uploadDocs();
}
public remove() {
@@ -197,8 +195,7 @@ function mapDispatchToProps(dispatch: Dispatch) {
fetchDocs: () => dispatch(fetchDocsStart()),
cancelDelete: () => dispatch(deleteDocCancel()),
deleteDoc: (id: number) => dispatch(deleteDocStart(id)),
uploadDoc: (id: number, name: string, content: string) =>
dispatch(uploadDocStart(id, name, content)),
uploadDocs: () => dispatch(uploadDocsStart()),
updateDoc: (id: number, name: string, content: string) =>
dispatch(updateDoc(id, name, content)),
};

View File

@@ -16,9 +16,9 @@ export enum DocsTypes {
DOC_DELETE_SUCCESS = "DOC_DELETE_SUCCESS",
DOC_DELETE_CANCEL = "DOC_DELETE_CANCEL",
DOC_UPLOAD_START = "DOC_UPLOAD_START",
DOC_UPLOAD_FAIL = "DOC_UPLOAD_FAIL",
DOC_UPLOAD_SUCCESS = "DOC_UPLOAD_SUCCESS",
DOCS_UPLOAD_START = "DOCS_UPLOAD_START",
DOCS_UPLOAD_FAIL = "DOCS_UPLOAD_FAIL",
DOCS_UPLOAD_SUCCESS = "DOCS_UPLOAD_SUCCESS",
DOCS_SHOW_SPINNER = "DOCS_SHOW_SPINNER",
@@ -142,41 +142,36 @@ export function deleteDocCancel(): IDocDeleteCancelAction {
return { type: DocsTypes.DOC_DELETE_CANCEL };
}
export interface IDocUploadStartAction extends Action {
type: DocsTypes.DOC_UPLOAD_START;
id: number;
name: string;
content: string;
export interface IDocsUploadStartAction extends Action {
type: DocsTypes.DOCS_UPLOAD_START;
}
export interface IDocUploadFailAction extends Action {
type: DocsTypes.DOC_UPLOAD_FAIL;
export interface IDocsUploadFailAction extends Action {
type: DocsTypes.DOCS_UPLOAD_FAIL;
payload: {
error: string;
};
}
export interface IDocUploadSuccessAction extends Action {
type: DocsTypes.DOC_UPLOAD_SUCCESS;
export interface IDocsUploadSuccessAction extends Action {
type: DocsTypes.DOCS_UPLOAD_SUCCESS;
payload: {
doc: IDocumentJSON;
all: IDocumentJSON[];
};
}
export function uploadDocStart(
id: number,
name: string,
content: string,
): IDocUploadStartAction {
return { type: DocsTypes.DOC_UPLOAD_START, id, name, content };
export function uploadDocsStart(): IDocsUploadStartAction {
return { type: DocsTypes.DOCS_UPLOAD_START };
}
export function uploadDocFail(error: string): IDocUploadFailAction {
return { type: DocsTypes.DOC_UPLOAD_FAIL, payload: { error } };
export function uploadDocsFail(error: string): IDocsUploadFailAction {
return { type: DocsTypes.DOCS_UPLOAD_FAIL, payload: { error } };
}
export function uploadDocSuccess(doc: IDocumentJSON): IDocUploadSuccessAction {
return { type: DocsTypes.DOC_UPLOAD_SUCCESS, payload: { doc } };
export function uploadDocsSuccess(
all: IDocumentJSON[],
): IDocsUploadSuccessAction {
return { type: DocsTypes.DOCS_UPLOAD_SUCCESS, payload: { all } };
}
export interface IDocUpdateAction extends Action {
@@ -209,7 +204,7 @@ export type DocsAction =
| IDocDeleteStartAction
| IDocDeleteSuccessAction
| IDocDeleteCancelAction
| IDocUploadFailAction
| IDocUploadStartAction
| IDocUploadSuccessAction
| IDocsUploadFailAction
| IDocsUploadStartAction
| IDocsUploadSuccessAction
| IDocUpdateAction;

View File

@@ -74,16 +74,17 @@ export const docsReducer: Reducer<IDocsState, DocsAction> = (
all[deletedDocument.id] = deletedDocument;
return { ...state, deletedDocument: null, all };
}
case DocsTypes.DOC_UPLOAD_START: {
case DocsTypes.DOCS_UPLOAD_START: {
return { ...state, uploading: true };
}
case DocsTypes.DOC_UPLOAD_FAIL: {
case DocsTypes.DOCS_UPLOAD_FAIL: {
return { ...state, uploading: false };
}
case DocsTypes.DOC_UPLOAD_SUCCESS: {
const all = { ...state.all };
const doc = action.payload.doc;
all[doc.id] = { ...doc, remote: doc, dirty: false };
case DocsTypes.DOCS_UPLOAD_SUCCESS: {
const all: { [key: number]: IDocumentEntry } = { ...state.all };
action.payload.all.forEach(doc => {
all[doc.id] = { ...doc, remote: doc, dirty: false };
});
return { ...state, all, uploading: false, dirty: false };
}
case DocsTypes.DOCS_FETCH_FAIL:

View File

@@ -6,6 +6,7 @@ import {
fork,
put,
race,
select,
take,
takeEvery,
takeLatest,
@@ -16,7 +17,8 @@ import {
fetchAllDocs,
patchDoc,
} from "~redux/api/docs";
import { IAppState } from "~redux/reducers";
import { IDocumentJSON } from "../../../../src/entity/Document";
import {
deleteDocFail,
deleteDocSuccess,
@@ -26,12 +28,12 @@ import {
IDocDeleteStartAction,
IDocNewStartAction,
IDocsFetchStartAction,
IDocUploadStartAction,
IDocsUploadStartAction,
newDocFail,
newDocSuccess,
showDocsSpinner,
uploadDocFail,
uploadDocSuccess,
uploadDocsFail,
uploadDocsSuccess,
} from "./actions";
function* startSpinner() {
@@ -128,32 +130,43 @@ function* docDeleteStart(action: IDocDeleteStartAction) {
}
}
function* docUploadStart(action: IDocUploadStartAction) {
function* docsUploadStart(action: IDocsUploadStartAction) {
try {
const spinner = yield fork(startSpinner);
const { response, timeout } = yield race({
response: call(patchDoc, action.id, action.name, action.content),
timeout: delay(10000),
});
const state: IAppState = yield select();
const allDocs = state.docs.all;
yield cancel(spinner);
const changedDocs: IDocumentJSON[] = Object.values(allDocs).filter(
e => e.dirty,
);
if (timeout) {
yield put(uploadDocFail("Timeout"));
return;
}
const updatedDocs: IDocumentJSON[] = [];
if (response) {
if (response.data == null) {
yield put(uploadDocFail(response.error));
} else {
const updDoc = response.data;
yield put(uploadDocSuccess(updDoc));
for (const doc of changedDocs) {
const { response, timeout } = yield race({
response: call(patchDoc, doc.id, doc.name, doc.content),
timeout: delay(10000),
});
if (timeout) {
yield put(uploadDocsFail("Timeout"));
return;
}
if (response) {
if (response.data == null) {
yield put(uploadDocsFail(response.error));
} else {
const updDoc = response.data;
updatedDocs.push(updDoc);
}
}
}
yield cancel(spinner);
yield put(uploadDocsSuccess(updatedDocs));
} catch (e) {
yield put(uploadDocFail("Internal error"));
yield put(uploadDocsFail("Internal error"));
}
}
@@ -162,6 +175,6 @@ export function* docsSaga() {
takeLatest(DocsTypes.DOCS_FETCH_START, docsFetchStart),
takeLatest(DocsTypes.DOC_NEW_START, docNewStart),
takeEvery(DocsTypes.DOC_DELETE_START, docDeleteStart),
takeLatest(DocsTypes.DOC_UPLOAD_START, docUploadStart),
takeLatest(DocsTypes.DOCS_UPLOAD_START, docsUploadStart),
]);
}