Compare commits
2 Commits
kenji/ke-f
...
feat/clan-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
985f66dac8 | ||
|
|
0a75575e08 |
@@ -18,7 +18,7 @@ interface APITesterForm extends FieldValues {
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export const ApiTester = () => {
|
||||
const ApiTester = () => {
|
||||
const [persistedTestData, setPersistedTestData] = makePersisted(
|
||||
createSignal<APITesterForm>(),
|
||||
{
|
||||
@@ -103,3 +103,5 @@ export const ApiTester = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ApiTester;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { For, type JSX, Show } from "solid-js";
|
||||
import { RouteSectionProps } from "@solidjs/router";
|
||||
import { AppRoute, routes } from "@/src";
|
||||
import { SidebarHeader } from "./SidebarHeader";
|
||||
import { SidebarListItem } from "./SidebarListItem";
|
||||
import { Typography } from "../Typography";
|
||||
import "./css/sidebar.css";
|
||||
import Icon, { IconVariant } from "../icon";
|
||||
import { clanMetaQuery } from "@/src/queries/clan-meta";
|
||||
import routes, { AppRoute } from "@/src/routes";
|
||||
|
||||
export const SidebarSection = (props: {
|
||||
title: string;
|
||||
|
||||
@@ -1,29 +1,13 @@
|
||||
/* @refresh reload */
|
||||
import { Portal, render } from "solid-js/web";
|
||||
import { Navigate, RouteDefinition, Router } from "@solidjs/router";
|
||||
import { Router } from "@solidjs/router";
|
||||
|
||||
import "./index.css";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/solid-query";
|
||||
import {
|
||||
CreateMachine,
|
||||
MachineDetails,
|
||||
MachineListView,
|
||||
} from "./routes/machines";
|
||||
import { Layout } from "./layout/layout";
|
||||
import { ClanDetails, ClanList, CreateClan } from "./routes/clans";
|
||||
import { Flash } from "./routes/flash/view";
|
||||
import { HostList } from "./routes/hosts/view";
|
||||
import { Welcome } from "./routes/welcome";
|
||||
import { Toaster } from "solid-toast";
|
||||
import { ModuleList } from "./routes/modules/list";
|
||||
import { ModuleDetails } from "./routes/modules/details";
|
||||
import { ModuleDetails as AddModule } from "./routes/modules/add";
|
||||
import { ApiTester } from "./api_test";
|
||||
import { IconVariant } from "./components/icon";
|
||||
import { Components } from "./routes/components";
|
||||
import { VarsPage } from "./routes/machines/install/vars-step";
|
||||
import { ThreePlayground } from "./three";
|
||||
import { ClanProvider } from "./contexts/clan";
|
||||
import routes from "@/src/routes";
|
||||
|
||||
export const client = new QueryClient();
|
||||
|
||||
@@ -40,145 +24,6 @@ if (import.meta.env.DEV) {
|
||||
await import("solid-devtools");
|
||||
}
|
||||
|
||||
export type AppRoute = Omit<RouteDefinition, "children"> & {
|
||||
label: string;
|
||||
icon?: IconVariant;
|
||||
children?: AppRoute[];
|
||||
hidden?: boolean;
|
||||
};
|
||||
|
||||
export const routes: AppRoute[] = [
|
||||
{
|
||||
path: "/",
|
||||
label: "",
|
||||
hidden: true,
|
||||
component: () => <Navigate href="/machines" />,
|
||||
},
|
||||
{
|
||||
path: "/machines",
|
||||
label: "Machines",
|
||||
icon: "Grid",
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
label: "Overview",
|
||||
component: () => <MachineListView />,
|
||||
},
|
||||
{
|
||||
path: "/create",
|
||||
label: "Create",
|
||||
component: () => <CreateMachine />,
|
||||
},
|
||||
{
|
||||
path: "/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: () => <MachineDetails />,
|
||||
},
|
||||
{
|
||||
path: "/:id/vars",
|
||||
label: "Vars",
|
||||
hidden: true,
|
||||
component: () => <VarsPage />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/clans",
|
||||
label: "Clans",
|
||||
hidden: true,
|
||||
icon: "List",
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
label: "Overview",
|
||||
component: () => <ClanList />,
|
||||
},
|
||||
{
|
||||
path: "/create",
|
||||
label: "Create",
|
||||
component: () => <CreateClan />,
|
||||
},
|
||||
{
|
||||
path: "/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: () => <ClanDetails />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/modules",
|
||||
label: "Modules",
|
||||
icon: "Search",
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
label: "App Store",
|
||||
component: () => <ModuleList />,
|
||||
},
|
||||
{
|
||||
path: "details/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: () => <ModuleDetails />,
|
||||
},
|
||||
{
|
||||
path: "/add/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: () => <AddModule />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/tools",
|
||||
label: "Tools",
|
||||
icon: "Folder",
|
||||
children: [
|
||||
{
|
||||
path: "/flash",
|
||||
label: "Flash Installer",
|
||||
component: () => <Flash />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/welcome",
|
||||
label: "",
|
||||
hidden: true,
|
||||
component: () => <Welcome />,
|
||||
},
|
||||
{
|
||||
path: "/internal-dev",
|
||||
label: "Internal (Only visible in dev mode)",
|
||||
children: [
|
||||
{
|
||||
path: "/hosts",
|
||||
label: "Local Hosts",
|
||||
component: () => <HostList />,
|
||||
},
|
||||
{
|
||||
path: "/3d",
|
||||
label: "3D-Playground",
|
||||
component: () => <ThreePlayground />,
|
||||
},
|
||||
{
|
||||
path: "/api_testing",
|
||||
label: "api_testing",
|
||||
hidden: false,
|
||||
component: () => <ApiTester />,
|
||||
},
|
||||
{
|
||||
path: "/components",
|
||||
label: "Components",
|
||||
hidden: false,
|
||||
component: () => <Components />,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
render(
|
||||
() => (
|
||||
<>
|
||||
|
||||
@@ -17,7 +17,7 @@ type CreateForm = Meta & {
|
||||
template: string;
|
||||
};
|
||||
|
||||
export const CreateClan = () => {
|
||||
const CreateClan = () => {
|
||||
const [formStore, { Form, Field }] = createForm<CreateForm>({
|
||||
initialValues: {
|
||||
name: "",
|
||||
@@ -205,3 +205,5 @@ type Meta = Extract<
|
||||
OperationResponse<"show_clan_meta">,
|
||||
{ status: "success" }
|
||||
>["data"];
|
||||
|
||||
export default CreateClan;
|
||||
|
||||
@@ -139,7 +139,7 @@ const EditClanForm = (props: EditClanFormProps) => {
|
||||
|
||||
type GeneralData = SuccessQuery<"show_clan_meta">["data"];
|
||||
|
||||
export const ClanDetails = () => {
|
||||
const ClanDetails = () => {
|
||||
const params = useParams();
|
||||
const clan_dir = window.atob(params.id);
|
||||
// Fetch general meta data
|
||||
@@ -158,3 +158,5 @@ export const ClanDetails = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClanDetails;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export * from "./list";
|
||||
export * from "./create";
|
||||
export * from "./details";
|
||||
@@ -124,7 +124,7 @@ const ClanItem = (props: ClanItemProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const ClanList = () => {
|
||||
const ClanList = () => {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div class="">
|
||||
@@ -158,3 +158,5 @@ export const ClanList = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClanList;
|
||||
|
||||
@@ -8,7 +8,7 @@ const disabled = [false, true];
|
||||
const readOnly = [false, true];
|
||||
const error = [false, true];
|
||||
|
||||
export const Components = () => {
|
||||
const Components = () => {
|
||||
const [formStore, { Form, Field }] = createForm<{ ef: string }>({});
|
||||
return (
|
||||
<>
|
||||
@@ -116,3 +116,5 @@ export const Components = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Components;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { callApi } from "@/src/api";
|
||||
import { useQuery } from "@tanstack/solid-query";
|
||||
import { useClanContext } from "@/src/contexts/clan";
|
||||
|
||||
export function DiskView() {
|
||||
const DiskView = () => {
|
||||
const { activeClanURI } = useClanContext();
|
||||
|
||||
const query = useQuery(() => ({
|
||||
@@ -28,4 +28,6 @@ export function DiskView() {
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default DiskView;
|
||||
|
||||
@@ -46,7 +46,7 @@ export interface FlashFormValues extends FieldValues {
|
||||
sshKeys: File[]; // This field will use CustomFileField
|
||||
}
|
||||
|
||||
export const Flash = () => {
|
||||
const Flash = () => {
|
||||
const [formStore, { Form, Field }] = createForm<FlashFormValues>({
|
||||
initialValues: {
|
||||
machine: {
|
||||
@@ -436,3 +436,5 @@ export const Flash = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Flash;
|
||||
|
||||
@@ -8,7 +8,7 @@ type ServiceModel = Extract<
|
||||
{ status: "success" }
|
||||
>["data"]["services"];
|
||||
|
||||
export const HostList: Component = () => {
|
||||
const HostList: Component = () => {
|
||||
const [services, setServices] = createSignal<ServiceModel>();
|
||||
|
||||
return (
|
||||
@@ -74,3 +74,5 @@ export const HostList: Component = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HostList;
|
||||
146
pkgs/clan-app/ui/src/routes/index.tsx
Normal file
146
pkgs/clan-app/ui/src/routes/index.tsx
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Navigate, RouteDefinition } from "@solidjs/router";
|
||||
import { IconVariant } from "@/src/components/icon";
|
||||
import { lazy } from "solid-js";
|
||||
|
||||
export type AppRoute = Omit<RouteDefinition, "children"> & {
|
||||
label: string;
|
||||
icon?: IconVariant;
|
||||
children?: AppRoute[];
|
||||
hidden?: boolean;
|
||||
};
|
||||
|
||||
const lazyLoad = (path: string) => lazy(() => import(path));
|
||||
|
||||
const routes: AppRoute[] = [
|
||||
{
|
||||
path: "/",
|
||||
label: "",
|
||||
hidden: true,
|
||||
component: () => <Navigate href="/machines" />,
|
||||
},
|
||||
{
|
||||
path: "/machines",
|
||||
label: "Machines",
|
||||
icon: "Grid",
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
label: "Overview",
|
||||
component: lazyLoad("./machines/list"),
|
||||
},
|
||||
{
|
||||
path: "/create",
|
||||
label: "Create",
|
||||
component: lazyLoad("./machines/create"),
|
||||
},
|
||||
{
|
||||
path: "/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: lazyLoad("./machines/details"),
|
||||
},
|
||||
{
|
||||
path: "/:id/vars",
|
||||
label: "Vars",
|
||||
hidden: true,
|
||||
component: lazyLoad("./machines/install/vars-step"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/clans",
|
||||
label: "Clans",
|
||||
hidden: true,
|
||||
icon: "List",
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
label: "Overview",
|
||||
component: lazyLoad("./clans/list"),
|
||||
},
|
||||
{
|
||||
path: "/create",
|
||||
label: "Create",
|
||||
component: lazyLoad("./clans/create"),
|
||||
},
|
||||
{
|
||||
path: "/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: lazyLoad("./clans/details"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/modules",
|
||||
label: "Modules",
|
||||
icon: "Search",
|
||||
children: [
|
||||
{
|
||||
path: "/",
|
||||
label: "App Store",
|
||||
component: lazyLoad("./modules/list"),
|
||||
},
|
||||
{
|
||||
path: "details/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: lazyLoad("./modules/details"),
|
||||
},
|
||||
{
|
||||
path: "/add/:id",
|
||||
label: "Details",
|
||||
hidden: true,
|
||||
component: lazyLoad("./modules/add"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/tools",
|
||||
label: "Tools",
|
||||
icon: "Folder",
|
||||
children: [
|
||||
{
|
||||
path: "/flash",
|
||||
label: "Flash Installer",
|
||||
component: lazyLoad("./flash/view"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/welcome",
|
||||
label: "",
|
||||
hidden: true,
|
||||
component: lazyLoad("./welcome"),
|
||||
},
|
||||
{
|
||||
path: "/internal-dev",
|
||||
label: "Internal (Only visible in dev mode)",
|
||||
children: [
|
||||
{
|
||||
path: "/hosts",
|
||||
label: "Local Hosts",
|
||||
component: lazyLoad("./hosts/list"),
|
||||
},
|
||||
{
|
||||
path: "/3d",
|
||||
label: "3D-Playground",
|
||||
component: lazyLoad("../three"),
|
||||
},
|
||||
{
|
||||
path: "/api_testing",
|
||||
label: "api_testing",
|
||||
hidden: false,
|
||||
component: lazyLoad("../api_test"),
|
||||
},
|
||||
{
|
||||
path: "/components",
|
||||
label: "Components",
|
||||
hidden: false,
|
||||
component: lazyLoad("./components"),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@@ -16,7 +16,7 @@ import { useClanContext } from "@/src/contexts/clan";
|
||||
|
||||
type CreateMachineForm = OperationArgs<"create_machine">;
|
||||
|
||||
export function CreateMachine() {
|
||||
const CreateMachine = () => {
|
||||
const navigate = useNavigate();
|
||||
const { activeClanURI } = useClanContext();
|
||||
|
||||
@@ -189,4 +189,6 @@ export function CreateMachine() {
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default CreateMachine;
|
||||
|
||||
@@ -699,7 +699,7 @@ const MachineForm = (props: MachineDetailsProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const MachineDetails = () => {
|
||||
const MachineDetails = () => {
|
||||
const params = useParams();
|
||||
const { activeClanURI } = useClanContext();
|
||||
|
||||
@@ -735,3 +735,5 @@ export const MachineDetails = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MachineDetails;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export * from "./details";
|
||||
export * from "./create";
|
||||
export * from "./list";
|
||||
@@ -203,7 +203,7 @@ export const VarsStep = (props: VarsStepProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const VarsPage = () => {
|
||||
const VarsPage = () => {
|
||||
const params = useParams();
|
||||
const navigate = useNavigate();
|
||||
const { activeClanURI } = useClanContext();
|
||||
@@ -249,3 +249,5 @@ export const VarsPage = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VarsPage;
|
||||
|
||||
@@ -18,7 +18,7 @@ export interface Filter {
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export const MachineListView: Component = () => {
|
||||
const MachineListView: Component = () => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const [filter, setFilter] = createSignal<Filter>({ tags: [] });
|
||||
@@ -213,3 +213,5 @@ export const MachineListView: Component = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default MachineListView;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { createForm, FieldValues, SubmitHandler } from "@modular-forms/solid";
|
||||
import { SelectInput } from "@/src/Form/fields/Select";
|
||||
import { useClanContext } from "@/src/contexts/clan";
|
||||
|
||||
export const ModuleDetails = () => {
|
||||
const ModuleDetails = () => {
|
||||
const params = useParams();
|
||||
const { activeClanURI } = useClanContext();
|
||||
const modulesQuery = createModulesQuery(activeClanURI());
|
||||
@@ -27,6 +27,8 @@ export const ModuleDetails = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ModuleDetails;
|
||||
|
||||
interface AddModuleProps {
|
||||
data: ModuleInfo;
|
||||
id: string;
|
||||
|
||||
@@ -12,7 +12,7 @@ import Icon from "@/src/components/icon";
|
||||
import { useClanContext } from "@/src/contexts/clan";
|
||||
import { activeClanURI } from "@/src/stores/clan";
|
||||
|
||||
export const ModuleDetails = () => {
|
||||
const ModuleDetails = () => {
|
||||
const params = useParams();
|
||||
const { activeClanURI } = useClanContext();
|
||||
const modulesQuery = createModulesQuery(activeClanURI());
|
||||
@@ -32,6 +32,8 @@ export const ModuleDetails = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ModuleDetails;
|
||||
|
||||
function deepMerge(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
obj1: Record<string, any>,
|
||||
|
||||
@@ -108,7 +108,7 @@ const ModuleItem = (props: {
|
||||
);
|
||||
};
|
||||
|
||||
export const ModuleList = () => {
|
||||
const ModuleList = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { activeClanURI } = useClanContext();
|
||||
const modulesQuery = createModulesQuery(activeClanURI(), {
|
||||
@@ -214,3 +214,5 @@ export const ModuleList = () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModuleList;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { registerClan } from "@/src/hooks";
|
||||
import { useNavigate } from "@solidjs/router";
|
||||
import { useClanContext } from "@/src/contexts/clan";
|
||||
|
||||
export const Welcome = () => {
|
||||
const Welcome = () => {
|
||||
const navigate = useNavigate();
|
||||
const { setActiveClanURI } = useClanContext();
|
||||
return (
|
||||
@@ -35,3 +35,5 @@ export const Welcome = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Welcome;
|
||||
|
||||
@@ -230,7 +230,7 @@ const View = (props: ViewProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const ThreePlayground = () => {
|
||||
const ThreePlayground = () => {
|
||||
const [count, setCount] = createSignal(1);
|
||||
const [selected, setSelected] = createSignal<string>("");
|
||||
|
||||
@@ -269,3 +269,5 @@ export const ThreePlayground = () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThreePlayground;
|
||||
|
||||
Reference in New Issue
Block a user