fix: resolve theme, overflow, and z-index bugs in Remove Collection modal (#7590)

Use themed styled-component classes instead of hardcoded Tailwind colors
for the drafts confirmation modal, add text truncation for long collection
names, and lower EditableTable resize-handle z-index so it no longer
renders above modals.

Co-authored-by: Chirag Chandrashekhar <cchirag85@gmail.com>
This commit is contained in:
Chirag Chandrashekhar
2026-03-27 19:52:57 +05:30
committed by GitHub
parent d2f6eb146b
commit 7ef3981656
3 changed files with 117 additions and 93 deletions

View File

@@ -63,7 +63,7 @@ const StyledWrapper = styled.div`
height: 100%;
cursor: col-resize;
background: transparent;
z-index: 100;
z-index: 10;
&:hover,
&.resizing {

View File

@@ -10,6 +10,7 @@ import { IconAlertTriangle, IconDeviceFloppy } from '@tabler/icons';
import Modal from 'components/Modal';
import toast from 'react-hot-toast';
import Button from 'ui/Button';
import StyledWrapper from './StyledWrapper';
const MAX_UNSAVED_REQUESTS_TO_SHOW = 5;
@@ -108,103 +109,105 @@ const ConfirmCollectionCloseDrafts = ({ onClose, collection, collectionUid }) =>
}
return (
<Modal
size="md"
title="Remove Collection"
confirmText="Save and Remove"
cancelText="Remove without saving"
handleCancel={onClose}
disableEscapeKey={true}
disableCloseOnOutsideClick={true}
closeModalFadeTimeout={150}
hideFooter={true}
>
<div className="flex items-center">
<IconAlertTriangle size={32} strokeWidth={1.5} className="text-yellow-600" />
<h1 className="ml-2 text-lg font-medium">Hold on..</h1>
</div>
<p className="mt-4">
You have unsaved changes in <span className="font-medium">{allDrafts.length}</span>{' '}
{pluralizeWord('request', allDrafts.length)}.
</p>
{/* Regular (saved) requests with changes */}
{currentDrafts.length > 0 && (
<div className="mt-4">
<p className="text-sm font-medium mb-2">
Saved {pluralizeWord('Request', currentDrafts.length)} ({currentDrafts.length})
</p>
<ul className="ml-2">
{currentDrafts.slice(0, MAX_UNSAVED_REQUESTS_TO_SHOW).map((item) => {
return (
<li key={item.uid} className="mt-1 text-xs text-gray-600">
{item.filename || item.name}
</li>
);
})}
</ul>
{currentDrafts.length > MAX_UNSAVED_REQUESTS_TO_SHOW && (
<p className="ml-2 mt-1 text-xs text-gray-500">
...{currentDrafts.length - MAX_UNSAVED_REQUESTS_TO_SHOW} additional{' '}
{pluralizeWord('request', currentDrafts.length - MAX_UNSAVED_REQUESTS_TO_SHOW)} not shown
</p>
)}
<StyledWrapper>
<Modal
size="md"
title="Remove Collection"
confirmText="Save and Remove"
cancelText="Remove without saving"
handleCancel={onClose}
disableEscapeKey={true}
disableCloseOnOutsideClick={true}
closeModalFadeTimeout={150}
hideFooter={true}
>
<div className="flex items-center">
<IconAlertTriangle size={32} strokeWidth={1.5} className="warning-text" />
<h1 className="ml-2 text-lg font-medium">Hold on..</h1>
</div>
)}
<p className="mt-4">
You have unsaved changes in <span className="font-medium">{allDrafts.length}</span>{' '}
{pluralizeWord('request', allDrafts.length)}.
</p>
{/* Transient (unsaved) requests */}
{currentTransientDrafts.length > 0 && (
<div className="mt-4">
<p className="text-sm font-medium mb-2">
Transient {pluralizeWord('Request', currentTransientDrafts.length)} ({currentTransientDrafts.length})
</p>
<p className="text-xs text-orange-600 mb-3">
These requests need to be saved individually before closing the collection.
</p>
<div className="space-y-2 max-h-64 overflow-y-auto pr-1">
{currentTransientDrafts.map((item) => {
return (
<div
key={item.uid}
className="flex items-center justify-between py-2 px-3 bg-gray-50 rounded border border-gray-200"
>
<span className="text-sm text-gray-700 truncate mr-3">{item.name}</span>
<Button
color="primary"
variant="ghost"
size="sm"
onClick={() => handleSaveTransient(item)}
icon={<IconDeviceFloppy size={14} strokeWidth={1.5} />}
{/* Regular (saved) requests with changes */}
{currentDrafts.length > 0 && (
<div className="mt-4">
<p className="text-sm font-medium mb-2">
Saved {pluralizeWord('Request', currentDrafts.length)} ({currentDrafts.length})
</p>
<ul className="ml-2">
{currentDrafts.slice(0, MAX_UNSAVED_REQUESTS_TO_SHOW).map((item) => {
return (
<li key={item.uid} className="mt-1 text-xs draft-list-item">
{item.filename || item.name}
</li>
);
})}
</ul>
{currentDrafts.length > MAX_UNSAVED_REQUESTS_TO_SHOW && (
<p className="ml-2 mt-1 text-xs draft-list-item">
...{currentDrafts.length - MAX_UNSAVED_REQUESTS_TO_SHOW} additional{' '}
{pluralizeWord('request', currentDrafts.length - MAX_UNSAVED_REQUESTS_TO_SHOW)} not shown
</p>
)}
</div>
)}
{/* Transient (unsaved) requests */}
{currentTransientDrafts.length > 0 && (
<div className="mt-4">
<p className="text-sm font-medium mb-2">
Transient {pluralizeWord('Request', currentTransientDrafts.length)} ({currentTransientDrafts.length})
</p>
<p className="text-xs transient-hint mb-3">
These requests need to be saved individually before closing the collection.
</p>
<div className="space-y-2 max-h-64 overflow-y-auto pr-1">
{currentTransientDrafts.map((item) => {
return (
<div
key={item.uid}
className="flex items-center justify-between py-2 px-3 transient-item"
>
Save
</Button>
</div>
);
})}
<span className="text-sm transient-item-name truncate mr-3">{item.name}</span>
<Button
color="primary"
variant="ghost"
size="sm"
onClick={() => handleSaveTransient(item)}
icon={<IconDeviceFloppy size={14} strokeWidth={1.5} />}
>
Save
</Button>
</div>
);
})}
</div>
</div>
)}
<div className="flex justify-between mt-6">
<div>
<Button color="danger" onClick={handleDiscardAll}>
Discard All and Remove
</Button>
</div>
<div>
<Button className="mr-2" color="secondary" variant="ghost" onClick={onClose}>
Cancel
</Button>
<Button
onClick={handleSaveAll}
disabled={currentTransientDrafts.length > 0}
title={currentTransientDrafts.length > 0 ? 'Please save or discard transient requests first' : ''}
>
{currentDrafts.length > 1 ? 'Save All and Remove' : 'Save and Remove'}
</Button>
</div>
</div>
)}
<div className="flex justify-between mt-6">
<div>
<Button color="danger" onClick={handleDiscardAll}>
Discard All and Remove
</Button>
</div>
<div>
<Button className="mr-2" color="secondary" variant="ghost" onClick={onClose}>
Cancel
</Button>
<Button
onClick={handleSaveAll}
disabled={currentTransientDrafts.length > 0}
title={currentTransientDrafts.length > 0 ? 'Please save or discard transient requests first' : ''}
>
{currentDrafts.length > 1 ? 'Save All and Remove' : 'Save and Remove'}
</Button>
</div>
</div>
</Modal>
</Modal>
</StyledWrapper>
);
};

View File

@@ -12,6 +12,9 @@ const StyledWrapper = styled.div`
color: ${(props) => props.theme.text};
margin-bottom: 4px;
cursor: default !important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:hover {
background: none !important;
}
@@ -24,6 +27,24 @@ const StyledWrapper = styled.div`
.warning-icon {
color: ${(props) => props.theme.status.warning.text};
}
.warning-text {
color: ${(props) => props.theme.status.warning.text};
}
.draft-list-item {
color: ${(props) => props.theme.colors.text.muted};
}
.transient-hint {
color: ${(props) => props.theme.colors.text.warning};
}
.transient-item {
background-color: ${(props) => props.theme.background.surface0};
border: 1px solid ${(props) => props.theme.border.border0};
border-radius: 4px;
}
.transient-item-name {
color: ${(props) => props.theme.text};
}
`;
export default StyledWrapper;