Support disabling devices (#7715)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
faaef31b9f
commit
3bdab738c6
|
@ -156,7 +156,9 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
|
|||
areaLookup[area.area_id] = area;
|
||||
}
|
||||
|
||||
let inputDevices = [...devices];
|
||||
let inputDevices = devices.filter(
|
||||
(device) => device.id === this.value || !device.disabled_by
|
||||
);
|
||||
|
||||
if (includeDomains) {
|
||||
inputDevices = inputDevices.filter((device) => {
|
||||
|
|
|
@ -17,6 +17,7 @@ export interface DeviceRegistryEntry {
|
|||
area_id?: string;
|
||||
name_by_user?: string;
|
||||
entry_type: "service" | null;
|
||||
disabled_by: string | null;
|
||||
}
|
||||
|
||||
export interface DeviceEntityLookup {
|
||||
|
@ -26,6 +27,7 @@ export interface DeviceEntityLookup {
|
|||
export interface DeviceRegistryEntryMutableParams {
|
||||
area_id?: string | null;
|
||||
name_by_user?: string | null;
|
||||
disabled_by?: string | null;
|
||||
}
|
||||
|
||||
export const fallbackDeviceName = (
|
||||
|
|
|
@ -19,10 +19,11 @@ import {
|
|||
|
||||
import { DeviceRegistryDetailDialogParams } from "./show-dialog-device-registry-detail";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import type { HaSwitch } from "../../../../components/ha-switch";
|
||||
import { PolymerChangedEvent } from "../../../../polymer-types";
|
||||
import { computeDeviceName } from "../../../../data/device_registry";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||
|
||||
@customElement("dialog-device-registry-detail")
|
||||
class DialogDeviceRegistryDetail extends LitElement {
|
||||
|
@ -36,6 +37,8 @@ class DialogDeviceRegistryDetail extends LitElement {
|
|||
|
||||
@internalProperty() private _areaId?: string;
|
||||
|
||||
@internalProperty() private _disabledBy!: string | null;
|
||||
|
||||
@internalProperty() private _submitting?: boolean;
|
||||
|
||||
public async showDialog(
|
||||
|
@ -45,6 +48,7 @@ class DialogDeviceRegistryDetail extends LitElement {
|
|||
this._error = undefined;
|
||||
this._nameByUser = this._params.device.name_by_user || "";
|
||||
this._areaId = this._params.device.area_id;
|
||||
this._disabledBy = this._params.device.disabled_by;
|
||||
await this.updateComplete;
|
||||
}
|
||||
|
||||
|
@ -80,6 +84,32 @@ class DialogDeviceRegistryDetail extends LitElement {
|
|||
.value=${this._areaId}
|
||||
@value-changed=${this._areaPicked}
|
||||
></ha-area-picker>
|
||||
<div class="row">
|
||||
<ha-switch
|
||||
.checked=${!this._disabledBy}
|
||||
@change=${this._disabledByChanged}
|
||||
>
|
||||
</ha-switch>
|
||||
<div>
|
||||
<div>
|
||||
${this.hass.localize("ui.panel.config.devices.enabled_label")}
|
||||
</div>
|
||||
<div class="secondary">
|
||||
${this._disabledBy && this._disabledBy !== "user"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.devices.enabled_cause",
|
||||
"cause",
|
||||
this.hass.localize(
|
||||
`config_entry.disabled_by.${this._disabledBy}`
|
||||
)
|
||||
)
|
||||
: ""}
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.devices.enabled_description"
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<mwc-button
|
||||
|
@ -109,12 +139,17 @@ class DialogDeviceRegistryDetail extends LitElement {
|
|||
this._areaId = event.detail.value;
|
||||
}
|
||||
|
||||
private _disabledByChanged(ev: Event): void {
|
||||
this._disabledBy = (ev.target as HaSwitch).checked ? null : "user";
|
||||
}
|
||||
|
||||
private async _updateEntry(): Promise<void> {
|
||||
this._submitting = true;
|
||||
try {
|
||||
await this._params!.updateEntry({
|
||||
name_by_user: this._nameByUser.trim() || null,
|
||||
area_id: this._areaId || null,
|
||||
disabled_by: this._disabledBy || null,
|
||||
});
|
||||
this._params = undefined;
|
||||
} catch (err) {
|
||||
|
@ -128,6 +163,7 @@ class DialogDeviceRegistryDetail extends LitElement {
|
|||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
.form {
|
||||
|
@ -139,6 +175,15 @@ class DialogDeviceRegistryDetail extends LitElement {
|
|||
.error {
|
||||
color: var(--error-color);
|
||||
}
|
||||
ha-switch {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.row {
|
||||
margin-top: 8px;
|
||||
color: var(--primary-text-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -246,6 +246,26 @@ export class HaConfigDevicePage extends LitElement {
|
|||
.devices=${this.devices}
|
||||
.device=${device}
|
||||
>
|
||||
${
|
||||
device.disabled_by
|
||||
? html`
|
||||
<div>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.devices.enabled_cause",
|
||||
"cause",
|
||||
device.disabled_by
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-actions" slot="actions">
|
||||
<mwc-button @click=${this._enableDevice}>
|
||||
${this.hass.localize("ui.common.enable")}
|
||||
</mwc-button>
|
||||
</div>
|
||||
`
|
||||
: html``
|
||||
}
|
||||
${this._renderIntegrationInfo(device, integrations)}
|
||||
</ha-device-info-card>
|
||||
|
||||
|
@ -272,9 +292,14 @@ export class HaConfigDevicePage extends LitElement {
|
|||
)}
|
||||
<ha-icon-button
|
||||
@click=${this._showAutomationDialog}
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.devices.automation.create"
|
||||
)}
|
||||
.disabled=${device.disabled_by}
|
||||
title=${device.disabled_by
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.devices.automation.create_disabled"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.devices.automation.create"
|
||||
)}
|
||||
icon="hass:plus-circle"
|
||||
></ha-icon-button>
|
||||
</h1>
|
||||
|
@ -342,9 +367,16 @@ export class HaConfigDevicePage extends LitElement {
|
|||
|
||||
<ha-icon-button
|
||||
@click=${this._createScene}
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.devices.scene.create"
|
||||
)}
|
||||
.disabled=${device.disabled_by}
|
||||
title=${
|
||||
device.disabled_by
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.devices.scene.create_disabled"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.devices.scene.create"
|
||||
)
|
||||
}
|
||||
icon="hass:plus-circle"
|
||||
></ha-icon-button>
|
||||
</h1>
|
||||
|
@ -415,9 +447,14 @@ export class HaConfigDevicePage extends LitElement {
|
|||
)}
|
||||
<ha-icon-button
|
||||
@click=${this._showScriptDialog}
|
||||
title=${this.hass.localize(
|
||||
"ui.panel.config.devices.script.create"
|
||||
)}
|
||||
.disabled=${device.disabled_by}
|
||||
title=${device.disabled_by
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.devices.script.create_disabled"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.devices.script.create"
|
||||
)}
|
||||
icon="hass:plus-circle"
|
||||
></ha-icon-button>
|
||||
</h1>
|
||||
|
@ -632,6 +669,12 @@ export class HaConfigDevicePage extends LitElement {
|
|||
});
|
||||
}
|
||||
|
||||
private async _enableDevice(): Promise<void> {
|
||||
await updateDeviceRegistryEntry(this.hass, this.deviceId, {
|
||||
disabled_by: null,
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
.container {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { mdiPlus } from "@mdi/js";
|
||||
import { mdiPlus, mdiFilterVariant } from "@mdi/js";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
|
@ -7,7 +10,9 @@ import {
|
|||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
|
||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||
|
@ -18,6 +23,7 @@ import {
|
|||
RowClickedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/entity/ha-battery-icon";
|
||||
import "../../../components/ha-button-menu";
|
||||
import { AreaRegistryEntry } from "../../../data/area_registry";
|
||||
import { ConfigEntry } from "../../../data/config_entries";
|
||||
import {
|
||||
|
@ -34,6 +40,7 @@ import { domainToName } from "../../../data/integration";
|
|||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
|
||||
interface DeviceRowData extends DeviceRegistryEntry {
|
||||
device?: DeviceRowData;
|
||||
|
@ -64,6 +71,12 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
window.location.search
|
||||
);
|
||||
|
||||
@internalProperty() private _showDisabled = false;
|
||||
|
||||
@internalProperty() private _filter = "";
|
||||
|
||||
@internalProperty() private _numHiddenDevices = 0;
|
||||
|
||||
private _activeFilters = memoizeOne(
|
||||
(
|
||||
entries: ConfigEntry[],
|
||||
|
@ -74,6 +87,10 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
filters.forEach((value, key) => {
|
||||
switch (key) {
|
||||
case "config_entry": {
|
||||
// If we are requested to show the devices for a given config entry,
|
||||
// also show the disabled ones by default.
|
||||
this._showDisabled = true;
|
||||
|
||||
const configEntry = entries.find(
|
||||
(entry) => entry.entry_id === value
|
||||
);
|
||||
|
@ -105,6 +122,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
entities: EntityRegistryEntry[],
|
||||
areas: AreaRegistryEntry[],
|
||||
filters: URLSearchParams,
|
||||
showDisabled: boolean,
|
||||
localize: LocalizeFunc
|
||||
) => {
|
||||
// Some older installations might have devices pointing at invalid entryIDs
|
||||
|
@ -117,6 +135,9 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
deviceLookup[device.id] = device;
|
||||
}
|
||||
|
||||
// If nothing gets filtered, this is our correct count of devices
|
||||
let startLength = outputDevices.length;
|
||||
|
||||
const deviceEntityLookup: DeviceEntityLookup = {};
|
||||
for (const entity of entities) {
|
||||
if (!entity.device_id) {
|
||||
|
@ -145,6 +166,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
outputDevices = outputDevices.filter((device) =>
|
||||
device.config_entries.includes(value)
|
||||
);
|
||||
startLength = outputDevices.length;
|
||||
const configEntry = entries.find((entry) => entry.entry_id === value);
|
||||
if (configEntry) {
|
||||
filterDomains.push(configEntry.domain);
|
||||
|
@ -152,6 +174,10 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
}
|
||||
});
|
||||
|
||||
if (!showDisabled) {
|
||||
outputDevices = outputDevices.filter((device) => !device.disabled_by);
|
||||
}
|
||||
|
||||
outputDevices = outputDevices.map((device) => {
|
||||
return {
|
||||
...device,
|
||||
|
@ -182,6 +208,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
};
|
||||
});
|
||||
|
||||
this._numHiddenDevices = startLength - outputDevices.length;
|
||||
return { devicesOutput: outputDevices, filteredDomains: filterDomains };
|
||||
}
|
||||
);
|
||||
|
@ -298,9 +325,119 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
this.entities,
|
||||
this.areas,
|
||||
this._searchParms,
|
||||
this._showDisabled,
|
||||
this.hass.localize
|
||||
);
|
||||
const includeZHAFab = filteredDomains.includes("zha");
|
||||
const activeFilters = this._activeFilters(
|
||||
this.entries,
|
||||
this._searchParms,
|
||||
this.hass.localize
|
||||
);
|
||||
|
||||
const headerToolbar = html`
|
||||
<search-input
|
||||
no-label-float
|
||||
no-underline
|
||||
@value-changed=${this._handleSearchChange}
|
||||
.filter=${this._filter}
|
||||
.label=${this.hass.localize("ui.panel.config.devices.picker.search")}
|
||||
></search-input
|
||||
>${activeFilters
|
||||
? html`<div class="active-filters">
|
||||
${this.narrow
|
||||
? html` <div>
|
||||
<ha-icon icon="hass:filter-variant"></ha-icon>
|
||||
<paper-tooltip animation-delay="0" position="left">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.filtering.filtering_by"
|
||||
)}
|
||||
${activeFilters.join(", ")}
|
||||
${this._numHiddenDevices
|
||||
? "(" +
|
||||
this.hass.localize(
|
||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
||||
"number",
|
||||
this._numHiddenDevices
|
||||
) +
|
||||
")"
|
||||
: ""}
|
||||
</paper-tooltip>
|
||||
</div>`
|
||||
: `${this.hass.localize(
|
||||
"ui.panel.config.filtering.filtering_by"
|
||||
)} ${activeFilters.join(", ")}
|
||||
${
|
||||
this._numHiddenDevices
|
||||
? "(" +
|
||||
this.hass.localize(
|
||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
||||
"number",
|
||||
this._numHiddenDevices
|
||||
) +
|
||||
")"
|
||||
: ""
|
||||
}
|
||||
`}
|
||||
<mwc-button @click=${this._clearFilter}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.filtering.clear"
|
||||
)}</mwc-button
|
||||
>
|
||||
</div>`
|
||||
: ""}
|
||||
${this._numHiddenDevices && !activeFilters
|
||||
? html`<div class="active-filters">
|
||||
${this.narrow
|
||||
? html` <div>
|
||||
<ha-icon icon="hass:filter-variant"></ha-icon>
|
||||
<paper-tooltip animation-delay="0" position="left">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
||||
"number",
|
||||
this._numHiddenDevices
|
||||
)}
|
||||
</paper-tooltip>
|
||||
</div>`
|
||||
: `${this.hass.localize(
|
||||
"ui.panel.config.devices.picker.filter.hidden_devices",
|
||||
"number",
|
||||
this._numHiddenDevices
|
||||
)}`}
|
||||
<mwc-button @click=${this._showAll}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.devices.picker.filter.show_all"
|
||||
)}</mwc-button
|
||||
>
|
||||
</div>`
|
||||
: ""}
|
||||
<ha-button-menu corner="BOTTOM_START" multi>
|
||||
<mwc-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass!.localize(
|
||||
"ui.panel.config.devices.picker.filter.filter"
|
||||
)}
|
||||
.title=${this.hass!.localize(
|
||||
"ui.panel.config.devices.picker.filter.filter"
|
||||
)}
|
||||
>
|
||||
<ha-svg-icon .path=${mdiFilterVariant}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
<mwc-list-item
|
||||
@request-selected="${this._showDisabledChanged}"
|
||||
graphic="control"
|
||||
.selected=${this._showDisabled}
|
||||
>
|
||||
<ha-checkbox
|
||||
slot="graphic"
|
||||
.checked=${this._showDisabled}
|
||||
></ha-checkbox>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.devices.picker.filter.show_disabled"
|
||||
)}
|
||||
</mwc-list-item>
|
||||
</ha-button-menu>
|
||||
`;
|
||||
|
||||
return html`
|
||||
<hass-tabs-subpage-data-table
|
||||
|
@ -313,11 +450,7 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
.route=${this.route}
|
||||
.columns=${this._columns(this.narrow)}
|
||||
.data=${devicesOutput}
|
||||
.activeFilters=${this._activeFilters(
|
||||
this.entries,
|
||||
this._searchParms,
|
||||
this.hass.localize
|
||||
)}
|
||||
.filter=${this._filter}
|
||||
@row-click=${this._handleRowClicked}
|
||||
clickable
|
||||
.hasFab=${includeZHAFab}
|
||||
|
@ -333,6 +466,15 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
</ha-fab>
|
||||
</a>`
|
||||
: html``}
|
||||
<div
|
||||
class=${classMap({
|
||||
"search-toolbar": this.narrow,
|
||||
"table-header": !this.narrow,
|
||||
})}
|
||||
slot="header"
|
||||
>
|
||||
${headerToolbar}
|
||||
</div>
|
||||
</hass-tabs-subpage-data-table>
|
||||
`;
|
||||
}
|
||||
|
@ -363,6 +505,136 @@ export class HaConfigDeviceDashboard extends LitElement {
|
|||
const deviceId = ev.detail.id;
|
||||
navigate(this, `/config/devices/device/${deviceId}`);
|
||||
}
|
||||
|
||||
private _showDisabledChanged(ev: CustomEvent<RequestSelectedDetail>) {
|
||||
if (ev.detail.source !== "property") {
|
||||
return;
|
||||
}
|
||||
this._showDisabled = ev.detail.selected;
|
||||
}
|
||||
|
||||
private _handleSearchChange(ev: CustomEvent) {
|
||||
this._filter = ev.detail.value;
|
||||
}
|
||||
|
||||
private _clearFilter() {
|
||||
navigate(this, window.location.pathname, true);
|
||||
}
|
||||
|
||||
private _showAll() {
|
||||
this._showDisabled = true;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
hass-loading-screen {
|
||||
--app-header-background-color: var(--sidebar-background-color);
|
||||
--app-header-text-color: var(--sidebar-text-color);
|
||||
}
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
font-family: var(--paper-font-headline_-_font-family);
|
||||
-webkit-font-smoothing: var(
|
||||
--paper-font-headline_-_-webkit-font-smoothing
|
||||
);
|
||||
font-size: var(--paper-font-headline_-_font-size);
|
||||
font-weight: var(--paper-font-headline_-_font-weight);
|
||||
letter-spacing: var(--paper-font-headline_-_letter-spacing);
|
||||
line-height: var(--paper-font-headline_-_line-height);
|
||||
opacity: var(--dark-primary-opacity);
|
||||
}
|
||||
p {
|
||||
font-family: var(--paper-font-subhead_-_font-family);
|
||||
-webkit-font-smoothing: var(
|
||||
--paper-font-subhead_-_-webkit-font-smoothing
|
||||
);
|
||||
font-weight: var(--paper-font-subhead_-_font-weight);
|
||||
line-height: var(--paper-font-subhead_-_line-height);
|
||||
}
|
||||
ha-data-table {
|
||||
width: 100%;
|
||||
--data-table-border-width: 0;
|
||||
}
|
||||
:host(:not([narrow])) ha-data-table {
|
||||
height: calc(100vh - 1px - var(--header-height));
|
||||
display: block;
|
||||
}
|
||||
ha-button-menu {
|
||||
margin-right: 8px;
|
||||
}
|
||||
.table-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12);
|
||||
}
|
||||
search-input {
|
||||
margin-left: 16px;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
.search-toolbar search-input {
|
||||
margin-left: 8px;
|
||||
top: 1px;
|
||||
}
|
||||
.search-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.search-toolbar ha-button-menu {
|
||||
position: static;
|
||||
}
|
||||
.selected-txt {
|
||||
font-weight: bold;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.table-header .selected-txt {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.search-toolbar .selected-txt {
|
||||
font-size: 16px;
|
||||
}
|
||||
.header-btns > mwc-button,
|
||||
.header-btns > ha-icon-button {
|
||||
margin: 8px;
|
||||
}
|
||||
.active-filters {
|
||||
color: var(--primary-text-color);
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2px 2px 2px 8px;
|
||||
margin-left: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.active-filters ha-icon {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.active-filters mwc-button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
.active-filters::before {
|
||||
background-color: var(--primary-color);
|
||||
opacity: 0.12;
|
||||
border-radius: 4px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
content: "";
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
|
|
@ -1755,11 +1755,15 @@
|
|||
"name": "Name",
|
||||
"update": "Update",
|
||||
"no_devices": "No devices",
|
||||
"enabled_label": "Enable device",
|
||||
"enabled_cause": "Disabled by {cause}.",
|
||||
"enabled_description": "Disabled devices will not be shown and entities belonging to the device will be disabled and not added to Home Assistant.",
|
||||
"automation": {
|
||||
"automations": "Automations",
|
||||
"no_automations": "No automations",
|
||||
"unknown_automation": "Unknown automation",
|
||||
"create": "Create automation with device",
|
||||
"create_disable": "Can't create automation with disabled device",
|
||||
"triggers": {
|
||||
"caption": "Do something when...",
|
||||
"no_triggers": "No triggers",
|
||||
|
@ -1780,12 +1784,14 @@
|
|||
"script": {
|
||||
"scripts": "Scripts",
|
||||
"no_scripts": "No scripts",
|
||||
"create": "Create script with device"
|
||||
"create": "Create script with device",
|
||||
"create_disable": "Can't create script with disabled device"
|
||||
},
|
||||
"scene": {
|
||||
"scenes": "Scenes",
|
||||
"no_scenes": "No scenes",
|
||||
"create": "Create scene with device"
|
||||
"create": "Create scene with device",
|
||||
"create_disable": "Can't create scene with disabled device"
|
||||
},
|
||||
"cant_edit": "You can only edit items that are created in the UI.",
|
||||
"device_not_found": "Device not found.",
|
||||
|
@ -1811,7 +1817,16 @@
|
|||
"no_area": "No area"
|
||||
},
|
||||
"delete": "Delete",
|
||||
"confirm_delete": "Are you sure you want to delete this device?"
|
||||
"confirm_delete": "Are you sure you want to delete this device?",
|
||||
"picker": {
|
||||
"search": "Search devices",
|
||||
"filter": {
|
||||
"filter": "Filter",
|
||||
"show_disabled": "Show disabled devices",
|
||||
"hidden_devices": "{number} hidden {number, plural,\n one {device}\n other {devices}\n}",
|
||||
"show_all": "Show all"
|
||||
}
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"caption": "Entities",
|
||||
|
|
Loading…
Reference in New Issue