-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: David Hu <[email protected]>
- Loading branch information
1 parent
c2964f4
commit ef1e40a
Showing
9 changed files
with
152 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ pub mod jobs; | |
pub mod namespaces; | ||
pub mod pods; | ||
pub mod replica_sets; | ||
pub mod stateful_sets; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use k8s_openapi::api::apps::v1::StatefulSet; | ||
use kube::{api::ListParams, core::ObjectList, Api}; | ||
|
||
use super::internal::get_api; | ||
|
||
#[tauri::command] | ||
pub async fn get_stateful_sets(namespace: Option<String>) -> ObjectList<StatefulSet> { | ||
let api: Api<StatefulSet> = get_api(namespace).await; | ||
let lp = ListParams::default(); | ||
return api.list(&lp).await.unwrap(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,48 @@ | ||
import type { PencilIcon } from "@heroicons/react/20/solid"; | ||
import { ArrowPathIcon, ArrowsUpDownIcon, PencilIcon } from "@heroicons/react/20/solid"; | ||
import type { PropsWithChildren } from "react"; | ||
|
||
export function ActionGroup({ children }: PropsWithChildren) { | ||
return <span className="isolate inline-flex rounded-md shadow-sm">{children}</span>; | ||
} | ||
|
||
export type Actions = "logs" | "edit" | "scale" | "restart"; | ||
|
||
interface ActionButtonProps { | ||
Icon: typeof PencilIcon; | ||
label: string; | ||
label: Actions; | ||
position: "left" | "right" | "middle"; | ||
onClick: () => void; | ||
} | ||
|
||
export function ActionButton({ Icon, label, position, onClick }: ActionButtonProps) { | ||
const getIcon = (label: Actions) => { | ||
switch (label) { | ||
case "logs": | ||
return ArrowPathIcon; | ||
case "edit": | ||
return PencilIcon; | ||
case "scale": | ||
return ArrowsUpDownIcon; | ||
case "restart": | ||
return ArrowPathIcon; | ||
} | ||
}; | ||
|
||
export function ActionButton({ label, position, onClick }: ActionButtonProps) { | ||
const roundedClass = | ||
position === "left" ? "rounded-l-md" : position === "right" ? "rounded-r-md" : ""; | ||
|
||
const Icon = getIcon(label); | ||
|
||
return ( | ||
<button | ||
type="button" | ||
onClick={onClick} | ||
className={`relative ${position === "left" ? "" : "-ml-px" | ||
} inline-flex items-center ${roundedClass} border border-gray-300 p-2 hover:bg-gray-50`} | ||
className={`relative ${ | ||
position === "left" ? "" : "-ml-px" | ||
} inline-flex items-center ${roundedClass} border border-gray-300 p-2 hover:bg-gray-50`} | ||
> | ||
<Icon className="mr-2 h-5 w-5 text-gray-400" aria-hidden="true" /> | ||
{label} | ||
{label[0].toUpperCase()} | ||
{label.slice(1)} | ||
</button> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import type { V1StatefulSet } from "@kubernetes/client-node"; | ||
import { useQuery } from "@tanstack/react-query"; | ||
import { invoke } from "@tauri-apps/api"; | ||
import { lazy, Suspense, useState } from "react"; | ||
|
||
import { ActionButton, ActionGroup } from "../components/action-group"; | ||
import { Table, TableHeader, TableBody, TableCell } from "../components/table"; | ||
import { useCurrentNamespace } from "../namespaces/namespaces"; | ||
import { ScaleModal } from "../components/scale-modal"; | ||
|
||
const ResourceEditDrawer = lazy(() => | ||
import("../components/resource-edit-drawer").then((module) => ({ | ||
default: module.ResourceEditDrawer, | ||
})) | ||
); | ||
|
||
type Actions = "edit" | "logs" | "scale"; | ||
|
||
export function StatefulSets() { | ||
const { namespace } = useCurrentNamespace(); | ||
|
||
const result = useQuery( | ||
["deployments", namespace], | ||
() => { | ||
return invoke<{ items: V1StatefulSet[] }>(`get_stateful_sets`, { namespace }); | ||
}, | ||
{ refetchInterval: 1000 } | ||
); | ||
|
||
const data = result.data?.items ?? []; | ||
|
||
const [action, setAction] = useState<Actions | null>(null); | ||
const [selected, setSelected] = useState<V1StatefulSet | null>(null); | ||
|
||
const handleOpen = (deployment: V1StatefulSet, action: Actions) => { | ||
setSelected(deployment); | ||
setAction(action); | ||
}; | ||
|
||
const handleClose = () => { | ||
setSelected(null); | ||
setAction(null); | ||
}; | ||
|
||
return ( | ||
<div> | ||
<Table> | ||
<TableHeader headers={["Name", "Image", "Pods", "Actions"]} /> | ||
<TableBody> | ||
{data.map((item) => ( | ||
<tr key={item.metadata?.uid}> | ||
<TableCell>{item.metadata?.name}</TableCell> | ||
<TableCell>{item.spec?.template.spec?.containers[0].image}</TableCell> | ||
<TableCell> | ||
{item.status?.availableReplicas} / {item.status?.replicas} | ||
</TableCell> | ||
<TableCell> | ||
<ActionGroup> | ||
<ActionButton | ||
label="logs" | ||
position="left" | ||
onClick={() => handleOpen(item, "logs")} | ||
/> | ||
<ActionButton | ||
label="edit" | ||
position="middle" | ||
onClick={() => handleOpen(item, "edit")} | ||
/> | ||
<ActionButton | ||
label="scale" | ||
position="right" | ||
onClick={() => handleOpen(item, "scale")} | ||
/> | ||
</ActionGroup> | ||
</TableCell> | ||
</tr> | ||
))} | ||
</TableBody> | ||
</Table> | ||
|
||
<Suspense fallback={<div>Loading Editor</div>}> | ||
<ResourceEditDrawer | ||
isOpen={action === "edit"} | ||
handleClose={handleClose} | ||
selectedResource={selected} | ||
/> | ||
</Suspense> | ||
|
||
<Suspense fallback={<div>Loading Scale Form</div>}> | ||
{selected && ( | ||
<ScaleModal | ||
isOpen={action === "scale"} | ||
handleClose={handleClose} | ||
deployment={selected} | ||
/> | ||
)} | ||
</Suspense> | ||
</div> | ||
); | ||
} |