Compare commits

..

1 Commits

Author SHA1 Message Date
Ludeeus
a6f8f0495c Do not show skip if entity support auto update 2022-03-31 16:12:48 +00:00
12 changed files with 214 additions and 230 deletions

View File

@@ -6,6 +6,7 @@ import {
UPDATE_SUPPORT_PROGRESS,
UPDATE_SUPPORT_INSTALL,
UPDATE_SUPPORT_RELEASE_NOTES,
UPDATE_SUPPORT_AUTO_UPDATE,
} from "../../../../src/data/update";
import "../../../../src/dialogs/more-info/more-info-content";
import { getEntity } from "../../../../src/fake_data/entity";
@@ -18,7 +19,7 @@ import { LONG_TEXT } from "../../data/text";
const base_attributes = {
title: "Awesome",
installed_version: "1.2.2",
current_version: "1.2.2",
latest_version: "1.2.3",
release_url: "https://home-assistant.io",
supported_features: UPDATE_SUPPORT_INSTALL,
@@ -50,7 +51,7 @@ const ENTITIES = [
}),
getEntity("update", "update5", "off", {
...base_attributes,
installed_version: "1.2.3",
current_version: "1.2.3",
friendly_name: "No update",
}),
getEntity("update", "update6", "off", {
@@ -102,8 +103,8 @@ const ENTITIES = [
}),
getEntity("update", "update14", "off", {
...base_attributes,
installed_version: null,
friendly_name: "Update without installed_version",
current_version: null,
friendly_name: "Update without current_version",
}),
getEntity("update", "update15", "off", {
...base_attributes,
@@ -128,10 +129,11 @@ const ENTITIES = [
supported_features:
base_attributes.supported_features + UPDATE_SUPPORT_RELEASE_NOTES,
}),
getEntity("update", "update19", "on", {
getEntity("update", "update18", "on", {
...base_attributes,
friendly_name: "Update with auto update",
auto_update: true,
supported_features:
base_attributes.supported_features + UPDATE_SUPPORT_AUTO_UPDATE,
}),
];

View File

@@ -32,6 +32,13 @@ interface AddonCheckboxItem extends CheckboxItem {
const _computeFolders = (folders): CheckboxItem[] => {
const list: CheckboxItem[] = [];
if (folders.includes("homeassistant")) {
list.push({
slug: "homeassistant",
name: "Home Assistant configuration",
checked: false,
});
}
if (folders.includes("ssl")) {
list.push({ slug: "ssl", name: "SSL", checked: false });
}
@@ -93,7 +100,7 @@ export class SupervisorBackupContent extends LitElement {
this.folders = _computeFolders(
this.backup
? this.backup.folders
: ["ssl", "share", "media", "addons/local"]
: ["homeassistant", "ssl", "share", "media", "addons/local"]
);
this.addons = _computeAddons(
this.backup ? this.backup.addons : this.supervisor?.supervisor.addons

View File

@@ -1,6 +1,6 @@
[metadata]
name = home-assistant-frontend
version = 20220401.0
version = 20220330.0
author = The Home Assistant Authors
author_email = hello@home-assistant.io
license = Apache-2.0

View File

@@ -68,7 +68,7 @@ class HaDevicesPicker extends LitElement {
.excludeDomains=${this.excludeDomains}
.includeDeviceClasses=${this.includeDeviceClasses}
.label=${this.pickDeviceLabel}
.required=${this.required && !currentDevices.length}
.required=${this.required}
@value-changed=${this._addDevice}
></ha-device-picker>
</div>

View File

@@ -110,7 +110,7 @@ class HaEntitiesPickerLight extends LitElement {
.includeUnitOfMeasurement=${this.includeUnitOfMeasurement}
.entityFilter=${this._entityFilter}
.label=${this.pickEntityLabel}
.required=${this.required && !currentEntities.length}
.required=${this.required}
@value-changed=${this._addEntity}
></ha-entity-picker>
</div>

View File

@@ -97,7 +97,7 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
.entityFilter=${this.entityFilter}
.disabled=${this.disabled}
.placeholder=${this.placeholder}
.required=${this.required && !currentAreas.length}
.required=${this.required}
@value-changed=${this._addArea}
></ha-area-picker>
</div>

View File

@@ -108,7 +108,7 @@ export class HaSelectSelector extends LitElement {
.hass=${this.hass}
.label=${this.label}
.disabled=${this.disabled}
.required=${this.required && !value.length}
.required=${this.required}
.value=${this._filter}
.items=${options.filter((item) => !this.value?.includes(item.value))}
@filter-changed=${this._filterChanged}

View File

@@ -11,10 +11,10 @@ export const UPDATE_SUPPORT_SPECIFIC_VERSION = 2;
export const UPDATE_SUPPORT_PROGRESS = 4;
export const UPDATE_SUPPORT_BACKUP = 8;
export const UPDATE_SUPPORT_RELEASE_NOTES = 16;
export const UPDATE_SUPPORT_AUTO_UPDATE = 32;
interface UpdateEntityAttributes extends HassEntityAttributeBase {
auto_update: boolean | null;
installed_version: string | null;
current_version: string | null;
in_progress: boolean | number;
latest_version: string | null;
release_summary: string | null;

View File

@@ -14,6 +14,7 @@ import {
UpdateEntity,
updateIsInstalling,
updateReleaseNotes,
UPDATE_SUPPORT_AUTO_UPDATE,
UPDATE_SUPPORT_BACKUP,
UPDATE_SUPPORT_INSTALL,
UPDATE_SUPPORT_PROGRESS,
@@ -66,11 +67,11 @@ class MoreInfoUpdate extends LitElement {
<div class="row">
<div class="key">
${this.hass.localize(
"ui.dialogs.more_info_control.update.installed_version"
"ui.dialogs.more_info_control.update.current_version"
)}
</div>
<div class="value">
${this.stateObj.attributes.installed_version ??
${this.stateObj.attributes.current_version ??
this.hass.localize("state.default.unavailable")}
</div>
</div>
@@ -130,20 +131,16 @@ class MoreInfoUpdate extends LitElement {
: ""}
<hr />
<div class="actions">
${this.stateObj.attributes.auto_update
${supportsFeature(this.stateObj, UPDATE_SUPPORT_AUTO_UPDATE)
? ""
: html`
<mwc-button
@click=${this._handleSkip}
.disabled=${skippedVersion ||
this.stateObj.state === "off" ||
updateIsInstalling(this.stateObj)}
>
${this.hass.localize(
"ui.dialogs.more_info_control.update.skip"
)}
</mwc-button>
`}
: html`<mwc-button
@click=${this._handleSkip}
.disabled=${skippedVersion ||
this.stateObj.state === "off" ||
updateIsInstalling(this.stateObj)}
>
${this.hass.localize("ui.dialogs.more_info_control.update.skip")}
</mwc-button>`}
${supportsFeature(this.stateObj, UPDATE_SUPPORT_INSTALL)
? html`
<mwc-button

View File

@@ -13,7 +13,6 @@ import { computeStateName } from "../../../common/entity/compute_state_name";
import "../../../components/ha-select";
import { UNAVAILABLE } from "../../../data/entity";
import { forwardHaptic } from "../../../data/haptics";
import type { InputSelectEntity } from "../../../data/input_select";
import { SelectEntity, setSelectOption } from "../../../data/select";
import { HomeAssistant } from "../../../types";
import { EntitiesCardEntityConfig } from "../cards/types";
@@ -107,14 +106,9 @@ class HuiSelectEntityRow extends LitElement implements LovelaceRow {
}
private _selectedChanged(ev): void {
const stateObj = this.hass!.states[
this._config!.entity
] as InputSelectEntity;
const stateObj = this.hass!.states[this._config!.entity];
const option = ev.target.value;
if (
option === stateObj.state ||
!stateObj.attributes.options.includes(option)
) {
if (option === stateObj.state) {
return;
}

View File

@@ -12,172 +12,158 @@ import "../../layouts/hass-error-screen";
import { HomeAssistant, Route } from "../../types";
import { documentationUrl } from "../../util/documentation-url";
const getRedirect = (
path: string,
hasSupervisor: boolean
): Redirect | undefined =>
((
{
developer_states: {
redirect: "/developer-tools/state",
},
developer_services: {
redirect: "/developer-tools/service",
},
developer_call_service: {
redirect: "/developer-tools/service",
params: {
service: "string",
},
},
developer_template: {
redirect: "/developer-tools/template",
},
developer_events: {
redirect: "/developer-tools/event",
},
developer_statistics: {
redirect: "/developer-tools/statistics",
},
config: {
redirect: "/config",
},
cloud: {
component: "cloud",
redirect: "/config/cloud",
},
integrations: {
redirect: "/config/integrations",
},
config_flow_start: {
redirect: "/config/integrations/add",
params: {
domain: "string",
},
},
config_mqtt: {
component: "mqtt",
redirect: "/config/mqtt",
},
config_zha: {
component: "zha",
redirect: "/config/zha/dashboard",
},
config_zwave_js: {
component: "zwave_js",
redirect: "/config/zwave_js/dashboard",
},
config_energy: {
component: "energy",
redirect: "/config/energy/dashboard",
},
devices: {
redirect: "/config/devices/dashboard",
},
entities: {
redirect: "/config/entities",
},
energy: {
component: "energy",
redirect: "/energy",
},
areas: {
redirect: "/config/areas/dashboard",
},
blueprints: {
component: "blueprint",
redirect: "/config/blueprint/dashboard",
},
blueprint_import: {
component: "blueprint",
redirect: "/config/blueprint/dashboard/import",
params: {
blueprint_url: "url",
},
},
automations: {
component: "automation",
redirect: "/config/automation/dashboard",
},
scenes: {
component: "scene",
redirect: "/config/scene/dashboard",
},
scripts: {
component: "script",
redirect: "/config/script/dashboard",
},
helpers: {
redirect: "/config/helpers",
},
tags: {
component: "tag",
redirect: "/config/tags",
},
lovelace_dashboards: {
component: "lovelace",
redirect: "/config/lovelace/dashboards",
},
lovelace_resources: {
component: "lovelace",
redirect: "/config/lovelace/resources",
},
people: {
component: "person",
redirect: "/config/person",
},
zones: {
component: "zone",
redirect: "/config/zone",
},
users: {
redirect: "/config/users",
},
general: {
redirect: "/config/core",
},
server_controls: {
redirect: "/config/server_control",
},
logs: {
redirect: "/config/logs",
},
info: {
redirect: "/config/info",
},
customize: {
// customize was removed in 2021.12, fallback to dashboard
redirect: "/config/dashboard",
},
profile: {
redirect: "/profile/dashboard",
},
logbook: {
component: "logbook",
redirect: "/logbook",
},
history: {
component: "history",
redirect: "/history",
},
media_browser: {
component: "media_source",
redirect: "/media-browser",
},
backup: {
component: hasSupervisor ? "hassio" : "backup",
redirect: hasSupervisor ? "/hassio/backups" : "/config/backup",
},
supervisor_snapshots: {
component: hasSupervisor ? "hassio" : "backup",
redirect: hasSupervisor ? "/hassio/backups" : "/config/backup",
},
supervisor_backups: {
component: hasSupervisor ? "hassio" : "backup",
redirect: hasSupervisor ? "/hassio/backups" : "/config/backup",
},
} as Redirects
)[path]);
const REDIRECTS: Redirects = {
developer_states: {
redirect: "/developer-tools/state",
},
developer_services: {
redirect: "/developer-tools/service",
},
developer_call_service: {
redirect: "/developer-tools/service",
params: {
service: "string",
},
},
developer_template: {
redirect: "/developer-tools/template",
},
developer_events: {
redirect: "/developer-tools/event",
},
developer_statistics: {
redirect: "/developer-tools/statistics",
},
config: {
redirect: "/config",
},
cloud: {
component: "cloud",
redirect: "/config/cloud",
},
integrations: {
redirect: "/config/integrations",
},
config_flow_start: {
redirect: "/config/integrations/add",
params: {
domain: "string",
},
},
config_mqtt: {
component: "mqtt",
redirect: "/config/mqtt",
},
config_zha: {
component: "zha",
redirect: "/config/zha/dashboard",
},
config_zwave_js: {
component: "zwave_js",
redirect: "/config/zwave_js/dashboard",
},
config_energy: {
component: "energy",
redirect: "/config/energy/dashboard",
},
devices: {
redirect: "/config/devices/dashboard",
},
entities: {
redirect: "/config/entities",
},
energy: {
component: "energy",
redirect: "/energy",
},
areas: {
redirect: "/config/areas/dashboard",
},
blueprints: {
component: "blueprint",
redirect: "/config/blueprint/dashboard",
},
blueprint_import: {
component: "blueprint",
redirect: "/config/blueprint/dashboard/import",
params: {
blueprint_url: "url",
},
},
automations: {
component: "automation",
redirect: "/config/automation/dashboard",
},
scenes: {
component: "scene",
redirect: "/config/scene/dashboard",
},
scripts: {
component: "script",
redirect: "/config/script/dashboard",
},
helpers: {
redirect: "/config/helpers",
},
tags: {
component: "tag",
redirect: "/config/tags",
},
lovelace_dashboards: {
component: "lovelace",
redirect: "/config/lovelace/dashboards",
},
lovelace_resources: {
component: "lovelace",
redirect: "/config/lovelace/resources",
},
backup: {
component: "backup",
redirect: "/config/backup",
},
people: {
component: "person",
redirect: "/config/person",
},
zones: {
component: "zone",
redirect: "/config/zone",
},
users: {
redirect: "/config/users",
},
general: {
redirect: "/config/core",
},
server_controls: {
redirect: "/config/server_control",
},
logs: {
redirect: "/config/logs",
},
info: {
redirect: "/config/info",
},
customize: {
// customize was removed in 2021.12, fallback to dashboard
redirect: "/config/dashboard",
},
profile: {
redirect: "/profile/dashboard",
},
logbook: {
component: "logbook",
redirect: "/logbook",
},
history: {
component: "history",
redirect: "/history",
},
media_browser: {
component: "media_source",
redirect: "/media-browser",
},
};
export type ParamType = "url" | "string";
@@ -198,17 +184,19 @@ class HaPanelMy extends LitElement {
@state() public _error?: string;
private _redirect?: Redirect;
connectedCallback() {
super.connectedCallback();
const path = this.route.path.substring(1);
const hasSupervisor = isComponentLoaded(this.hass, "hassio");
this._redirect = getRedirect(path, hasSupervisor);
if (path === "backup" && isComponentLoaded(this.hass, "hassio")) {
navigate("/hassio/backups", {
replace: true,
});
return;
}
if (path.startsWith("supervisor") && this._redirect === undefined) {
if (!hasSupervisor) {
if (path.startsWith("supervisor")) {
if (!isComponentLoaded(this.hass, "hassio")) {
this._error = "no_supervisor";
return;
}
@@ -218,14 +206,16 @@ class HaPanelMy extends LitElement {
return;
}
if (!this._redirect) {
const redirect = REDIRECTS[path];
if (!redirect) {
this._error = "not_supported";
return;
}
if (
this._redirect.component &&
!isComponentLoaded(this.hass, this._redirect.component)
redirect.component &&
!isComponentLoaded(this.hass, redirect.component)
) {
this._error = "no_component";
return;
@@ -233,7 +223,7 @@ class HaPanelMy extends LitElement {
let url: string;
try {
url = this._createRedirectUrl();
url = this._createRedirectUrl(redirect);
} catch (err: any) {
this._error = "url_error";
return;
@@ -264,16 +254,10 @@ class HaPanelMy extends LitElement {
this.hass.localize(
"ui.panel.my.component_not_loaded",
"integration",
html`<a
target="_blank"
rel="noreferrer noopener"
href=${documentationUrl(
this.hass,
`/integrations/${this._redirect!.component!}`
)}
>
${domainToName(this.hass.localize, this._redirect!.component!)}
</a>`
domainToName(
this.hass.localize,
REDIRECTS[this.route.path.substr(1)].component!
)
) || "This redirect is not supported.";
break;
case "no_supervisor":
@@ -296,18 +280,18 @@ class HaPanelMy extends LitElement {
return html``;
}
private _createRedirectUrl(): string {
const params = this._createRedirectParams();
return `${this._redirect!.redirect}${params}`;
private _createRedirectUrl(redirect: Redirect): string {
const params = this._createRedirectParams(redirect);
return `${redirect.redirect}${params}`;
}
private _createRedirectParams(): string {
private _createRedirectParams(redirect: Redirect): string {
const params = extractSearchParamsObject();
if (!this._redirect!.params && !Object.keys(params).length) {
if (!redirect.params && !Object.keys(params).length) {
return "";
}
const resultParams = {};
Object.entries(this._redirect!.params || {}).forEach(([key, type]) => {
Object.entries(redirect.params || {}).forEach(([key, type]) => {
if (!params[key] || !this._checkParamType(type, params[key])) {
throw Error();
}

View File

@@ -731,7 +731,7 @@
"setting": "Setting"
},
"update": {
"installed_version": "Installed version",
"current_version": "Current version",
"latest_version": "Latest version",
"release_announcement": "Read release announcement",
"skip": "Skip",