Refact: single modal component for saving requests

This commit is contained in:
Ricardo Silverio 2024-09-29 11:44:30 -03:00
parent 453dc4d6dc
commit bc07087028
4 changed files with 65 additions and 105 deletions

View File

@ -1,49 +0,0 @@
import React from 'react';
import { IconAlertTriangle } from '@tabler/icons';
import Modal from 'components/Modal';
const ConfirmRequestClose = ({ item, onCancel, onCloseWithoutSave, onSaveAndClose }) => {
return (
<Modal
size="md"
title="Unsaved changes"
confirmText="Save and Close"
cancelText="Close without saving"
disableEscapeKey={true}
disableCloseOnOutsideClick={true}
closeModalFadeTimeout={150}
handleCancel={onCancel}
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
}}
hideFooter={true}
>
<div className="flex items-center font-normal">
<IconAlertTriangle size={32} strokeWidth={1.5} className="text-yellow-600" />
<h1 className="ml-2 text-lg font-semibold">Hold on..</h1>
</div>
<div className="font-normal mt-4">
You have unsaved changes in request <span className="font-semibold">{item.name}</span>.
</div>
<div className="flex justify-between mt-6">
<div>
<button className="btn btn-sm btn-danger" onClick={onCloseWithoutSave}>
Don't Save
</button>
</div>
<div>
<button className="btn btn-close btn-sm mr-2" onClick={onCancel}>
Cancel
</button>
<button className="btn btn-secondary btn-sm" onClick={onSaveAndClose}>
Save
</button>
</div>
</div>
</Modal>
);
};
export default ConfirmRequestClose;

View File

@ -1,15 +1,13 @@
import React, { useState, useRef, Fragment } from 'react';
import get from 'lodash/get';
import { closeTabs } from 'providers/ReduxStore/slices/tabs';
import { saveMultipleRequests, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
import SaveRequestsModal from 'providers/App/ConfirmAppClose/SaveRequestsModal';
import SaveRequestsModal from 'components/SaveRequestsModal';
import { deleteRequestDraft } from 'providers/ReduxStore/slices/collections';
import { useTheme } from 'providers/Theme';
import { useDispatch, useSelector } from 'react-redux';
import darkTheme from 'themes/dark';
import lightTheme from 'themes/light';
import { findItemInCollection } from 'utils/collections';
import ConfirmRequestClose from './ConfirmRequestClose';
import RequestTabNotFound from './RequestTabNotFound';
import SpecialTab from './SpecialTab';
import StyledWrapper from './StyledWrapper';
@ -194,38 +192,23 @@ function SaveModal ({ tabsUidsToClose, collection, onCloseModal }) {
onCloseModal();
}
const handleSaveAndClose = async itemsToSave => {
await dispatch(saveMultipleRequests(itemsToSave.map(item => ({ ...item, collectionUid: collection.uid }))));
const handleSaveAndClose = async () => {
handleCloseTabs();
onCloseModal();
}
if (!tabsUidsToClose.some(tabUid => tabUids.includes(tabUid))) return null;
const tabsAndItemsToShowSaveModal = tabsUidsToClose.reduce((acc, tabUid) => {
const itemsPendingSave = tabsUidsToClose.reduce((acc, tabUid) => {
const item = findItemInCollection(collection, tabUid);
if (item && item.draft) acc[tabUid] = item;
if (item && item.draft) acc.push({ ...item, collectionUid: collection.uid });
return acc;
}, {});
}, []);
const pendingSaveCount = Object.keys(tabsAndItemsToShowSaveModal).length;
if (pendingSaveCount === 0) return null;
if (pendingSaveCount === 1) {
const tabUid = Object.keys(tabsAndItemsToShowSaveModal)[0];
const item = tabsAndItemsToShowSaveModal[tabUid];
return (
<ConfirmRequestClose
item={item}
onCancel={onCloseModal}
onCloseWithoutSave={() => handleCloseWithoutSave([item])}
onSaveAndClose={() => handleSaveAndClose([item])}
/>
);
}
if (!itemsPendingSave.length) return null;
return (
<SaveRequestsModal items={Object.values(tabsAndItemsToShowSaveModal)}
<SaveRequestsModal items={itemsPendingSave}
onCancel={onCloseModal}
onCloseWithoutSave={handleCloseWithoutSave}
onSaveAndClose={handleSaveAndClose} />

View File

@ -1,11 +1,61 @@
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { pluralizeWord } from 'utils/common';
import { IconAlertTriangle } from '@tabler/icons';
import Modal from 'components/Modal';
import { saveMultipleRequests } from 'providers/ReduxStore/slices/collections/actions';
const SingleRequestMessage = ({ item }) => {
return (
<div className="font-normal mt-4">
You have unsaved changes in request <span className="font-semibold">{item.name}</span>.
</div>
)
}
const MultipleRequestsMessage = ({ items, maxItems }) => {
return (
<>
<p className="mt-4">
Do you want to save the changes you made to the following{' '}
<span className="font-medium">{items.length}</span> {pluralizeWord('request', items.length)}?
</p>
<ul className="mt-4">
{items.slice(0, maxItems).map((item) => {
return (
<li key={item.uid} className="mt-1 text-xs">
{item.filename}
</li>
);
})}
</ul>
{items.length > maxItems && (
<p className="mt-1 text-xs">
...{items.length - maxItems} additional{' '}
{pluralizeWord('request', items.length - maxItems)} not shown
</p>
)}
</>
)
}
const SaveRequestsModal = ({ onSaveAndClose, onCloseWithoutSave, onCancel, items = [] }) => {
const dispatch = useDispatch();
const MAX_UNSAVED_REQUESTS_TO_SHOW = 5;
const handleSaveAndClose = async () => {
await dispatch(saveMultipleRequests(items));
onSaveAndClose(items);
}
const handleCloseWithoutSave = async () => {
onCloseWithoutSave(items);
}
useEffect(() => {
if (items.length === 0) {
return onCloseWithoutSave([]);
@ -32,31 +82,13 @@ const SaveRequestsModal = ({ onSaveAndClose, onCloseWithoutSave, onCancel, items
<IconAlertTriangle size={32} strokeWidth={1.5} className="text-yellow-600" />
<h1 className="ml-2 text-lg font-semibold">Hold on..</h1>
</div>
<p className="mt-4">
Do you want to save the changes you made to the following{' '}
<span className="font-medium">{items.length}</span> {pluralizeWord('request', items.length)}?
</p>
<ul className="mt-4">
{items.slice(0, MAX_UNSAVED_REQUESTS_TO_SHOW).map((item) => {
return (
<li key={item.uid} className="mt-1 text-xs">
{item.filename}
</li>
);
})}
</ul>
{items.length > MAX_UNSAVED_REQUESTS_TO_SHOW && (
<p className="mt-1 text-xs">
...{items.length - MAX_UNSAVED_REQUESTS_TO_SHOW} additional{' '}
{pluralizeWord('request', items.length - MAX_UNSAVED_REQUESTS_TO_SHOW)} not shown
</p>
)}
{items.length > 1 ?
<MultipleRequestsMessage items={items} maxItems={MAX_UNSAVED_REQUESTS_TO_SHOW} /> :
<SingleRequestMessage item={items[0]} />
}
<div className="flex justify-between mt-6">
<div>
<button className="btn btn-sm btn-danger" onClick={() => onCloseWithoutSave(items)}>
<button className="btn btn-sm btn-danger" onClick={handleCloseWithoutSave}>
Don't Save
</button>
</div>
@ -64,7 +96,7 @@ const SaveRequestsModal = ({ onSaveAndClose, onCloseWithoutSave, onCancel, items
<button className="btn btn-close btn-sm mr-2" onClick={onCancel}>
Cancel
</button>
<button className="btn btn-secondary btn-sm" onClick={() => onSaveAndClose(items)}>
<button className="btn btn-secondary btn-sm" onClick={handleSaveAndClose}>
{items.length > 1 ? 'Save All' : 'Save'}
</button>
</div>

View File

@ -5,9 +5,8 @@ import { findCollectionByUid, flattenItems, isItemARequest } from 'utils/collect
import each from 'lodash/each';
import filter from 'lodash/filter';
import groupBy from 'lodash/groupBy';
import SaveRequestsModal from './SaveRequestsModal';
import SaveRequestsModal from 'components/SaveRequestsModal';
import { isElectron } from 'utils/common/platform';
import { saveMultipleRequests } from 'providers/ReduxStore/slices/collections/actions';
import { completeQuitFlow } from 'providers/ReduxStore/slices/app';
const ConfirmAppClose = () => {
@ -56,15 +55,10 @@ const ConfirmAppClose = () => {
const quit = () => dispatch(completeQuitFlow());
const handleSaveAndClose = async items => {
await dispatch(saveMultipleRequests(items));
quit();
}
return <SaveRequestsModal items={getAllDraftRequests()}
onCancel={() => setShowConfirmClose(false)}
onCloseWithoutSave={quit}
onSaveAndClose={handleSaveAndClose} />;
onSaveAndClose={quit} />;
};
export default ConfirmAppClose;