Reaply: #3777: fix/machine-detail-view
This commit is contained in:
committed by
Johannes Kirschbauer
parent
b9c7c530f7
commit
f57a9b5ea9
@@ -2,6 +2,7 @@ import type { Preview } from "@kachurun/storybook-solid";
|
|||||||
|
|
||||||
import "@/src/components/v2/index.css";
|
import "@/src/components/v2/index.css";
|
||||||
import "./preview.css";
|
import "./preview.css";
|
||||||
|
import "../src/index.css";
|
||||||
|
|
||||||
export const preview: Preview = {
|
export const preview: Preview = {
|
||||||
tags: ["autodocs"],
|
tags: ["autodocs"],
|
||||||
|
|||||||
7
pkgs/clan-app/ui/src/components/TagList/TagList.css
Normal file
7
pkgs/clan-app/ui/src/components/TagList/TagList.css
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
div.tag-list {
|
||||||
|
@apply flex flex-wrap gap-2;
|
||||||
|
|
||||||
|
span.tag {
|
||||||
|
@apply w-fit rounded-full px-3 py-2 bg-inv-4 fg-inv-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
pkgs/clan-app/ui/src/components/TagList/TagList.stories.tsx
Normal file
36
pkgs/clan-app/ui/src/components/TagList/TagList.stories.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import type { Meta, StoryObj } from "@kachurun/storybook-solid";
|
||||||
|
import { TagList, TagListProps } from "./TagList";
|
||||||
|
|
||||||
|
const meta: Meta<TagListProps> = {
|
||||||
|
title: "Components/TagList",
|
||||||
|
component: TagList,
|
||||||
|
decorators: [
|
||||||
|
// wrap in a fixed width div so we can check that it wraps
|
||||||
|
(Story) => {
|
||||||
|
return (
|
||||||
|
<div style={{ width: "20em" }}>
|
||||||
|
<Story />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
type Story = StoryObj<TagListProps>;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
args: {
|
||||||
|
values: [
|
||||||
|
"Titan",
|
||||||
|
"Enceladus",
|
||||||
|
"Mimas",
|
||||||
|
"Dione",
|
||||||
|
"Iapetus",
|
||||||
|
"Tethys",
|
||||||
|
"Hyperion",
|
||||||
|
"Epimetheus",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
21
pkgs/clan-app/ui/src/components/TagList/TagList.tsx
Normal file
21
pkgs/clan-app/ui/src/components/TagList/TagList.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { Component, For } from "solid-js";
|
||||||
|
import { Typography } from "@/src/components/Typography";
|
||||||
|
import "./TagList.css";
|
||||||
|
|
||||||
|
export interface TagListProps {
|
||||||
|
values: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TagList: Component<TagListProps> = (props) => {
|
||||||
|
return (
|
||||||
|
<div class="tag-list">
|
||||||
|
<For each={props.values}>
|
||||||
|
{(tag) => (
|
||||||
|
<Typography hierarchy="label" size="s" inverted={true} class="tag">
|
||||||
|
{tag}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -137,7 +137,7 @@ export const InputLabel = (props: InputLabelProps) => {
|
|||||||
weight="bold"
|
weight="bold"
|
||||||
size="xs"
|
size="xs"
|
||||||
>
|
>
|
||||||
{"∗"}
|
<>*</>
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
{props.help && (
|
{props.help && (
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
FileSelectorField,
|
FileSelectorField,
|
||||||
} from "@/src/components/fileSelect";
|
} from "@/src/components/fileSelect";
|
||||||
import { useClanContext } from "@/src/contexts/clan";
|
import { useClanContext } from "@/src/contexts/clan";
|
||||||
|
import { TagList } from "@/src/components/TagList/TagList";
|
||||||
|
|
||||||
type MachineFormInterface = MachineData & {
|
type MachineFormInterface = MachineData & {
|
||||||
sshKey?: File;
|
sshKey?: File;
|
||||||
@@ -77,10 +78,12 @@ const LoadingBar = () => (
|
|||||||
function sleep(ms: number) {
|
function sleep(ms: number) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InstallMachineProps {
|
interface InstallMachineProps {
|
||||||
name?: string;
|
name?: string;
|
||||||
machine: MachineData;
|
machine: MachineData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const InstallMachine = (props: InstallMachineProps) => {
|
const InstallMachine = (props: InstallMachineProps) => {
|
||||||
const { activeClanURI } = useClanContext();
|
const { activeClanURI } = useClanContext();
|
||||||
|
|
||||||
@@ -381,6 +384,7 @@ const InstallMachine = (props: InstallMachineProps) => {
|
|||||||
interface MachineDetailsProps {
|
interface MachineDetailsProps {
|
||||||
initialData: MachineData;
|
initialData: MachineData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MachineForm = (props: MachineDetailsProps) => {
|
const MachineForm = (props: MachineDetailsProps) => {
|
||||||
const [formStore, { Form, Field }] =
|
const [formStore, { Form, Field }] =
|
||||||
// TODO: retrieve the correct initial values from API
|
// TODO: retrieve the correct initial values from API
|
||||||
@@ -595,49 +599,47 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
</Field>
|
</Field>
|
||||||
<Field name="machine.tags" type="string[]">
|
<Field name="machine.tags" type="string[]">
|
||||||
{(field, props) => (
|
{(field, props) => (
|
||||||
<div class="flex items-center gap-4">
|
<div class="grid grid-cols-10 items-center">
|
||||||
<Typography hierarchy="label" size="default" weight="bold">
|
<Typography
|
||||||
|
hierarchy="label"
|
||||||
|
size="default"
|
||||||
|
weight="bold"
|
||||||
|
class="col-span-5"
|
||||||
|
>
|
||||||
Tags{" "}
|
Tags{" "}
|
||||||
</Typography>
|
</Typography>
|
||||||
<For each={field.value}>
|
<div class="col-span-5 justify-self-end">
|
||||||
{(tag) => (
|
{/* alphabetically sort the tags */}
|
||||||
<span class="mx-2 w-fit rounded-full px-3 py-0.5 bg-inv-4 fg-inv-1">
|
<TagList values={[...(field.value || [])].sort()} />
|
||||||
<Typography
|
</div>
|
||||||
hierarchy="label"
|
|
||||||
size="s"
|
|
||||||
inverted={true}
|
|
||||||
>
|
|
||||||
{tag}
|
|
||||||
</Typography>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
</Fieldset>
|
</Fieldset>
|
||||||
|
|
||||||
<Fieldset legend="Hardware">
|
<Typography hierarchy={"body"} size={"s"}>
|
||||||
<Field name="hw_config">
|
<Fieldset legend="Hardware">
|
||||||
{(field, props) => (
|
<Field name="hw_config">
|
||||||
<FieldLayout
|
{(field, props) => (
|
||||||
label={<InputLabel>Hardware Configuration</InputLabel>}
|
|
||||||
field={<span>{field.value || "None"}</span>}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Field>
|
|
||||||
<hr />
|
|
||||||
<Field name="disk_schema.schema_name">
|
|
||||||
{(field, props) => (
|
|
||||||
<>
|
|
||||||
<FieldLayout
|
<FieldLayout
|
||||||
label={<InputLabel>Disk schema</InputLabel>}
|
label={<InputLabel>Hardware Configuration</InputLabel>}
|
||||||
field={<span>{field.value || "None"}</span>}
|
field={<span>{field.value || "None"}</span>}
|
||||||
/>
|
/>
|
||||||
</>
|
)}
|
||||||
)}
|
</Field>
|
||||||
</Field>
|
<hr />
|
||||||
</Fieldset>
|
<Field name="disk_schema.schema_name">
|
||||||
|
{(field, props) => (
|
||||||
|
<>
|
||||||
|
<FieldLayout
|
||||||
|
label={<InputLabel>Disk schema</InputLabel>}
|
||||||
|
field={<span>{field.value || "None"}</span>}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</Fieldset>
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Accordion title="Connection Settings">
|
<Accordion title="Connection Settings">
|
||||||
<Fieldset>
|
<Fieldset>
|
||||||
|
|||||||
Reference in New Issue
Block a user