minor design update & fix markdown pages display

This commit is contained in:
arabcoders
2025-04-07 21:50:40 +03:00
parent dc822771a4
commit 42c3c81fd8
17 changed files with 168 additions and 61 deletions

View File

@@ -224,3 +224,18 @@ html {
background-repeat: no-repeat;
background-blend-mode: darken;
}
.is-terminal {
background-color: #1f2229 !important;
color: #e3c981;
padding: 0.50rem;
line-height: 1.7;
}
.is-terminal > span:nth-child(even), .is-terminal > code > span:nth-child(even) {
color: #ffc9d4;
}
.is-terminal > span:nth-child(odd), .is-terminal > code > span:nth-child(odd) {
color: #e3c981;
}

View File

@@ -96,7 +96,8 @@
<span>{{ !toggleData ? 'Show' : 'Hide' }} attached data</span>
</h2>
<div v-if="toggleData" class="is-relative">
<code class="text-container is-block p-4" :class="{ 'is-pre': !wrapLines, 'is-pre-wrap': wrapLines }">
<code class="text-container is-block p-4 is-terminal"
:class="{ 'is-pre': !wrapLines, 'is-pre-wrap': wrapLines }">
{{ JSON.stringify(item.event_data, null, 2) }}
</code>
<button class="button m-4" v-tooltip="'Copy event data'"
@@ -115,8 +116,9 @@
<span>{{ !toggleLogs ? 'Show' : 'Hide' }} event logs</span>
</h2>
<div v-if="toggleLogs" class="is-relative">
<code class="is-block text-container p-4" :class="{ 'is-pre': !wrapLines, 'is-pre-wrap': wrapLines }">
<span class="is-log-line is-block pt-1" v-for="(item, index) in filteredRows" :key="'log_line-' + index"
<code class="is-block text-container p-4 is-terminal"
:class="{ 'is-pre': !wrapLines, 'is-pre-wrap': wrapLines }">
<span class="is-block pt-1" v-for="(item, index) in filteredRows" :key="'log_line-' + index"
v-text="item"/>
</code>
<button class="button m-4" v-tooltip="'Copy logs'" @click="() => copyText(filteredRows.join('\n'))"
@@ -134,7 +136,8 @@
<span>{{ !toggleOptions ? 'Show' : 'Hide' }} attached options</span>
</h2>
<div v-if="toggleOptions" class="is-relative">
<code class="is-block text-container p-4" :class="{ 'is-pre': !wrapLines, 'is-pre-wrap': wrapLines }">
<code class="is-block text-container p-4 is-terminal"
:class="{ 'is-pre': !wrapLines, 'is-pre-wrap': wrapLines }">
{{ JSON.stringify(item.options, null, 2) }}
</code>
<button class="button m-4" v-tooltip="'Copy options'"
@@ -168,6 +171,9 @@ const toggleData = useStorage('events_toggle_data', true)
const toggleOptions = useStorage('events_toggle_options', true)
const wrapLines = useStorage('logs_wrap_lines', false)
const bg_enable = useStorage('bg_enable', true)
const bg_opacity = useStorage('bg_opacity', 0.95)
watch(toggleFilter, () => {
if (!toggleFilter.value) {
query.value = ''
@@ -182,6 +188,9 @@ const filteredRows = computed(() => {
});
onMounted(async () => {
if (bg_enable.value) {
document.querySelector('body').setAttribute("style", "opacity: 1");
}
if (!props.id) {
throw createError({
statusCode: 404,
@@ -191,6 +200,12 @@ onMounted(async () => {
return await loadContent()
})
onUnmounted(async () => {
if (bg_enable.value && bg_opacity.value) {
document.querySelector('body').setAttribute("style", `opacity: ${bg_opacity.value}`)
}
})
const loadContent = async () => {
try {
isLoading.value = true

View File

@@ -23,9 +23,9 @@ onMounted(async () => {
marked.use({
gfm: true,
renderer: {
text: (text) => {
// -- replace github [!] with icon
hooks: {
postprocess: (text) => {
// -- replace github [! with icon
text = text.replace(/\[!IMPORTANT\]/g, `
<span class="is-block title is-4">
<span class="icon-text">

View File

@@ -87,14 +87,14 @@
<div class="column is-12">
<h1 class="title is-4">Recent History</h1>
</div>
<div class="column is-6-tablet" v-for="history in bHistory" :key="history.id">
<div class="card" :class="{ 'is-success': history.watched }">
<div class="column is-6-tablet" v-for="item in bHistory" :key="item.id">
<div class="card" :class="{ 'is-success': item.watched }">
<header class="card-header">
<p class="card-header-title is-text-overflow pr-1">
<NuxtLink :to="`/history/${history.id}`" v-text="makeName(history)"/>
<NuxtLink :to="`/history/${item.id}`" v-text="makeName(item)"/>
</p>
<span class="card-header-icon">
<span class="icon" v-if="'episode' === history.type"><i class="fas fa-tv"></i></span>
<span class="card-header-icon" @click="item.showItem = !item.showItem">
<span class="icon" v-if="'episode' === item.type"><i class="fas fa-tv"></i></span>
<span class="icon" v-else><i class="fas fa-film"></i></span>
</span>
</header>
@@ -104,8 +104,8 @@
<span class="icon-text">
<span class="icon"><i class="fas fa-calendar"></i>&nbsp;</span>
<span class="has-tooltip"
v-tooltip="`Updated at: ${moment.unix(history.updated_at ?? history.updated).format(TOOLTIP_DATE_FORMAT)}`">
{{ moment.unix(history.updated_at ?? history.updated).fromNow() }}
v-tooltip="`Updated at: ${moment.unix(item.updated_at ?? item.updated).format(TOOLTIP_DATE_FORMAT)}`">
{{ moment.unix(item.updated_at ?? item.updated).fromNow() }}
</span>
</span>
</div>
@@ -113,24 +113,33 @@
<span class="icon-text">
<span class="icon"><i class="fas fa-server"></i></span>
<span>
<NuxtLink :to="'/backend/'+history.via" v-text="history.via"/>
<NuxtLink :to="'/backend/'+item.via" v-text="item.via"/>
</span>
</span>
</div>
<div class="column is-4-tablet is-12-mobile has-text-left-mobile">
<span class="icon-text">
<span class="icon"><i class="fas fa-envelope"></i></span>
<span>{{ history.event }}</span>
<span>{{ item.event }}</span>
</span>
</div>
</div>
</div>
<div class="card-footer" v-if="history.progress">
<div class="card-content p-0 m-0" v-if="item?.showItem">
<div class="mt-2" style="position: relative; max-height: 343px; overflow-y: auto;">
<code class="is-terminal is-block is-pre-wrap" v-text="JSON.stringify(item, null, 2)"/>
<button class="button m-4" v-tooltip="'Copy text'" style="position: absolute; top:0; right:0;"
@click="() => copyText(JSON.stringify(item, null, 2))">
<span class="icon"><i class="fas fa-copy"/></span>
</button>
</div>
</div>
<div class="card-footer" v-if="item.progress">
<div class="card-footer-item">
<span class="has-text-success" v-if="history.watched">Played</span>
<span class="has-text-success" v-if="item.watched">Played</span>
<span class="has-text-danger" v-else>Unplayed</span>
</div>
<div class="card-footer-item">{{ formatDuration(history.progress) }}</div>
<div class="card-footer-item">{{ formatDuration(item.progress) }}</div>
</div>
</div>
</div>
@@ -149,8 +158,12 @@
<h1 class="title is-4">Basic info</h1>
</div>
<div class="column is-12">
<div class="content">
<code class="is-block is-pre-wrap" v-text="info"></code>
<div class="mt-2" style="position: relative;">
<code class="is-terminal is-block is-pre-wrap" v-text="info"/>
<button class="button m-4" v-tooltip="'Copy text'" style="position: absolute; top:0; right:0;"
@click="() => copyText(JSON.stringify(info, null, 2))">
<span class="icon"><i class="fas fa-copy"/></span>
</button>
</div>
</div>
</div>

View File

@@ -100,7 +100,13 @@
</div>
</div>
<div class="card-content p-0 m-0" v-if="item?.showItem">
<pre><code>{{ JSON.stringify(item, null, 2) }}</code></pre>
<div class="mt-2" style="position: relative; max-height: 343px; overflow-y: auto;">
<code class="is-terminal is-block is-pre-wrap" v-text="JSON.stringify(item, null, 2)"/>
<button class="button m-4" v-tooltip="'Copy text'" style="position: absolute; top:0; right:0;"
@click="() => copyText(JSON.stringify(item, null, 2))">
<span class="icon"><i class="fas fa-copy"/></span>
</button>
</div>
</div>
</div>
</div>

View File

@@ -112,7 +112,7 @@
<p class="card-header-title is-text-overflow">
<NuxtLink :to="item.webUrl" v-text="makeName(item)" target="_blank"/>
</p>
<span class="card-header-icon">
<span class="card-header-icon" @click="item.showItem = !item.showItem">
<span class="icon">
<i class="fas"
:class="{'fa-folder': 'show' === item.type, 'fa-tv': 'episode' === item.type, 'fa-film': 'movie' === item.type}"></i>
@@ -139,6 +139,15 @@
</div>
</div>
</div>
<div class="card-content p-0 m-0" v-if="item?.showItem">
<div class="mt-2" style="position: relative; max-height: 343px; overflow-y: auto;">
<code class="is-terminal is-block is-pre-wrap" v-text="JSON.stringify(item, null, 2)"/>
<button class="button m-4" v-tooltip="'Copy text'" style="position: absolute; top:0; right:0;"
@click="() => copyText(JSON.stringify(item, null, 2))">
<span class="icon"><i class="fas fa-copy"/></span>
</button>
</div>
</div>
<div class="card-footer">
<div class="card-footer-item">
<span class="icon"><i class="fas fa-calendar"></i>&nbsp;</span>

View File

@@ -100,7 +100,13 @@
</div>
</div>
<div class="card-content p-0 m-0" v-if="item?.showItem">
<pre><code>{{ JSON.stringify(item, null, 2) }}</code></pre>
<div class="mt-2" style="position: relative; max-height: 343px; overflow-y: auto;">
<code class="is-terminal is-block is-pre-wrap" v-text="JSON.stringify(item, null, 2)"/>
<button class="button m-4" v-tooltip="'Copy text'" style="position: absolute; top:0; right:0;"
@click="() => copyText(JSON.stringify(item, null, 2))">
<span class="icon"><i class="fas fa-copy"/></span>
</button>
</div>
</div>
<div class="card-footer">
<div class="card-footer-item">

View File

@@ -28,7 +28,7 @@
</p>
</header>
<section class="card-content p-0 m-0">
<div ref="outputConsole" style="min-height: 60vh;max-height:70vh;"/>
<div ref="outputConsole" style="min-height: 60vh; max-height:70vh;"/>
</section>
<section class="card-content p-1 m-1">
<div class="field">
@@ -106,6 +106,17 @@
</div>
</div>
</template>
<style>
.xterm {
padding: 0.50rem !important;
}
.xterm-viewport {
background-color: #1f2229 !important;
}
</style>
<script setup>
import "@xterm/xterm/css/xterm.css"
@@ -293,11 +304,13 @@ onMounted(async () => {
fontSize: 16,
fontFamily: "'JetBrains Mono', monospace",
cursorBlink: false,
cursorStyle: 'underline',
cursorStyle: 'none',
cols: 108,
rows: 10,
disableStdin: true,
convertEol: true,
altClickMovesCursor: false,
})
terminal.value.open(outputConsole.value)
terminal.value.loadAddon(terminalFit.value)

View File

@@ -439,8 +439,8 @@
</span>
</span>
<p class="subtitle">Useful for debugging.</p>
<div v-if="showRawData" class="mt-2" style="position: relative;">
<code class="is-block is-pre-wrap p-4">{{
<div v-if="showRawData" class="mt-2" style="position: relative; max-height: 400px; overflow-y: auto;">
<code class="is-terminal is-block is-pre-wrap p-4">{{
JSON.stringify(Object.keys(data)
.filter(key => !['files', 'hardware', 'content_exists', '_toggle'].includes(key))
.reduce((obj, key) => {

View File

@@ -252,12 +252,12 @@
</div>
</div>
<div class="card-content p-0 m-0" v-if="item?.showRawData">
<pre style="position: relative; max-height: 343px;"><code>{{ JSON.stringify(item, null, 2) }}</code>
<button class="button m-4" @click="() => copyText(JSON.stringify(item, null, 2))"
style="position: absolute; top:0; right:0;">
<span class="icon"><i class="fas fa-copy"></i></span>
</button>
</pre>
<pre class="is-terminal" style="position: relative; max-height: 343px;"><code
v-text="JSON.stringify(item, null, 2)"/><button class="button m-4"
@click="() => copyText(JSON.stringify(item, null, 2))"
style="position: absolute; top:0; right:0;">
<span class="icon"><i class="fas fa-copy"/></span>
</button></pre>
</div>
<div class="card-footer has-text-centered">
<div class="card-footer-item">

View File

@@ -86,22 +86,20 @@
</NuxtLink>
</span>
</h1>
<code class="box logs-container">
<code class="box logs-container is-terminal" style="border-radius: 0 !important;">
<span class="is-block" v-for="(item, index) in log.lines" :key="log.filename + '-' + index">
<template v-if="item?.date">[<span class="has-tooltip"
v-tooltip="`${moment(item.date).format(TOOLTIP_DATE_FORMAT)}`">
{{ moment(item.date).format('HH:mm:ss') }}</span>]
</template>
<template v-if="item?.item_id">
<NuxtLink @click="goto_history_item(item)">
<span class="icon-text">
v-tooltip="`${moment(item.date).format(TOOLTIP_DATE_FORMAT)}`">
{{ moment(item.date).format('HH:mm:ss') }}</span>]
</template>
<template v-if="item?.item_id">
<span @click="goto_history_item(item)" class="is-clickable has-tooltip">
<span class="icon"><i class="fas fa-history"/></span>
<span>View</span>
</span>
</NuxtLink>&nbsp;
</template>
<span>{{ item.text }}</span>
</span></code>
</span>&nbsp;
</template>
<span>{{ item.text }}</span>
</span></code>
</div>
<div class="column is-12">
@@ -142,7 +140,7 @@
import request from '~/utils/request'
import moment from 'moment'
import Message from '~/components/Message'
import {formatDuration, makeName, TOOLTIP_DATE_FORMAT, goto_history_item} from '~/utils/index'
import {formatDuration, goto_history_item, makeName, TOOLTIP_DATE_FORMAT} from '~/utils/index'
import {NuxtLink} from '#components'
import {useStorage} from '@vueuse/core'

View File

@@ -227,7 +227,8 @@
</div>
</div>
<div class="card-content p-0 m-0" v-if="item?.showRawData">
<pre style="position: relative; max-height: 343px;"><code>{{ JSON.stringify(item, null, 2) }}</code>
<pre style="position: relative; max-height: 343px;"
class="is-terminal"><code>{{ JSON.stringify(item, null, 2) }}</code>
<button class="button is-small m-4" @click="() => copyText(JSON.stringify(item, null, 2))"
style="position: absolute; top:0; right:0;">
<span class="icon"><i class="fas fa-copy"></i></span>

View File

@@ -189,7 +189,8 @@
</div>
</div>
<div class="card-content p-0 m-0" v-if="item?.showRawData">
<pre style="position: relative; max-height: 343px;"><code>{{ JSON.stringify(item, null, 2) }}</code>
<pre style="position: relative; max-height: 343px;"
class="is-terminal"><code>{{ JSON.stringify(item, null, 2) }}</code>
<button class="button is-small m-4" @click="() => copyText(JSON.stringify(item, null, 2))"
style="position: absolute; top:0; right:0;">
<span class="icon"><i class="fas fa-copy"></i></span>

View File

@@ -40,16 +40,17 @@
icon="fas fa-spinner fa-spin" message="Loading data. Please wait..."/>
<Message v-else class="has-background-warning-80 has-text-dark" title="Warning"
icon="fas fa-exclamation-triangle" :use-close="true" @close="filter = ''">
<div class="icon-text">
<div>
<span class="icon" v-if="filter"><i class="fas fa-filter"/></span>
No items found.
<span v-if="filter">For <code><strong>Filter</strong> : <strong>{{ filter }}</strong></code></span>
<span v-if="filter">For query: <code class="is-underlined is-bold" v-text="filter"/></span>
</div>
</Message>
</div>
<div v-else class="column is-12" v-if="items">
<div class="table-container">
<table class="table is-fullwidth is-hoverable is-striped">
<div class="table-container" style="max-height: 70vh; overflow-y: auto">
<table class="table is-fullwidth is-hoverable is-striped is-bordered">
<thead>
<tr>
<th>PID</th>

View File

@@ -9,8 +9,18 @@
<div class="is-pulled-right" v-if="false === show_report_warning">
<div class="field is-grouped">
<p class="control">
<button class="button is-primary" @click="copyText(data.join('\n'))" v-tooltip.bottom="'Copy Report'">
<span class="icon"><i class="fas fa-copy"></i></span>
<button class="button is-info" @click="scrollToTop" v-tooltip.bottom="'Scroll to top'">
<span class="icon"><i class="fas fa-arrow-up"/></span>
</button>
</p>
<p class="control">
<button class="button is-warning" @click="scrollToBottom" v-tooltip.bottom="'Scroll to bottom'">
<span class="icon"><i class="fas fa-arrow-down"/></span>
</button>
</p>
<p class="control">
<button class="button is-primary" @click="copyText(data.join('\n'))" v-tooltip.bottom="'Copy report'">
<span class="icon"><i class="fas fa-copy"/></span>
</button>
</p>
</div>
@@ -32,7 +42,7 @@
<NuxtLink class="is-block is-fullwidth is-primary" @click="show_report_warning = false">
<span class="icon-text">
<span class="icon"><i class="fas fa-thumbs-up"></i></span>
<span>I Understand. Show me the report.</span>
<span>I understand. Show me the report.</span>
</span>
</NuxtLink>
</div>
@@ -40,8 +50,10 @@
<Message message_class="has-background-info-90 has-text-dark" v-if="!show_report_warning && data.length < 1"
title="Loading" icon="fas fa-spinner fa-spin" message="Generating the report. Please wait..."/>
<template v-if="!show_report_warning && data.length > 0">
<pre style="min-height: 60vh;max-height:70vh; overflow-y: scroll" id="report-content"
><code><span v-for="(item, index) in data" :key="index" class="is-block">{{ item }}</span></code></pre>
<pre style="min-height: 60vh;max-height:70vh; overflow-y: scroll" class="is-terminal"
ref="data-content"><code><div ref="topMarker"></div><span v-for="(item, index) in data" :key="index"
class="is-block">{{ item }}</span></code><div
ref="bottomMarker"></div></pre>
</template>
</div>
</div>
@@ -57,6 +69,12 @@ useHead({title: `System Report`})
const data = ref([])
const show_report_warning = ref(true)
/** @type {Ref<HTMLPreElement|null>} */
const bottomMarker = ref(null)
/** @type {Ref<HTMLPreElement|null>} */
const topMarker = ref(null)
watch(show_report_warning, async v => {
if (false !== v) {
return
@@ -71,4 +89,15 @@ watch(show_report_warning, async v => {
data.value = json
})
const scrollToTop = () => {
if (topMarker.value) {
topMarker.value.scrollIntoView({behavior: 'smooth'})
}
}
const scrollToBottom = () => {
if (bottomMarker.value) {
bottomMarker.value.scrollIntoView({behavior: 'smooth'})
}
}
</script>

View File

@@ -45,7 +45,7 @@
<li>Reset all users backends last sync date.</li>
</ul>
<p>There is no undo operation. This action is irreversible.</p>
<p class="is-underlined is-bold">There is no undo operation. This action is irreversible.</p>
</Message>
</div>

View File

@@ -152,12 +152,12 @@
<div class="column is-12">
<span class="icon">
<i class="fa"
:class="{ 'fa-code': 'regex' === formData.type, 'fa-heading': 'contains' === formData.type }"></i>
:class="{ 'fa-code': 'regex' === formData.type, 'fa-r': 'contains' === formData.type }"></i>
</span>
<code>{{ item.rule }}</code>
</div>
<div class="column is-12">
<span class="icon"><i class="fa fa-font"></i></span>
<span class="icon"><i class="fa fa-e"></i></span>
<code>{{ item.example }}</code>
</div>
</div>