diff --git a/pkgs/clan-app/ui/.storybook/preview.ts b/pkgs/clan-app/ui/.storybook/preview.ts index 33aafbfb6..b1bbb8cda 100644 --- a/pkgs/clan-app/ui/.storybook/preview.ts +++ b/pkgs/clan-app/ui/.storybook/preview.ts @@ -1,6 +1,5 @@ import type { Preview } from "@kachurun/storybook-solid-vite"; -import "@/src/components/v2/index.css"; import "../src/index.css"; import "./preview.css"; diff --git a/pkgs/clan-app/ui/src/Form/fields/FormSection.tsx b/pkgs/clan-app/ui/src/Form/fields/FormSection.tsx deleted file mode 100644 index 66a17717d..000000000 --- a/pkgs/clan-app/ui/src/Form/fields/FormSection.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { JSX } from "solid-js"; - -interface FormSectionProps { - children: JSX.Element; -} -const FormSection = (props: FormSectionProps) => { - return
{props.children}
; -}; diff --git a/pkgs/clan-app/ui/src/Form/fields/TextInput.tsx b/pkgs/clan-app/ui/src/Form/fields/TextInput.tsx deleted file mode 100644 index 7487fabb9..000000000 --- a/pkgs/clan-app/ui/src/Form/fields/TextInput.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { splitProps, type JSX } from "solid-js"; -import { - InputBase, - InputError, - InputLabel, - InputVariant, -} from "@/src/components/inputBase"; -import { FieldLayout } from "./layout"; - -interface TextInputProps { - // Common - error?: string; - required?: boolean; - disabled?: boolean; - // Passed to input - value: string; - inputProps?: JSX.InputHTMLAttributes; - placeholder?: string; - variant?: InputVariant; - // Passed to label - label: JSX.Element; - help?: string; - // Passed to layout - class?: string; -} - -export function TextInput(props: TextInputProps) { - const [layoutProps, rest] = splitProps(props, ["class"]); - return ( - - {props.label} - - } - field={ - - } - error={props.error && } - {...layoutProps} - /> - ); -} diff --git a/pkgs/clan-app/ui/src/Form/fields/index.ts b/pkgs/clan-app/ui/src/Form/fields/index.ts deleted file mode 100644 index 46efa5eec..000000000 --- a/pkgs/clan-app/ui/src/Form/fields/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./FormSection"; -export * from "./TextInput"; diff --git a/pkgs/clan-app/ui/src/Form/fields/layout.tsx b/pkgs/clan-app/ui/src/Form/fields/layout.tsx deleted file mode 100644 index 32d4a8888..000000000 --- a/pkgs/clan-app/ui/src/Form/fields/layout.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { JSX, splitProps } from "solid-js"; -import cx from "classnames"; - -interface LayoutProps extends JSX.HTMLAttributes { - field?: JSX.Element; - label?: JSX.Element; - error?: JSX.Element; -} -export const FieldLayout = (props: LayoutProps) => { - const [intern, divProps] = splitProps(props, [ - "field", - "label", - "error", - "class", - ]); - return ( -
-
{props.label}
-
{props.field}
- {props.error && {props.error}} -
- ); -}; diff --git a/pkgs/clan-app/ui/src/api/index.tsx b/pkgs/clan-app/ui/src/api/index.tsx deleted file mode 100644 index 519062817..000000000 --- a/pkgs/clan-app/ui/src/api/index.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import { API } from "@/api/API"; -import { Schema as Inventory } from "@/api/Inventory"; -import { toast } from "solid-toast"; -import { - ErrorToastComponent, - CancelToastComponent, -} from "@/src/components/toast"; - -type OperationNames = keyof API; -type Services = NonNullable; -type ServiceNames = keyof Services; - -export type OperationArgs = API[T]["arguments"]; -export type OperationResponse = API[T]["return"]; - -export type ClanServiceInstance = NonNullable< - Services[T] ->[string]; - -export type SuccessQuery = Extract< - OperationResponse, - { status: "success" } ->; -export type SuccessData = SuccessQuery["data"]; - -interface SendHeaderType { - logging?: { group_path: string[] }; -} -interface BackendSendType { - body: OperationArgs; - header?: SendHeaderType; -} - -// eslint-disable-next-line @typescript-eslint/no-empty-object-type -interface ReceiveHeaderType {} -interface BackendReturnType { - body: OperationResponse; - header: ReceiveHeaderType; -} - -const _callApi = ( - method: K, - args: OperationArgs, - backendOpts?: SendHeaderType, -): { promise: Promise>; op_key: string } => { - // if window[method] does not exist, throw an error - if (!(method in window)) { - console.error(`Method ${method} not found on window object`); - // return a rejected promise - return { - promise: Promise.resolve({ - body: { - status: "error", - errors: [ - { - message: `Method ${method} not found on window object`, - code: "method_not_found", - }, - ], - op_key: "noop", - }, - header: {}, - }), - op_key: "noop", - }; - } - - const message: BackendSendType = { - body: args, - header: backendOpts, - }; - - const promise = ( - window as unknown as Record< - OperationNames, - ( - args: BackendSendType, - ) => Promise> - > - )[method](message) as Promise>; - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const op_key = (promise as any)._webviewMessageId as string; - - return { promise, op_key }; -}; - -const handleCancel = async ( - ops_key: string, - orig_task: Promise>, -) => { - console.log("Canceling operation: ", ops_key); - const { promise, op_key } = _callApi("delete_task", { task_id: ops_key }); - promise.catch((error) => { - toast.custom( - (t) => ( - - ), - { - duration: 5000, - }, - ); - console.error("Unhandled promise rejection in callApi:", error); - }); - const resp = await promise; - - if (resp.body.status === "error") { - toast.custom( - (t) => ( - - ), - { - duration: 5000, - }, - ); - } else { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (orig_task as any).cancelled = true; - } - console.log("Cancel response: ", resp); -}; - -export const callApi = ( - method: K, - args: OperationArgs, - backendOpts?: SendHeaderType, -): { promise: Promise>; op_key: string } => { - console.log("Calling API", method, args, backendOpts); - - const { promise, op_key } = _callApi(method, args, backendOpts); - promise.catch((error) => { - toast.custom( - (t) => ( - - ), - { - duration: 5000, - }, - ); - console.error("Unhandled promise rejection in callApi:", error); - }); - - const toastId = toast.custom( - ( - t, // t is the Toast object, t.id is the id of THIS toast instance - ) => ( - - ), - { - duration: Infinity, - }, - ); - - const new_promise = promise.then((response) => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const cancelled = (promise as any).cancelled; - if (cancelled) { - console.log("Not printing toast because operation was cancelled"); - } - - const body = response.body; - if (body.status === "error" && !cancelled) { - toast.remove(toastId); - toast.custom( - (t) => ( - - ), - { - duration: Infinity, - }, - ); - } else { - toast.remove(toastId); - } - return body; - }); - - return { promise: new_promise, op_key: op_key }; -}; diff --git a/pkgs/clan-app/ui/src/api_test.tsx b/pkgs/clan-app/ui/src/api_test.tsx deleted file mode 100644 index 76ab8ac65..000000000 --- a/pkgs/clan-app/ui/src/api_test.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import { - createForm, - FieldValues, - getValues, - setValue, - SubmitHandler, -} from "@modular-forms/solid"; -import { TextInput } from "@/src/Form/fields/TextInput"; -import { Button } from "./components/Button/Button"; -import { callApi } from "./api"; -import { API } from "@/api/API"; -import { createSignal, Match, Switch, For, Show } from "solid-js"; -import { Typography } from "./components/Typography"; -import { useQuery } from "@tanstack/solid-query"; -import { makePersisted } from "@solid-primitives/storage"; -import jsonSchema from "@/api/API.json"; - -interface APITesterForm extends FieldValues { - endpoint: string; - payload: string; -} - -const ACTUAL_API_ENDPOINT_NAMES: (keyof API)[] = jsonSchema.required.map( - (key) => key as keyof API, -); - -export const ApiTester = () => { - const [persistedTestData, setPersistedTestData] = makePersisted( - createSignal(), - { - name: "_test_data", - storage: localStorage, - }, - ); - - const [formStore, { Form, Field }] = createForm({ - initialValues: persistedTestData() || { endpoint: "", payload: "" }, - }); - - const [endpointSearchTerm, setEndpointSearchTerm] = createSignal( - getValues(formStore).endpoint || "", - ); - const [showSuggestions, setShowSuggestions] = createSignal(false); - - const filteredEndpoints = () => { - const term = endpointSearchTerm().toLowerCase(); - if (!term) return ACTUAL_API_ENDPOINT_NAMES; - return ACTUAL_API_ENDPOINT_NAMES.filter((ep) => - ep.toLowerCase().includes(term), - ); - }; - - const query = useQuery(() => { - const currentEndpoint = getValues(formStore).endpoint; - const currentPayload = getValues(formStore).payload; - const values = getValues(formStore); - - return { - queryKey: ["api-tester", currentEndpoint, currentPayload], - queryFn: async () => { - return await callApi( - values.endpoint as keyof API, - JSON.parse(values.payload || "{}"), - ).promise; - }, - staleTime: Infinity, - enabled: false, - }; - }); - - const handleSubmit: SubmitHandler = (values) => { - console.log(values); - setPersistedTestData(values); - setEndpointSearchTerm(values.endpoint); - query.refetch(); - - const v = getValues(formStore); - console.log(v); - }; - return ( -
-

API Tester

-
-
- - {(field, fieldProps) => ( -
- { - if (fieldProps.onInput) { - (fieldProps.onInput as (ev: Event) => void)(e); - } - setEndpointSearchTerm( - (e.currentTarget as HTMLInputElement).value, - ); - setShowSuggestions(true); - }, - onBlur: (e: FocusEvent) => { - if (fieldProps.onBlur) { - (fieldProps.onBlur as (ev: FocusEvent) => void)(e); - } - setTimeout(() => setShowSuggestions(false), 150); - }, - onFocus: (e: FocusEvent) => { - setEndpointSearchTerm(field.value || ""); - setShowSuggestions(true); - }, - onKeyDown: (e: KeyboardEvent) => { - if (e.key === "Escape") { - setShowSuggestions(false); - } - }, - }} - /> - 0} - > -
    - - {(ep) => ( -
  • { - e.preventDefault(); - setValue(formStore, "endpoint", ep); - setEndpointSearchTerm(ep); - setShowSuggestions(false); - }} - > - {ep} -
  • - )} -
    -
-
-
- )} -
- - {(field, fieldProps) => ( -
- -