mirror of
https://github.com/moghtech/komodo.git
synced 2026-04-29 04:10:01 -05:00
fix the type change
This commit is contained in:
@@ -192,7 +192,7 @@ export const AccountSelector = ({
|
||||
}) => {
|
||||
const request =
|
||||
type === "Server" ? "GetAvailableAccounts" : "GetBuilderAvailableAccounts";
|
||||
const accounts = useRead(request, { id: id! }, { enabled: !!id }).data;
|
||||
const accounts = useRead(request, { server: id! }, { enabled: !!id }).data;
|
||||
return (
|
||||
<ConfigItem label={`${account_type} Account`}>
|
||||
<Select
|
||||
|
||||
@@ -1,189 +1,192 @@
|
||||
import { Section } from "./layouts";
|
||||
import { Loader2, Lock, PlusCircle, User } from "lucide-react";
|
||||
import { useRead, useWrite } from "@lib/hooks";
|
||||
import { UsableResource } from "@types";
|
||||
import { Card, CardHeader, CardTitle } from "@ui/card";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@ui/select";
|
||||
import { Types } from "@monitor/client";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@ui/dialog";
|
||||
import { Button } from "@ui/button";
|
||||
import { useState } from "react";
|
||||
import { ResourceTarget } from "@monitor/client/dist/types";
|
||||
// import { Section } from "./layouts";
|
||||
// import { Loader2, Lock, PlusCircle, User } from "lucide-react";
|
||||
// import { useRead, useWrite } from "@lib/hooks";
|
||||
// import { UsableResource } from "@types";
|
||||
// import { Card, CardHeader, CardTitle } from "@ui/card";
|
||||
// import {
|
||||
// Select,
|
||||
// SelectContent,
|
||||
// SelectGroup,
|
||||
// SelectItem,
|
||||
// SelectTrigger,
|
||||
// SelectValue,
|
||||
// } from "@ui/select";
|
||||
// import { Types } from "@monitor/client";
|
||||
// import {
|
||||
// Dialog,
|
||||
// DialogContent,
|
||||
// DialogFooter,
|
||||
// DialogHeader,
|
||||
// DialogTitle,
|
||||
// DialogTrigger,
|
||||
// } from "@ui/dialog";
|
||||
// import { Button } from "@ui/button";
|
||||
// import { useState } from "react";
|
||||
// import { ResourceTarget } from "@monitor/client/dist/types";
|
||||
|
||||
const Username = ({ user_id }: { user_id: string }) => {
|
||||
const username = useRead("GetUsername", { user_id }).data?.username;
|
||||
return <>{username}</>;
|
||||
};
|
||||
// const Username = ({ user_id }: { user_id: string }) => {
|
||||
// const username = useRead("GetUsername", { user_id }).data?.username;
|
||||
// return <>{username}</>;
|
||||
// };
|
||||
|
||||
const NewPermission = ({ id, type }: ResourceTarget) => {
|
||||
const [open, set] = useState(false);
|
||||
const [user_id, setUserId] = useState<string>();
|
||||
const [permission, setPermission] = useState<Types.PermissionLevel>();
|
||||
const users = useRead("GetUsers", {}).data?.filter((u) => !u.admin);
|
||||
const { mutate, isPending } = useWrite("UpdateUserPermissionsOnTarget");
|
||||
// const NewPermission = ({ id, type }: ResourceTarget) => {
|
||||
// const [open, set] = useState(false);
|
||||
// const [user_id, setUserId] = useState<string>();
|
||||
// const [permission, setPermission] = useState<Types.PermissionLevel>();
|
||||
// const users = useRead("GetUsers", {}).data?.filter((u) => !u.admin);
|
||||
// const { mutate, isPending } = useWrite("UpdateUserPermissionsOnTarget");
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={set}>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="gap-2">
|
||||
Add Permission
|
||||
<PlusCircle className="w-4 h-4" />
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Add User</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="grid gap-4 my-4">
|
||||
<div className="flex items-center justify-between">
|
||||
User
|
||||
<Select value={user_id} onValueChange={setUserId}>
|
||||
<SelectTrigger className="w-48">
|
||||
<SelectValue placeholder="Select User" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="w-48">
|
||||
<SelectGroup>
|
||||
{users?.map((user) => (
|
||||
<SelectItem key={user._id?.$oid} value={user._id!.$oid}>
|
||||
{user.username}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
Permissions Level
|
||||
<Select
|
||||
value={permission}
|
||||
onValueChange={(lv: any) => setPermission(lv as Types.PermissionLevel)}
|
||||
>
|
||||
<SelectTrigger className="w-48">
|
||||
<SelectValue placeholder="Select Permission Level" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="w-48">
|
||||
<SelectGroup>
|
||||
<SelectItem value={Types.PermissionLevel.Read}>
|
||||
Read
|
||||
</SelectItem>
|
||||
<SelectItem value={Types.PermissionLevel.Update}>
|
||||
Update
|
||||
</SelectItem>
|
||||
<SelectItem value={Types.PermissionLevel.Execute}>
|
||||
Execute
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter className="flex justify-end">
|
||||
<Button
|
||||
className="gap-2"
|
||||
disabled={isPending}
|
||||
onClick={() =>
|
||||
permission &&
|
||||
user_id &&
|
||||
mutate({ permission, user_id, target: { id, type } })
|
||||
}
|
||||
>
|
||||
Add Permissions
|
||||
{isPending ? (
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
) : (
|
||||
<PlusCircle className="w-4 h-4" />
|
||||
)}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
// return (
|
||||
// <Dialog open={open} onOpenChange={set}>
|
||||
// <DialogTrigger asChild>
|
||||
// <Button className="gap-2">
|
||||
// Add Permission
|
||||
// <PlusCircle className="w-4 h-4" />
|
||||
// </Button>
|
||||
// </DialogTrigger>
|
||||
// <DialogContent>
|
||||
// <DialogHeader>
|
||||
// <DialogTitle>Add User</DialogTitle>
|
||||
// </DialogHeader>
|
||||
// <div className="grid gap-4 my-4">
|
||||
// <div className="flex items-center justify-between">
|
||||
// User
|
||||
// <Select value={user_id} onValueChange={setUserId}>
|
||||
// <SelectTrigger className="w-48">
|
||||
// <SelectValue placeholder="Select User" />
|
||||
// </SelectTrigger>
|
||||
// <SelectContent className="w-48">
|
||||
// <SelectGroup>
|
||||
// {users?.map((user) => (
|
||||
// <SelectItem key={user._id?.$oid} value={user._id!.$oid}>
|
||||
// {user.username}
|
||||
// </SelectItem>
|
||||
// ))}
|
||||
// </SelectGroup>
|
||||
// </SelectContent>
|
||||
// </Select>
|
||||
// </div>
|
||||
// <div className="flex items-center justify-between">
|
||||
// Permissions Level
|
||||
// <Select
|
||||
// value={permission}
|
||||
// onValueChange={(lv: any) =>
|
||||
// setPermission(lv as Types.PermissionLevel)
|
||||
// }
|
||||
// >
|
||||
// <SelectTrigger className="w-48">
|
||||
// <SelectValue placeholder="Select Permission Level" />
|
||||
// </SelectTrigger>
|
||||
// <SelectContent className="w-48">
|
||||
// <SelectGroup>
|
||||
// <SelectItem value={Types.PermissionLevel.Read}>
|
||||
// Read
|
||||
// </SelectItem>
|
||||
// <SelectItem value={Types.PermissionLevel.Execute}>
|
||||
// Execute
|
||||
// </SelectItem>
|
||||
// <SelectItem value={Types.PermissionLevel.Write}>
|
||||
// Write
|
||||
// </SelectItem>
|
||||
// </SelectGroup>
|
||||
// </SelectContent>
|
||||
// </Select>
|
||||
// </div>
|
||||
// </div>
|
||||
// <DialogFooter className="flex justify-end">
|
||||
// <Button
|
||||
// className="gap-2"
|
||||
// disabled={isPending}
|
||||
// onClick={() =>
|
||||
// permission &&
|
||||
// user_id &&
|
||||
// mutate({ permission, user_id, target: { id, type } })
|
||||
// }
|
||||
// >
|
||||
// Add Permissions
|
||||
// {isPending ? (
|
||||
// <Loader2 className="w-4 h-4 animate-spin" />
|
||||
// ) : (
|
||||
// <PlusCircle className="w-4 h-4" />
|
||||
// )}
|
||||
// </Button>
|
||||
// </DialogFooter>
|
||||
// </DialogContent>
|
||||
// </Dialog>
|
||||
// );
|
||||
// };
|
||||
|
||||
export const ResourcePermissions = ({
|
||||
type,
|
||||
id,
|
||||
}: {
|
||||
type: UsableResource;
|
||||
id: string;
|
||||
}) => {
|
||||
const admin = useRead("GetUser", {}).data?.admin;
|
||||
const me = useRead("GetUser", {}).data?._id?.$oid;
|
||||
const permissions = useRead(`Get${type}`, { id }, { enabled: admin }).data
|
||||
?.permissions;
|
||||
// // export const ResourcePermissions = ({
|
||||
// // type,
|
||||
// // id,
|
||||
// // }: {
|
||||
// // type: UsableResource;
|
||||
// // id: string;
|
||||
// // }) => {
|
||||
// // const user = useRead("GetUser", {}).data;
|
||||
// // const admin = user?.admin;
|
||||
// // const me = user?._id?.$oid;
|
||||
// // const permissions = useRead(`Get${type}`, { id }, { enabled: admin }).data
|
||||
// // ?.permissions;
|
||||
|
||||
const users = useRead("GetUsers", {}).data?.filter((u) => !u.admin);
|
||||
// // const users = useRead("GetUsers", {}).data?.filter((u) => !u.admin);
|
||||
|
||||
const { mutate: update, isPending } = useWrite(
|
||||
"UpdateUserPermissionsOnTarget"
|
||||
);
|
||||
// // const { mutate: update, isPending } = useWrite(
|
||||
// // "UpdateUserPermissionsOnTarget"
|
||||
// // );
|
||||
|
||||
const display = Object.keys(permissions ?? {})
|
||||
.filter((id) => id != me)
|
||||
.filter((id) => !users?.find((u) => u._id?.$oid === id)?.admin);
|
||||
// // const display = Object.keys(permissions ?? {})
|
||||
// // .filter((id) => id != me)
|
||||
// // .filter((id) => !users?.find((u) => u._id?.$oid === id)?.admin);
|
||||
|
||||
if (!admin || !display.length) return null;
|
||||
// // if (!admin || !display.length) return null;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title="Permissions"
|
||||
icon={<Lock className="w-4 h-4" />}
|
||||
actions={<NewPermission id={id} type={type} />}
|
||||
>
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{display.map((user_id) => (
|
||||
<Card key={user_id}>
|
||||
<CardHeader className="justify-between">
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<User className="w-4 h-4" />
|
||||
<Username user_id={user_id} />
|
||||
</CardTitle>
|
||||
<Select
|
||||
value={permissions?.[user_id]}
|
||||
onValueChange={(p: any) =>
|
||||
update({
|
||||
permission: p as Types.PermissionLevel,
|
||||
user_id,
|
||||
target: { type, id },
|
||||
})
|
||||
}
|
||||
disabled={isPending}
|
||||
>
|
||||
<SelectTrigger className="w-32">
|
||||
<SelectValue placeholder="Set Permissions" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="w-32">
|
||||
<SelectGroup>
|
||||
<SelectItem value={Types.PermissionLevel.Read}>
|
||||
Read
|
||||
</SelectItem>
|
||||
<SelectItem value={Types.PermissionLevel.Update}>
|
||||
Update
|
||||
</SelectItem>
|
||||
<SelectItem value={Types.PermissionLevel.Execute}>
|
||||
Execute
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
// // return (
|
||||
// // <Section
|
||||
// // title="Permissions"
|
||||
// // icon={<Lock className="w-4 h-4" />}
|
||||
// // actions={<NewPermission id={id} type={type} />}
|
||||
// // >
|
||||
// // <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
// // {display.map((user_id) => (
|
||||
// // <Card key={user_id}>
|
||||
// // <CardHeader className="justify-between">
|
||||
// // <CardTitle className="flex items-center gap-2">
|
||||
// // <User className="w-4 h-4" />
|
||||
// // <Username user_id={user_id} />
|
||||
// // </CardTitle>
|
||||
// // <Select
|
||||
// // value={permissions?.[user_id]}
|
||||
// // onValueChange={(p: any) =>
|
||||
// // update({
|
||||
// // permission: p as Types.PermissionLevel,
|
||||
// // user_id,
|
||||
// // target: { type, id },
|
||||
// // })
|
||||
// // }
|
||||
// // disabled={isPending}
|
||||
// // >
|
||||
// // <SelectTrigger className="w-32">
|
||||
// // <SelectValue placeholder="Set Permissions" />
|
||||
// // </SelectTrigger>
|
||||
// // <SelectContent className="w-32">
|
||||
// // <SelectGroup>
|
||||
// // <SelectItem value={Types.PermissionLevel.Read}>
|
||||
// // Read
|
||||
// // </SelectItem>
|
||||
// // <SelectItem value={Types.PermissionLevel.Update}>
|
||||
// // Update
|
||||
// // </SelectItem>
|
||||
// // <SelectItem value={Types.PermissionLevel.Execute}>
|
||||
// // Execute
|
||||
// // </SelectItem>
|
||||
// // </SelectGroup>
|
||||
// // </SelectContent>
|
||||
// // </Select>
|
||||
// // </CardHeader>
|
||||
// // </Card>
|
||||
// // ))}
|
||||
// // </div>
|
||||
// // </Section>
|
||||
// // );
|
||||
// // };
|
||||
|
||||
@@ -66,7 +66,7 @@ const NewAlerter = () => {
|
||||
};
|
||||
|
||||
const SlackAlerterConfig = ({ id }: { id: string }) => {
|
||||
const config = useRead("GetAlerter", { id }).data?.config;
|
||||
const config = useRead("GetAlerter", { alerter: id }).data?.config;
|
||||
const [update, set] = useState<Partial<Types.SlackAlerterConfig>>({});
|
||||
const { mutate } = useWrite("UpdateAlerter");
|
||||
if (!config) return null;
|
||||
@@ -89,7 +89,7 @@ const SlackAlerterConfig = ({ id }: { id: string }) => {
|
||||
};
|
||||
|
||||
const CustomAlerterConfig = ({ id }: { id: string }) => {
|
||||
const config = useRead("GetAlerter", { id }).data?.config;
|
||||
const config = useRead("GetAlerter", { alerter: id }).data?.config;
|
||||
const [update, set] = useState<Partial<Types.CustomAlerterConfig>>({});
|
||||
const { mutate } = useWrite("UpdateAlerter");
|
||||
if (!config) return null;
|
||||
@@ -165,7 +165,7 @@ export const AlerterComponents: RequiredResourceComponents = {
|
||||
Info: ({ id }) => <>{id}</>,
|
||||
Page: {
|
||||
Config: ({ id }: { id: string }) => {
|
||||
const config = useRead("GetAlerter", { id }).data?.config;
|
||||
const config = useRead("GetAlerter", { alerter: id }).data?.config;
|
||||
if (config?.type === "Slack") return <SlackAlerterConfig id={id} />;
|
||||
if (config?.type === "Custom") return <CustomAlerterConfig id={id} />;
|
||||
},
|
||||
|
||||
@@ -75,7 +75,7 @@ export const BuildArgs = ({
|
||||
};
|
||||
|
||||
export const BuildConfig = ({ id }: { id: string }) => {
|
||||
const config = useRead("GetBuild", { id }).data?.config;
|
||||
const config = useRead("GetBuild", { build: id }).data?.config;
|
||||
// const orgs = useRead("GetAccounts")
|
||||
const [update, set] = useState<Partial<Types.BuildConfig>>({});
|
||||
const { mutate } = useWrite("UpdateBuild");
|
||||
@@ -147,7 +147,7 @@ export const BuildConfig = ({ id }: { id: string }) => {
|
||||
const Name = ({ id }: { id: string }) => <>{useBuild(id)?.name}</>;
|
||||
|
||||
const Icon = ({ id }: { id: string }) => {
|
||||
const building = useRead("GetBuildActionState", { id }).data?.building;
|
||||
const building = useRead("GetBuildActionState", { build: id }).data?.building;
|
||||
const className = building
|
||||
? "w-4 h-4 animate-spin fill-green-500"
|
||||
: "w-4 h-4";
|
||||
@@ -244,7 +244,7 @@ export const BuildComponents: RequiredResourceComponents = {
|
||||
},
|
||||
Actions: ({ id }) => {
|
||||
const { toast } = useToast();
|
||||
const building = useRead("GetBuildActionState", { id }).data?.building;
|
||||
const building = useRead("GetBuildActionState", { build: id }).data?.building;
|
||||
const { mutate: run_mutate, isPending: runPending } = useExecute(
|
||||
"RunBuild",
|
||||
{
|
||||
@@ -270,7 +270,7 @@ export const BuildComponents: RequiredResourceComponents = {
|
||||
title="Cancel Build"
|
||||
variant="destructive"
|
||||
icon={<Ban className="h-4 w-4" />}
|
||||
onClick={() => cancel_mutate({ build_id: id })}
|
||||
onClick={() => cancel_mutate({ build: id })}
|
||||
disabled={cancelPending}
|
||||
/>
|
||||
);
|
||||
@@ -285,7 +285,7 @@ export const BuildComponents: RequiredResourceComponents = {
|
||||
<Hammer className="h-4 w-4" />
|
||||
)
|
||||
}
|
||||
onClick={() => run_mutate({ build_id: id })}
|
||||
onClick={() => run_mutate({ build: id })}
|
||||
disabled={runPending}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ const useBuilder = (id?: string) =>
|
||||
useRead("ListBuilders", {}).data?.find((d) => d.id === id);
|
||||
|
||||
const AwsBuilderConfig = ({ id }: { id: string }) => {
|
||||
const config = useRead("GetBuilder", { id }).data?.config;
|
||||
const config = useRead("GetBuilder", { builder: id }).data?.config;
|
||||
const [update, set] = useState<Partial<Types.AwsBuilderConfig>>({});
|
||||
const { mutate } = useWrite("UpdateBuilder");
|
||||
if (!config) return null;
|
||||
@@ -72,7 +72,7 @@ const AwsBuilderConfig = ({ id }: { id: string }) => {
|
||||
};
|
||||
|
||||
const ServerBuilderConfig = ({ id }: { id: string }) => {
|
||||
const config = useRead("GetBuilder", { id }).data?.config;
|
||||
const config = useRead("GetBuilder", { builder: id }).data?.config;
|
||||
const [update, set] = useState<Partial<Types.ServerBuilderConfig>>({});
|
||||
const { mutate } = useWrite("UpdateBuilder");
|
||||
if (!config) return null;
|
||||
@@ -224,7 +224,7 @@ export const BuilderComponents: RequiredResourceComponents = {
|
||||
Icon: () => <Factory className="w-4 h-4" />,
|
||||
Page: {
|
||||
Config: ({ id }) => {
|
||||
const config = useRead("GetBuilder", { id }).data?.config;
|
||||
const config = useRead("GetBuilder", { builder: id }).data?.config;
|
||||
if (config?.type === "Aws") return <AwsBuilderConfig id={id} />;
|
||||
if (config?.type === "Server") return <ServerBuilderConfig id={id} />;
|
||||
},
|
||||
|
||||
@@ -19,14 +19,15 @@ export const RedeployContainer = ({ id }: DeploymentId) => {
|
||||
const { mutate, isPending } = useExecute("Deploy");
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const deployment = deployments?.find((d) => d.id === id);
|
||||
const deploying = useRead("GetDeploymentActionState", { id }).data?.deploying;
|
||||
const deploying = useRead("GetDeploymentActionState", { deployment: id }).data
|
||||
?.deploying;
|
||||
|
||||
return (
|
||||
<ConfirmButton
|
||||
title={deployment?.info.status ? "Redeploy" : "Deploy"}
|
||||
// intent="success"
|
||||
icon={<Rocket className="h-4 w-4" />}
|
||||
onClick={() => mutate({ deployment_id: id })}
|
||||
onClick={() => mutate({ deployment: id })}
|
||||
disabled={isPending}
|
||||
loading={deploying}
|
||||
/>
|
||||
@@ -34,10 +35,10 @@ export const RedeployContainer = ({ id }: DeploymentId) => {
|
||||
};
|
||||
|
||||
const StartContainer = ({ id }: DeploymentId) => {
|
||||
const { data: d } = useRead("GetDeployment", { id });
|
||||
const { data: d } = useRead("GetDeployment", { deployment: id });
|
||||
const { mutate, isPending } = useExecute("StartContainer");
|
||||
const starting = useRead("GetDeploymentActionState", {
|
||||
id,
|
||||
deployment: id,
|
||||
}).data?.starting;
|
||||
|
||||
if (!d) return null;
|
||||
@@ -47,7 +48,7 @@ const StartContainer = ({ id }: DeploymentId) => {
|
||||
title="Start"
|
||||
// intent="success"
|
||||
icon={<Play className="h-4 w-4" />}
|
||||
onClick={() => mutate({ deployment_id: id })}
|
||||
onClick={() => mutate({ deployment: id })}
|
||||
disabled={isPending}
|
||||
loading={starting}
|
||||
/>
|
||||
@@ -55,10 +56,10 @@ const StartContainer = ({ id }: DeploymentId) => {
|
||||
};
|
||||
|
||||
const StopContainer = ({ id }: DeploymentId) => {
|
||||
const { data: d } = useRead("GetDeployment", { id });
|
||||
const { data: d } = useRead("GetDeployment", { deployment: id });
|
||||
const { mutate, isPending } = useExecute("StopContainer");
|
||||
const stopping = useRead("GetDeploymentActionState", {
|
||||
id,
|
||||
deployment: id,
|
||||
}).data?.stopping;
|
||||
|
||||
if (!d) return null;
|
||||
@@ -68,7 +69,7 @@ const StopContainer = ({ id }: DeploymentId) => {
|
||||
title="Stop"
|
||||
// intent="warning"
|
||||
icon={<Pause className="h-4 w-4" />}
|
||||
onClick={() => mutate({ deployment_id: id })}
|
||||
onClick={() => mutate({ deployment: id })}
|
||||
disabled={isPending}
|
||||
loading={stopping}
|
||||
/>
|
||||
@@ -88,14 +89,14 @@ export const StartOrStopContainer = ({ id }: DeploymentId) => {
|
||||
};
|
||||
|
||||
export const RemoveContainer = ({ id }: DeploymentId) => {
|
||||
const deployment = useRead("GetDeployment", { id }).data;
|
||||
const deployment = useRead("GetDeployment", { deployment: id }).data;
|
||||
const { mutate, isPending } = useExecute("RemoveContainer");
|
||||
|
||||
const deployments = useRead("ListDeployments", {}).data;
|
||||
const state = deployments?.find((d) => d.id === id)?.info.state;
|
||||
|
||||
const removing = useRead("GetDeploymentActionState", {
|
||||
id,
|
||||
deployment: id,
|
||||
}).data?.removing;
|
||||
|
||||
if (!deployment) return null;
|
||||
@@ -107,7 +108,7 @@ export const RemoveContainer = ({ id }: DeploymentId) => {
|
||||
title="Remove"
|
||||
// intent="warning"
|
||||
icon={<Trash className="h-4 w-4" />}
|
||||
onClick={() => mutate({ deployment_id: id })}
|
||||
onClick={() => mutate({ deployment: id })}
|
||||
disabled={isPending}
|
||||
loading={removing}
|
||||
/>
|
||||
@@ -116,10 +117,10 @@ export const RemoveContainer = ({ id }: DeploymentId) => {
|
||||
|
||||
export const DeleteDeployment = ({ id }: { id: string }) => {
|
||||
const nav = useNavigate();
|
||||
const { data: d } = useRead("GetDeployment", { id });
|
||||
const { data: d } = useRead("GetDeployment", { deployment: id });
|
||||
const { mutateAsync, isPending } = useWrite("DeleteDeployment");
|
||||
|
||||
const deleting = useRead("GetDeploymentActionState", { id }).data?.deleting;
|
||||
const deleting = useRead("GetDeploymentActionState", { deployment: id }).data?.deleting;
|
||||
|
||||
if (!d) return null;
|
||||
return (
|
||||
|
||||
@@ -23,7 +23,7 @@ const BuildVersionSelector = ({
|
||||
}) => {
|
||||
const versions = useRead(
|
||||
"GetBuildVersions",
|
||||
{ id: buildId! },
|
||||
{ build: buildId! },
|
||||
{ enabled: !!buildId }
|
||||
).data;
|
||||
return (
|
||||
|
||||
@@ -19,7 +19,7 @@ export const NetworkModeSelector = ({
|
||||
}) => {
|
||||
const networks = useRead(
|
||||
"GetDockerNetworks",
|
||||
{ server_id: server_id! },
|
||||
{ server: server_id! },
|
||||
{ enabled: !!server_id }
|
||||
).data;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export const DeploymentLogs = ({ id }: { id: string }) => {
|
||||
|
||||
const { data: logs, refetch } = useRead(
|
||||
"GetLog",
|
||||
{ deployment_id: id, tail: Number(tail) },
|
||||
{ deployment: id, tail: Number(tail) },
|
||||
{ refetchInterval: 30000 }
|
||||
);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { BuilderComponents } from "./builder";
|
||||
import { DeploymentComponents } from "./deployment";
|
||||
import { RepoComponents } from "./repo";
|
||||
import { ServerComponents } from "./server";
|
||||
import { ProcedureComponents } from "./procedure";
|
||||
import { ProcedureComponents } from "./procedure/index";
|
||||
|
||||
export const ResourceComponents: {
|
||||
[key in UsableResource]: RequiredResourceComponents;
|
||||
|
||||
@@ -1,413 +1,30 @@
|
||||
import { ResourceSelector } from "@components/config/util";
|
||||
import { NewResource } from "@components/layouts";
|
||||
import { TagsWithBadge } from "@components/tags";
|
||||
import { ConfirmButton } from "@components/util";
|
||||
import { useExecute, useRead, useWrite } from "@lib/hooks";
|
||||
import { useExecute, useRead } from "@lib/hooks";
|
||||
import { fmt_date_with_minutes } from "@lib/utils";
|
||||
import { Types } from "@monitor/client";
|
||||
import { Execution } from "@monitor/client/dist/types";
|
||||
import { Icon } from "@radix-ui/react-select";
|
||||
import { RequiredResourceComponents, UsableResource } from "@types";
|
||||
import { Button } from "@ui/button";
|
||||
import { RequiredResourceComponents } from "@types";
|
||||
import { Card, CardDescription, CardHeader, CardTitle } from "@ui/card";
|
||||
import { DataTable } from "@ui/data-table";
|
||||
import { Input } from "@ui/input";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@ui/select";
|
||||
import { Loader2, Route, Save } from "lucide-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link, Loader2, Route } from "lucide-react";
|
||||
|
||||
const useProcedure = (id?: string) =>
|
||||
useRead("ListProcedures", {}).data?.find((d) => d.id === id);
|
||||
|
||||
const Name = ({ id }: { id: string }) => <>{useProcedure(id)?.name}</>;
|
||||
|
||||
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?._id?.$oid || !_id?.$oid) return;
|
||||
if (
|
||||
parent.config.type === "Sequence" ||
|
||||
parent.config.type === "Parallel"
|
||||
) {
|
||||
update_parent({
|
||||
id: parent._id.$oid,
|
||||
config: {
|
||||
...parent.config,
|
||||
data: [...parent.config.data, { enabled: true, id: _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"];
|
||||
|
||||
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 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 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;
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const [type, setType] = useState<ExecutionType>(procedure.config.data.type);
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const [params, setParams] = useState(procedure.config.data.params);
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
useEffect(() => {
|
||||
if (procedure?.config.type !== "Execution") return;
|
||||
if (type !== procedure.config.data.type) {
|
||||
setParams(EXEC_TYPES[type].params);
|
||||
}
|
||||
}, [procedure, type]);
|
||||
|
||||
const Component = EXEC_TYPES[type].component;
|
||||
|
||||
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">
|
||||
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
|
||||
<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>
|
||||
{procedure.config.data.map((p) => (
|
||||
<ProcedureConfig id={p.id} key={p.id} />
|
||||
))}
|
||||
</div>
|
||||
</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 ProcedureDashboard = () => {
|
||||
const procedure_count = useRead("ListProcedures", {}).data?.length;
|
||||
return (
|
||||
<Link to="/procedures/" className="w-full">
|
||||
<Card>
|
||||
<CardHeader className="justify-between">
|
||||
<div>
|
||||
<CardTitle>Procedures</CardTitle>
|
||||
<CardDescription>{procedure_count} Total</CardDescription>
|
||||
</div>
|
||||
<Route className="w-4 h-4" />
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export const ProcedureComponents: 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} />,
|
||||
// Config: ({ id }) => <ProcedureConfig id={id} />,
|
||||
},
|
||||
Actions: ({ id }) => {
|
||||
const running = useRead("GetProcedureActionState", { id }).data?.running;
|
||||
const running = useRead("GetProcedureActionState", { procedure: id }).data
|
||||
?.running;
|
||||
const { mutate, isPending } = useExecute("RunProcedure");
|
||||
return (
|
||||
<ConfirmButton
|
||||
title={running ? "Building" : "Run"}
|
||||
title={running ? "Running" : "Run"}
|
||||
icon={
|
||||
running ? (
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
@@ -415,16 +32,16 @@ export const ProcedureComponents: RequiredResourceComponents = {
|
||||
<Route className="h-4 w-4" />
|
||||
)
|
||||
}
|
||||
onClick={() => mutate({ procedure_id: id })}
|
||||
onClick={() => mutate({ procedure: id })}
|
||||
disabled={running || isPending}
|
||||
/>
|
||||
);
|
||||
},
|
||||
Table: () => {
|
||||
const alerters = useRead("ListAlerters", {}).data;
|
||||
const procedures = useRead("ListProcedures", {}).data;
|
||||
return (
|
||||
<DataTable
|
||||
data={alerters ?? []}
|
||||
data={procedures ?? []}
|
||||
columns={[
|
||||
{
|
||||
accessorKey: "id",
|
||||
@@ -436,13 +53,22 @@ export const ProcedureComponents: RequiredResourceComponents = {
|
||||
to={`/procedures/${id}`}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<Icon id={id} />
|
||||
<Name id={id} />
|
||||
<ProcedureComponents.Icon id={id} />
|
||||
<ProcedureComponents.Name id={id} />
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
},
|
||||
{ header: "Tags", accessorFn: ({ tags }) => tags.join(", ") },
|
||||
{
|
||||
header: "Tags",
|
||||
cell: ({ row }) => {
|
||||
return (
|
||||
<div className="flex gap-1">
|
||||
<TagsWithBadge tag_ids={row.original.tags} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: "Created",
|
||||
accessorFn: ({ created_at }) =>
|
||||
@@ -452,6 +78,21 @@ export const ProcedureComponents: RequiredResourceComponents = {
|
||||
/>
|
||||
);
|
||||
},
|
||||
New: () => <NewProcedure />,
|
||||
Dashboard: ProcedureDashboard,
|
||||
New: () => <></>,
|
||||
Dashboard: () => {
|
||||
const procedure_count = useRead("ListProcedures", {}).data?.length;
|
||||
return (
|
||||
<Link to="/procedures/" className="w-full">
|
||||
<Card>
|
||||
<CardHeader className="justify-between">
|
||||
<div>
|
||||
<CardTitle>Procedures</CardTitle>
|
||||
<CardDescription>{procedure_count} Total</CardDescription>
|
||||
</div>
|
||||
<Route className="w-4 h-4" />
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
450
frontend/src/components/resources/procedure/index2.tsx
Normal file
450
frontend/src/components/resources/procedure/index2.tsx
Normal file
@@ -0,0 +1,450 @@
|
||||
// import { ResourceSelector } from "@components/config/util";
|
||||
// import { NewResource } from "@components/layouts";
|
||||
// import { ConfirmButton } from "@components/util";
|
||||
// import { useExecute, useRead, useWrite } from "@lib/hooks";
|
||||
// import { fmt_date_with_minutes } from "@lib/utils";
|
||||
// import { Types } from "@monitor/client";
|
||||
// import { Execution } from "@monitor/client/dist/types";
|
||||
// import { Icon } from "@radix-ui/react-select";
|
||||
// import { RequiredResourceComponents, UsableResource } from "@types";
|
||||
// import { Button } from "@ui/button";
|
||||
// import { Card, CardDescription, CardHeader, CardTitle } from "@ui/card";
|
||||
// import { DataTable } from "@ui/data-table";
|
||||
// import { Input } from "@ui/input";
|
||||
// import {
|
||||
// Select,
|
||||
// SelectContent,
|
||||
// SelectGroup,
|
||||
// SelectItem,
|
||||
// SelectTrigger,
|
||||
// SelectValue,
|
||||
// } from "@ui/select";
|
||||
// import { Loader2, Route, Save } from "lucide-react";
|
||||
// import React, { useEffect, useState } from "react";
|
||||
// import { Link } from "react-router-dom";
|
||||
|
||||
// const useProcedure = (id?: string) =>
|
||||
// useRead("ListProcedures", {}).data?.find((d) => d.id === id);
|
||||
|
||||
// const Name = ({ id }: { id: string }) => <>{useProcedure(id)?.name}</>;
|
||||
|
||||
// // 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?._id?.$oid || !_id?.$oid) return;
|
||||
// // if (
|
||||
// // parent.config.type === "Sequence" ||
|
||||
// // parent.config.type === "Parallel"
|
||||
// // ) {
|
||||
// // update_parent({
|
||||
// // id: parent._id.$oid,
|
||||
// // config: {
|
||||
// // ...parent.config,
|
||||
// // data: [...parent.config.data, { enabled: true, id: _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"];
|
||||
|
||||
// // 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 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 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;
|
||||
|
||||
// // // eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
// // const [type, setType] = useState<ExecutionType>(procedure.config.data.type);
|
||||
|
||||
// // // eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
// // const [params, setParams] = useState(procedure.config.data.params);
|
||||
|
||||
// // // eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
// // useEffect(() => {
|
||||
// // if (procedure?.config.type !== "Execution") return;
|
||||
// // if (type !== procedure.config.data.type) {
|
||||
// // setParams(EXEC_TYPES[type].params);
|
||||
// // }
|
||||
// // }, [procedure, type]);
|
||||
|
||||
// // const Component = EXEC_TYPES[type].component;
|
||||
|
||||
// // 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">
|
||||
// // {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
|
||||
// // <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>
|
||||
// // {procedure.config.data.map((p) => (
|
||||
// // <ProcedureConfig id={p.id} key={p.id} />
|
||||
// // ))}
|
||||
// // </div>
|
||||
// // </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 ProcedureDashboard = () => {
|
||||
// const procedure_count = useRead("ListProcedures", {}).data?.length;
|
||||
// return (
|
||||
// <Link to="/procedures/" className="w-full">
|
||||
// <Card>
|
||||
// <CardHeader className="justify-between">
|
||||
// <div>
|
||||
// <CardTitle>Procedures</CardTitle>
|
||||
// <CardDescription>{procedure_count} Total</CardDescription>
|
||||
// </div>
|
||||
// <Route className="w-4 h-4" />
|
||||
// </CardHeader>
|
||||
// </Card>
|
||||
// </Link>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export const ProcedureComponents: 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", { procedure: id }).data?.running;
|
||||
// const { mutate, isPending } = 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 })}
|
||||
// disabled={running || isPending}
|
||||
// />
|
||||
// );
|
||||
// },
|
||||
// Table: () => {
|
||||
// const alerters = useRead("ListAlerters", {}).data;
|
||||
// return (
|
||||
// <DataTable
|
||||
// data={alerters ?? []}
|
||||
// columns={[
|
||||
// {
|
||||
// accessorKey: "id",
|
||||
// header: "Name",
|
||||
// cell: ({ row }) => {
|
||||
// const id = row.original.id;
|
||||
// return (
|
||||
// <Link
|
||||
// to={`/procedures/${id}`}
|
||||
// className="flex items-center gap-2"
|
||||
// >
|
||||
// <Icon id={id} />
|
||||
// <Name id={id} />
|
||||
// </Link>
|
||||
// );
|
||||
// },
|
||||
// },
|
||||
// { header: "Tags", accessorFn: ({ tags }) => tags.join(", ") },
|
||||
// {
|
||||
// header: "Created",
|
||||
// accessorFn: ({ created_at }) =>
|
||||
// fmt_date_with_minutes(new Date(created_at)),
|
||||
// },
|
||||
// ]}
|
||||
// />
|
||||
// );
|
||||
// },
|
||||
// New: () => <NewProcedure />,
|
||||
// Dashboard: ProcedureDashboard,
|
||||
// };
|
||||
@@ -39,7 +39,7 @@ export const RepoComponents: RequiredResourceComponents = {
|
||||
Icon: () => <GitBranch className="w-4 h-4" />,
|
||||
Page: {
|
||||
Config: ({ id }) => {
|
||||
const config = useRead("GetRepo", { id }).data?.config;
|
||||
const config = useRead("GetRepo", { repo: id }).data?.config;
|
||||
const [update, set] = useState<Partial<Types.RepoConfig>>({});
|
||||
const mutate = useWrite("UpdateRepo");
|
||||
if (!config) return null;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useNavigate } from "react-router-dom";
|
||||
|
||||
export const DeleteServer = ({ id }: { id: string }) => {
|
||||
const nav = useNavigate();
|
||||
const server = useRead("GetServer", { id }).data;
|
||||
const server = useRead("GetServer", { server: id }).data;
|
||||
const { mutateAsync, isPending } = useWrite("DeleteServer");
|
||||
|
||||
if (!server) return null;
|
||||
|
||||
@@ -37,12 +37,12 @@ export const ServerInfo = ({
|
||||
const server = useServer(id);
|
||||
const stats = useRead(
|
||||
"GetBasicSystemStats",
|
||||
{ server_id: id },
|
||||
{ server: id },
|
||||
{ enabled: server ? server.info.status !== "Disabled" : false }
|
||||
).data;
|
||||
const info = useRead(
|
||||
"GetSystemInformation",
|
||||
{ server_id: id },
|
||||
{ server: id },
|
||||
{ enabled: server ? server.info.status !== "Disabled" : false }
|
||||
).data;
|
||||
return (
|
||||
@@ -84,7 +84,7 @@ export const ServerIconComponent = ({ id }: { id?: string }) => {
|
||||
|
||||
const ServerConfig = ({ id }: { id: string }) => {
|
||||
const invalidate = useInvalidate();
|
||||
const config = useRead("GetServer", { id }).data?.config;
|
||||
const config = useRead("GetServer", { server: id }).data?.config;
|
||||
const [update, set] = useState<Partial<Types.ServerConfig>>({});
|
||||
const { mutate } = useWrite("UpdateServer", {
|
||||
onSuccess: () => {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { Types } from "@monitor/client";
|
||||
export const ServerStats = ({ server_id }: { server_id: string }) => {
|
||||
const stats = useRead(
|
||||
"GetAllSystemStats",
|
||||
{ server_id },
|
||||
{ server: server_id },
|
||||
{ refetchInterval: 1000 }
|
||||
).data;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import { BuildComponents } from "@components/resources/build";
|
||||
import { RepoComponents } from "@components/resources/repo";
|
||||
import { BuilderComponents } from "@components/resources/builder";
|
||||
import { AlerterComponents } from "@components/resources/alerter";
|
||||
import { ProcedureComponents } from "@components/resources/procedure";
|
||||
import { ProcedureComponents } from "@components/resources/procedure/index2";
|
||||
import { TagsSummary } from "@components/dashboard/tags";
|
||||
import { ApiKeysSummary } from "@components/dashboard/api-keys";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user