Merge pull request 'fix/machine-detail-view' (#3777) from fix/machine-detail-view into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3777
This commit is contained in:
hsjobeki
2025-06-03 12:10:21 +00:00
7 changed files with 117 additions and 37 deletions

View File

@@ -1,5 +1,7 @@
import type { Preview } from "@kachurun/storybook-solid";
import "../src/index.css";
export const preview: Preview = {
tags: ["autodocs"],
parameters: {

View File

@@ -1,6 +1,6 @@
import type { Meta, StoryObj } from "@kachurun/storybook-solid";
import { Button, ButtonProps } from "./Button";
import FlashIcon from "@/icons/flash.svg";
import Icon from "../icon";
const meta: Meta<ButtonProps> = {
title: "Components/Button",
@@ -12,12 +12,10 @@ export default meta;
type Story = StoryObj<ButtonProps>;
const children = "click me";
const startIcon = <FlashIcon width={16} height={16} viewBox="0 0 48 48" />;
export const Default: Story = {
args: {
children,
startIcon,
},
};
@@ -41,3 +39,17 @@ export const Ghost: Story = {
variant: "ghost",
},
};
export const StartIcon: Story = {
args: {
...Default.args,
startIcon: <Icon size={12} icon="Flash" />,
},
};
export const EndIcon: Story = {
args: {
...Default.args,
endIcon: <Icon size={12} icon="Flash" />,
},
};

View 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;
}
}

View 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",
],
},
};

View 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>
);
};

View File

@@ -137,7 +137,7 @@ export const InputLabel = (props: InputLabelProps) => {
weight="bold"
size="xs"
>
{""}
<>&#42;</>
</Typography>
)}
{props.help && (

View File

@@ -32,6 +32,7 @@ import {
FileSelectorField,
} from "@/src/components/fileSelect";
import { useClanContext } from "@/src/contexts/clan";
import { TagList } from "@/src/components/TagList/TagList";
type MachineFormInterface = MachineData & {
sshKey?: File;
@@ -77,10 +78,12 @@ const LoadingBar = () => (
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
interface InstallMachineProps {
name?: string;
machine: MachineData;
}
const InstallMachine = (props: InstallMachineProps) => {
const { activeClanURI } = useClanContext();
@@ -381,6 +384,7 @@ const InstallMachine = (props: InstallMachineProps) => {
interface MachineDetailsProps {
initialData: MachineData;
}
const MachineForm = (props: MachineDetailsProps) => {
const [formStore, { Form, Field }] =
// TODO: retrieve the correct initial values from API
@@ -595,28 +599,25 @@ const MachineForm = (props: MachineDetailsProps) => {
</Field>
<Field name="machine.tags" type="string[]">
{(field, props) => (
<div class="flex items-center gap-4">
<Typography hierarchy="label" size="default" weight="bold">
Tags{" "}
</Typography>
<For each={field.value}>
{(tag) => (
<span class="mx-2 w-fit rounded-full px-3 py-0.5 bg-inv-4 fg-inv-1">
<div class="grid grid-cols-10 items-center">
<Typography
hierarchy="label"
size="s"
inverted={true}
size="default"
weight="bold"
class="col-span-5"
>
{tag}
Tags{" "}
</Typography>
</span>
)}
</For>
<div class="col-span-5 justify-self-end">
{/* alphabetically sort the tags */}
<TagList values={[...(field.value || [])].sort()} />
</div>
</div>
)}
</Field>
</Fieldset>
<Typography hierarchy={"body"} size={"s"}>
<Fieldset legend="Hardware">
<Field name="hw_config">
{(field, props) => (
@@ -638,6 +639,7 @@ const MachineForm = (props: MachineDetailsProps) => {
)}
</Field>
</Fieldset>
</Typography>
<Accordion title="Connection Settings">
<Fieldset>