Merge branch 'rc'

This commit is contained in:
Bram Kragten 2025-09-04 16:30:48 +02:00
commit 2cbcf1a689
16 changed files with 318 additions and 166 deletions

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
version = "20250903.2"
version = "20250903.3"
license = "Apache-2.0"
license-files = ["LICENSE*"]
description = "The Home Assistant frontend"

View File

@ -232,7 +232,6 @@ export class HaBottomSheet extends LitElement {
box-shadow: var(--wa-shadow-l);
padding: 0;
margin: 0;
top: auto;
inset-inline-end: auto;
bottom: 0;

View File

@ -11,20 +11,22 @@ import type { HomeAssistant } from "../../types";
import { isMac } from "../../util/is_mac";
interface Text {
type: "text";
key: LocalizeKeys;
textTranslationKey: LocalizeKeys;
}
type ShortcutString = string | { key: LocalizeKeys };
interface LocalizedShortcut {
shortcutTranslationKey: LocalizeKeys;
}
type ShortcutString = string | LocalizedShortcut;
interface Shortcut {
type: "shortcut";
shortcut: ShortcutString[];
key: LocalizeKeys;
descriptionTranslationKey: LocalizeKeys;
}
interface Section {
key: LocalizeKeys;
titleTranslationKey: LocalizeKeys;
items: (Text | Shortcut)[];
}
@ -32,105 +34,115 @@ const CTRL_CMD = "__CTRL_CMD__";
const _SHORTCUTS: Section[] = [
{
key: "ui.dialogs.shortcuts.searching.title",
titleTranslationKey: "ui.dialogs.shortcuts.searching.title",
items: [
{ type: "text", key: "ui.dialogs.shortcuts.searching.on_any_page" },
{
type: "shortcut",
textTranslationKey: "ui.dialogs.shortcuts.searching.on_any_page",
},
{
shortcut: ["C"],
key: "ui.dialogs.shortcuts.searching.search_command",
descriptionTranslationKey:
"ui.dialogs.shortcuts.searching.search_command",
},
{
type: "shortcut",
shortcut: ["E"],
key: "ui.dialogs.shortcuts.searching.search_entities",
descriptionTranslationKey:
"ui.dialogs.shortcuts.searching.search_entities",
},
{
type: "shortcut",
shortcut: ["D"],
key: "ui.dialogs.shortcuts.searching.search_devices",
descriptionTranslationKey:
"ui.dialogs.shortcuts.searching.search_devices",
},
{
type: "text",
key: "ui.dialogs.shortcuts.searching.on_pages_with_tables",
textTranslationKey:
"ui.dialogs.shortcuts.searching.on_pages_with_tables",
},
{
type: "shortcut",
shortcut: [CTRL_CMD, "F"],
key: "ui.dialogs.shortcuts.searching.search_in_table",
descriptionTranslationKey:
"ui.dialogs.shortcuts.searching.search_in_table",
},
],
},
{
key: "ui.dialogs.shortcuts.assist.title",
titleTranslationKey: "ui.dialogs.shortcuts.assist.title",
items: [
{
type: "shortcut",
shortcut: ["A"],
key: "ui.dialogs.shortcuts.assist.open_assist",
descriptionTranslationKey: "ui.dialogs.shortcuts.assist.open_assist",
},
],
},
{
key: "ui.dialogs.shortcuts.automation_script.title",
titleTranslationKey: "ui.dialogs.shortcuts.automation_script.title",
items: [
{
type: "shortcut",
shortcut: [CTRL_CMD, "C"],
key: "ui.dialogs.shortcuts.automation_script.copy",
descriptionTranslationKey:
"ui.dialogs.shortcuts.automation_script.copy",
},
{
type: "shortcut",
shortcut: [CTRL_CMD, "X"],
key: "ui.dialogs.shortcuts.automation_script.cut",
descriptionTranslationKey: "ui.dialogs.shortcuts.automation_script.cut",
},
{
type: "shortcut",
shortcut: [CTRL_CMD, "del"],
key: "ui.dialogs.shortcuts.automation_script.delete",
},
{
type: "shortcut",
shortcut: [CTRL_CMD, "V"],
key: "ui.dialogs.shortcuts.automation_script.paste",
},
{
type: "shortcut",
shortcut: [CTRL_CMD, "S"],
key: "ui.dialogs.shortcuts.automation_script.save",
},
],
},
{
key: "ui.dialogs.shortcuts.charts.title",
items: [
{
type: "shortcut",
shortcut: [CTRL_CMD, { key: "ui.dialogs.shortcuts.shortcuts.drag" }],
key: "ui.dialogs.shortcuts.charts.drag_to_zoom",
},
{
type: "shortcut",
shortcut: [
CTRL_CMD,
{ key: "ui.dialogs.shortcuts.shortcuts.scroll_wheel" },
{ shortcutTranslationKey: "ui.dialogs.shortcuts.keys.del" },
],
key: "ui.dialogs.shortcuts.charts.scroll_to_zoom",
descriptionTranslationKey:
"ui.dialogs.shortcuts.automation_script.delete",
},
{
type: "shortcut",
shortcut: [{ key: "ui.dialogs.shortcuts.shortcuts.double_click" }],
key: "ui.dialogs.shortcuts.charts.double_click",
shortcut: [CTRL_CMD, "V"],
descriptionTranslationKey:
"ui.dialogs.shortcuts.automation_script.paste",
},
{
shortcut: [CTRL_CMD, "S"],
descriptionTranslationKey:
"ui.dialogs.shortcuts.automation_script.save",
},
],
},
{
key: "ui.dialogs.shortcuts.other.title",
titleTranslationKey: "ui.dialogs.shortcuts.charts.title",
items: [
{
shortcut: [
CTRL_CMD,
{ shortcutTranslationKey: "ui.dialogs.shortcuts.shortcuts.drag" },
],
descriptionTranslationKey: "ui.dialogs.shortcuts.charts.drag_to_zoom",
},
{
shortcut: [
CTRL_CMD,
{
shortcutTranslationKey:
"ui.dialogs.shortcuts.shortcuts.scroll_wheel",
},
],
descriptionTranslationKey: "ui.dialogs.shortcuts.charts.scroll_to_zoom",
},
{
shortcut: [
{
shortcutTranslationKey:
"ui.dialogs.shortcuts.shortcuts.double_click",
},
],
descriptionTranslationKey: "ui.dialogs.shortcuts.charts.double_click",
},
],
},
{
titleTranslationKey: "ui.dialogs.shortcuts.other.title",
items: [
{
type: "shortcut",
shortcut: ["M"],
key: "ui.dialogs.shortcuts.other.my_link",
descriptionTranslationKey: "ui.dialogs.shortcuts.other.my_link",
},
],
},
@ -152,28 +164,28 @@ class DialogShortcuts extends LitElement {
}
private _renderShortcut(
shortcuts: ShortcutString[],
translationKey: LocalizeKeys
shortcutKeys: ShortcutString[],
descriptionKey: LocalizeKeys
) {
const keys = shortcuts.map((shortcut) =>
typeof shortcut === "string" ? shortcut : this.hass.localize(shortcut.key)
);
return html`
<div class="shortcut">
${keys.map(
(key) =>
${shortcutKeys.map(
(shortcutKey) =>
html`<span
>${key === CTRL_CMD
>${shortcutKey === CTRL_CMD
? isMac
? html`<ha-svg-icon
.path=${mdiAppleKeyboardCommand}
></ha-svg-icon>`
: this.hass.localize("ui.panel.config.automation.editor.ctrl")
: key}</span
: typeof shortcutKey === "string"
? shortcutKey
: this.hass.localize(
shortcutKey.shortcutTranslationKey
)}</span
>`
)}
${this.hass.localize(translationKey)}
${this.hass.localize(descriptionKey)}
</div>
`;
}
@ -197,16 +209,18 @@ class DialogShortcuts extends LitElement {
<div class="content">
${_SHORTCUTS.map(
(section) => html`
<h3>${this.hass.localize(section.key)}</h3>
<h3>${this.hass.localize(section.titleTranslationKey)}</h3>
<div class="items">
${section.items.map((item) => {
if (item.type === "text") {
return html`<p>${this.hass.localize(item.key)}</p>`;
if ("shortcut" in item) {
return this._renderShortcut(
(item as Shortcut).shortcut,
(item as Shortcut).descriptionTranslationKey
);
}
if (item.type === "shortcut") {
return this._renderShortcut(item.shortcut, item.key);
}
return nothing;
return html`<p>
${this.hass.localize((item as Text).textTranslationKey)}
</p>`;
})}
</div>
`

View File

@ -171,7 +171,6 @@ export default class HaAutomationSidebarCard extends LitElement {
transition: box-shadow 180ms ease-in-out;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
z-index: 6;
position: relative;
background-color: var(
--ha-dialog-surface-background,
@ -201,6 +200,7 @@ export default class HaAutomationSidebarCard extends LitElement {
.card-content {
max-height: calc(100% - 80px);
overflow: auto;
margin-top: 0;
}
@media (min-width: 450px) and (min-height: 500px) {

View File

@ -65,6 +65,10 @@ export default class HaAutomationSidebarCondition extends LitElement {
}
}
}
// Reset testing state when condition changes
if (changedProperties.has("sidebarKey")) {
this._testing = false;
}
}
protected render() {
@ -283,20 +287,23 @@ export default class HaAutomationSidebarCondition extends LitElement {
sidebar
></ha-automation-condition-editor>`
)}
<div
class="testing ${classMap({
active: this._testing,
pass: this._testingResult === true,
error: this._testingResult === false,
})}"
>
${this._testingResult
? this.hass.localize(
"ui.panel.config.automation.editor.conditions.testing_pass"
)
: this.hass.localize(
"ui.panel.config.automation.editor.conditions.testing_error"
)}
<div class="testing-wrapper">
<div
class="testing ${classMap({
active: this._testing,
pass: this._testingResult === true,
error: this._testingResult === false,
narrow: this.narrow,
})}"
>
${this._testingResult
? this.hass.localize(
"ui.panel.config.automation.editor.conditions.testing_pass"
)
: this.hass.localize(
"ui.panel.config.automation.editor.conditions.testing_error"
)}
</div>
</div>
</ha-automation-sidebar-card>`;
}
@ -396,21 +403,13 @@ export default class HaAutomationSidebarCondition extends LitElement {
ha-automation-sidebar-card {
position: relative;
}
.testing {
.testing-wrapper {
position: absolute;
z-index: 6;
top: 0px;
right: 0px;
left: 0px;
text-transform: uppercase;
font-size: var(--ha-font-size-m);
font-weight: var(--ha-font-weight-bold);
background-color: var(--divider-color, #e0e0e0);
color: var(--text-primary-color);
max-height: 0px;
margin: -1px;
overflow: hidden;
transition: max-height 0.3s;
text-align: center;
border-top-right-radius: var(
--ha-card-border-radius,
var(--ha-border-radius-lg)
@ -419,15 +418,33 @@ export default class HaAutomationSidebarCondition extends LitElement {
--ha-card-border-radius,
var(--ha-border-radius-lg)
);
pointer-events: none;
height: 100px;
}
.testing {
--testing-color: var(--divider-color, #e0e0e0);
text-transform: uppercase;
font-size: var(--ha-font-size-m);
font-weight: var(--ha-font-weight-bold);
background-color: var(--testing-color);
color: var(--text-primary-color);
max-height: 0px;
transition:
max-height 0.3s ease-in-out,
padding-top 0.3s ease-in-out;
text-align: center;
}
.testing.active.narrow {
padding-top: 16px;
}
.testing.active {
max-height: 100px;
max-height: 100%;
}
.testing.error {
background-color: var(--accent-color);
--testing-color: var(--accent-color);
}
.testing.pass {
background-color: var(--success-color);
--testing-color: var(--success-color);
}
`,
];

View File

@ -217,7 +217,7 @@ export const automationRowsStyles = css`
export const sidebarEditorStyles = css`
.sidebar-editor {
display: block;
padding-top: 16px;
padding-top: 8px;
}
.description {
padding-top: 16px;

View File

@ -4,6 +4,8 @@ import { customElement, property, state } from "lit/decorators";
import { computeDomain } from "../../../common/entity/compute_domain";
import "../../../components/ha-control-button";
import "../../../components/ha-control-button-group";
import { hasScriptFields } from "../../../data/script";
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
import type { HomeAssistant } from "../../../types";
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
import { cardFeatureStyles } from "./common/card-feature-styles";
@ -46,6 +48,14 @@ class HuiButtonCardFeature extends LitElement implements LovelaceCardFeature {
const service =
domain === "button" || domain === "input_button" ? "press" : "turn_on";
if (domain === "script") {
const entityId = this._stateObj.entity_id;
if (hasScriptFields(this.hass!, entityId)) {
showMoreInfoDialog(this, { entityId: entityId });
return;
}
}
this.hass.callService(domain, service, {
entity_id: this._stateObj.entity_id,
});

View File

@ -9,7 +9,7 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../types";
import { coordinatesMinimalResponseCompressedState } from "../common/graph/coordinates";
import "../components/hui-graph-base";
import type { LovelaceCardFeature } from "../types";
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
import type {
TrendGraphCardFeatureConfig,
LovelaceCardFeatureContext,
@ -27,7 +27,7 @@ export const supportsTrendGraphCardFeature = (
return domain === "sensor" && isNumericFromAttributes(stateObj.attributes);
};
const DEFAULT_HOURS_TO_SHOW = 24;
export const DEFAULT_HOURS_TO_SHOW = 24;
@customElement("hui-trend-graph-card-feature")
class HuiHistoryChartCardFeature
@ -51,6 +51,13 @@ class HuiHistoryChartCardFeature
};
}
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
await import(
"../editor/config-elements/hui-trend-graph-card-feature-editor"
);
return document.createElement("hui-trend-graph-card-feature-editor");
}
public setConfig(config: TrendGraphCardFeatureConfig): void {
if (!config) {
throw new Error("Invalid configuration");

View File

@ -109,7 +109,7 @@ class HuiEnergySankeyCard
"ui.panel.lovelace.cards.energy.energy_distribution.home"
),
value: Math.max(0, consumption.total.used_total),
color: computedStyle.getPropertyValue("--primary-color"),
color: computedStyle.getPropertyValue("--primary-color").trim(),
index: 1,
};
nodes.push(homeNode);
@ -125,7 +125,9 @@ class HuiEnergySankeyCard
"ui.panel.lovelace.cards.energy.energy_distribution.battery"
),
value: totalBatteryOut,
color: computedStyle.getPropertyValue("--energy-battery-out-color"),
color: computedStyle
.getPropertyValue("--energy-battery-out-color")
.trim(),
index: 0,
});
links.push({
@ -141,7 +143,9 @@ class HuiEnergySankeyCard
"ui.panel.lovelace.cards.energy.energy_distribution.battery"
),
value: totalBatteryIn,
color: computedStyle.getPropertyValue("--energy-battery-in-color"),
color: computedStyle
.getPropertyValue("--energy-battery-in-color")
.trim(),
index: 1,
});
if (consumption.total.grid_to_battery > 0) {
@ -169,9 +173,9 @@ class HuiEnergySankeyCard
"ui.panel.lovelace.cards.energy.energy_distribution.grid"
),
value: totalFromGrid,
color: computedStyle.getPropertyValue(
"--energy-grid-consumption-color"
),
color: computedStyle
.getPropertyValue("--energy-grid-consumption-color")
.trim(),
index: 0,
});
@ -192,7 +196,7 @@ class HuiEnergySankeyCard
"ui.panel.lovelace.cards.energy.energy_distribution.solar"
),
value: totalSolarProduction,
color: computedStyle.getPropertyValue("--energy-solar-color"),
color: computedStyle.getPropertyValue("--energy-solar-color").trim(),
index: 0,
});
@ -213,7 +217,9 @@ class HuiEnergySankeyCard
"ui.panel.lovelace.cards.energy.energy_distribution.grid"
),
value: totalToGrid,
color: computedStyle.getPropertyValue("--energy-grid-return-color"),
color: computedStyle
.getPropertyValue("--energy-grid-return-color")
.trim(),
index: 1,
});
if (consumption.total.battery_to_grid > 0) {
@ -295,7 +301,7 @@ class HuiEnergySankeyCard
label: this.hass.floors[floorId].name,
value: floors[floorId].value,
index: 2,
color: computedStyle.getPropertyValue("--primary-color"),
color: computedStyle.getPropertyValue("--primary-color").trim(),
});
links.push({
source: "home",
@ -316,7 +322,7 @@ class HuiEnergySankeyCard
label: this.hass.areas[areaId]!.name,
value: areas[areaId].value,
index: 3,
color: computedStyle.getPropertyValue("--primary-color"),
color: computedStyle.getPropertyValue("--primary-color").trim(),
});
links.push({
source: floorNodeId,
@ -360,7 +366,9 @@ class HuiEnergySankeyCard
"ui.panel.lovelace.cards.energy.energy_devices_detail_graph.untracked_consumption"
),
value: untrackedConsumption,
color: computedStyle.getPropertyValue("--state-unavailable-color"),
color: computedStyle
.getPropertyValue("--state-unavailable-color")
.trim(),
index: 3 + deviceSections.length,
});
links.push({

View File

@ -128,6 +128,7 @@ const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
"lawn-mower-commands",
"numeric-input",
"select-options",
"trend-graph",
"update-actions",
"vacuum-commands",
"water-heater-operation-modes",

View File

@ -0,0 +1,82 @@
import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-form/ha-form";
import type {
HaFormSchema,
SchemaUnion,
} from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types";
import { DEFAULT_HOURS_TO_SHOW } from "../../card-features/hui-trend-graph-card-feature";
import type {
LovelaceCardFeatureContext,
TrendGraphCardFeatureConfig,
} from "../../card-features/types";
import type { LovelaceCardFeatureEditor } from "../../types";
const SCHEMA = [
{
name: "hours_to_show",
default: DEFAULT_HOURS_TO_SHOW,
selector: { number: { min: 1, mode: "box" } },
},
] as const satisfies HaFormSchema[];
@customElement("hui-trend-graph-card-feature-editor")
export class HuiTrendGraphCardFeatureEditor
extends LitElement
implements LovelaceCardFeatureEditor
{
@property({ attribute: false }) public hass?: HomeAssistant;
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
@state() private _config?: TrendGraphCardFeatureConfig;
public setConfig(config: TrendGraphCardFeatureConfig): void {
this._config = config;
}
protected render() {
if (!this.hass || !this._config) {
return nothing;
}
const data = { ...this._config };
if (!this._config.hours_to_show) {
data.hours_to_show = DEFAULT_HOURS_TO_SHOW;
}
return html`
<ha-form
.hass=${this.hass}
.data=${data}
.schema=${SCHEMA}
.computeLabel=${this._computeLabelCallback}
@value-changed=${this._valueChanged}
></ha-form>
`;
}
private _valueChanged(ev: CustomEvent): void {
fireEvent(this, "config-changed", { config: ev.detail.value });
}
private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
switch (schema.name) {
case "hours_to_show":
return this.hass!.localize(
`ui.panel.lovelace.editor.card.generic.${schema.name}`
);
default:
return "";
}
};
}
declare global {
interface HTMLElementTagNameMap {
"hui-trend-graph-card-feature-editor": HuiTrendGraphCardFeatureEditor;
}
}

View File

@ -33,8 +33,28 @@ const processAreasForClimate = (
area: area.area_id,
});
const areaEntities = entities.filter(areaFilter);
const areaCards: LovelaceCardConfig[] = [];
if (areaEntities.length > 0) {
const temperatureEntityId = area.temperature_entity_id;
if (temperatureEntityId && hass.states[temperatureEntityId]) {
areaCards.push({
...computeTileCard(temperatureEntityId),
features: [{ type: "trend-graph" }],
});
}
const humidityEntityId = area.humidity_entity_id;
if (humidityEntityId && hass.states[humidityEntityId]) {
areaCards.push({
...computeTileCard(humidityEntityId),
features: [{ type: "trend-graph" }],
});
}
for (const entityId of areaEntities) {
areaCards.push(computeTileCard(entityId));
}
if (areaCards.length > 0) {
cards.push({
heading_style: "subtitle",
type: "heading",
@ -44,23 +64,7 @@ const processAreasForClimate = (
navigation_path: `areas-${area.area_id}`,
},
});
if (area.temperature_entity_id) {
cards.push({
...computeTileCard(area.temperature_entity_id),
features: [{ type: "trend-graph" }],
});
}
if (area.humidity_entity_id) {
cards.push({
...computeTileCard(area.humidity_entity_id),
features: [{ type: "trend-graph" }],
});
}
for (const entityId of areaEntities) {
cards.push(computeTileCard(entityId));
}
cards.push(...areaCards);
}
}

View File

@ -32,10 +32,15 @@ const processAreasForLights = (
area: area.area_id,
});
const areaLights = entities.filter(areaFilter);
const areaCards: LovelaceCardConfig[] = [];
const computeTileCard = computeAreaTileCardConfig(hass, "", false);
if (areaLights.length > 0) {
for (const entityId of areaLights) {
areaCards.push(computeTileCard(entityId));
}
if (areaCards.length > 0) {
cards.push({
heading_style: "subtitle",
type: "heading",
@ -45,10 +50,7 @@ const processAreasForLights = (
navigation_path: `areas-${area.area_id}`,
},
});
for (const entityId of areaLights) {
cards.push(computeTileCard(entityId));
}
cards.push(...areaCards);
}
}

View File

@ -29,6 +29,14 @@ const processAreasForMediaPlayers = (
area: area.area_id,
});
const areaEntities = entities.filter(areaFilter);
const areaCards: LovelaceCardConfig[] = [];
for (const entityId of areaEntities) {
cards.push({
type: "media-control",
entity: entityId,
} satisfies MediaControlCardConfig);
}
if (areaEntities.length > 0) {
cards.push({
@ -40,13 +48,7 @@ const processAreasForMediaPlayers = (
navigation_path: `areas-${area.area_id}`,
},
});
for (const entityId of areaEntities) {
cards.push({
type: "media-control",
entity: entityId,
} satisfies MediaControlCardConfig);
}
cards.push(...areaCards);
}
}

View File

@ -32,7 +32,13 @@ const processAreasForSecurity = (
const areaFilter = generateEntityFilter(hass, {
area: area.area_id,
});
const areaEntities = entities.filter(areaFilter);
const areaCards: LovelaceCardConfig[] = [];
for (const entityId of areaEntities) {
areaCards.push(computeTileCard(entityId));
}
if (areaEntities.length > 0) {
cards.push({
@ -44,10 +50,7 @@ const processAreasForSecurity = (
navigation_path: `areas-${area.area_id}`,
},
});
for (const entityId of areaEntities) {
cards.push(computeTileCard(entityId));
}
cards.push(...areaCards);
}
}

View File

@ -5,7 +5,7 @@
"config": "Settings",
"states": "Overview",
"map": "Map",
"logbook": "Activity",
"logbook": "Logbook",
"history": "History",
"todo": "To-do lists",
"developer_tools": "Developer tools",
@ -526,7 +526,7 @@
}
},
"logbook": {
"entries_not_found": "No activity found.",
"entries_not_found": "No logbook events found.",
"triggered_by": "triggered by",
"triggered_by_automation": "triggered by automation",
"triggered_by_script": "triggered by script",
@ -539,7 +539,7 @@
"triggered_by_homeassistant_stopping": "triggered by Home Assistant stopping",
"triggered_by_homeassistant_starting": "triggered by Home Assistant starting",
"show_trace": "[%key:ui::panel::config::automation::editor::show_trace%]",
"retrieval_error": "Could not load activity",
"retrieval_error": "Could not load logbook",
"not_loaded": "[%key:ui::dialogs::helper_settings::platform_not_loaded%]",
"messages": {
"was_away": "was detected away",
@ -1382,7 +1382,7 @@
"info": "Information",
"related": "Related",
"history": "History",
"logbook": "Activity",
"logbook": "Logbook",
"device_info": "Device info",
"device_or_service_info": "[%key:ui::panel::config::devices::device_info%]",
"device_type": {
@ -2040,6 +2040,9 @@
"title": "Shortcuts",
"enable_shortcuts_hint": "For keyboard shortcuts to work, make sure you have them enabled in your {user_profile}.",
"enable_shortcuts_hint_user_profile": "user profile",
"keys": {
"del": "Del"
},
"shortcuts": {
"double_click": "Double-click",
"scroll_wheel": "Scroll",
@ -4593,7 +4596,7 @@
"tabs": {
"details": "Step details",
"timeline": "Trace timeline",
"logbook": "Related activity",
"logbook": "Related logbook entries",
"automation_config": "Automation config",
"step_config": "Step config",
"changed_variables": "Changed variables",
@ -4610,7 +4613,7 @@
"error": "Error: {error}",
"result": "Result:",
"step_not_executed": "This step was not executed.",
"no_logbook_entries": "No activity found for this step.",
"no_logbook_entries": "No logbook entries found for this step.",
"no_variables_changed": "No variables changed",
"unable_to_find_config": "Unable to find config"
},
@ -4636,8 +4639,8 @@
"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.",
"not_all_entries_are_related_automation_note": "Not all shown activity might be related to this automation.",
"not_all_entries_are_related_script_note": "Not all shown activity might be related to this script."
"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."
}
}
},
@ -7554,8 +7557,8 @@
"square": "Render cards as squares"
},
"logbook": {
"name": "Activity",
"description": "The Activity card shows a list of events for entities."
"name": "Logbook",
"description": "The Logbook card shows a list of events for entities."
},
"history-graph": {
"name": "History graph",