From 8d2bcb605f61d23dcf1859364be486b24aa91f34 Mon Sep 17 00:00:00 2001 From: Adarsh Murthy Date: Mon, 3 Apr 2017 14:49:43 -0400 Subject: [PATCH 1/7] Create delete button. Function to store project document slot id and corresponding document key. Function to get project document slot id from document key and function to delete the document slot. Front end does not update view when delete completes, need to refresh. --- src/components/Project/index.js | 53 +++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/components/Project/index.js b/src/components/Project/index.js index 357dd92e..69655ebb 100644 --- a/src/components/Project/index.js +++ b/src/components/Project/index.js @@ -24,6 +24,7 @@ export default class Project extends Component { convertingFile: false, error: false, projectDocumentsLoading: false, + projectDocumentId: null, }; } @@ -56,6 +57,45 @@ export default class Project extends Component { }); } + getProjDocId = (key) => { + const pdId = this.state.projectDocumentId.reduce((acc, item) => { + if (item.key === key) { + return item.pid; + } + return acc; + }, -1); + console.log('got pdid: ', pdId); + return pdId; + } + + setProjectDocumentSlotId = () => { + request(`${projectDocumentURL}?project_id=${this.props.params.projectId}`, { + method: 'GET', + headers: getHeaders(), + }).then((res) => { + if (!res.err) { + const d = res.data.map(this.createdict); + this.setState({ projectDocumentId: d }); + } + }); + } + + deleteDocumentSlot = (docSlotId) => { + request(`${projectDocumentURL}${docSlotId}`, { + method: 'DELETE', + headers: getHeaders(), + }).then((res) => { + console.log(res); + }); + } + + createdict = (obj) => { + const f = {}; + f.key = obj.document_key; + f.pid = obj.id; + return f; + } + // Post a project document to the projectservice postProjectDocument = (documentKey, slot) => { request(`${projectDocumentURL}`, { @@ -130,6 +170,13 @@ export default class Project extends Component { fileReader.readAsDataURL(file); } + handleDeleteDoc = (doc) => { + // this.setState({ projectDocumentsLoading: true }); + this.setProjectDocumentSlotId(); + this.deleteDocumentSlot(this.getProjDocId(doc.key)); + // this.setState({ projectDocumentsLoading: false }); + } + renderUploadButton = (slot) => { let disabled = false; let img = ( @@ -173,6 +220,12 @@ export default class Project extends Component { docs = documentList.map(item => (
+
)); } -- GitLab From 2879d44ef75fac5f4723cebb107d9e2a4d476826 Mon Sep 17 00:00:00 2001 From: Adarsh Murthy Date: Mon, 3 Apr 2017 14:58:09 -0400 Subject: [PATCH 2/7] Fix for null project document slot id-document key dictionary --- src/components/Project/index.js | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/components/Project/index.js b/src/components/Project/index.js index 69655ebb..f822e246 100644 --- a/src/components/Project/index.js +++ b/src/components/Project/index.js @@ -43,6 +43,8 @@ export default class Project extends Component { headers: getHeaders(), }).then((res) => { if (!res.err) { + const d = res.data.map(this.createdict); + this.setState({ projectDocumentId: d }); const documentKeys = res.data.map(val => ( val.document_key )); @@ -68,18 +70,6 @@ export default class Project extends Component { return pdId; } - setProjectDocumentSlotId = () => { - request(`${projectDocumentURL}?project_id=${this.props.params.projectId}`, { - method: 'GET', - headers: getHeaders(), - }).then((res) => { - if (!res.err) { - const d = res.data.map(this.createdict); - this.setState({ projectDocumentId: d }); - } - }); - } - deleteDocumentSlot = (docSlotId) => { request(`${projectDocumentURL}${docSlotId}`, { method: 'DELETE', @@ -172,7 +162,6 @@ export default class Project extends Component { handleDeleteDoc = (doc) => { // this.setState({ projectDocumentsLoading: true }); - this.setProjectDocumentSlotId(); this.deleteDocumentSlot(this.getProjDocId(doc.key)); // this.setState({ projectDocumentsLoading: false }); } -- GitLab From 79b6990d4f6a49723861fff7cde8e978697a1880 Mon Sep 17 00:00:00 2001 From: Adarsh Murthy Date: Mon, 3 Apr 2017 17:11:52 -0400 Subject: [PATCH 3/7] Delete from projectservice and update in frontend. Need to fix error: Unexpected end of JSON input and update to make calls to documentservice --- src/components/Project/index.js | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/components/Project/index.js b/src/components/Project/index.js index f822e246..c6c1c981 100644 --- a/src/components/Project/index.js +++ b/src/components/Project/index.js @@ -24,7 +24,8 @@ export default class Project extends Component { convertingFile: false, error: false, projectDocumentsLoading: false, - projectDocumentId: null, + projectDocumentIds: null, + deleteDocumentSlot: false, }; } @@ -43,8 +44,9 @@ export default class Project extends Component { headers: getHeaders(), }).then((res) => { if (!res.err) { + // storing project doc slot id to doc key relation const d = res.data.map(this.createdict); - this.setState({ projectDocumentId: d }); + this.setState({ projectDocumentIds: d }); const documentKeys = res.data.map(val => ( val.document_key )); @@ -60,22 +62,25 @@ export default class Project extends Component { } getProjDocId = (key) => { - const pdId = this.state.projectDocumentId.reduce((acc, item) => { + console.log('In getProjId'); + const pdId = this.state.projectDocumentIds.reduce((acc, item) => { if (item.key === key) { return item.pid; } return acc; }, -1); - console.log('got pdid: ', pdId); + console.log('Got project document id: ', pdId); return pdId; } deleteDocumentSlot = (docSlotId) => { + console.log('In deleteDocumentSlot'); request(`${projectDocumentURL}${docSlotId}`, { method: 'DELETE', headers: getHeaders(), }).then((res) => { - console.log(res); + console.log('Response for delete: ', res); + this.setState({ deleteDocumentSlot: false }); }); } @@ -161,9 +166,21 @@ export default class Project extends Component { } handleDeleteDoc = (doc) => { - // this.setState({ projectDocumentsLoading: true }); + console.log('Clicked delete button'); + this.setState({ deleteDocumentSlot: true }); + console.log('Old props.documents.files.project: ', + this.props.documents.files.project); + const indexOfpdId = this.props.documents.files.project.reduce((acc, item) => { + if (item.key === doc.key) { + return this.props.documents.files.project.indexOf(item); + } + return acc; + }, -1); + console.log('Obtained index: ', indexOfpdId); + this.props.documents.files.project.splice(indexOfpdId, 1); + console.log('New props.documents.files.project: ', + this.props.documents.files.project); this.deleteDocumentSlot(this.getProjDocId(doc.key)); - // this.setState({ projectDocumentsLoading: false }); } renderUploadButton = (slot) => { -- GitLab From a012507dae82f8e590c114a5f49be4415db92673 Mon Sep 17 00:00:00 2001 From: Adarsh Murthy Date: Tue, 4 Apr 2017 14:37:43 -0400 Subject: [PATCH 4/7] Add action to dispatch delete document slot in a project. Add constants for the same and add case in reducer to see the action and change states. Add implementation in sagas to ping projectservice to get project document slot id and use that id to delete from project service. Connect deletedocumentslot with the buildings container and add it as a property and to be passed to its children. Call this function in Project when the 'x' button is clicked. --- src/components/Project/index.js | 56 ++------------------------- src/containers/Building/index.js | 5 ++- src/containers/Documents/actions.js | 26 +++++++++++++ src/containers/Documents/constants.js | 3 ++ src/containers/Documents/reducer.js | 39 +++++++++++++++++++ src/containers/Documents/sagas.js | 38 +++++++++++++++++- 6 files changed, 113 insertions(+), 54 deletions(-) diff --git a/src/components/Project/index.js b/src/components/Project/index.js index c6c1c981..e1fb204d 100644 --- a/src/components/Project/index.js +++ b/src/components/Project/index.js @@ -24,8 +24,6 @@ export default class Project extends Component { convertingFile: false, error: false, projectDocumentsLoading: false, - projectDocumentIds: null, - deleteDocumentSlot: false, }; } @@ -44,9 +42,6 @@ export default class Project extends Component { headers: getHeaders(), }).then((res) => { if (!res.err) { - // storing project doc slot id to doc key relation - const d = res.data.map(this.createdict); - this.setState({ projectDocumentIds: d }); const documentKeys = res.data.map(val => ( val.document_key )); @@ -61,36 +56,6 @@ export default class Project extends Component { }); } - getProjDocId = (key) => { - console.log('In getProjId'); - const pdId = this.state.projectDocumentIds.reduce((acc, item) => { - if (item.key === key) { - return item.pid; - } - return acc; - }, -1); - console.log('Got project document id: ', pdId); - return pdId; - } - - deleteDocumentSlot = (docSlotId) => { - console.log('In deleteDocumentSlot'); - request(`${projectDocumentURL}${docSlotId}`, { - method: 'DELETE', - headers: getHeaders(), - }).then((res) => { - console.log('Response for delete: ', res); - this.setState({ deleteDocumentSlot: false }); - }); - } - - createdict = (obj) => { - const f = {}; - f.key = obj.document_key; - f.pid = obj.id; - return f; - } - // Post a project document to the projectservice postProjectDocument = (documentKey, slot) => { request(`${projectDocumentURL}`, { @@ -165,22 +130,8 @@ export default class Project extends Component { fileReader.readAsDataURL(file); } - handleDeleteDoc = (doc) => { - console.log('Clicked delete button'); - this.setState({ deleteDocumentSlot: true }); - console.log('Old props.documents.files.project: ', - this.props.documents.files.project); - const indexOfpdId = this.props.documents.files.project.reduce((acc, item) => { - if (item.key === doc.key) { - return this.props.documents.files.project.indexOf(item); - } - return acc; - }, -1); - console.log('Obtained index: ', indexOfpdId); - this.props.documents.files.project.splice(indexOfpdId, 1); - console.log('New props.documents.files.project: ', - this.props.documents.files.project); - this.deleteDocumentSlot(this.getProjDocId(doc.key)); + deleteSlot = (doc) => { + this.props.deleteDocumentSlot(doc.key, this.state.projectId); } renderUploadButton = (slot) => { @@ -228,7 +179,7 @@ export default class Project extends Component { @@ -297,4 +248,5 @@ Project.propTypes = { getDocuments: PropTypes.func, uploadDocument: PropTypes.func, getFolderUrl: PropTypes.func, + deleteDocumentSlot: PropTypes.func, }; diff --git a/src/containers/Building/index.js b/src/containers/Building/index.js index 4d3c14e3..a8f39539 100644 --- a/src/containers/Building/index.js +++ b/src/containers/Building/index.js @@ -6,7 +6,7 @@ import { completeOverviewPropTypes, completeProjectPropTypes } from './propTypes import { loadBuildingDetail, loadProjects } from './actions'; import documentsPropType from '../Documents/propTypes'; -import { loadDocuments, uploadDocument, loadFolderUrl } from '../Documents/actions'; +import { loadDocuments, uploadDocument, loadFolderUrl, deleteDocumentSlot } from '../Documents/actions'; import SideBarDetail from '../../components/SideBarDetail'; import ErrorAlert from '../../components/ErrorAlert'; @@ -36,6 +36,7 @@ class Building extends Component { getDocuments: this.props.loadDocuments, uploadDocument: this.props.uploadDocument, getFolderUrl: this.props.loadFolderUrl, + deleteDocumentSlot: this.props.deleteDocumentSlot, }); } @@ -65,6 +66,7 @@ Building.propTypes = { loadDocuments: PropTypes.func, uploadDocument: PropTypes.func, loadFolderUrl: PropTypes.func, + deleteDocumentSlot: PropTypes.func, }; function mapDispatchToProps(dispatch) { @@ -74,6 +76,7 @@ function mapDispatchToProps(dispatch) { loadDocuments, uploadDocument, loadFolderUrl, + deleteDocumentSlot, }, dispatch); } diff --git a/src/containers/Documents/actions.js b/src/containers/Documents/actions.js index b7eb9320..5be8b6c1 100644 --- a/src/containers/Documents/actions.js +++ b/src/containers/Documents/actions.js @@ -8,6 +8,9 @@ import { LOAD_FOLDER_URL, LOAD_FOLDER_URL_SUCCESS, POST_TO_SERVICE, + DELETE_DOCUMENT_SLOT, + DOCUMENT_SLOT_DELETE_SUCCESS, + DOCUMENT_SLOT_DELETE_ERROR, } from './constants'; export function loadDocuments(documentPaths, documentKeys, fileKey) { @@ -87,3 +90,26 @@ export function folderUrlLoaded(url) { payload: url, }; } + +export function deleteDocumentSlot(documentKey, projectId) { + return { + type: DELETE_DOCUMENT_SLOT, + documentKey, + projectId, + }; +} + +export function documentSlotDeleteSuccess(res, documentKey) { + return { + type: DOCUMENT_SLOT_DELETE_SUCCESS, + res, + documentKey, + }; +} + +export function documentSlotDeleteError(errorMsg) { + return { + type: DOCUMENT_SLOT_DELETE_ERROR, + errorMsg, + }; +} diff --git a/src/containers/Documents/constants.js b/src/containers/Documents/constants.js index 4efbcad5..ef271c92 100644 --- a/src/containers/Documents/constants.js +++ b/src/containers/Documents/constants.js @@ -7,3 +7,6 @@ export const UPLOAD_DOCUMENT_ERROR = 'UPLOAD_DOCUMENT_ERROR'; export const LOAD_FOLDER_URL = 'LOAD_FOLDER_URL'; export const LOAD_FOLDER_URL_SUCCESS = 'LOAD_FOLDER_URL_SUCCESS'; export const POST_TO_SERVICE = 'POST_TO_SERVICE'; +export const DELETE_DOCUMENT_SLOT = 'DELETE_DOCUMENT_SLOT'; +export const DOCUMENT_SLOT_DELETE_SUCCESS = 'DOCUMENT_SLOT_DELETE_SUCCESS'; +export const DOCUMENT_SLOT_DELETE_ERROR = 'DOCUMENT_SLOT_DELETE_ERROR'; diff --git a/src/containers/Documents/reducer.js b/src/containers/Documents/reducer.js index 4f35c347..2c7d5b0d 100644 --- a/src/containers/Documents/reducer.js +++ b/src/containers/Documents/reducer.js @@ -7,6 +7,9 @@ import { UPLOAD_DOCUMENT_ERROR, LOAD_FOLDER_URL, LOAD_FOLDER_URL_SUCCESS, + DELETE_DOCUMENT_SLOT, + DOCUMENT_SLOT_DELETE_SUCCESS, + DOCUMENT_SLOT_DELETE_ERROR, } from './constants'; import { @@ -19,6 +22,8 @@ const initState = { uploading: false, uploadError: false, documentUrl: '#', + deleting: false, + deleteError: false, files: { building: [], // Root Directory project: [], @@ -27,6 +32,9 @@ const initState = { }, }; +let indexOfProjectDocumentSlot = -1; +let currentState = []; + export default function (state = initState, action) { switch (action.type) { case LOAD_DOCUMENTS: @@ -95,6 +103,37 @@ export default function (state = initState, action) { case LOAD_BUILDING_DETAIL: return initState; + case DELETE_DOCUMENT_SLOT: + return { + ...state, + deleting: true, + }; + + case DOCUMENT_SLOT_DELETE_SUCCESS: + currentState = [...state.files.project]; + indexOfProjectDocumentSlot = currentState.reduce((acc, item) => { + if (item.key === action.documentKey) { + return state.files.project.indexOf(item); + } + return acc; + }, -1); + currentState.splice(indexOfProjectDocumentSlot, 1); + return { + ...state, + files: { + ...state.files, + project: currentState, + }, + deleting: false, + }; + + case DOCUMENT_SLOT_DELETE_ERROR: + return { + ...state, + deleting: false, + deleteError: action.errorMsg, + }; + default: return state; } diff --git a/src/containers/Documents/sagas.js b/src/containers/Documents/sagas.js index 67b2bc29..74cdf78b 100644 --- a/src/containers/Documents/sagas.js +++ b/src/containers/Documents/sagas.js @@ -1,12 +1,13 @@ import { call, put, takeLatest } from 'redux-saga/effects'; import request from '../../utils/request'; -import { getHeaders, documentURL } from '../../utils/restServices'; +import { getHeaders, documentURL, projectDocumentURL } from '../../utils/restServices'; import { LOAD_DOCUMENTS, UPLOAD_DOCUMENT, LOAD_FOLDER_URL, POST_TO_SERVICE, + DELETE_DOCUMENT_SLOT, } from './constants'; import { @@ -16,6 +17,8 @@ import { documentUploadError, folderUrlLoaded, postToService, + documentSlotDeleteSuccess, + documentSlotDeleteError, } from './actions'; function* getDocuments(action) { @@ -90,6 +93,38 @@ function* uploadDocument(action) { } } +function* deleteDocumentSlot(action) { + const { documentKey, projectId } = action; + let errorMsg = null; + let projectDocumentSlotId = -1; + const res = yield call( + request, + `${projectDocumentURL}?project_id=${projectId}`, { + method: 'GET', + headers: getHeaders(), + }); + + if (!res.err) { + projectDocumentSlotId = res.data.reduce((acc, item) => { + if (item.document_key === action.documentKey) { + return item.id; + } + return acc; + }, -1); + } + + const deleteURL = `${projectDocumentURL}${projectDocumentSlotId}`; + fetch(deleteURL, { + method: 'DELETE', + headers: getHeaders(), + }).catch((err) => { errorMsg = err; }); + if (errorMsg) { + yield put(documentSlotDeleteError(errorMsg)); + } else { + yield put(documentSlotDeleteSuccess(res, documentKey)); + } +} + function* getFolderUrl(action) { const { folderPath } = action; @@ -111,4 +146,5 @@ export default function* () { yield takeLatest(UPLOAD_DOCUMENT, uploadDocument); yield takeLatest(POST_TO_SERVICE, postToServiceSaga); yield takeLatest(LOAD_FOLDER_URL, getFolderUrl); + yield takeLatest(DELETE_DOCUMENT_SLOT, deleteDocumentSlot); } -- GitLab From 5be176f09753cbb8de6e911f588b262aa8bab86d Mon Sep 17 00:00:00 2001 From: Adarsh Murthy Date: Tue, 4 Apr 2017 17:37:36 -0400 Subject: [PATCH 5/7] Action to dispatch delete document from document service. This happens after the document slot has been deleted from the project service. --- src/components/Project/index.js | 4 ++++ src/containers/Building/index.js | 5 ++++- src/containers/Documents/actions.js | 23 +++++++++++++++++++++++ src/containers/Documents/constants.js | 3 +++ src/containers/Documents/reducer.js | 26 ++++++++++++++++++++++---- src/containers/Documents/sagas.js | 19 +++++++++++++++++++ 6 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/components/Project/index.js b/src/components/Project/index.js index e1fb204d..3b8f00ca 100644 --- a/src/components/Project/index.js +++ b/src/components/Project/index.js @@ -130,8 +130,10 @@ export default class Project extends Component { fileReader.readAsDataURL(file); } + // deleteSlot makes calls to delete the slot from projectservice and documentservice deleteSlot = (doc) => { this.props.deleteDocumentSlot(doc.key, this.state.projectId); + this.props.deleteDocument(doc.id); } renderUploadButton = (slot) => { @@ -177,6 +179,7 @@ export default class Project extends Component { docs = documentList.map(item => (
+ {/* Button to delete a document from projectservice and documentservice */}