forked from github-starred/komodo
start permissions UI etc
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
"cmdk": "^0.2.0",
|
"cmdk": "^0.2.0",
|
||||||
"jotai": "^2.4.1",
|
"jotai": "^2.4.1",
|
||||||
"lightweight-charts": "^4.0.1",
|
"lightweight-charts": "^4.0.1",
|
||||||
"lucide-react": "^0.274.0",
|
"lucide-react": "^0.285.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-minimal-pie-chart": "^8.4.0",
|
"react-minimal-pie-chart": "^8.4.0",
|
||||||
|
|||||||
@@ -155,10 +155,11 @@ export const ResourceSelector = ({
|
|||||||
onSelect: (id: string) => void;
|
onSelect: (id: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const resources = useRead(`List${type}s`, {}).data;
|
const resources = useRead(`List${type}s`, {}).data;
|
||||||
|
const value = resources?.find((r) => r.id === selected)?.name;
|
||||||
return (
|
return (
|
||||||
<Select value={selected ?? undefined} onValueChange={onSelect}>
|
<Select value={value ?? undefined} onValueChange={onSelect}>
|
||||||
<SelectTrigger className="w-full lg:w-[300px]">
|
<SelectTrigger className="w-full lg:w-[300px]">
|
||||||
<SelectValue placeholder={`Select ${type}`} />
|
{value ?? `Select ${type}`}
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
@@ -187,9 +188,7 @@ export const AccountSelector = ({
|
|||||||
onSelect: (id: string) => void;
|
onSelect: (id: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const request =
|
const request =
|
||||||
type === "Server"
|
type === "Server" ? "GetAvailableAccounts" : "GetBuilderAvailableAccounts";
|
||||||
? "GetServerAvailableAccounts"
|
|
||||||
: "GetBuilderAvailableAccounts";
|
|
||||||
const accounts = useRead(request, { id: id! }, { enabled: !!id }).data;
|
const accounts = useRead(request, { id: id! }, { enabled: !!id }).data;
|
||||||
return (
|
return (
|
||||||
<ConfigItem label={`${account_type} Account`}>
|
<ConfigItem label={`${account_type} Account`}>
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ import { ResourceTarget } from "@monitor/client/dist/types";
|
|||||||
|
|
||||||
const Username = ({ user_id }: { user_id: string }) => {
|
const Username = ({ user_id }: { user_id: string }) => {
|
||||||
const username = useRead("GetUsername", { user_id }).data?.username;
|
const username = useRead("GetUsername", { user_id }).data?.username;
|
||||||
|
|
||||||
console.log(user_id, useRead("GetUsername", { user_id }).data);
|
|
||||||
return <>{username}</>;
|
return <>{username}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -138,8 +136,6 @@ export const ResourcePermissions = ({
|
|||||||
.filter((id) => id != me)
|
.filter((id) => id != me)
|
||||||
.filter((id) => !users?.find((u) => u._id?.$oid === id)?.admin);
|
.filter((id) => !users?.find((u) => u._id?.$oid === id)?.admin);
|
||||||
|
|
||||||
console.log(users, display);
|
|
||||||
|
|
||||||
if (!admin || !display.length) return null;
|
if (!admin || !display.length) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Builder } from "./builder";
|
|||||||
import { Deployment } from "./deployment";
|
import { Deployment } from "./deployment";
|
||||||
import { Repo } from "./repo";
|
import { Repo } from "./repo";
|
||||||
import { Server } from "./server";
|
import { Server } from "./server";
|
||||||
|
import { Procedure } from "./procedure";
|
||||||
|
|
||||||
export const ResourceComponents: {
|
export const ResourceComponents: {
|
||||||
[key in UsableResource]: RequiredResourceComponents;
|
[key in UsableResource]: RequiredResourceComponents;
|
||||||
@@ -15,4 +16,5 @@ export const ResourceComponents: {
|
|||||||
Deployment,
|
Deployment,
|
||||||
Repo,
|
Repo,
|
||||||
Server,
|
Server,
|
||||||
|
Procedure,
|
||||||
};
|
};
|
||||||
|
|||||||
403
frontend/src/components/resources/procedure/index.tsx
Normal file
403
frontend/src/components/resources/procedure/index.tsx
Normal file
@@ -0,0 +1,403 @@
|
|||||||
|
import { ResourceSelector } from "@components/config/util";
|
||||||
|
import { NewResource } from "@components/layouts";
|
||||||
|
import { ConfirmButton } from "@components/util";
|
||||||
|
import { useExecute, useRead, useWrite } from "@lib/hooks";
|
||||||
|
import { Types } from "@monitor/client";
|
||||||
|
import { Execution } from "@monitor/client/dist/types";
|
||||||
|
import { RequiredResourceComponents, UsableResource } from "@types";
|
||||||
|
import { Button } from "@ui/button";
|
||||||
|
import { Input } from "@ui/input";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "@ui/select";
|
||||||
|
import { Loader2, Route, Save } from "lucide-react";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
|
||||||
|
const useProcedure = (id?: string) =>
|
||||||
|
useRead("ListProcedures", {}).data?.find((d) => d.id === id);
|
||||||
|
|
||||||
|
const get_default_data = <T extends Types.ProcedureConfig["type"]>(
|
||||||
|
type: T
|
||||||
|
): string[] | Types.Execution => {
|
||||||
|
if (type === "Execution") return { type: "None", params: {} };
|
||||||
|
return [] as string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const NewProcedure = ({ parent }: { parent?: Types.Procedure }) => {
|
||||||
|
const [name, setName] = useState("");
|
||||||
|
const [type, setType] = useState<Types.ProcedureConfig["type"]>("Execution");
|
||||||
|
|
||||||
|
const update_parent = useWrite("UpdateProcedure").mutate;
|
||||||
|
|
||||||
|
const { mutateAsync } = useWrite("CreateProcedure", {
|
||||||
|
onSuccess: ({ _id }) => {
|
||||||
|
if (!parent) return;
|
||||||
|
if (
|
||||||
|
parent.config.type === "Sequence" ||
|
||||||
|
parent.config.type === "Parallel"
|
||||||
|
) {
|
||||||
|
update_parent({
|
||||||
|
id: parent._id?.$oid!,
|
||||||
|
config: {
|
||||||
|
...parent.config,
|
||||||
|
data: [...parent.config.data, _id?.$oid!],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NewResource
|
||||||
|
type="Procedure"
|
||||||
|
onSuccess={() =>
|
||||||
|
mutateAsync({
|
||||||
|
name,
|
||||||
|
config: {
|
||||||
|
type,
|
||||||
|
data: get_default_data(type),
|
||||||
|
} as Types.ProcedureConfig,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
enabled={!!name}
|
||||||
|
>
|
||||||
|
<div className="grid md:grid-cols-2">
|
||||||
|
Procedure Name
|
||||||
|
<Input
|
||||||
|
placeholder="procedure-name"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="grid md:grid-cols-2">
|
||||||
|
Procedure Type
|
||||||
|
<Select
|
||||||
|
value={type}
|
||||||
|
onValueChange={(value) => setType(value as typeof type)}
|
||||||
|
>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Select Type" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectItem value="Execution">Execution</SelectItem>
|
||||||
|
<SelectItem value="Sequence">Sequence</SelectItem>
|
||||||
|
<SelectItem value="Paralell">Paralell</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</NewResource>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
type ExecutionType = Extract<
|
||||||
|
Types.ProcedureConfig,
|
||||||
|
{ type: "Execution" }
|
||||||
|
>["data"]["type"];
|
||||||
|
|
||||||
|
const TypeSelector = ({
|
||||||
|
type,
|
||||||
|
selected,
|
||||||
|
onSelect,
|
||||||
|
}: {
|
||||||
|
type: UsableResource;
|
||||||
|
selected: string;
|
||||||
|
onSelect: (value: string) => void;
|
||||||
|
}) => (
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
{type}
|
||||||
|
<ResourceSelector type={type} selected={selected} onSelect={onSelect} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
// const EXECUTION_TYPES: ExecutionType[] = [
|
||||||
|
// "None",
|
||||||
|
// "CloneRepo",
|
||||||
|
// "Deploy",
|
||||||
|
// "PruneDockerContainers",
|
||||||
|
// "PruneDockerImages",
|
||||||
|
// "PruneDockerNetworks",
|
||||||
|
// "PullRepo",
|
||||||
|
// "RemoveContainer",
|
||||||
|
// "RunBuild",
|
||||||
|
// "RunProcedure",
|
||||||
|
// "StartContainer",
|
||||||
|
// "StopAllContainers",
|
||||||
|
// "StopContainer",
|
||||||
|
// ];
|
||||||
|
|
||||||
|
type ExecutionConfigComponent<
|
||||||
|
T extends ExecutionType,
|
||||||
|
P = Extract<Execution, { type: T }>["params"]
|
||||||
|
> = React.FC<{
|
||||||
|
params: P;
|
||||||
|
setParams: React.Dispatch<React.SetStateAction<P>>;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
type ExecutionConfigParams<T extends ExecutionType> = Extract<
|
||||||
|
Execution,
|
||||||
|
{ type: T }
|
||||||
|
>["params"];
|
||||||
|
|
||||||
|
type ExecutionConfigs = {
|
||||||
|
[ExType in ExecutionType]: {
|
||||||
|
component: ExecutionConfigComponent<ExType>;
|
||||||
|
params: ExecutionConfigParams<ExType>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const EXEC_TYPES: ExecutionConfigs = {
|
||||||
|
None: {
|
||||||
|
params: {},
|
||||||
|
component: () => <></>,
|
||||||
|
},
|
||||||
|
CloneRepo: {
|
||||||
|
params: { id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Repo"
|
||||||
|
selected={params.id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Deploy: {
|
||||||
|
params: { deployment_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Deployment"
|
||||||
|
selected={params.deployment_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, deployment_id: id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
PruneDockerContainers: {
|
||||||
|
params: { server_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Server"
|
||||||
|
selected={params.server_id}
|
||||||
|
onSelect={(server_id) => setParams((p) => ({ ...p, server_id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
PruneDockerImages: {
|
||||||
|
params: { server_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Server"
|
||||||
|
selected={params.server_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
PruneDockerNetworks: {
|
||||||
|
params: { server_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Server"
|
||||||
|
selected={params.server_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
PullRepo: {
|
||||||
|
params: { id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Repo"
|
||||||
|
selected={params.id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
RemoveContainer: {
|
||||||
|
params: { deployment_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Deployment"
|
||||||
|
selected={params.deployment_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, deployment_id: id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
RunBuild: {
|
||||||
|
params: { build_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Build"
|
||||||
|
selected={params.build_id}
|
||||||
|
onSelect={(build_id) => setParams((p) => ({ ...p, build_id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
RunProcedure: {
|
||||||
|
params: { procedure_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Procedure"
|
||||||
|
selected={params.procedure_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, procedure_id: id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
StartContainer: {
|
||||||
|
params: { deployment_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Deployment"
|
||||||
|
selected={params.deployment_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, deployment_id: id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
StopAllContainers: {
|
||||||
|
params: { server_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Server"
|
||||||
|
selected={params.server_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, server_id: id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
StopContainer: {
|
||||||
|
params: { deployment_id: "" },
|
||||||
|
component: ({ params, setParams }) => (
|
||||||
|
<TypeSelector
|
||||||
|
type="Deployment"
|
||||||
|
selected={params.deployment_id}
|
||||||
|
onSelect={(id) => setParams((p) => ({ ...p, deployment_id: id }))}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const UpdateProcedure = ({
|
||||||
|
id,
|
||||||
|
procedure,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
procedure: Types.ProcedureConfig;
|
||||||
|
}) => {
|
||||||
|
const { mutate } = useWrite("UpdateProcedure");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button onClick={() => mutate({ id, config: procedure })}>
|
||||||
|
<Save className="w-4" />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ExecutionConfig = ({ id }: { id: string }) => {
|
||||||
|
const procedure = useRead("GetProcedure", { id }).data;
|
||||||
|
if (procedure?.config.type !== "Execution") return null;
|
||||||
|
|
||||||
|
const [type, setType] = useState<ExecutionType>(procedure.config.data.type);
|
||||||
|
const [params, setParams] = useState(
|
||||||
|
procedure.config.data ?? EXEC_TYPES[type].params
|
||||||
|
);
|
||||||
|
|
||||||
|
const Component = EXEC_TYPES[type].component;
|
||||||
|
|
||||||
|
console.log(params);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-4 border rounded-md flex flex-col gap-4">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
{procedure.name}
|
||||||
|
<UpdateProcedure
|
||||||
|
id={id}
|
||||||
|
procedure={{ type: "Execution", data: { type, params } as Execution }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
Execution Type
|
||||||
|
<Select
|
||||||
|
value={type}
|
||||||
|
onValueChange={(value) => setType(value as typeof type)}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-72">
|
||||||
|
<SelectValue placeholder="Select Type" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent className="w-72">
|
||||||
|
<SelectGroup>
|
||||||
|
{Object.keys(EXEC_TYPES).map((type) => (
|
||||||
|
<SelectItem
|
||||||
|
value={type}
|
||||||
|
className="whitespace-nowrap"
|
||||||
|
key={type}
|
||||||
|
>
|
||||||
|
{type.match(/[A-Z][a-z]+/g)?.join(" ")}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="pt-2 border-t">
|
||||||
|
<Component params={params as any} setParams={setParams as any} />
|
||||||
|
</div>
|
||||||
|
<div className="pt-2 border-t">
|
||||||
|
<pre>{JSON.stringify(procedure?.config, null, 2)}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SequenceConfig = ({ id }: { id: string }) => {
|
||||||
|
const procedure = useRead("GetProcedure", { id }).data;
|
||||||
|
if (procedure?.config.type !== "Sequence") return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-4 border rounded-md flex flex-col gap-4">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
{procedure?.name}
|
||||||
|
<NewProcedure parent={procedure} />
|
||||||
|
</div>
|
||||||
|
<pre>{JSON.stringify(procedure?.config, null, 2)}</pre>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ProcedureConfig = ({ id }: { id: string }) => {
|
||||||
|
const procedure = useRead("GetProcedure", { id }).data;
|
||||||
|
if (procedure?.config.type === "Sequence") return <SequenceConfig id={id} />;
|
||||||
|
if (procedure?.config.type === "Execution")
|
||||||
|
return <ExecutionConfig id={id} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Procedure: RequiredResourceComponents = {
|
||||||
|
Name: ({ id }) => <>{useProcedure(id)?.name}</>,
|
||||||
|
Description: ({ id }) => <>{useProcedure(id)?.info.procedure_type}</>,
|
||||||
|
Info: ({ id }) => <>{id}</>,
|
||||||
|
Icon: () => <Route className="w-4" />,
|
||||||
|
Page: {
|
||||||
|
Config: ({ id }) => <ProcedureConfig id={id} />,
|
||||||
|
},
|
||||||
|
Actions: ({ id }) => {
|
||||||
|
const running = useRead("GetProcedureActionState", { id }).data?.running;
|
||||||
|
const { mutate, isLoading } = useExecute("RunProcedure");
|
||||||
|
return (
|
||||||
|
<ConfirmButton
|
||||||
|
title={running ? "Building" : "Run"}
|
||||||
|
icon={
|
||||||
|
running ? (
|
||||||
|
<Loader2 className="w-4 h-4 animate-spin" />
|
||||||
|
) : (
|
||||||
|
<Route className="h-4 w-4" />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
onClick={() => mutate({ procedure_id: id })}
|
||||||
|
disabled={running || isLoading}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
New: () => <NewProcedure />,
|
||||||
|
};
|
||||||
@@ -34,11 +34,11 @@ export const useRead = <
|
|||||||
(T | P)[]
|
(T | P)[]
|
||||||
>,
|
>,
|
||||||
"queryFn" | "queryKey"
|
"queryFn" | "queryKey"
|
||||||
>,
|
>
|
||||||
>(
|
>(
|
||||||
type: T,
|
type: T,
|
||||||
params: P,
|
params: P,
|
||||||
config?: C,
|
config?: C
|
||||||
) => useQuery([type, params], () => client.read({ type, params } as R), config);
|
) => useQuery([type, params], () => client.read({ type, params } as R), config);
|
||||||
|
|
||||||
export const useWrite = <
|
export const useWrite = <
|
||||||
@@ -48,10 +48,10 @@ export const useWrite = <
|
|||||||
C extends Omit<
|
C extends Omit<
|
||||||
UseMutationOptions<WriteResponses[T], unknown, P, unknown>,
|
UseMutationOptions<WriteResponses[T], unknown, P, unknown>,
|
||||||
"mutationKey" | "mutationFn"
|
"mutationKey" | "mutationFn"
|
||||||
>,
|
>
|
||||||
>(
|
>(
|
||||||
type: T,
|
type: T,
|
||||||
config?: C,
|
config?: C
|
||||||
) =>
|
) =>
|
||||||
useMutation([type], (params: P) => client.write({ type, params } as R), {
|
useMutation([type], (params: P) => client.write({ type, params } as R), {
|
||||||
...config,
|
...config,
|
||||||
@@ -67,10 +67,10 @@ export const useExecute = <
|
|||||||
C extends Omit<
|
C extends Omit<
|
||||||
UseMutationOptions<ExecuteResponses[T], unknown, P, unknown>,
|
UseMutationOptions<ExecuteResponses[T], unknown, P, unknown>,
|
||||||
"mutationKey" | "mutationFn"
|
"mutationKey" | "mutationFn"
|
||||||
>,
|
>
|
||||||
>(
|
>(
|
||||||
type: T,
|
type: T,
|
||||||
config?: C,
|
config?: C
|
||||||
) =>
|
) =>
|
||||||
useMutation([type], (params: P) => client.execute({ type, params } as R), {
|
useMutation([type], (params: P) => client.execute({ type, params } as R), {
|
||||||
...config,
|
...config,
|
||||||
@@ -85,14 +85,10 @@ export const useInvalidate = () => {
|
|||||||
|
|
||||||
return <
|
return <
|
||||||
T extends Types.ReadRequest["type"],
|
T extends Types.ReadRequest["type"],
|
||||||
P = Extract<Types.ReadRequest, { type: T }>["params"],
|
P = Extract<Types.ReadRequest, { type: T }>["params"]
|
||||||
>(
|
>(
|
||||||
...keys: Array<[T] | [T, P]>
|
...keys: Array<[T] | [T, P]>
|
||||||
) =>
|
) => keys.forEach((k) => qc.invalidateQueries([...k]));
|
||||||
keys.forEach((k) => {
|
|
||||||
console.log("invalidating", k);
|
|
||||||
qc.invalidateQueries([...k]);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePushRecentlyViewed = ({ type, id }: Types.ResourceTarget) => {
|
export const usePushRecentlyViewed = ({ type, id }: Types.ResourceTarget) => {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const RESOURCE_TARGETS: UsableResource[] = [
|
|||||||
"Deployment",
|
"Deployment",
|
||||||
"Repo",
|
"Repo",
|
||||||
"Server",
|
"Server",
|
||||||
|
"Procedure",
|
||||||
];
|
];
|
||||||
|
|
||||||
export const fmt_update_date = (d: Date) =>
|
export const fmt_update_date = (d: Date) =>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import "globals.css";
|
import "globals.css";
|
||||||
|
import React from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import { MonitorClient } from "@monitor/client";
|
import { MonitorClient } from "@monitor/client";
|
||||||
import { ThemeProvider } from "@ui/theme";
|
import { ThemeProvider } from "@ui/theme";
|
||||||
@@ -21,7 +22,7 @@ const query_client = new QueryClient({
|
|||||||
});
|
});
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||||
// <React.StrictMode>
|
<React.StrictMode>
|
||||||
<QueryClientProvider client={query_client}>
|
<QueryClientProvider client={query_client}>
|
||||||
<WebsocketProvider url={UPDATE_WS_URL}>
|
<WebsocketProvider url={UPDATE_WS_URL}>
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
@@ -30,5 +31,5 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</WebsocketProvider>
|
</WebsocketProvider>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
// </React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|||||||
13
frontend/src/types.d.ts
vendored
13
frontend/src/types.d.ts
vendored
@@ -2,19 +2,6 @@ import { Types } from "@monitor/client";
|
|||||||
|
|
||||||
export type UsableResource = Exclude<Types.ResourceTarget["type"], "System">;
|
export type UsableResource = Exclude<Types.ResourceTarget["type"], "System">;
|
||||||
|
|
||||||
// export type RequiredComponents =
|
|
||||||
// | "Name"
|
|
||||||
// | "Description"
|
|
||||||
// | "Icon"
|
|
||||||
// | "Info"
|
|
||||||
// | "Actions";
|
|
||||||
|
|
||||||
// export type RequiredResourceComponents = {
|
|
||||||
// [key in RequiredComponents]: React.FC<{ id: string }>;
|
|
||||||
// } & { Page: { [key: string]: React.FC<{ id: string }> } } & {
|
|
||||||
// New: () => React.ReactNode;
|
|
||||||
// };
|
|
||||||
|
|
||||||
type IdComponent = React.FC<{ id: string }>;
|
type IdComponent = React.FC<{ id: string }>;
|
||||||
type OptionalIdComponent = React.FC<{ id?: string }>;
|
type OptionalIdComponent = React.FC<{ id?: string }>;
|
||||||
|
|
||||||
|
|||||||
@@ -1968,10 +1968,10 @@ lru-cache@^6.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
yallist "^4.0.0"
|
yallist "^4.0.0"
|
||||||
|
|
||||||
lucide-react@^0.274.0:
|
lucide-react@^0.285.0:
|
||||||
version "0.274.0"
|
version "0.285.0"
|
||||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.274.0.tgz#d3b54dcb972b12f1292061448d61d422ef2e269d"
|
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.285.0.tgz#2929460f74aeb6b709ef5c1f9fad7cd208cd6507"
|
||||||
integrity sha512-qiWcojRXEwDiSimMX1+arnxha+ROJzZjJaVvCC0rsG6a9pUPjZePXSq7em4ZKMp0NDm1hyzPNkM7UaWC3LU2AA==
|
integrity sha512-TvWtS0Zc2lT0wTMyD+sEB7x9TM/38MQMJfJbQMMWJOsPx+lEaWBk1aKalqhCZj/Vbl2r00Uqln7xTTY2T7R63g==
|
||||||
|
|
||||||
merge2@^1.3.0, merge2@^1.4.1:
|
merge2@^1.3.0, merge2@^1.4.1:
|
||||||
version "1.4.1"
|
version "1.4.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user