Merge pull request #12582 from home-assistant/dev
This commit is contained in:
commit
a39af9c307
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = home-assistant-frontend
|
name = home-assistant-frontend
|
||||||
version = 20220503.0
|
version = 20220504.0
|
||||||
author = The Home Assistant Authors
|
author = The Home Assistant Authors
|
||||||
author_email = hello@home-assistant.io
|
author_email = hello@home-assistant.io
|
||||||
license = Apache-2.0
|
license = Apache-2.0
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
import "@lit-labs/virtualizer";
|
||||||
|
import type { LitVirtualizer } from "@lit-labs/virtualizer";
|
||||||
|
import { grid } from "@lit-labs/virtualizer/layouts/grid";
|
||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import "@material/mwc-list/mwc-list";
|
import "@material/mwc-list/mwc-list";
|
||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import { mdiArrowUpRight, mdiPlay, mdiPlus } from "@mdi/js";
|
import { mdiArrowUpRight, mdiPlay, mdiPlus } from "@mdi/js";
|
||||||
import "@polymer/paper-tooltip/paper-tooltip";
|
import "@polymer/paper-tooltip/paper-tooltip";
|
||||||
import { grid } from "@lit-labs/virtualizer/layouts/grid";
|
|
||||||
import "@lit-labs/virtualizer";
|
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
|
@ -21,10 +22,12 @@ import {
|
||||||
state,
|
state,
|
||||||
} from "lit/decorators";
|
} from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { until } from "lit/directives/until";
|
import { until } from "lit/directives/until";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
import { computeRTLDirection } from "../../common/util/compute_rtl";
|
import { computeRTLDirection } from "../../common/util/compute_rtl";
|
||||||
import { debounce } from "../../common/util/debounce";
|
import { debounce } from "../../common/util/debounce";
|
||||||
|
import { getSignedPath } from "../../data/auth";
|
||||||
import type { MediaPlayerItem } from "../../data/media-player";
|
import type { MediaPlayerItem } from "../../data/media-player";
|
||||||
import {
|
import {
|
||||||
browseMediaPlayer,
|
browseMediaPlayer,
|
||||||
|
@ -39,6 +42,7 @@ import { showAlertDialog } from "../../dialogs/generic/show-dialog-box";
|
||||||
import { installResizeObserver } from "../../panels/lovelace/common/install-resize-observer";
|
import { installResizeObserver } from "../../panels/lovelace/common/install-resize-observer";
|
||||||
import { haStyle } from "../../resources/styles";
|
import { haStyle } from "../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../types";
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import { brandsUrl, extractDomainFromBrandUrl } from "../../util/brands-url";
|
||||||
import { documentationUrl } from "../../util/documentation-url";
|
import { documentationUrl } from "../../util/documentation-url";
|
||||||
import "../entity/ha-entity-picker";
|
import "../entity/ha-entity-picker";
|
||||||
import "../ha-button-menu";
|
import "../ha-button-menu";
|
||||||
|
@ -49,8 +53,6 @@ import "../ha-icon-button";
|
||||||
import "../ha-svg-icon";
|
import "../ha-svg-icon";
|
||||||
import "./ha-browse-media-tts";
|
import "./ha-browse-media-tts";
|
||||||
import type { TtsMediaPickedEvent } from "./ha-browse-media-tts";
|
import type { TtsMediaPickedEvent } from "./ha-browse-media-tts";
|
||||||
import { getSignedPath } from "../../data/auth";
|
|
||||||
import { brandsUrl, extractDomainFromBrandUrl } from "../../util/brands-url";
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
|
@ -100,6 +102,10 @@ export class HaMediaPlayerBrowse extends LitElement {
|
||||||
|
|
||||||
@query(".content") private _content?: HTMLDivElement;
|
@query(".content") private _content?: HTMLDivElement;
|
||||||
|
|
||||||
|
@query("lit-virtualizer") private _virtualizer?: LitVirtualizer;
|
||||||
|
|
||||||
|
private _observed = false;
|
||||||
|
|
||||||
private _headerOffsetHeight = 0;
|
private _headerOffsetHeight = 0;
|
||||||
|
|
||||||
private _resizeObserver?: ResizeObserver;
|
private _resizeObserver?: ResizeObserver;
|
||||||
|
@ -280,6 +286,19 @@ export class HaMediaPlayerBrowse extends LitElement {
|
||||||
this._animateHeaderHeight();
|
this._animateHeaderHeight();
|
||||||
} else if (changedProps.has("_currentItem")) {
|
} else if (changedProps.has("_currentItem")) {
|
||||||
this._setHeaderHeight();
|
this._setHeaderHeight();
|
||||||
|
|
||||||
|
// This fixes a race condition for resizing of the cards using the grid layout
|
||||||
|
if (this._observed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const virtualizer = this._virtualizer?._virtualizer;
|
||||||
|
|
||||||
|
if (virtualizer) {
|
||||||
|
this._observed = true;
|
||||||
|
setTimeout(() => virtualizer._observeMutations(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,6 +496,9 @@ export class HaMediaPlayerBrowse extends LitElement {
|
||||||
<lit-virtualizer
|
<lit-virtualizer
|
||||||
scroller
|
scroller
|
||||||
.items=${children}
|
.items=${children}
|
||||||
|
style=${styleMap({
|
||||||
|
height: `${children.length * 72 + 26}px`,
|
||||||
|
})}
|
||||||
.renderItem=${this._renderListItem}
|
.renderItem=${this._renderListItem}
|
||||||
></lit-virtualizer>
|
></lit-virtualizer>
|
||||||
${currentItem.not_shown
|
${currentItem.not_shown
|
||||||
|
@ -606,7 +628,6 @@ export class HaMediaPlayerBrowse extends LitElement {
|
||||||
</div>
|
</div>
|
||||||
<span class="title">${child.title}</span>
|
<span class="title">${child.title}</span>
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
<li divider role="separator"></li>
|
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,10 @@ import type {
|
||||||
HassEntities,
|
HassEntities,
|
||||||
HassEntityAttributeBase,
|
HassEntityAttributeBase,
|
||||||
HassEntityBase,
|
HassEntityBase,
|
||||||
|
HassEvent,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import { BINARY_STATE_ON } from "../common/const";
|
import { BINARY_STATE_ON } from "../common/const";
|
||||||
|
import { computeDomain } from "../common/entity/compute_domain";
|
||||||
import { computeStateDomain } from "../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../common/entity/compute_state_domain";
|
||||||
import { supportsFeature } from "../common/entity/supports-feature";
|
import { supportsFeature } from "../common/entity/supports-feature";
|
||||||
import { caseInsensitiveStringCompare } from "../common/string/compare";
|
import { caseInsensitiveStringCompare } from "../common/string/compare";
|
||||||
|
@ -110,15 +112,32 @@ export const checkForEntityUpdates = async (
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let updated = 0;
|
||||||
|
|
||||||
|
const unsubscribeEvents = await hass.connection.subscribeEvents<HassEvent>(
|
||||||
|
(event) => {
|
||||||
|
if (computeDomain(event.data.entity_id) === "update") {
|
||||||
|
updated++;
|
||||||
|
showToast(element, {
|
||||||
|
message: hass.localize("ui.panel.config.updates.updates_refreshed", {
|
||||||
|
count: updated,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"state_changed"
|
||||||
|
);
|
||||||
|
|
||||||
await hass.callService("homeassistant", "update_entity", {
|
await hass.callService("homeassistant", "update_entity", {
|
||||||
entity_id: entities,
|
entity_id: entities,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (filterUpdateEntitiesWithInstall(hass.states).length) {
|
// there is no reliable way to know if all the updates are done updating, so we just wait a bit for now...
|
||||||
showToast(element, {
|
await new Promise((r) => setTimeout(r, 10000));
|
||||||
message: hass.localize("ui.panel.config.updates.updates_refreshed"),
|
|
||||||
});
|
unsubscribeEvents();
|
||||||
} else {
|
|
||||||
|
if (updated === 0) {
|
||||||
showToast(element, {
|
showToast(element, {
|
||||||
message: hass.localize("ui.panel.config.updates.no_new_updates"),
|
message: hass.localize("ui.panel.config.updates.no_new_updates"),
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import deepClone from "deep-clone-simple";
|
||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import { css, CSSResultGroup, html, LitElement } from "lit";
|
import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
@ -83,7 +84,7 @@ export default class HaAutomationAction extends LitElement {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const index = (ev.target as any).index;
|
const index = (ev.target as any).index;
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
value: this.actions.concat(this.actions[index]),
|
value: this.actions.concat(deepClone(this.actions[index])),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import deepClone from "deep-clone-simple";
|
||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
|
import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
@ -96,7 +97,7 @@ export default class HaAutomationCondition extends LitElement {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const index = (ev.target as any).index;
|
const index = (ev.target as any).index;
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
value: this.conditions.concat(this.conditions[index]),
|
value: this.conditions.concat(deepClone(this.conditions[index])),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import deepClone from "deep-clone-simple";
|
||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import { css, CSSResultGroup, html, LitElement } from "lit";
|
import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
@ -67,7 +68,7 @@ export default class HaAutomationTrigger extends LitElement {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const index = (ev.target as any).index;
|
const index = (ev.target as any).index;
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
value: this.triggers.concat(this.triggers[index]),
|
value: this.triggers.concat(deepClone(this.triggers[index])),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,11 @@ class HaConfigSectionUpdates extends LitElement {
|
||||||
></ha-config-updates>
|
></ha-config-updates>
|
||||||
`
|
`
|
||||||
: html`
|
: html`
|
||||||
${this.hass.localize("ui.panel.config.updates.no_updates")}
|
<div class="no-updates">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.updates.no_updates"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
|
@ -198,6 +202,10 @@ class HaConfigSectionUpdates extends LitElement {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-updates {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import "../../../components/ha-alert";
|
||||||
import "../../../components/ha-icon-next";
|
import "../../../components/ha-icon-next";
|
||||||
import type { UpdateEntity } from "../../../data/update";
|
import type { UpdateEntity } from "../../../data/update";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
|
import "../../../components/ha-circular-progress";
|
||||||
|
|
||||||
@customElement("ha-config-updates")
|
@customElement("ha-config-updates")
|
||||||
class HaConfigUpdates extends LitElement {
|
class HaConfigUpdates extends LitElement {
|
||||||
|
@ -51,7 +52,18 @@ class HaConfigUpdates extends LitElement {
|
||||||
.title=${entity.attributes.title ||
|
.title=${entity.attributes.title ||
|
||||||
entity.attributes.friendly_name}
|
entity.attributes.friendly_name}
|
||||||
.stateObj=${entity}
|
.stateObj=${entity}
|
||||||
|
class=${this.narrow && entity.attributes.in_progress
|
||||||
|
? "updating"
|
||||||
|
: ""}
|
||||||
></state-badge>
|
></state-badge>
|
||||||
|
${this.narrow && entity.attributes.in_progress
|
||||||
|
? html`<ha-circular-progress
|
||||||
|
active
|
||||||
|
size="small"
|
||||||
|
slot="graphic"
|
||||||
|
class="absolute"
|
||||||
|
></ha-circular-progress>`
|
||||||
|
: ""}
|
||||||
<span
|
<span
|
||||||
>${entity.attributes.title ||
|
>${entity.attributes.title ||
|
||||||
entity.attributes.friendly_name}</span
|
entity.attributes.friendly_name}</span
|
||||||
|
@ -67,7 +79,13 @@ class HaConfigUpdates extends LitElement {
|
||||||
: ""}
|
: ""}
|
||||||
</span>
|
</span>
|
||||||
${!this.narrow
|
${!this.narrow
|
||||||
? html`<ha-icon-next slot="meta"></ha-icon-next>`
|
? entity.attributes.in_progress
|
||||||
|
? html`<ha-circular-progress
|
||||||
|
active
|
||||||
|
size="small"
|
||||||
|
slot="meta"
|
||||||
|
></ha-circular-progress>`
|
||||||
|
: html`<ha-icon-next slot="meta"></ha-icon-next>`
|
||||||
: ""}
|
: ""}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
`
|
`
|
||||||
|
@ -121,6 +139,12 @@ class HaConfigUpdates extends LitElement {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
ha-circular-progress.absolute {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
state-badge.updating {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ import type { ConfigEntryExtended } from "./ha-config-integrations";
|
||||||
import "./ha-integration-header";
|
import "./ha-integration-header";
|
||||||
|
|
||||||
const integrationsWithPanel = {
|
const integrationsWithPanel = {
|
||||||
hassio: "/hassio/dashboard",
|
|
||||||
mqtt: "/config/mqtt",
|
mqtt: "/config/mqtt",
|
||||||
zha: "/config/zha/dashboard",
|
zha: "/config/zha/dashboard",
|
||||||
zwave_js: "/config/zwave_js/dashboard",
|
zwave_js: "/config/zwave_js/dashboard",
|
||||||
|
|
|
@ -1175,7 +1175,7 @@
|
||||||
},
|
},
|
||||||
"updates": {
|
"updates": {
|
||||||
"caption": "Updates",
|
"caption": "Updates",
|
||||||
"description": "Manage updates of Home Assistant, Add-ons and devices",
|
"description": "Manage updates of Home Assistant, add-ons and devices",
|
||||||
"no_updates": "No updates available",
|
"no_updates": "No updates available",
|
||||||
"no_update_entities": {
|
"no_update_entities": {
|
||||||
"title": "Unable to check for updates",
|
"title": "Unable to check for updates",
|
||||||
|
@ -1183,7 +1183,7 @@
|
||||||
},
|
},
|
||||||
"check_updates": "Check for updates",
|
"check_updates": "Check for updates",
|
||||||
"no_new_updates": "No new updates found",
|
"no_new_updates": "No new updates found",
|
||||||
"updates_refreshed": "Updates refreshed",
|
"updates_refreshed": "{count} {count, plural,\n one {update}\n other {updates}\n} refreshed",
|
||||||
"title": "{count} {count, plural,\n one {update}\n other {updates}\n}",
|
"title": "{count} {count, plural,\n one {update}\n other {updates}\n}",
|
||||||
"unable_to_fetch": "Unable to load updates",
|
"unable_to_fetch": "Unable to load updates",
|
||||||
"version_available": "Version {version_available} is available",
|
"version_available": "Version {version_available} is available",
|
||||||
|
@ -1490,7 +1490,7 @@
|
||||||
},
|
},
|
||||||
"core": {
|
"core": {
|
||||||
"caption": "General",
|
"caption": "General",
|
||||||
"description": "Name, Timezone and locale settings",
|
"description": "Name, time zone and locale settings",
|
||||||
"section": {
|
"section": {
|
||||||
"core": {
|
"core": {
|
||||||
"header": "General Configuration",
|
"header": "General Configuration",
|
||||||
|
@ -3139,7 +3139,7 @@
|
||||||
},
|
},
|
||||||
"analytics": {
|
"analytics": {
|
||||||
"caption": "Analytics",
|
"caption": "Analytics",
|
||||||
"description": "Learn how to share data to better the Open Home"
|
"description": "Learn how to share data to improve Home Assistant"
|
||||||
},
|
},
|
||||||
"network": {
|
"network": {
|
||||||
"caption": "Network",
|
"caption": "Network",
|
||||||
|
@ -3184,11 +3184,11 @@
|
||||||
},
|
},
|
||||||
"system_health": {
|
"system_health": {
|
||||||
"caption": "System Health",
|
"caption": "System Health",
|
||||||
"description": "Status, Stats and Integration startup time",
|
"description": "Status, metrics and integration startup time",
|
||||||
"cpu_usage": "Processor Usage",
|
"cpu_usage": "Processor Usage",
|
||||||
"ram_usage": "Memory Usage",
|
"ram_usage": "Memory Usage",
|
||||||
"core_stats": "Core Stats",
|
"core_stats": "Core Metrics",
|
||||||
"supervisor_stats": "Supervisor Stats",
|
"supervisor_stats": "Supervisor Metrics",
|
||||||
"integration_start_time": "Integration Startup Time"
|
"integration_start_time": "Integration Startup Time"
|
||||||
},
|
},
|
||||||
"system_dashboard": {
|
"system_dashboard": {
|
||||||
|
|
Loading…
Reference in New Issue