diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css b/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css
index d16943f55..5ccbe397d 100644
--- a/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css
+++ b/dashboard/src/assets/mdi-subset/materialdesignicons-subset.css
@@ -1,4 +1,4 @@
-/* Auto-generated MDI subset – 258 icons */
+/* Auto-generated MDI subset – 257 icons */
/* Do not edit manually. Run: pnpm run subset-icons */
@font-face {
@@ -140,10 +140,6 @@
content: "\F08A7";
}
-.mdi-calendar-multiple::before {
- content: "\F00F1";
-}
-
.mdi-calendar-plus::before {
content: "\F00F3";
}
diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff
index d8440ff58..eaa3ed4b9 100644
Binary files a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff and b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff differ
diff --git a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2
index 3d6d6e6e8..7f20c9d0c 100644
Binary files a/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 and b/dashboard/src/assets/mdi-subset/materialdesignicons-webfont-subset.woff2 differ
diff --git a/dashboard/src/components/shared/ConsoleDisplayer.vue b/dashboard/src/components/shared/ConsoleDisplayer.vue
index cf4be65cf..8789925ca 100644
--- a/dashboard/src/components/shared/ConsoleDisplayer.vue
+++ b/dashboard/src/components/shared/ConsoleDisplayer.vue
@@ -23,7 +23,7 @@ import { EventSourcePolyfill } from 'event-source-polyfill';
>
-
@@ -279,6 +279,36 @@ export default {
this.isFullscreen = !!document.fullscreenElement;
},
+ appendLogContent(element, log) {
+ const levelMatch = log.match(/\[(DEBG|INFO|WARN|ERRO|CRIT|DEBUG|WARNING|ERROR|CRITICAL)\]/);
+ if (!levelMatch) {
+ element.innerText = `${log}`;
+ return;
+ }
+
+ const levelStart = levelMatch.index;
+ const levelEnd = levelStart + levelMatch[0].length;
+ const prefix = log.slice(0, levelStart).trimEnd();
+ const message = log.slice(levelEnd).trimStart();
+
+ const prefixSpan = document.createElement('span');
+ prefixSpan.className = 'console-log-prefix';
+ prefixSpan.innerText = prefix;
+
+ const levelSpan = document.createElement('span');
+ levelSpan.className = 'console-log-level';
+ levelSpan.innerText = levelMatch[0];
+
+ const messageSpan = document.createElement('span');
+ messageSpan.className = 'console-log-message';
+ messageSpan.innerText = message;
+
+ element.classList.add('console-log-line--structured');
+ element.appendChild(prefixSpan);
+ element.appendChild(levelSpan);
+ element.appendChild(messageSpan);
+ },
+
printLog(log) {
let ele = document.getElementById('term')
if (!ele) {
@@ -297,7 +327,7 @@ export default {
span.style = style
span.classList.add('console-log-line', 'fade-in')
- span.innerText = `${log}`;
+ this.appendLogContent(span, log);
ele.appendChild(span)
if (this.autoScroll) {
ele.scrollTop = ele.scrollHeight
@@ -325,7 +355,14 @@ export default {
flex-wrap: wrap;
gap: 8px;
margin-bottom: 8px;
- margin-left: 20px;
+}
+
+.console-term {
+ background-color: #1e1e1e;
+ border-radius: 8px;
+ height: 100%;
+ overflow-y: auto;
+ padding: 16px;
}
.fullscreen-btn {
@@ -334,12 +371,35 @@ export default {
:deep(.console-log-line) {
display: block;
- margin-bottom: 2px;
+ margin: 0 0 2px;
font-family: SFMono-Regular, Menlo, Monaco, Consolas, var(--astrbot-font-cjk-mono), monospace;
font-size: 12px;
white-space: pre-wrap;
}
+:deep(.console-log-line--structured) {
+ display: grid;
+ grid-template-columns: max-content 10ch minmax(0, 1fr);
+ column-gap: 8px;
+ align-items: start;
+ white-space: normal;
+}
+
+:deep(.console-log-prefix),
+:deep(.console-log-level),
+:deep(.console-log-message) {
+ min-width: 0;
+ white-space: pre-wrap;
+}
+
+:deep(.console-log-level) {
+ font-variant-numeric: tabular-nums;
+}
+
+:deep(.console-log-message) {
+ overflow-wrap: anywhere;
+}
+
:deep(.fade-in) {
animation: fadeIn 0.3s;
}
diff --git a/dashboard/src/styles/dashboard-shell.css b/dashboard/src/styles/dashboard-shell.css
index 83a4bd31e..7398d3b1e 100644
--- a/dashboard/src/styles/dashboard-shell.css
+++ b/dashboard/src/styles/dashboard-shell.css
@@ -38,27 +38,18 @@
min-width: 0;
}
-.dashboard-eyebrow {
- margin-bottom: 8px;
- color: var(--dashboard-subtle);
- font-size: 12px;
- font-weight: 600;
- letter-spacing: 0.08em;
- text-transform: uppercase;
-}
-
.dashboard-title {
margin: 0;
- font-size: clamp(32px, 4vw, 44px);
- line-height: 1.04;
+ font-size: 1.5rem;
+ line-height: 1.2;
font-weight: 700;
- letter-spacing: -0.04em;
+ letter-spacing: 0;
}
.dashboard-subtitle {
- margin: 10px 0 0;
+ margin: 4px 0 0;
color: var(--dashboard-muted);
- font-size: 15px;
+ font-size: 0.875rem;
line-height: 1.6;
max-width: 860px;
}
diff --git a/dashboard/src/views/ConsolePage.vue b/dashboard/src/views/ConsolePage.vue
index b4c813f49..04575c334 100644
--- a/dashboard/src/views/ConsolePage.vue
+++ b/dashboard/src/views/ConsolePage.vue
@@ -7,20 +7,13 @@ const { tm } = useModuleI18n('features/console');
-
-
+
+
-
+
-
diff --git a/dashboard/src/views/CronJobPage.vue b/dashboard/src/views/CronJobPage.vue
index dbc8f410e..b59d3b0be 100644
--- a/dashboard/src/views/CronJobPage.vue
+++ b/dashboard/src/views/CronJobPage.vue
@@ -3,7 +3,6 @@