Merge pull request 'UI: init draggable dialog' (#2660) from hsjobeki/clan-core:hsjobeki-main into main

This commit is contained in:
clan-bot
2024-12-29 11:30:51 +00:00
8 changed files with 492 additions and 50 deletions

View File

@@ -105,7 +105,7 @@ def dataclass_to_dict(obj: Any, *, use_alias: bool = True) -> Any:
and getattr(obj, field.name) is not None # type: ignore
}
if isinstance(obj, list | tuple | set):
return sorted([_to_dict(item) for item in obj])
return [_to_dict(item) for item in obj]
if isinstance(obj, dict):
return {sanitize_string(k): _to_dict(v) for k, v in obj.items()}
if isinstance(obj, Path):

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor"><path fill-rule="evenodd" d="M25.6 4h-4.1v8.2h4.1zm-8.2 12.3h12.3v4.1h4.1v8.2h-4.1v8.2H17.4v-8.2h-4.1v-8.2h4.1zm0 24.6h12.3V45H17.4zm28.7-18.45v4.1h-8.2v-4.1zm-36.9 4.1v-4.1H1v4.1zM33.8 12.2h4.1v4.1h-4.1zm4.1 0H42V8.1h-4.1zm-28.7 0h4.1v4.1H9.2zm0 0V8.1H5.1v4.1z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 373 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="currentColor"><path fill-rule="evenodd" d="M42 6H5v37h37zm-20.555 8.222h4.111v12.334h-4.111zm0 16.445h4.111v4.11h-4.111z" clip-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 218 B

View File

@@ -16,6 +16,7 @@
"@tanstack/eslint-plugin-query": "^5.51.12",
"@tanstack/solid-query": "^5.51.2",
"@types/json-schema": "^7.0.15",
"corvu": "^0.7.1",
"material-icons": "^1.13.12",
"nanoid": "^5.0.7",
"solid-js": "^1.8.11",
@@ -406,6 +407,165 @@
"node": ">=6.9.0"
}
},
"node_modules/@corvu/accordion": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@corvu/accordion/-/accordion-0.2.3.tgz",
"integrity": "sha512-M+qDysE1bKXeCmVsaHVs4FbrIWzQfffOrQ2H2yYYuGQfZINi5783rBcLTn7eNhUknOfdwVcjs2rnODeIomVC3A==",
"license": "MIT",
"dependencies": {
"@corvu/disclosure": "~0.2.0",
"@corvu/utils": "~0.4.0",
"solid-list": "~0.3.0"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/dialog": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@corvu/dialog/-/dialog-0.2.3.tgz",
"integrity": "sha512-1p1lG2Pdu7CtDYw0FP+gdU0Db4zsB2ljOP7UxszZIQpvVvnrAYhNPfu/8IpscB38c0hZCodEnv5hR0NaEEA/Ag==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.0",
"solid-dismissible": "~0.1.0",
"solid-focus-trap": "~0.1.7",
"solid-presence": "~0.1.8",
"solid-prevent-scroll": "~0.1.9"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/disclosure": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@corvu/disclosure/-/disclosure-0.2.0.tgz",
"integrity": "sha512-+SkGXXcah8CiXQeM1qrYgikEEX6CFGZ8AOAEDHHkxFkQHC8ll0wAdGAkqT11quPvE9O6/f1ulfWNWdrX4Lqmnw==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.3.0",
"solid-presence": "~0.1.6"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/disclosure/node_modules/@corvu/utils": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@corvu/utils/-/utils-0.3.2.tgz",
"integrity": "sha512-ZWlyWEE8qV9+CB9OAyo2bTrZGXQN9ZeM+JfYv89zoR+lRACKTDuoOZEdiyL8Uc7U5dUSH1uTqKhTTnaHWb+wZA==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.7"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/drawer": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@corvu/drawer/-/drawer-0.2.2.tgz",
"integrity": "sha512-gj0dGnAc5fxoOe1E55uo8LPrHFxR+MaStn3UB8I1ZbtlJeeLDTK40uCc/Ee9xVxYpYNpUDX6ICGr3i23bsZyOA==",
"license": "MIT",
"dependencies": {
"@corvu/dialog": "~0.2.1",
"@corvu/utils": "~0.3.2",
"@solid-primitives/memo": "^1.3.8",
"solid-transition-size": "~0.1.4"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/drawer/node_modules/@corvu/utils": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@corvu/utils/-/utils-0.3.2.tgz",
"integrity": "sha512-ZWlyWEE8qV9+CB9OAyo2bTrZGXQN9ZeM+JfYv89zoR+lRACKTDuoOZEdiyL8Uc7U5dUSH1uTqKhTTnaHWb+wZA==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.7"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/otp-field": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@corvu/otp-field/-/otp-field-0.1.4.tgz",
"integrity": "sha512-3eG7OoUt6CfVqGujIYfqImdrhGR/s4DpKr5ZQT10zzw3nawIlcwVpqoHTam0v4cgv+NXXvl6I8DoA3J+WgW2YA==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.2"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/popover": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@corvu/popover/-/popover-0.2.0.tgz",
"integrity": "sha512-zynRWyRV7mk2uX7t/COQL4OEa6H6FBgOxxlXLQJ1BV8hTiBJwmfAN/yB/9jy+zlp0G9vp64E8VdsNn6gxUEUEQ==",
"license": "MIT",
"dependencies": {
"@corvu/dialog": "~0.2.0",
"@corvu/utils": "~0.3.0",
"@floating-ui/dom": "^1.6.5"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/popover/node_modules/@corvu/utils": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@corvu/utils/-/utils-0.3.2.tgz",
"integrity": "sha512-ZWlyWEE8qV9+CB9OAyo2bTrZGXQN9ZeM+JfYv89zoR+lRACKTDuoOZEdiyL8Uc7U5dUSH1uTqKhTTnaHWb+wZA==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.7"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/resizable": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@corvu/resizable/-/resizable-0.2.3.tgz",
"integrity": "sha512-UwpObxqKlx1mc3G496Daz9NjK25Gx1V5fB8zIGazbq5tJs7aU8RjPW4png5OoNpMyxV7GQWjQtVc59zaAEVAJg==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.0"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/tooltip": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@corvu/tooltip/-/tooltip-0.2.1.tgz",
"integrity": "sha512-y2CQ2/6DH/gJJZPo1fV3O7l4Jfgu5ZW58bpqPmKS+l8Pa6gIKV6zkrMoyBg8Hsn6z9RmdZFqkGFs/9C5fvwKpg==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.0",
"@floating-ui/dom": "^1.6.8",
"solid-dismissible": "~0.1.0",
"solid-presence": "~0.1.8"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@corvu/utils": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@corvu/utils/-/utils-0.4.2.tgz",
"integrity": "sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.11"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
@@ -847,18 +1007,20 @@
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz",
"integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==",
"version": "1.6.12",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.5"
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz",
"integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ=="
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
"license": "MIT"
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.14",
@@ -1379,6 +1541,19 @@
"solid-js": "^1.6.12"
}
},
"node_modules/@solid-primitives/memo": {
"version": "1.3.10",
"resolved": "https://registry.npmjs.org/@solid-primitives/memo/-/memo-1.3.10.tgz",
"integrity": "sha512-S4cNjjKINVC4KiY3ovP1oagbTVQI77VvSRMNsInFIi7T4hM/N5InJk5k+W0zD4lt+SUYrWF04BMbZyMy17vfUw==",
"license": "MIT",
"dependencies": {
"@solid-primitives/scheduled": "^1.4.4",
"@solid-primitives/utils": "^6.2.3"
},
"peerDependencies": {
"solid-js": "^1.6.12"
}
},
"node_modules/@solid-primitives/platform": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@solid-primitives/platform/-/platform-0.1.2.tgz",
@@ -1440,10 +1615,10 @@
}
},
"node_modules/@solid-primitives/scheduled": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/@solid-primitives/scheduled/-/scheduled-1.4.3.tgz",
"integrity": "sha512-HfWN5w7b7FEc6VPLBKnnE302h90jsLMuR28Fcf7neRGGf8jBj6wm6/UFQ00VlKexHFMR6KQ2u4VBh5a1ZcqM8g==",
"dev": true,
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/@solid-primitives/scheduled/-/scheduled-1.4.4.tgz",
"integrity": "sha512-BTGdFP7t+s7RSak+s1u0eTix4lHP23MrbGkgQTFlt1E+4fmnD/bEx3ZfNW7Grylz3GXgKyXrgDKA7jQ/wuWKgA==",
"license": "MIT",
"peerDependencies": {
"solid-js": "^1.6.12"
}
@@ -2614,6 +2789,25 @@
"optional": true,
"peer": true
},
"node_modules/corvu": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/corvu/-/corvu-0.7.1.tgz",
"integrity": "sha512-MmiSyTM75+Co6KtvkocZ+qy2HJrDwkjJPL0zt06klvkHkKkGZBKYhmzzpEeni/7b7woR6/3XSDGsn3ljGP/O4w==",
"license": "MIT",
"dependencies": {
"@corvu/accordion": "~0.2.0",
"@corvu/dialog": "~0.2.0",
"@corvu/disclosure": "~0.2.0",
"@corvu/drawer": "~0.2.1",
"@corvu/otp-field": "~0.1.0",
"@corvu/popover": "~0.2.0",
"@corvu/resizable": "~0.2.1",
"@corvu/tooltip": "~0.2.0"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -6312,6 +6506,42 @@
}
}
},
"node_modules/solid-dismissible": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/solid-dismissible/-/solid-dismissible-0.1.1.tgz",
"integrity": "sha512-9kcKBJIMdS+586cA1g63HYWxKh3h89leeNHbPZ1csYjuni+NvPBtNr11l0iEX2AKKEt6FHk6qNhc/gjoYAW1pA==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.1"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/solid-focus-trap": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/solid-focus-trap/-/solid-focus-trap-0.1.7.tgz",
"integrity": "sha512-NSJiIkL+WTWGgca+OKQA9rV3bD51lT23iLn1Z+Ap1Qk3rJBxQ8SoEAQ0FvXoQThtyXFKAK1ibcVBBMMEcu6YMw==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.3.1"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/solid-focus-trap/node_modules/@corvu/utils": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@corvu/utils/-/utils-0.3.2.tgz",
"integrity": "sha512-ZWlyWEE8qV9+CB9OAyo2bTrZGXQN9ZeM+JfYv89zoR+lRACKTDuoOZEdiyL8Uc7U5dUSH1uTqKhTTnaHWb+wZA==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.7"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/solid-js": {
"version": "1.8.17",
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.17.tgz",
@@ -6322,6 +6552,18 @@
"seroval-plugins": "^1.0.3"
}
},
"node_modules/solid-list": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/solid-list/-/solid-list-0.3.0.tgz",
"integrity": "sha512-t4hx/F/l8Vmq+ib9HtZYl7Z9F1eKxq3eKJTXlvcm7P7yI4Z8O7QSOOEVHb/K6DD7M0RxzVRobK/BS5aSfLRwKg==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.0"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/solid-markdown": {
"version": "2.0.13",
"resolved": "https://registry.npmjs.org/solid-markdown/-/solid-markdown-2.0.13.tgz",
@@ -6347,6 +6589,30 @@
"solid-js": "^1.6.0"
}
},
"node_modules/solid-presence": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/solid-presence/-/solid-presence-0.1.8.tgz",
"integrity": "sha512-pWGtXUFWYYUZNbg5YpG5vkQJyOtzn2KXhxYaMx/4I+lylTLYkITOLevaCwMRN+liCVk0pqB6EayLWojNqBFECA==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.0"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/solid-prevent-scroll": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/solid-prevent-scroll/-/solid-prevent-scroll-0.1.10.tgz",
"integrity": "sha512-KplGPX2GHiWJLZ6AXYRql4M127PdYzfwvLJJXMkO+CMb8Np4VxqDAg5S8jLdwlEuBis/ia9DKw2M8dFx5u8Mhw==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.4.1"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/solid-refresh": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/solid-refresh/-/solid-refresh-0.6.3.tgz",
@@ -6369,6 +6635,30 @@
"solid-js": "^1.5.4"
}
},
"node_modules/solid-transition-size": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/solid-transition-size/-/solid-transition-size-0.1.4.tgz",
"integrity": "sha512-ocHVnbfy23CgfaH4cEUR/AFg0Y3CEL8Oh3n9Qv8OHFJgPh+zkmERKZQfi/xH5XvxDCizg8VjPrVUhiHB1Gza8g==",
"license": "MIT",
"dependencies": {
"@corvu/utils": "~0.3.2"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/solid-transition-size/node_modules/@corvu/utils": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@corvu/utils/-/utils-0.3.2.tgz",
"integrity": "sha512-ZWlyWEE8qV9+CB9OAyo2bTrZGXQN9ZeM+JfYv89zoR+lRACKTDuoOZEdiyL8Uc7U5dUSH1uTqKhTTnaHWb+wZA==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.7"
},
"peerDependencies": {
"solid-js": "^1.8"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",

View File

@@ -43,6 +43,7 @@
"@tanstack/eslint-plugin-query": "^5.51.12",
"@tanstack/solid-query": "^5.51.2",
"@types/json-schema": "^7.0.15",
"corvu": "^0.7.1",
"material-icons": "^1.13.12",
"nanoid": "^5.0.7",
"solid-js": "^1.8.11",

View File

@@ -10,6 +10,7 @@ import CaretRight from "@/icons/caret-right.svg";
import Checkmark from "@/icons/checkmark.svg";
import ClanIcon from "@/icons/clan-icon.svg";
import ClanLogo from "@/icons/clan-logo.svg";
import Close from "@/icons/close.svg";
import Download from "@/icons/download.svg";
import Edit from "@/icons/edit.svg";
import Expand from "@/icons/expand.svg";
@@ -44,6 +45,7 @@ const icons = {
Checkmark,
ClanIcon,
ClanLogo,
Close,
Download,
Edit,
Expand,

View File

@@ -0,0 +1,119 @@
import Dialog from "corvu/dialog";
import { createEffect, createSignal, JSX } from "solid-js";
import { Button } from "../button";
import Icon from "../icon";
import cx from "classnames";
interface ModalProps {
open: boolean | undefined;
handleClose: () => void;
title: string;
children: JSX.Element;
}
export const Modal = (props: ModalProps) => {
const [dragging, setDragging] = createSignal(false);
const [startOffset, setStartOffset] = createSignal({ x: 0, y: 0 });
// const [dialogStyle, setDialogStyle] = createSignal({ top: 100, left: 100 });
let dialogRef: HTMLDivElement;
const handleMouseDown = (e: MouseEvent) => {
setDragging(true);
const rect = dialogRef.getBoundingClientRect();
setStartOffset({
x: e.clientX - rect.left,
y: e.clientY - rect.top,
});
};
const handleMouseMove = (e: MouseEvent) => {
if (dragging()) {
const newTop = e.clientY - startOffset().y;
const newLeft = e.clientX - startOffset().x;
dialogRef.style.top = `${newTop}px`;
dialogRef.style.left = `${newLeft}px`;
}
};
const handleMouseUp = () => setDragging(false);
createEffect(() => {
console.log("dialog open", props.open);
});
return (
<Dialog open={props.open} trapFocus={true}>
<Dialog.Portal>
<Dialog.Overlay
class="fixed inset-0 z-50 bg-black/50"
onMouseMove={handleMouseMove}
/>
<Dialog.Content
class="absolute left-1/3 top-1/3 z-50 min-w-[320px] rounded-md border border-def-4 focus-visible:outline-none"
classList={{
"!cursor-grabbing": dragging(),
[cx("scale-105 transition-transform")]: dragging(),
}}
ref={(el) => {
dialogRef = el;
}}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
onMouseDown={(e: MouseEvent) => {
e.stopPropagation(); // Prevent backdrop drag conflict
}}
onClick={(e: MouseEvent) => e.stopPropagation()} // Prevent backdrop click closing
>
<Dialog.Label
as="div"
class="flex w-full justify-center rounded-t-md border-b-2 px-4 py-2 align-middle bg-def-3 border-def-5"
onMouseDown={handleMouseDown}
>
<div
class="flex w-full cursor-move flex-col gap-px py-1 "
classList={{
"!cursor-grabbing": dragging(),
}}
>
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
</div>
<span class="mx-2"> {props.title}</span>
<div
class="flex w-full cursor-move flex-col gap-px py-1 "
classList={{
"!cursor-grabbing": dragging(),
}}
>
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
<hr class="h-px w-full border-none bg-secondary-300" />
</div>
<div class="absolute right-1 top-2 pl-1 bg-def-3">
<Button
onMouseDown={(e) => e.stopPropagation()}
tabIndex={-1}
class="size-4"
variant="ghost"
onClick={() => props.handleClose()}
size="s"
startIcon={<Icon icon={"Close"} />}
/>
</div>
</Dialog.Label>
<Dialog.Description class="flex flex-col bg-def-1" as="div">
{props.children}
</Dialog.Description>
</Dialog.Content>
</Dialog.Portal>
</Dialog>
);
};

View File

@@ -20,6 +20,7 @@ import { createEffect, createSignal, For, Show } from "solid-js";
import toast from "solid-toast";
import { FieldLayout } from "@/src/Form/fields/layout";
import { InputLabel } from "@/src/components/inputBase";
import { Modal } from "@/src/components/modal";
interface Wifi extends FieldValues {
ssid: string;
@@ -144,11 +145,15 @@ export const Flash = () => {
}
return dataTransfer.files;
};
const [confirmOpen, setConfirmOpen] = createSignal(false);
const handleSubmit = async (values: FlashFormValues) => {
const handleConfirm = async (values: FlashFormValues) => {
setConfirmOpen(true);
console.log("Submit:", values);
toast.error("Not fully implemented yet");
// Disabled for now. To prevent accidental flashing of local disks
// User should confirm the disk to flash to
// try {
// await callApi("flash_machine", {
// machine: {
@@ -177,6 +182,30 @@ export const Flash = () => {
return (
<>
<Header title="Flash installer" />
<Modal
open={confirmOpen()}
handleClose={() => setConfirmOpen(false)}
title="Confirm"
>
<div class="flex flex-col gap-4 p-4">
<div class="flex justify-between rounded-sm border p-4 align-middle text-red-900 border-def-2">
<Typography
hierarchy="label"
weight="medium"
size="default"
class="flex-wrap break-words pr-4"
>
Warning: All data on will be lost.
<br />
Selected disk: '{getValue(formStore, "disk")}'
</Typography>
</div>
<div class="flex w-full justify-between">
<Button variant="light">Cancel</Button>
<Button>Confirm</Button>
</div>
</div>
</Modal>
<div class="p-4">
<Typography tag="p" hierarchy="body" size="default" color="primary">
USB Utility image.
@@ -185,7 +214,7 @@ export const Flash = () => {
Will make bootstrapping new machines easier by providing secure remote
connection to any machine when plugged in.
</Typography>
<Form onSubmit={handleSubmit}>
<Form onSubmit={handleConfirm}>
<div class="my-4">
<Field name="sshKeys" type="File[]">
{(field, props) => (
@@ -242,7 +271,7 @@ export const Flash = () => {
value={field.value || ""}
error={field.error}
required
placeholder="Select a thing where the installer will be flashed to"
placeholder="Select a drive where the clan-installer will be flashed to"
options={
deviceQuery.data?.blockdevices.map((d) => ({
value: d.path,
@@ -285,7 +314,7 @@ export const Flash = () => {
label="SSID"
value={field.value ?? ""}
error={field.error}
class="col-span-3"
class="col-span-full "
required
/>
)}
@@ -295,8 +324,8 @@ export const Flash = () => {
validate={[required("Password is required")]}
>
{(field, props) => (
<div class="relative col-span-3 w-full">
<TextInput
class="col-span-full"
inputProps={{
...props,
type: passwordVisibility()[index()]
@@ -328,7 +357,6 @@ export const Flash = () => {
// }}
required
/>
</div>
)}
</Field>
</div>