feat: Рефакторинг модальных окон с добавлением обработчиков клика по фону для закрытия. Обновление компонентов ConfirmDialog, ConfirmDiffModal, ConfirmModal, FormModal, HistoryModal, ImportModal, SettingsModal и WsUpdateModal для улучшения взаимодействия с пользователем и унификации интерфейса.
Publish Fast Tabler Docker image / build-and-push-fast (push) Failing after 1m6s
Publish Fast Tabler Docker image / build-and-push-fast (push) Failing after 1m6s
This commit is contained in:
@@ -18,12 +18,23 @@ export default function ConfirmDialog({
|
|||||||
}) {
|
}) {
|
||||||
if (!open) return null;
|
if (!open) return null;
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onCancel?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onCancel?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onCancel?.(); }}
|
||||||
>
|
>
|
||||||
<div className={`modal-dialog ${size === 'sm' ? 'modal-sm' : size === 'lg' ? 'modal-lg' : ''} modal-dialog-centered`} role="document">
|
<div className={`modal-dialog ${size === 'sm' ? 'modal-sm' : size === 'lg' ? 'modal-lg' : ''} modal-dialog-centered`} role="document">
|
||||||
@@ -49,7 +60,7 @@ export default function ConfirmDialog({
|
|||||||
>
|
>
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h5 className="modal-title">{title}</h5>
|
<h5 className="modal-title">{title}</h5>
|
||||||
<button type="button" className="btn-close" onClick={onCancel} />
|
<button type="button" className="btn-close" onClick={onCancel} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
@@ -89,5 +100,6 @@ export default function ConfirmDialog({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,23 @@ function ConfirmDiffModal({ show, diff, onConfirm, onClose, loading = false }) {
|
|||||||
|
|
||||||
if (!show) return null;
|
if (!show) return null;
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||||
>
|
>
|
||||||
<div className="modal-dialog modal-sm modal-dialog-centered" role="document">
|
<div className="modal-dialog modal-sm modal-dialog-centered" role="document">
|
||||||
@@ -42,7 +53,7 @@ function ConfirmDiffModal({ show, diff, onConfirm, onClose, loading = false }) {
|
|||||||
>
|
>
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h5 className="modal-title">Подтвердить сохранение</h5>
|
<h5 className="modal-title">Подтвердить сохранение</h5>
|
||||||
<button type="button" className="btn-close" onClick={onClose} />
|
<button type="button" className="btn-close" onClick={onClose} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
@@ -98,6 +109,7 @@ function ConfirmDiffModal({ show, diff, onConfirm, onClose, loading = false }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,23 @@ function ConfirmModal({
|
|||||||
onConfirm?.();
|
onConfirm?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||||
>
|
>
|
||||||
<div className="modal-dialog modal-sm modal-dialog-centered" role="document">
|
<div className="modal-dialog modal-sm modal-dialog-centered" role="document">
|
||||||
@@ -54,7 +65,7 @@ function ConfirmModal({
|
|||||||
>
|
>
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h5 className="modal-title">{title}</h5>
|
<h5 className="modal-title">{title}</h5>
|
||||||
<button type="button" className="btn-close" onClick={onClose} />
|
<button type="button" className="btn-close" onClick={onClose} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
@@ -92,6 +103,7 @@ function ConfirmModal({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,23 @@ function FormModal({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -52,7 +63,7 @@ function FormModal({
|
|||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<h5 className="modal-title">{title}</h5>
|
<h5 className="modal-title">{title}</h5>
|
||||||
<button type="button" className="btn-close" onClick={onClose} />
|
<button type="button" className="btn-close" onClick={onClose} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
@@ -85,6 +96,7 @@ function FormModal({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,13 +55,23 @@ export default function HistoryModal({ resource, show, onClose, onRolledBack })
|
|||||||
refetch().catch(() => notify.error('Не удалось загрузить историю версий'));
|
refetch().catch(() => notify.error('Не удалось загрузить историю версий'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||||
>
|
>
|
||||||
<div className="modal-dialog modal-lg modal-dialog-centered" role="document">
|
<div className="modal-dialog modal-lg modal-dialog-centered" role="document">
|
||||||
@@ -90,7 +100,7 @@ export default function HistoryModal({ resource, show, onClose, onRolledBack })
|
|||||||
<IconHistory className="me-2" size={24} />
|
<IconHistory className="me-2" size={24} />
|
||||||
История версий
|
История версий
|
||||||
</h5>
|
</h5>
|
||||||
<button type="button" className="btn-close" onClick={onClose} />
|
<button type="button" className="btn-close" onClick={onClose} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
|
|||||||
@@ -86,12 +86,23 @@ function ImportModal({
|
|||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||||
>
|
>
|
||||||
<div className="modal-dialog modal-lg modal-dialog-centered" role="document">
|
<div className="modal-dialog modal-lg modal-dialog-centered" role="document">
|
||||||
@@ -101,7 +112,7 @@ function ImportModal({
|
|||||||
<IconUpload className="me-2" size={24} />
|
<IconUpload className="me-2" size={24} />
|
||||||
{title}
|
{title}
|
||||||
</h5>
|
</h5>
|
||||||
<button type="button" className="btn-close" onClick={onClose} />
|
<button type="button" className="btn-close" onClick={onClose} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
|
|||||||
@@ -50,12 +50,23 @@ function Modal({
|
|||||||
|
|
||||||
if (!show) return null;
|
if (!show) return null;
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (backdrop && e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className={`modal show d-block ${className}`}
|
className={`modal show d-block ${className}`}
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -107,6 +118,7 @@ function Modal({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,12 +103,23 @@ export default function SettingsModal({ open, onClose }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||||
>
|
>
|
||||||
<div className="modal-dialog modal-dialog-centered" role="document">
|
<div className="modal-dialog modal-dialog-centered" role="document">
|
||||||
@@ -118,7 +129,7 @@ export default function SettingsModal({ open, onClose }) {
|
|||||||
<IconSettings className="me-2" size={24} />
|
<IconSettings className="me-2" size={24} />
|
||||||
Настройки интерфейса
|
Настройки интерфейса
|
||||||
</h5>
|
</h5>
|
||||||
<button type="button" className="btn-close" onClick={onClose} />
|
<button type="button" className="btn-close" onClick={onClose} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
|
|||||||
@@ -117,12 +117,23 @@ function WsUpdateModal({ show, url, onClose }) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleBackdropClick = (e) => {
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
onClose?.();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{/* Modal Backdrop */}
|
||||||
|
<div className="modal-backdrop show" onClick={handleBackdropClick} />
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
<div
|
<div
|
||||||
className="modal show d-block"
|
className="modal show d-block"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}
|
tabIndex={-1}
|
||||||
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
onKeyDown={(e) => { if (e.key === 'Escape') onClose?.(); }}
|
||||||
>
|
>
|
||||||
<div className="modal-dialog modal-lg modal-dialog-centered" role="document">
|
<div className="modal-dialog modal-lg modal-dialog-centered" role="document">
|
||||||
@@ -133,7 +144,7 @@ function WsUpdateModal({ show, url, onClose }) {
|
|||||||
Логи запуска
|
Логи запуска
|
||||||
{getStatusBadge()}
|
{getStatusBadge()}
|
||||||
</h5>
|
</h5>
|
||||||
<button type="button" className="btn-close" onClick={onClose} />
|
<button type="button" className="btn-close" onClick={onClose} aria-label="Закрыть" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="modal-body">
|
<div className="modal-body">
|
||||||
|
|||||||
Reference in New Issue
Block a user