feat: add interactive terminal support for containers via WebSocket
All checks were successful
Build and Push Docker Images / docker (push) Successful in 30s
All checks were successful
Build and Push Docker Images / docker (push) Successful in 30s
- Implemented WebSocket endpoint for executing interactive shells in Docker containers. - Added ticket-based authentication for terminal access to enhance security. - Updated frontend to support terminal interactions, including lazy loading of terminal components. - Enhanced backend to manage terminal session tickets and settings for enabling/disabling terminal access. - Updated Nginx configuration to support WebSocket connections for terminal sessions. - Added necessary dependencies for terminal functionality in the frontend. - Improved user interface to include terminal access controls and feedback on terminal status.
This commit is contained in:
@@ -33,15 +33,20 @@ export default function Modal({
|
||||
children,
|
||||
bodyClassName = 'overflow-y-auto p-4',
|
||||
panelClassName = '',
|
||||
// Le terminal a besoin de Tab (complétion) et d'Échap (vim) : il désactive
|
||||
// ces deux raccourcis et se ferme via la croix.
|
||||
trapTab = true,
|
||||
closeOnEscape = true,
|
||||
}) {
|
||||
const panelRef = useRef(null)
|
||||
const onCloseRef = useRef(onClose)
|
||||
const titleId = useId()
|
||||
const panelRef = useRef(null)
|
||||
const titleId = useId()
|
||||
|
||||
// `onClose` est souvent une lambda recréée à chaque rendu du parent : on la
|
||||
// lit via une ref pour que l'effet ne se rejoue pas (sinon le focus sauterait
|
||||
// au premier champ à chaque rafraîchissement automatique).
|
||||
useEffect(() => { onCloseRef.current = onClose })
|
||||
// `onClose` est souvent une lambda recréée à chaque rendu du parent : le
|
||||
// gestionnaire de touches lit ces valeurs via une ref pour que l'effet ne se
|
||||
// rejoue pas (sinon le focus sauterait au premier champ à chaque
|
||||
// rafraîchissement automatique).
|
||||
const handlersRef = useRef({ onClose, trapTab, closeOnEscape })
|
||||
useEffect(() => { handlersRef.current = { onClose, trapTab, closeOnEscape } })
|
||||
|
||||
useEffect(() => {
|
||||
const previouslyFocused = document.activeElement
|
||||
@@ -50,12 +55,12 @@ export default function Modal({
|
||||
;(firstFocusable ?? panel)?.focus({ preventScroll: true })
|
||||
|
||||
const onKeyDown = (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
if (e.key === 'Escape' && handlersRef.current.closeOnEscape) {
|
||||
e.stopPropagation()
|
||||
onCloseRef.current?.()
|
||||
handlersRef.current.onClose?.()
|
||||
return
|
||||
}
|
||||
if (e.key !== 'Tab' || !panel) return
|
||||
if (e.key !== 'Tab' || !handlersRef.current.trapTab || !panel) return
|
||||
|
||||
const items = [...panel.querySelectorAll(FOCUSABLE)].filter(el => el.offsetParent !== null)
|
||||
if (items.length === 0) return
|
||||
|
||||
Reference in New Issue
Block a user