1
0
mirror of https://github.com/amir20/dozzle.git synced 2025-12-30 09:45:15 +01:00
Files
dozzle/assets/components/LogViewer.vue
Amir Raminfar e2072d35c8 Settings to useStorage (#1602)
* Uses storage for settings

* Cleans settings

* Fixes tests for storage

* Removes store.js

* Uses ts

* Fixes tests

* Removes autoprefixer
2021-11-18 14:06:54 -08:00

123 lines
2.6 KiB
Vue

<template>
<ul class="events" :class="size">
<li v-for="item in filtered" :key="item.key" :data-event="item.event">
<span class="date" v-if="showTimestamp"> <relative-time :date="item.date"></relative-time></span>
<span class="text" v-html="colorize(item.message)"></span>
</li>
</ul>
</template>
<script lang="ts" setup>
import { computed } from "vue";
import { useStore } from "vuex";
import { size, showTimestamp } from "@/composables/settings";
import RelativeTime from "./RelativeTime.vue";
import AnsiConvertor from "ansi-to-html";
const props = defineProps({
messages: {
type: Array,
required: true,
},
});
const store = useStore();
const ansiConvertor = new AnsiConvertor({ escapeXML: true });
function colorize(value: string) {
return ansiConvertor.toHtml(value).replace("&lt;mark&gt;", "<mark>").replace("&lt;/mark&gt;", "</mark>");
}
const searchFilter = computed(() => store.state.searchFilter);
const filtered = computed(() => {
if (searchFilter && searchFilter.value) {
const isSmartCase = searchFilter.value === searchFilter.value.toLowerCase();
try {
const regex = isSmartCase ? new RegExp(searchFilter.value, "i") : new RegExp(searchFilter.value);
return props.messages
.filter((d) => d.message.match(regex))
.map((d) => ({
...d,
message: d.message.replace(regex, "<mark>$&</mark>"),
}));
} catch (e) {
if (e instanceof SyntaxError) {
console.info(`Ignoring SytaxError from search.`, e);
return props.messages;
}
throw e;
}
}
return props.messages;
});
</script>
<style scoped lang="scss">
.events {
padding: 1em;
font-family: SFMono-Regular, Consolas, Liberation Mono, monaco, Menlo, monospace;
& > li {
word-wrap: break-word;
line-height: 130%;
&:last-child {
scroll-snap-align: end;
scroll-margin-block-end: 5rem;
}
&[data-event="container-stopped"] {
color: #f14668;
}
&[data-event="container-started"] {
color: hsl(141, 53%, 53%);
}
}
&.small {
font-size: 60%;
}
&.medium {
font-size: 80%;
}
&.large {
font-size: 120%;
}
}
.date {
background-color: #262626;
color: #258ccd;
[data-theme="light"] & {
background-color: #f0f0f0;
color: #009900;
padding-left: 5px;
padding-right: 5px;
}
}
.text {
white-space: pre-wrap;
&::before {
content: " ";
}
}
: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>