🚚 New Routes for resources
This commit is contained in:
parent
74ebe0b925
commit
fe3dcd2165
16
classes/CustomResourceDefinition.ts
Normal file
16
classes/CustomResourceDefinition.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import type { Metadata } from "./Metadata";
|
||||
|
||||
export class CustomResourceDefinition
|
||||
{
|
||||
constructor (
|
||||
public metadata: Metadata,
|
||||
public spec: Spec
|
||||
) { }
|
||||
}
|
||||
|
||||
export class Spec
|
||||
{
|
||||
constructor (
|
||||
public group: string
|
||||
) { }
|
||||
}
|
||||
@ -2,5 +2,7 @@ import type { Metadata } from "./Metadata";
|
||||
|
||||
export class Namespace
|
||||
{
|
||||
metadata?: Metadata;
|
||||
constructor (
|
||||
public metadata: Metadata
|
||||
) { }
|
||||
}
|
||||
55
classes/ResourceRepo.ts
Normal file
55
classes/ResourceRepo.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import axios from "axios";
|
||||
|
||||
export class ResourceRepo<T>
|
||||
{
|
||||
private resources: Ref<T[] | undefined> = ref(undefined);
|
||||
private interval: NodeJS.Timeout | undefined = undefined;
|
||||
|
||||
static init<T>()
|
||||
{
|
||||
return new ResourceRepo<T>();
|
||||
}
|
||||
|
||||
load(resourceType: string)
|
||||
{
|
||||
this.refresh(resourceType);
|
||||
return this;
|
||||
}
|
||||
|
||||
clear()
|
||||
{
|
||||
clearTimeout(this.interval);
|
||||
}
|
||||
|
||||
get()
|
||||
{
|
||||
return computed(() => {
|
||||
return this.resources.value;
|
||||
})
|
||||
}
|
||||
|
||||
private refresh(resourceType: string)
|
||||
{
|
||||
const namespace = this.getNamespace();
|
||||
let url = useRuntimeConfig().public.apiBase + '/resources/' + resourceType
|
||||
if (namespace)
|
||||
{
|
||||
url = url + "/" + namespace;
|
||||
}
|
||||
axios.get<T[]>(url)
|
||||
.then((response) => {
|
||||
this.resources.value = undefined;
|
||||
this.resources.value = response.data;
|
||||
});
|
||||
}
|
||||
|
||||
private getNamespace()
|
||||
{
|
||||
const namespace = useRoute().params.namespace as string;
|
||||
if (namespace !== "_all")
|
||||
{
|
||||
return namespace as string;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@ -3,20 +3,12 @@
|
||||
<div class="content-l">
|
||||
<h2>Kubooboo</h2>
|
||||
<div class="nav">
|
||||
<NuxtLink class="resources" to="/account/inspect/nodes">Nodes</NuxtLink>
|
||||
<NuxtLink class="resources" to="/account/inspect/ingresses">Ingresses</NuxtLink>
|
||||
<NuxtLink class="resources" to="/account/inspect/services">Services</NuxtLink>
|
||||
<NuxtLink class="resources" to="/account/inspect/deployments">Deployments</NuxtLink>
|
||||
<NuxtLink class="resources" to="/account/inspect/pods">Pods</NuxtLink>
|
||||
<NuxtLink class="resources" v-for="[key, value] of resources" :to="'/account/inspect/' + key + '/_all'" :class="{ 'router-link-active': useRoute().params.resource === key }">{{ value }}</NuxtLink>
|
||||
</div>
|
||||
<div class="divider" :class="{ hide: !inNamespaceScopedResource }"></div>
|
||||
<div :class="{ hide: !inNamespaceScopedResource }">
|
||||
<div class="namespace" :class="{ active: currentNamespace === undefined }" @click="() => namespaceStore.selectNamespace(undefined)">
|
||||
<p>Alle</p>
|
||||
</div>
|
||||
<div class="namespace" v-for="namespace in namespaces" @click="() => namespaceStore.selectNamespace(namespace)" :class="{ active: namespace.metadata?.name === currentNamespace?.metadata?.name }">
|
||||
<p v-if="namespace.metadata">{{ namespace.metadata.name }}</p>
|
||||
</div>
|
||||
<div class="nav" :class="{ hide: !inNamespaceScopedResource }">
|
||||
<NuxtLink class="namespace" :to="base + '/_all'">Alle</NuxtLink>
|
||||
<NuxtLink v-for="namespace in namespaces" class="namespace" :to="base + '/' + namespace.metadata.name">{{ namespace.metadata.name }}</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<div class="left-center" v-if="user" @click="() => accountPopup.open()">
|
||||
@ -31,6 +23,8 @@ import SidebarTemplate from './SidebarTemplate.vue';
|
||||
|
||||
import { useNamespaceStore } from '#imports';
|
||||
|
||||
const resources = new Map<string, string>([["nodes", "Nodes"], ["ingresses", "Ingresses"], ["services", "Services"], ["deployments", "Deployments"], ["pods", "Pods"], ["custom-resource-definitions", "CDRs"]]);
|
||||
|
||||
const namespaceStore = useNamespaceStore();
|
||||
|
||||
const namespaces = computed(namespaceStore.getNamespaces);
|
||||
@ -41,8 +35,18 @@ const user = getUser();
|
||||
|
||||
const accountPopup = ref();
|
||||
|
||||
const base = computed(() => {
|
||||
const resource = useRoute().params.resource as string;
|
||||
if (resource)
|
||||
{
|
||||
return '/account/inspect/' + resource;
|
||||
}
|
||||
throw new Error();
|
||||
})
|
||||
|
||||
const inNamespaceScopedResource: ComputedRef<boolean> = computed(() => {
|
||||
if(useRoute().fullPath.startsWith('/account/inspect/nodes'))
|
||||
const resource = useRoute().params.resource as string;
|
||||
if(['custom-resource-definitions', 'nodes'].includes(resource))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -35,5 +35,7 @@ defineExpose({
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
min-height: 100%;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
</style>
|
||||
@ -24,10 +24,8 @@
|
||||
border-radius: 0.25rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
.namespace.active, .resources.router-link-active {
|
||||
background-color: var(--primary-color)
|
||||
}
|
||||
.namespace.active *, .resources.router-link-active {
|
||||
.router-link-active {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
.divider {
|
||||
|
||||
32
components/TableComponent.vue
Normal file
32
components/TableComponent.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="table">
|
||||
<slot v-if="!loading"></slot>
|
||||
<div class="loading center" v-if="loading">
|
||||
<UiLoadingIcon></UiLoadingIcon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
loading: boolean
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
}
|
||||
.loading {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.grid-element {
|
||||
height: 2.25rem;
|
||||
}
|
||||
</style>
|
||||
@ -14,7 +14,6 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Deployment } from '~/classes/Deployment';
|
||||
import { rescaleDeployment } from '~/requests/deployments';
|
||||
import RescaleDeploymentPopup from '../RescaleDeploymentPopup.vue';
|
||||
|
||||
defineProps<{
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<TableComponent :loading="customResourceDefinitions == null">
|
||||
<div class="resource-container crd-container">
|
||||
<div class="header">
|
||||
<p>Name</p>
|
||||
<p>Gruppe</p>
|
||||
</div>
|
||||
<div v-for="customResourceDefinition, index in customResourceDefinitions" class="resource" :class="{ even: index % 2 }">
|
||||
<p class="grid-element">{{ customResourceDefinition.metadata.name }}</p>
|
||||
<p class="grid-element">{{ customResourceDefinition.spec.group }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</TableComponent>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { CustomResourceDefinition } from '~/classes/CustomResourceDefinition';
|
||||
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||
|
||||
const customResourceDefinitions = ResourceRepo.init<CustomResourceDefinition>().load('custom-resource-definitions').get();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.crd-container {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
</style>
|
||||
27
components/inspect/resources/DeploymentComponent.vue
Normal file
27
components/inspect/resources/DeploymentComponent.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<TableComponent :loading="deployments == null">
|
||||
<div class="resource-container deployment-container">
|
||||
<div class="header">
|
||||
<p>Name</p>
|
||||
<p>Namespace</p>
|
||||
<p>Replicas</p>
|
||||
<p>Aktionen</p>
|
||||
</div>
|
||||
<DeploymentComponent :deployment="deployment" v-for="deployment, index in deployments" class="resource" :class="{ even: index % 2 }"></DeploymentComponent>
|
||||
</div>
|
||||
</TableComponent>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Deployment } from '~/classes/Deployment';
|
||||
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||
import DeploymentComponent from '~/components/deployments/DeploymentComponent.vue';
|
||||
|
||||
const deployments = ResourceRepo.init<Deployment>().load('deployments').get();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.deployment-container {
|
||||
grid-template-columns: auto 1fr 1fr auto;
|
||||
}
|
||||
</style>
|
||||
24
components/inspect/resources/IngressComponent.vue
Normal file
24
components/inspect/resources/IngressComponent.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<TableComponent :loading="ingresses == null">
|
||||
<div class="resource-container ingress-container">
|
||||
<div class="header">
|
||||
<p>Name</p>
|
||||
<p>Namespace</p>
|
||||
</div>
|
||||
<IngressComponent :ingress="ingress" v-for="ingress, index in ingresses" class="resource" :class="{ even: index % 2 }"></IngressComponent>
|
||||
</div>
|
||||
</TableComponent>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Ingress } from '~/classes/Ingress';
|
||||
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||
|
||||
const ingresses = ResourceRepo.init<Ingress>().load('ingresses').get();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ingress-container {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
</style>
|
||||
28
components/inspect/resources/NodeComponent.vue
Normal file
28
components/inspect/resources/NodeComponent.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<TableComponent :loading="node == null">
|
||||
<div class="resource-container node-container">
|
||||
<div class="header">
|
||||
<p>Name</p>
|
||||
<p>Alter</p>
|
||||
<p>Status</p>
|
||||
<p>CPU</p>
|
||||
<p>RAM</p>
|
||||
</div>
|
||||
<NodeComponent :node-stats="ns" v-for="ns, index in node" class="resource" :class="{ even: index % 2 }"></NodeComponent>
|
||||
</div>
|
||||
</TableComponent>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { NodeStats } from '~/classes/Node';
|
||||
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||
import NodeComponent from '~/components/NodeComponent.vue';
|
||||
|
||||
const node = ResourceRepo.init<NodeStats>().load('nodes').get();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.node-container {
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
||||
}
|
||||
</style>
|
||||
23
components/inspect/resources/PodComponent.vue
Normal file
23
components/inspect/resources/PodComponent.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<TableComponent :loading="pods == null">
|
||||
<div class="resource-container pod-container">
|
||||
<div class="header">
|
||||
<p>Pod</p>
|
||||
<p>Namespace</p>
|
||||
<p>Alter</p>
|
||||
<p>Node</p>
|
||||
<p>Status</p>
|
||||
<p>Aktionen</p>
|
||||
</div>
|
||||
<PodComponent v-for="pod, index in pods" :pod="pod" class="resource" :class="{ even: index % 2 }"></PodComponent>
|
||||
</div>
|
||||
</TableComponent>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Pod } from '~/classes/Pod';
|
||||
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||
import PodComponent from '~/components/pod/PodComponent.vue';
|
||||
|
||||
const pods = ResourceRepo.init<Pod>().load('pods').get();
|
||||
</script>
|
||||
26
components/inspect/resources/ServiceComponent.vue
Normal file
26
components/inspect/resources/ServiceComponent.vue
Normal file
@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<TableComponent :loading="services == null">
|
||||
<div class="resource-container service-container">
|
||||
<div class="header">
|
||||
<p>Service</p>
|
||||
<p>Namespace</p>
|
||||
<p>Type</p>
|
||||
<p>Aktionen</p>
|
||||
</div>
|
||||
<ServiceComponent :service="service" v-for="service, index in services" class="resource" :class="{ even: index % 2 }"></ServiceComponent>
|
||||
</div>
|
||||
</TableComponent>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ResourceRepo } from '~/classes/ResourceRepo';
|
||||
import type { Service } from '~/classes/Service';
|
||||
|
||||
const services = ResourceRepo.init<Service>().load('services').get();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.service-container {
|
||||
grid-template-columns: auto auto 1fr auto;
|
||||
}
|
||||
</style>
|
||||
@ -9,6 +9,7 @@ import UiIcon from './UiIcon.vue';
|
||||
<style scoped>
|
||||
.rotate{
|
||||
animation: rotate 1s linear infinite;
|
||||
user-select: none;
|
||||
}
|
||||
@keyframes rotate{
|
||||
to{ transform: rotate(360deg); }
|
||||
|
||||
10
pages/account/inspect/[resource].vue
Normal file
10
pages/account/inspect/[resource].vue
Normal file
@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<NuxtPage></NuxtPage>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
</style>
|
||||
20
pages/account/inspect/[resource]/[namespace].vue
Normal file
20
pages/account/inspect/[resource]/[namespace].vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<PodComponent v-if="resource === 'pods'"></PodComponent>
|
||||
<CustomResourceDefinitionComponent v-else-if="resource === 'custom-resource-definitions'"></CustomResourceDefinitionComponent>
|
||||
<IngressComponent v-else-if="resource === 'ingresses'"></IngressComponent>
|
||||
<ServiceComponent v-else-if="resource === 'services'"></ServiceComponent>
|
||||
<DeploymentComponent v-else-if="resource === 'deployments'"></DeploymentComponent>
|
||||
<NodeComponent v-else-if="resource === 'nodes'"></NodeComponent>
|
||||
<p v-else>Invalid resource</p>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PodComponent from '~/components/inspect/resources/PodComponent.vue';
|
||||
import CustomResourceDefinitionComponent from '~/components/inspect/resources/CustomResourceDefinitionComponent.vue';
|
||||
import IngressComponent from '~/components/inspect/resources/IngressComponent.vue';
|
||||
import ServiceComponent from '~/components/inspect/resources/ServiceComponent.vue';
|
||||
import DeploymentComponent from '~/components/inspect/resources/DeploymentComponent.vue';
|
||||
import NodeComponent from '~/components/inspect/resources/NodeComponent.vue';
|
||||
|
||||
const resource = useRoute().params.resource as string;
|
||||
</script>
|
||||
@ -1,50 +0,0 @@
|
||||
<template>
|
||||
<div class="resource-container deployment-container">
|
||||
<div class="header">
|
||||
<p>Name</p>
|
||||
<p>Namespace</p>
|
||||
<p>Replicas</p>
|
||||
<p>Aktionen</p>
|
||||
</div>
|
||||
<DeploymentComponent :deployment="deployment" v-for="deployment, index in deployments" class="resource" :class="{ even: index % 2 }"></DeploymentComponent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Deployment } from '~/classes/Deployment';
|
||||
import { useNamespaceStore } from '#imports';
|
||||
import type { Namespace } from '~/classes/Namespace';
|
||||
import { getDeployments } from '~/requests/deployments';
|
||||
import DeploymentComponent from '~/components/deployments/DeploymentComponent.vue';
|
||||
|
||||
const deployments: Ref<Deployment[] | undefined> = ref(undefined);
|
||||
|
||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
||||
|
||||
let interval: NodeJS.Timeout | undefined = undefined;
|
||||
onMounted(() => {
|
||||
watch(namespace, (newNamespace) => {
|
||||
loadDeployments(newNamespace);
|
||||
clearInterval(interval);
|
||||
interval = setInterval(() => {
|
||||
loadDeployments(newNamespace);
|
||||
}, 10000);
|
||||
}, { immediate: true })
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearInterval(interval);
|
||||
});
|
||||
|
||||
function loadDeployments(namespace?: Namespace)
|
||||
{
|
||||
getDeployments(namespace?.metadata?.name, (_deployments: Deployment[]) => {
|
||||
deployments.value = _deployments;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.deployment-container {
|
||||
grid-template-columns: 1fr 1fr 1fr auto;
|
||||
}
|
||||
</style>
|
||||
@ -1,33 +0,0 @@
|
||||
<template>
|
||||
<div class="resource-container ingress-container">
|
||||
<div class="header">
|
||||
<p>Name</p>
|
||||
<p>Namespace</p>
|
||||
</div>
|
||||
<IngressComponent :ingress="ingress" v-for="ingress, index in ingresses" class="resource" :class="{ even: index % 2 }"></IngressComponent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Ingress } from '~/classes/Ingress';
|
||||
import IngressComponent from '~/components/IngressComponent.vue';
|
||||
import { getIngresses } from '~/requests/ingresses';
|
||||
|
||||
const ingresses: Ref<Ingress[] | undefined> = ref(undefined);
|
||||
|
||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
||||
|
||||
onMounted(() => {
|
||||
watch(namespace, (newNamespace) => {
|
||||
getIngresses(newNamespace?.metadata?.name, (_ingresses: Ingress[]) => {
|
||||
ingresses.value = _ingresses;
|
||||
});
|
||||
}, { immediate: true })
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ingress-container {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
</style>
|
||||
@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<div class="resource-container node-container">
|
||||
<div class="header">
|
||||
<p>Name</p>
|
||||
<p>Alter</p>
|
||||
<p>Status</p>
|
||||
<p>CPU</p>
|
||||
<p>RAM</p>
|
||||
</div>
|
||||
<NodeComponent :node-stats="ns" v-for="ns, index in nodeStats" class="resource" :class="{ even: index % 2 }"></NodeComponent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NodeStats } from '~/classes/Node';
|
||||
import { getNodes } from '~/requests/nodes';
|
||||
|
||||
const nodeStats: Ref<NodeStats[] | undefined> = ref(undefined);
|
||||
|
||||
let interval: NodeJS.Timeout | undefined = undefined;
|
||||
onMounted(() => {
|
||||
loadNodes();
|
||||
interval = setInterval(() => {
|
||||
loadNodes();
|
||||
}, 10000)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearInterval(interval);
|
||||
});
|
||||
|
||||
function loadNodes()
|
||||
{
|
||||
getNodes((_nodes: NodeStats[]) => {
|
||||
nodeStats.value = _nodes;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.node-container {
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
|
||||
}
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,55 +0,0 @@
|
||||
<template>
|
||||
<div class="resource-container pod-container">
|
||||
<div class="header">
|
||||
<p>Pod</p>
|
||||
<p>Namespace</p>
|
||||
<p>Alter</p>
|
||||
<p>Node</p>
|
||||
<p>Status</p>
|
||||
<p>Aktionen</p>
|
||||
</div>
|
||||
<PodComponent v-for="pod, index in pods" :pod="pod" class="resource" :class="{ even: index % 2 }"></PodComponent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type Pod } from '~/classes/Pod';
|
||||
import { getPods } from '~/requests/pod';
|
||||
import { useNamespaceStore } from '#imports';
|
||||
import type { Namespace } from '~/classes/Namespace';
|
||||
|
||||
const pods: Ref<Pod[] | undefined> = ref(undefined);
|
||||
|
||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
||||
|
||||
let interval: NodeJS.Timeout | undefined = undefined;
|
||||
onMounted(() => {
|
||||
watch(namespace, (newNamespace) => {
|
||||
loadPods(newNamespace);
|
||||
clearInterval(interval);
|
||||
interval = setInterval(() => {
|
||||
loadPods(newNamespace);
|
||||
}, 10000);
|
||||
}, { immediate: true })
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearInterval(interval);
|
||||
});
|
||||
|
||||
function loadPods(namespace?: Namespace)
|
||||
{
|
||||
getPods(namespace?.metadata?.name, (_pods: Pod[]) => {
|
||||
pods.value = _pods;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pod-container {
|
||||
grid-template-columns: auto auto auto 1fr auto auto;
|
||||
}
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,53 +0,0 @@
|
||||
<template>
|
||||
<div class="resource-container service-container">
|
||||
<div class="header">
|
||||
<p>Service</p>
|
||||
<p>Namespace</p>
|
||||
<p>Type</p>
|
||||
<p>Aktionen</p>
|
||||
</div>
|
||||
<ServiceComponent :service="service" v-for="service, index in services" class="resource" :class="{ even: index % 2 }"></ServiceComponent>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useNamespaceStore } from '#imports';
|
||||
import type { Namespace } from '~/classes/Namespace';
|
||||
import type { Service } from '~/classes/Service';
|
||||
import { getServices } from '~/requests/services';
|
||||
|
||||
const services: Ref<Service[] | undefined> = ref(undefined);
|
||||
|
||||
const namespace = computed(useNamespaceStore().getCurrentNamespace);
|
||||
|
||||
let interval: NodeJS.Timeout | undefined = undefined;
|
||||
onMounted(() => {
|
||||
watch(namespace, (newNamespace) => {
|
||||
loadServices(newNamespace);
|
||||
clearInterval(interval);
|
||||
interval = setInterval(() => {
|
||||
loadServices(newNamespace);
|
||||
}, 10000);
|
||||
}, { immediate: true })
|
||||
})
|
||||
onUnmounted(() => {
|
||||
clearInterval(interval);
|
||||
})
|
||||
|
||||
function loadServices(namespace?: Namespace)
|
||||
{
|
||||
getServices(namespace?.metadata?.name, (_services: Service[]) => {
|
||||
services.value = _services;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.service-container {
|
||||
grid-template-columns: auto auto 1fr auto;
|
||||
}
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<p>{{ namespace }}</p>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const namespace = computed(() => {
|
||||
const namespace = useRoute().params.namespace;
|
||||
if (namespace)
|
||||
{
|
||||
return namespace;
|
||||
}
|
||||
return "Alle";
|
||||
});
|
||||
</script>
|
||||
@ -1,3 +0,0 @@
|
||||
<template>
|
||||
|
||||
</template>
|
||||
@ -42,7 +42,7 @@ function doLogin()
|
||||
const decode = jwtDecode(token) as any;
|
||||
getUser(decode.upn, token, (user: User) => {
|
||||
setSessionCookie(new Session(user, token), decode.exp as number);
|
||||
useRouter().push('/account/inspect');
|
||||
useRouter().push('/account/inspect/nodes/_all');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -8,7 +8,9 @@ export const useNamespaceStore = defineStore('namespace', {
|
||||
}),
|
||||
getters: {
|
||||
getNamespaces: (state) => {
|
||||
return (): Namespace[] | undefined => state.namespaces;
|
||||
return (): Namespace[] | undefined => {
|
||||
return state.namespaces;
|
||||
}
|
||||
},
|
||||
getCurrentNamespace: (state) => {
|
||||
return (): Namespace | undefined => state.currentNamespace;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user