From 9c7b895d4ce0d771c4fba924f2c83a8182a39dfa Mon Sep 17 00:00:00 2001 From: LynithDev <61880709+LynithDev@users.noreply.github.com> Date: Fri, 19 Jul 2024 22:12:11 +0200 Subject: [PATCH] feat: begin work on Cluster creation modal --- apps/desktop/src/ui/App.tsx | 43 +++++---- .../desktop/src/ui/components/WindowFrame.tsx | 2 +- .../components/overlay/FullscreenOverlay.tsx | 20 ++-- .../src/ui/components/overlay/Modal.tsx | 93 ++++++++++++------- .../overlay/cluster/ClusterCreationModal.tsx | 67 +++++++++++++ .../overlay/cluster/ClusterStepOne.tsx | 23 +++++ apps/desktop/src/ui/pages/Home.tsx | 18 +--- 7 files changed, 189 insertions(+), 77 deletions(-) create mode 100644 apps/desktop/src/ui/components/overlay/cluster/ClusterCreationModal.tsx create mode 100644 apps/desktop/src/ui/components/overlay/cluster/ClusterStepOne.tsx diff --git a/apps/desktop/src/ui/App.tsx b/apps/desktop/src/ui/App.tsx index f5231bb4..fce3a0b0 100644 --- a/apps/desktop/src/ui/App.tsx +++ b/apps/desktop/src/ui/App.tsx @@ -6,6 +6,7 @@ import ErrorBoundary from './components/ErrorBoundary'; import AnimatedRoutes from './components/AnimatedRoutes'; import NotificationOverlay from './components/overlay/notifications/NotificationOverlay'; import { SettingsProvider } from './hooks/useSettings'; +import { ClusterModalController } from './components/overlay/cluster/ClusterCreationModal'; import { AppInfo } from '~utils/program-info'; function App(props: ParentProps) { @@ -15,28 +16,30 @@ function App(props: ParentProps) { }); return ( - -
- -
- -
- -
-
- - - - {props.children} - - - + + +
+ +
+
-
- -
-
+
+
+ + + + {props.children} + + + +
+
+ + + + + ); } diff --git a/apps/desktop/src/ui/components/WindowFrame.tsx b/apps/desktop/src/ui/components/WindowFrame.tsx index f6134813..1d682563 100644 --- a/apps/desktop/src/ui/components/WindowFrame.tsx +++ b/apps/desktop/src/ui/components/WindowFrame.tsx @@ -52,7 +52,7 @@ function WindowFrame() { quit()} danger /> - ; setVisible: Setter; + mount?: Node | undefined; + zIndex?: number; } & ParentProps; function FullscreenOverlay(props: FullscreenOverlayProps) { - function onBackdropClick() { - props.setVisible(false); + function onBackdropClick(this: HTMLDivElement, e: MouseEvent) { + e.preventDefault(); + if (e.target === this) + props.setVisible(false); } return ( - -
-
onBackdropClick()} /> + +
+ {/* New element to prevent from having to call stopPropagation in child elements */} + {/*
onBackdropClick()} /> */} -
+
{props.children}
diff --git a/apps/desktop/src/ui/components/overlay/Modal.tsx b/apps/desktop/src/ui/components/overlay/Modal.tsx index 44c3f485..48af4169 100644 --- a/apps/desktop/src/ui/components/overlay/Modal.tsx +++ b/apps/desktop/src/ui/components/overlay/Modal.tsx @@ -2,14 +2,71 @@ import type { Accessor, JSX, ParentProps, + Ref, Setter, } from 'solid-js'; -import { For, mergeProps } from 'solid-js'; +import { For } from 'solid-js'; +import { mergeRefs } from '@solid-primitives/refs'; import Button from '../base/Button'; import FullscreenOverlay from './FullscreenOverlay'; +export type ModalProps = { + visible: Accessor; + setVisible: Setter; + zIndex?: number | undefined; + mount?: Node | undefined; + ref?: Ref | undefined; +} & ParentProps; + +// TODO: Implement some sort of stacking control? +function Modal(props: ModalProps) { + return ( + +
+
+ {props.children} +
+
+
+ ); +} + type ModalButtonProps = string | JSX.Element; +export type ModalSimpleProps = { + title: string; + buttons?: ModalButtonProps[]; +} & ModalProps; + +Modal.Simple = function (props: ModalSimpleProps) { + return ( + +

{props.title}

+
+ {props.children} +
+
+ + {button => ( + + )} + +
+
+ ); +}; + function ModalButton(button: { props: ModalButtonProps }) { return ( <> @@ -26,38 +83,4 @@ function ModalButton(button: { props: ModalButtonProps }) { ); } -type ModalProps = { - title: string; - visible: Accessor; - setVisible: Setter; - buttons?: ModalButtonProps[]; -} & ParentProps; - -function Modal(props: ModalProps) { - const merged: ModalProps = mergeProps({ buttons: ['Ok'] }, props); - - return ( - -
-
-

{props.title}

-
- {props.children} -
-
- - {button => ( - - )} - -
-
-
-
- ); -} - export default Modal; diff --git a/apps/desktop/src/ui/components/overlay/cluster/ClusterCreationModal.tsx b/apps/desktop/src/ui/components/overlay/cluster/ClusterCreationModal.tsx new file mode 100644 index 00000000..136e86e9 --- /dev/null +++ b/apps/desktop/src/ui/components/overlay/cluster/ClusterCreationModal.tsx @@ -0,0 +1,67 @@ +import { type Accessor, type Context, Match, type ParentProps, type Setter, Show, Switch, createContext, createSignal, useContext } from 'solid-js'; +import { Server01Icon } from '@untitled-theme/icons-solid'; +import Modal, { type ModalProps } from '../Modal'; +import HeaderImage from '../../../../assets/images/header.png'; + +// Why the fuck do I need to use a context for all this??? +// TODO: Rewrite for use with the new Modal stacking system +type ClusterModalContextFunc = [ + step: Accessor, + setStep: Setter, + setVisible: Setter, +]; + +const ClusterModalContext = createContext() as Context; + +export function ClusterModalController(props: ParentProps) { + const [step, setStep] = createSignal(1); + const [visible, setVisible] = createSignal(false); + + const stepper: ClusterModalContextFunc = [ + step, + setStep, + setVisible, + ]; + + return ( + + {props.children} + + + ); +} + +export function useClusterModalController() { + return useContext(ClusterModalContext); +} + +type ClusterCreationModalProps = ModalProps & { + step: number; +}; + +function ClusterCreationModal(props: ClusterCreationModalProps) { + // const StepComponent = () => ( + // + // + // + // + // + // ); + + return ( + +
+
+ Header Image +
+
+ +
+

New Cluster

+ agagwag +
+
+
+
+ ); +} diff --git a/apps/desktop/src/ui/components/overlay/cluster/ClusterStepOne.tsx b/apps/desktop/src/ui/components/overlay/cluster/ClusterStepOne.tsx new file mode 100644 index 00000000..8e16c7fa --- /dev/null +++ b/apps/desktop/src/ui/components/overlay/cluster/ClusterStepOne.tsx @@ -0,0 +1,23 @@ +import type { JSX } from 'solid-js'; + +export default function ClusterStepOne() { + return ( +
+ helo +
+ ); +} + +interface ProviderCardProps { + icon: () => JSX.Element; + name: string; +}; + +function ProviderCard(props: ProviderCardProps) { + return ( +
+ + {props.name} +
+ ); +} diff --git a/apps/desktop/src/ui/pages/Home.tsx b/apps/desktop/src/ui/pages/Home.tsx index f7e47a44..881978c9 100644 --- a/apps/desktop/src/ui/pages/Home.tsx +++ b/apps/desktop/src/ui/pages/Home.tsx @@ -19,6 +19,7 @@ import type { Cluster } from '~bindings'; import useCommand from '~ui/hooks/useCommand'; import { bridge } from '~imports'; import { upperFirst } from '~utils/primitives'; +import { useClusterModalController } from '~ui/components/overlay/cluster/ClusterCreationModal'; // TODO: Replace this into it's own component // possibly with the core ui lirbary with autogenerated and optimized svgs pls @@ -186,23 +187,10 @@ function ClusterGroup(props: ClusterGroupProps) { function HomePage() { const [clusters, { refetch }] = useCommand(bridge.commands.getClusters); + const [step, setStep, setVisible] = useClusterModalController(); async function newInstance() { - // bridge.commands.createCluster({ - - // }); - - // await createCluster({ - // name: '1.0 cluster', - // version: 'a1.0.11', - // client: { - // type: 'Vanilla', - // }, - // cover: null, - // group: null, - // }); - - // await refetch(); + setVisible(true); } return (