diff --git a/ui/app/pages/console.vue b/ui/app/pages/console.vue
index e91b1b69..f5c8d4fb 100644
--- a/ui/app/pages/console.vue
+++ b/ui/app/pages/console.vue
@@ -87,8 +87,7 @@
- Press Enter to run single-line input, Shift+Enter to
- switch to multi-line, and Ctrl+Enter to run multi-line input.
+ Shift+Enter to switch to multi-line input.
diff --git a/ui/app/pages/logs.vue b/ui/app/pages/logs.vue
index 701f954f..f590ccec 100644
--- a/ui/app/pages/logs.vue
+++ b/ui/app/pages/logs.vue
@@ -130,16 +130,18 @@
v-if="canLoadFilteredHistory"
class="flex justify-center border-b border-default/40 px-4 py-3"
>
-
+
Load older lines into filter
-
+
@@ -204,20 +206,29 @@
v-else
class="flex min-h-[55vh] flex-col items-center justify-center gap-3 px-6 py-8 text-center font-sans"
>
-
+
+
+
+
Loading logs...
+
Connecting to log stream.
+
+
-
-
- {{ hasActiveFilter ? 'No logs match these filters' : 'No log lines available' }}
-
+
+
+
+
No logs match these filters
+
Try adjusting or clearing the filters.
+
+
-
- {{ hasActiveFilter ? 'No logs match these filters' : 'No log lines available' }}
-
-
+
+
+
+
No log lines available
+
There are no log entries to display.
+
+
@@ -319,16 +330,15 @@ const normalizedQuery = computed(() => query.value.trim().toLowerCase());
const selectedLevelSet = computed(
() => new Set(LOG_LEVELS.filter((level) => selectedLevels.value.includes(level))),
);
-const hasLevelFilter = computed(() => selectedLevelSet.value.size !== LOG_LEVELS.length);
const filterContext = computed(() => {
const match = normalizedQuery.value.match(FILTER_CONTEXT_REGEX);
return match ? parseInt(match[1] ?? '0', 10) : 0;
});
const searchTerm = computed(() => normalizedQuery.value.replace(FILTER_CONTEXT_REGEX, '').trim());
const hasTextFilter = computed(() => Boolean(searchTerm.value));
-const hasActiveFilter = computed(() => hasTextFilter.value || hasLevelFilter.value);
+const hasActiveFilter = computed(() => hasTextFilter.value);
const canLoadFilteredHistory = computed(
- () => hasActiveFilter.value && !reachedEnd.value && logs.value.length > 0,
+ () => hasTextFilter.value && !reachedEnd.value && logs.value.length > 0,
);
const levelCounts = computed>(() => {
const counts: Record = {
@@ -413,12 +423,14 @@ watch(detailsOpen, (open) => {
const filteredLogs = computed(() => {
if (!hasActiveFilter.value) {
- return logs.value.map((log) => ({
- log,
- level: getLogLevel(log.level),
- isMatch: false,
- isContext: false,
- }));
+ return logs.value
+ .filter((log) => selectedLevelSet.value.has(getLogLevel(log.level)))
+ .map((log) => ({
+ log,
+ level: getLogLevel(log.level),
+ isMatch: false,
+ isContext: false,
+ }));
}
const result: Array = [];
@@ -483,7 +495,7 @@ const scrollLogContainerToBottom = async (behavior: ScrollBehavior = 'auto'): Pr
const fetchLogs = async (force = false): Promise => {
loading.value = true;
- if (reachedEnd.value || (!force && hasActiveFilter.value && logs.value.length > 0)) {
+ if (reachedEnd.value || (!force && hasTextFilter.value && logs.value.length > 0)) {
loading.value = false;
return;
}
@@ -525,7 +537,7 @@ const fetchLogs = async (force = false): Promise => {
};
const handleScroll = (): void => {
- if (!logContainer.value || hasActiveFilter.value) {
+ if (!logContainer.value || hasTextFilter.value) {
return;
}
@@ -535,11 +547,11 @@ const handleScroll = (): void => {
autoScroll.value = nearBottom;
- if (nearTop && !loading.value && !scrollTimeout) {
+ if (nearTop && !loading.value && !scrollTimeout && !reachedEnd.value) {
scrollTimeout = setTimeout(async () => {
const previousHeight = container.scrollHeight;
await fetchLogs();
- nextTick(() => {
+ await nextTick(() => {
const newHeight = container.scrollHeight;
container.scrollTop += newHeight - previousHeight;
});