mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-17 13:19:26 +00:00
Compare commits
14 Commits
add-no-dev
...
fix/Dropdo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
35d6c638ab | ||
![]() |
68f8239708 | ||
![]() |
0db64cca0b | ||
![]() |
accfda5f4b | ||
![]() |
c97c20f57d | ||
![]() |
2725d0191d | ||
![]() |
852cc62398 | ||
![]() |
654e3ce437 | ||
![]() |
20a3a00aec | ||
![]() |
22b927d666 | ||
![]() |
709d6be2e3 | ||
![]() |
fbda9ca418 | ||
![]() |
4e97e3763e | ||
![]() |
4c9c52d27d |
@@ -10,6 +10,7 @@ import {
|
||||
import { HomeAssistantAppEl } from "../../src/layouts/home-assistant";
|
||||
import { HomeAssistant } from "../../src/types";
|
||||
import { selectedDemoConfig } from "./configs/demo-configs";
|
||||
import { mockAreaRegistry } from "./stubs/area_registry";
|
||||
import { mockAuth } from "./stubs/auth";
|
||||
import { mockConfigEntries } from "./stubs/config_entries";
|
||||
import { mockEnergy } from "./stubs/energy";
|
||||
@@ -23,10 +24,10 @@ import { mockLovelace } from "./stubs/lovelace";
|
||||
import { mockMediaPlayer } from "./stubs/media_player";
|
||||
import { mockPersistentNotification } from "./stubs/persistent_notification";
|
||||
import { mockRecorder } from "./stubs/recorder";
|
||||
import { mockTodo } from "./stubs/todo";
|
||||
import { mockSensor } from "./stubs/sensor";
|
||||
import { mockSystemLog } from "./stubs/system_log";
|
||||
import { mockTemplate } from "./stubs/template";
|
||||
import { mockTodo } from "./stubs/todo";
|
||||
import { mockTranslations } from "./stubs/translations";
|
||||
|
||||
@customElement("ha-demo")
|
||||
@@ -62,6 +63,7 @@ export class HaDemo extends HomeAssistantAppEl {
|
||||
mockEnergy(hass);
|
||||
mockPersistentNotification(hass);
|
||||
mockConfigEntries(hass);
|
||||
mockAreaRegistry(hass);
|
||||
mockEntityRegistry(hass, [
|
||||
{
|
||||
config_entry_id: "co2signal",
|
||||
|
@@ -151,7 +151,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.24.4",
|
||||
"@babel/helper-define-polyfill-provider": "0.6.1",
|
||||
"@babel/helper-define-polyfill-provider": "0.6.2",
|
||||
"@babel/plugin-proposal-decorators": "7.24.1",
|
||||
"@babel/plugin-transform-runtime": "7.24.3",
|
||||
"@babel/preset-env": "7.24.4",
|
||||
@@ -175,7 +175,7 @@
|
||||
"@types/glob": "8.1.0",
|
||||
"@types/html-minifier-terser": "7.0.2",
|
||||
"@types/js-yaml": "4.0.9",
|
||||
"@types/leaflet": "1.9.11",
|
||||
"@types/leaflet": "1.9.12",
|
||||
"@types/leaflet-draw": "1.0.11",
|
||||
"@types/luxon": "3.4.2",
|
||||
"@types/mocha": "10.0.6",
|
||||
@@ -185,8 +185,8 @@
|
||||
"@types/tar": "6.1.13",
|
||||
"@types/ua-parser-js": "0.7.39",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@typescript-eslint/eslint-plugin": "7.7.0",
|
||||
"@typescript-eslint/parser": "7.7.0",
|
||||
"@typescript-eslint/eslint-plugin": "7.7.1",
|
||||
"@typescript-eslint/parser": "7.7.1",
|
||||
"@web/dev-server": "0.1.38",
|
||||
"@web/dev-server-rollup": "0.4.1",
|
||||
"babel-loader": "9.1.3",
|
||||
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20240424.0"
|
||||
version = "20240426.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { mdiArrowDown, mdiArrowUp, mdiChevronDown } from "@mdi/js";
|
||||
import { mdiArrowDown, mdiArrowUp, mdiChevronUp } from "@mdi/js";
|
||||
import deepClone from "deep-clone-simple";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
@@ -578,7 +578,7 @@ export class HaDataTable extends LitElement {
|
||||
@click=${this._collapseGroup}
|
||||
>
|
||||
<ha-icon-button
|
||||
.path=${mdiChevronDown}
|
||||
.path=${mdiChevronUp}
|
||||
class=${this._collapsedGroups.includes(groupName)
|
||||
? "collapsed"
|
||||
: ""}
|
||||
|
@@ -69,7 +69,7 @@ export class HaFilterDevices extends LitElement {
|
||||
@value-changed=${this._handleSearchChange}
|
||||
>
|
||||
</search-input-outlined>
|
||||
<mwc-list class="ha-scrollbar">
|
||||
<mwc-list class="ha-scrollbar" multi>
|
||||
<lit-virtualizer
|
||||
.items=${this._devices(
|
||||
this.hass.devices,
|
||||
|
198
src/components/ha-filter-domains.ts
Normal file
198
src/components/ha-filter-domains.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
import { mdiFilterVariantRemove } from "@mdi/js";
|
||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { stringCompare } from "../common/string/compare";
|
||||
import { domainToName } from "../data/integration";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-domain-icon";
|
||||
import "./search-input-outlined";
|
||||
import { computeDomain } from "../common/entity/compute_domain";
|
||||
|
||||
@customElement("ha-filter-domains")
|
||||
export class HaFilterDomains extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public value?: string[];
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@property({ type: Boolean, reflect: true }) public expanded = false;
|
||||
|
||||
@state() private _shouldRender = false;
|
||||
|
||||
@state() private _filter?: string;
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-expansion-panel
|
||||
leftChevron
|
||||
.expanded=${this.expanded}
|
||||
@expanded-will-change=${this._expandedWillChange}
|
||||
@expanded-changed=${this._expandedChanged}
|
||||
>
|
||||
<div slot="header" class="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.headers.domain"
|
||||
)}
|
||||
${this.value?.length
|
||||
? html`<div class="badge">${this.value?.length}</div>
|
||||
<ha-icon-button
|
||||
.path=${mdiFilterVariantRemove}
|
||||
@click=${this._clearFilter}
|
||||
></ha-icon-button>`
|
||||
: nothing}
|
||||
</div>
|
||||
${this._shouldRender
|
||||
? html`<search-input-outlined
|
||||
.hass=${this.hass}
|
||||
.filter=${this._filter}
|
||||
@value-changed=${this._handleSearchChange}
|
||||
>
|
||||
</search-input-outlined>
|
||||
<mwc-list
|
||||
class="ha-scrollbar"
|
||||
@click=${this._handleItemClick}
|
||||
multi
|
||||
>
|
||||
${repeat(
|
||||
this._domains(this.hass.states, this._filter),
|
||||
(i) => i,
|
||||
(domain) =>
|
||||
html`<ha-check-list-item
|
||||
.value=${domain}
|
||||
.selected=${(this.value || []).includes(domain)}
|
||||
graphic="icon"
|
||||
>
|
||||
<ha-domain-icon
|
||||
slot="graphic"
|
||||
.hass=${this.hass}
|
||||
.domain=${domain}
|
||||
brandFallback
|
||||
></ha-domain-icon>
|
||||
${domainToName(this.hass.localize, domain)}
|
||||
</ha-check-list-item>`
|
||||
)}
|
||||
</mwc-list> `
|
||||
: nothing}
|
||||
</ha-expansion-panel>
|
||||
`;
|
||||
}
|
||||
|
||||
private _domains = memoizeOne((states, filter) => {
|
||||
const domains = new Set<string>();
|
||||
Object.keys(states).forEach((entityId) => {
|
||||
domains.add(computeDomain(entityId));
|
||||
});
|
||||
return Array.from(domains)
|
||||
.filter((domain) => !filter || domain.toLowerCase().includes(filter))
|
||||
.sort((a, b) => stringCompare(a, b, this.hass.locale.language));
|
||||
});
|
||||
|
||||
protected updated(changed) {
|
||||
if (changed.has("expanded") && this.expanded) {
|
||||
setTimeout(() => {
|
||||
if (!this.expanded) return;
|
||||
this.renderRoot.querySelector("mwc-list")!.style.height =
|
||||
`${this.clientHeight - 49 - 32}px`; // 32px is the height of the search input
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
private _expandedWillChange(ev) {
|
||||
this._shouldRender = ev.detail.expanded;
|
||||
}
|
||||
|
||||
private _expandedChanged(ev) {
|
||||
this.expanded = ev.detail.expanded;
|
||||
}
|
||||
|
||||
private _handleItemClick(ev) {
|
||||
const listItem = ev.target.closest("ha-check-list-item");
|
||||
const value = listItem?.value;
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (this.value?.includes(value)) {
|
||||
this.value = this.value?.filter((val) => val !== value);
|
||||
} else {
|
||||
this.value = [...(this.value || []), value];
|
||||
}
|
||||
|
||||
listItem.selected = this.value.includes(value);
|
||||
|
||||
fireEvent(this, "data-table-filter-changed", {
|
||||
value: this.value,
|
||||
items: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
private _clearFilter(ev) {
|
||||
ev.preventDefault();
|
||||
this.value = undefined;
|
||||
fireEvent(this, "data-table-filter-changed", {
|
||||
value: undefined,
|
||||
items: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
private _handleSearchChange(ev: CustomEvent) {
|
||||
this._filter = ev.detail.value.toLowerCase();
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyleScrollbar,
|
||||
css`
|
||||
:host {
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
:host([expanded]) {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
}
|
||||
ha-expansion-panel {
|
||||
--ha-card-border-radius: 0;
|
||||
--expansion-panel-content-padding: 0;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.header ha-icon-button {
|
||||
margin-inline-start: auto;
|
||||
margin-inline-end: 8px;
|
||||
}
|
||||
.badge {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
margin-inline-start: 8px;
|
||||
margin-inline-end: 0;
|
||||
min-width: 16px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 50%;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
background-color: var(--primary-color);
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
padding: 0px 2px;
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
search-input-outlined {
|
||||
display: block;
|
||||
padding: 0 8px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-filter-domains": HaFilterDomains;
|
||||
}
|
||||
}
|
@@ -71,7 +71,7 @@ export class HaFilterEntities extends LitElement {
|
||||
@value-changed=${this._handleSearchChange}
|
||||
>
|
||||
</search-input-outlined>
|
||||
<mwc-list class="ha-scrollbar">
|
||||
<mwc-list class="ha-scrollbar" multi>
|
||||
<lit-virtualizer
|
||||
.items=${this._entities(
|
||||
this.hass.states,
|
||||
|
@@ -55,7 +55,11 @@ export class HaFilterIntegrations extends LitElement {
|
||||
@value-changed=${this._handleSearchChange}
|
||||
>
|
||||
</search-input-outlined>
|
||||
<mwc-list class="ha-scrollbar" @click=${this._handleItemClick}>
|
||||
<mwc-list
|
||||
class="ha-scrollbar"
|
||||
@click=${this._handleItemClick}
|
||||
multi
|
||||
>
|
||||
${repeat(
|
||||
this._integrations(this._manifests, this._filter, this.value),
|
||||
(i) => i.domain,
|
||||
|
@@ -71,6 +71,10 @@ export const computeInitialHaFormData = (
|
||||
if (selector.country?.countries?.length) {
|
||||
data[field.name] = selector.country.countries[0];
|
||||
}
|
||||
} else if ("language" in selector) {
|
||||
if (selector.language?.languages?.length) {
|
||||
data[field.name] = selector.language.languages[0];
|
||||
}
|
||||
} else if ("duration" in selector) {
|
||||
data[field.name] = {
|
||||
hours: 0,
|
||||
@@ -93,7 +97,9 @@ export const computeInitialHaFormData = (
|
||||
) {
|
||||
data[field.name] = {};
|
||||
} else {
|
||||
throw new Error("Selector not supported in initial form data");
|
||||
throw new Error(
|
||||
`Selector ${Object.keys(selector)[0]} not supported in initial form data`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -1,13 +1,29 @@
|
||||
import { FormfieldBase } from "@material/mwc-formfield/mwc-formfield-base";
|
||||
import { styles } from "@material/mwc-formfield/mwc-formfield.css";
|
||||
import { css } from "lit";
|
||||
import { css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
|
||||
@customElement("ha-formfield")
|
||||
export class HaFormfield extends FormfieldBase {
|
||||
@property({ type: Boolean, reflect: true }) public disabled = false;
|
||||
|
||||
protected override render() {
|
||||
const classes = {
|
||||
"mdc-form-field--align-end": this.alignEnd,
|
||||
"mdc-form-field--space-between": this.spaceBetween,
|
||||
"mdc-form-field--nowrap": this.nowrap,
|
||||
};
|
||||
|
||||
return html` <div class="mdc-form-field ${classMap(classes)}">
|
||||
<slot></slot>
|
||||
<label class="mdc-label" @click=${this._labelClick}
|
||||
><slot name="label">${this.label}</slot></label
|
||||
>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
protected _labelClick() {
|
||||
const input = this.input as HTMLInputElement | undefined;
|
||||
if (!input) return;
|
||||
@@ -39,6 +55,9 @@ export class HaFormfield extends FormfieldBase {
|
||||
margin-inline-end: 10px;
|
||||
margin-inline-start: inline;
|
||||
}
|
||||
.mdc-form-field {
|
||||
align-items: var(--ha-formfield-align-items, center);
|
||||
}
|
||||
.mdc-form-field > label {
|
||||
direction: var(--direction);
|
||||
margin-inline-start: 0;
|
||||
|
@@ -19,7 +19,7 @@ import { customElement, property, query, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import type { LeafletModuleType } from "../../common/dom/setup-leaflet-map";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import type { HomeAssistant, ThemeMode } from "../../types";
|
||||
import "../ha-input-helper-text";
|
||||
import "./ha-map";
|
||||
import type { HaMap } from "./ha-map";
|
||||
@@ -61,7 +61,8 @@ export class HaLocationsEditor extends LitElement {
|
||||
|
||||
@property({ type: Number }) public zoom = 16;
|
||||
|
||||
@property({ type: Boolean }) public darkMode = false;
|
||||
@property({ attribute: "theme-mode", type: String })
|
||||
public themeMode: ThemeMode = "auto";
|
||||
|
||||
@state() private _locationMarkers?: Record<string, Marker | Circle>;
|
||||
|
||||
@@ -133,7 +134,7 @@ export class HaLocationsEditor extends LitElement {
|
||||
.layers=${this._getLayers(this._circles, this._locationMarkers)}
|
||||
.zoom=${this.zoom}
|
||||
.autoFit=${this.autoFit}
|
||||
?forceDarkMode=${this.darkMode}
|
||||
.themeMode=${this.themeMode}
|
||||
></ha-map>
|
||||
${this.helper
|
||||
? html`<ha-input-helper-text>${this.helper}</ha-input-helper-text>`
|
||||
|
@@ -1,32 +1,32 @@
|
||||
import { isToday } from "date-fns";
|
||||
import type {
|
||||
Circle,
|
||||
CircleMarker,
|
||||
LatLngTuple,
|
||||
LatLngExpression,
|
||||
LatLngTuple,
|
||||
Layer,
|
||||
Map,
|
||||
Marker,
|
||||
Polyline,
|
||||
} from "leaflet";
|
||||
import { isToday } from "date-fns";
|
||||
import { css, CSSResultGroup, PropertyValues, ReactiveElement } from "lit";
|
||||
import { CSSResultGroup, PropertyValues, ReactiveElement, css } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { formatDateTime } from "../../common/datetime/format_date_time";
|
||||
import {
|
||||
formatTimeWeekday,
|
||||
formatTimeWithSeconds,
|
||||
} from "../../common/datetime/format_time";
|
||||
import {
|
||||
LeafletModuleType,
|
||||
setupLeafletMap,
|
||||
} from "../../common/dom/setup-leaflet-map";
|
||||
import {
|
||||
formatTimeWithSeconds,
|
||||
formatTimeWeekday,
|
||||
} from "../../common/datetime/format_time";
|
||||
import { formatDateTime } from "../../common/datetime/format_date_time";
|
||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { loadPolyfillIfNeeded } from "../../resources/resize-observer.polyfill";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { HomeAssistant, ThemeMode } from "../../types";
|
||||
import { isTouch } from "../../util/is_touch";
|
||||
import "../ha-icon-button";
|
||||
import "./ha-entity-marker";
|
||||
import { isTouch } from "../../util/is_touch";
|
||||
|
||||
const getEntityId = (entity: string | HaMapEntity): string =>
|
||||
typeof entity === "string" ? entity : entity.entity_id;
|
||||
@@ -69,9 +69,8 @@ export class HaMap extends ReactiveElement {
|
||||
|
||||
@property({ type: Boolean }) public fitZones = false;
|
||||
|
||||
@property({ type: Boolean }) public forceDarkMode = false;
|
||||
|
||||
@property({ type: Boolean }) public forceLightMode = false;
|
||||
@property({ attribute: "theme-mode", type: String })
|
||||
public themeMode: ThemeMode = "auto";
|
||||
|
||||
@property({ type: Number }) public zoom = 14;
|
||||
|
||||
@@ -156,8 +155,7 @@ export class HaMap extends ReactiveElement {
|
||||
}
|
||||
|
||||
if (
|
||||
!changedProps.has("forceDarkMode") &&
|
||||
!changedProps.has("forceLightMode") &&
|
||||
!changedProps.has("themeMode") &&
|
||||
(!changedProps.has("hass") ||
|
||||
(oldHass && oldHass.themes?.darkMode === this.hass.themes?.darkMode))
|
||||
) {
|
||||
@@ -166,14 +164,18 @@ export class HaMap extends ReactiveElement {
|
||||
this._updateMapStyle();
|
||||
}
|
||||
|
||||
private get _darkMode() {
|
||||
return (
|
||||
this.themeMode === "dark" ||
|
||||
(this.themeMode === "auto" && Boolean(this.hass.themes.darkMode))
|
||||
);
|
||||
}
|
||||
|
||||
private _updateMapStyle(): void {
|
||||
const darkMode =
|
||||
!this.forceLightMode &&
|
||||
(this.forceDarkMode || (this.hass.themes.darkMode ?? false));
|
||||
const map = this.renderRoot.querySelector("#map");
|
||||
map!.classList.toggle("dark", darkMode);
|
||||
map!.classList.toggle("forced-dark", this.forceDarkMode);
|
||||
map!.classList.toggle("forced-light", this.forceLightMode);
|
||||
map!.classList.toggle("dark", this._darkMode);
|
||||
map!.classList.toggle("forced-dark", this.themeMode === "dark");
|
||||
map!.classList.toggle("forced-light", this.themeMode === "light");
|
||||
}
|
||||
|
||||
private async _loadMap(): Promise<void> {
|
||||
@@ -403,13 +405,7 @@ export class HaMap extends ReactiveElement {
|
||||
"--dark-primary-color"
|
||||
);
|
||||
|
||||
const className = this.forceLightMode
|
||||
? "light"
|
||||
: this.forceDarkMode
|
||||
? "dark"
|
||||
: this.hass.themes.darkMode
|
||||
? "dark"
|
||||
: "light";
|
||||
const className = this._darkMode ? "dark" : "light";
|
||||
|
||||
for (const entity of this.entities) {
|
||||
const stateObj = hass.states[getEntityId(entity)];
|
||||
|
@@ -16,21 +16,23 @@ class MoreInfoCounter extends LitElement {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const disabled = isUnavailableState(this.stateObj!.state);
|
||||
const disabled = isUnavailableState(this.stateObj.state);
|
||||
|
||||
return html`
|
||||
<div class="actions">
|
||||
<mwc-button
|
||||
.action=${"increment"}
|
||||
@click=${this._handleActionClick}
|
||||
.disabled=${disabled}
|
||||
.disabled=${disabled ||
|
||||
Number(this.stateObj.state) === this.stateObj.attributes.maximum}
|
||||
>
|
||||
${this.hass!.localize("ui.card.counter.actions.increment")}
|
||||
</mwc-button>
|
||||
<mwc-button
|
||||
.action=${"decrement"}
|
||||
@click=${this._handleActionClick}
|
||||
.disabled=${disabled}
|
||||
.disabled=${disabled ||
|
||||
Number(this.stateObj.state) === this.stateObj.attributes.minimum}
|
||||
>
|
||||
${this.hass!.localize("ui.card.counter.actions.decrement")}
|
||||
</mwc-button>
|
||||
|
@@ -41,7 +41,7 @@ import type { HomeAssistant } from "../types";
|
||||
import { onBoardingStyles } from "./styles";
|
||||
|
||||
const AMSTERDAM: [number, number] = [52.3731339, 4.8903147];
|
||||
const mql = matchMedia("(prefers-color-scheme: dark)");
|
||||
const darkMql = matchMedia("(prefers-color-scheme: dark)");
|
||||
const LOCATION_MARKER_ID = "location";
|
||||
|
||||
@customElement("onboarding-location")
|
||||
@@ -199,7 +199,7 @@ class OnboardingLocation extends LitElement {
|
||||
this._highlightedMarker
|
||||
)}
|
||||
zoom="14"
|
||||
.darkMode=${mql.matches}
|
||||
.themeMode=${darkMql.matches ? "dark" : "light"}
|
||||
.disabled=${this._working}
|
||||
@location-updated=${this._locationChanged}
|
||||
@marker-clicked=${this._markerClicked}
|
||||
|
@@ -97,7 +97,7 @@ export class HaManualAutomationEditor extends LitElement {
|
||||
<ha-automation-trigger
|
||||
role="region"
|
||||
aria-labelledby="triggers-heading"
|
||||
.triggers=${this.config.trigger}
|
||||
.triggers=${this.config.trigger || []}
|
||||
.path=${["trigger"]}
|
||||
@value-changed=${this._triggerChanged}
|
||||
@item-moved=${this._itemMoved}
|
||||
|
@@ -1,16 +1,19 @@
|
||||
import { mdiContentCopy, mdiHelpCircle } from "@mdi/js";
|
||||
import { mdiContentCopy, mdiEye, mdiEyeOff, mdiHelpCircle } from "@mdi/js";
|
||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { copyToClipboard } from "../../../../common/util/copy-clipboard";
|
||||
import "../../../../components/ha-alert";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-expansion-panel";
|
||||
import "../../../../components/ha-formfield";
|
||||
import "../../../../components/ha-radio";
|
||||
import "../../../../components/ha-settings-row";
|
||||
import "../../../../components/ha-switch";
|
||||
// eslint-disable-next-line
|
||||
import { formatDate } from "../../../../common/datetime/format_date";
|
||||
import type { HaRadio } from "../../../../components/ha-radio";
|
||||
import type { HaSwitch } from "../../../../components/ha-switch";
|
||||
import {
|
||||
CloudStatusLoggedIn,
|
||||
@@ -20,8 +23,8 @@ import {
|
||||
} from "../../../../data/cloud";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { showToast } from "../../../../util/toast";
|
||||
import { showCloudCertificateDialog } from "../dialog-cloud-certificate/show-dialog-cloud-certificate";
|
||||
import { showAlertDialog } from "../../../lovelace/custom-card-helpers";
|
||||
import { showCloudCertificateDialog } from "../dialog-cloud-certificate/show-dialog-cloud-certificate";
|
||||
|
||||
@customElement("cloud-remote-pref")
|
||||
export class CloudRemotePref extends LitElement {
|
||||
@@ -29,6 +32,8 @@ export class CloudRemotePref extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public cloudStatus?: CloudStatusLoggedIn;
|
||||
|
||||
@state() private _unmaskedUrl = false;
|
||||
|
||||
protected render() {
|
||||
if (!this.cloudStatus) {
|
||||
return nothing;
|
||||
@@ -109,35 +114,180 @@ export class CloudRemotePref extends LitElement {
|
||||
)}
|
||||
></ha-alert>
|
||||
`
|
||||
: ""}
|
||||
${this.hass.localize("ui.panel.config.cloud.account.remote.info")}
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.cloud.account.remote.${
|
||||
remote_connected
|
||||
? "instance_is_available"
|
||||
: "instance_will_be_available"
|
||||
}`
|
||||
)}
|
||||
<a
|
||||
href="https://${remote_domain}"
|
||||
target="_blank"
|
||||
class="break-word"
|
||||
rel="noreferrer"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.nabu_casa_url"
|
||||
)}</a
|
||||
>.
|
||||
<ha-svg-icon
|
||||
.url=${`https://${remote_domain}`}
|
||||
@click=${this._copyURL}
|
||||
.path=${mdiContentCopy}
|
||||
></ha-svg-icon>
|
||||
: strict_connection === "drop_connection"
|
||||
? html`<ha-alert
|
||||
alert-type="warning"
|
||||
.title=${this.hass.localize(
|
||||
`ui.panel.config.cloud.account.remote.drop_connection_warning_title`
|
||||
)}
|
||||
>${this.hass.localize(
|
||||
`ui.panel.config.cloud.account.remote.drop_connection_warning`
|
||||
)}</ha-alert
|
||||
>`
|
||||
: nothing}
|
||||
<p>
|
||||
${this.hass.localize("ui.panel.config.cloud.account.remote.info")}
|
||||
</p>
|
||||
${remote_connected
|
||||
? nothing
|
||||
: html`
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.info_instance_will_be_available"
|
||||
)}
|
||||
</p>
|
||||
`}
|
||||
<div class="url-container">
|
||||
<div class="textfield-container">
|
||||
<ha-textfield
|
||||
.value=${this._unmaskedUrl
|
||||
? `https://${remote_domain}`
|
||||
: "https://•••••••••••••••••.ui.nabu.casa"}
|
||||
readonly
|
||||
.suffix=${
|
||||
// reserve some space for the icon.
|
||||
html`<div style="width: 24px"></div>`
|
||||
}
|
||||
></ha-textfield>
|
||||
<ha-icon-button
|
||||
class="toggle-unmasked-url"
|
||||
toggles
|
||||
.label=${this.hass.localize(
|
||||
`ui.panel.config.cloud.account.remote.${this._unmaskedUrl ? "hide" : "show"}_url`
|
||||
)}
|
||||
@click=${this._toggleUnmaskedUrl}
|
||||
.path=${this._unmaskedUrl ? mdiEyeOff : mdiEye}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
<ha-button
|
||||
.url=${`https://${remote_domain}`}
|
||||
@click=${this._copyURL}
|
||||
unelevated
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentCopy}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.copy_link"
|
||||
)}
|
||||
</ha-button>
|
||||
</div>
|
||||
|
||||
<ha-expansion-panel
|
||||
outlined
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.advanced_options"
|
||||
"ui.panel.config.cloud.account.remote.security_options"
|
||||
)}
|
||||
>
|
||||
<ha-settings-row>
|
||||
<span slot="heading">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection"
|
||||
)}
|
||||
</span>
|
||||
<span slot="description">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_secondary"
|
||||
)}
|
||||
</span>
|
||||
</ha-settings-row>
|
||||
|
||||
<div class="strict-connection-container">
|
||||
<ha-formfield>
|
||||
<ha-radio
|
||||
name="strict-connection-mode"
|
||||
value="disabled"
|
||||
.checked=${strict_connection === "disabled"}
|
||||
@change=${this._strictConnectionModeChanged}
|
||||
></ha-radio>
|
||||
<div slot="label">
|
||||
<div class="primary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_disabled"
|
||||
)}
|
||||
</div>
|
||||
<div class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_disabled_secondary"
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</ha-formfield>
|
||||
|
||||
<ha-formfield>
|
||||
<ha-radio
|
||||
name="strict-connection-mode"
|
||||
value="guard_page"
|
||||
.checked=${strict_connection === "guard_page"}
|
||||
@change=${this._strictConnectionModeChanged}
|
||||
></ha-radio>
|
||||
<div slot="label">
|
||||
<div class="primary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_guard_page"
|
||||
)}
|
||||
</div>
|
||||
<div class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_guard_page_secondary"
|
||||
)}
|
||||
<br /><br />
|
||||
⚠️
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_guard_page_warning"
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</ha-formfield>
|
||||
|
||||
<ha-formfield>
|
||||
<ha-radio
|
||||
name="strict-connection-mode"
|
||||
value="drop_connection"
|
||||
.checked=${strict_connection === "drop_connection"}
|
||||
@change=${this._strictConnectionModeChanged}
|
||||
></ha-radio>
|
||||
<div slot="label">
|
||||
<div class="primary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_drop_connection"
|
||||
)}
|
||||
</div>
|
||||
<div class="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_drop_connection_secondary"
|
||||
)}
|
||||
<br /><br />
|
||||
⚠️
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_option_drop_connection_warning"
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</ha-formfield>
|
||||
</div>
|
||||
|
||||
${strict_connection !== "disabled"
|
||||
? html`
|
||||
<ha-settings-row>
|
||||
<span slot="heading"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_link"
|
||||
)}</span
|
||||
>
|
||||
<span slot="description"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_link_secondary"
|
||||
)}</span
|
||||
>
|
||||
<ha-button @click=${this._createLoginUrl}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_create_link"
|
||||
)}</ha-button
|
||||
>
|
||||
</ha-settings-row>
|
||||
`
|
||||
: nothing}
|
||||
|
||||
<hr />
|
||||
<ha-settings-row>
|
||||
<span slot="heading"
|
||||
>${this.hass.localize(
|
||||
@@ -154,61 +304,7 @@ export class CloudRemotePref extends LitElement {
|
||||
@change=${this._toggleAllowRemoteEnabledChanged}
|
||||
></ha-switch>
|
||||
</ha-settings-row>
|
||||
<ha-settings-row>
|
||||
<span slot="heading"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection"
|
||||
)}</span
|
||||
>
|
||||
<span slot="description"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_secondary"
|
||||
)}</span
|
||||
>
|
||||
<ha-select
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_mode"
|
||||
)}
|
||||
@selected=${this._setStrictConnectionMode}
|
||||
naturalMenuWidth
|
||||
.value=${strict_connection}
|
||||
>
|
||||
<ha-list-item value="disabled">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_modes.disabled"
|
||||
)}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="guard_page">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_modes.guard_page"
|
||||
)}
|
||||
</ha-list-item>
|
||||
<ha-list-item value="drop_connection">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_modes.drop_connection"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-select>
|
||||
</ha-settings-row>
|
||||
${strict_connection !== "disabled"
|
||||
? html` <ha-settings-row>
|
||||
<span slot="heading"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_link"
|
||||
)}</span
|
||||
>
|
||||
<span slot="description"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_link_secondary"
|
||||
)}</span
|
||||
>
|
||||
<ha-button @click=${this._createLoginUrl}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_create_link"
|
||||
)}</ha-button
|
||||
>
|
||||
</ha-settings-row>`
|
||||
: nothing}
|
||||
<hr />
|
||||
<ha-settings-row>
|
||||
<span slot="heading"
|
||||
>${this.hass.localize(
|
||||
@@ -249,6 +345,10 @@ export class CloudRemotePref extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _toggleUnmaskedUrl(): void {
|
||||
this._unmaskedUrl = !this._unmaskedUrl;
|
||||
}
|
||||
|
||||
private async _toggleChanged(ev) {
|
||||
const toggle = ev.target as HaSwitch;
|
||||
|
||||
@@ -279,15 +379,21 @@ export class CloudRemotePref extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private async _setStrictConnectionMode(ev) {
|
||||
const mode = ev.target.value;
|
||||
private async _strictConnectionModeChanged(ev) {
|
||||
const toggle = ev.target as HaRadio;
|
||||
|
||||
if (ev.target.value === this.cloudStatus?.prefs.strict_connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await updateCloudPref(this.hass, {
|
||||
strict_connection: mode,
|
||||
strict_connection: ev.target.value,
|
||||
});
|
||||
fireEvent(this, "ha-refresh-cloud-status");
|
||||
} catch (err: any) {
|
||||
alert(err.message);
|
||||
toggle.checked = !toggle.checked;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,17 +422,22 @@ export class CloudRemotePref extends LitElement {
|
||||
text: html`${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_link_created_message"
|
||||
)}
|
||||
<pre>${result.response.url}</pre>
|
||||
<ha-button
|
||||
.url=${result.response.url}
|
||||
@click=${this._copyURL}
|
||||
unelevated
|
||||
<div
|
||||
style="display: flex; align-items: center; gap: 8px; margin-top: 8px;"
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentCopy}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.strict_connection_copy_link"
|
||||
)}
|
||||
</ha-button>`,
|
||||
<ha-textfield .value=${result.response.url} readonly></ha-textfield>
|
||||
<ha-button
|
||||
style="flex-basis: 180px;"
|
||||
.url=${result.response.url}
|
||||
@click=${this._copyURL}
|
||||
unelevated
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentCopy}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.cloud.account.remote.copy_link"
|
||||
)}
|
||||
</ha-button>
|
||||
</div>`,
|
||||
});
|
||||
} catch (err: any) {
|
||||
showAlertDialog(this, { text: err.message });
|
||||
@@ -343,8 +454,8 @@ export class CloudRemotePref extends LitElement {
|
||||
}
|
||||
.header-actions {
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
inset-inline-end: 24px;
|
||||
right: 16px;
|
||||
inset-inline-end: 16px;
|
||||
inset-inline-start: initial;
|
||||
top: 24px;
|
||||
display: flex;
|
||||
@@ -378,17 +489,71 @@ export class CloudRemotePref extends LitElement {
|
||||
.card-actions a {
|
||||
text-decoration: none;
|
||||
}
|
||||
ha-svg-icon {
|
||||
--mdc-icon-size: 18px;
|
||||
color: var(--secondary-text-color);
|
||||
cursor: pointer;
|
||||
ha-expansion-panel {
|
||||
margin-top: 16px;
|
||||
}
|
||||
ha-formfield {
|
||||
margin-top: 8px;
|
||||
ha-settings-row {
|
||||
padding: 0;
|
||||
}
|
||||
ha-expansion-panel {
|
||||
--expansion-panel-content-padding: 0 16px;
|
||||
--expansion-panel-summary-padding: 0 16px;
|
||||
}
|
||||
ha-alert {
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.url-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.textfield-container {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
}
|
||||
.textfield-container ha-textfield {
|
||||
display: block;
|
||||
}
|
||||
.toggle-unmasked-url {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
inset-inline-start: initial;
|
||||
inset-inline-end: 8px;
|
||||
--mdc-icon-button-size: 40px;
|
||||
--mdc-icon-size: 20px;
|
||||
color: var(--secondary-text-color);
|
||||
direction: var(--direction);
|
||||
}
|
||||
ha-formfield {
|
||||
margin-left: -12px;
|
||||
margin-inline-start: -12px;
|
||||
--ha-formfield-align-items: start;
|
||||
}
|
||||
.strict-connection-container {
|
||||
gap: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.strict-connection-container ha-formfield {
|
||||
--ha-formfield-align-items: start;
|
||||
}
|
||||
.strict-connection-container .primary {
|
||||
font-size: 14px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.strict-connection-container .secondary {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 12px;
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
background-color: var(--divider-color);
|
||||
margin: 8px 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@@ -53,6 +53,7 @@ import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-check-list-item";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-domains";
|
||||
import "../../../components/ha-filter-floor-areas";
|
||||
import "../../../components/ha-filter-integrations";
|
||||
import "../../../components/ha-filter-labels";
|
||||
@@ -443,6 +444,10 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
entryIds.includes(entity.config_entry_id))
|
||||
);
|
||||
filter.value!.forEach((domain) => filteredDomains.add(domain));
|
||||
} else if (key === "ha-filter-domains" && filter.value?.length) {
|
||||
filteredEntities = filteredEntities.filter((entity) =>
|
||||
filter.value?.includes(computeDomain(entity.entity_id))
|
||||
);
|
||||
} else if (key === "ha-filter-labels" && filter.value?.length) {
|
||||
filteredEntities = filteredEntities.filter((entity) =>
|
||||
entity.labels.some((lbl) => filter.value!.includes(lbl))
|
||||
@@ -782,6 +787,15 @@ ${
|
||||
.narrow=${this.narrow}
|
||||
@expanded-changed=${this._filterExpanded}
|
||||
></ha-filter-devices>
|
||||
<ha-filter-domains
|
||||
.hass=${this.hass}
|
||||
.value=${this._filters["ha-filter-domains"]?.value}
|
||||
@data-table-filter-changed=${this._filterChanged}
|
||||
slot="filter-pane"
|
||||
.expanded=${this._expandedFilter === "ha-filter-domains"}
|
||||
.narrow=${this.narrow}
|
||||
@expanded-changed=${this._filterExpanded}
|
||||
></ha-filter-domains>
|
||||
<ha-filter-integrations
|
||||
.hass=${this.hass}
|
||||
.value=${this._filters["ha-filter-integrations"]?.value}
|
||||
|
@@ -47,6 +47,7 @@ class DialogZHAReconfigureDevice extends LitElement {
|
||||
|
||||
public showDialog(params: ZHAReconfigureDeviceDialogParams): void {
|
||||
this._params = params;
|
||||
this._clusterConfigurationStatuses = new Map();
|
||||
this._stages = undefined;
|
||||
}
|
||||
|
||||
|
@@ -424,7 +424,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
|
||||
? {
|
||||
physics: {
|
||||
barnesHut: {
|
||||
springConstant: 0.05,
|
||||
springConstant: 0,
|
||||
avoidOverlap: 10,
|
||||
damping: 0.09,
|
||||
},
|
||||
|
@@ -122,7 +122,7 @@ export class HaManualScriptEditor extends LitElement {
|
||||
<ha-automation-action
|
||||
role="region"
|
||||
aria-labelledby="sequence-heading"
|
||||
.actions=${this.config.sequence}
|
||||
.actions=${this.config.sequence || []}
|
||||
.path=${["sequence"]}
|
||||
@value-changed=${this._sequenceChanged}
|
||||
@item-moved=${this._itemMoved}
|
||||
|
@@ -159,6 +159,9 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
? false
|
||||
: this.hass.themes.darkMode;
|
||||
|
||||
const themeMode =
|
||||
this._config.theme_mode || (this._config.dark_mode ? "dark" : "auto");
|
||||
|
||||
return html`
|
||||
<ha-card id="card" .header=${this._config.title}>
|
||||
<div id="root">
|
||||
@@ -169,9 +172,7 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
.paths=${this._getHistoryPaths(this._config, this._stateHistory)}
|
||||
.autoFit=${this._config.auto_fit || false}
|
||||
.fitZones=${this._config.fit_zones}
|
||||
?forceDarkMode=${this._config.theme_mode === "dark" ||
|
||||
this._config.dark_mode}
|
||||
?forceLightMode=${this._config.theme_mode === "light"}
|
||||
.themeMode=${themeMode}
|
||||
interactiveZones
|
||||
renderPassive
|
||||
></ha-map>
|
||||
|
@@ -3821,38 +3821,42 @@
|
||||
}
|
||||
},
|
||||
"remote": {
|
||||
"title": "Remote control",
|
||||
"title": "Remote access",
|
||||
"connected": "Connected",
|
||||
"not_connected": "Not connected",
|
||||
"reconnecting": "Not connected. Trying to reconnect.",
|
||||
"access_is_being_prepared": "Remote control is being prepared. We will notify you when it's ready.",
|
||||
"access_is_being_prepared": "Remote access is being prepared. We will notify you when it's ready.",
|
||||
"cerificate_loading": "Your certificate is loading.",
|
||||
"cerificate_loaded": "Your certificate is loaded, waiting for validation.",
|
||||
"cerificate_error": "There was an error generating the certificate, check your logs.",
|
||||
"info": "Home Assistant Cloud provides a secure remote connection to your instance while away from home.",
|
||||
"instance_is_available": "Your instance is available at your",
|
||||
"instance_will_be_available": "Your instance will be available at your",
|
||||
"info": "Home Assistant Cloud provides a secure remote access to your instance while away from home. For more information on remote access and these settings visit our security documentation.",
|
||||
"info_instance_will_be_available": "Your instance will be available at your Nabu Casa URL.",
|
||||
"link_learn_how_it_works": "Learn how it works",
|
||||
"nabu_casa_url": "Nabu Casa URL",
|
||||
"advanced_options": "Advanced options",
|
||||
"external_activation": "Allow external activation of remote control",
|
||||
"external_activation_secondary": "Allows you to turn on remote control from your Nabu Casa account page, even if you're outside your local network",
|
||||
"strict_connection": "Restrict access to logged in users",
|
||||
"strict_connection_secondary": "When a user is not logged in to your Home Assistant instance, they will not be able to access your instance remotely",
|
||||
"strict_connection_mode": "Mode",
|
||||
"strict_connection_modes": {
|
||||
"disabled": "Disabled",
|
||||
"guard_page": "Guard page",
|
||||
"drop_connection": "Drop connection"
|
||||
},
|
||||
"strict_connection_link": "Create login link",
|
||||
"strict_connection_link_secondary": "You can create a link that will give temporary access to the login page.",
|
||||
"show_url": "Show full URL",
|
||||
"hide_url": "Hide URL",
|
||||
"copy_link": "Copy link",
|
||||
"security_options": "Security options",
|
||||
"strict_connection": "Remote login access",
|
||||
"strict_connection_secondary": "Choose what happens when new devices visit your remote access link.",
|
||||
"strict_connection_option_disabled": "Show login page",
|
||||
"strict_connection_option_disabled_secondary": "Any new device visiting your remote access link are presented with a login page.",
|
||||
"strict_connection_option_guard_page": "Block remote logins",
|
||||
"strict_connection_option_guard_page_secondary": "New devices must log in with a temporary access link. Devices accessing the link that are not logged in will be presented with a page explaining the restrictions.",
|
||||
"strict_connection_option_guard_page_warning": "This prevents outsiders from trying to log in to your system but also your own devices if they have not logged in previously.",
|
||||
"strict_connection_option_drop_connection": "Block remote logins and show nothing",
|
||||
"strict_connection_option_drop_connection_secondary": "This is the same as the above setting but instead provides a blank page for additional security.",
|
||||
"strict_connection_option_drop_connection_warning": "This prevents outsiders from snooping the remote web address and trying to log in, but it may appear as if there is no system running when users try to access it.",
|
||||
"external_activation": "Allow external activation of remote access",
|
||||
"external_activation_secondary": "If you disable remote access on this page, having this setting enabled allows you to reactivate it remotely via your Nabu Casa account.",
|
||||
"drop_connection_warning_title": "Remote log in has been deactivated",
|
||||
"drop_connection_warning": "The below security options may make it appear the system is not running.",
|
||||
"strict_connection_link": "Provide temporary login access",
|
||||
"strict_connection_link_secondary": "This provides a link for new devices to login for the next hour.",
|
||||
"strict_connection_create_link": "Create link",
|
||||
"strict_connection_link_created_message": "Give this link to the person you want to give remote access to the login page of your Home Assistant instance.",
|
||||
"strict_connection_copy_link": "Copy link",
|
||||
"certificate_info": "Certificate info",
|
||||
"certificate_expire": "Will be renewed at {date}",
|
||||
"more_info": "More info"
|
||||
"certificate_info": "Certificate information",
|
||||
"certificate_expire": "Certificate renewal at {date}",
|
||||
"more_info": "More details"
|
||||
},
|
||||
"alexa": {
|
||||
"title": "Alexa",
|
||||
|
124
yarn.lock
124
yarn.lock
@@ -160,9 +160,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/helper-define-polyfill-provider@npm:0.6.1, @babel/helper-define-polyfill-provider@npm:^0.6.1":
|
||||
version: 0.6.1
|
||||
resolution: "@babel/helper-define-polyfill-provider@npm:0.6.1"
|
||||
"@babel/helper-define-polyfill-provider@npm:0.6.2, @babel/helper-define-polyfill-provider@npm:^0.6.1":
|
||||
version: 0.6.2
|
||||
resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2"
|
||||
dependencies:
|
||||
"@babel/helper-compilation-targets": "npm:^7.22.6"
|
||||
"@babel/helper-plugin-utils": "npm:^7.22.5"
|
||||
@@ -171,7 +171,7 @@ __metadata:
|
||||
resolve: "npm:^1.14.2"
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||
checksum: 10/316e7c0f05d2ae233d5fbb622c6339436da8d2b2047be866b64a16e6996c078a23b4adfebbdb33bc6a9882326a6cc20b95daa79a5e0edc92e9730e36d45fa523
|
||||
checksum: 10/bb32ec12024d3f16e70641bc125d2534a97edbfdabbc9f69001ec9c4ce46f877c7a224c566aa6c8c510c3b0def2e43dc4433bf6a40896ba5ce0cef4ea5ccbcff
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -4302,12 +4302,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/leaflet@npm:*, @types/leaflet@npm:1.9.11":
|
||||
version: 1.9.11
|
||||
resolution: "@types/leaflet@npm:1.9.11"
|
||||
"@types/leaflet@npm:*, @types/leaflet@npm:1.9.12":
|
||||
version: 1.9.12
|
||||
resolution: "@types/leaflet@npm:1.9.12"
|
||||
dependencies:
|
||||
"@types/geojson": "npm:*"
|
||||
checksum: 10/a7f3936b83f1007fa74f65eee7a905e582966c3218d3a45ad1c713445038e69cdefeb668c8f0cb70bc293e77d3d801b299a90bc2fd33e52ff90fd93f342108a2
|
||||
checksum: 10/ff6dce2f613b97bdc3ceb929e6eeaaa8bef8bbafdf9758935b1d679cbaf76360e366080d77e42da58e41aac146434c5d18c70ec919d37e01e0592f0a4f2e967e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -4574,15 +4574,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/eslint-plugin@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:7.7.0"
|
||||
"@typescript-eslint/eslint-plugin@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/eslint-plugin@npm:7.7.1"
|
||||
dependencies:
|
||||
"@eslint-community/regexpp": "npm:^4.10.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.7.0"
|
||||
"@typescript-eslint/type-utils": "npm:7.7.0"
|
||||
"@typescript-eslint/utils": "npm:7.7.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.7.1"
|
||||
"@typescript-eslint/type-utils": "npm:7.7.1"
|
||||
"@typescript-eslint/utils": "npm:7.7.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.1"
|
||||
debug: "npm:^4.3.4"
|
||||
graphemer: "npm:^1.4.0"
|
||||
ignore: "npm:^5.3.1"
|
||||
@@ -4595,44 +4595,44 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/9e6b6fbb9920581813c01daaa2f89419c3476e42823755c0627f4491640cfaffaebeb0592231ed4f318eefadfcdd4560b77b2903d66ab4e0c8df746a7037a603
|
||||
checksum: 10/54064fe466edcebece50cf4cfc4cb18753bcba7da0e3f0db29bf628586716b14945cadf01529ebc3d823e35bc62debf21aa636ae1f5e4fa92670dce65b3dec8c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/parser@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/parser@npm:7.7.0"
|
||||
"@typescript-eslint/parser@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/parser@npm:7.7.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager": "npm:7.7.0"
|
||||
"@typescript-eslint/types": "npm:7.7.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.7.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.7.1"
|
||||
"@typescript-eslint/types": "npm:7.7.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.7.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.1"
|
||||
debug: "npm:^4.3.4"
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/9f8c53ca29af09cd366e37420410319c8f69e9f4a676513ecd91f5e6d822b9935b6a8ad7ec931d604fc4a0ecd93d51063d0c93227f78f2380196c8a7fa6970d1
|
||||
checksum: 10/39cd5c686e9f7e86da669fc3622b203e1025f162d42c4f45373e827c659b8823535fe4ea62ccb5e672ef999f8491d74c8c5c4c497367c884672fc835497ea180
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/scope-manager@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/scope-manager@npm:7.7.0"
|
||||
"@typescript-eslint/scope-manager@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/scope-manager@npm:7.7.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.7.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.0"
|
||||
checksum: 10/c8890aaf99b57543774e50549c5b178c13695b21a6b30c65292268137fe5e6856cc0e050c118b47b5835dd8a48c96e042fc75891a7f6093a0b94b6b3b251afd9
|
||||
"@typescript-eslint/types": "npm:7.7.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.1"
|
||||
checksum: 10/7823cd15e7205d2c0d9e69432717c385b2ecd7559d5edba79113c2e97c6c5e8ca3dae9343a734bc740be97e096bfcb9dfb81a3da697f9fbf5600a56a42cf70e9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/type-utils@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/type-utils@npm:7.7.0"
|
||||
"@typescript-eslint/type-utils@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/type-utils@npm:7.7.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree": "npm:7.7.0"
|
||||
"@typescript-eslint/utils": "npm:7.7.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.7.1"
|
||||
"@typescript-eslint/utils": "npm:7.7.1"
|
||||
debug: "npm:^4.3.4"
|
||||
ts-api-utils: "npm:^1.3.0"
|
||||
peerDependencies:
|
||||
@@ -4640,23 +4640,23 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/a3f5358b4b7046458ea573607f3d6ea7f48e16524390b24c9360bdf8b03cc89fc6eb5da31b3e541e7f1e5f6958194ecaad5b644ca9b0d90c9a7b182f345451aa
|
||||
checksum: 10/c64dfd3e535741270012d289d1327e487df877adfa8a9920b1f8d6616f3b7159ef8ee1d6b62e866b6a5c64d675c5008e87f4ea20b5fc032e95f197a749d38ae6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/types@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/types@npm:7.7.0"
|
||||
checksum: 10/d54ff9eeea168188fcbf1c8efe42892d1646ead801ea0a0f1312c80cfb74ee5dd61a145bc982919fb396683fb4578f98f7ad90e5d466d7aa1ca593e4338e1a2e
|
||||
"@typescript-eslint/types@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/types@npm:7.7.1"
|
||||
checksum: 10/a1ecbaf3b8a5243394d421644f2b3eb164feea645e36dd07f1afb5008598201f19c7988141fc162c647f380dda7cf571017c0eabbbc4c5432b0143383853e134
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/typescript-estree@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:7.7.0"
|
||||
"@typescript-eslint/typescript-estree@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/typescript-estree@npm:7.7.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.7.0"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.0"
|
||||
"@typescript-eslint/types": "npm:7.7.1"
|
||||
"@typescript-eslint/visitor-keys": "npm:7.7.1"
|
||||
debug: "npm:^4.3.4"
|
||||
globby: "npm:^11.1.0"
|
||||
is-glob: "npm:^4.0.3"
|
||||
@@ -4666,34 +4666,34 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10/40af26b3edb07af439f99728aa149bbc8668dae4a700a128abaf98d7f9bc0d5d31f8027aa1d13d6a55b22c20738d7cab84a3046a56417a2551de58671b39dbdf
|
||||
checksum: 10/df5fe6c573b15e8058b88d1535eeca11115118adc54225f511d2762d74e2d453205ba27e63f6666cb5f3dc73d639208a183fb05db1f75063b115d52b1fae3e20
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/utils@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/utils@npm:7.7.0"
|
||||
"@typescript-eslint/utils@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/utils@npm:7.7.1"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.4.0"
|
||||
"@types/json-schema": "npm:^7.0.15"
|
||||
"@types/semver": "npm:^7.5.8"
|
||||
"@typescript-eslint/scope-manager": "npm:7.7.0"
|
||||
"@typescript-eslint/types": "npm:7.7.0"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.7.0"
|
||||
"@typescript-eslint/scope-manager": "npm:7.7.1"
|
||||
"@typescript-eslint/types": "npm:7.7.1"
|
||||
"@typescript-eslint/typescript-estree": "npm:7.7.1"
|
||||
semver: "npm:^7.6.0"
|
||||
peerDependencies:
|
||||
eslint: ^8.56.0
|
||||
checksum: 10/4223233ee022460a74f389302b50779537dfbb3bd414486dca356d2628a08d5b2c4c6002bae3bdffad92b368569024faf25faee9be739340d9459c23549a866f
|
||||
checksum: 10/5a352c3a849300b5d676bf5f451418a2fb0cd3ab515f3733521ad03cf047849c52c76f6e5d2406e08f6d0dbad3a4708b490f909c91a1a9e3d73060a750b3bca2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@typescript-eslint/visitor-keys@npm:7.7.0":
|
||||
version: 7.7.0
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:7.7.0"
|
||||
"@typescript-eslint/visitor-keys@npm:7.7.1":
|
||||
version: 7.7.1
|
||||
resolution: "@typescript-eslint/visitor-keys@npm:7.7.1"
|
||||
dependencies:
|
||||
"@typescript-eslint/types": "npm:7.7.0"
|
||||
"@typescript-eslint/types": "npm:7.7.1"
|
||||
eslint-visitor-keys: "npm:^3.4.3"
|
||||
checksum: 10/9f03591ab60b0b164f6bb222b5d5ae75f73fbe7f264be9318f770be9dc5dff8138d34701928940ffc18924058ae80754a738a1e623912a297d57a8a59cdfb41d
|
||||
checksum: 10/dcc5748b10bb1b169516b33e87b6d86b562e25725a95e5ac515cb197589d9667aaa7cfffa93234095a73c80addb6dd88e2a9ab01d2be0c274254b5be1ca4057a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -9556,7 +9556,7 @@ __metadata:
|
||||
resolution: "home-assistant-frontend@workspace:."
|
||||
dependencies:
|
||||
"@babel/core": "npm:7.24.4"
|
||||
"@babel/helper-define-polyfill-provider": "npm:0.6.1"
|
||||
"@babel/helper-define-polyfill-provider": "npm:0.6.2"
|
||||
"@babel/plugin-proposal-decorators": "npm:7.24.1"
|
||||
"@babel/plugin-transform-runtime": "npm:7.24.3"
|
||||
"@babel/preset-env": "npm:7.24.4"
|
||||
@@ -9644,7 +9644,7 @@ __metadata:
|
||||
"@types/glob": "npm:8.1.0"
|
||||
"@types/html-minifier-terser": "npm:7.0.2"
|
||||
"@types/js-yaml": "npm:4.0.9"
|
||||
"@types/leaflet": "npm:1.9.11"
|
||||
"@types/leaflet": "npm:1.9.12"
|
||||
"@types/leaflet-draw": "npm:1.0.11"
|
||||
"@types/luxon": "npm:3.4.2"
|
||||
"@types/mocha": "npm:10.0.6"
|
||||
@@ -9654,8 +9654,8 @@ __metadata:
|
||||
"@types/tar": "npm:6.1.13"
|
||||
"@types/ua-parser-js": "npm:0.7.39"
|
||||
"@types/webspeechapi": "npm:0.0.29"
|
||||
"@typescript-eslint/eslint-plugin": "npm:7.7.0"
|
||||
"@typescript-eslint/parser": "npm:7.7.0"
|
||||
"@typescript-eslint/eslint-plugin": "npm:7.7.1"
|
||||
"@typescript-eslint/parser": "npm:7.7.1"
|
||||
"@vaadin/combo-box": "npm:24.3.11"
|
||||
"@vaadin/vaadin-themable-mixin": "npm:24.3.11"
|
||||
"@vibrant/color": "npm:3.2.1-alpha.1"
|
||||
|
Reference in New Issue
Block a user