chore: frontend updates
This commit is contained in:
parent
570c0ba087
commit
7345744e41
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
<title>OliveTin</title>
|
||||
|
||||
<link rel = "stylesheet" type = "text/css" href = "/style.css" />
|
||||
<link rel = "stylesheet" type = "text/css" href = "/theme.css" />
|
||||
<link rel = "stylesheet" href = "node_modules/@xterm/xterm/css/xterm.css" />
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
import 'femtocrank/style.css'
|
||||
import '/style.css'
|
||||
|
||||
import { createClient } from '@connectrpc/connect'
|
||||
import { createConnectTransport } from '@connectrpc/connect-web'
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -11,8 +11,8 @@
|
|||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.3.1",
|
||||
"process": "^0.11.10",
|
||||
"stylelint": "^15.6.0",
|
||||
"stylelint-config-standard": "^33.0.0"
|
||||
"stylelint": "^16.23.1",
|
||||
"stylelint-config-standard": "^39.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
|
|
@ -27,16 +27,16 @@
|
|||
],
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@connectrpc/connect": "^2.0.3",
|
||||
"@connectrpc/connect-web": "^2.0.3",
|
||||
"@connectrpc/connect": "^2.1.0",
|
||||
"@connectrpc/connect-web": "^2.1.0",
|
||||
"@hugeicons/core-free-icons": "^1.0.16",
|
||||
"@hugeicons/vue": "^1.0.3",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"femtocrank": "^1.2.4",
|
||||
"unplugin-vue-components": "^28.8.0",
|
||||
"vite": "^7.0.6",
|
||||
"picocrank": "^1.3.1",
|
||||
"unplugin-vue-components": "^29.0.0",
|
||||
"vite": "^7.1.4",
|
||||
"vue-router": "^4.5.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,6 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div class="fg1">
|
||||
<Breadcrumbs />
|
||||
</div>
|
||||
|
||||
<div id="banner" v-if="bannerMessage" :style="bannerCss">
|
||||
<p>{{ bannerMessage }}</p>
|
||||
</div>
|
||||
|
|
@ -65,10 +61,11 @@
|
|||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import Sidebar from './components/Sidebar.vue';
|
||||
import Sidebar from 'picocrank/vue/components/Sidebar.vue';
|
||||
import { HugeiconsIcon } from '@hugeicons/vue'
|
||||
import { Menu01Icon } from '@hugeicons/core-free-icons'
|
||||
import { UserCircle02Icon } from '@hugeicons/core-free-icons'
|
||||
import { DashboardSquare01Icon } from '@hugeicons/core-free-icons'
|
||||
|
||||
const sidebar = ref(null);
|
||||
const username = ref('guest');
|
||||
|
|
@ -88,22 +85,29 @@ async function requestInit() {
|
|||
try {
|
||||
const initResponse = await window.client.init({})
|
||||
|
||||
console.log("init response", initResponse)
|
||||
|
||||
username.value = initResponse.authenticatedUser
|
||||
currentVersion.value = initResponse.currentVersion
|
||||
bannerMessage.value = initResponse.bannerMessage || '';
|
||||
bannerCss.value = initResponse.bannerCss || '';
|
||||
|
||||
sidebar.value.addRouterLink('Actions')
|
||||
|
||||
for (const rootDashboard of initResponse.rootDashboards) {
|
||||
sidebar.value.addNavigationLink({
|
||||
id: rootDashboard,
|
||||
name: rootDashboard,
|
||||
title: rootDashboard,
|
||||
path: `/dashboards/${rootDashboard}`,
|
||||
icon: '📊'
|
||||
icon: DashboardSquare01Icon,
|
||||
})
|
||||
}
|
||||
|
||||
sidebar.value.addSeparator()
|
||||
sidebar.value.addRouterLink('Entities')
|
||||
sidebar.value.addRouterLink('Logs')
|
||||
sidebar.value.addRouterLink('Diagnostics')
|
||||
|
||||
|
||||
hasLoaded.value = true;
|
||||
} catch (error) {
|
||||
console.error("Error initializing client", error)
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ const props = defineProps({
|
|||
const dashboard = ref(null)
|
||||
|
||||
async function getDashboard() {
|
||||
console.log("getting dashboard", props.title)
|
||||
const ret = await window.client.getDashboard({
|
||||
title: props.title,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,246 +0,0 @@
|
|||
<template>
|
||||
<aside :class="{ 'shown': isOpen, 'stuck': isStuck }" class="sidebar">
|
||||
<div class = "flex-row">
|
||||
<h2>Navigation</h2>
|
||||
<div class = "fg1" />
|
||||
<button
|
||||
class="stick-toggle"
|
||||
:aria-pressed="isStuck"
|
||||
:title="isStuck ? 'Unstick sidebar' : 'Stick sidebar'"
|
||||
@click="toggleStick"
|
||||
>
|
||||
<span v-if="isStuck">
|
||||
<HugeiconsIcon :icon="Pin02Icon" width = "1em" height = "1em" />
|
||||
</span>
|
||||
<span v-else>
|
||||
<HugeiconsIcon :icon="PinIcon" width = "1em" height = "1em" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav class="mainnav">
|
||||
<ul class="navigation-links">
|
||||
<li v-for="link in navigationLinks" :key="link.id" :title="link.title">
|
||||
<router-link :to="link.path" :class="{ active: isActive(link.path) }">
|
||||
<HugeiconsIcon :icon="link.icon" />
|
||||
<span>{{ link.title }}</span>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="supplemental-links">
|
||||
<li v-for="link in supplementalLinks" :key="link.id" :title="link.title">
|
||||
<router-link :to="link.path" :class="{ active: isActive(link.path) }">
|
||||
<HugeiconsIcon :icon="link.icon" />
|
||||
<span>{{ link.title }}</span>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { HugeiconsIcon } from '@hugeicons/vue'
|
||||
import { DashboardSquare01Icon } from '@hugeicons/core-free-icons'
|
||||
import { LeftToRightListDashIcon } from '@hugeicons/core-free-icons'
|
||||
import { Wrench01Icon } from '@hugeicons/core-free-icons'
|
||||
import { Pin02Icon } from '@hugeicons/core-free-icons'
|
||||
import { PinIcon } from '@hugeicons/core-free-icons'
|
||||
import { CellsIcon } from '@hugeicons/core-free-icons'
|
||||
|
||||
const isOpen = ref(false)
|
||||
const isStuck = ref(false)
|
||||
const navigationLinks = ref([
|
||||
{
|
||||
id: 'actions',
|
||||
title: 'Actions',
|
||||
path: '/',
|
||||
icon: DashboardSquare01Icon,
|
||||
}
|
||||
])
|
||||
|
||||
const supplementalLinks = ref([
|
||||
{
|
||||
id: 'entities',
|
||||
title: 'Entities',
|
||||
path: '/entities',
|
||||
icon: CellsIcon,
|
||||
},
|
||||
{
|
||||
id: 'logs',
|
||||
title: 'Logs',
|
||||
path: '/logs',
|
||||
icon: LeftToRightListDashIcon,
|
||||
},
|
||||
{
|
||||
id: 'diagnostics',
|
||||
title: 'Diagnostics',
|
||||
path: '/diagnostics',
|
||||
icon: Wrench01Icon,
|
||||
}
|
||||
])
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
function toggleStick() {
|
||||
isStuck.value = !isStuck.value
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
isOpen.value = !isOpen.value
|
||||
isStuck.value = false
|
||||
}
|
||||
|
||||
function open() {
|
||||
isOpen.value = true
|
||||
}
|
||||
|
||||
function close() {
|
||||
isOpen.value = false
|
||||
isStuck.value = false
|
||||
}
|
||||
|
||||
function isActive(path) {
|
||||
return route.path === path
|
||||
}
|
||||
|
||||
// Method to add navigation links from other components
|
||||
function addNavigationLink(link) {
|
||||
link.icon = DashboardSquare01Icon
|
||||
|
||||
const existingIndex = navigationLinks.value.findIndex(l => l.id === link.id)
|
||||
if (existingIndex >= 0) {
|
||||
navigationLinks.value[existingIndex] = { ...link }
|
||||
} else {
|
||||
navigationLinks.value.push({ ...link })
|
||||
}
|
||||
}
|
||||
|
||||
// Method to add supplemental links from other components
|
||||
function addSupplementalLink(link) {
|
||||
const existingIndex = supplementalLinks.value.findIndex(l => l.id === link.id)
|
||||
if (existingIndex >= 0) {
|
||||
supplementalLinks.value[existingIndex] = { ...link }
|
||||
} else {
|
||||
supplementalLinks.value.push({ ...link })
|
||||
}
|
||||
}
|
||||
|
||||
// Method to remove links
|
||||
function removeNavigationLink(linkId) {
|
||||
navigationLinks.value = navigationLinks.value.filter(link => link.id !== linkId)
|
||||
}
|
||||
|
||||
function removeSupplementalLink(linkId) {
|
||||
supplementalLinks.value = supplementalLinks.value.filter(link => link.id !== linkId)
|
||||
}
|
||||
|
||||
// Method to clear all links
|
||||
function clearNavigationLinks() {
|
||||
navigationLinks.value = []
|
||||
}
|
||||
|
||||
function clearSupplementalLinks() {
|
||||
supplementalLinks.value = []
|
||||
}
|
||||
|
||||
// Method to get all links
|
||||
function getNavigationLinks() {
|
||||
return [...navigationLinks.value]
|
||||
}
|
||||
|
||||
function getSupplementalLinks() {
|
||||
return [...supplementalLinks.value]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// Make the sidebar globally accessible
|
||||
window.sidebar = {
|
||||
get isOpen() { return isOpen.value },
|
||||
set isOpen(val) { isOpen.value = val },
|
||||
toggle,
|
||||
open,
|
||||
close,
|
||||
addNavigationLink,
|
||||
addSupplementalLink,
|
||||
removeNavigationLink,
|
||||
removeSupplementalLink,
|
||||
clearNavigationLinks,
|
||||
clearSupplementalLinks,
|
||||
getNavigationLinks,
|
||||
getSupplementalLinks
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
isOpen,
|
||||
navigationLinks,
|
||||
supplementalLinks,
|
||||
toggle,
|
||||
open,
|
||||
close,
|
||||
isActive,
|
||||
addNavigationLink,
|
||||
addSupplementalLink,
|
||||
removeNavigationLink,
|
||||
removeSupplementalLink,
|
||||
clearNavigationLinks,
|
||||
clearSupplementalLinks,
|
||||
getNavigationLinks,
|
||||
getSupplementalLinks
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.navigation-links a,
|
||||
.supplemental-links a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: #333;
|
||||
transition: background-color 0.2s ease;
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
|
||||
.navigation-links a:hover,
|
||||
.supplemental-links a:hover {
|
||||
background: #f8f9fa;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 1.2em;
|
||||
width: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.supplemental-links {
|
||||
border-top: 1px solid #eee;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
/* Responsive design */
|
||||
@media (max-width: 768px) {
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
left: -100%;
|
||||
}
|
||||
|
||||
.sidebar.shown {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
import { Wrench01Icon } from '@hugeicons/core-free-icons'
|
||||
import { LeftToRightListDashIcon } from '@hugeicons/core-free-icons'
|
||||
import { CellsIcon } from '@hugeicons/core-free-icons'
|
||||
import { DashboardSquare01Icon } from '@hugeicons/core-free-icons'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Home',
|
||||
name: 'Actions',
|
||||
component: () => import('./Dashboard.vue'),
|
||||
props: { title: 'default' },
|
||||
meta: { title: 'OliveTin - Dashboard' }
|
||||
meta: { title: 'Actions', icon: DashboardSquare01Icon }
|
||||
},
|
||||
{
|
||||
path: '/dashboards/:title',
|
||||
|
|
@ -26,13 +31,19 @@ const routes = [
|
|||
path: '/logs',
|
||||
name: 'Logs',
|
||||
component: () => import('./views/LogsListView.vue'),
|
||||
meta: { title: 'OliveTin - Logs' }
|
||||
meta: {
|
||||
title: 'OliveTin - Logs',
|
||||
icon: LeftToRightListDashIcon
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/entities',
|
||||
name: 'Entities',
|
||||
component: () => import('./views/EntitiesView.vue'),
|
||||
meta: { title: 'OliveTin - Entities' }
|
||||
meta: {
|
||||
title: 'OliveTin - Entities',
|
||||
icon: CellsIcon
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/entity-details/:entityType/:entityKey',
|
||||
|
|
@ -64,7 +75,10 @@ const routes = [
|
|||
path: '/diagnostics',
|
||||
name: 'Diagnostics',
|
||||
component: () => import('./views/DiagnosticsView.vue'),
|
||||
meta: { title: 'OliveTin - Diagnostics' }
|
||||
meta: {
|
||||
title: 'OliveTin - Diagnostics',
|
||||
icon: Wrench01Icon
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
|
|
|
|||
|
|
@ -1,55 +1,40 @@
|
|||
<template>
|
||||
<section>
|
||||
<div class="section-header">
|
||||
<h2>Get support</h2>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p>If you are having problems with OliveTin and want to raise a support request, it would be very helpful to include a sosreport from this page.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://docs.olivetin.app/sosreport.html" target="_blank">sosreport Documentation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href = "https://docs.olivetin.app/troubleshooting/wheretofindhelp.html" target="_blank">Where to find help</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<Section title = "Get support">
|
||||
<p>If you are having problems with OliveTin and want to raise a support request, it would be very helpful to include a sosreport from this page.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://docs.olivetin.app/sosreport.html" target="_blank">sosreport Documentation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href = "https://docs.olivetin.app/troubleshooting/wheretofindhelp.html" target="_blank">Where to find help</a>
|
||||
</li>
|
||||
</ul>
|
||||
</Section>
|
||||
|
||||
<section>
|
||||
<div class="section-header">
|
||||
<h2>SSH</h2>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<dl>
|
||||
<dt>Found Key</dt>
|
||||
<dd>{{ diagnostics.sshFoundKey || '?' }}</dd>
|
||||
<dt>Found Config</dt>
|
||||
<dd>{{ diagnostics.sshFoundConfig || '?' }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</section>
|
||||
<Section title = "SSH">
|
||||
<dl>
|
||||
<dt>Found Key</dt>
|
||||
<dd>{{ diagnostics.sshFoundKey || '?' }}</dd>
|
||||
<dt>Found Config</dt>
|
||||
<dd>{{ diagnostics.sshFoundConfig || '?' }}</dd>
|
||||
</dl>
|
||||
</Section>
|
||||
|
||||
<section>
|
||||
<div class="section-header">
|
||||
<h2>SOS Report</h2>
|
||||
<Section title = "SOS Report">
|
||||
<p>This section allows you to generate a detailed report of your configuration and environment. It is a good idea to include this when raising a support request.</p>
|
||||
|
||||
<div role="toolbar">
|
||||
<button @click="generateSosReport" :disabled="loading" class = "good">Generate SOS Report</button>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
|
||||
<p>This section allows you to generate a detailed report of your configuration and environment. It is a good idea to include this when raising a support request.</p>
|
||||
|
||||
<div role="toolbar">
|
||||
<button @click="generateSosReport" :disabled="loading" class = "good">Generate SOS Report</button>
|
||||
</div>
|
||||
|
||||
<textarea v-model="sosReport" readonly style="flex: 1; min-height: 200px; resize: vertical;"></textarea>
|
||||
</div>
|
||||
</section>
|
||||
<textarea v-model="sosReport" readonly style="flex: 1; min-height: 200px; resize: vertical;"></textarea>
|
||||
</Section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import Section from 'picocrank/vue/components/Section.vue'
|
||||
|
||||
const diagnostics = ref({})
|
||||
const loading = ref(false)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
<template>
|
||||
<section class = "with-header-and-content" v-if="entityDefinitions.length === 0">
|
||||
<Section class = "with-header-and-content" v-if="entityDefinitions.length === 0" title="Loading entity definitions...">
|
||||
<div class = "section-header">
|
||||
<h2 class="loading-message">
|
||||
Loading entity definitions...
|
||||
</h2>
|
||||
</div>
|
||||
</section>
|
||||
</Section>
|
||||
<template v-else>
|
||||
<section v-for="def in entityDefinitions" :key="def.name" class="with-header-and-content">
|
||||
<div class = "section-header">
|
||||
<h2>Entity: {{ def.title }}</h2>
|
||||
</div>
|
||||
|
||||
<Section v-for="def in entityDefinitions" :key="def.name" :title="'Entity: ' + def.title ">
|
||||
<div class = "section-content">
|
||||
<p>{{ def.instances.length }} instances.</p>
|
||||
|
||||
|
|
@ -32,12 +28,13 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</Section>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import Section from 'picocrank/vue/components/Section.vue'
|
||||
|
||||
const entityDefinitions = ref([])
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,16 @@
|
|||
<template>
|
||||
<section class="with-header-and-content">
|
||||
<div class="section-header">
|
||||
<h2>Entity Details</h2>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<Section title="Entity Details">
|
||||
<div>
|
||||
<p v-if="!entityDetails">Loading entity details...</p>
|
||||
<p v-else-if="!entityDetails.title">No details available for this entity.</p>
|
||||
<p v-else>{{ entityDetails.title }}</p>
|
||||
</div>
|
||||
</section>
|
||||
</Section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import Section from 'picocrank/vue/components/Section.vue'
|
||||
|
||||
const entityDetails = ref(null)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,16 @@
|
|||
<template>
|
||||
<section class="with-header-and-content">
|
||||
<div class="section-header">
|
||||
<h2>Execution Results: {{ title }}</h2>
|
||||
|
||||
<Section :title="'Execution Results: ' + title">
|
||||
<template #toolbar>
|
||||
<button @click="toggleSize" title="Toggle dialog size">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path fill="currentColor"
|
||||
d="M3 3h6v2H6.462l4.843 4.843l-1.415 1.414L5 6.367V9H3zm0 18h6v-2H6.376l4.929-4.928l-1.415-1.414L5 17.548V15H3zm12 0h6v-6h-2v2.524l-4.867-4.866l-1.414 1.414L17.647 19H15zm6-18h-6v2h2.562l-4.843 4.843l1.414 1.414L19 6.39V9h2z" />
|
||||
</svg>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<div v-if="logEntry">
|
||||
<div class="action-header padded-content" style="float: right">
|
||||
<span class="icon" role="img" v-html="icon"></span>
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<div v-if="logEntry" class = "flex-row">
|
||||
<dl class = "fg1">
|
||||
<dt>Duration</dt>
|
||||
<dd><span v-html="duration"></span></dd>
|
||||
|
||||
|
|
@ -26,9 +19,10 @@
|
|||
<ActionStatusDisplay :log-entry="logEntry" />
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<span class="icon" role="img" v-html="icon" style = "align-self: start"></span>
|
||||
</div>
|
||||
|
||||
<div ref="xtermOutput"></div>
|
||||
<div ref="xtermOutput"></div>
|
||||
|
||||
<br />
|
||||
|
||||
|
|
@ -49,13 +43,14 @@
|
|||
Kill
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</Section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
|
||||
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||
import ActionStatusDisplay from '../components/ActionStatusDisplay.vue'
|
||||
import Section from 'picocrank/vue/components/Section.vue'
|
||||
import { OutputTerminal } from '../../../js/OutputTerminal.js'
|
||||
import { HugeiconsIcon } from '@hugeicons/vue'
|
||||
import { WorkoutRunIcon, Cancel02Icon, ArrowLeftIcon } from '@hugeicons/core-free-icons'
|
||||
|
|
@ -66,7 +61,6 @@ const router = useRouter()
|
|||
|
||||
// Refs for DOM elements
|
||||
const xtermOutput = ref(null)
|
||||
const dialog = ref(null)
|
||||
|
||||
const props = defineProps({
|
||||
executionTrackingId: {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
<template>
|
||||
<section>
|
||||
<div class="section-header">
|
||||
<h2>Logs</h2>
|
||||
|
||||
<div>
|
||||
<Section title="Logs" :padding="false">
|
||||
<template #toolbar>
|
||||
<label class="input-with-icons">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path fill="currentColor"
|
||||
|
|
@ -17,12 +14,9 @@
|
|||
</svg>
|
||||
</button>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<p>This is a list of logs from actions that have been executed. You can filter the list by action title.</p>
|
||||
<p class = "padding">This is a list of logs from actions that have been executed. You can filter the list by action title.</p>
|
||||
<div v-show="filteredLogs.length > 0">
|
||||
<table class="logs-table">
|
||||
<thead>
|
||||
|
|
@ -60,7 +54,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
<Pagination :pageSize="pageSize" :total="totalCount" :currentPage="currentPage" @page-change="handlePageChange"
|
||||
<Pagination :pageSize="pageSize" :total="totalCount" :currentPage="currentPage" @page-change="handlePageChange" class = "padding"
|
||||
@page-size-change="handlePageSizeChange" itemTitle="execution logs" />
|
||||
</div>
|
||||
|
||||
|
|
@ -68,13 +62,13 @@
|
|||
<p>There are no logs to display.</p>
|
||||
<router-link to="/">Return to index</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import Pagination from '../components/Pagination.vue'
|
||||
import Section from 'picocrank/vue/components/Section.vue'
|
||||
|
||||
const logs = ref([])
|
||||
const searchText = ref('')
|
||||
|
|
|
|||
|
|
@ -92,10 +92,6 @@ div.buttons button svg {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
section .section-content {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
font-size: small;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue