UI/install: bootstrap steps for {DiskSchema, Vars, Summary}
This commit is contained in:
@@ -66,3 +66,38 @@ export const InstallCheckHardware: Story = {
|
||||
initialStep: "install:check-hardware",
|
||||
},
|
||||
};
|
||||
export const InstallSelectDisk: Story = {
|
||||
description: "Select disk to install the system on",
|
||||
args: {
|
||||
machineName: "Test Machine",
|
||||
initialStep: "install:disk",
|
||||
},
|
||||
};
|
||||
export const InstallVars: Story = {
|
||||
description: "Fill required credentials and data for the installation",
|
||||
args: {
|
||||
machineName: "Test Machine",
|
||||
initialStep: "install:data",
|
||||
},
|
||||
};
|
||||
export const InstallSummary: Story = {
|
||||
description: "Summary of the installation steps",
|
||||
args: {
|
||||
machineName: "Test Machine",
|
||||
initialStep: "install:summary",
|
||||
},
|
||||
};
|
||||
export const InstallProgress: Story = {
|
||||
description: "Shown while the installation is in progress",
|
||||
args: {
|
||||
machineName: "Test Machine",
|
||||
initialStep: "install:progress",
|
||||
},
|
||||
};
|
||||
export const InstallDone: Story = {
|
||||
description: "Shown after the installation is done",
|
||||
args: {
|
||||
machineName: "Test Machine",
|
||||
initialStep: "install:done",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -16,10 +16,11 @@ import { createSignal, Show } from "solid-js";
|
||||
import { Divider } from "@/src/components/Divider/Divider";
|
||||
import { Orienter } from "@/src/components/Form/Orienter";
|
||||
import { Button } from "@/src/components/Button/Button";
|
||||
import { Select } from "@/src/components/Select/Select";
|
||||
|
||||
export const InstallHeader = (props: { machineName: string }) => {
|
||||
return (
|
||||
<Typography hierarchy="label" size="default" class="px-6">
|
||||
<Typography hierarchy="label" size="default">
|
||||
Installing: {props.machineName}
|
||||
</Typography>
|
||||
);
|
||||
@@ -129,6 +130,216 @@ const CheckHardware = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const DiskSchema = v.object({
|
||||
mainDisk: v.pipe(
|
||||
v.string("Please select a disk"),
|
||||
v.nonEmpty("Please select a disk"),
|
||||
),
|
||||
});
|
||||
|
||||
type DiskForm = v.InferInput<typeof DiskSchema>;
|
||||
|
||||
const ConfigureDisk = () => {
|
||||
const [formStore, { Form, Field }] = createForm<DiskForm>({
|
||||
validate: valiForm(DiskSchema),
|
||||
});
|
||||
const stepSignal = useStepper<InstallSteps>();
|
||||
|
||||
const handleSubmit: SubmitHandler<DiskForm> = (values, event) => {
|
||||
console.log("submitted", values);
|
||||
// Here you would typically trigger the ISO creation process
|
||||
stepSignal.next();
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<StepLayout
|
||||
body={
|
||||
<div class="flex flex-col gap-2">
|
||||
<Fieldset>
|
||||
<Field name="mainDisk">
|
||||
{(field, props) => (
|
||||
<Select
|
||||
{...props}
|
||||
value={field.value}
|
||||
error={field.error}
|
||||
required
|
||||
label={{
|
||||
label: "Main disk",
|
||||
description: "Select the disk to install the system on",
|
||||
}}
|
||||
// TODO: Get from api
|
||||
options={[{ value: "disk", label: "Disk0" }]}
|
||||
placeholder="Select a disk"
|
||||
name={field.name}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</Fieldset>
|
||||
</div>
|
||||
}
|
||||
footer={
|
||||
<div class="flex justify-between">
|
||||
<BackButton />
|
||||
<NextButton type="submit">Next</NextButton>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
type DynamicForm = Record<string, string>;
|
||||
|
||||
const ConfigureData = () => {
|
||||
const [formStore, { Form, Field }] = createForm<DynamicForm>({
|
||||
// TODO: Dynamically validate fields
|
||||
});
|
||||
const stepSignal = useStepper<InstallSteps>();
|
||||
|
||||
const handleSubmit: SubmitHandler<DynamicForm> = (values, event) => {
|
||||
console.log("vars submitted", values);
|
||||
// Here you would typically trigger the ISO creation process
|
||||
stepSignal.next();
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<StepLayout
|
||||
body={
|
||||
<div class="flex flex-col gap-2">
|
||||
<Fieldset legend="Root password">
|
||||
<Field name="root-password">
|
||||
{(field, props) => (
|
||||
<TextInput
|
||||
{...field}
|
||||
label="Root password"
|
||||
description="Set the root password for the machine"
|
||||
value={field.value}
|
||||
required
|
||||
orientation="horizontal"
|
||||
validationState={
|
||||
getError(formStore, "root-password") ? "invalid" : "valid"
|
||||
}
|
||||
icon="EyeClose"
|
||||
input={{
|
||||
...props,
|
||||
type: "password",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</Fieldset>
|
||||
<Fieldset legend="WIFI TU-YAN">
|
||||
<Field name="networkSSID">
|
||||
{(field, props) => (
|
||||
<TextInput
|
||||
{...field}
|
||||
label="ssid"
|
||||
description="Name of the wifi network"
|
||||
value={field.value}
|
||||
required
|
||||
orientation="horizontal"
|
||||
validationState={
|
||||
getError(formStore, "wifi/password") ? "invalid" : "valid"
|
||||
}
|
||||
input={{
|
||||
...props,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
<Field name="password">
|
||||
{(field, props) => (
|
||||
<TextInput
|
||||
{...field}
|
||||
label="password"
|
||||
description="Password for the wifi network"
|
||||
value={field.value}
|
||||
required
|
||||
orientation="horizontal"
|
||||
validationState={
|
||||
getError(formStore, "wifi/password") ? "invalid" : "valid"
|
||||
}
|
||||
icon="EyeClose"
|
||||
input={{
|
||||
...props,
|
||||
type: "password",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</Fieldset>
|
||||
</div>
|
||||
}
|
||||
footer={
|
||||
<div class="flex justify-between">
|
||||
<BackButton />
|
||||
<NextButton type="submit">Next</NextButton>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
const Display = (props: { value: string; label: string }) => {
|
||||
return (
|
||||
<>
|
||||
<Typography hierarchy="label" size="xs" color="primary" weight="bold">
|
||||
{props.label}
|
||||
</Typography>
|
||||
<Typography hierarchy="body" size="s" weight="medium">
|
||||
{props.value}
|
||||
</Typography>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const InstallSummary = () => {
|
||||
const stepSignal = useStepper<InstallSteps>();
|
||||
|
||||
const handleInstall = () => {
|
||||
// Here you would typically trigger the installation process
|
||||
console.log("Installation started");
|
||||
stepSignal.setActiveStep("install:progress");
|
||||
};
|
||||
return (
|
||||
<StepLayout
|
||||
body={
|
||||
<div class="flex flex-col gap-4">
|
||||
<Fieldset legend="Deploy to">
|
||||
<Orienter orientation="horizontal">
|
||||
{/* TOOD: Display the values emited from previous steps */}
|
||||
<Display label="Target" value="flash-installer.local" />
|
||||
</Orienter>
|
||||
</Fieldset>
|
||||
<Fieldset legend="Disk Configuration">
|
||||
<Orienter orientation="horizontal">
|
||||
<Display label="Disk Schema" value="Single" />
|
||||
</Orienter>
|
||||
<Divider orientation="horizontal" />
|
||||
<Orienter orientation="horizontal">
|
||||
<Display
|
||||
label="Main Disk"
|
||||
value="nvme-WD_PC_SN740_SDDQNQD-512G"
|
||||
/>
|
||||
</Orienter>
|
||||
</Fieldset>
|
||||
</div>
|
||||
}
|
||||
footer={
|
||||
<div class="flex justify-between">
|
||||
<BackButton />
|
||||
<NextButton type="button" onClick={handleInstall} endIcon="Flash">
|
||||
Install
|
||||
</NextButton>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const installSteps = [
|
||||
{
|
||||
id: "install:address",
|
||||
@@ -141,14 +352,28 @@ export const installSteps = [
|
||||
content: CheckHardware,
|
||||
},
|
||||
{
|
||||
id: "install:confirm",
|
||||
id: "install:check-hardware",
|
||||
title: InstallHeader,
|
||||
content: (props: { machineName: string }) => (
|
||||
<div>
|
||||
Confirm the installation of {props.machineName}
|
||||
<NextButton />
|
||||
</div>
|
||||
content: CheckHardware,
|
||||
},
|
||||
{
|
||||
id: "install:disk",
|
||||
title: InstallHeader,
|
||||
content: ConfigureDisk,
|
||||
},
|
||||
{
|
||||
id: "install:data",
|
||||
title: InstallHeader,
|
||||
content: ConfigureData,
|
||||
},
|
||||
{
|
||||
id: "install:summary",
|
||||
title: () => (
|
||||
<Typography hierarchy="label" size="default">
|
||||
Summary
|
||||
</Typography>
|
||||
),
|
||||
content: InstallSummary,
|
||||
},
|
||||
{
|
||||
id: "install:progress",
|
||||
@@ -160,4 +385,9 @@ export const installSteps = [
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: "install:done",
|
||||
title: InstallHeader,
|
||||
content: () => <div>Done</div>,
|
||||
},
|
||||
] as const;
|
||||
|
||||
Reference in New Issue
Block a user