add create/join switch
This commit is contained in:
@@ -21,6 +21,7 @@ def nix_flake_show(flake_url: AnyUrl | Path) -> list[str]:
|
|||||||
"show",
|
"show",
|
||||||
"--json",
|
"--json",
|
||||||
"--show-trace",
|
"--show-trace",
|
||||||
|
"--no-write-lock-file",
|
||||||
f"{flake_url}",
|
f"{flake_url}",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -35,6 +36,7 @@ def nix_build(
|
|||||||
"build",
|
"build",
|
||||||
"--no-link",
|
"--no-link",
|
||||||
"--print-out-paths",
|
"--print-out-paths",
|
||||||
|
"--no-write-lock-file",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
+ flags
|
+ flags
|
||||||
@@ -57,6 +59,7 @@ def nix_eval(flags: list[str]) -> list[str]:
|
|||||||
"eval",
|
"eval",
|
||||||
"--show-trace",
|
"--show-trace",
|
||||||
"--json",
|
"--json",
|
||||||
|
"--no-write-lock-file",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
if os.environ.get("IN_NIX_SANDBOX"):
|
if os.environ.get("IN_NIX_SANDBOX"):
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ class TaskPool:
|
|||||||
self.lock: threading.RLock = threading.RLock()
|
self.lock: threading.RLock = threading.RLock()
|
||||||
self.pool: dict[UUID, BaseTask] = {}
|
self.pool: dict[UUID, BaseTask] = {}
|
||||||
|
|
||||||
|
|
||||||
def __getitem__(self, uuid: UUID) -> BaseTask:
|
def __getitem__(self, uuid: UUID) -> BaseTask:
|
||||||
with self.lock:
|
with self.lock:
|
||||||
return self.pool[uuid]
|
return self.pool[uuid]
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { useListMachines } from "@/api/default/default";
|
import { AxiosError } from "axios";
|
||||||
import { MachinesResponse } from "@/api/model";
|
|
||||||
import { AxiosError, AxiosResponse } from "axios";
|
|
||||||
import React, {
|
import React, {
|
||||||
Dispatch,
|
Dispatch,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
@@ -8,7 +6,6 @@ import React, {
|
|||||||
createContext,
|
createContext,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { KeyedMutator } from "swr";
|
|
||||||
|
|
||||||
type AppContextType = {
|
type AppContextType = {
|
||||||
// data: AxiosResponse<{}, any> | undefined;
|
// data: AxiosResponse<{}, any> | undefined;
|
||||||
@@ -18,7 +15,7 @@ type AppContextType = {
|
|||||||
error: AxiosError<any> | undefined;
|
error: AxiosError<any> | undefined;
|
||||||
|
|
||||||
setAppState: Dispatch<SetStateAction<AppState>>;
|
setAppState: Dispatch<SetStateAction<AppState>>;
|
||||||
mutate: KeyedMutator<AxiosResponse<MachinesResponse, any>>;
|
// mutate: KeyedMutator<AxiosResponse<MachinesResponse, any>>;
|
||||||
swrKey: string | false | Record<any, any>;
|
swrKey: string | false | Record<any, any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -38,7 +35,11 @@ interface AppContextProviderProps {
|
|||||||
}
|
}
|
||||||
export const WithAppState = (props: AppContextProviderProps) => {
|
export const WithAppState = (props: AppContextProviderProps) => {
|
||||||
const { children } = props;
|
const { children } = props;
|
||||||
const { isLoading, error, mutate, swrKey } = useListMachines("defaultFlake");
|
const { isLoading, error, swrKey } = {
|
||||||
|
isLoading: false,
|
||||||
|
error: undefined,
|
||||||
|
swrKey: "default",
|
||||||
|
};
|
||||||
|
|
||||||
const [data, setAppState] = useState<AppState>({ isJoined: false });
|
const [data, setAppState] = useState<AppState>({ isJoined: false });
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ export const WithAppState = (props: AppContextProviderProps) => {
|
|||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
swrKey,
|
swrKey,
|
||||||
mutate,
|
// mutate,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -1,31 +1,82 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { IconButton, Input, InputAdornment } from "@mui/material";
|
import {
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
InputAdornment,
|
||||||
|
LinearProgress,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
} from "@mui/material";
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams } from "next/navigation";
|
||||||
import { Suspense } from "react";
|
import { Suspense, useState } from "react";
|
||||||
|
|
||||||
|
import { createFlake } from "@/api/default/default";
|
||||||
|
import { useAppState } from "@/components/hooks/useAppContext";
|
||||||
import { Confirm } from "@/components/join/confirm";
|
import { Confirm } from "@/components/join/confirm";
|
||||||
import { Layout } from "@/components/join/layout";
|
import { Layout } from "@/components/join/layout";
|
||||||
import { ChevronRight } from "@mui/icons-material";
|
import { ChevronRight } from "@mui/icons-material";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
|
||||||
type FormValues = {
|
type FormValues = {
|
||||||
|
workflow: "join" | "create";
|
||||||
flakeUrl: string;
|
flakeUrl: string;
|
||||||
|
dest?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function JoinPrequel() {
|
export default function JoinPrequel() {
|
||||||
const queryParams = useSearchParams();
|
const queryParams = useSearchParams();
|
||||||
const flakeUrl = queryParams.get("flake") || "";
|
const flakeUrl = queryParams.get("flake") || "";
|
||||||
const flakeAttr = queryParams.get("attr") || "default";
|
const flakeAttr = queryParams.get("attr") || "default";
|
||||||
const { control, formState, getValues, reset } = useForm<FormValues>({
|
const [forkInProgress, setForkInProgress] = useState(false);
|
||||||
defaultValues: { flakeUrl: "" },
|
const { setAppState } = useAppState();
|
||||||
});
|
|
||||||
|
|
||||||
|
const { control, formState, getValues, reset, watch, handleSubmit } =
|
||||||
|
useForm<FormValues>({
|
||||||
|
defaultValues: { flakeUrl: "", dest: undefined, workflow: "join" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const workflow = watch("workflow");
|
||||||
|
|
||||||
|
const WorkflowAdornment = (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<Controller
|
||||||
|
name="workflow"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Select
|
||||||
|
{...field}
|
||||||
|
label="workflow"
|
||||||
|
variant="standard"
|
||||||
|
disableUnderline
|
||||||
|
>
|
||||||
|
<MenuItem value={"join"}>Join</MenuItem>
|
||||||
|
<MenuItem value={"create"}>Create</MenuItem>
|
||||||
|
</Select>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<IconButton type="submit">
|
||||||
|
<ChevronRight />
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Suspense fallback="Loading">
|
<Suspense fallback="Loading">
|
||||||
{!formState.isSubmitted && !flakeUrl && (
|
{!formState.isSubmitted && !flakeUrl && (
|
||||||
<form
|
<form
|
||||||
// onSubmit={handleSubmit(() => {})}
|
onSubmit={handleSubmit((values) => {
|
||||||
|
console.log("submitted", { values });
|
||||||
|
if (workflow === "create") {
|
||||||
|
setForkInProgress(true);
|
||||||
|
createFlake({
|
||||||
|
flake_name: values.dest || "default",
|
||||||
|
url: values.flakeUrl,
|
||||||
|
}).then(() => {
|
||||||
|
setForkInProgress(false);
|
||||||
|
setAppState((s) => ({ ...s, isJoined: true }));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})}
|
||||||
className="w-full max-w-2xl justify-self-center"
|
className="w-full max-w-2xl justify-self-center"
|
||||||
>
|
>
|
||||||
<Controller
|
<Controller
|
||||||
@@ -33,6 +84,8 @@ export default function JoinPrequel() {
|
|||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<Input
|
<Input
|
||||||
|
disableUnderline
|
||||||
|
placeholder="url"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
aria-required="true"
|
aria-required="true"
|
||||||
{...field}
|
{...field}
|
||||||
@@ -42,18 +95,42 @@ export default function JoinPrequel() {
|
|||||||
<InputAdornment position="start">Clan</InputAdornment>
|
<InputAdornment position="start">Clan</InputAdornment>
|
||||||
}
|
}
|
||||||
endAdornment={
|
endAdornment={
|
||||||
<InputAdornment position="end">
|
workflow == "join" ? WorkflowAdornment : undefined
|
||||||
<IconButton type="submit">
|
|
||||||
<ChevronRight />
|
|
||||||
</IconButton>
|
|
||||||
</InputAdornment>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
{workflow === "create" && (
|
||||||
|
<Controller
|
||||||
|
name="dest"
|
||||||
|
control={control}
|
||||||
|
render={({ field }) => (
|
||||||
|
<Input
|
||||||
|
sx={{ my: 2 }}
|
||||||
|
placeholder="Location"
|
||||||
|
color="secondary"
|
||||||
|
aria-required="true"
|
||||||
|
{...field}
|
||||||
|
required
|
||||||
|
fullWidth
|
||||||
|
startAdornment={
|
||||||
|
<InputAdornment position="start">Name</InputAdornment>
|
||||||
|
}
|
||||||
|
endAdornment={
|
||||||
|
workflow == "create" ? WorkflowAdornment : undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
)}
|
)}
|
||||||
{(formState.isSubmitted || flakeUrl) && (
|
{formState.isSubmitted && workflow == "create" && (
|
||||||
|
<div>
|
||||||
|
<LinearProgress />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(formState.isSubmitted || flakeUrl) && workflow == "join" && (
|
||||||
<Confirm
|
<Confirm
|
||||||
handleBack={() => reset()}
|
handleBack={() => reset()}
|
||||||
flakeUrl={formState.isSubmitted ? getValues("flakeUrl") : flakeUrl}
|
flakeUrl={formState.isSubmitted ? getValues("flakeUrl") : flakeUrl}
|
||||||
|
|||||||
Reference in New Issue
Block a user