Skip to content

Commit

Permalink
wip: tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeroen Nijhuis committed Jan 2, 2024
1 parent c8f8d21 commit b8e4ef4
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 23 deletions.
37 changes: 34 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"radix-vue": "^1.2.5",
"tailwind-merge": "^2.1.0",
"tailwindcss-animate": "^1.0.7",
"vite-plugin-dynamic-import": "^1.5.0",
"vite-svg-loader": "^5.1.0",
"vue": "3.3.4",
"vue-router": "^4.2.5"
Expand Down
15 changes: 9 additions & 6 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import CommandPalette from "./components/CommandPalette.vue";
import SettingsContextProvider from "./providers/SettingsContextProvider";
import KubeContextProvider from "./providers/KubeContextProvider";
import CommandPaletteProvider from "./providers/CommandPaletteProvider";
import TabProvider from "./providers/TabProvider";
</script>

<template>
Expand All @@ -18,12 +19,14 @@ import CommandPaletteProvider from "./providers/CommandPaletteProvider";
<Suspense>
<SettingsContextProvider>
<KubeContextProvider>
<CommandPaletteProvider>
<Navigation />
<RouterViewport />
<Toaster />
<CommandPalette />
</CommandPaletteProvider>
<TabProvider>
<CommandPaletteProvider>
<Navigation />
<RouterViewport />
<Toaster />
<CommandPalette />
</CommandPaletteProvider>
</TabProvider>
</KubeContextProvider>
</SettingsContextProvider>
</Suspense>
Expand Down
1 change: 1 addition & 0 deletions src/assets/icons/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion src/components/RouterViewport.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import TabOrchestrator from "@/components/TabOrchestrator.vue";
</script>
<template>
<div class="flex flex-col max-h-screen relative w-full">
<div class="flex flex-col max-h-screen relative router-viewport">
<ScrollArea
class="w-full flex flex-grow border-l border-[#232323] bg-[#0f0f0f]"
>
Expand All @@ -13,3 +13,8 @@ import TabOrchestrator from "@/components/TabOrchestrator.vue";
<TabOrchestrator />
</div>
</template>
<style>
.router-viewport {
width: calc(100vw - 200px);
}
</style>
45 changes: 34 additions & 11 deletions src/components/TabOrchestrator.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,43 @@
<script setup lang="ts">
import {
TabProviderStateKey,
TabProviderCloseTabKey,
} from "@/providers/TabProvider";
import { injectStrict } from "@/lib/utils";
import Expand from "@/assets/icons/expand.svg";
import Close from "@/assets/icons/close.svg";
const { tabs, activeTabId } = injectStrict(TabProviderStateKey);
const closeTab = injectStrict(TabProviderCloseTabKey);
const state = reactive({
open: false,
open: true,
});
const activeTab = computed(() => {
return tabs.value.find((tab) => tab.id === activeTabId.value);
});
</script>
<template>
<div class="border-t border-l bg-background">
<div class="border-t border-l bg-background" v-if="tabs.length > 0">
<div class="flex items-center mb-0 text-xs py-1 px-1">
<div class="flex space-x-3">
<div
class="py-1 px-2 rounded cursor-pointer max-w-[200px] truncate hover:bg-border"
class="group relative flex items-center py-1 px-2 rounded cursor-pointer max-w-[200px] truncate hover:bg-border"
:class="{
'bg-border': activeTabId === tab.id,
'text-gray-400': activeTabId !== tab.id,
}"
v-for="tab in tabs"
@click="activeTabId = tab.id"
>
Logs for minikube/default/countdown-b8dz2
</div>
<div class="py-1 px-2 rounded cursor-pointer hover:bg-border">
Tab 2
</div>
<div class="py-1 px-2 rounded cursor-pointer hover:bg-border">
Tab 3
<span class="truncate">{{ tab.title }}</span>
<div
@click="closeTab(tab.id)"
class="hidden group-hover:block absolute right-1 p-0.5 rounded-sm bg-opacity-50 bg-white hover:bg-white text-background"
>
<Close class="h-3" />
</div>
</div>
</div>
<div
Expand All @@ -31,6 +50,10 @@ const state = reactive({
/>
</div>
</div>
<div class="" v-show="state.open">Test</div>
<div class="p-2" v-show="state.open">
<keep-alive>
<component :is="activeTab?.component" v-bind="activeTab?.props" />
</keep-alive>
</div>
</div>
</template>
2 changes: 1 addition & 1 deletion src/components/tables/pods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const columns: ColumnDef<V1Pod>[] = [
},
{
header: "IP",
accessorKey: "status.podIP",
accessorFn: (row) => row.status?.podIP || "",
},
{
header: "Node",
Expand Down
69 changes: 69 additions & 0 deletions src/providers/TabProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
provide,
reactive,
InjectionKey,
toRefs,
ToRefs,
shallowRef,
} from "vue";

export const TabProviderStateKey: InjectionKey<ToRefs<TabProviderState>> =
Symbol("TabProviderState");
export const TabProviderAddTabKey: InjectionKey<
(id: string, title: string, component: any, props?: any) => void
> = Symbol("TabProviderAddTab");
export const TabProviderCloseTabKey: InjectionKey<(id: string) => void> =
Symbol("TabProviderCloseTab");

export interface Tab {
id: string;
title: string;
component: any;
props?: any;
}

export interface TabProviderState {
tabs: Tab[];
activeTabId: string | null;
}

export default {
setup() {
const state: TabProviderState = reactive({
tabs: [],
activeTabId: null,
});

provide(TabProviderStateKey, toRefs(state));

const addTab = (id: string, title: string, component: any, props?: any) => {
if (state.tabs.find((tab) => tab.id === id)) {
state.activeTabId = id;
return;
}

state.tabs.push({
id,
title,
component: shallowRef(component),
props,
});

state.activeTabId = id;
};

const closeTab = (id: string) => {
const tabIndex = state.tabs.findIndex((tab) => tab.id === id);

if (tabIndex !== -1) {
state.tabs.splice(tabIndex, 1);
}
};

provide(TabProviderAddTabKey, addTab);
provide(TabProviderCloseTabKey, closeTab);
},
render(): any {
return this.$slots.default();
},
};
10 changes: 10 additions & 0 deletions src/views/LogViewer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script setup lang="ts">
const props = defineProps<{
context: string;
namespace: string;
pod: string;
}>();
</script>
<template>
<div>Logs for {{ props }}</div>
</template>
13 changes: 12 additions & 1 deletion src/views/Pods.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import DataTable from "@/components/ui/DataTable.vue";
import { RowAction } from "@/components/tables/types";
import { columns } from "@/components/tables/pods";
import { useDataRefresher } from "@/composables/refresher";
import { TabProviderAddTabKey } from "@/providers/TabProvider";
const { context, namespace } = injectStrict(KubeContextStateKey);
const addTab = injectStrict(TabProviderAddTabKey);
const { toast } = useToast();
const router = useRouter();
Expand All @@ -36,7 +38,16 @@ const rowActions: RowAction<V1Pod>[] = [
{
label: "Logs",
handler: (row) => {
router.push({ name: "PodLogs", params: { podName: row.metadata?.name } });
addTab(
`logs_${row.metadata?.name}`,
`Logs for ${row.metadata?.name}`,
defineAsyncComponent(() => import("@/views/LogViewer.vue")),
{
context: context.value,
namespace: namespace.value,
pod: row.metadata?.name,
}
);
},
},
];
Expand Down

0 comments on commit b8e4ef4

Please sign in to comment.