From 9878b5e6b4d9f9ea14b65b9cfdb1134f373996c0 Mon Sep 17 00:00:00 2001 From: Bilal Catic Date: Wed, 28 Aug 2019 12:44:47 +0200 Subject: [PATCH] implement mapping update --- .../components/SingleMapping.js | 105 ++++++++++++++++-- .../src/scenes/RoomOfficeNameMapping/index.js | 33 ++++-- .../src/store/actions/integrationActions.js | 13 +++ controllers/integration.js | 25 ++++- routes/index.js | 2 + services/officeRnD/resources.js | 11 +- 6 files changed, 166 insertions(+), 23 deletions(-) diff --git a/client/src/scenes/RoomOfficeNameMapping/components/SingleMapping.js b/client/src/scenes/RoomOfficeNameMapping/components/SingleMapping.js index 3c39ff5..2e7d36d 100644 --- a/client/src/scenes/RoomOfficeNameMapping/components/SingleMapping.js +++ b/client/src/scenes/RoomOfficeNameMapping/components/SingleMapping.js @@ -1,12 +1,12 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; -import { Table, Label, Icon } from 'semantic-ui-react'; +import { Table, Label, Icon, Dropdown } from 'semantic-ui-react'; import PromptMessage from '../../../components/PromptMessage'; -import { deleteMapping } from '../../../store/actions'; +import { deleteMapping, updateMapping } from '../../../store/actions'; class SingleMapping extends Component { - state = {showDeletePrompt: false}; + state = {showDeletePrompt: false, newOfficeId: null, newResourceId: null}; deleteMapping = () => { this.setState({showDeletePrompt: true}); @@ -24,10 +24,70 @@ class SingleMapping extends Component { this.onPromptClose(); }; + onOfficeChange = (event, data) => { + const newOfficeId = data.value; + const { allResourceOptions, officeId: oldOfficeId } = this.props; + + if (oldOfficeId !== newOfficeId){ + let newResourceId = null; + const roomOptionsForOffice = allResourceOptions[newOfficeId] && allResourceOptions[newOfficeId].roomOptions ? + allResourceOptions[newOfficeId].roomOptions : []; + + if (roomOptionsForOffice.length > 0){ + newResourceId = roomOptionsForOffice[0].value; + } + + this.setState({newOfficeId, newResourceId}); + }else{ + this.setState({newOfficeId: null, newResourceId: null}); + } + }; + + onResourceChange = (event, data) => { + const newResourceId = data.value; + const oldResourceId = this.props.resourceId; + + if (oldResourceId !== newResourceId){ + this.setState({newResourceId}); + }else{ + this.setState({newResourceId: null}); + } + }; + + onMappingUpdate = () => { + const { singleMapping: { id, officeSlug, resourceSlug }, updateMapping, officeId, resourceId } = this.props; + const { newOfficeId, newResourceId } = this.state; + + const selectedOfficeId = newOfficeId ? newOfficeId : officeId; + const selectedResourceId = newResourceId ? newResourceId : resourceId; + + if (parseInt(id)){ + + const modifiedMapping = { + officeSlug, + resourceSlug, + officeId: selectedOfficeId, + resourceId: selectedResourceId, + }; + + updateMapping(id, modifiedMapping); + this.setState({newOfficeId: null, newResourceId: null}); + } + }; + render() { const { singleMapping: { officeSlug, resourceSlug } } = this.props; - const { officeName, resourceName } = this.props; - const { showDeletePrompt } = this.state; + const { officeId, resourceId, officeOptions, allResourceOptions, pendingMappings } = this.props; + const { showDeletePrompt, newOfficeId, newResourceId } = this.state; + + const selectedOfficeId = newOfficeId ? newOfficeId : officeId; + const selectedResourceId = newResourceId ? newResourceId : resourceId; + + const resourceOptions = allResourceOptions && officeId ? allResourceOptions[selectedOfficeId].roomOptions : []; + + const enableActions = !pendingMappings; + const enableSave = enableActions && ((newOfficeId !== null) || (newResourceId !== null)); + const saveIconColor = enableSave ? 'green' : null; return ( @@ -42,20 +102,36 @@ class SingleMapping extends Component { - {officeName} - {resourceName} + + + + + + @@ -64,8 +140,13 @@ class SingleMapping extends Component { } } -const mapDispatchToProps = (dispatch) => ({ - deleteMapping: (id) => deleteMapping(dispatch, id), +const mapStateToProps = (state) => ({ + pendingMappings: state.mappingsData.pending, }); -export default connect(null, mapDispatchToProps)(SingleMapping); +const mapDispatchToProps = (dispatch) => ({ + deleteMapping: (id) => deleteMapping(dispatch, id), + updateMapping: (id, mapping) => updateMapping(dispatch, id, mapping), +}); + +export default connect(mapStateToProps, mapDispatchToProps)(SingleMapping); diff --git a/client/src/scenes/RoomOfficeNameMapping/index.js b/client/src/scenes/RoomOfficeNameMapping/index.js index 228db12..efaebf2 100644 --- a/client/src/scenes/RoomOfficeNameMapping/index.js +++ b/client/src/scenes/RoomOfficeNameMapping/index.js @@ -20,17 +20,30 @@ class RoomOfficeNameMapping extends Component { const offices = mappings && mappings.offices ? mappings.offices : []; const resources = mappings && mappings.resources ? mappings.resources : []; - const officesMap = {}; - const resourcesMap = {}; - - offices.forEach((office) => { + const officeDropdownOptions = offices.map((office) => { const { officeId, officeName } = office; - officesMap[officeId] = officeName; + return { + key: officeId, + value: officeId, + text: officeName, + } }); + const allResourceOptions = {}; resources.forEach((resource) => { - const { resourceId, resourceName } = resource; - resourcesMap[resourceId] = resourceName; + const { resourceId, resourceName, officeId } = resource; + + if (!allResourceOptions[officeId]){ + allResourceOptions[officeId] = { + roomOptions: [] + } + } + + allResourceOptions[officeId].roomOptions.push({ + key: resourceId, + value: resourceId, + text: resourceName, + }); }); return ( @@ -56,8 +69,10 @@ class RoomOfficeNameMapping extends Component { return }) } diff --git a/client/src/store/actions/integrationActions.js b/client/src/store/actions/integrationActions.js index 1544a18..bef2eb7 100644 --- a/client/src/store/actions/integrationActions.js +++ b/client/src/store/actions/integrationActions.js @@ -49,6 +49,19 @@ export const deleteMapping = (dispatch, mappingId) => { }); }; +export const updateMapping = (dispatch, id, mapping) => { + dispatch({type: FETCH_MAPPINGS_PENDING}); + API.put(`integration/mappings/${id}`, { + mapping + }) + .then(response => { + dispatch({type: FETCH_MAPPINGS_SUCCESS, payload: response.data}); + }) + .catch(error => { + dispatch({type: FETCH_MAPPINGS_FAILED, payload: error.response}); + }); +}; + export const addNewMapping = (dispatch, mapping) => { dispatch({type: ADD_NEW_MAPPING_PENDING}); API.post('integration/mappings', { diff --git a/controllers/integration.js b/controllers/integration.js index 0ba8882..5b17d23 100644 --- a/controllers/integration.js +++ b/controllers/integration.js @@ -2,7 +2,7 @@ const moment = require('moment-timezone'); -const { getMappingsFromDatabase, fetchOffices, fetchResources, saveNewMappingToDatabase, deleteMappingById } = require('../services/officeRnD/resources'); +const { getMappingsFromDatabase, fetchOffices, fetchResources, saveNewMappingToDatabase, deleteMappingById, updateMappingById } = require('../services/officeRnD/resources'); const { getAllIncidents, getMemberPracticeSummaryReport } = require('../services/integration/reports'); const { getMembersFeesForDateRange } = require('../services/integration/invoiceIntegration'); const { deleteFeesFromORD, addFeesToORD } = require('../services/officeRnD/fees'); @@ -24,6 +24,7 @@ const getKnownOfficeResourceMappings = (req, res) => { }); }) .catch(error => { + console.log('Error with fetching mappings : ', error); res.status(500).send(); }); }; @@ -54,6 +55,27 @@ const deleteMapping = (req, res) => { console.log(error); res.status(500).send(); }); + }else{ + getKnownOfficeResourceMappings(req, res); + } +}; + +const updateMapping = (req, res) => { + const mappingId = req.params.mappingId; + const mapping = req.body && req.body.mapping ? req.body.mapping : null; + + if (mappingId && parseInt(mappingId)){ + updateMappingById(mappingId, mapping) + .then(() => { + getKnownOfficeResourceMappings(req, res); + }) + .catch((error) => { + console.log('Error updating mapping with id = ', mappingId); + console.log(error); + res.status(500).send(); + }); + }else{ + getKnownOfficeResourceMappings(req, res); } }; @@ -187,6 +209,7 @@ module.exports = { getKnownOfficeResourceMappings, addNewMapping, deleteMapping, + updateMapping, getAllIncidentsController, getMemberIncidents, addFees, diff --git a/routes/index.js b/routes/index.js index 439fb2e..c8d30fe 100644 --- a/routes/index.js +++ b/routes/index.js @@ -7,6 +7,7 @@ const { getKnownOfficeResourceMappings, addNewMapping, deleteMapping, + updateMapping, getAllIncidentsController, getMemberIncidents, addFees, @@ -25,6 +26,7 @@ router.post('/doorLock/upload', uploadDoorLockData); router.get('/integration/mappings', getKnownOfficeResourceMappings); router.post('/integration/mappings', addNewMapping); router.delete('/integration/mappings/:mappingId', deleteMapping); +router.put('/integration/mappings/:mappingId', updateMapping); router.get('/integration/report/member/:memberId/:startDate/:endDate', getMemberIncidents); router.get('/integration/report/allIncidents/:startDate/:endDate', getAllIncidentsController); diff --git a/services/officeRnD/resources.js b/services/officeRnD/resources.js index 4c39ab7..918bc68 100644 --- a/services/officeRnD/resources.js +++ b/services/officeRnD/resources.js @@ -70,13 +70,21 @@ const getResourceMappings = () => { }; const getMappingsFromDatabase = () => { - return db.officeResourceMapping.findAll(); + return db.officeResourceMapping.findAll({order: [['id']]}); }; const deleteMappingById = (id) => { return db.officeResourceMapping.destroy({where: {id}}); }; +const updateMappingById = (id, mapping) => { + if (mapping.id) { + delete mapping.id; + } + + return db.officeResourceMapping.update(mapping, {where: {id}}); +}; + const saveNewMappingToDatabase = (mapping) => { return db.officeResourceMapping.findOrCreate({where: {...mapping}, defaults: {...mapping}}); }; @@ -88,4 +96,5 @@ module.exports = { getResourceMappings, saveNewMappingToDatabase, deleteMappingById, + updateMappingById, };