🚸 Improve Console
This commit is contained in:
parent
84b2c105d1
commit
9398f0a113
4
.gitignore
vendored
4
.gitignore
vendored
@ -9,10 +9,6 @@ dist
|
|||||||
# Node dependencies
|
# Node dependencies
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.fleet
|
.fleet
|
||||||
|
|||||||
@ -22,6 +22,22 @@ html * {
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html a.external {
|
||||||
|
color: #24a4ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
html .marked.green {
|
||||||
|
color: #24ff24;
|
||||||
|
}
|
||||||
|
|
||||||
|
html .marked.yellow {
|
||||||
|
color: #ffa32b;
|
||||||
|
}
|
||||||
|
|
||||||
|
html .marked.red {
|
||||||
|
color: #ff362f;
|
||||||
|
}
|
||||||
|
|
||||||
html, body, #__nuxt {
|
html, body, #__nuxt {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|||||||
@ -4,14 +4,13 @@ export class LogRepo
|
|||||||
{
|
{
|
||||||
websocket?: WebSocket = undefined;
|
websocket?: WebSocket = undefined;
|
||||||
|
|
||||||
listen(namespace: string, name: string, onReceive: (logs: Log[]) => void)
|
listen(resourceType: string, namespace: string, name: string, onReceive: (logs: Log[]) => void)
|
||||||
{
|
{
|
||||||
const websocket = new WebSocket(StringUtils.format("%s/logs/%s/%s", ApiConfig.getWsBase(), namespace, name));
|
const websocket = new WebSocket(StringUtils.format("%s/logs/%s/%s/%s", ApiConfig.getWsBase(), resourceType, namespace, name));
|
||||||
websocket.addEventListener('open', () => {
|
websocket.addEventListener('open', () => {
|
||||||
console.info("Opened Websocket.");
|
console.info("Opened Websocket.");
|
||||||
})
|
})
|
||||||
websocket.addEventListener("message", (event) => {
|
websocket.addEventListener("message", (event) => {
|
||||||
console.log(event.data);
|
|
||||||
onReceive(JSON.parse(event.data) as Log[]);
|
onReceive(JSON.parse(event.data) as Log[]);
|
||||||
});
|
});
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
|
|||||||
@ -2,16 +2,27 @@ import dayjs from "dayjs";
|
|||||||
import advancedFormat from "dayjs/plugin/advancedFormat";
|
import advancedFormat from "dayjs/plugin/advancedFormat";
|
||||||
import type { Metadata } from "./Metadata";
|
import type { Metadata } from "./Metadata";
|
||||||
import type { HasMetadata } from "./repo/ResourceRepo";
|
import type { HasMetadata } from "./repo/ResourceRepo";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
export class Pod implements HasMetadata
|
export class Pod implements HasMetadata
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
public metadata: Metadata,
|
public metadata: Metadata,
|
||||||
public spec: Spec,
|
public spec: Spec,
|
||||||
public status: Status
|
public status: Status
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
|
static getByDeployment(namespace: string, name: string, onSuccess: (pods: Pod[]) => void)
|
||||||
|
{
|
||||||
|
axios.get<Pod[]>(StringUtils.format('%s/resources/deployments/%s/%s/pods', ApiConfig.getHttpBase(), namespace, name), {
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer " + requireToken()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
onSuccess(response.data)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Spec {
|
class Spec {
|
||||||
|
|||||||
@ -1,88 +0,0 @@
|
|||||||
<template>
|
|
||||||
<PopupTemplate :heading="'Logs: ' + pod.metadata?.namespace + '/' + pod.metadata?.name" ref="base" @close="emits('close')">
|
|
||||||
<ScrollComponent ref="scrollComponent" v-show="logs">
|
|
||||||
<div class="console" v-if="logs">
|
|
||||||
<p class="log" v-for="log, index in logs" :class="{ even: index % 2 }"><span>[{{ dayjs(log.timestamp).format('YYYY-MM-DD HH:mm') }}]</span><span>{{ log.message }}</span></p>
|
|
||||||
</div>
|
|
||||||
</ScrollComponent>
|
|
||||||
<div v-if="logs == null" class="center" style="height: 100%; width: 100%">
|
|
||||||
<UiLoadingIcon size="2rem"></UiLoadingIcon>
|
|
||||||
</div>
|
|
||||||
<p>{{ logs }}</p>
|
|
||||||
</PopupTemplate>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { LogRepo } from '~/classes/LogRepo';
|
|
||||||
import type { Pod } from '~/classes/Pod';
|
|
||||||
import { getLogs } from '~/requests/logs';
|
|
||||||
import { Log } from '~/requests/logs';
|
|
||||||
|
|
||||||
const base = ref();
|
|
||||||
|
|
||||||
const logs: Ref<Log[]> = ref([]);
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
pod: Pod
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const emits = defineEmits<{
|
|
||||||
(e: 'close'): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollComponent = ref();
|
|
||||||
|
|
||||||
const logRepo = new LogRepo();
|
|
||||||
onMounted(() => {
|
|
||||||
logRepo.listen( props.pod.metadata.namespace, props.pod.metadata.name,(_logs: Log[]) => {
|
|
||||||
logs.value.push(..._logs);
|
|
||||||
scrollComponent.value.scrollToBottom();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
onUnmounted(() => {
|
|
||||||
logRepo.clear();
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
document.addEventListener('keydown', (event) => {
|
|
||||||
if(event.key === 'Escape')
|
|
||||||
{
|
|
||||||
emits('close');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.log {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto 1fr;
|
|
||||||
padding: 0.125rem 1rem;
|
|
||||||
gap: 1rem;
|
|
||||||
}
|
|
||||||
.log * {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
word-break: break-all;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
color: white;
|
|
||||||
line-height: 1.15rem;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console {
|
|
||||||
background-color: black;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
display: grid;
|
|
||||||
padding: 1rem 0;
|
|
||||||
align-content: start;
|
|
||||||
}
|
|
||||||
.even {
|
|
||||||
background-color: rgb(24, 24, 24);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -15,6 +15,7 @@ function scrollToBottom()
|
|||||||
const element = document.getElementById(id);
|
const element = document.getElementById(id);
|
||||||
if(element)
|
if(element)
|
||||||
{
|
{
|
||||||
|
console.log("Scroll to bottom");
|
||||||
element.scrollTo({top: element.scrollHeight, behavior: 'instant'});
|
element.scrollTo({top: element.scrollHeight, behavior: 'instant'});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -5,11 +5,13 @@
|
|||||||
<p class="grid-element">{{ calcAge(deployment.metadata.creationTimestamp) }}</p>
|
<p class="grid-element">{{ calcAge(deployment.metadata.creationTimestamp) }}</p>
|
||||||
<p class="grid-element">{{ deployment.spec.replicas }}</p>
|
<p class="grid-element">{{ deployment.spec.replicas }}</p>
|
||||||
<div class="grid-element action-buttons">
|
<div class="grid-element action-buttons">
|
||||||
|
<ActionButton @click="() => showLogsPopup = true">text_snippet</ActionButton>
|
||||||
<ActionButton>autorenew</ActionButton>
|
<ActionButton>autorenew</ActionButton>
|
||||||
<ActionButton @click="() => rescaleDeploymentPopup.open()">height</ActionButton>
|
<ActionButton @click="() => rescaleDeploymentPopup.open()">height</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
<RescaleDeploymentPopup ref="rescaleDeploymentPopup" :deployment="deployment"></RescaleDeploymentPopup>
|
<RescaleDeploymentPopup ref="rescaleDeploymentPopup" :deployment="deployment"></RescaleDeploymentPopup>
|
||||||
<DeploymentViewPopup v-if="showViewPopup" :deployment="deployment" @close="() => showViewPopup = false"></DeploymentViewPopup>
|
<DeploymentViewPopup v-if="showViewPopup" :deployment="deployment" @close="() => showViewPopup = false"></DeploymentViewPopup>
|
||||||
|
<DeploymentLogPopup v-if="showLogsPopup" :deployment="deployment" @close="() => showLogsPopup = false"></DeploymentLogPopup>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -18,6 +20,7 @@ import { Deployment } from '~/classes/Deployment';
|
|||||||
import { calcAge } from '~/classes/Pod';
|
import { calcAge } from '~/classes/Pod';
|
||||||
import RescaleDeploymentPopup from '../RescaleDeploymentPopup.vue';
|
import RescaleDeploymentPopup from '../RescaleDeploymentPopup.vue';
|
||||||
import DeploymentViewPopup from "~/components/deployment/view/DeploymentViewPopup.vue";
|
import DeploymentViewPopup from "~/components/deployment/view/DeploymentViewPopup.vue";
|
||||||
|
import DeploymentLogPopup from "~/components/inspect/logs/DeploymentLogPopup.vue";
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
deployment: Deployment
|
deployment: Deployment
|
||||||
@ -25,4 +28,5 @@ defineProps<{
|
|||||||
|
|
||||||
const rescaleDeploymentPopup = ref();
|
const rescaleDeploymentPopup = ref();
|
||||||
const showViewPopup = ref(false);
|
const showViewPopup = ref(false);
|
||||||
|
const showLogsPopup = ref(false);
|
||||||
</script>
|
</script>
|
||||||
95
components/inspect/logs/Console.vue
Normal file
95
components/inspect/logs/Console.vue
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<template>
|
||||||
|
<ScrollComponent ref="scrollComponent" v-show="logs">
|
||||||
|
<div class="console" v-if="logs">
|
||||||
|
<p class="log no-wrap" v-for="(log, index) in logs" :class="{ even: index % 2, wrap: config.lineWrap, nowrap: !config.lineWrap }"><span v-if="config.podNames">{{ log.podName }}</span><span v-if="config.timestamps">[{{ dayjs(log.timestamp).format('YYYY-MM-DD HH:mm') }}]</span><span v-html="process(log.message)"></span></p>
|
||||||
|
</div>
|
||||||
|
</ScrollComponent>
|
||||||
|
<div v-if="logs == null" class="center" style="height: 100%; width: 100%">
|
||||||
|
<UiLoadingIcon size="2rem"></UiLoadingIcon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type {Log} from "~/requests/logs";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import type {ConsoleConfig} from "~/components/inspect/logs/ConsoleConfig";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
config: ConsoleConfig
|
||||||
|
logs?: Log[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const scrollComponent = ref();
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
watch(props, () => {
|
||||||
|
scrollComponent.value.scrollToBottom();
|
||||||
|
}, { immediate: true, deep: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
function process(text: string)
|
||||||
|
{
|
||||||
|
return text.replace(/https?:\/\/\S+/g, (url) => {
|
||||||
|
return StringUtils.format("<a class='external' href='%s' target='_blank'>%s</a>", url, url);
|
||||||
|
})
|
||||||
|
.replace("INFO", () => {
|
||||||
|
return StringUtils.format("<span class='marked green'>%s</span>", "INFO");
|
||||||
|
})
|
||||||
|
.replace("[INFO]", () => {
|
||||||
|
return StringUtils.format("<span class='marked green'>%s</span>", "[INFO]");
|
||||||
|
})
|
||||||
|
.replace("WARN", () => {
|
||||||
|
return StringUtils.format("<span class='marked yellow'>%s</span>", "WARN");
|
||||||
|
})
|
||||||
|
.replace("[WARN]", () => {
|
||||||
|
return StringUtils.format("<span class='marked yellow'>%s</span>", "[WARN]");
|
||||||
|
})
|
||||||
|
.replace("ERROR", () => {
|
||||||
|
return StringUtils.format("<span class='marked red'>%s</span>", "ERROR");
|
||||||
|
})
|
||||||
|
.replace("[ERROR]", () => {
|
||||||
|
return StringUtils.format("<span class='marked red'>%s</span>", "[ERROR]");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.log {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto 1fr;
|
||||||
|
padding: 0.125rem 1rem;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
.log *:not(a, .marked) {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
color: white;
|
||||||
|
line-height: 1.15rem;
|
||||||
|
padding: 0.1rem 0;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console {
|
||||||
|
background-color: #0e0e0e;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
display: grid;
|
||||||
|
padding: 1rem 0;
|
||||||
|
align-content: start;
|
||||||
|
}
|
||||||
|
.even {
|
||||||
|
background-color: rgb(35, 35, 35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nowrap *:not(a) {
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
.green {
|
||||||
|
color: #2e9a00;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
13
components/inspect/logs/ConsoleConfig.ts
Normal file
13
components/inspect/logs/ConsoleConfig.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export class ConsoleConfig
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
public timestamps: boolean,
|
||||||
|
public podNames: boolean,
|
||||||
|
public lineWrap: boolean
|
||||||
|
) {}
|
||||||
|
|
||||||
|
static default(timestamps: boolean, podNames: boolean, lineWrap: boolean)
|
||||||
|
{
|
||||||
|
return new ConsoleConfig(timestamps, podNames, lineWrap);
|
||||||
|
}
|
||||||
|
}
|
||||||
73
components/inspect/logs/DeploymentLogPopup.vue
Normal file
73
components/inspect/logs/DeploymentLogPopup.vue
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<PopupTemplate :heading="'Logs: ' + deployment.metadata.namespace + '/' + deployment.metadata.name" ref="base" @close="emits('close')">
|
||||||
|
<div class="log-container" v-if="pods">
|
||||||
|
<div class="spaced-center">
|
||||||
|
<div class="left-center">
|
||||||
|
<UiButton @click="() => config.timestamps = true" v-if="!config.timestamps"><span>Show Timestamp</span> <UiIcon>visibility</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.timestamps = false" v-if="config.timestamps"><span>Hide Timestamp</span> <UiIcon>visibility_off</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.podNames = true" v-if="!config.podNames"><span>Show Pod Name</span> <UiIcon>visibility</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.podNames = false" v-if="config.podNames"><span>Hide Pod Name</span> <UiIcon>visibility_off</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.lineWrap = true" v-if="!config.lineWrap"><span>Wrap Line</span> <UiIcon>format_text_wrap</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.lineWrap = false" v-if="config.lineWrap"><span>Unwrap Line</span> <UiIcon>format_text_overflow</UiIcon></UiButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Console :logs="logs" :config="config"></Console>
|
||||||
|
</div>
|
||||||
|
</PopupTemplate>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { LogRepo } from '~/classes/LogRepo';
|
||||||
|
import { Pod } from '~/classes/Pod';
|
||||||
|
import { Log } from '~/requests/logs';
|
||||||
|
import Console from "~/components/inspect/logs/Console.vue";
|
||||||
|
import type {Deployment} from "~/classes/Deployment";
|
||||||
|
import UiIcon from "~/components/ui/UiIcon.vue";
|
||||||
|
import { ConsoleConfig } from '~/components/inspect/logs/ConsoleConfig'
|
||||||
|
|
||||||
|
const config = ref(ConsoleConfig.default(true, true, false));
|
||||||
|
|
||||||
|
const base = ref();
|
||||||
|
|
||||||
|
const logs: Ref<Log[]> = ref([]);
|
||||||
|
const pods: Ref<Pod[] | undefined> = ref(undefined);
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
deployment: Deployment
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emits = defineEmits<{
|
||||||
|
(e: 'close'): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const logRepo = new LogRepo();
|
||||||
|
onMounted(() => {
|
||||||
|
logRepo.listen("deployments", props.deployment.metadata.namespace, props.deployment.metadata.name,(_logs: Log[]) => {
|
||||||
|
logs.value.push(..._logs);
|
||||||
|
});
|
||||||
|
Pod.getByDeployment(props.deployment.metadata.namespace, props.deployment.metadata.name, (_pods: Pod[]) => {
|
||||||
|
pods.value = _pods;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
logRepo.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if(event.key === 'Escape')
|
||||||
|
{
|
||||||
|
emits('close');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.log-container {
|
||||||
|
height: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
64
components/inspect/logs/PodLogPopup.vue
Normal file
64
components/inspect/logs/PodLogPopup.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<PopupTemplate :heading="'Logs: ' + pod.metadata?.namespace + '/' + pod.metadata?.name" ref="base" @close="emits('close')">
|
||||||
|
<div class="log-container">
|
||||||
|
<div class="left-center">
|
||||||
|
<UiButton @click="() => config.timestamps = true" v-if="!config.timestamps"><span>Show Timestamp</span> <UiIcon>visibility</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.timestamps = false" v-if="config.timestamps"><span>Hide Timestamp</span> <UiIcon>visibility_off</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.lineWrap = true" v-if="!config.lineWrap"><span>Wrap Line</span> <UiIcon>format_text_wrap</UiIcon></UiButton>
|
||||||
|
<UiButton @click="() => config.lineWrap = false" v-if="config.lineWrap"><span>Unwrap Line</span> <UiIcon>format_text_overflow</UiIcon></UiButton>
|
||||||
|
</div>
|
||||||
|
<Console :logs="logs" :config="config"></Console>
|
||||||
|
</div>
|
||||||
|
</PopupTemplate>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { LogRepo } from '~/classes/LogRepo';
|
||||||
|
import type { Pod } from '~/classes/Pod';
|
||||||
|
import { Log } from '~/requests/logs';
|
||||||
|
import Console from "~/components/inspect/logs/Console.vue";
|
||||||
|
import UiIcon from "~/components/ui/UiIcon.vue";
|
||||||
|
import { ConsoleConfig } from '~/components/inspect/logs/ConsoleConfig'
|
||||||
|
|
||||||
|
const config = ref(ConsoleConfig.default(true, false, false));
|
||||||
|
|
||||||
|
const base = ref();
|
||||||
|
|
||||||
|
const logs: Ref<Log[]> = ref([]);
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
pod: Pod
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emits = defineEmits<{
|
||||||
|
(e: 'close'): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const logRepo = new LogRepo();
|
||||||
|
onMounted(() => {
|
||||||
|
logRepo.listen("pods", props.pod.metadata.namespace, props.pod.metadata.name,(_logs: Log[]) => {
|
||||||
|
logs.value.push(..._logs);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
logRepo.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if(event.key === 'Escape')
|
||||||
|
{
|
||||||
|
emits('close');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.log-container {
|
||||||
|
height: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<ActionButton @click="showDeletePopup = true">delete</ActionButton>
|
<ActionButton @click="showDeletePopup = true">delete</ActionButton>
|
||||||
</div>
|
</div>
|
||||||
<PodDeletePopup v-if="showDeletePopup" :pod="pod" @close="showDeletePopup = false"></PodDeletePopup>
|
<PodDeletePopup v-if="showDeletePopup" :pod="pod" @close="showDeletePopup = false"></PodDeletePopup>
|
||||||
<LogPopup v-if="showLogPopup" :pod="pod" @close="showLogPopup = false"></LogPopup>
|
<PodLogPopup v-if="showLogPopup" :pod="pod" @close="showLogPopup = false"></PodLogPopup>
|
||||||
<PodViewPopup v-if="showViewPopup" :pod="pod" @close="showViewPopup = false"></PodViewPopup>
|
<PodViewPopup v-if="showViewPopup" :pod="pod" @close="showViewPopup = false"></PodViewPopup>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -23,6 +23,7 @@
|
|||||||
import type { Pod } from '~/classes/Pod';
|
import type { Pod } from '~/classes/Pod';
|
||||||
import { calcAge } from '~/classes/Pod';
|
import { calcAge } from '~/classes/Pod';
|
||||||
import PodDeletePopup from './view/PodDeletePopup.vue';
|
import PodDeletePopup from './view/PodDeletePopup.vue';
|
||||||
|
import PodLogPopup from "~/components/inspect/logs/PodLogPopup.vue";
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
pod: Pod
|
pod: Pod
|
||||||
|
|||||||
21
components/ui/PodPicker.vue
Normal file
21
components/ui/PodPicker.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<div class="pod-picker base-shape">
|
||||||
|
<div v-for="pod in pods">
|
||||||
|
<p>{{ pod.metadata.name }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type {Pod} from "~/classes/Pod";
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
pods: Pod[]
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.pod-picker {
|
||||||
|
background-color: var(--tile-color);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -3,6 +3,7 @@ import axios from "axios";
|
|||||||
export class Log
|
export class Log
|
||||||
{
|
{
|
||||||
constructor (
|
constructor (
|
||||||
|
public podName: string,
|
||||||
public timestamp: string,
|
public timestamp: string,
|
||||||
public message: string
|
public message: string
|
||||||
) {}
|
) {}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user