No Logbook entries found for this step.
diff --git a/src/components/trace/ha-trace-path-details.ts b/src/components/trace/ha-trace-path-details.ts
index 2a38ca6504c8..410f05bd7bf0 100644
--- a/src/components/trace/ha-trace-path-details.ts
+++ b/src/components/trace/ha-trace-path-details.ts
@@ -291,7 +291,10 @@ export class HaTracePathDetails extends LitElement {
.entries=${entries}
.narrow=${this.narrow}
>
-
+
`
: html`
${this.hass!.localize(
diff --git a/src/components/trace/ha-trace-timeline.ts b/src/components/trace/ha-trace-timeline.ts
index 7c62b3fbb033..07e7fc360026 100644
--- a/src/components/trace/ha-trace-timeline.ts
+++ b/src/components/trace/ha-trace-timeline.ts
@@ -28,7 +28,10 @@ export class HaTraceTimeline extends LitElement {
allowPick
>
-
+
`;
}
diff --git a/src/components/trace/hat-logbook-note.ts b/src/components/trace/hat-logbook-note.ts
index 1d790a21afa7..bda976fe28af 100644
--- a/src/components/trace/hat-logbook-note.ts
+++ b/src/components/trace/hat-logbook-note.ts
@@ -1,14 +1,22 @@
-import { css, html, LitElement } from "lit";
+import { css, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
+import type { HomeAssistant } from "../../types";
@customElement("hat-logbook-note")
class HatLogbookNote extends LitElement {
- @property() public domain = "automation";
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property() public domain: "automation" | "script" = "automation";
render() {
- return html`
- Not all shown logbook entries might be related to this ${this.domain}.
- `;
+ if (this.domain === "script") {
+ return this.hass.localize(
+ "ui.panel.config.automation.trace.messages.not_all_entries_are_related_script_note"
+ );
+ }
+ return this.hass.localize(
+ "ui.panel.config.automation.trace.messages.not_all_entries_are_related_automation_note"
+ );
}
static styles = css`
diff --git a/src/dialogs/more-info/controls/more-info-update.ts b/src/dialogs/more-info/controls/more-info-update.ts
index 7014a505e99f..5fe6d6d792c6 100644
--- a/src/dialogs/more-info/controls/more-info-update.ts
+++ b/src/dialogs/more-info/controls/more-info-update.ts
@@ -52,59 +52,61 @@ class MoreInfoUpdate extends LitElement {
return html`
- ${this.stateObj.attributes.in_progress
- ? supportsFeature(this.stateObj, UpdateEntityFeature.PROGRESS) &&
- this.stateObj.attributes.update_percentage !== null
- ? html` `
- : html` `
- : nothing}
- ${this._error} `
- : nothing}
- {
+ private async _downloadLogs(): Promise {
if (this._streamSupported) {
showDownloadLogsDialog(this, {
header: this.header,
@@ -378,6 +455,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,
@@ -438,6 +527,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 {
@@ -461,10 +561,13 @@ class ErrorLogCard extends LitElement {
if (err.name === "AbortError") {
return;
}
- this._error = this.hass.localize("ui.panel.config.logs.failed_get_logs", {
- provider: this.provider,
- error: extractApiErrorMessage(err),
- });
+ this._error = (this.localizeFunc || this.hass.localize)(
+ "ui.panel.config.logs.failed_get_logs",
+ {
+ provider: this.provider,
+ error: extractApiErrorMessage(err),
+ }
+ );
}
}
@@ -585,6 +688,18 @@ class ErrorLogCard extends LitElement {
}
}
+ private _toggleLineWrap() {
+ this._wrapLines = !this._wrapLines;
+ }
+
+ private _handleOverflowAction(ev: CustomEvent) {
+ switch (ev.detail.index) {
+ case 0:
+ this._showBootsSelect = !this._showBootsSelect;
+ break;
+ }
+ }
+
private _toggleBootsMenu() {
if (this._bootsMenu) {
this._bootsMenu.open = !this._bootsMenu.open;
@@ -597,6 +712,9 @@ class ErrorLogCard extends LitElement {
}
static styles: CSSResultGroup = css`
+ :host {
+ direction: var(--direction);
+ }
.error-log-intro {
text-align: center;
margin: 16px;
@@ -646,7 +764,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;
@@ -713,6 +831,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);
+ }
`;
}
diff --git a/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts b/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts
index 8db4e6b44a6b..5e021d53dad3 100644
--- a/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts
+++ b/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts
@@ -1,11 +1,11 @@
import type { CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
+import "../../../../components/ha-card";
import type { HomeAssistant } from "../../../../types";
import { hasConfigChanged } from "../../common/has-changed";
import "../../components/hui-energy-period-selector";
-import "../../../../components/ha-card";
-import type { LovelaceCard, LovelaceLayoutOptions } from "../../types";
+import type { LovelaceCard, LovelaceGridOptions } from "../../types";
import type { EnergyCardBaseConfig } from "../types";
@customElement("hui-energy-date-selection-card")
@@ -21,10 +21,10 @@ export class HuiEnergyDateSelectionCard
return 1;
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
return {
- grid_rows: 1,
- grid_columns: 4,
+ rows: 1,
+ columns: 12,
};
}
diff --git a/src/panels/lovelace/cards/hui-area-card.ts b/src/panels/lovelace/cards/hui-area-card.ts
index 1e2b335ade56..e8c0eb8cea78 100644
--- a/src/panels/lovelace/cards/hui-area-card.ts
+++ b/src/panels/lovelace/cards/hui-area-card.ts
@@ -45,7 +45,7 @@ import "../components/hui-warning";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { AreaCardConfig } from "./types";
@@ -534,10 +534,11 @@ export class HuiAreaCard
forwardHaptic("light");
}
- getLayoutOptions(): LovelaceLayoutOptions {
+ getGridOptions(): LovelaceGridOptions {
return {
- grid_columns: 4,
- grid_rows: 3,
+ columns: 12,
+ rows: 3,
+ min_columns: 3,
};
}
diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts
index 2bed7c6038e9..2fbb0adb2f9e 100644
--- a/src/panels/lovelace/cards/hui-button-card.ts
+++ b/src/panels/lovelace/cards/hui-button-card.ts
@@ -46,7 +46,7 @@ import { createEntityNotFoundWarning } from "../components/hui-warning";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { ButtonCardConfig } from "./types";
@@ -134,20 +134,23 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
);
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
if (
this._config?.show_icon &&
(this._config?.show_name || this._config?.show_state)
) {
return {
- grid_rows: 2,
- grid_columns: 2,
- grid_min_rows: 2,
+ rows: 2,
+ columns: 6,
+ min_columns: 2,
+ min_rows: 2,
};
}
return {
- grid_rows: 1,
- grid_columns: 1,
+ rows: 1,
+ columns: 3,
+ min_columns: 2,
+ min_rows: 1,
};
}
diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts
index b2b849525540..6e5b30e2b44d 100644
--- a/src/panels/lovelace/cards/hui-entity-card.ts
+++ b/src/panels/lovelace/cards/hui-entity-card.ts
@@ -33,8 +33,8 @@ import { createEntityNotFoundWarning } from "../components/hui-warning";
import { createHeaderFooterElement } from "../create-element/create-header-footer-element";
import type {
LovelaceCard,
+ LovelaceGridOptions,
LovelaceHeaderFooter,
- LovelaceLayoutOptions,
} from "../types";
import type { HuiErrorCard } from "./hui-error-card";
import type { EntityCardConfig } from "./types";
@@ -249,12 +249,12 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
fireEvent(this, "hass-more-info", { entityId: this._config!.entity });
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
return {
- grid_columns: 2,
- grid_rows: 2,
- grid_min_columns: 2,
- grid_min_rows: 2,
+ columns: 6,
+ rows: 2,
+ min_columns: 6,
+ min_rows: 2,
};
}
diff --git a/src/panels/lovelace/cards/hui-heading-card.ts b/src/panels/lovelace/cards/hui-heading-card.ts
index 6d57a1ae064c..307fc6bfdbe2 100644
--- a/src/panels/lovelace/cards/hui-heading-card.ts
+++ b/src/panels/lovelace/cards/hui-heading-card.ts
@@ -16,7 +16,7 @@ import "../heading-badges/hui-heading-badge";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { HeadingCardConfig } from "./types";
@@ -65,10 +65,11 @@ export class HuiHeadingCard extends LitElement implements LovelaceCard {
return 1;
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
return {
- grid_columns: "full",
- grid_rows: this._config?.heading_style === "subtitle" ? "auto" : 1,
+ columns: "full",
+ rows: this._config?.heading_style === "subtitle" ? "auto" : 1,
+ min_columns: 3,
};
}
diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts
index c342934afc6e..15bee2a43d8f 100644
--- a/src/panels/lovelace/cards/hui-humidifier-card.ts
+++ b/src/panels/lovelace/cards/hui-humidifier-card.ts
@@ -19,7 +19,7 @@ import { createEntityNotFoundWarning } from "../components/hui-warning";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { HumidifierCardConfig } from "./types";
@@ -171,21 +171,21 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
`;
}
- public getLayoutOptions(): LovelaceLayoutOptions {
- const grid_columns = 4;
- let grid_rows = 5;
- let grid_min_rows = 2;
- const grid_min_columns = 2;
+ public getGridOptions(): LovelaceGridOptions {
+ const columns = 12;
+ let rows = 5;
+ let min_rows = 2;
+ const min_columns = 6;
if (this._config?.features?.length) {
const featureHeight = Math.ceil((this._config.features.length * 2) / 3);
- grid_rows += featureHeight;
- grid_min_rows += featureHeight;
+ rows += featureHeight;
+ min_rows += featureHeight;
}
return {
- grid_columns,
- grid_rows,
- grid_min_rows,
- grid_min_columns,
+ columns,
+ rows,
+ min_columns,
+ min_rows,
};
}
diff --git a/src/panels/lovelace/cards/hui-iframe-card.ts b/src/panels/lovelace/cards/hui-iframe-card.ts
index aa078608cebc..72188af3ba7d 100644
--- a/src/panels/lovelace/cards/hui-iframe-card.ts
+++ b/src/panels/lovelace/cards/hui-iframe-card.ts
@@ -11,7 +11,7 @@ import { IFRAME_SANDBOX } from "../../../util/iframe";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { IframeCardConfig } from "./types";
@@ -113,11 +113,12 @@ export class HuiIframeCard extends LitElement implements LovelaceCard {
`;
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
return {
- grid_columns: "full",
- grid_rows: 4,
- grid_min_rows: 2,
+ columns: "full",
+ rows: 4,
+ min_columns: 3,
+ min_rows: 2,
};
}
diff --git a/src/panels/lovelace/cards/hui-map-card.ts b/src/panels/lovelace/cards/hui-map-card.ts
index 9931303f93f6..f1234225722c 100644
--- a/src/panels/lovelace/cards/hui-map-card.ts
+++ b/src/panels/lovelace/cards/hui-map-card.ts
@@ -11,8 +11,8 @@ import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { deepEqual } from "../../../common/util/deep-equal";
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
-import "../../../components/ha-card";
import "../../../components/ha-alert";
+import "../../../components/ha-card";
import "../../../components/ha-icon-button";
import "../../../components/map/ha-map";
import type {
@@ -23,15 +23,15 @@ import type {
} from "../../../components/map/ha-map";
import type { HistoryStates } from "../../../data/history";
import { subscribeHistoryStatesTimeWindow } from "../../../data/history";
+import type { HomeAssistant } from "../../../types";
+import { findEntities } from "../common/find-entities";
import {
hasConfigChanged,
hasConfigOrEntitiesChanged,
} from "../common/has-changed";
-import type { HomeAssistant } from "../../../types";
-import { findEntities } from "../common/find-entities";
import { processConfigEntities } from "../common/process-config-entities";
import type { EntityConfig } from "../entity-rows/types";
-import type { LovelaceCard, LovelaceLayoutOptions } from "../types";
+import type { LovelaceCard, LovelaceGridOptions } from "../types";
import type { MapCardConfig } from "./types";
export const DEFAULT_HOURS_TO_SHOW = 0;
@@ -431,12 +431,12 @@ class HuiMapCard extends LitElement implements LovelaceCard {
}
);
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
return {
- grid_columns: "full",
- grid_rows: 4,
- grid_min_columns: 2,
- grid_min_rows: 2,
+ columns: "full",
+ rows: 4,
+ min_columns: 6,
+ min_rows: 2,
};
}
diff --git a/src/panels/lovelace/cards/hui-sensor-card.ts b/src/panels/lovelace/cards/hui-sensor-card.ts
index 0bc454e3c533..db964f9e0d6b 100644
--- a/src/panels/lovelace/cards/hui-sensor-card.ts
+++ b/src/panels/lovelace/cards/hui-sensor-card.ts
@@ -6,7 +6,7 @@ import { computeDomain } from "../../../common/entity/compute_domain";
import type { HomeAssistant } from "../../../types";
import { findEntities } from "../common/find-entities";
import type { GraphHeaderFooterConfig } from "../header-footer/types";
-import type { LovelaceCardEditor, LovelaceLayoutOptions } from "../types";
+import type { LovelaceCardEditor, LovelaceGridOptions } from "../types";
import { HuiEntityCard } from "./hui-entity-card";
import type { EntityCardConfig, SensorCardConfig } from "./types";
@@ -73,12 +73,12 @@ class HuiSensorCard extends HuiEntityCard {
super.setConfig(entityCardConfig);
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
return {
- grid_columns: 2,
- grid_rows: 2,
- grid_min_columns: 2,
- grid_min_rows: 2,
+ columns: 6,
+ rows: 2,
+ min_columns: 6,
+ min_rows: 2,
};
}
diff --git a/src/panels/lovelace/cards/hui-statistic-card.ts b/src/panels/lovelace/cards/hui-statistic-card.ts
index e0ee0c079e17..7fafcf8a7db3 100644
--- a/src/panels/lovelace/cards/hui-statistic-card.ts
+++ b/src/panels/lovelace/cards/hui-statistic-card.ts
@@ -26,7 +26,7 @@ import type {
LovelaceCard,
LovelaceCardEditor,
LovelaceHeaderFooter,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { HuiErrorCard } from "./hui-error-card";
import type { EntityCardConfig, StatisticCardConfig } from "./types";
@@ -249,12 +249,12 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard {
fireEvent(this, "hass-more-info", { entityId: this._config!.entity });
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
return {
- grid_columns: 2,
- grid_rows: 2,
- grid_min_columns: 2,
- grid_min_rows: 2,
+ columns: 6,
+ rows: 2,
+ min_columns: 6,
+ min_rows: 2,
};
}
diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts
index f96264e75eea..f33d1dbdfe50 100644
--- a/src/panels/lovelace/cards/hui-thermostat-card.ts
+++ b/src/panels/lovelace/cards/hui-thermostat-card.ts
@@ -19,7 +19,7 @@ import { createEntityNotFoundWarning } from "../components/hui-warning";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { ThermostatCardConfig } from "./types";
@@ -163,21 +163,21 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
`;
}
- public getLayoutOptions(): LovelaceLayoutOptions {
- const grid_columns = 4;
- let grid_rows = 5;
- let grid_min_rows = 2;
- const grid_min_columns = 2;
+ public getGridOptions(): LovelaceGridOptions {
+ const columns = 12;
+ let rows = 5;
+ let min_rows = 2;
+ const min_columns = 6;
if (this._config?.features?.length) {
const featureHeight = Math.ceil((this._config.features.length * 2) / 3);
- grid_rows += featureHeight;
- grid_min_rows += featureHeight;
+ rows += featureHeight;
+ min_rows += featureHeight;
}
return {
- grid_columns,
- grid_rows,
- grid_min_rows,
- grid_min_columns,
+ columns,
+ rows,
+ min_columns,
+ min_rows,
};
}
diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts
index 820926d4bb16..457363681fd6 100644
--- a/src/panels/lovelace/cards/hui-tile-card.ts
+++ b/src/panels/lovelace/cards/hui-tile-card.ts
@@ -34,7 +34,7 @@ import { hasAction } from "../common/has-action";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import { renderTileBadge } from "./tile/badges/tile-badge";
import type { ThermostatCardConfig, TileCardConfig } from "./types";
@@ -109,22 +109,22 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
);
}
- public getLayoutOptions(): LovelaceLayoutOptions {
- const grid_columns = 2;
- let grid_min_columns = 2;
- let grid_rows = 1;
+ public getGridOptions(): LovelaceGridOptions {
+ const columns = 6;
+ let min_columns = 6;
+ let rows = 1;
if (this._config?.features?.length) {
- grid_rows += this._config.features.length;
+ rows += this._config.features.length;
}
if (this._config?.vertical) {
- grid_rows++;
- grid_min_columns = 1;
+ rows++;
+ min_columns = 3;
}
return {
- grid_columns,
- grid_rows,
- grid_min_rows: grid_rows,
- grid_min_columns,
+ columns,
+ rows,
+ min_columns,
+ min_rows: rows,
};
}
diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts
index 5fc2ec050438..ca8fc571af5e 100644
--- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts
+++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts
@@ -34,7 +34,7 @@ import { createEntityNotFoundWarning } from "../components/hui-warning";
import type {
LovelaceCard,
LovelaceCardEditor,
- LovelaceLayoutOptions,
+ LovelaceGridOptions,
} from "../types";
import type { WeatherForecastCardConfig } from "./types";
@@ -418,31 +418,31 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
return typeof item !== "undefined" && item !== null;
}
- public getLayoutOptions(): LovelaceLayoutOptions {
+ public getGridOptions(): LovelaceGridOptions {
if (
this._config?.show_current !== false &&
this._config?.show_forecast !== false
) {
return {
- grid_columns: 4,
- grid_min_columns: 2,
- grid_rows: 4,
- grid_min_rows: 4,
+ columns: 12,
+ rows: 4,
+ min_columns: 6,
+ min_rows: 4,
};
}
if (this._config?.show_forecast !== false) {
return {
- grid_columns: 4,
- grid_min_columns: 2,
- grid_rows: 3,
- grid_min_rows: 3,
+ columns: 12,
+ rows: 3,
+ min_columns: 6,
+ min_rows: 3,
};
}
return {
- grid_columns: 4,
- grid_min_columns: 2,
- grid_rows: 2,
- grid_min_rows: 2,
+ columns: 12,
+ rows: 2,
+ min_columns: 6,
+ min_rows: 2,
};
}
diff --git a/src/panels/lovelace/components/hui-card-edit-mode.ts b/src/panels/lovelace/components/hui-card-edit-mode.ts
index c599910cce71..9775e67e734a 100644
--- a/src/panels/lovelace/components/hui-card-edit-mode.ts
+++ b/src/panels/lovelace/components/hui-card-edit-mode.ts
@@ -233,7 +233,7 @@ export class HuiCardEditMode extends LitElement {
}
private _handleAction(ev) {
- switch (ev.target.action) {
+ switch (ev.currentTarget.action) {
case "edit":
this._editCard();
break;
diff --git a/src/translations/en.json b/src/translations/en.json
index 09c4d2b1a83d..2762e217884c 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2492,10 +2492,15 @@
"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.",
+ "haos_boots_title": "Logs of HAOS startup",
+ "show_haos_boots": "Show HAOS startups",
+ "hide_haos_boots": "Hide HAOS startups",
+ "full_width": "Full width",
+ "wrap_lines": "Wrap lines",
"current": "Current",
"previous": "Previous",
"startups_ago": "{boot} startups ago",
@@ -3581,7 +3586,9 @@
"stopped_unknown_reason": "Stopped because of unknown reason {reason} at {time} (runtime: {executiontime} seconds)",
"disabled": "(disabled)",
"triggered_by": "{triggeredBy, select, \n alias {{alias} triggered}\n other {Triggered} \n} {triggeredPath, select, \n trigger {by the {trigger}}\n other {manually} \n} at {time}",
- "path_error": "Unable to extract path {path}. Download trace and report as bug."
+ "path_error": "Unable to extract path {path}. Download trace and report as bug.",
+ "not_all_entries_are_related_automation_note": "Not all shown logbook entries might be related to this automation.",
+ "not_all_entries_are_related_script_note": "Not all shown logbook entries might be related to this script."
}
}
},
@@ -7848,6 +7855,62 @@
"restore": "[%key:ui::components::data-table::settings::restore%]"
}
}
+ },
+ "panel": {
+ "config": {
+ "logs": {
+ "caption": "[%key:ui::panel::config::logs::caption%]",
+ "description": "[%key:ui::panel::config::logs::description%]",
+ "details": "[%key:ui::panel::config::logs::details%]",
+ "search": "[%key:ui::panel::config::logs::search%]",
+ "failed_get_logs": "[%key:ui::panel::config::logs::failed_get_logs%]",
+ "no_issues_search": "[%key:ui::panel::config::logs::no_issues_search%]",
+ "load_logs": "[%key:ui::panel::config::logs::load_logs%]",
+ "nr_of_lines": "[%key:ui::panel::config::logs::nr_of_lines%]",
+ "loading_log": "[%key:ui::panel::config::logs::loading_log%]",
+ "no_errors": "[%key:ui::panel::config::logs::no_errors%]",
+ "no_issues": "[%key:ui::panel::config::logs::no_issues%]",
+ "clear": "[%key:ui::panel::config::logs::clear%]",
+ "refresh": "[%key:ui::panel::config::logs::refresh%]",
+ "copy": "[%key:ui::panel::config::logs::copy%]",
+ "log_provider": "[%key:ui::panel::config::logs::log_provider%]",
+ "multiple_messages": "[%key:ui::panel::config::logs::multiple_messages%]",
+ "level": {
+ "critical": "[%key:ui::panel::config::logs::level::critical%]",
+ "error": "[%key:ui::panel::config::logs::level::error%]",
+ "warning": "[%key:ui::panel::config::logs::level::warning%]",
+ "info": "[%key:ui::panel::config::logs::level::info%]",
+ "debug": "[%key:ui::panel::config::logs::level::debug%]"
+ },
+ "custom_integration": "[%key:ui::panel::config::logs::custom_integration%]",
+ "error_from_custom_integration": "[%key:ui::panel::config::logs::error_from_custom_integration%]",
+ "show_full_logs": "[%key:ui::panel::config::logs::show_full_logs%]",
+ "select_number_of_lines": "[%key:ui::panel::config::logs::select_number_of_lines%]",
+ "lines": "[%key:ui::panel::config::logs::lines%]",
+ "download_logs": "[%key:ui::panel::config::logs::download_logs%]",
+ "scroll_down_button": "[%key:ui::panel::config::logs::scroll_down_button%]",
+ "provider_not_found": "[%key:ui::panel::config::logs::provider_not_found%]",
+ "provider_not_available": "[%key:ui::panel::config::logs::provider_not_available%]",
+ "haos_boots_title": "[%key:ui::panel::config::logs::haos_boots_title%]",
+ "show_haos_boots": "[%key:ui::panel::config::logs::show_haos_boots%]",
+ "hide_haos_boots": "[%key:ui::panel::config::logs::hide_haos_boots%]",
+ "full_width": "[%key:ui::panel::config::logs::full_width%]",
+ "wrap_lines": "[%key:ui::panel::config::logs::wrap_lines%]",
+ "current": "[%key:ui::panel::config::logs::current%]",
+ "previous": "[%key:ui::panel::config::logs::previous%]",
+ "startups_ago": "[%key:ui::panel::config::logs::startups_ago%]",
+ "detail": {
+ "logger": "[%key:ui::panel::config::logs::detail::logger%]",
+ "source": "[%key:ui::panel::config::logs::detail::source%]",
+ "integration": "[%key:ui::panel::config::integrations::integration%]",
+ "documentation": "[%key:ui::panel::config::logs::detail::documentation%]",
+ "issues": "[%key:ui::panel::config::logs::detail::issues%]",
+ "first_occurred": "[%key:ui::panel::config::logs::detail::first_occurred%]",
+ "occurrences": "[%key:ui::panel::config::logs::detail::occurrences%]",
+ "last_logged": "[%key:ui::panel::config::logs::detail::last_logged%]"
+ }
+ }
+ }
}
}
}
diff --git a/src/util/file_download.ts b/src/util/file_download.ts
index f163b146a55c..dc9ba6b54ad7 100644
--- a/src/util/file_download.ts
+++ b/src/util/file_download.ts
@@ -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";
@@ -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;
diff --git a/src/util/is_ios.ts b/src/util/is_ios.ts
new file mode 100644
index 000000000000..b7f72ed2f562
--- /dev/null
+++ b/src/util/is_ios.ts
@@ -0,0 +1,5 @@
+import type { HomeAssistant } from "../types";
+import { isSafari } from "./is_safari";
+
+export const isIosApp = (hass: HomeAssistant): boolean =>
+ isSafari && !!hass.auth.external;
${this.stateObj.attributes.title}
- ${this._error - ? html`
-
-
- ${this.hass.formatEntityAttributeName(
- this.stateObj,
- "installed_version"
- )}
-
-
- ${this.stateObj.attributes.installed_version ??
- this.hass.localize("state.default.unavailable")}
-
-
- ;
+
@property() public filter = "";
@property() public header?: string;
@@ -109,30 +125,42 @@ class ErrorLogCard extends LitElement {
@state() private _boots?: number[];
+ @state() private _showBootsSelect = false;
+
+ @state() private _wrapLines = true;
+
+ @state() private _downloadSupported;
+
+ @state() private _logsFileLink;
+
protected render(): TemplateResult {
+ const localize = this.localizeFunc || this.hass.localize;
return html`
- ${this.hass.localize("ui.panel.config.logs.scroll_down_button")}
+ ${localize("ui.panel.config.logs.scroll_down_button")}
+ ${this._streamSupported &&
+ this._loadingState !== "loading" &&
+ !this._error
+ ? html`
-
- ${this.hass.localize("ui.panel.config.logs.download_full_log")}
-
+ ${this._downloadSupported
+ ? html`
+
+
+ ${localize("ui.panel.config.logs.download_logs")}
+
+ `
+ : nothing}
- ${this.hass.localize("ui.panel.config.logs.load_logs")}
+ ${localize("ui.panel.config.logs.load_logs")}
`
- : ""}
+ : nothing}
`;
}
@@ -268,6 +342,9 @@ class ErrorLogCard extends LitElement {
11
);
}
+ if (this._downloadSupported === undefined && this.hass) {
+ this._downloadSupported = downloadFileSupported(this.hass);
+ }
}
protected firstUpdated(changedProps: PropertyValues) {
@@ -331,7 +408,7 @@ class ErrorLogCard extends LitElement {
);
}
- private async _downloadFullLog(): Promise
- ${this.hass.formatEntityAttributeName(
- this.stateObj,
- "latest_version"
- )}
+
${this.hass.localize("ui.common.cancel")}
-
+
${this.hass.localize("ui.common.download")}
@@ -103,7 +105,7 @@ class DownloadLogsDialog extends LitElement {
`;
}
- private async _dowloadLogs() {
+ private async _downloadLogs() {
const provider = this._dialogParams!.provider;
const boot = this._dialogParams!.boot;
diff --git a/src/panels/config/logs/error-log-card.ts b/src/panels/config/logs/error-log-card.ts
index 259a87ca7d12..9bd729632bde 100644
--- a/src/panels/config/logs/error-log-card.ts
+++ b/src/panels/config/logs/error-log-card.ts
@@ -1,9 +1,16 @@
import "@material/mwc-list/mwc-list-item";
+import type { ActionDetail } from "@material/mwc-list";
+
import {
mdiArrowCollapseDown,
+ mdiDotsVertical,
+ mdiCircle,
mdiDownload,
+ mdiFormatListNumbered,
mdiMenuDown,
mdiRefresh,
+ mdiWrap,
+ mdiWrapDisabled,
} from "@mdi/js";
import {
css,
@@ -31,6 +38,8 @@ import "../../../components/chips/ha-assist-chip";
import "../../../components/ha-menu";
import "../../../components/ha-md-menu-item";
import "../../../components/ha-md-divider";
+import "../../../components/ha-button-menu";
+import "../../../components/ha-list-item";
import { getSignedPath } from "../../../data/auth";
@@ -40,10 +49,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";
@@ -51,6 +64,7 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { debounce } from "../../../common/util/debounce";
import { showDownloadLogsDialog } from "./show-dialog-download-logs";
import type { HaMenu } from "../../../components/ha-menu";
+import type { LocalizeFunc } from "../../../common/translations/localize";
const NUMBER_OF_LINES = 100;
@@ -58,6 +72,8 @@ const NUMBER_OF_LINES = 100;
class ErrorLogCard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
+ @property({ attribute: false }) public localizeFunc?: LocalizeFunc
+ ${this.stateObj.attributes.in_progress
+ ? supportsFeature(this.stateObj, UpdateEntityFeature.PROGRESS) &&
+ this.stateObj.attributes.update_percentage !== null
+ ? html` `
+ : html` `
+ : nothing}
+ ${this._error} `
+ : nothing}
+
${supportsFeature(this.stateObj!, UpdateEntityFeature.RELEASE_NOTES) &&
!this._error
? this._releaseNotes === undefined
@@ -293,6 +295,11 @@ class MoreInfoUpdate extends LitElement {
ha-expansion-panel {
margin: 16px 0;
}
+
+ .summary {
+ margin-bottom: 16px;
+ }
+
.row {
margin: 0;
display: flex;
@@ -308,7 +315,9 @@ class MoreInfoUpdate extends LitElement {
);
position: sticky;
bottom: 0;
- margin: 0 -24px -24px -24px;
+ margin: 0 -24px 0 -24px;
+ margin-bottom: calc(-1 * max(env(safe-area-inset-bottom), 24px));
+ padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
display: flex;
flex-direction: column;
diff --git a/src/external_app/external_messaging.ts b/src/external_app/external_messaging.ts
index a870b72be2ff..292746bdee17 100644
--- a/src/external_app/external_messaging.ts
+++ b/src/external_app/external_messaging.ts
@@ -264,6 +264,7 @@ export interface ExternalConfig {
hasAssist: boolean;
hasBarCodeScanner: number;
canSetupImprov: boolean;
+ downloadFileSupported: boolean;
}
export class ExternalMessaging {
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index 99e497a70b6f..c5d298e44db8 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -370,7 +370,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
}`,
description:
this.hass.localize(
- `component.${domain}.services.${service}.description`
+ `component.${dmn}.services.${service}.description`
) || services[dmn][service]?.description,
});
}
diff --git a/src/panels/config/logs/dialog-download-logs.ts b/src/panels/config/logs/dialog-download-logs.ts
index 0a7e9d965f40..801ef1db2262 100644
--- a/src/panels/config/logs/dialog-download-logs.ts
+++ b/src/panels/config/logs/dialog-download-logs.ts
@@ -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() {
@@ -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 });
}
@@ -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);
}
@@ -63,7 +65,7 @@ class DownloadLogsDialog extends LitElement {
.path=${mdiClose}
>
- ${this.hass.localize("ui.panel.config.logs.download_full_log")}
+ ${this.hass.localize("ui.panel.config.logs.download_logs")}
${this._dialogParams.header}${this._dialogParams.boot === 0
@@ -95,7 +97,7 @@ class DownloadLogsDialog extends LitElement {
${this.stateObj.attributes.title}
+ ${this._error + ? html`
+
-
+ ${this.hass.formatEntityAttributeName(
+ this.stateObj,
+ "installed_version"
+ )}
+
+
+ ${this.stateObj.attributes.installed_version ??
+ this.hass.localize("state.default.unavailable")}
+
- ${this.stateObj.attributes.latest_version ??
- this.hass.localize("state.default.unavailable")}
+
- ${this.stateObj.attributes.release_url
- ? html``
- : nothing}
+ ${this.stateObj.attributes.release_url
+ ? html``
+ : nothing}
+
+
-
+ ${this.hass.formatEntityAttributeName(
+ this.stateObj,
+ "latest_version"
+ )}
+
+
+ ${this.stateObj.attributes.latest_version ??
+ this.hass.localize("state.default.unavailable")}
+
${this._error
? html`${this._error} `
- : ""}
+ : nothing}
+
- ${this.header || - this.hass.localize("ui.panel.config.logs.show_full_logs")} + ${this.header || localize("ui.panel.config.logs.show_full_logs")}
@@ -202,25 +267,22 @@ class ErrorLogCard extends LitElement {
`
: nothing}
${this._loadingState === "loading"
- ? html`
- ${this.hass.localize("ui.panel.config.logs.loading_log")}
-
`
+ ? html`${localize("ui.panel.config.logs.loading_log")}
`
: this._loadingState === "empty"
- ? html`
- ${this.hass.localize("ui.panel.config.logs.no_errors")}
-
`
+ ? html`${localize("ui.panel.config.logs.no_errors")}
`
: nothing}
${this._loadingState === "loaded" &&
this.filter &&
this._noSearchResults
? html`
- ${this.hass.localize(
- "ui.panel.config.logs.no_issues_search",
- { term: this.filter }
- )}
+ ${localize("ui.panel.config.logs.no_issues_search", {
+ term: this.filter,
+ })}
`
: nothing}
-
+
+ Live
+
`
+ : nothing}
${this.show === false
? html`
-