mirror of
https://github.com/usebruno/bruno.git
synced 2025-06-25 14:31:44 +02:00
prompt and close multiple tabs
This commit is contained in:
parent
a4043779ca
commit
85bb762ff1
@ -1,10 +1,11 @@
|
|||||||
import React, { useState, useRef, Fragment } from 'react';
|
import React, { useState, useRef, Fragment } from 'react';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import { closeTabs } from 'providers/ReduxStore/slices/tabs';
|
import { closeTabs } from 'providers/ReduxStore/slices/tabs';
|
||||||
import { saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
import { saveMultipleRequests, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
|
import SaveRequestsModal from 'providers/App/ConfirmAppClose/SaveRequestsModal';
|
||||||
import { deleteRequestDraft } from 'providers/ReduxStore/slices/collections';
|
import { deleteRequestDraft } from 'providers/ReduxStore/slices/collections';
|
||||||
import { useTheme } from 'providers/Theme';
|
import { useTheme } from 'providers/Theme';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import darkTheme from 'themes/dark';
|
import darkTheme from 'themes/dark';
|
||||||
import lightTheme from 'themes/light';
|
import lightTheme from 'themes/light';
|
||||||
import { findItemInCollection } from 'utils/collections';
|
import { findItemInCollection } from 'utils/collections';
|
||||||
@ -21,7 +22,7 @@ import DraftTabIcon from './DraftTabIcon';
|
|||||||
const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUid }) => {
|
const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUid }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { storedTheme } = useTheme();
|
const { storedTheme } = useTheme();
|
||||||
const [showConfirmClose, setShowConfirmClose] = useState(false);
|
const [tabsUidsToClose, setTabsUidsToClose] = useState([]);
|
||||||
|
|
||||||
const dropdownTippyRef = useRef();
|
const dropdownTippyRef = useRef();
|
||||||
const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);
|
const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);
|
||||||
@ -68,6 +69,20 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi
|
|||||||
return theme.request.methods[method.toLocaleLowerCase()];
|
return theme.request.methods[method.toLocaleLowerCase()];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showSaveModalForCurrentTab = () => {
|
||||||
|
setTabsUidsToClose([tab.uid]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideSaveModal = () => {
|
||||||
|
setTabsUidsToClose([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCloseTabs = tabUids => {
|
||||||
|
const pendingSaveCount = tabUids.map(tabUid => findItemInCollection(collection, tabUid)).filter(item => item && item.draft).length;
|
||||||
|
if (pendingSaveCount === 0) return dispatch(closeTabs({ tabUids }));
|
||||||
|
setTabsUidsToClose(tabUids);
|
||||||
|
}
|
||||||
|
|
||||||
const folder = folderUid ? findItemInCollection(collection, folderUid) : null;
|
const folder = folderUid ? findItemInCollection(collection, folderUid) : null;
|
||||||
if (['collection-settings', 'folder-settings', 'variables', 'collection-runner', 'security-settings'].includes(tab.type)) {
|
if (['collection-settings', 'folder-settings', 'variables', 'collection-runner', 'security-settings'].includes(tab.type)) {
|
||||||
return (
|
return (
|
||||||
@ -90,14 +105,7 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi
|
|||||||
return (
|
return (
|
||||||
<StyledWrapper
|
<StyledWrapper
|
||||||
className="flex items-center justify-between tab-container px-1"
|
className="flex items-center justify-between tab-container px-1"
|
||||||
onMouseUp={(e) => {
|
onMouseUp={handleMouseUp}
|
||||||
if (e.button === 1) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
dispatch(closeTabs({ tabUids: [tab.uid] }));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<RequestTabNotFound handleCloseClick={handleCloseClick} />
|
<RequestTabNotFound handleCloseClick={handleCloseClick} />
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
@ -107,91 +115,123 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi
|
|||||||
const method = item.draft ? get(item, 'draft.request.method') : get(item, 'request.method');
|
const method = item.draft ? get(item, 'draft.request.method') : get(item, 'request.method');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className="flex items-center justify-between tab-container px-1">
|
<>
|
||||||
{showConfirmClose && (
|
{tabsUidsToClose.length > 0 && (
|
||||||
<ConfirmRequestClose
|
<SaveModal tabsUidsToClose={tabsUidsToClose} collection={collection} onCloseModal={hideSaveModal} />
|
||||||
item={item}
|
|
||||||
onCancel={() => setShowConfirmClose(false)}
|
|
||||||
onCloseWithoutSave={() => {
|
|
||||||
dispatch(
|
|
||||||
deleteRequestDraft({
|
|
||||||
itemUid: item.uid,
|
|
||||||
collectionUid: collection.uid
|
|
||||||
})
|
|
||||||
);
|
|
||||||
dispatch(
|
|
||||||
closeTabs({
|
|
||||||
tabUids: [tab.uid]
|
|
||||||
})
|
|
||||||
);
|
|
||||||
setShowConfirmClose(false);
|
|
||||||
}}
|
|
||||||
onSaveAndClose={() => {
|
|
||||||
dispatch(saveRequest(item.uid, collection.uid))
|
|
||||||
.then(() => {
|
|
||||||
dispatch(
|
|
||||||
closeTabs({
|
|
||||||
tabUids: [tab.uid]
|
|
||||||
})
|
|
||||||
);
|
|
||||||
setShowConfirmClose(false);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.log('err', err);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<div
|
<StyledWrapper className="flex items-center justify-between tab-container px-1">
|
||||||
className="flex items-baseline tab-label pl-2"
|
<div
|
||||||
onContextMenu={handleRightClick}
|
className="flex items-baseline tab-label pl-2"
|
||||||
onMouseUp={(e) => {
|
onContextMenu={handleRightClick}
|
||||||
if (!item.draft) return handleMouseUp(e);
|
onMouseUp={(e) => {
|
||||||
|
if (!item.draft) return handleMouseUp(e);
|
||||||
|
|
||||||
|
if (e.button === 1) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
showSaveModalForCurrentTab();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="tab-method uppercase" style={{ color: getMethodColor(method), fontSize: 12 }}>
|
||||||
|
{method}
|
||||||
|
</span>
|
||||||
|
<span className="ml-1 tab-name" title={item.name}>
|
||||||
|
{item.name}
|
||||||
|
</span>
|
||||||
|
<RequestTabMenu
|
||||||
|
onDropdownCreate={onDropdownCreate}
|
||||||
|
onCloseTabs={handleCloseTabs}
|
||||||
|
tabIndex={tabIndex}
|
||||||
|
collectionRequestTabs={collectionRequestTabs}
|
||||||
|
tabItem={item}
|
||||||
|
collection={collection}
|
||||||
|
dropdownTippyRef={dropdownTippyRef}
|
||||||
|
dispatch={dispatch}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex px-2 close-icon-container"
|
||||||
|
onClick={(e) => {
|
||||||
|
if (!item.draft) return handleCloseClick(e);
|
||||||
|
|
||||||
if (e.button === 1) {
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setShowConfirmClose(true);
|
showSaveModalForCurrentTab();
|
||||||
}
|
}}
|
||||||
}}
|
>
|
||||||
>
|
{!item.draft ? (
|
||||||
<span className="tab-method uppercase" style={{ color: getMethodColor(method), fontSize: 12 }}>
|
<CloseTabIcon />
|
||||||
{method}
|
) : (
|
||||||
</span>
|
<DraftTabIcon />
|
||||||
<span className="ml-1 tab-name" title={item.name}>
|
)}
|
||||||
{item.name}
|
</div>
|
||||||
</span>
|
</StyledWrapper>
|
||||||
<RequestTabMenu
|
</>
|
||||||
onDropdownCreate={onDropdownCreate}
|
|
||||||
tabIndex={tabIndex}
|
|
||||||
collectionRequestTabs={collectionRequestTabs}
|
|
||||||
tabItem={item}
|
|
||||||
collection={collection}
|
|
||||||
dropdownTippyRef={dropdownTippyRef}
|
|
||||||
dispatch={dispatch}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="flex px-2 close-icon-container"
|
|
||||||
onClick={(e) => {
|
|
||||||
if (!item.draft) return handleCloseClick(e);
|
|
||||||
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
setShowConfirmClose(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{!item.draft ? (
|
|
||||||
<CloseTabIcon />
|
|
||||||
) : (
|
|
||||||
<DraftTabIcon />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</StyledWrapper>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function RequestTabMenu({ onDropdownCreate, collectionRequestTabs, tabIndex, collection, dropdownTippyRef, dispatch }) {
|
function SaveModal ({ tabsUidsToClose, collection, onCloseModal }) {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const tabs = useSelector((state) => state.tabs.tabs);
|
||||||
|
const tabUids = tabs.map(tab => tab.uid);
|
||||||
|
|
||||||
|
const handleCloseTabs = () => {
|
||||||
|
return dispatch(closeTabs({ tabUids: tabsUidsToClose }));
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCloseWithoutSave = async discardedItems => {
|
||||||
|
await Promise.all(discardedItems.map(item => {
|
||||||
|
dispatch(
|
||||||
|
deleteRequestDraft({
|
||||||
|
itemUid: item.uid,
|
||||||
|
collectionUid: collection.uid
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}));
|
||||||
|
handleCloseTabs();
|
||||||
|
onCloseModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSaveAndClose = async itemsToSave => {
|
||||||
|
await dispatch(saveMultipleRequests(itemsToSave.map(item => ({ ...item, collectionUid: collection.uid }))));
|
||||||
|
handleCloseTabs();
|
||||||
|
onCloseModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tabsUidsToClose.some(tabUid => tabUids.includes(tabUid))) return null;
|
||||||
|
|
||||||
|
const tabsAndItemsToShowSaveModal = tabsUidsToClose.reduce((acc, tabUid) => {
|
||||||
|
const item = findItemInCollection(collection, tabUid);
|
||||||
|
if (item && item.draft) acc[tabUid] = item;
|
||||||
|
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])}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SaveRequestsModal items={Object.values(tabsAndItemsToShowSaveModal)}
|
||||||
|
onCancel={onCloseModal}
|
||||||
|
onCloseWithoutSave={handleCloseWithoutSave}
|
||||||
|
onSaveAndClose={handleSaveAndClose} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RequestTabMenu({ onDropdownCreate, onCloseTabs, collectionRequestTabs, tabIndex, collection, dropdownTippyRef, dispatch }) {
|
||||||
const [showCloneRequestModal, setShowCloneRequestModal] = useState(false);
|
const [showCloneRequestModal, setShowCloneRequestModal] = useState(false);
|
||||||
const [showAddNewRequestModal, setShowAddNewRequestModal] = useState(false);
|
const [showAddNewRequestModal, setShowAddNewRequestModal] = useState(false);
|
||||||
|
|
||||||
@ -202,8 +242,9 @@ function RequestTabMenu({ onDropdownCreate, collectionRequestTabs, tabIndex, col
|
|||||||
const hasLeftTabs = tabIndex !== 0;
|
const hasLeftTabs = tabIndex !== 0;
|
||||||
const hasRightTabs = totalTabs > tabIndex + 1;
|
const hasRightTabs = totalTabs > tabIndex + 1;
|
||||||
const hasOtherTabs = totalTabs > 1;
|
const hasOtherTabs = totalTabs > 1;
|
||||||
|
const hasSavedTabs = collectionRequestTabs.map((tab) => findItemInCollection(collection, tab.uid)).some((item) => item && !item.draft);
|
||||||
|
|
||||||
async function handleCloseTab(event, tabUid) {
|
function handleCurrentTabClose(event, tabUid) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
dropdownTippyRef.current.hide();
|
dropdownTippyRef.current.hide();
|
||||||
|
|
||||||
@ -211,48 +252,42 @@ function RequestTabMenu({ onDropdownCreate, collectionRequestTabs, tabIndex, col
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return onCloseTabs([tabUid]);
|
||||||
const item = findItemInCollection(collection, tabUid);
|
|
||||||
// silently save unsaved changes before closing the tab
|
|
||||||
if (item.draft) {
|
|
||||||
await dispatch(saveRequest(item.uid, collection.uid, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(closeTabs({ tabUids: [tabUid] }));
|
|
||||||
} catch (err) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCloseOtherTabs(event) {
|
function handleCloseOtherTabs(event) {
|
||||||
dropdownTippyRef.current.hide();
|
dropdownTippyRef.current.hide();
|
||||||
|
|
||||||
const otherTabs = collectionRequestTabs.filter((_, index) => index !== tabIndex);
|
const otherTabs = collectionRequestTabs.filter((_, index) => index !== tabIndex);
|
||||||
otherTabs.forEach((tab) => handleCloseTab(event, tab.uid));
|
onCloseTabs(otherTabs.map((tab) => tab.uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCloseTabsToTheLeft(event) {
|
function handleCloseTabsToTheLeft(event) {
|
||||||
dropdownTippyRef.current.hide();
|
dropdownTippyRef.current.hide();
|
||||||
|
|
||||||
const leftTabs = collectionRequestTabs.filter((_, index) => index < tabIndex);
|
const leftTabs = collectionRequestTabs.filter((_, index) => index < tabIndex);
|
||||||
leftTabs.forEach((tab) => handleCloseTab(event, tab.uid));
|
onCloseTabs(leftTabs.map((tab) => tab.uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCloseTabsToTheRight(event) {
|
function handleCloseTabsToTheRight(event) {
|
||||||
dropdownTippyRef.current.hide();
|
dropdownTippyRef.current.hide();
|
||||||
|
|
||||||
const rightTabs = collectionRequestTabs.filter((_, index) => index > tabIndex);
|
const rightTabs = collectionRequestTabs.filter((_, index) => index > tabIndex);
|
||||||
rightTabs.forEach((tab) => handleCloseTab(event, tab.uid));
|
onCloseTabs(rightTabs.map((tab) => tab.uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCloseSavedTabs(event) {
|
function handleCloseSavedTabs(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
const savedTabs = collection.items.filter((item) => !item.draft);
|
const savedTabs = collectionRequestTabs.filter((tab) => {
|
||||||
const savedTabIds = savedTabs.map((item) => item.uid) || [];
|
const item = findItemInCollection(collection, tab.uid)
|
||||||
dispatch(closeTabs({ tabUids: savedTabIds }));
|
return item && !item.draft;
|
||||||
|
});
|
||||||
|
onCloseTabs(savedTabs.map((tab) => tab.uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCloseAllTabs(event) {
|
function handleCloseAllTabs(event) {
|
||||||
collectionRequestTabs.forEach((tab) => handleCloseTab(event, tab.uid));
|
onCloseTabs(collectionRequestTabs.map((tab) => tab.uid));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -288,7 +323,7 @@ function RequestTabMenu({ onDropdownCreate, collectionRequestTabs, tabIndex, col
|
|||||||
>
|
>
|
||||||
Clone Request
|
Clone Request
|
||||||
</button>
|
</button>
|
||||||
<button className="dropdown-item w-full" onClick={(e) => handleCloseTab(e, currentTabUid)}>
|
<button className="dropdown-item w-full" onClick={(e) => handleCurrentTabClose(e, currentTabUid)}>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
<button disabled={!hasOtherTabs} className="dropdown-item w-full" onClick={handleCloseOtherTabs}>
|
<button disabled={!hasOtherTabs} className="dropdown-item w-full" onClick={handleCloseOtherTabs}>
|
||||||
@ -300,7 +335,7 @@ function RequestTabMenu({ onDropdownCreate, collectionRequestTabs, tabIndex, col
|
|||||||
<button disabled={!hasRightTabs} className="dropdown-item w-full" onClick={handleCloseTabsToTheRight}>
|
<button disabled={!hasRightTabs} className="dropdown-item w-full" onClick={handleCloseTabsToTheRight}>
|
||||||
Close to the Right
|
Close to the Right
|
||||||
</button>
|
</button>
|
||||||
<button className="dropdown-item w-full" onClick={handleCloseSavedTabs}>
|
<button disabled={!hasSavedTabs} className="dropdown-item w-full" onClick={handleCloseSavedTabs}>
|
||||||
Close Saved
|
Close Saved
|
||||||
</button>
|
</button>
|
||||||
<button className="dropdown-item w-full" onClick={handleCloseAllTabs}>
|
<button className="dropdown-item w-full" onClick={handleCloseAllTabs}>
|
||||||
|
@ -1,32 +1,18 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
|
||||||
import { pluralizeWord } from 'utils/common';
|
import { pluralizeWord } from 'utils/common';
|
||||||
import { saveMultipleRequests } from 'providers/ReduxStore/slices/collections/actions';
|
|
||||||
import { IconAlertTriangle } from '@tabler/icons';
|
import { IconAlertTriangle } from '@tabler/icons';
|
||||||
import Modal from 'components/Modal';
|
import Modal from 'components/Modal';
|
||||||
|
|
||||||
const SaveRequestsModal = ({ onConfirm, onClose, draftRequests = [] }) => {
|
const SaveRequestsModal = ({ onSaveAndClose, onCloseWithoutSave, onCancel, items = [] }) => {
|
||||||
const MAX_UNSAVED_REQUESTS_TO_SHOW = 5;
|
const MAX_UNSAVED_REQUESTS_TO_SHOW = 5;
|
||||||
const dispatch = useDispatch();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (draftRequests.length === 0) {
|
if (items.length === 0) {
|
||||||
return dispatch(onConfirm());
|
return onCloseWithoutSave([]);
|
||||||
}
|
}
|
||||||
}, [draftRequests, dispatch]);
|
}, [items]);
|
||||||
|
|
||||||
const closeWithoutSave = () => {
|
if (!items.length) {
|
||||||
dispatch(onConfirm());
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeWithSave = () => {
|
|
||||||
dispatch(saveMultipleRequests(draftRequests))
|
|
||||||
.then(() => dispatch(onConfirm()))
|
|
||||||
.then(() => onClose());
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!draftRequests.length) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +22,7 @@ const SaveRequestsModal = ({ onConfirm, onClose, draftRequests = [] }) => {
|
|||||||
title="Unsaved changes"
|
title="Unsaved changes"
|
||||||
confirmText="Save and Close"
|
confirmText="Save and Close"
|
||||||
cancelText="Close without saving"
|
cancelText="Close without saving"
|
||||||
handleCancel={onClose}
|
handleCancel={onCancel}
|
||||||
disableEscapeKey={true}
|
disableEscapeKey={true}
|
||||||
disableCloseOnOutsideClick={true}
|
disableCloseOnOutsideClick={true}
|
||||||
closeModalFadeTimeout={150}
|
closeModalFadeTimeout={150}
|
||||||
@ -48,11 +34,11 @@ const SaveRequestsModal = ({ onConfirm, onClose, draftRequests = [] }) => {
|
|||||||
</div>
|
</div>
|
||||||
<p className="mt-4">
|
<p className="mt-4">
|
||||||
Do you want to save the changes you made to the following{' '}
|
Do you want to save the changes you made to the following{' '}
|
||||||
<span className="font-medium">{draftRequests.length}</span> {pluralizeWord('request', draftRequests.length)}?
|
<span className="font-medium">{items.length}</span> {pluralizeWord('request', items.length)}?
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul className="mt-4">
|
<ul className="mt-4">
|
||||||
{draftRequests.slice(0, MAX_UNSAVED_REQUESTS_TO_SHOW).map((item) => {
|
{items.slice(0, MAX_UNSAVED_REQUESTS_TO_SHOW).map((item) => {
|
||||||
return (
|
return (
|
||||||
<li key={item.uid} className="mt-1 text-xs">
|
<li key={item.uid} className="mt-1 text-xs">
|
||||||
{item.filename}
|
{item.filename}
|
||||||
@ -61,25 +47,25 @@ const SaveRequestsModal = ({ onConfirm, onClose, draftRequests = [] }) => {
|
|||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{draftRequests.length > MAX_UNSAVED_REQUESTS_TO_SHOW && (
|
{items.length > MAX_UNSAVED_REQUESTS_TO_SHOW && (
|
||||||
<p className="mt-1 text-xs">
|
<p className="mt-1 text-xs">
|
||||||
...{draftRequests.length - MAX_UNSAVED_REQUESTS_TO_SHOW} additional{' '}
|
...{items.length - MAX_UNSAVED_REQUESTS_TO_SHOW} additional{' '}
|
||||||
{pluralizeWord('request', draftRequests.length - MAX_UNSAVED_REQUESTS_TO_SHOW)} not shown
|
{pluralizeWord('request', items.length - MAX_UNSAVED_REQUESTS_TO_SHOW)} not shown
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex justify-between mt-6">
|
<div className="flex justify-between mt-6">
|
||||||
<div>
|
<div>
|
||||||
<button className="btn btn-sm btn-danger" onClick={closeWithoutSave}>
|
<button className="btn btn-sm btn-danger" onClick={() => onCloseWithoutSave(items)}>
|
||||||
Don't Save
|
Don't Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button className="btn btn-close btn-sm mr-2" onClick={onClose}>
|
<button className="btn btn-close btn-sm mr-2" onClick={onCancel}>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button className="btn btn-secondary btn-sm" onClick={closeWithSave}>
|
<button className="btn btn-secondary btn-sm" onClick={() => onSaveAndClose(items)}>
|
||||||
{draftRequests.length > 1 ? 'Save All' : 'Save'}
|
{items.length > 1 ? 'Save All' : 'Save'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,6 +7,7 @@ import filter from 'lodash/filter';
|
|||||||
import groupBy from 'lodash/groupBy';
|
import groupBy from 'lodash/groupBy';
|
||||||
import SaveRequestsModal from './SaveRequestsModal';
|
import SaveRequestsModal from './SaveRequestsModal';
|
||||||
import { isElectron } from 'utils/common/platform';
|
import { isElectron } from 'utils/common/platform';
|
||||||
|
import { saveMultipleRequests } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
import { completeQuitFlow } from 'providers/ReduxStore/slices/app';
|
import { completeQuitFlow } from 'providers/ReduxStore/slices/app';
|
||||||
|
|
||||||
const ConfirmAppClose = () => {
|
const ConfirmAppClose = () => {
|
||||||
@ -41,10 +42,10 @@ const ConfirmAppClose = () => {
|
|||||||
const collection = findCollectionByUid(collections, collectionUid);
|
const collection = findCollectionByUid(collections, collectionUid);
|
||||||
if (collection) {
|
if (collection) {
|
||||||
const items = flattenItems(collection.items);
|
const items = flattenItems(collection.items);
|
||||||
const drafts = filter(items, (item) => isItemARequest(item) && item.draft);
|
const requests = filter(items, (item) => isItemARequest(item) && item.draft);
|
||||||
each(drafts, (draft) => {
|
each(requests, (request) => {
|
||||||
draftRequests.push({
|
draftRequests.push({
|
||||||
...draft,
|
...request,
|
||||||
collectionUid: collectionUid
|
collectionUid: collectionUid
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -53,7 +54,17 @@ const ConfirmAppClose = () => {
|
|||||||
return draftRequests
|
return draftRequests
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SaveRequestsModal draftRequests={getAllDraftRequests()} onConfirm={completeQuitFlow} onClose={() => setShowConfirmClose(false)} />;
|
const quit = () => dispatch(completeQuitFlow());
|
||||||
|
|
||||||
|
const handleSaveAndClose = async items => {
|
||||||
|
await dispatch(saveMultipleRequests(items));
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return <SaveRequestsModal items={getAllDraftRequests()}
|
||||||
|
onCancel={() => setShowConfirmClose(false)}
|
||||||
|
onCloseWithoutSave={quit}
|
||||||
|
onSaveAndClose={handleSaveAndClose} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ConfirmAppClose;
|
export default ConfirmAppClose;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user