diff --git a/src/App.vue b/src/App.vue index 93ec0c0..72ec9f5 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,39 +1,35 @@ diff --git a/src/components/DialogHandler.vue b/src/components/DialogHandler.vue new file mode 100644 index 0000000..01685df --- /dev/null +++ b/src/components/DialogHandler.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/components/tables/pods.ts b/src/components/tables/pods.ts index 49c0854..3cc92c0 100644 --- a/src/components/tables/pods.ts +++ b/src/components/tables/pods.ts @@ -28,7 +28,13 @@ export const columns: ColumnDef[] = [ }, { header: "Status", - accessorFn: (row) => row.status?.phase, + accessorFn: (row) => { + if (row.metadata?.deletionTimestamp) { + return "Terminating"; + } + + return row.status?.phase; + }, }, { header: "CPU", diff --git a/src/components/tables/types.ts b/src/components/tables/types.ts index fd5bf0a..2733016 100644 --- a/src/components/tables/types.ts +++ b/src/components/tables/types.ts @@ -1,3 +1,5 @@ +import { BaseDialogInterface } from "@/providers/DialogProvider"; +import { Command } from "@tauri-apps/api/shell"; import { VirtualService } from "@kubernetes-models/istio/networking.istio.io/v1beta1"; import { KubernetesObject } from "@kubernetes/client-node"; @@ -19,8 +21,9 @@ export type RowAction = WithOptions | WithHandler; export function getDefaultActions( addTab: any, + spawnDialog: any, context: string, - isGenericResource: boolean = false + isGenericResource = false ): RowAction[] { return [ { @@ -58,5 +61,46 @@ export function getDefaultActions( ); }, }, + { + label: "Delete", + handler: (row) => { + const dialog: BaseDialogInterface = { + title: "Delete", + message: `Are you sure you want to delete ${row.metadata?.name}?`, + buttons: [ + { + label: "Cancel", + handler: (dialog) => { + dialog.close(); + }, + }, + { + label: "Delete", + handler: (dialog) => { + const command = new Command("kubectl", [ + "delete", + `${row.kind}/${row.metadata?.name}`, + "--context", + context, + "--namespace", + row.metadata?.namespace || "", + ]); + + command.stderr.on("data", (error: string) => { + console.log(error); + }); + + command.on("close", () => { + dialog.close(); + }); + + command.spawn(); + }, + }, + ], + }; + spawnDialog(dialog); + }, + }, ]; } diff --git a/src/providers/DialogProvider.ts b/src/providers/DialogProvider.ts new file mode 100644 index 0000000..1ba8e6a --- /dev/null +++ b/src/providers/DialogProvider.ts @@ -0,0 +1,46 @@ +import { ToRefs } from "vue"; + +export const DialogProviderStateKey: InjectionKey> = + Symbol("DialogProviderState"); + +export const DialogProviderSpawnDialogKey: InjectionKey< + (dialog: DialogInterface) => void +> = Symbol("DialogProviderSpawnDialog"); + +export interface DialogButtonInterface { + label: string; + handler: (dialog: DialogInterface) => void; +} + +export interface BaseDialogInterface { + title: string; + message: string; + buttons: DialogButtonInterface[]; +} + +export interface DialogInterface extends BaseDialogInterface { + close: () => void; +} + +export interface DialogProviderState { + dialog: DialogInterface | null; +} + +export default { + setup() { + const state: DialogProviderState = reactive({ + dialog: null, + }); + + provide(DialogProviderStateKey, toRefs(state)); + + const spawnDialog = (dialog: BaseDialogInterface) => { + state.dialog = { ...dialog, close: () => (state.dialog = null) }; + }; + + provide(DialogProviderSpawnDialogKey, spawnDialog); + }, + render(): any { + return this.$slots.default(); + }, +}; diff --git a/src/views/ConfigMaps.vue b/src/views/ConfigMaps.vue index f6d7498..7583550 100644 --- a/src/views/ConfigMaps.vue +++ b/src/views/ConfigMaps.vue @@ -19,8 +19,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), ]; async function getConfigMaps(refresh: boolean = false) { diff --git a/src/views/CronJobs.vue b/src/views/CronJobs.vue index b43374e..7f34548 100644 --- a/src/views/CronJobs.vue +++ b/src/views/CronJobs.vue @@ -19,8 +19,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), ]; async function getCronJobs(refresh: boolean = false) { diff --git a/src/views/Deployments.vue b/src/views/Deployments.vue index dc3219f..20cfc01 100644 --- a/src/views/Deployments.vue +++ b/src/views/Deployments.vue @@ -11,6 +11,9 @@ const { context, namespace } = injectStrict(KubeContextStateKey); import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + import DataTable from "@/components/ui/DataTable.vue"; import { RowAction, getDefaultActions } from "@/components/tables/types"; import { columns } from "@/components/tables/deployments"; @@ -20,8 +23,8 @@ const { toast } = useToast(); const deployments = ref([]); const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), - { + ...getDefaultActions(addTab, spawnDialog, context.value), + { label: "Logs", handler: (row) => { addTab( diff --git a/src/views/GenericResource.vue b/src/views/GenericResource.vue index 2cadfd9..a659af4 100644 --- a/src/views/GenericResource.vue +++ b/src/views/GenericResource.vue @@ -18,8 +18,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value, true), + ...getDefaultActions(addTab, spawnDialog, context.value, true), ]; onBeforeRouteUpdate((to, from, next) => { diff --git a/src/views/Ingresses.vue b/src/views/Ingresses.vue index bcca069..b2e06ab 100644 --- a/src/views/Ingresses.vue +++ b/src/views/Ingresses.vue @@ -19,8 +19,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), ]; async function getIngresses(refresh: boolean = false) { diff --git a/src/views/Jobs.vue b/src/views/Jobs.vue index b11248f..4bb39ec 100644 --- a/src/views/Jobs.vue +++ b/src/views/Jobs.vue @@ -19,8 +19,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), ]; async function getJobs(refresh: boolean = false) { diff --git a/src/views/PersistentVolumeClaims.vue b/src/views/PersistentVolumeClaims.vue index 2e12ec0..57af6c9 100644 --- a/src/views/PersistentVolumeClaims.vue +++ b/src/views/PersistentVolumeClaims.vue @@ -19,8 +19,15 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions( + addTab, + spawnDialog, + context.value + ), ]; async function getPersistentVolumeClaims(refresh: boolean = false) { diff --git a/src/views/Pods.vue b/src/views/Pods.vue index 420508a..c1bce5e 100644 --- a/src/views/Pods.vue +++ b/src/views/Pods.vue @@ -17,12 +17,15 @@ import { TabProviderAddTabKey } from "@/providers/TabProvider"; const { context, namespace } = injectStrict(KubeContextStateKey); const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const { toast } = useToast(); const pods = ref([]); const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), { label: "Shell", options: (row) => { diff --git a/src/views/Secrets.vue b/src/views/Secrets.vue index a085773..28ab22c 100644 --- a/src/views/Secrets.vue +++ b/src/views/Secrets.vue @@ -19,8 +19,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), ]; async function getConfigMaps(refresh: boolean = false) { diff --git a/src/views/Services.vue b/src/views/Services.vue index 5750789..f3e437c 100644 --- a/src/views/Services.vue +++ b/src/views/Services.vue @@ -19,8 +19,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), ]; async function getServices(refresh: boolean = false) { diff --git a/src/views/VirtualServices.vue b/src/views/VirtualServices.vue index 8b8ba32..cf72471 100644 --- a/src/views/VirtualServices.vue +++ b/src/views/VirtualServices.vue @@ -19,8 +19,11 @@ import { RowAction, getDefaultActions } from "@/components/tables/types"; import { TabProviderAddTabKey } from "@/providers/TabProvider"; const addTab = injectStrict(TabProviderAddTabKey); +import { DialogProviderSpawnDialogKey } from "@/providers/DialogProvider"; +const spawnDialog = injectStrict(DialogProviderSpawnDialogKey); + const rowActions: RowAction[] = [ - ...getDefaultActions(addTab, context.value), + ...getDefaultActions(addTab, spawnDialog, context.value), ]; async function getVirtualServices(refresh: boolean = false) {