clan-app: Remove unused files and exports

This commit is contained in:
Qubasa
2025-06-18 21:34:23 +02:00
parent e81c879386
commit 4e0a9dea01
28 changed files with 42 additions and 208 deletions

View File

@@ -4,6 +4,7 @@
"stylelint.config.js",
"util.ts",
"src/components/v2/**",
"api/**"
"api/**",
"tailwind/**"
]
}

View File

@@ -17,37 +17,30 @@
"storybook-dev": "storybook dev -p 6006",
"test-storybook": "vitest run --project storybook",
"test-storybook-update-snapshots": "vitest run --project storybook --update",
"test-storybook-static": "npm run storybook-build && concurrently -k -s first -n 'SB,TEST' -c 'magenta,blue' 'http-server storybook-static --port 6006 --silent' 'wait-on tcp:127.0.0.1:6006 && npm run test-storybook'"
"test-storybook-static": "npm run storybook-build && concurrently -k -s first -n 'SB,TEST' -c 'magenta,blue' 'npx http-server storybook-static --port 6006 --silent' 'npx wait-on tcp:127.0.0.1:6006 && npm run test-storybook'"
},
"license": "MIT",
"devDependencies": {
"@babel/plugin-syntax-import-attributes": "^7.27.1",
"@eslint/js": "^9.3.0",
"@kachurun/storybook-solid": "^9.0.11",
"@kachurun/storybook-solid-vite": "^9.0.11",
"@storybook/addon-a11y": "^9.0.8",
"@storybook/addon-docs": "^9.0.8",
"@storybook/addon-links": "^9.0.8",
"@storybook/addon-onboarding": "^9.0.8",
"@storybook/addon-viewport": "^9.0.8",
"@storybook/addon-vitest": "^9.0.8",
"@tailwindcss/typography": "^0.5.13",
"@types/json-schema": "^7.0.15",
"@types/node": "^22.15.19",
"@types/three": "^0.177.0",
"@typescript-eslint/parser": "^8.32.1",
"@vitest/browser": "^3.2.3",
"@vitest/coverage-v8": "^3.2.3",
"autoprefixer": "^10.4.19",
"classnames": "^2.5.1",
"concurrently": "^9.1.2",
"eslint": "^9.27.0",
"eslint-plugin-tailwindcss": "^3.17.0",
"http-server": "^14.1.1",
"jsdom": "^26.1.0",
"knip": "^5.61.2",
"playwright": "~1.53.0",
"postcss": "^8.4.38",
"postcss-url": "^10.1.3",
"prettier": "^3.2.5",
"solid-devtools": "^0.34.0",
"storybook": "^9.0.8",
@@ -57,8 +50,7 @@
"vite": "^6.3.5",
"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.3"
},
"dependencies": {
"@floating-ui/dom": "^1.6.8",
@@ -70,12 +62,9 @@
"@tanstack/eslint-plugin-query": "^5.51.12",
"@tanstack/solid-query": "^5.76.0",
"corvu": "^0.7.1",
"material-icons": "^1.13.12",
"nanoid": "^5.0.7",
"solid-js": "^1.9.7",
"solid-markdown": "^2.0.13",
"solid-toast": "^0.5.0",
"three": "^0.177.0"
"solid-toast": "^0.5.0"
},
"optionalDependencies": {
"@esbuild/darwin-arm64": "^0.25.4",

View File

@@ -6,10 +6,8 @@ import type {
} from "@floating-ui/dom";
import { computePosition } from "@floating-ui/dom";
export interface UseFloatingOptions<
R extends ReferenceElement,
F extends HTMLElement,
> extends Partial<ComputePositionConfig> {
interface UseFloatingOptions<R extends ReferenceElement, F extends HTMLElement>
extends Partial<ComputePositionConfig> {
whileElementsMounted?: (
reference: R,
floating: F,
@@ -23,7 +21,7 @@ interface UseFloatingState extends Omit<ComputePositionReturn, "x" | "y"> {
y?: number | null;
}
export interface UseFloatingResult extends UseFloatingState {
interface UseFloatingResult extends UseFloatingState {
update(): void;
}

View File

@@ -3,6 +3,6 @@ import { JSX } from "solid-js";
interface FormSectionProps {
children: JSX.Element;
}
export const FormSection = (props: FormSectionProps) => {
const FormSection = (props: FormSectionProps) => {
return <div class="p-2">{props.children}</div>;
};

View File

@@ -21,7 +21,7 @@ import { FieldLayout } from "./layout";
import Icon from "@/src/components/icon";
import { useContext } from "corvu/dialog";
export interface Option {
interface Option {
value: string;
label: string;
disabled?: boolean;

View File

@@ -139,7 +139,7 @@ interface SchemaFieldsProps<T extends FieldValues, R extends ResponseData> {
readonly: boolean;
parent: JSONSchema7;
}
export function SchemaFields<T extends FieldValues, R extends ResponseData>(
function SchemaFields<T extends FieldValues, R extends ResponseData>(
props: SchemaFieldsProps<T, R>,
) {
return (
@@ -172,7 +172,7 @@ export function SchemaFields<T extends FieldValues, R extends ResponseData>(
);
}
export function StringField<T extends FieldValues, R extends ResponseData>(
function StringField<T extends FieldValues, R extends ResponseData>(
props: SchemaFieldsProps<T, R>,
) {
if (
@@ -325,7 +325,7 @@ export function StringField<T extends FieldValues, R extends ResponseData>(
interface OptionSchemaProps {
itemSpec: JSONSchema7Type;
}
export function OptionSchema(props: OptionSchemaProps) {
function OptionSchema(props: OptionSchemaProps) {
return (
<Switch
fallback={<option class="text-error-700">Item spec unhandled</option>}
@@ -344,7 +344,7 @@ interface ValueDisplayProps<T extends FieldValues, R extends ResponseData>
idx: number;
of: number;
}
export function ListValueDisplay<T extends FieldValues, R extends ResponseData>(
function ListValueDisplay<T extends FieldValues, R extends ResponseData>(
props: ValueDisplayProps<T, R>,
) {
const removeItem = (e: Event) => {
@@ -446,7 +446,7 @@ const OnlyStringItems = (props: OnlyStringItems) => {
);
};
export function ArrayFields<T extends FieldValues, R extends ResponseData>(
function ArrayFields<T extends FieldValues, R extends ResponseData>(
props: SchemaFieldsProps<T, R>,
) {
if (props.schema.type !== "array") {
@@ -711,7 +711,7 @@ interface ObjectFieldPropertyLabelProps {
schema: JSONSchema7;
fallback: JSX.Element;
}
export function ObjectFieldPropertyLabel(props: ObjectFieldPropertyLabelProps) {
function ObjectFieldPropertyLabel(props: ObjectFieldPropertyLabelProps) {
return (
<Switch fallback={props.fallback}>
{/* @ts-expect-error: $exportedModuleInfo should exist since we export it */}
@@ -722,7 +722,7 @@ export function ObjectFieldPropertyLabel(props: ObjectFieldPropertyLabelProps) {
);
}
export function ObjectFields<T extends FieldValues, R extends ResponseData>(
function ObjectFields<T extends FieldValues, R extends ResponseData>(
props: SchemaFieldsProps<T, R>,
) {
if (props.schema.type !== "object") {

View File

@@ -7,21 +7,14 @@ import {
ErrorToastComponent,
CancelToastComponent,
} from "@/src/components/toast";
export type OperationNames = keyof API;
type OperationNames = keyof API;
type Services = NonNullable<Inventory["services"]>;
type ServiceNames = keyof Services;
export type OperationArgs<T extends OperationNames> = API[T]["arguments"];
export type OperationResponse<T extends OperationNames> = API[T]["return"];
export type ApiEnvelope<T> =
| {
status: "success";
data: T;
op_key: string;
}
| ApiError;
export type Services = NonNullable<Inventory["services"]>;
export type ServiceNames = keyof Services;
export type ClanService<T extends ServiceNames> = Services[T];
export type ClanServiceInstance<T extends ServiceNames> = NonNullable<
Services[T]
>[string];
@@ -32,18 +25,6 @@ export type SuccessQuery<T extends OperationNames> = Extract<
>;
export type SuccessData<T extends OperationNames> = SuccessQuery<T>["data"];
export type ErrorQuery<T extends OperationNames> = Extract<
OperationResponse<T>,
{ status: "error" }
>;
export type ErrorData<T extends OperationNames> = ErrorQuery<T>["errors"];
export type ClanOperations = Record<OperationNames, (str: string) => void>;
export interface GtkResponse<T> {
result: T;
op_key: string;
}
const _callApi = <K extends OperationNames>(
method: K,
args: OperationArgs<K>,

View File

@@ -1,20 +0,0 @@
import { callApi } from ".";
import { Schema as Inventory } from "@/api/Inventory";
export const instance_name = (machine_name: string) =>
`${machine_name}_wifi_0` as const;
export async function get_iwd_service(base_path: string, machine_name: string) {
const r = await callApi("get_inventory", {
flake: { identifier: base_path },
}).promise;
if (r.status == "error") {
return null;
}
// @FIXME: Clean this up once we implement the feature
// @ts-expect-error: This doesn't check currently
const inventory: Inventory = r.data;
const instance_key = instance_name(machine_name);
return inventory.services?.iwd?.[instance_key] || null;
}

View File

@@ -42,8 +42,7 @@ const sizeFont: Record<Size, string> = {
s: cx("text-[0.75rem]"),
};
export interface ButtonProps
extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
interface ButtonProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: Variants;
size?: Size;
children?: JSX.Element;

View File

@@ -1,54 +0,0 @@
import { FieldValues, FormStore, ResponseData } from "@modular-forms/solid";
import { Show } from "solid-js";
import { type JSX } from "solid-js";
import cx from "classnames";
interface SelectInputProps<T extends FieldValues, R extends ResponseData> {
formStore: FormStore<T, R>;
value: string;
options: JSX.Element;
selectProps: JSX.HTMLAttributes<HTMLSelectElement>;
label: JSX.Element;
error?: string;
required?: boolean;
topRightLabel?: JSX.Element;
class?: string;
}
export function SelectInput<T extends FieldValues, R extends ResponseData>(
props: SelectInputProps<T, R>,
) {
return (
<label
class={cx(" w-full", props.class)}
aria-disabled={props.formStore.submitting}
>
<div class="">
<span
class=" block"
classList={{
"after:ml-0.5 after:text-primary after:content-['*']":
props.required,
}}
>
{props.label}
</span>
<Show when={props.topRightLabel}>
<span class="">{props.topRightLabel}</span>
</Show>
</div>
<select
{...props.selectProps}
required={props.required}
class="w-full"
value={props.value}
>
{props.options}
</select>
{props.error && (
<span class=" font-bold text-error-700">{props.error}</span>
)}
</label>
);
}

View File

@@ -8,7 +8,7 @@ import "./css/sidebar.css";
import Icon, { IconVariant } from "../icon";
import { clanMetaQuery } from "@/src/queries/clan-meta";
export const SidebarSection = (props: {
const SidebarSection = (props: {
title: string;
icon: IconVariant;
children: JSX.Element;

View File

@@ -2,7 +2,7 @@ import { Component, For } from "solid-js";
import { Typography } from "@/src/components/Typography";
import "./TagList.css";
export interface TagListProps {
interface TagListProps {
values: string[];
}

View File

@@ -3,7 +3,7 @@ import { Dynamic } from "solid-js/web";
import cx from "classnames";
import "./css/typography.css";
export type Hierarchy = "body" | "title" | "headline" | "label";
type Hierarchy = "body" | "title" | "headline" | "label";
type Color = "primary" | "secondary" | "tertiary";
type Weight = "normal" | "medium" | "bold";
type Tag = "span" | "p" | "h1" | "h2" | "h3" | "h4" | "div";

View File

@@ -12,7 +12,7 @@ export const Group = (props: GroupProps) => (
</div>
);
export type SectionVariant = "attention" | "danger";
type SectionVariant = "attention" | "danger";
interface SectionHeaderProps {
variant: SectionVariant;

View File

@@ -108,7 +108,7 @@ export const RndThumbnail = (props: RndThumbnailProps) => {
return <img src={imageSrc()} alt={props.name} />;
};
export const RndThumbnailShow = () => {
const RndThumbnailShow = () => {
const names = ["hsjobeki", "mic92", "lassulus", "D", "A", "D", "B", "C"];
return (

View File

@@ -68,7 +68,7 @@ const WarningIcon: Component = () => (
// --- Base Props and Styles ---
export interface BaseToastProps {
interface BaseToastProps {
t: Toast;
message: string;
onCancel?: () => void; // Optional custom function on X click
@@ -254,7 +254,7 @@ export const CancelToastComponent: Component<BaseToastProps> = (props) => {
};
// Warning Toast
export const WarningToastComponent: Component<BaseToastProps> = (props) => {
const WarningToastComponent: Component<BaseToastProps> = (props) => {
let timeoutId: number | undefined;
const [clicked, setClicked] = createSignal(false);
const [exiting, setExiting] = createSignal(false);

View File

@@ -6,10 +6,8 @@ import type {
} from "@floating-ui/dom";
import { computePosition } from "@floating-ui/dom";
export interface UseFloatingOptions<
R extends ReferenceElement,
F extends HTMLElement,
> extends Partial<ComputePositionConfig> {
interface UseFloatingOptions<R extends ReferenceElement, F extends HTMLElement>
extends Partial<ComputePositionConfig> {
whileElementsMounted?: (
reference: R,
floating: F,
@@ -23,7 +21,7 @@ interface UseFloatingState extends Omit<ComputePositionReturn, "x" | "y"> {
y?: number | null;
}
export interface UseFloatingResult extends UseFloatingState {
interface UseFloatingResult extends UseFloatingState {
update(): void;
}

View File

@@ -23,7 +23,7 @@ export const registerClan = async () => {
* Opens the custom file dialog
* Returns a native FileList to allow interaction with the native input type="file"
*/
export const selectSshKeys = async (): Promise<FileList> => {
const selectSshKeys = async (): Promise<FileList> => {
const dataTransfer = new DataTransfer();
const response = await callApi("open_file", {

View File

@@ -2,7 +2,7 @@ import { useQuery } from "@tanstack/solid-query";
import { callApi } from "../api";
import toast from "solid-toast";
export interface ModulesFilter {
interface ModulesFilter {
features: string[];
}
export const createModulesQuery = (

View File

@@ -1,13 +0,0 @@
export const colors = () => {
return (
<div class="grid grid-cols-3 gap-2">
<div class="h-10 w-20 bg-red-500">red</div>
<div class="h-10 w-20 bg-green-500">green</div>
<div class="h-10 w-20 bg-blue-500">blue</div>
<div class="h-10 w-20 bg-yellow-500">yellow</div>
<div class="h-10 w-20 bg-purple-500">purple</div>
<div class="h-10 w-20 bg-cyan-500">cyan</div>
<div class="h-10 w-20 bg-pink-500">pink</div>
</div>
);
};

View File

@@ -1,6 +0,0 @@
import { callApi } from "@/src/api";
import { createQuery } from "@tanstack/solid-query";
export const Deploy = () => {
return <div>Deloy view</div>;
};

View File

@@ -1,31 +0,0 @@
import { callApi } from "@/src/api";
import { useQuery } from "@tanstack/solid-query";
import { useClanContext } from "@/src/contexts/clan";
export function DiskView() {
const { activeClanURI } = useClanContext();
const query = useQuery(() => ({
queryKey: ["disk", activeClanURI()],
queryFn: async () => {
const currUri = activeClanURI();
if (currUri) {
// Example of calling an API
const result = await callApi("get_inventory", {
flake: { identifier: currUri },
}).promise;
if (result.status === "error") throw new Error("Failed to fetch data");
return result.data;
}
},
}));
return (
<div>
<h1>Configure Disk</h1>
<p>
Select machine then configure the disk. Required before installing for
the first time.
</p>
</div>
);
}

View File

@@ -34,7 +34,7 @@ interface Wifi extends FieldValues {
password: string;
}
export interface FlashFormValues extends FieldValues {
interface FlashFormValues extends FieldValues {
machine: {
devicePath: string;
flake: string;

View File

@@ -1,9 +1,2 @@
export { MachineActionsBar } from "./MachineActionsBar";
export { MachineAvatar } from "./MachineAvatar";
export { MachineForm } from "./MachineForm";
export { MachineGeneralFields } from "./MachineGeneralFields";
export { MachineHardwareInfo } from "./MachineHardwareInfo";
export { InstallMachine } from "./InstallMachine";
export { InstallProgress } from "./InstallProgress";
export { InstallStepper } from "./InstallStepper";
export { InstallStepNavigation } from "./InstallStepNavigation";
export { MachineAvatar } from "./MachineAvatar";

View File

@@ -19,7 +19,7 @@ import { useClanContext } from "@/src/contexts/clan";
export type VarsValues = FieldValues & Record<string, Record<string, string>>;
export interface VarsFormProps {
interface VarsFormProps {
machine_id: string;
dir: string;
handleSubmit: SubmitHandler<VarsValues>;
@@ -27,7 +27,7 @@ export interface VarsFormProps {
footer: JSX.Element;
}
export const VarsForm = (props: VarsFormProps) => {
const VarsForm = (props: VarsFormProps) => {
const [formStore, { Form, Field }] = createForm<VarsValues>({});
const handleSubmit: SubmitHandler<VarsValues> = async (values, event) => {

View File

@@ -32,7 +32,7 @@ interface AddModuleProps {
id: string;
}
export const AddModule = (props: AddModuleProps) => {
const AddModule = (props: AddModuleProps) => {
const { activeClanURI } = useClanContext();
const tags = tagsQuery(activeClanURI());
const machines = machinesQuery(activeClanURI());

View File

@@ -140,7 +140,7 @@ interface SchemaFormProps {
path: string[];
}
export const ModuleForm = (props: { id: string }) => {
const ModuleForm = (props: { id: string }) => {
// TODO: Fetch the synced schema for all the modules at runtime
// We use static schema file at build time for now. (Different versions might have different schema at runtime)
const schemaQuery = createQuery(() => ({

View File

@@ -80,7 +80,6 @@ const removeClanURI = (uri: string) => {
export {
store,
setStore,
activeClanURI,
setActiveClanURI,
clanURIs,