mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
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:
committed by
GitHub
parent
d2f6eb146b
commit
7ef3981656
@@ -63,7 +63,7 @@ const StyledWrapper = styled.div`
|
||||
height: 100%;
|
||||
cursor: col-resize;
|
||||
background: transparent;
|
||||
z-index: 100;
|
||||
z-index: 10;
|
||||
|
||||
&:hover,
|
||||
&.resizing {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user