From 88b7456d49aef2c1a798fe791de304b4dba9486a Mon Sep 17 00:00:00 2001 From: Jonah <47046556+jwbonner@users.noreply.github.com> Date: Sat, 2 Nov 2024 16:16:47 -0400 Subject: [PATCH] Add option to highlight warnings and errors in console (closes #240) --- docsSite/docs/tab-reference/console.md | 4 +++ src/shared/renderers/ConsoleRenderer.ts | 46 +++++++++++++++++++++++-- www/hub.html | 7 ++-- www/renderers.css | 44 +++++++++++++++++++++-- www/satellite.html | 7 ++-- www/symbols/paintpalette.fill.svg | 11 ++++++ 6 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 www/symbols/paintpalette.fill.svg diff --git a/docsSite/docs/tab-reference/console.md b/docsSite/docs/tab-reference/console.md index c4d4bbd9..7443b1fc 100644 --- a/docsSite/docs/tab-reference/console.md +++ b/docsSite/docs/tab-reference/console.md @@ -16,3 +16,7 @@ Drag the desired field to the main view to get started. Each row represents an u ![Console view](./img/console-1.png) The controls are similar to the 🔢 [Table](../tab-reference/table.md) tab. The selected time is synchronized across all tabs. Click a row to select it, or hover over a row to preview it in any visible pop-up windows. Clicking the ↓ button jumps to the selected time (or the time entered in the box). Enter text in the "Filter" input to only display rows which contain the filter text. Press **Ctrl+F** to quickly select the "Filter" input. + +:::tip +Click the color palette icon to toggle highlighting for warning and error messages. Messages are highlighted if they contain the text "warning" or "error". +::: diff --git a/src/shared/renderers/ConsoleRenderer.ts b/src/shared/renderers/ConsoleRenderer.ts index 1667c10f..6b2c9334 100644 --- a/src/shared/renderers/ConsoleRenderer.ts +++ b/src/shared/renderers/ConsoleRenderer.ts @@ -4,10 +4,14 @@ import { arraysEqual, formatTimeWithMS, htmlEncode } from "../util"; import TabRenderer from "./TabRenderer"; export default class ConsoleRenderer implements TabRenderer { + private ERROR_TEXT = "error"; + private WARNING_TEXT = "warning"; + private TABLE_CONTAINER: HTMLElement; private TABLE_BODY: HTMLElement; private JUMP_INPUT: HTMLInputElement; private JUMP_BUTTON: HTMLInputElement; + private HIGHLIGHT_BUTTON: HTMLButtonElement; private FILTER_INPUT: HTMLInputElement; private FIELD_CELL: HTMLElement; private FIELD_TEXT: HTMLElement; @@ -32,6 +36,7 @@ export default class ConsoleRenderer implements TabRenderer { this.TABLE_BODY = this.TABLE_CONTAINER.firstElementChild?.firstElementChild as HTMLElement; this.JUMP_INPUT = this.TABLE_BODY.firstElementChild?.firstElementChild?.firstElementChild as HTMLInputElement; this.JUMP_BUTTON = this.TABLE_BODY.firstElementChild?.firstElementChild?.lastElementChild as HTMLInputElement; + this.HIGHLIGHT_BUTTON = this.TABLE_BODY.firstElementChild?.lastElementChild?.children[1] as HTMLButtonElement; this.FILTER_INPUT = this.TABLE_BODY.firstElementChild?.lastElementChild?.lastElementChild as HTMLInputElement; this.FIELD_CELL = this.TABLE_BODY.firstElementChild?.lastElementChild as HTMLElement; this.FIELD_TEXT = this.FIELD_CELL.firstElementChild?.firstElementChild as HTMLElement; @@ -69,6 +74,12 @@ export default class ConsoleRenderer implements TabRenderer { this.JUMP_BUTTON.addEventListener("click", jump); this.FILTER_INPUT.addEventListener("input", () => this.updateData()); + // Highlight button + this.HIGHLIGHT_BUTTON.addEventListener("click", () => { + this.HIGHLIGHT_BUTTON.classList.toggle("active"); + this.updateData(); + }); + // Delete button handling this.FIELD_DELETE.addEventListener("click", () => { root.dispatchEvent(new CustomEvent("close-field")); @@ -87,10 +98,22 @@ export default class ConsoleRenderer implements TabRenderer { } saveState(): unknown { - return null; + return { + highlight: this.HIGHLIGHT_BUTTON.classList.contains("active") + }; } - restoreState(state: unknown): void {} + restoreState(state: unknown): void { + if (state === null || typeof state !== "object") return; + if ("highlight" in state && typeof state.highlight === "boolean") { + if (state.highlight) { + this.HIGHLIGHT_BUTTON.classList.add("active"); + } else { + this.HIGHLIGHT_BUTTON.classList.remove("active"); + } + this.updateData(); + } + } getAspectRatio(): number | null { return null; @@ -244,6 +267,24 @@ export default class ConsoleRenderer implements TabRenderer { } valueFormatted = valueFormatted.replaceAll("\n", "
"); + // Update highlight + let row = this.TABLE_BODY.children[i + 1]; + if (this.HIGHLIGHT_BUTTON.classList.contains("active")) { + if (values[i].toLowerCase().includes(this.ERROR_TEXT)) { + row.classList.add("error"); + } else { + row.classList.remove("error"); + } + if (values[i].toLowerCase().includes(this.WARNING_TEXT)) { + row.classList.add("warning"); + } else { + row.classList.remove("warning"); + } + } else { + row.classList.remove("error"); + row.classList.remove("warning"); + } + // Check if value has changed let hasChanged = false; if (i > this.renderedTimestamps.length) { @@ -256,7 +297,6 @@ export default class ConsoleRenderer implements TabRenderer { // Update cell contents if (hasChanged) { - let row = this.TABLE_BODY.children[i + 1]; (row.children[0] as HTMLElement).innerText = formatTimeWithMS(timestamps[i]); (row.children[1] as HTMLElement).innerHTML = valueFormatted; } diff --git a/www/hub.html b/www/hub.html index 1ccd3e7a..c668adb5 100644 --- a/www/hub.html +++ b/www/hub.html @@ -587,12 +587,15 @@
- Hello +
- + + diff --git a/www/renderers.css b/www/renderers.css index 6c9f5446..2f635da4 100644 --- a/www/renderers.css +++ b/www/renderers.css @@ -488,7 +488,7 @@ table.console-table th:not(:first-child) div { left: 0px; top: 0px; height: 30px; - right: 200px; + right: 218px; padding-left: 5px; overflow: hidden; font-size: 14px; @@ -497,7 +497,23 @@ table.console-table th:not(:first-child) div { white-space: nowrap; } -table.console-table th:not(:first-child) input { +table.console-table button.highlight-button { + position: absolute; + top: 50%; + right: 188px; + height: 25px; + width: 25px; + padding-top: 9px; + padding-bottom: 9px; + transform: translateY(-50%); +} + +table.console-table button.highlight-button.active img { + /* https://codepen.io/sosuke/pen/Pjoqqp */ + filter: invert(84%) sepia(28%) saturate(6635%) hue-rotate(354deg) brightness(96%) contrast(112%); +} + +table.console-table input.filter { position: absolute; top: 50%; right: 5px; @@ -551,6 +567,30 @@ table.console-table tr.selected td { background-color: #e3e3e3; } +table.console-table tr.warning td { + background-color: #ffaa0055; +} + +table.console-table tr.warning.hovered td { + background-color: #ffaa0088; +} + +table.console-table tr.warning.selected td { + background-color: #ffaa00aa; +} + +table.console-table tr.error td { + background-color: #ff000055; +} + +table.console-table tr.error.hovered td { + background-color: #ff000088; +} + +table.console-table tr.error.selected td { + background-color: #ff0000aa; +} + @media (prefers-color-scheme: dark) { table.console-table th { border-right: 1px solid #333; diff --git a/www/satellite.html b/www/satellite.html index fd54f73f..d380e765 100644 --- a/www/satellite.html +++ b/www/satellite.html @@ -108,12 +108,15 @@
- Hello +
- + + diff --git a/www/symbols/paintpalette.fill.svg b/www/symbols/paintpalette.fill.svg new file mode 100644 index 00000000..5fcac83c --- /dev/null +++ b/www/symbols/paintpalette.fill.svg @@ -0,0 +1,11 @@ + + + + + + + + +