mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-24 06:28:42 +01:00
Cleans up log viewer and adds zigzag line for skipped logs (#1885)
* Cleans up log viewer and adds zigzag line for skipped logs * Updates components * Cleans up css * Cleans up more css * Fixes tests * Fixes typing * Fixes typescript errors * Fixes selected color
This commit is contained in:
6
assets/components.d.ts
vendored
6
assets/components.d.ts
vendored
@@ -11,18 +11,16 @@ declare module '@vue/runtime-core' {
|
||||
CilColumns: typeof import('~icons/cil/columns')['default']
|
||||
CilFindInPage: typeof import('~icons/cil/find-in-page')['default']
|
||||
ComplexLogItem: typeof import('./components/LogViewer/ComplexLogItem.vue')['default']
|
||||
ComplexPayload: typeof import('./components/LogViewer/ComplexPayload.vue')['default']
|
||||
ContainerStat: typeof import('./components/LogViewer/ContainerStat.vue')['default']
|
||||
ContainerTitle: typeof import('./components/LogViewer/ContainerTitle.vue')['default']
|
||||
copy: typeof import('./components/LogViewer/DockerEventLogItem copy.vue')['default']
|
||||
DockerEventLogItem: typeof import('./components/LogViewer/DockerEventLogItem.vue')['default']
|
||||
DropdownMenu: typeof import('./components/DropdownMenu.vue')['default']
|
||||
FieldList: typeof import('./components/LogViewer/FieldList.vue')['default']
|
||||
FuzzySearchModal: typeof import('./components/FuzzySearchModal.vue')['default']
|
||||
InfiniteLoader: typeof import('./components/InfiniteLoader.vue')['default']
|
||||
JSONPayload: typeof import('./components/LogViewer/JSONPayload.vue')['default']
|
||||
LogActionsToolbar: typeof import('./components/LogViewer/LogActionsToolbar.vue')['default']
|
||||
LogContainer: typeof import('./components/LogViewer/LogContainer.vue')['default']
|
||||
LogDate: typeof import('./components/LogViewer/LogDate.vue')['default']
|
||||
LogEventSource: typeof import('./components/LogViewer/LogEventSource.vue')['default']
|
||||
LogViewer: typeof import('./components/LogViewer/LogViewer.vue')['default']
|
||||
LogViewerWithSource: typeof import('./components/LogViewer/LogViewerWithSource.vue')['default']
|
||||
@@ -46,6 +44,6 @@ declare module '@vue/runtime-core' {
|
||||
SideMenu: typeof import('./components/SideMenu.vue')['default']
|
||||
SimpleLogItem: typeof import('./components/LogViewer/SimpleLogItem.vue')['default']
|
||||
SkippedEntriesLogItem: typeof import('./components/LogViewer/SkippedEntriesLogItem.vue')['default']
|
||||
StringPayload: typeof import('./components/LogViewer/StringPayload.vue')['default']
|
||||
ZigZag: typeof import('./components/LogViewer/ZigZag.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
<template>
|
||||
<div>
|
||||
<ul class="fields" @click="expanded = !expanded">
|
||||
<li v-for="(value, name) in logEntry.message">
|
||||
<template v-if="value">
|
||||
<span class="has-text-grey">{{ name }}=</span>
|
||||
<span class="has-text-weight-bold" v-html="markSearch(value)"></span>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
<field-list :fields="logEntry.unfilteredMessage" :expanded="expanded" :visible-keys="visibleKeys"></field-list>
|
||||
<div class="columns is-1 is-variable">
|
||||
<div class="column is-narrow" v-if="showTimestamp">
|
||||
<log-date :date="logEntry.date"></log-date>
|
||||
</div>
|
||||
<div class="column">
|
||||
<ul class="fields" @click="expanded = !expanded">
|
||||
<li v-for="(value, name) in logEntry.message">
|
||||
<template v-if="value">
|
||||
<span class="has-text-grey">{{ name }}=</span>
|
||||
<span class="has-text-weight-bold" v-html="markSearch(value)"></span>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
<field-list :fields="logEntry.unfilteredMessage" :expanded="expanded" :visible-keys="visibleKeys"></field-list>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
@@ -42,7 +47,6 @@ let expanded = $ref(false);
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,9 +19,6 @@ span {
|
||||
}
|
||||
&.text {
|
||||
white-space: pre-wrap;
|
||||
&::before {
|
||||
content: " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
45
assets/components/LogViewer/LogDate.vue
Normal file
45
assets/components/LogViewer/LogDate.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<relative-time :date="date" class="date"></relative-time>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
date: Date;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.date {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.date {
|
||||
background-color: #262626;
|
||||
color: #258ccd;
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
.date {
|
||||
background-color: #262626;
|
||||
color: #258ccd;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.date {
|
||||
background-color: #f0f0f0;
|
||||
color: #009900;
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
.date {
|
||||
background-color: #f0f0f0;
|
||||
color: #009900;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -6,7 +6,7 @@ import LogEventSource from "./LogEventSource.vue";
|
||||
import LogViewer from "./LogViewer.vue";
|
||||
import { settings } from "../../composables/settings";
|
||||
import { useSearchFilter } from "@/composables/search";
|
||||
import { vi, describe, expect, beforeEach, test, beforeAll, afterAll, afterEach } from "vitest";
|
||||
import { vi, describe, expect, beforeEach, test, afterEach } from "vitest";
|
||||
import { computed, nextTick } from "vue";
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
|
||||
@@ -23,6 +23,7 @@ describe("<LogEventSource />", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
global.EventSource = EventSource;
|
||||
// @ts-ignore
|
||||
window.scrollTo = vi.fn();
|
||||
global.IntersectionObserver = vi.fn().mockImplementation(() => ({
|
||||
observe: vi.fn(),
|
||||
@@ -112,6 +113,7 @@ describe("<LogEventSource />", () => {
|
||||
vi.runAllTimers();
|
||||
await nextTick();
|
||||
|
||||
// @ts-ignore
|
||||
const [message, _] = wrapper.vm.messages;
|
||||
expect(message).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ const emit = defineEmits<{
|
||||
}>();
|
||||
|
||||
const container = inject("container") as ComputedRef<Container>;
|
||||
const { connect, messages, loadOlderLogs } = useLogStream(container);
|
||||
const { messages, loadOlderLogs } = useLogStream(container);
|
||||
|
||||
const beforeLoading = () => emit("loading-more", true);
|
||||
const afterLoading = () => emit("loading-more", false);
|
||||
@@ -22,6 +22,4 @@ defineExpose({
|
||||
});
|
||||
|
||||
const fetchMore = () => loadOlderLogs({ beforeLoading, afterLoading });
|
||||
|
||||
connect();
|
||||
</script>
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
</a>
|
||||
</dropdown-menu>
|
||||
</div>
|
||||
<div class="line">
|
||||
<span class="date" v-if="showTimestamp"> <relative-time :date="item.date"></relative-time></span>
|
||||
<component :is="item.getComponent()" :log-entry="item" :visible-keys="visibleKeys.value"></component>
|
||||
</div>
|
||||
<component :is="item.getComponent()" :log-entry="item" :visible-keys="visibleKeys.value"></component>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
@@ -34,7 +31,7 @@
|
||||
import { type ComputedRef, toRaw } from "vue";
|
||||
import { useRouteHash } from "@vueuse/router";
|
||||
import { type Container } from "@/types/Container";
|
||||
import { type JSONObject, type LogEntry } from "@/models/LogEntry";
|
||||
import { type JSONObject, LogEntry } from "@/models/LogEntry";
|
||||
|
||||
const props = defineProps<{
|
||||
messages: LogEntry<string | JSONObject>[];
|
||||
@@ -50,10 +47,10 @@ const visible = filteredPayload(messages);
|
||||
const filtered = filteredMessages(visible);
|
||||
|
||||
const events = ref<HTMLElement>();
|
||||
let lastSelectedItem = ref<LogEntry<string | JSONObject>>();
|
||||
let lastSelectedItem: LogEntry<string | JSONObject> | undefined = $ref(undefined);
|
||||
|
||||
function handleJumpLineSelected(e: Event, item: LogEntry<string | JSONObject>) {
|
||||
lastSelectedItem.value = item;
|
||||
lastSelectedItem = item;
|
||||
resetSearch();
|
||||
}
|
||||
|
||||
@@ -71,12 +68,6 @@ watch(
|
||||
padding: 1em 0;
|
||||
font-family: SFMono-Regular, Consolas, Liberation Mono, monaco, Menlo, monospace;
|
||||
|
||||
&.disable-wrap {
|
||||
.line {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
& > li {
|
||||
display: flex;
|
||||
word-wrap: break-word;
|
||||
@@ -89,19 +80,10 @@ watch(
|
||||
background-color: rgba(125, 125, 125, 0.08);
|
||||
}
|
||||
|
||||
&.selected .date {
|
||||
background-color: var(--menu-item-active-background-color);
|
||||
&.selected {
|
||||
border: 1px var(--secondary-color) solid;
|
||||
}
|
||||
|
||||
color: var(--text-color);
|
||||
}
|
||||
&.selected > .date {
|
||||
background-color: white;
|
||||
}
|
||||
& > .line {
|
||||
margin: auto 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
& > .line-options {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
@@ -121,55 +103,4 @@ watch(
|
||||
font-size: 120%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.date {
|
||||
background-color: #262626;
|
||||
color: #258ccd;
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
.date {
|
||||
background-color: #262626;
|
||||
color: #258ccd;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.date {
|
||||
background-color: #f0f0f0;
|
||||
color: #009900;
|
||||
}
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
.date {
|
||||
background-color: #f0f0f0;
|
||||
color: #009900;
|
||||
}
|
||||
}
|
||||
|
||||
.date {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(mark) {
|
||||
border-radius: 2px;
|
||||
background-color: var(--secondary-color);
|
||||
animation: pops 200ms ease-out;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@keyframes pops {
|
||||
0% {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<span class="text" v-html="colorize(logEntry.message)"></span>
|
||||
<div class="columns is-1 is-variable">
|
||||
<div class="column is-narrow" v-if="showTimestamp">
|
||||
<log-date :date="logEntry.date"></log-date>
|
||||
</div>
|
||||
<div class="text column" v-html="colorize(logEntry.message)"></div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { SimpleLogEntry } from "@/models/LogEntry";
|
||||
@@ -23,8 +28,5 @@ const colorize = (value: string) => markSearch(ansiConvertor.toHtml(value));
|
||||
|
||||
.text {
|
||||
white-space: pre-wrap;
|
||||
&::before {
|
||||
content: " ";
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<span class="text">{{ $t("error.logs-skipped", { total: logEntry.totalSkipped }) }}</span>
|
||||
<div class="is-flex-grow-1 has-text-centered my-4">
|
||||
<div class="is-relative">
|
||||
<zig-zag class="is-overlay mt-2"></zig-zag>
|
||||
<span class="text is-relative py-2 px-4">{{ $t("error.logs-skipped", { total: logEntry.totalSkipped }) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { SkippedLogsEntry } from "@/models/LogEntry";
|
||||
@@ -10,15 +15,9 @@ defineProps<{
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
span {
|
||||
&.text {
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
white-space: pre-wrap;
|
||||
&::before {
|
||||
content: " ";
|
||||
}
|
||||
}
|
||||
.text {
|
||||
font-weight: bold;
|
||||
white-space: pre-wrap;
|
||||
background-color: var(--body-background-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
19
assets/components/LogViewer/ZigZag.vue
Normal file
19
assets/components/LogViewer/ZigZag.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<svg width="100%" height="8" class="zigzag">
|
||||
<defs>
|
||||
<pattern id="zigzag" x="0" y="0" width="30" height="8" patternUnits="userSpaceOnUse">
|
||||
<line x1="0" y1="0" x2="15" y2="8" class="line" />
|
||||
<line x1="15" y1="8" x2="30" y2="0" class="line" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="url(#zigzag)"></rect>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.line {
|
||||
stroke: var(--primary-color);
|
||||
stroke-width: 1;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
</style>
|
||||
@@ -23,7 +23,10 @@ exports[`<LogEventSource /> > render html correctly > should render dates with 1
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"line\\" data-v-2e92daca=\\"\\"><span class=\\"date\\" data-v-2e92daca=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" data-v-2e92daca=\\"\\">06/12/2019 10:55:42 AM</time></span><span class=\\"text\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\"><test>foo bar</test></span></div>
|
||||
<div class=\\"columns is-1 is-variable\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\">
|
||||
<div class=\\"column is-narrow\\" data-v-a49e52d4=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" class=\\"date\\" data-v-de513450=\\"\\" data-v-a49e52d4=\\"\\">06/12/2019 10:55:42 AM</time></div>
|
||||
<div class=\\"text column\\" data-v-a49e52d4=\\"\\"><test>foo bar</test></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>"
|
||||
`;
|
||||
@@ -51,7 +54,10 @@ exports[`<LogEventSource /> > render html correctly > should render dates with 2
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"line\\" data-v-2e92daca=\\"\\"><span class=\\"date\\" data-v-2e92daca=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" data-v-2e92daca=\\"\\">06/12/2019 10:55:42</time></span><span class=\\"text\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\"><test>foo bar</test></span></div>
|
||||
<div class=\\"columns is-1 is-variable\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\">
|
||||
<div class=\\"column is-narrow\\" data-v-a49e52d4=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" class=\\"date\\" data-v-de513450=\\"\\" data-v-a49e52d4=\\"\\">06/12/2019 10:55:42</time></div>
|
||||
<div class=\\"text column\\" data-v-a49e52d4=\\"\\"><test>foo bar</test></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>"
|
||||
`;
|
||||
@@ -79,7 +85,10 @@ exports[`<LogEventSource /> > render html correctly > should render messages 1`]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"line\\" data-v-2e92daca=\\"\\"><span class=\\"date\\" data-v-2e92daca=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" data-v-2e92daca=\\"\\">06/12/2019 10:55:42 AM</time></span><span class=\\"text\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\">This is a message.</span></div>
|
||||
<div class=\\"columns is-1 is-variable\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\">
|
||||
<div class=\\"column is-narrow\\" data-v-a49e52d4=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" class=\\"date\\" data-v-de513450=\\"\\" data-v-a49e52d4=\\"\\">06/12/2019 10:55:42 AM</time></div>
|
||||
<div class=\\"text column\\" data-v-a49e52d4=\\"\\">This is a message.</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>"
|
||||
`;
|
||||
@@ -107,7 +116,10 @@ exports[`<LogEventSource /> > render html correctly > should render messages wit
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"line\\" data-v-2e92daca=\\"\\"><span class=\\"date\\" data-v-2e92daca=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" data-v-2e92daca=\\"\\">06/12/2019 10:55:42 AM</time></span><span class=\\"text\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\"><span style=\\"color:#000\\">black<span style=\\"color:#AAA\\">white</span></span></span></div>
|
||||
<div class=\\"columns is-1 is-variable\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\">
|
||||
<div class=\\"column is-narrow\\" data-v-a49e52d4=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" class=\\"date\\" data-v-de513450=\\"\\" data-v-a49e52d4=\\"\\">06/12/2019 10:55:42 AM</time></div>
|
||||
<div class=\\"text column\\" data-v-a49e52d4=\\"\\"><span style=\\"color:#000\\">black<span style=\\"color:#AAA\\">white</span></span></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>"
|
||||
`;
|
||||
@@ -135,7 +147,10 @@ exports[`<LogEventSource /> > render html correctly > should render messages wit
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"line\\" data-v-2e92daca=\\"\\"><span class=\\"date\\" data-v-2e92daca=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" data-v-2e92daca=\\"\\">06/12/2019 10:55:42 AM</time></span><span class=\\"text\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\"><mark>test</mark> bar</span></div>
|
||||
<div class=\\"columns is-1 is-variable\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\">
|
||||
<div class=\\"column is-narrow\\" data-v-a49e52d4=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" class=\\"date\\" data-v-de513450=\\"\\" data-v-a49e52d4=\\"\\">06/12/2019 10:55:42 AM</time></div>
|
||||
<div class=\\"text column\\" data-v-a49e52d4=\\"\\"><mark>test</mark> bar</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>"
|
||||
`;
|
||||
@@ -163,7 +178,10 @@ exports[`<LogEventSource /> > render html correctly > should render messages wit
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"line\\" data-v-2e92daca=\\"\\"><span class=\\"date\\" data-v-2e92daca=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" data-v-2e92daca=\\"\\">06/12/2019 10:55:42 AM</time></span><span class=\\"text\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\"><test>foo bar</test></span></div>
|
||||
<div class=\\"columns is-1 is-variable\\" visible-keys=\\"\\" data-v-a49e52d4=\\"\\" data-v-2e92daca=\\"\\">
|
||||
<div class=\\"column is-narrow\\" data-v-a49e52d4=\\"\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\" class=\\"date\\" data-v-de513450=\\"\\" data-v-a49e52d4=\\"\\">06/12/2019 10:55:42 AM</time></div>
|
||||
<div class=\\"text column\\" data-v-a49e52d4=\\"\\"><test>foo bar</test></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>"
|
||||
`;
|
||||
|
||||
@@ -46,10 +46,10 @@ const store = useContainerStore();
|
||||
const route = useRoute();
|
||||
const { visibleContainers, allContainersById } = storeToRefs(store);
|
||||
|
||||
const showNav = ref(false);
|
||||
let showNav = $ref(false);
|
||||
|
||||
watch(route, () => {
|
||||
showNav.value = false;
|
||||
showNav = false;
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -16,8 +16,8 @@ function parseMessage(data: string): LogEntry<string | JSONObject> {
|
||||
}
|
||||
|
||||
export function useLogStream(container: ComputedRef<Container>) {
|
||||
let messages = $ref<LogEntry<string | JSONObject>[]>([]);
|
||||
let buffer = $ref<LogEntry<string | JSONObject>[]>([]);
|
||||
let messages: LogEntry<string | JSONObject>[] = $ref([]);
|
||||
let buffer: LogEntry<string | JSONObject>[] = $ref([]);
|
||||
const scrollingPaused = $ref(inject("scrollingPaused") as Ref<boolean>);
|
||||
|
||||
function flushNow() {
|
||||
@@ -117,8 +117,9 @@ export function useLogStream(container: ComputedRef<Container>) {
|
||||
|
||||
watch(
|
||||
() => container.value.id,
|
||||
() => connect()
|
||||
() => connect(),
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
return $$({ connect, messages, loadOlderLogs });
|
||||
return { ...$$({ messages }), loadOlderLogs };
|
||||
}
|
||||
|
||||
@@ -49,9 +49,9 @@ export function useSearchFilter() {
|
||||
});
|
||||
}
|
||||
|
||||
function markSearch(log: string): string;
|
||||
function markSearch(log: { toString(): string }): string;
|
||||
function markSearch(log: string[]): string[];
|
||||
function markSearch(log: string | string[]) {
|
||||
function markSearch(log: { toString(): string } | string[]) {
|
||||
if (!debouncedSearchFilter.value) {
|
||||
return log;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
// @ts-ignore - splitpanes types are not available
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
import { useProgrammatic } from "@oruga-ui/oruga-next";
|
||||
import FuzzySearchModal from "@/components/FuzzySearchModal.vue";
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
type="text"
|
||||
:placeholder="$t('placeholder.search-containers')"
|
||||
v-model="search"
|
||||
@keyup.esc="search = null"
|
||||
@keyup.esc="search.value = null"
|
||||
@keyup.enter="onEnter()"
|
||||
/>
|
||||
<span class="icon is-left">
|
||||
|
||||
@@ -57,7 +57,7 @@ setTitle(t("title.login"));
|
||||
let error = $ref(false);
|
||||
let username = $ref("");
|
||||
let password = $ref("");
|
||||
let form = $ref();
|
||||
let form: HTMLFormElement = $ref();
|
||||
|
||||
async function onLogin() {
|
||||
const response = await fetch(`${config.base}/api/validateCredentials`, {
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
type="text"
|
||||
:placeholder="$t('placeholder.search-containers')"
|
||||
v-model="search"
|
||||
@keyup.esc="search = null"
|
||||
@keyup.esc="search.value = null"
|
||||
@keyup.enter="onEnter()"
|
||||
/>
|
||||
<span class="icon is-left">
|
||||
|
||||
@@ -57,7 +57,7 @@ setTitle(t("title.login"));
|
||||
let error = $ref(false);
|
||||
let username = $ref("");
|
||||
let password = $ref("");
|
||||
let form = $ref();
|
||||
let form: HTMLFormElement = $ref();
|
||||
|
||||
async function onLogin() {
|
||||
const response = await fetch(`${config.base}/api/validateCredentials`, {
|
||||
|
||||
@@ -176,3 +176,19 @@ html.has-custom-scrollbars {
|
||||
.button .button-wrapper > span {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
mark {
|
||||
border-radius: 2px;
|
||||
background-color: var(--secondary-color);
|
||||
animation: pops 200ms ease-out;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@keyframes pops {
|
||||
0% {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user