Skip to content

Commit 88d3764

Browse files
committed
[dashboard] improve modal
the modal dialog should - close on ESC - close on click outside modal but not within - handle enter
1 parent a406854 commit 88d3764

File tree

2 files changed

+41
-11
lines changed

2 files changed

+41
-11
lines changed

components/dashboard/src/components/Modal.tsx

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,47 @@
1+
import { Disposable, DisposableCollection } from "@gitpod/gitpod-protocol";
2+
13
export default function Modal(props: {
24
children: React.ReactChild[] | React.ReactChild,
35
visible: boolean,
46
closeable?: boolean,
57
className?: string,
6-
onClose: () => void
8+
onClose: () => void,
9+
onEnter?: () => boolean
710
}) {
11+
const disposable = new DisposableCollection();
12+
const close = () => {
13+
disposable.dispose();
14+
props.onClose();
15+
}
816
if (!props.visible) {
917
return null;
1018
}
11-
setTimeout(() => window.addEventListener('click', props.onClose, { once: true }), 0);
19+
setTimeout(() => {
20+
const keyHandler = (k: globalThis.KeyboardEvent) => {
21+
if (!k.bubbles) {
22+
if (k.key === 'Escape') {
23+
close();
24+
}
25+
if (k.key === 'Enter') {
26+
if (props.onEnter) {
27+
if (props.onEnter() === false) {
28+
return;
29+
}
30+
}
31+
close();
32+
k.stopPropagation();
33+
}
34+
}
35+
}
36+
window.addEventListener('keydown', keyHandler, { capture: true });
37+
disposable.push(Disposable.create(()=> window.removeEventListener('keydown', keyHandler)));
38+
}, 0);
1239
return (
13-
<div className="fixed top-0 left-0 bg-black bg-opacity-70 z-50 w-screen h-screen" >
40+
<div className="fixed top-0 left-0 bg-black bg-opacity-70 z-50 w-screen h-screen" onClick={close}>
1441
<div className="w-screen h-screen align-middle" style={{display: 'table-cell'}}>
15-
<div className={"relative bg-white border rounded-xl p-6 max-w-lg mx-auto text-gray-600" + props.className}>
42+
<div className={"relative bg-white border rounded-xl p-6 max-w-lg mx-auto text-gray-600" + props.className} onClick={e => e.stopPropagation()}>
1643
{props.closeable !== false && (
17-
<div className="absolute right-9 top-8 cursor-pointer" onClick={props.onClose}>
44+
<div className="absolute right-9 top-8 cursor-pointer" onClick={close}>
1845
<svg version="1.1" width="14px" height="14px"
1946
viewBox="0 0 100 100">
2047
<line x1="0" y1="0" x2="100" y2="100" stroke="currentColor" strokeWidth="10px" />

components/dashboard/src/workspaces/WorkspaceEntry.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,17 @@ export function WorkspaceEntry({ desc, model }: { desc: WorkspaceInfo, model: Wo
133133
<Modal visible={isChangesModalVisible} onClose={() => setChangesModalVisible(false)}>
134134
{getChangesPopup(pendingChanges)}
135135
</Modal>
136-
<Modal visible={isModalVisible} onClose={() => setModalVisible(false)}>
136+
<Modal visible={isModalVisible} onClose={() => setModalVisible(false)} onEnter={() => {model.deleteWorkspace(ws.id); return true;}}>
137137
<div>
138-
<h3>Delete {ws.id}</h3>
139-
<div className="py-4">
140-
<p>Do you really want to delete this workspace?</p>
138+
<h3>Delete Workspace</h3>
139+
<div className="border-t border-gray-200 mt-2 -mx-6 px-6 py-2">
140+
<p>Do you really want to delete the following workspace?</p>
141+
<div className="w-full p-3">
142+
<p className="text-base text-gray-800 font-semibold">{ws.id}</p>
143+
<p>{ws.description}</p>
144+
</div>
141145
</div>
142-
<div className="flex">
143-
<div className="flex-1"></div>
146+
<div className="flex justify-end mt-4">
144147
<button className="cursor-pointer px-3 py-2 text-white text-sm rounded-md border-2 border-red-800 bg-red-600 hover:bg-red-800"
145148
onClick={() => model.deleteWorkspace(ws.id)}>
146149
Delete

0 commit comments

Comments
 (0)