diff --git a/package.json b/package.json index 3f9802b6..5078e4d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "buildly-react-template", - "version": "v0.9.2", + "version": "v0.9.3", "description": "Frontend Template from Buildly built using the React framework", "main": "src/index.js", "private": true, diff --git a/src/pages/ProductRoadmap/ProductRoadmap.js b/src/pages/ProductRoadmap/ProductRoadmap.js index d52b2d95..98a1784d 100644 --- a/src/pages/ProductRoadmap/ProductRoadmap.js +++ b/src/pages/ProductRoadmap/ProductRoadmap.js @@ -311,6 +311,7 @@ const ProductRoadmap = ({ history }) => { history.push(routes.STATUS_BOARD, { from: location.pathname, product_uuid: selectedProduct, + editStatus: selectedProduct && _.toNumber(selectedProduct) !== 0 && _.includes(_.uniq(_.map(statusData, 'product_uuid')), selectedProduct), }); }; diff --git a/src/pages/ProductRoadmap/forms/StatusBoard.js b/src/pages/ProductRoadmap/forms/StatusBoard.js index 805222bb..1279dc23 100644 --- a/src/pages/ProductRoadmap/forms/StatusBoard.js +++ b/src/pages/ProductRoadmap/forms/StatusBoard.js @@ -18,6 +18,8 @@ import Loader from '@components/Loader/Loader'; import useAlert from '@hooks/useAlert'; import { getAllStatusQuery } from '@react-query/queries/release/getAllStatusQuery'; import { useCreateStatusMutation } from '@react-query/mutations/release/createStatusMutation'; +import { useUpdateStatusMutation } from '@react-query/mutations/release/updateStatusMutation'; +import { useDeleteStatusMutation } from '@react-query/mutations/release/deleteStatusMutation'; import { STATUSTYPES } from '../ProductRoadmapConstants'; const useStyles = makeStyles((theme) => ({ @@ -42,11 +44,7 @@ const useStyles = makeStyles((theme) => ({ const StatusBoard = ({ history, location }) => { const classes = useStyles(); - const editData = ( - location.state - && location.state.type === 'edit' - && location.state.data - ) || {}; + const editStatus = location.state && location.state.editStatus; const product_uuid = location.state && location.state.product_uuid; const redirectTo = location.state && location.state.from; @@ -70,13 +68,20 @@ const StatusBoard = ({ history, location }) => { const filteredStatus = _.filter(statuses, { product_uuid }); const statusDefault = _.find(filteredStatus, (s) => s.is_default_status); setStatus(_.map(filteredStatus, 'name')); - setDefaultStatus(statusDefault.name || ''); + setDefaultStatus((!!statusDefault && statusDefault.name) || ''); }, [statuses]); const closeFormModal = () => { + const filteredStatus = _.filter(statuses, { product_uuid }); + const statusDefault = _.find(filteredStatus, (s) => s.is_default_status); + const dataHasChanged = ( - (!_.isEmpty(editData) && !_.isEqual(status, editData.status)) - || (_.isEmpty(editData) && !_.isEmpty(status)) + (editStatus && !_.isEqual(status, _.map(statuses, 'name'))) + || (editStatus && ( + (!statusDefault && !!defaultStatus) + || (!!statusDefault && !_.isEqual(defaultStatus, statusDefault.name)) + )) + || (!editStatus && !_.isEmpty(status)) ); if (dataHasChanged) { @@ -113,17 +118,70 @@ const StatusBoard = ({ history, location }) => { }; const { mutate: createStatusMutation, isLoading: isCreatingStatusLoading } = useCreateStatusMutation(history, redirectTo, product_uuid, discardFormData, displayAlert); + const { mutate: updateStatusMutation, isLoading: isUpdatingStatusLoading } = useUpdateStatusMutation(history, redirectTo, product_uuid, discardFormData, displayAlert); + const { mutate: deleteStatusMutation, isLoading: isDeletingStatusLoading } = useDeleteStatusMutation(history, redirectTo, product_uuid, discardFormData, displayAlert); const handleSubmit = (event) => { event.preventDefault(); - const statusData = _.map(status, (col) => ({ - product_uuid, - name: col, - description: col, - status_tracking_id: null, - is_default_status: !!(col === defaultStatus), - })); - createStatusMutation(statusData); + if (!editStatus) { + const statusData = _.map(status, (col) => ({ + product_uuid, + name: col, + description: col, + status_tracking_id: null, + is_default_status: _.isEqual(col, defaultStatus), + })); + + createStatusMutation(statusData); + } else { + let createStatusData = []; + let editStatusData = []; + let deleteStatusData = []; + + // Existing status + const filteredStatus = _.filter(statuses, { product_uuid }); + const statusDefault = _.find(filteredStatus, (s) => s.is_default_status); + const nameList = _.map(filteredStatus, 'name'); + + _.forEach(nameList, (name) => { + if (!_.includes(status, name)) { + const st = _.find(filteredStatus, { name }); + if (!_.isEmpty(st)) { + deleteStatusData = [...deleteStatusData, st]; + } + } + }); + + _.forEach(status, (st) => { + if (_.includes(nameList, st)) { + const existingStatus = _.find(filteredStatus, { name: st }); + if (!_.isEmpty(existingStatus)) { + editStatusData = [...editStatusData, { ...existingStatus, is_default_status: _.isEqual(st, defaultStatus) }]; + } + } else { + createStatusData = [ + ...createStatusData, + { + product_uuid, + name: st, + description: st, + status_tracking_id: null, + is_default_status: _.isEqual(st, defaultStatus), + }, + ]; + } + }); + + if (!_.isEmpty(deleteStatusData)) { + deleteStatusMutation(deleteStatusData); + } + if (!_.isEmpty(editStatusData)) { + updateStatusMutation(editStatusData); + } + if (!_.isEmpty(createStatusData)) { + createStatusMutation(createStatusData); + } + } }; const submitDisabled = () => { @@ -155,7 +213,8 @@ const StatusBoard = ({ history, location }) => { setConfirmModal={setConfirmModal} handleConfirmModal={discardFormData} > - {(isCreatingStatusLoading || isAllStatusLoading) && } + {(isCreatingStatusLoading || isUpdatingStatusLoading || isDeletingStatusLoading || isAllStatusLoading) + && }
diff --git a/src/react-query/mutations/release/deleteStatusMutation.js b/src/react-query/mutations/release/deleteStatusMutation.js new file mode 100644 index 00000000..8231752e --- /dev/null +++ b/src/react-query/mutations/release/deleteStatusMutation.js @@ -0,0 +1,38 @@ +import { useMutation, useQueryClient } from 'react-query'; +import { httpService } from '@modules/http/http.service'; +import _ from 'lodash'; + +export const useDeleteStatusMutation = (history, redirectTo, product_uuid, discardFormData, displayAlert) => { + const queryClient = useQueryClient(); + + return useMutation( + async (deleteStatusData) => { + const statuses = await Promise.all( + _.map(deleteStatusData, (status_data) => ( + httpService.makeRequest( + 'delete', + `${window.env.API_URL}release/status/${status_data.status_uuid}/`, + status_data, + ) + )), + ); + const finalResponse = _.flatMap(_.map(statuses, 'data')); + return finalResponse; + }, + { + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ['allStatuses', product_uuid] }); + displayAlert('success', 'Status deleted successfully'); + discardFormData(); + if (history) { + history.push(redirectTo); + } + }, + }, + { + onError: () => { + displayAlert('error', 'Unable to delete status!'); + }, + }, + ); +}; diff --git a/src/react-query/mutations/release/updateStatusMutation.js b/src/react-query/mutations/release/updateStatusMutation.js new file mode 100644 index 00000000..2bbc7d9d --- /dev/null +++ b/src/react-query/mutations/release/updateStatusMutation.js @@ -0,0 +1,48 @@ +import { useMutation, useQueryClient } from 'react-query'; +import { httpService } from '@modules/http/http.service'; +import _ from 'lodash'; + +export const useUpdateStatusMutation = (history, redirectTo, product_uuid, discardFormData, displayAlert) => { + const queryClient = useQueryClient(); + + return useMutation( + async (editStatusData) => { + let finalResponse; + if (_.size(editStatusData) > 1) { + const statuses = await Promise.all( + _.map(editStatusData, (status_data) => ( + httpService.makeRequest( + 'put', + `${window.env.API_URL}release/status/${status_data.status_uuid}/`, + status_data, + ) + )), + ); + finalResponse = _.flatMap(_.map(statuses, 'data')); + } else { + const status = await httpService.makeRequest( + 'put', + `${window.env.API_URL}release/status/${editStatusData.status_uuid}`, + editStatusData, + ); + finalResponse = status.data; + } + return finalResponse; + }, + { + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ['allStatuses', product_uuid] }); + displayAlert('success', 'Status updated successfully'); + discardFormData(); + if (history) { + history.push(redirectTo); + } + }, + }, + { + onError: () => { + displayAlert('error', 'Unable to update status!'); + }, + }, + ); +};