mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 05:47:20 +00:00
Add badge to configuration sidebar to indicate pending updates (#12146)
This commit is contained in:
parent
ca22ec6340
commit
85d3011625
@ -37,6 +37,7 @@ import { LocalStorage } from "../common/decorators/local-storage";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { toggleAttribute } from "../common/dom/toggle_attribute";
|
||||
import { computeDomain } from "../common/entity/compute_domain";
|
||||
import { computeStateDomain } from "../common/entity/compute_state_domain";
|
||||
import { stringCompare } from "../common/string/compare";
|
||||
import { computeRTL } from "../common/util/compute_rtl";
|
||||
import { ActionHandlerDetail } from "../data/lovelace";
|
||||
@ -44,6 +45,7 @@ import {
|
||||
PersistentNotification,
|
||||
subscribeNotifications,
|
||||
} from "../data/persistent_notification";
|
||||
import { updateCanInstall, UpdateEntity } from "../data/update";
|
||||
import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
import type { HomeAssistant, PanelInfo, Route } from "../types";
|
||||
@ -68,7 +70,6 @@ const SORT_VALUE_URL_PATHS = {
|
||||
|
||||
const PANEL_ICONS = {
|
||||
calendar: mdiCalendar,
|
||||
config: mdiCog,
|
||||
"developer-tools": mdiHammer,
|
||||
energy: mdiLightningBolt,
|
||||
history: mdiChartBox,
|
||||
@ -190,6 +191,8 @@ class HaSidebar extends LitElement {
|
||||
|
||||
@state() private _notifications?: PersistentNotification[];
|
||||
|
||||
@state() private _updatesCount = 0;
|
||||
|
||||
@state() private _renderEmptySortable = false;
|
||||
|
||||
private _mouseLeaveTimeout?: number;
|
||||
@ -235,6 +238,7 @@ class HaSidebar extends LitElement {
|
||||
changedProps.has("narrow") ||
|
||||
changedProps.has("alwaysExpand") ||
|
||||
changedProps.has("_externalConfig") ||
|
||||
changedProps.has("_updatesCount") ||
|
||||
changedProps.has("_notifications") ||
|
||||
changedProps.has("editMode") ||
|
||||
changedProps.has("_renderEmptySortable") ||
|
||||
@ -290,6 +294,12 @@ class HaSidebar extends LitElement {
|
||||
toggleAttribute(this, "rtl", computeRTL(this.hass));
|
||||
}
|
||||
|
||||
this._updatesCount = Object.values(this.hass.states).filter(
|
||||
(entity) =>
|
||||
computeStateDomain(entity) === "update" &&
|
||||
updateCanInstall(entity as UpdateEntity)
|
||||
).length;
|
||||
|
||||
if (!SUPPORT_SCROLL_IF_NEEDED) {
|
||||
return;
|
||||
}
|
||||
@ -387,35 +397,37 @@ class HaSidebar extends LitElement {
|
||||
icon?: string | null,
|
||||
iconPath?: string | null
|
||||
) {
|
||||
return html`
|
||||
<a
|
||||
role="option"
|
||||
href=${`/${urlPath}`}
|
||||
data-panel=${urlPath}
|
||||
tabindex="-1"
|
||||
@mouseenter=${this._itemMouseEnter}
|
||||
@mouseleave=${this._itemMouseLeave}
|
||||
>
|
||||
<paper-icon-item>
|
||||
${iconPath
|
||||
? html`<ha-svg-icon
|
||||
slot="item-icon"
|
||||
.path=${iconPath}
|
||||
></ha-svg-icon>`
|
||||
: html`<ha-icon slot="item-icon" .icon=${icon}></ha-icon>`}
|
||||
<span class="item-text">${title}</span>
|
||||
</paper-icon-item>
|
||||
${this.editMode
|
||||
? html`<ha-icon-button
|
||||
.label=${this.hass.localize("ui.sidebar.hide_panel")}
|
||||
.path=${mdiClose}
|
||||
class="hide-panel"
|
||||
.panel=${urlPath}
|
||||
@click=${this._hidePanel}
|
||||
></ha-icon-button>`
|
||||
: ""}
|
||||
</a>
|
||||
`;
|
||||
return urlPath === "config"
|
||||
? this._renderConfiguration(title)
|
||||
: html`
|
||||
<a
|
||||
role="option"
|
||||
href=${`/${urlPath}`}
|
||||
data-panel=${urlPath}
|
||||
tabindex="-1"
|
||||
@mouseenter=${this._itemMouseEnter}
|
||||
@mouseleave=${this._itemMouseLeave}
|
||||
>
|
||||
<paper-icon-item>
|
||||
${iconPath
|
||||
? html`<ha-svg-icon
|
||||
slot="item-icon"
|
||||
.path=${iconPath}
|
||||
></ha-svg-icon>`
|
||||
: html`<ha-icon slot="item-icon" .icon=${icon}></ha-icon>`}
|
||||
<span class="item-text">${title}</span>
|
||||
</paper-icon-item>
|
||||
${this.editMode
|
||||
? html`<ha-icon-button
|
||||
.label=${this.hass.localize("ui.sidebar.hide_panel")}
|
||||
.path=${mdiClose}
|
||||
class="hide-panel"
|
||||
.panel=${urlPath}
|
||||
@click=${this._hidePanel}
|
||||
></ha-icon-button>`
|
||||
: ""}
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderPanelsEdit(beforeSpacer: PanelInfo[]) {
|
||||
@ -477,6 +489,35 @@ class HaSidebar extends LitElement {
|
||||
return html`<div class="spacer" disabled></div>`;
|
||||
}
|
||||
|
||||
private _renderConfiguration(title: string | null) {
|
||||
return html` <a
|
||||
class="configuration-container"
|
||||
role="option"
|
||||
href="/config"
|
||||
data-panel="config"
|
||||
tabindex="-1"
|
||||
@mouseenter=${this._itemMouseEnter}
|
||||
@mouseleave=${this._itemMouseLeave}
|
||||
>
|
||||
<paper-icon-item class="configuration" role="option">
|
||||
<ha-svg-icon slot="item-icon" .path=${mdiCog}></ha-svg-icon>
|
||||
${!this.alwaysExpand && this._updatesCount > 0
|
||||
? html`
|
||||
<span class="configuration-badge" slot="item-icon">
|
||||
${this._updatesCount}
|
||||
</span>
|
||||
`
|
||||
: ""}
|
||||
<span class="item-text">${title}</span>
|
||||
${this.alwaysExpand && this._updatesCount > 0
|
||||
? html`
|
||||
<span class="configuration-badge">${this._updatesCount}</span>
|
||||
`
|
||||
: ""}
|
||||
</paper-icon-item>
|
||||
</a>`;
|
||||
}
|
||||
|
||||
private _renderNotifications() {
|
||||
let notificationCount = this._notifications
|
||||
? this._notifications.length
|
||||
@ -953,18 +994,21 @@ class HaSidebar extends LitElement {
|
||||
height: 1px;
|
||||
background-color: var(--divider-color);
|
||||
}
|
||||
.notifications-container {
|
||||
.notifications-container,
|
||||
.configuration-container {
|
||||
display: flex;
|
||||
margin-left: env(safe-area-inset-left);
|
||||
}
|
||||
:host([rtl]) .notifications-container {
|
||||
:host([rtl]) .notifications-container,
|
||||
:host([rtl]) .configuration-container {
|
||||
margin-left: initial;
|
||||
margin-right: env(safe-area-inset-right);
|
||||
}
|
||||
.notifications {
|
||||
cursor: pointer;
|
||||
}
|
||||
.notifications .item-text {
|
||||
.notifications .item-text,
|
||||
.configuration .item-text {
|
||||
flex: 1;
|
||||
}
|
||||
.profile {
|
||||
@ -988,7 +1032,8 @@ class HaSidebar extends LitElement {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.notification-badge {
|
||||
.notification-badge,
|
||||
.configuration-badge {
|
||||
min-width: 20px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
@ -999,7 +1044,11 @@ class HaSidebar extends LitElement {
|
||||
padding: 0px 6px;
|
||||
color: var(--text-accent-color, var(--text-primary-color));
|
||||
}
|
||||
ha-svg-icon + .notification-badge {
|
||||
.configuration-badge {
|
||||
background-color: var(--primary-color);
|
||||
}
|
||||
ha-svg-icon + .notification-badge,
|
||||
ha-svg-icon + .configuration-badge {
|
||||
position: absolute;
|
||||
bottom: 14px;
|
||||
left: 26px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user