Merge pull request 'Clan-app: fix welcome screen for initially empty clan' (#1953) from hsjobeki/clan-core:hsjobeki-main into main
This commit is contained in:
@@ -16,6 +16,7 @@ interface TextInputProps<T extends FieldValues, R extends ResponseData> {
|
|||||||
position: "start" | "end";
|
position: "start" | "end";
|
||||||
content: JSX.Element;
|
content: JSX.Element;
|
||||||
};
|
};
|
||||||
|
placeholder?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TextInput<T extends FieldValues, R extends ResponseData>(
|
export function TextInput<T extends FieldValues, R extends ResponseData>(
|
||||||
@@ -51,7 +52,7 @@ export function TextInput<T extends FieldValues, R extends ResponseData>(
|
|||||||
classList={{
|
classList={{
|
||||||
"input-disabled": props.formStore.submitting,
|
"input-disabled": props.formStore.submitting,
|
||||||
}}
|
}}
|
||||||
placeholder="name"
|
placeholder={`${props.placeholder || props.label}`}
|
||||||
required
|
required
|
||||||
disabled={props.formStore.submitting}
|
disabled={props.formStore.submitting}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ import { createQuery } from "@tanstack/solid-query";
|
|||||||
import { activeURI } from "../App";
|
import { activeURI } from "../App";
|
||||||
import { callApi } from "../api";
|
import { callApi } from "../api";
|
||||||
import { Accessor, Show } from "solid-js";
|
import { Accessor, Show } from "solid-js";
|
||||||
|
import { useNavigate } from "@solidjs/router";
|
||||||
|
|
||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
clan_dir: Accessor<string | null>;
|
clan_dir: Accessor<string | null>;
|
||||||
}
|
}
|
||||||
export const Header = (props: HeaderProps) => {
|
export const Header = (props: HeaderProps) => {
|
||||||
const { clan_dir } = props;
|
const { clan_dir } = props;
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const query = createQuery(() => ({
|
const query = createQuery(() => ({
|
||||||
queryKey: [clan_dir(), "meta"],
|
queryKey: [clan_dir(), "meta"],
|
||||||
@@ -63,7 +65,7 @@ export const Header = (props: HeaderProps) => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex-none">
|
<div class="flex-none">
|
||||||
<span class="tooltip tooltip-bottom" data-tip="Settings">
|
<span class="tooltip tooltip-bottom" data-tip="Settings">
|
||||||
<button class="link">
|
<button class="link" onClick={() => navigate("/clan")}>
|
||||||
<span class="material-icons">settings</span>
|
<span class="material-icons">settings</span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -2,12 +2,20 @@ import { Component, createEffect, Show } from "solid-js";
|
|||||||
import { Header } from "./header";
|
import { Header } from "./header";
|
||||||
import { Sidebar } from "../Sidebar";
|
import { Sidebar } from "../Sidebar";
|
||||||
import { activeURI, clanList } from "../App";
|
import { activeURI, clanList } from "../App";
|
||||||
import { RouteSectionProps } from "@solidjs/router";
|
import { redirect, RouteSectionProps, useNavigate } from "@solidjs/router";
|
||||||
import { Toaster } from "solid-toast";
|
import { Toaster } from "solid-toast";
|
||||||
|
|
||||||
export const Layout: Component<RouteSectionProps> = (props) => {
|
export const Layout: Component<RouteSectionProps> = (props) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
console.log("Layout props", props.location);
|
console.log("Layout props", props.location);
|
||||||
|
console.log(
|
||||||
|
"empty ClanList, redirect to welcome page",
|
||||||
|
clanList().length === 0,
|
||||||
|
);
|
||||||
|
if (clanList().length === 0) {
|
||||||
|
navigate("/welcome");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div class="h-screen bg-gradient-to-b from-white to-base-100 p-4">
|
<div class="h-screen bg-gradient-to-b from-white to-base-100 p-4">
|
||||||
|
|||||||
@@ -98,22 +98,6 @@ export function CreateMachine() {
|
|||||||
label={"Deployment target"}
|
label={"Deployment target"}
|
||||||
error={field.error}
|
error={field.error}
|
||||||
/>
|
/>
|
||||||
<div class="label">
|
|
||||||
<span class="label-text-alt text-neutral">
|
|
||||||
Must be set before deployment for the following tasks:
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<span>Detect hardware config</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span>Detect disk layout</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span>Remote installation</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
createQuery,
|
createQuery,
|
||||||
useQueryClient,
|
useQueryClient,
|
||||||
} from "@tanstack/solid-query";
|
} from "@tanstack/solid-query";
|
||||||
|
import { useNavigate } from "@solidjs/router";
|
||||||
|
|
||||||
type MachinesModel = Extract<
|
type MachinesModel = Extract<
|
||||||
OperationResponse<"list_inventory_machines">,
|
OperationResponse<"list_inventory_machines">,
|
||||||
@@ -73,6 +74,7 @@ export const MachineListView: Component = () => {
|
|||||||
nixosQuery.data?.filter(
|
nixosQuery.data?.filter(
|
||||||
(name) => !inventoryMachines().some(([key, machine]) => key === name),
|
(name) => !inventoryMachines().some(([key, machine]) => key === name),
|
||||||
);
|
);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -83,10 +85,7 @@ export const MachineListView: Component = () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="tooltip tooltip-bottom" data-tip="Create machine">
|
<div class="tooltip tooltip-bottom" data-tip="Create machine">
|
||||||
<button
|
<button class="btn btn-ghost" onClick={() => navigate("create")}>
|
||||||
class="btn btn-ghost"
|
|
||||||
// onClick={() => setRoute("machines/add")}
|
|
||||||
>
|
|
||||||
<span class="material-icons ">add</span>
|
<span class="material-icons ">add</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { createQuery } from "@tanstack/solid-query";
|
|||||||
import { useFloating } from "@/src/floating";
|
import { useFloating } from "@/src/floating";
|
||||||
import { autoUpdate, flip, hide, offset, shift } from "@floating-ui/dom";
|
import { autoUpdate, flip, hide, offset, shift } from "@floating-ui/dom";
|
||||||
import { EditClanForm } from "../clan/editClan";
|
import { EditClanForm } from "../clan/editClan";
|
||||||
|
import { useNavigate } from "@solidjs/router";
|
||||||
|
|
||||||
export const registerClan = async () => {
|
export const registerClan = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -68,6 +69,18 @@ const ClanDetails = (props: ClanDetailsProps) => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const handleRemove = () => {
|
||||||
|
setClanList((s) =>
|
||||||
|
s.filter((v, idx) => {
|
||||||
|
if (v == clan_dir) {
|
||||||
|
setActiveURI(clanList()[idx - 1] || clanList()[idx + 1] || null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<div class="stat-figure text-primary">
|
<div class="stat-figure text-primary">
|
||||||
@@ -103,6 +116,7 @@ const ClanDetails = (props: ClanDetailsProps) => {
|
|||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
popover="auto"
|
popover="auto"
|
||||||
|
role="tooltip"
|
||||||
id={`clan-delete-popover-${clan_dir}`}
|
id={`clan-delete-popover-${clan_dir}`}
|
||||||
ref={setFloating}
|
ref={setFloating}
|
||||||
style={{
|
style={{
|
||||||
@@ -110,30 +124,22 @@ const ClanDetails = (props: ClanDetailsProps) => {
|
|||||||
top: `${position.y ?? 0}px`,
|
top: `${position.y ?? 0}px`,
|
||||||
left: `${position.x ?? 0}px`,
|
left: `${position.x ?? 0}px`,
|
||||||
}}
|
}}
|
||||||
class="bg-transparent"
|
class="m-0 bg-transparent"
|
||||||
>
|
>
|
||||||
<button
|
<button class="btn bg-[#ffdd2c]" onClick={handleRemove}>
|
||||||
class="btn btn-warning btn-sm"
|
|
||||||
onClick={() => {
|
|
||||||
setClanList((s) =>
|
|
||||||
s.filter((v, idx) => {
|
|
||||||
if (v == clan_dir) {
|
|
||||||
setActiveURI(
|
|
||||||
clanList()[idx - 1] || clanList()[idx + 1] || null,
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Remove from App
|
Remove from App
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-title">{clan_dir}</div>
|
<div
|
||||||
|
class="stat-title"
|
||||||
|
classList={{
|
||||||
|
"badge badge-primary": activeURI() === clan_dir,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{clan_dir}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Show when={details.isLoading}>
|
<Show when={details.isLoading}>
|
||||||
<div class="skeleton h-12 w-80" />
|
<div class="skeleton h-12 w-80" />
|
||||||
@@ -151,6 +157,7 @@ const ClanDetails = (props: ClanDetailsProps) => {
|
|||||||
export const Settings = () => {
|
export const Settings = () => {
|
||||||
const [editURI, setEditURI] = createSignal<string | null>(null);
|
const [editURI, setEditURI] = createSignal<string | null>(null);
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
return (
|
return (
|
||||||
<div class="card card-normal">
|
<div class="card card-normal">
|
||||||
<Switch>
|
<Switch>
|
||||||
@@ -167,15 +174,31 @@ export const Settings = () => {
|
|||||||
<Match when={!editURI()}>
|
<Match when={!editURI()}>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
<div class="label-text">Registered Clans</div>
|
<div class="label-text text-2xl text-neutral">
|
||||||
<button
|
Registered Clans
|
||||||
class="btn btn-square btn-primary"
|
</div>
|
||||||
onClick={() => {
|
<div class="flex gap-2">
|
||||||
registerClan();
|
<span class="tooltip tooltip-top" data-tip="Register clan">
|
||||||
}}
|
<button
|
||||||
>
|
class="btn btn-square btn-ghost"
|
||||||
<span class="material-icons">add</span>
|
onClick={() => {
|
||||||
</button>
|
registerClan();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span class="material-icons">post_add</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
<span class="tooltip tooltip-top" data-tip="Create new clan">
|
||||||
|
<button
|
||||||
|
class="btn btn-square btn-ghost"
|
||||||
|
onClick={() => {
|
||||||
|
navigate("create");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span class="material-icons">add</span>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stats stats-vertical shadow">
|
<div class="stats stats-vertical shadow">
|
||||||
<For each={clanList()}>
|
<For each={clanList()}>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { setActiveURI } from "@/src/App";
|
import { setActiveURI, setClanList } from "@/src/App";
|
||||||
import { registerClan } from "../settings";
|
import { registerClan } from "../settings";
|
||||||
|
import { useNavigate } from "@solidjs/router";
|
||||||
|
|
||||||
export const Welcome = () => {
|
export const Welcome = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
return (
|
return (
|
||||||
<div class="hero min-h-[calc(100vh-10rem)]">
|
<div class="hero min-h-[calc(100vh-10rem)]">
|
||||||
<div class="hero-content mb-32 text-center">
|
<div class="hero-content mb-32 text-center">
|
||||||
@@ -19,7 +21,10 @@ export const Welcome = () => {
|
|||||||
class="link w-full text-right text-primary"
|
class="link w-full text-right text-primary"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const uri = await registerClan();
|
const uri = await registerClan();
|
||||||
if (uri) setActiveURI(uri);
|
if (uri) {
|
||||||
|
setActiveURI(uri);
|
||||||
|
navigate("/machines");
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Or select folder
|
Or select folder
|
||||||
@@ -27,7 +32,7 @@ export const Welcome = () => {
|
|||||||
<button
|
<button
|
||||||
class="link w-full text-right text-secondary"
|
class="link w-full text-right text-secondary"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
// setRoute("machines");
|
setClanList((c) => [...c, "debug"]);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Skip (Debug)
|
Skip (Debug)
|
||||||
|
|||||||
Reference in New Issue
Block a user