Skip to content

Commit

Permalink
Check for empty logs (#22675)
Browse files Browse the repository at this point in the history
* Fix download logs default lines + translations + iOS, add live logs indicator

* Fix rtl in error-log-card

* Fix downloadFileSupported
  • Loading branch information
wendevlin authored Nov 6, 2024
1 parent 38da01a commit e908fbb
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/external_app/external_messaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ export interface ExternalConfig {
hasAssist: boolean;
hasBarCodeScanner: number;
canSetupImprov: boolean;
downloadFileSupported: boolean;
}

export class ExternalMessaging {
Expand Down
16 changes: 9 additions & 7 deletions src/panels/config/logs/dialog-download-logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ import type { HomeAssistant } from "../../../types";
import { fileDownload } from "../../../util/file_download";
import type { DownloadLogsDialogParams } from "./show-dialog-download-logs";

const DEFAULT_LINE_COUNT = 500;

@customElement("dialog-download-logs")
class DownloadLogsDialog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@state() private _dialogParams?: DownloadLogsDialogParams;

@state() private _lineCount = 100;
@state() private _lineCount = DEFAULT_LINE_COUNT;

@query("ha-md-dialog") private _dialogElement!: HaMdDialog;

public showDialog(dialogParams: DownloadLogsDialogParams) {
this._dialogParams = dialogParams;
this._lineCount = this._dialogParams?.defaultLineCount ?? 100;
this._lineCount = this._dialogParams?.defaultLineCount || 500;
}

public closeDialog() {
Expand All @@ -38,7 +40,7 @@ class DownloadLogsDialog extends LitElement {

private _dialogClosed() {
this._dialogParams = undefined;
this._lineCount = 100;
this._lineCount = DEFAULT_LINE_COUNT;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}

Expand All @@ -48,7 +50,7 @@ class DownloadLogsDialog extends LitElement {
}

const numberOfLinesOptions = [100, 500, 1000, 5000, 10000];
if (!numberOfLinesOptions.includes(this._lineCount)) {
if (!numberOfLinesOptions.includes(this._lineCount) && this._lineCount) {
numberOfLinesOptions.push(this._lineCount);
numberOfLinesOptions.sort((a, b) => a - b);
}
Expand All @@ -63,7 +65,7 @@ class DownloadLogsDialog extends LitElement {
.path=${mdiClose}
></ha-icon-button>
<span slot="title" id="dialog-light-color-favorite-title">
${this.hass.localize("ui.panel.config.logs.download_full_log")}
${this.hass.localize("ui.panel.config.logs.download_logs")}
</span>
<span slot="subtitle">
${this._dialogParams.header}${this._dialogParams.boot === 0
Expand Down Expand Up @@ -95,15 +97,15 @@ class DownloadLogsDialog extends LitElement {
<ha-button @click=${this.closeDialog}>
${this.hass.localize("ui.common.cancel")}
</ha-button>
<ha-button @click=${this._dowloadLogs}>
<ha-button @click=${this._downloadLogs}>
${this.hass.localize("ui.common.download")}
</ha-button>
</div>
</ha-md-dialog>
`;
}

private async _dowloadLogs() {
private async _downloadLogs() {
const provider = this._dialogParams!.provider;
const boot = this._dialogParams!.boot;

Expand Down
129 changes: 115 additions & 14 deletions src/panels/config/logs/error-log-card.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "@material/mwc-list/mwc-list-item";
import {
mdiArrowCollapseDown,
mdiCircle,
mdiDownload,
mdiMenuDown,
mdiRefresh,
Expand Down Expand Up @@ -40,10 +41,14 @@ import {
fetchHassioBoots,
fetchHassioLogs,
fetchHassioLogsFollow,
getHassioLogDownloadLinesUrl,
getHassioLogDownloadUrl,
} from "../../../data/hassio/supervisor";
import type { HomeAssistant } from "../../../types";
import { fileDownload } from "../../../util/file_download";
import {
downloadFileSupported,
fileDownload,
} from "../../../util/file_download";
import type { HASSDomEvent } from "../../../common/dom/fire_event";
import type { ConnectionStatus } from "../../../data/connection-status";
import { atLeastVersion } from "../../../common/config/version";
Expand Down Expand Up @@ -109,6 +114,10 @@ class ErrorLogCard extends LitElement {

@state() private _boots?: number[];

@state() private _downloadSupported;

@state() private _logsFileLink;

protected render(): TemplateResult {
return html`
<div class="error-log-intro">
Expand Down Expand Up @@ -176,13 +185,32 @@ class ErrorLogCard extends LitElement {
</ha-menu>
`
: nothing}
<ha-icon-button
.path=${mdiDownload}
@click=${this._downloadFullLog}
.label=${this.hass.localize(
"ui.panel.config.logs.download_full_log"
)}
></ha-icon-button>
${this._downloadSupported
? html`
<ha-icon-button
.path=${mdiDownload}
@click=${this._downloadLogs}
.label=${this.hass.localize(
"ui.panel.config.logs.download_logs"
)}
></ha-icon-button>
`
: this._logsFileLink
? html`
<a
href=${this._logsFileLink}
target="_blank"
class="download-link"
>
<ha-icon-button
.path=${mdiDownload}
.label=${this.hass.localize(
"ui.panel.config.logs.download_logs"
)}
></ha-icon-button>
</a>
`
: nothing}
${!this._streamSupported || this._error
? html`<ha-icon-button
.path=${mdiRefresh}
Expand Down Expand Up @@ -242,13 +270,27 @@ class ErrorLogCard extends LitElement {
slot="trailingIcon"
></ha-svg-icon>
</ha-button>
${this._streamSupported &&
this._loadingState !== "loading" &&
!this._error
? html`<div class="live-indicator">
<ha-svg-icon path=${mdiCircle}></ha-svg-icon>
Live
</div>`
: nothing}
</ha-card>
${this.show === false
? html`
<ha-button outlined @click=${this._downloadFullLog}>
<ha-svg-icon .path=${mdiDownload}></ha-svg-icon>
${this.hass.localize("ui.panel.config.logs.download_full_log")}
</ha-button>
${this._downloadSupported
? html`
<ha-button outlined @click=${this._downloadLogs}>
<ha-svg-icon .path=${mdiDownload}></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.logs.download_logs"
)}
</ha-button>
`
: nothing}
<mwc-button raised @click=${this._showLogs}>
${this.hass.localize("ui.panel.config.logs.load_logs")}
</mwc-button>
Expand All @@ -268,6 +310,9 @@ class ErrorLogCard extends LitElement {
11
);
}
if (this._downloadSupported === undefined && this.hass) {
this._downloadSupported = downloadFileSupported(this.hass);
}
}

protected firstUpdated(changedProps: PropertyValues) {
Expand Down Expand Up @@ -331,7 +376,7 @@ class ErrorLogCard extends LitElement {
);
}

private async _downloadFullLog(): Promise<void> {
private async _downloadLogs(): Promise<void> {
if (this._streamSupported) {
showDownloadLogsDialog(this, {
header: this.header,
Expand Down Expand Up @@ -378,6 +423,18 @@ class ErrorLogCard extends LitElement {
isComponentLoaded(this.hass, "hassio") &&
this.provider
) {
// check if there are any logs at all
const testResponse = await fetchHassioLogs(
this.hass,
this.provider,
`entries=:-1:`,
this._boot
);
const testLogs = await testResponse.text();
if (!testLogs.trim()) {
this._loadingState = "empty";
}

const response = await fetchHassioLogsFollow(
this.hass,
this.provider,
Expand Down Expand Up @@ -438,6 +495,17 @@ class ErrorLogCard extends LitElement {
} else {
this._newLogsIndicator = true;
}

if (!this._downloadSupported) {
const downloadUrl = getHassioLogDownloadLinesUrl(
this.provider,
this._numberOfLines,
this._boot
);
getSignedPath(this.hass, downloadUrl).then((signedUrl) => {
this._logsFileLink = signedUrl.path;
});
}
}
}
} else {
Expand Down Expand Up @@ -597,6 +665,9 @@ class ErrorLogCard extends LitElement {
}

static styles: CSSResultGroup = css`
:host {
direction: var(--direction);
}
.error-log-intro {
text-align: center;
margin: 16px;
Expand Down Expand Up @@ -646,7 +717,7 @@ class ErrorLogCard extends LitElement {
position: relative;
font-family: var(--code-font-family, monospace);
clear: both;
text-align: left;
text-align: start;
padding-top: 12px;
padding-bottom: 12px;
overflow-y: scroll;
Expand Down Expand Up @@ -713,6 +784,36 @@ class ErrorLogCard extends LitElement {
--ha-assist-chip-container-shape: 10px;
--md-assist-chip-trailing-space: 8px;
}
@keyframes breathe {
from {
opacity: 0.8;
}
to {
opacity: 0;
}
}
.live-indicator {
position: absolute;
bottom: 0;
inset-inline-end: 16px;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
background-color: var(--primary-color);
color: var(--text-primary-color);
padding: 4px 8px;
opacity: 0.8;
}
.live-indicator ha-svg-icon {
animation: breathe 1s cubic-bezier(0.5, 0, 1, 1) infinite alternate;
height: 14px;
width: 14px;
}
.download-link {
color: var(--text-color);
}
`;
}

Expand Down
2 changes: 1 addition & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2492,7 +2492,7 @@
"show_full_logs": "Show full logs",
"select_number_of_lines": "Select number of lines to download",
"lines": "Lines",
"download_full_log": "Download full log",
"download_logs": "Download logs",
"scroll_down_button": "New logs - Click to scroll",
"provider_not_found": "Log provider not found",
"provider_not_available": "Logs for ''{provider}'' are not available on your system.",
Expand Down
6 changes: 6 additions & 0 deletions src/util/file_download.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import type { HomeAssistant } from "../types";
import { isIosApp } from "./is_ios";

export const fileDownload = (href: string, filename = ""): void => {
const a = document.createElement("a");
a.target = "_blank";
Expand All @@ -8,3 +11,6 @@ export const fileDownload = (href: string, filename = ""): void => {
a.dispatchEvent(new MouseEvent("click"));
document.body.removeChild(a);
};

export const downloadFileSupported = (hass: HomeAssistant): boolean =>
!isIosApp(hass) || !!hass.auth.external?.config.downloadFileSupported;
5 changes: 5 additions & 0 deletions src/util/is_ios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { HomeAssistant } from "../types";
import { isSafari } from "./is_safari";

export const isIosApp = (hass: HomeAssistant): boolean =>
isSafari && !!hass.auth.external;

0 comments on commit e908fbb

Please sign in to comment.