Merge pull request 'ui: clean up using knip' (#5633) from hgl-storybook into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5633
This commit is contained in:
3
pkgs/clan-app/ui/.gitignore
vendored
3
pkgs/clan-app/ui/.gitignore
vendored
@@ -2,5 +2,4 @@ app/api
|
||||
app/.fonts
|
||||
|
||||
.vite
|
||||
storybook-static
|
||||
*.css.d.ts
|
||||
*.css.d.ts
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
{
|
||||
"ignore": [
|
||||
"gtk.webview.js",
|
||||
"src/api/clan/client-fetch.ts",
|
||||
"stylelint.config.js",
|
||||
"util.ts",
|
||||
"src/components/v2/**",
|
||||
"api/**",
|
||||
"tailwind/**"
|
||||
],
|
||||
"ignoreDependencies": [
|
||||
"@babel/plugin-syntax-import-attributes",
|
||||
"@storybook/addon-viewport",
|
||||
"@typescript-eslint/parser",
|
||||
"@vitest/coverage-v8",
|
||||
"http-server",
|
||||
"playwright",
|
||||
"wait-on"
|
||||
]
|
||||
}
|
||||
|
||||
1382
pkgs/clan-app/ui/package-lock.json
generated
1382
pkgs/clan-app/ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -20,40 +20,28 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@babel/plugin-syntax-import-attributes": "^7.27.1",
|
||||
"@eslint/js": "^9.3.0",
|
||||
"@kachurun/storybook-solid-vite": "^9.0.11",
|
||||
"@linaria/core": "^6.3.0",
|
||||
"@sinonjs/fake-timers": "^14.0.0",
|
||||
"@storybook/addon-a11y": "^9.0.8",
|
||||
"@storybook/addon-docs": "^9.0.8",
|
||||
"@storybook/addon-links": "^9.0.8",
|
||||
"@storybook/addon-viewport": "^9.0.8",
|
||||
"@storybook/addon-vitest": "^9.0.8",
|
||||
"@types/node": "^22.15.19",
|
||||
"@types/sinonjs__fake-timers": "^8.1.5",
|
||||
"@types/three": "^0.176.0",
|
||||
"@typescript-eslint/parser": "^8.32.1",
|
||||
"@vitest/browser": "^3.2.3",
|
||||
"@vitest/coverage-v8": "^3.2.3",
|
||||
"@wyw-in-js/vite": "^0.7.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"classnames": "^2.5.1",
|
||||
"concurrently": "^9.1.2",
|
||||
"eslint": "^9.27.0",
|
||||
"eslint-plugin-tailwindcss": "^3.17.0",
|
||||
"eslint-plugin-unused-imports": "^4.1.4",
|
||||
"extend": "^3.0.2",
|
||||
"http-server": "^14.1.1",
|
||||
"jsdom": "^26.1.0",
|
||||
"knip": "^5.61.2",
|
||||
"markdown-to-jsx": "^7.7.10",
|
||||
"playwright": "1.54.1",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss-url": "^10.1.3",
|
||||
"prettier": "^3.2.5",
|
||||
"storybook": "^9.0.8",
|
||||
"swagger-ui-dist": "^5.26.2",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^5.4.5",
|
||||
"typescript-eslint": "^8.32.1",
|
||||
@@ -62,11 +50,9 @@
|
||||
"vite-css-modules": "^1.10.0",
|
||||
"vite-plugin-solid": "^2.8.2",
|
||||
"vite-plugin-solid-svg": "^0.8.1",
|
||||
"vitest": "^3.2.3",
|
||||
"wait-on": "^8.0.3"
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.6.8",
|
||||
"@kobalte/core": "^0.13.10",
|
||||
"@kobalte/tailwindcss": "^0.9.0",
|
||||
"@modular-forms/solid": "^0.25.1",
|
||||
@@ -80,7 +66,6 @@
|
||||
"solid-js": "^1.9.7",
|
||||
"solid-toast": "^0.5.0",
|
||||
"three": "^0.176.0",
|
||||
"troika-three-text": "^0.52.4",
|
||||
"valibot": "^1.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
||||
@@ -8,11 +8,11 @@ import Icon, { IconVariant } from "@/src/components/Icon/Icon";
|
||||
import { Loader } from "@/src/components/Loader/Loader";
|
||||
import { getInClasses, joinByDash, keepTruthy } from "@/src/util";
|
||||
|
||||
export type Size = "default" | "s" | "xs";
|
||||
export type Hierarchy = "primary" | "secondary";
|
||||
export type Elasticity = "default" | "fit";
|
||||
type Size = "default" | "s" | "xs";
|
||||
type Hierarchy = "primary" | "secondary";
|
||||
type Elasticity = "default" | "fit";
|
||||
|
||||
export type Action = () => Promise<void>;
|
||||
type Action = () => Promise<void>;
|
||||
|
||||
export interface ButtonProps
|
||||
extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
|
||||
@@ -10,15 +10,15 @@ import styles from "./Label.module.css";
|
||||
import cx from "classnames";
|
||||
import { getInClasses } from "@/src/util";
|
||||
|
||||
export type Size = "default" | "s";
|
||||
type Size = "default" | "s";
|
||||
|
||||
export type LabelComponent =
|
||||
type LabelComponent =
|
||||
| typeof TextField.Label
|
||||
| typeof Checkbox.Label
|
||||
| typeof Combobox.Label
|
||||
| typeof Select.Label;
|
||||
|
||||
export type DescriptionComponent =
|
||||
type DescriptionComponent =
|
||||
| typeof TextField.Description
|
||||
| typeof Checkbox.Description
|
||||
| typeof Combobox.Description
|
||||
|
||||
@@ -19,7 +19,7 @@ import { CollectionNode } from "@kobalte/core";
|
||||
import styles from "./MachineTags.module.css";
|
||||
import { keepTruthy } from "@/src/util";
|
||||
|
||||
export interface MachineTag {
|
||||
interface MachineTag {
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { JSX, mergeProps } from "solid-js";
|
||||
|
||||
import styles from "./Orienter.module.css";
|
||||
|
||||
export interface OrienterProps {
|
||||
interface OrienterProps {
|
||||
orientation?: "vertical" | "horizontal";
|
||||
align?: "center" | "start";
|
||||
children: JSX.Element;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { mergeProps } from "solid-js";
|
||||
import styles from "./Loader.module.css";
|
||||
import cx from "classnames";
|
||||
|
||||
export type Hierarchy = "primary" | "secondary";
|
||||
type Hierarchy = "primary" | "secondary";
|
||||
|
||||
export interface LoaderProps {
|
||||
hierarchy?: Hierarchy;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { JSX } from "solid-js";
|
||||
import styles from "./LoadingBar.module.css";
|
||||
import cx from "classnames";
|
||||
|
||||
export type LoadingBarProps = JSX.HTMLAttributes<HTMLDivElement> & {};
|
||||
type LoadingBarProps = JSX.HTMLAttributes<HTMLDivElement> & {};
|
||||
export const LoadingBar = (props: LoadingBarProps) => (
|
||||
<div {...props} class={cx(styles.loading_bar, props.class)} />
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ import Icon from "../Icon/Icon";
|
||||
import cx from "classnames";
|
||||
import { Dynamic } from "solid-js/web";
|
||||
|
||||
export interface ModalContextType {
|
||||
interface ModalContextType {
|
||||
portalRef: HTMLDivElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { CollectionNode } from "@kobalte/core/*";
|
||||
import cx from "classnames";
|
||||
import { Loader } from "../Loader/Loader";
|
||||
|
||||
export interface Option {
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { CollectionNode } from "@kobalte/core/*";
|
||||
import { Loader } from "../Loader/Loader";
|
||||
import cx from "classnames";
|
||||
|
||||
export interface Option {
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
|
||||
@@ -16,7 +16,7 @@ import cx from "classnames";
|
||||
import { useModalContext } from "../Modal/Modal";
|
||||
import { keepTruthy } from "@/src/util";
|
||||
|
||||
export interface Option {
|
||||
interface Option {
|
||||
value: string;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
|
||||
@@ -4,12 +4,12 @@ import { SidebarBody } from "@/src/components/Sidebar/SidebarBody";
|
||||
import cx from "classnames";
|
||||
import { splitProps } from "solid-js";
|
||||
|
||||
export interface LinkProps {
|
||||
interface LinkProps {
|
||||
path: string;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export interface SectionProps {
|
||||
interface SectionProps {
|
||||
title: string;
|
||||
links: LinkProps[];
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { JSX, Show } from "solid-js";
|
||||
import styles from "./SidebarSection.module.css";
|
||||
import { Typography } from "@/src/components/Typography/Typography";
|
||||
|
||||
export interface SidebarSectionProps {
|
||||
interface SidebarSectionProps {
|
||||
title: string;
|
||||
controls?: JSX.Element;
|
||||
children: JSX.Element;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { Button } from "@/src/components/Button/Button";
|
||||
import { Loader } from "../../components/Loader/Loader";
|
||||
import { SidebarSection } from "./SidebarSection";
|
||||
|
||||
export interface SidebarSectionFormProps<FormValues extends FieldValues> {
|
||||
interface SidebarSectionFormProps<FormValues extends FieldValues> {
|
||||
title: string;
|
||||
schema: GenericSchema<FormValues> | GenericSchemaAsync<FormValues>;
|
||||
initialValues: PartialValues<FormValues>;
|
||||
|
||||
@@ -7,7 +7,7 @@ import styles from "./SidebarSectionInstall.module.css";
|
||||
import { Alert } from "../Alert/Alert";
|
||||
import { useClanContext } from "@/src/routes/Clan/Clan";
|
||||
|
||||
export interface SidebarSectionInstallProps {
|
||||
interface SidebarSectionInstallProps {
|
||||
clanURI: string;
|
||||
machineName: string;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import styles from "./SidebarSectionInstall.module.css";
|
||||
import { UpdateModal } from "@/src/workflows/InstallMachine/UpdateMachine";
|
||||
import { useClanContext } from "@/src/routes/Clan/Clan";
|
||||
|
||||
export interface SidebarSectionUpdateProps {
|
||||
interface SidebarSectionUpdateProps {
|
||||
clanURI: string;
|
||||
machineName: string;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import Icon, { IconVariant } from "@/src/components/Icon/Icon";
|
||||
import type { JSX } from "solid-js";
|
||||
import { Tooltip } from "../Tooltip/Tooltip";
|
||||
|
||||
export interface ToolbarButtonProps
|
||||
interface ToolbarButtonProps
|
||||
extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
icon: IconVariant;
|
||||
description: JSX.Element;
|
||||
|
||||
@@ -9,15 +9,15 @@ import { getInClasses } from "@/src/util";
|
||||
export type Hierarchy = "body" | "title" | "headline" | "label" | "teaser";
|
||||
export type Weight = "normal" | "medium" | "bold";
|
||||
export type Family = "regular" | "mono";
|
||||
export type Transform = "uppercase" | "lowercase" | "capitalize";
|
||||
export interface SizeForHierarchy {
|
||||
type Transform = "uppercase" | "lowercase" | "capitalize";
|
||||
interface SizeForHierarchy {
|
||||
body: "default" | "s" | "xs" | "xxs";
|
||||
headline: "default" | "m" | "l" | "xl" | "xxl";
|
||||
title: "default" | "m" | "l";
|
||||
label: "default" | "s" | "xs" | "xxs";
|
||||
teaser: "default";
|
||||
}
|
||||
export interface TagForHierarchy {
|
||||
interface TagForHierarchy {
|
||||
body: "span" | "p" | "div";
|
||||
headline: "h1" | "h2" | "h3" | "h4";
|
||||
title: "h1" | "h2" | "h3" | "h4";
|
||||
@@ -40,7 +40,7 @@ const defaultTagMap = {
|
||||
label: "span",
|
||||
teaser: "h3",
|
||||
} as const;
|
||||
export interface TypographyProps<H extends Hierarchy> {
|
||||
interface TypographyProps<H extends Hierarchy> {
|
||||
hierarchy: H;
|
||||
children: JSX.Element;
|
||||
size?: SizeForHierarchy[H];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createContext, JSX, useContext } from "solid-js";
|
||||
import { ApiCall, OperationArgs, OperationNames } from "./api";
|
||||
|
||||
export interface ApiClient {
|
||||
interface ApiClient {
|
||||
fetch: Fetcher;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { addClanURI, setActiveClanURI } from "@/src/stores/clan";
|
||||
import { Params, Navigator, useParams, useSearchParams } from "@solidjs/router";
|
||||
|
||||
export const encodeBase64 = (value: string) => window.btoa(value);
|
||||
export const decodeBase64 = (value: string) => window.atob(value);
|
||||
const decodeBase64 = (value: string) => window.atob(value);
|
||||
|
||||
export const selectClanFolder = async () => {
|
||||
const req = callApi("get_clan_folder", {});
|
||||
@@ -80,7 +80,7 @@ export const navigateToClan = (navigate: Navigator, clanURI: string) => {
|
||||
export const navigateToOnboarding = (navigate: Navigator, addClan: boolean) =>
|
||||
navigate(`/${addClan ? "?addClan=true" : ""}`);
|
||||
|
||||
export const navigateToMachine = (
|
||||
const navigateToMachine = (
|
||||
navigate: Navigator,
|
||||
clanURI: string,
|
||||
name: string,
|
||||
@@ -90,7 +90,7 @@ export const navigateToMachine = (
|
||||
navigate(path);
|
||||
};
|
||||
|
||||
export const clanURIParam = (params: Params) => {
|
||||
const clanURIParam = (params: Params) => {
|
||||
try {
|
||||
return decodeBase64(params.clanURI);
|
||||
} catch (e) {
|
||||
@@ -101,19 +101,19 @@ export const clanURIParam = (params: Params) => {
|
||||
|
||||
export const useClanURI = () => clanURIParam(useParams());
|
||||
|
||||
export const machineNameParam = (params: Params) => {
|
||||
const machineNameParam = (params: Params) => {
|
||||
return params.machineName;
|
||||
};
|
||||
|
||||
export const inputParam = (params: Params) => params.input;
|
||||
export const nameParam = (params: Params) => params.name;
|
||||
export const idParam = (params: Params) => params.id;
|
||||
const inputParam = (params: Params) => params.input;
|
||||
const nameParam = (params: Params) => params.name;
|
||||
const idParam = (params: Params) => params.id;
|
||||
|
||||
export const useMachineName = (): string => machineNameParam(useParams());
|
||||
export const useInputParam = (): string => inputParam(useParams());
|
||||
export const useNameParam = (): string => nameParam(useParams());
|
||||
const useInputParam = (): string => inputParam(useParams());
|
||||
const useNameParam = (): string => nameParam(useParams());
|
||||
|
||||
export const maybeUseIdParam = (): string | null => {
|
||||
const maybeUseIdParam = (): string | null => {
|
||||
const params = useParams();
|
||||
if (params.id === undefined) {
|
||||
return null;
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import { useMutation, useQueryClient } from "@tanstack/solid-query";
|
||||
import { callApi, OperationArgs } from "@/src/hooks/api";
|
||||
import { encodeBase64 } from "@/src/hooks/clan";
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
export const updateMachine = useMutation(() => ({
|
||||
mutationFn: async (args: OperationArgs<"set_machine">) => {
|
||||
const call = callApi("set_machine", args);
|
||||
return {
|
||||
args,
|
||||
...call,
|
||||
};
|
||||
},
|
||||
onSuccess: async ({ args }) => {
|
||||
const {
|
||||
name,
|
||||
flake: { identifier },
|
||||
} = args.machine;
|
||||
|
||||
await queryClient.invalidateQueries({
|
||||
queryKey: ["clans", encodeBase64(identifier), "machine", name],
|
||||
});
|
||||
},
|
||||
}));
|
||||
@@ -44,7 +44,7 @@ window.notifyBus = (msg: ProcessMessage) => {
|
||||
*
|
||||
* consider using useNotify for reactive usage on solidjs
|
||||
*/
|
||||
export function _subscribeNotify<T extends ProcessMessage>(
|
||||
function _subscribeNotify<T extends ProcessMessage>(
|
||||
filter: (msg: T) => boolean,
|
||||
callback: (msg: T) => void,
|
||||
) {
|
||||
@@ -65,7 +65,7 @@ export function _subscribeNotify<T extends ProcessMessage>(
|
||||
* The signal has the value of the last message where filter was true
|
||||
* null in case no message was recieved yet
|
||||
*/
|
||||
export function useNotify<T extends ProcessMessage = ProcessMessage>(
|
||||
function useNotify<T extends ProcessMessage = ProcessMessage>(
|
||||
filter: (msg: T) => boolean = () => true as boolean,
|
||||
) {
|
||||
const [message, setMessage] = createSignal<T | null>(null);
|
||||
|
||||
@@ -16,16 +16,16 @@ export interface ClanDetails {
|
||||
fieldsSchema: SuccessData<"get_clan_details_schema">;
|
||||
}
|
||||
|
||||
export type Tags = SuccessData<"list_tags">;
|
||||
type Tags = SuccessData<"list_tags">;
|
||||
export type Machine = SuccessData<"get_machine">;
|
||||
|
||||
export type MachineState = SuccessData<"get_machine_state">;
|
||||
type MachineState = SuccessData<"get_machine_state">;
|
||||
export type MachineStatus = MachineState["status"];
|
||||
|
||||
export type ListMachines = SuccessData<"list_machines">;
|
||||
export type MachineDetails = SuccessData<"get_machine_details">;
|
||||
type ListMachines = SuccessData<"list_machines">;
|
||||
type MachineDetails = SuccessData<"get_machine_details">;
|
||||
|
||||
export type ListServiceModules = SuccessData<"list_service_modules">;
|
||||
type ListServiceModules = SuccessData<"list_service_modules">;
|
||||
export type ListServiceInstances = SuccessData<"list_service_instances">;
|
||||
|
||||
export interface MachineDetail {
|
||||
@@ -35,7 +35,7 @@ export interface MachineDetail {
|
||||
}
|
||||
|
||||
export type MachinesQueryResult = UseQueryResult<ListMachines>;
|
||||
export type ClanListQueryResult = UseQueryResult<ClanDetails>[];
|
||||
type ClanListQueryResult = UseQueryResult<ClanDetails>[];
|
||||
|
||||
export const DefaultQueryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
@@ -67,7 +67,7 @@ export const useMachinesQuery = (clanURI: string) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const machineKey = (clanUri: string, machineName: string) => [
|
||||
const machineKey = (clanUri: string, machineName: string) => [
|
||||
...clanKey(clanUri),
|
||||
"machine",
|
||||
encodeBase64(machineName),
|
||||
@@ -174,7 +174,7 @@ export const useMachineStateQuery = (clanURI: string, machineName: string) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const useServiceModulesQuery = (clanURI: string) => {
|
||||
const useServiceModulesQuery = (clanURI: string) => {
|
||||
const client = useApiClient();
|
||||
|
||||
return useQuery<ListServiceModules>(() => ({
|
||||
@@ -222,10 +222,7 @@ export const useServiceInstancesQuery = (clanURI: string) => {
|
||||
}));
|
||||
};
|
||||
|
||||
export const useMachineDetailsQuery = (
|
||||
clanURI: string,
|
||||
machineName: string,
|
||||
) => {
|
||||
const useMachineDetailsQuery = (clanURI: string, machineName: string) => {
|
||||
const client = useApiClient();
|
||||
return useQuery<MachineDetails>(() => ({
|
||||
queryKey: [machineKey(clanURI, machineName), "details"],
|
||||
@@ -251,7 +248,7 @@ export const useMachineDetailsQuery = (
|
||||
}));
|
||||
};
|
||||
|
||||
export const ClanDetailsPersister = experimental_createQueryPersister({
|
||||
const ClanDetailsPersister = experimental_createQueryPersister({
|
||||
storage: ClanDetailsStore,
|
||||
});
|
||||
|
||||
@@ -373,10 +370,10 @@ export const useClanListQuery = (
|
||||
}));
|
||||
};
|
||||
|
||||
export type MachineFlashOptions = SuccessData<"get_machine_flash_options">;
|
||||
export type MachineFlashOptionsQuery = UseQueryResult<MachineFlashOptions>;
|
||||
type MachineFlashOptions = SuccessData<"get_machine_flash_options">;
|
||||
type MachineFlashOptionsQuery = UseQueryResult<MachineFlashOptions>;
|
||||
|
||||
export const useMachineFlashOptions = (): MachineFlashOptionsQuery => {
|
||||
const useMachineFlashOptions = (): MachineFlashOptionsQuery => {
|
||||
const client = useApiClient();
|
||||
return useQuery<MachineFlashOptions>(() => ({
|
||||
queryKey: ["flash_options"],
|
||||
@@ -395,8 +392,8 @@ export const useMachineFlashOptions = (): MachineFlashOptionsQuery => {
|
||||
}));
|
||||
};
|
||||
|
||||
export type SystemStorageOptions = SuccessData<"list_system_storage_devices">;
|
||||
export type SystemStorageOptionsQuery = UseQueryResult<SystemStorageOptions>;
|
||||
type SystemStorageOptions = SuccessData<"list_system_storage_devices">;
|
||||
type SystemStorageOptionsQuery = UseQueryResult<SystemStorageOptions>;
|
||||
|
||||
export const useSystemStorageOptions = (): SystemStorageOptionsQuery => {
|
||||
const client = useApiClient();
|
||||
@@ -417,10 +414,8 @@ export const useSystemStorageOptions = (): SystemStorageOptionsQuery => {
|
||||
}));
|
||||
};
|
||||
|
||||
export type MachineHardwareSummary =
|
||||
SuccessData<"get_machine_hardware_summary">;
|
||||
export type MachineHardwareSummaryQuery =
|
||||
UseQueryResult<MachineHardwareSummary>;
|
||||
type MachineHardwareSummary = SuccessData<"get_machine_hardware_summary">;
|
||||
type MachineHardwareSummaryQuery = UseQueryResult<MachineHardwareSummary>;
|
||||
|
||||
export const useMachineHardwareSummary = (
|
||||
clanUri: string,
|
||||
@@ -457,8 +452,8 @@ export const useMachineHardwareSummary = (
|
||||
}));
|
||||
};
|
||||
|
||||
export type MachineDiskSchema = SuccessData<"get_machine_disk_schemas">;
|
||||
export type MachineDiskSchemaQuery = UseQueryResult<MachineDiskSchema>;
|
||||
type MachineDiskSchema = SuccessData<"get_machine_disk_schemas">;
|
||||
type MachineDiskSchemaQuery = UseQueryResult<MachineDiskSchema>;
|
||||
|
||||
export const useMachineDiskSchemas = (
|
||||
clanUri: string,
|
||||
@@ -496,7 +491,7 @@ export const useMachineDiskSchemas = (
|
||||
};
|
||||
|
||||
export type MachineGenerators = SuccessData<"get_generators">;
|
||||
export type MachineGeneratorsQuery = UseQueryResult<MachineGenerators>;
|
||||
type MachineGeneratorsQuery = UseQueryResult<MachineGenerators>;
|
||||
|
||||
export const useMachineGenerators = (
|
||||
clanUri: string,
|
||||
@@ -538,7 +533,7 @@ export const useMachineGenerators = (
|
||||
}));
|
||||
};
|
||||
|
||||
export type ServiceModulesQuery = ReturnType<typeof useServiceModules>;
|
||||
type ServiceModulesQuery = ReturnType<typeof useServiceModules>;
|
||||
export type ServiceModules = SuccessData<"list_service_modules">;
|
||||
export const useServiceModules = (clanUri: string) => {
|
||||
const client = useApiClient();
|
||||
@@ -566,7 +561,7 @@ export const useServiceModules = (clanUri: string) => {
|
||||
export const clanKey = (clanUri: string) => ["clans", encodeBase64(clanUri)];
|
||||
|
||||
export type ServiceInstancesQuery = ReturnType<typeof useServiceInstances>;
|
||||
export type ServiceInstances = SuccessData<"list_service_instances">;
|
||||
type ServiceInstances = SuccessData<"list_service_instances">;
|
||||
export const useServiceInstances = (clanUri: string) => {
|
||||
const client = useApiClient();
|
||||
return useQuery(() => ({
|
||||
|
||||
@@ -7,13 +7,13 @@ import {
|
||||
} from "solid-js";
|
||||
import { createStore, SetStoreFunction, Store } from "solid-js/store";
|
||||
|
||||
export interface StepBase {
|
||||
interface StepBase {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export type Step<ExtraFields = unknown> = StepBase & ExtraFields;
|
||||
type Step<ExtraFields = unknown> = StepBase & ExtraFields;
|
||||
|
||||
export interface StepOptions<Id, StoreType> {
|
||||
interface StepOptions<Id, StoreType> {
|
||||
initialStep: Id;
|
||||
initialStoreData?: StoreType;
|
||||
}
|
||||
@@ -95,10 +95,7 @@ export function createStepper<
|
||||
}
|
||||
|
||||
type StoreTuple<T> = [get: Store<T>, set: SetStoreFunction<T>];
|
||||
export interface StepperReturn<
|
||||
T extends readonly Step[],
|
||||
StepId = T[number]["id"],
|
||||
> {
|
||||
interface StepperReturn<T extends readonly Step[], StepId = T[number]["id"]> {
|
||||
_store: never;
|
||||
activeStep: Accessor<StepId>;
|
||||
setActiveStep: (id: StepId) => void;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useClanListQuery } from "@/src/hooks/queries";
|
||||
import { Alert } from "@/src/components/Alert/Alert";
|
||||
import { NavSection } from "@/src/components/NavSection/NavSection";
|
||||
|
||||
export interface ListClansModalProps {
|
||||
interface ListClansModalProps {
|
||||
onClose?: () => void;
|
||||
error?: {
|
||||
title: string;
|
||||
|
||||
@@ -39,7 +39,7 @@ import { ListClansModal } from "@/src/modals/ListClansModal/ListClansModal";
|
||||
import { AddMachine } from "@/src/workflows/AddMachine/AddMachine";
|
||||
import { SelectService } from "@/src/workflows/Service/SelectServiceFlyout";
|
||||
|
||||
export type WorldMode = "default" | "select" | "service" | "create" | "move";
|
||||
type WorldMode = "default" | "select" | "service" | "create" | "move";
|
||||
|
||||
function createClanContext(
|
||||
clanURI: string,
|
||||
|
||||
@@ -22,7 +22,7 @@ type FieldNames = "name" | "description" | "machineClass";
|
||||
|
||||
type FormValues = v.InferInput<typeof schema>;
|
||||
|
||||
export interface SectionGeneralProps {
|
||||
interface SectionGeneralProps {
|
||||
clanURI: string;
|
||||
machineName: string;
|
||||
onSubmit: (values: FormValues) => Promise<void>;
|
||||
|
||||
@@ -52,7 +52,7 @@ export function createMachineMesh() {
|
||||
};
|
||||
}
|
||||
|
||||
export function createCubeBase(
|
||||
function createCubeBase(
|
||||
color: THREE.ColorRepresentation,
|
||||
emissive: THREE.ColorRepresentation,
|
||||
geometry: THREE.BoxGeometry,
|
||||
@@ -70,7 +70,7 @@ export function createCubeBase(
|
||||
}
|
||||
|
||||
// Function to build rounded rect shape
|
||||
export function roundedRectShape(w: number, h: number, r: number) {
|
||||
function roundedRectShape(w: number, h: number, r: number) {
|
||||
const shape = new THREE.Shape();
|
||||
const x = -w / 2;
|
||||
const y = -h / 2;
|
||||
|
||||
@@ -80,7 +80,7 @@ const [lastClickedMachine, setLastClickedMachine] = createSignal<string | null>(
|
||||
|
||||
// Exported so others could also emit the signal if needed
|
||||
// And for testing purposes
|
||||
export function emitMachineClick(id: string | null) {
|
||||
function emitMachineClick(id: string | null) {
|
||||
setLastClickedMachine(id);
|
||||
if (id) {
|
||||
// Clear after a short delay to allow re-clicking the same machine
|
||||
|
||||
@@ -7,7 +7,7 @@ const [highlightGroups, setHighlightGroups] = createStore<
|
||||
>({});
|
||||
|
||||
// Add highlight
|
||||
export function highlight(group: string, nodeId: string) {
|
||||
function highlight(group: string, nodeId: string) {
|
||||
setHighlightGroups(group, (prev = new Set()) => {
|
||||
const next = new Set(prev);
|
||||
next.add(nodeId);
|
||||
@@ -16,7 +16,7 @@ export function highlight(group: string, nodeId: string) {
|
||||
}
|
||||
|
||||
// Remove highlight
|
||||
export function unhighlight(group: string, nodeId: string) {
|
||||
function unhighlight(group: string, nodeId: string) {
|
||||
setHighlightGroups(group, (prev = new Set()) => {
|
||||
const next = new Set(prev);
|
||||
next.delete(nodeId);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { makePersisted } from "@solid-primitives/storage";
|
||||
|
||||
export type SceneData = Record<string, { position: [number, number] }>;
|
||||
|
||||
export interface ClanStoreType {
|
||||
interface ClanStoreType {
|
||||
clanURIs: string[];
|
||||
activeClanURI?: string;
|
||||
sceneData: Record<string, SceneData>;
|
||||
|
||||
@@ -32,7 +32,7 @@ const AddMachineStepper = (props: AddMachineStepperProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export interface AddMachineProps {
|
||||
interface AddMachineProps {
|
||||
onClose: () => void;
|
||||
onCreated: (id: string) => void;
|
||||
initialStep?: AddMachineSteps[number]["id"];
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Typography } from "@/src/components/Typography/Typography";
|
||||
import { Show } from "solid-js";
|
||||
import { Alert } from "@/src/components/Alert/Alert";
|
||||
|
||||
export interface StepProgressProps {
|
||||
interface StepProgressProps {
|
||||
onDone: () => void;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ const InstallStepper = (props: InstallStepperProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export interface InstallModalProps {
|
||||
interface InstallModalProps {
|
||||
machineName: string;
|
||||
initialStep?: InstallSteps[number]["id"];
|
||||
mount?: Node;
|
||||
|
||||
@@ -84,7 +84,7 @@ const UpdateStepper = (props: UpdateStepperProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export interface UpdateModalProps {
|
||||
interface UpdateModalProps {
|
||||
machineName: string;
|
||||
open: boolean;
|
||||
initialStep?: UpdateSteps[number]["id"];
|
||||
@@ -92,7 +92,7 @@ export interface UpdateModalProps {
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export const UpdateHeader = (props: { machineName: string }) => {
|
||||
const UpdateHeader = (props: { machineName: string }) => {
|
||||
return (
|
||||
<Typography hierarchy="label" size="default">
|
||||
Update: {props.machineName}
|
||||
@@ -206,8 +206,8 @@ const steps = [
|
||||
},
|
||||
] as const;
|
||||
|
||||
export type UpdateSteps = typeof steps;
|
||||
export type PromptValues = Record<string, Record<string, string>>;
|
||||
type UpdateSteps = typeof steps;
|
||||
type PromptValues = Record<string, Record<string, string>>;
|
||||
|
||||
export const UpdateModal = (props: UpdateModalProps) => {
|
||||
const stepper = createStepper(
|
||||
|
||||
@@ -39,7 +39,7 @@ import { Loader } from "@/src/components/Loader/Loader";
|
||||
import { Button as KButton } from "@kobalte/core/button";
|
||||
import usbLogo from "@/logos/usb-stick-min.png?url";
|
||||
|
||||
export const InstallHeader = (props: { machineName: string }) => {
|
||||
const InstallHeader = (props: { machineName: string }) => {
|
||||
return (
|
||||
<Typography hierarchy="label" size="default">
|
||||
Installing: {props.machineName}
|
||||
|
||||
@@ -462,7 +462,7 @@ const steps = [
|
||||
{ id: "settings", content: () => <div>Adjust settings here.</div> },
|
||||
] as const;
|
||||
|
||||
export type ServiceSteps = typeof steps;
|
||||
type ServiceSteps = typeof steps;
|
||||
|
||||
interface ServiceWorkflowProps {
|
||||
initialStep?: ServiceSteps[number]["id"];
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface ServiceStoreType {
|
||||
}
|
||||
|
||||
// TODO: Ideally we would impot this from a backend model package
|
||||
export interface InventoryInstance {
|
||||
interface InventoryInstance {
|
||||
name: string;
|
||||
module: {
|
||||
name: string;
|
||||
@@ -33,7 +33,7 @@ export type SubmitServiceHandler = (
|
||||
action: "create" | "update",
|
||||
) => void | Promise<void>;
|
||||
|
||||
export type ModuleItem = ServiceModules["modules"][number];
|
||||
type ModuleItem = ServiceModules["modules"][number];
|
||||
|
||||
export interface Module {
|
||||
value: string;
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
export function isValidHostname(value: string | null | undefined) {
|
||||
if (typeof value !== "string") return false;
|
||||
|
||||
const validHostnameChars = /^[a-zA-Z0-9-.]{1,253}\.?$/g;
|
||||
|
||||
if (!validHostnameChars.test(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value.endsWith(".")) {
|
||||
value = value.slice(0, value.length - 1);
|
||||
}
|
||||
|
||||
if (value.length > 253) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const labels = value.split(".");
|
||||
|
||||
const isValid = labels.every(function (label) {
|
||||
const validLabelChars = /^([a-zA-Z0-9-]+)$/g;
|
||||
|
||||
const validLabel =
|
||||
validLabelChars.test(label) &&
|
||||
label.length < 64 &&
|
||||
!label.startsWith("-") &&
|
||||
!label.endsWith("-");
|
||||
|
||||
return validLabel;
|
||||
});
|
||||
|
||||
return isValid;
|
||||
}
|
||||
Reference in New Issue
Block a user