mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 10:16:46 +00:00
Adds more log types to the system tab (#5496)
* Add more log types to the system tab * Fix lint issues * Fix more lint issues * Add loading screen while waiting for logs. * Only show log selector if advenced user. * Update hassio/src/system/hassio-supervisor-log.ts Co-Authored-By: Bram Kragten <mail@bramkragten.nl> * Log adjustments * Remove the need for exported ANSI_HTML_STYLE * Add core as a log provider * Removed unneeded hints Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
b04fe141ac
commit
8029c3d672
@ -7,7 +7,6 @@ import {
|
|||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
query,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import {
|
import {
|
||||||
@ -16,18 +15,18 @@ import {
|
|||||||
} from "../../../src/data/hassio/addon";
|
} from "../../../src/data/hassio/addon";
|
||||||
import { haStyle } from "../../../src/resources/styles";
|
import { haStyle } from "../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../src/types";
|
import { HomeAssistant } from "../../../src/types";
|
||||||
import { ANSI_HTML_STYLE, parseTextToColoredPre } from "../ansi-to-html";
|
import "../components/hassio-ansi-to-html";
|
||||||
import { hassioStyle } from "../resources/hassio-style";
|
import { hassioStyle } from "../resources/hassio-style";
|
||||||
|
|
||||||
@customElement("hassio-addon-logs")
|
@customElement("hassio-addon-logs")
|
||||||
class HassioAddonLogs extends LitElement {
|
class HassioAddonLogs extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public addon!: HassioAddonDetails;
|
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||||
|
|
||||||
@property() private _error?: string;
|
@property() private _error?: string;
|
||||||
|
|
||||||
@query("#content") private _logContent!: any;
|
@property() private _content?: string;
|
||||||
|
|
||||||
public async connectedCallback(): Promise<void> {
|
public async connectedCallback(): Promise<void> {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@ -38,7 +37,13 @@ class HassioAddonLogs extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<paper-card heading="Log">
|
<paper-card heading="Log">
|
||||||
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
||||||
<div class="card-content" id="content"></div>
|
<div class="card-content">
|
||||||
|
${this._content
|
||||||
|
? html`<hassio-ansi-to-html
|
||||||
|
.content=${this._content}
|
||||||
|
></hassio-ansi-to-html>`
|
||||||
|
: html`<loading-screen></loading-screen>`}
|
||||||
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<mwc-button @click=${this._refresh}>Refresh</mwc-button>
|
<mwc-button @click=${this._refresh}>Refresh</mwc-button>
|
||||||
</div>
|
</div>
|
||||||
@ -50,17 +55,11 @@ class HassioAddonLogs extends LitElement {
|
|||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
ANSI_HTML_STYLE,
|
|
||||||
css`
|
css`
|
||||||
:host,
|
:host,
|
||||||
paper-card {
|
paper-card {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
pre {
|
|
||||||
overflow-x: auto;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
}
|
|
||||||
.errors {
|
.errors {
|
||||||
color: var(--google-red-500);
|
color: var(--google-red-500);
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
@ -72,13 +71,11 @@ class HassioAddonLogs extends LitElement {
|
|||||||
private async _loadData(): Promise<void> {
|
private async _loadData(): Promise<void> {
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
try {
|
try {
|
||||||
const content = await fetchHassioAddonLogs(this.hass, this.addon.slug);
|
this._content = await fetchHassioAddonLogs(this.hass, this.addon.slug);
|
||||||
while (this._logContent.lastChild) {
|
|
||||||
this._logContent.removeChild(this._logContent.lastChild as Node);
|
|
||||||
}
|
|
||||||
this._logContent.appendChild(parseTextToColoredPre(content));
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to get addon logs, ${err.body?.message || err}`;
|
this._error = `Failed to get supervisor logs, ${
|
||||||
|
err.body?.message || err
|
||||||
|
}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,223 +0,0 @@
|
|||||||
import { css } from "lit-element";
|
|
||||||
|
|
||||||
interface State {
|
|
||||||
bold: boolean;
|
|
||||||
italic: boolean;
|
|
||||||
underline: boolean;
|
|
||||||
strikethrough: boolean;
|
|
||||||
foregroundColor: null | string;
|
|
||||||
backgroundColor: null | string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ANSI_HTML_STYLE = css`
|
|
||||||
.bold {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.italic {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.underline {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.strikethrough {
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
.underline.strikethrough {
|
|
||||||
text-decoration: underline line-through;
|
|
||||||
}
|
|
||||||
.fg-red {
|
|
||||||
color: rgb(222, 56, 43);
|
|
||||||
}
|
|
||||||
.fg-green {
|
|
||||||
color: rgb(57, 181, 74);
|
|
||||||
}
|
|
||||||
.fg-yellow {
|
|
||||||
color: rgb(255, 199, 6);
|
|
||||||
}
|
|
||||||
.fg-blue {
|
|
||||||
color: rgb(0, 111, 184);
|
|
||||||
}
|
|
||||||
.fg-magenta {
|
|
||||||
color: rgb(118, 38, 113);
|
|
||||||
}
|
|
||||||
.fg-cyan {
|
|
||||||
color: rgb(44, 181, 233);
|
|
||||||
}
|
|
||||||
.fg-white {
|
|
||||||
color: rgb(204, 204, 204);
|
|
||||||
}
|
|
||||||
.bg-black {
|
|
||||||
background-color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
.bg-red {
|
|
||||||
background-color: rgb(222, 56, 43);
|
|
||||||
}
|
|
||||||
.bg-green {
|
|
||||||
background-color: rgb(57, 181, 74);
|
|
||||||
}
|
|
||||||
.bg-yellow {
|
|
||||||
background-color: rgb(255, 199, 6);
|
|
||||||
}
|
|
||||||
.bg-blue {
|
|
||||||
background-color: rgb(0, 111, 184);
|
|
||||||
}
|
|
||||||
.bg-magenta {
|
|
||||||
background-color: rgb(118, 38, 113);
|
|
||||||
}
|
|
||||||
.bg-cyan {
|
|
||||||
background-color: rgb(44, 181, 233);
|
|
||||||
}
|
|
||||||
.bg-white {
|
|
||||||
background-color: rgb(204, 204, 204);
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export function parseTextToColoredPre(text) {
|
|
||||||
const pre = document.createElement("pre");
|
|
||||||
const re = /\033(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))/g;
|
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
const state: State = {
|
|
||||||
bold: false,
|
|
||||||
italic: false,
|
|
||||||
underline: false,
|
|
||||||
strikethrough: false,
|
|
||||||
foregroundColor: null,
|
|
||||||
backgroundColor: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const addSpan = (content) => {
|
|
||||||
const span = document.createElement("span");
|
|
||||||
if (state.bold) {
|
|
||||||
span.classList.add("bold");
|
|
||||||
}
|
|
||||||
if (state.italic) {
|
|
||||||
span.classList.add("italic");
|
|
||||||
}
|
|
||||||
if (state.underline) {
|
|
||||||
span.classList.add("underline");
|
|
||||||
}
|
|
||||||
if (state.strikethrough) {
|
|
||||||
span.classList.add("strikethrough");
|
|
||||||
}
|
|
||||||
if (state.foregroundColor !== null) {
|
|
||||||
span.classList.add(`fg-${state.foregroundColor}`);
|
|
||||||
}
|
|
||||||
if (state.backgroundColor !== null) {
|
|
||||||
span.classList.add(`bg-${state.backgroundColor}`);
|
|
||||||
}
|
|
||||||
span.appendChild(document.createTextNode(content));
|
|
||||||
pre.appendChild(span);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* eslint-disable no-cond-assign */
|
|
||||||
let match;
|
|
||||||
// eslint-disable-next-line
|
|
||||||
while ((match = re.exec(text)) !== null) {
|
|
||||||
const j = match!.index;
|
|
||||||
addSpan(text.substring(i, j));
|
|
||||||
i = j + match[0].length;
|
|
||||||
|
|
||||||
if (match[1] === undefined) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
match[1].split(";").forEach((colorCode: string) => {
|
|
||||||
switch (parseInt(colorCode, 10)) {
|
|
||||||
case 0:
|
|
||||||
// reset
|
|
||||||
state.bold = false;
|
|
||||||
state.italic = false;
|
|
||||||
state.underline = false;
|
|
||||||
state.strikethrough = false;
|
|
||||||
state.foregroundColor = null;
|
|
||||||
state.backgroundColor = null;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
state.bold = true;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
state.italic = true;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
state.underline = true;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
state.strikethrough = true;
|
|
||||||
break;
|
|
||||||
case 22:
|
|
||||||
state.bold = false;
|
|
||||||
break;
|
|
||||||
case 23:
|
|
||||||
state.italic = false;
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
state.underline = false;
|
|
||||||
break;
|
|
||||||
case 29:
|
|
||||||
state.strikethrough = false;
|
|
||||||
break;
|
|
||||||
case 30:
|
|
||||||
// foreground black
|
|
||||||
state.foregroundColor = null;
|
|
||||||
break;
|
|
||||||
case 31:
|
|
||||||
state.foregroundColor = "red";
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
state.foregroundColor = "green";
|
|
||||||
break;
|
|
||||||
case 33:
|
|
||||||
state.foregroundColor = "yellow";
|
|
||||||
break;
|
|
||||||
case 34:
|
|
||||||
state.foregroundColor = "blue";
|
|
||||||
break;
|
|
||||||
case 35:
|
|
||||||
state.foregroundColor = "magenta";
|
|
||||||
break;
|
|
||||||
case 36:
|
|
||||||
state.foregroundColor = "cyan";
|
|
||||||
break;
|
|
||||||
case 37:
|
|
||||||
state.foregroundColor = "white";
|
|
||||||
break;
|
|
||||||
case 39:
|
|
||||||
// foreground reset
|
|
||||||
state.foregroundColor = null;
|
|
||||||
break;
|
|
||||||
case 40:
|
|
||||||
state.backgroundColor = "black";
|
|
||||||
break;
|
|
||||||
case 41:
|
|
||||||
state.backgroundColor = "red";
|
|
||||||
break;
|
|
||||||
case 42:
|
|
||||||
state.backgroundColor = "green";
|
|
||||||
break;
|
|
||||||
case 43:
|
|
||||||
state.backgroundColor = "yellow";
|
|
||||||
break;
|
|
||||||
case 44:
|
|
||||||
state.backgroundColor = "blue";
|
|
||||||
break;
|
|
||||||
case 45:
|
|
||||||
state.backgroundColor = "magenta";
|
|
||||||
break;
|
|
||||||
case 46:
|
|
||||||
state.backgroundColor = "cyan";
|
|
||||||
break;
|
|
||||||
case 47:
|
|
||||||
state.backgroundColor = "white";
|
|
||||||
break;
|
|
||||||
case 49:
|
|
||||||
// background reset
|
|
||||||
state.backgroundColor = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
addSpan(text.substring(i));
|
|
||||||
|
|
||||||
return pre;
|
|
||||||
}
|
|
253
hassio/src/components/hassio-ansi-to-html.ts
Normal file
253
hassio/src/components/hassio-ansi-to-html.ts
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
bold: boolean;
|
||||||
|
italic: boolean;
|
||||||
|
underline: boolean;
|
||||||
|
strikethrough: boolean;
|
||||||
|
foregroundColor: null | string;
|
||||||
|
backgroundColor: null | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement("hassio-ansi-to-html")
|
||||||
|
class HassioAnsiToHtml extends LitElement {
|
||||||
|
@property() public content!: string;
|
||||||
|
|
||||||
|
public render(): TemplateResult | void {
|
||||||
|
return html`${this._parseTextToColoredPre(this.content)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
pre {
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.underline {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.strikethrough {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
.underline.strikethrough {
|
||||||
|
text-decoration: underline line-through;
|
||||||
|
}
|
||||||
|
.fg-red {
|
||||||
|
color: rgb(222, 56, 43);
|
||||||
|
}
|
||||||
|
.fg-green {
|
||||||
|
color: rgb(57, 181, 74);
|
||||||
|
}
|
||||||
|
.fg-yellow {
|
||||||
|
color: rgb(255, 199, 6);
|
||||||
|
}
|
||||||
|
.fg-blue {
|
||||||
|
color: rgb(0, 111, 184);
|
||||||
|
}
|
||||||
|
.fg-magenta {
|
||||||
|
color: rgb(118, 38, 113);
|
||||||
|
}
|
||||||
|
.fg-cyan {
|
||||||
|
color: rgb(44, 181, 233);
|
||||||
|
}
|
||||||
|
.fg-white {
|
||||||
|
color: rgb(204, 204, 204);
|
||||||
|
}
|
||||||
|
.bg-black {
|
||||||
|
background-color: rgb(0, 0, 0);
|
||||||
|
}
|
||||||
|
.bg-red {
|
||||||
|
background-color: rgb(222, 56, 43);
|
||||||
|
}
|
||||||
|
.bg-green {
|
||||||
|
background-color: rgb(57, 181, 74);
|
||||||
|
}
|
||||||
|
.bg-yellow {
|
||||||
|
background-color: rgb(255, 199, 6);
|
||||||
|
}
|
||||||
|
.bg-blue {
|
||||||
|
background-color: rgb(0, 111, 184);
|
||||||
|
}
|
||||||
|
.bg-magenta {
|
||||||
|
background-color: rgb(118, 38, 113);
|
||||||
|
}
|
||||||
|
.bg-cyan {
|
||||||
|
background-color: rgb(44, 181, 233);
|
||||||
|
}
|
||||||
|
.bg-white {
|
||||||
|
background-color: rgb(204, 204, 204);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _parseTextToColoredPre(text) {
|
||||||
|
const pre = document.createElement("pre");
|
||||||
|
const re = /\033(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))/g;
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
const state: State = {
|
||||||
|
bold: false,
|
||||||
|
italic: false,
|
||||||
|
underline: false,
|
||||||
|
strikethrough: false,
|
||||||
|
foregroundColor: null,
|
||||||
|
backgroundColor: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const addSpan = (content) => {
|
||||||
|
const span = document.createElement("span");
|
||||||
|
if (state.bold) {
|
||||||
|
span.classList.add("bold");
|
||||||
|
}
|
||||||
|
if (state.italic) {
|
||||||
|
span.classList.add("italic");
|
||||||
|
}
|
||||||
|
if (state.underline) {
|
||||||
|
span.classList.add("underline");
|
||||||
|
}
|
||||||
|
if (state.strikethrough) {
|
||||||
|
span.classList.add("strikethrough");
|
||||||
|
}
|
||||||
|
if (state.foregroundColor !== null) {
|
||||||
|
span.classList.add(`fg-${state.foregroundColor}`);
|
||||||
|
}
|
||||||
|
if (state.backgroundColor !== null) {
|
||||||
|
span.classList.add(`bg-${state.backgroundColor}`);
|
||||||
|
}
|
||||||
|
span.appendChild(document.createTextNode(content));
|
||||||
|
pre.appendChild(span);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* eslint-disable no-cond-assign */
|
||||||
|
let match;
|
||||||
|
// eslint-disable-next-line
|
||||||
|
while ((match = re.exec(text)) !== null) {
|
||||||
|
const j = match!.index;
|
||||||
|
addSpan(text.substring(i, j));
|
||||||
|
i = j + match[0].length;
|
||||||
|
|
||||||
|
if (match[1] === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
match[1].split(";").forEach((colorCode: string) => {
|
||||||
|
switch (parseInt(colorCode, 10)) {
|
||||||
|
case 0:
|
||||||
|
// reset
|
||||||
|
state.bold = false;
|
||||||
|
state.italic = false;
|
||||||
|
state.underline = false;
|
||||||
|
state.strikethrough = false;
|
||||||
|
state.foregroundColor = null;
|
||||||
|
state.backgroundColor = null;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
state.bold = true;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
state.italic = true;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
state.underline = true;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
state.strikethrough = true;
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
state.bold = false;
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
state.italic = false;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
state.underline = false;
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
state.strikethrough = false;
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
// foreground black
|
||||||
|
state.foregroundColor = null;
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
state.foregroundColor = "red";
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
state.foregroundColor = "green";
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
state.foregroundColor = "yellow";
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
state.foregroundColor = "blue";
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.foregroundColor = "magenta";
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.foregroundColor = "cyan";
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
state.foregroundColor = "white";
|
||||||
|
break;
|
||||||
|
case 39:
|
||||||
|
// foreground reset
|
||||||
|
state.foregroundColor = null;
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
state.backgroundColor = "black";
|
||||||
|
break;
|
||||||
|
case 41:
|
||||||
|
state.backgroundColor = "red";
|
||||||
|
break;
|
||||||
|
case 42:
|
||||||
|
state.backgroundColor = "green";
|
||||||
|
break;
|
||||||
|
case 43:
|
||||||
|
state.backgroundColor = "yellow";
|
||||||
|
break;
|
||||||
|
case 44:
|
||||||
|
state.backgroundColor = "blue";
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
state.backgroundColor = "magenta";
|
||||||
|
break;
|
||||||
|
case 46:
|
||||||
|
state.backgroundColor = "cyan";
|
||||||
|
break;
|
||||||
|
case 47:
|
||||||
|
state.backgroundColor = "white";
|
||||||
|
break;
|
||||||
|
case 49:
|
||||||
|
// background reset
|
||||||
|
state.backgroundColor = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
addSpan(text.substring(i));
|
||||||
|
|
||||||
|
return pre;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hassio-ansi-to-html": HassioAnsiToHtml;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
import "@polymer/paper-card/paper-card";
|
import "@polymer/paper-card/paper-card";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
@ -7,22 +10,58 @@ import {
|
|||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
query,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { fetchSupervisorLogs } from "../../../src/data/hassio/supervisor";
|
|
||||||
import { haStyle } from "../../../src/resources/styles";
|
import { haStyle } from "../../../src/resources/styles";
|
||||||
import { HomeAssistant } from "../../../src/types";
|
import { HomeAssistant } from "../../../src/types";
|
||||||
import { ANSI_HTML_STYLE, parseTextToColoredPre } from "../ansi-to-html";
|
|
||||||
|
import { fetchHassioLogs } from "../../../src/data/hassio/supervisor";
|
||||||
|
|
||||||
|
import "../components/hassio-ansi-to-html";
|
||||||
import { hassioStyle } from "../resources/hassio-style";
|
import { hassioStyle } from "../resources/hassio-style";
|
||||||
|
import "../../../src/layouts/loading-screen";
|
||||||
|
|
||||||
|
interface LogProvider {
|
||||||
|
key: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const logProviders: LogProvider[] = [
|
||||||
|
{
|
||||||
|
key: "supervisor",
|
||||||
|
name: "Supervisor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "core",
|
||||||
|
name: "Core",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "host",
|
||||||
|
name: "Host",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "dns",
|
||||||
|
name: "DNS",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "audio",
|
||||||
|
name: "Audio",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "multicast",
|
||||||
|
name: "Multicast",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
@customElement("hassio-supervisor-log")
|
@customElement("hassio-supervisor-log")
|
||||||
class HassioSupervisorLog extends LitElement {
|
class HassioSupervisorLog extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() private _error?: string;
|
@property() private _error?: string;
|
||||||
|
|
||||||
@query("#content") private _logContent!: HTMLDivElement;
|
@property() private _selectedLogProvider = "supervisor";
|
||||||
|
|
||||||
|
@property() private _content?: string;
|
||||||
|
|
||||||
public async connectedCallback(): Promise<void> {
|
public async connectedCallback(): Promise<void> {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
@ -33,7 +72,36 @@ class HassioSupervisorLog extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<paper-card>
|
<paper-card>
|
||||||
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
${this._error ? html` <div class="errors">${this._error}</div> ` : ""}
|
||||||
<div class="card-content" id="content"></div>
|
${this.hass.userData?.showAdvanced
|
||||||
|
? html`
|
||||||
|
<paper-dropdown-menu
|
||||||
|
label="Log provider"
|
||||||
|
@iron-select=${this._setLogProvider}
|
||||||
|
>
|
||||||
|
<paper-listbox
|
||||||
|
slot="dropdown-content"
|
||||||
|
attr-for-selected="provider"
|
||||||
|
.selected=${this._selectedLogProvider}
|
||||||
|
>
|
||||||
|
${logProviders.map((provider) => {
|
||||||
|
return html`
|
||||||
|
<paper-item provider=${provider.key}
|
||||||
|
>${provider.name}</paper-item
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
})}
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
|
||||||
|
<div class="card-content" id="content">
|
||||||
|
${this._content
|
||||||
|
? html`<hassio-ansi-to-html
|
||||||
|
.content=${this._content}
|
||||||
|
></hassio-ansi-to-html>`
|
||||||
|
: html`<loading-screen></loading-screen>`}
|
||||||
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<mwc-button @click=${this._refresh}>Refresh</mwc-button>
|
<mwc-button @click=${this._refresh}>Refresh</mwc-button>
|
||||||
</div>
|
</div>
|
||||||
@ -45,7 +113,6 @@ class HassioSupervisorLog extends LitElement {
|
|||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
hassioStyle,
|
hassioStyle,
|
||||||
ANSI_HTML_STYLE,
|
|
||||||
css`
|
css`
|
||||||
paper-card {
|
paper-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -53,22 +120,36 @@ class HassioSupervisorLog extends LitElement {
|
|||||||
pre {
|
pre {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
paper-dropdown-menu {
|
||||||
|
padding: 0 2%;
|
||||||
|
width: 96%;
|
||||||
|
}
|
||||||
.errors {
|
.errors {
|
||||||
color: var(--google-red-500);
|
color: var(--google-red-500);
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
.card-content {
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _setLogProvider(ev): Promise<void> {
|
||||||
|
const provider = ev.detail.item.getAttribute("provider");
|
||||||
|
this._selectedLogProvider = provider;
|
||||||
|
await this._loadData();
|
||||||
|
}
|
||||||
|
|
||||||
private async _loadData(): Promise<void> {
|
private async _loadData(): Promise<void> {
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
|
this._content = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const content = await fetchSupervisorLogs(this.hass);
|
this._content = await fetchHassioLogs(
|
||||||
while (this._logContent.lastChild) {
|
this.hass,
|
||||||
this._logContent.removeChild(this._logContent.lastChild as Node);
|
this._selectedLogProvider
|
||||||
}
|
);
|
||||||
this._logContent.appendChild(parseTextToColoredPre(content));
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = `Failed to get supervisor logs, ${
|
this._error = `Failed to get supervisor logs, ${
|
||||||
err.body?.message || err
|
err.body?.message || err
|
||||||
|
@ -37,8 +37,11 @@ export const fetchHassioSupervisorInfo = async (hass: HomeAssistant) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchSupervisorLogs = async (hass: HomeAssistant) => {
|
export const fetchHassioLogs = async (
|
||||||
return hass.callApi<string>("GET", "hassio/supervisor/logs");
|
hass: HomeAssistant,
|
||||||
|
provider: string
|
||||||
|
) => {
|
||||||
|
return hass.callApi<string>("GET", `hassio/${provider}/logs`);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createHassioSession = async (hass: HomeAssistant) => {
|
export const createHassioSession = async (hass: HomeAssistant) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user