Merge branch 'dev'
2
.github/workflows/relative-ci.yaml
vendored
@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send bundle stats and build information to RelativeCI
|
||||
uses: relative-ci/agent-action@v2.1.12
|
||||
uses: relative-ci/agent-action@v2.1.13
|
||||
with:
|
||||
key: ${{ secrets[format('RELATIVE_CI_KEY_{0}_{1}', matrix.bundle, matrix.build)] }}
|
||||
token: ${{ github.token }}
|
||||
|
2
.github/workflows/release.yaml
vendored
@ -55,7 +55,7 @@ jobs:
|
||||
script/release
|
||||
|
||||
- name: Upload release assets
|
||||
uses: softprops/action-gh-release@v2.0.8
|
||||
uses: softprops/action-gh-release@v2.0.9
|
||||
with:
|
||||
files: |
|
||||
dist/*.whl
|
||||
|
@ -223,7 +223,10 @@ class HassioAddonInfo extends LitElement {
|
||||
<div class="description light-color">
|
||||
${this.addon.version
|
||||
? html`
|
||||
Current version: ${this.addon.version}
|
||||
${this.supervisor.localize(
|
||||
"addon.dashboard.current_version",
|
||||
{ version: this.addon.version }
|
||||
)}
|
||||
<div class="changelog" @click=${this._openChangelog}>
|
||||
(<span class="changelog-link"
|
||||
>${this.supervisor.localize(
|
||||
|
22
package.json
@ -27,11 +27,11 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "7.26.0",
|
||||
"@braintree/sanitize-url": "7.1.0",
|
||||
"@codemirror/autocomplete": "6.18.1",
|
||||
"@codemirror/autocomplete": "6.18.2",
|
||||
"@codemirror/commands": "6.7.1",
|
||||
"@codemirror/language": "6.10.3",
|
||||
"@codemirror/legacy-modes": "6.4.1",
|
||||
"@codemirror/search": "6.5.6",
|
||||
"@codemirror/search": "6.5.7",
|
||||
"@codemirror/state": "6.4.1",
|
||||
"@codemirror/view": "6.34.1",
|
||||
"@egjs/hammerjs": "2.0.17",
|
||||
@ -101,7 +101,7 @@
|
||||
"chart.js": "4.4.6",
|
||||
"color-name": "2.0.0",
|
||||
"comlink": "4.4.1",
|
||||
"core-js": "3.38.1",
|
||||
"core-js": "3.39.0",
|
||||
"cropperjs": "1.6.2",
|
||||
"date-fns": "4.1.0",
|
||||
"date-fns-tz": "3.2.0",
|
||||
@ -142,12 +142,12 @@
|
||||
"vue": "2.7.16",
|
||||
"vue2-daterange-picker": "0.6.8",
|
||||
"weekstart": "2.0.0",
|
||||
"workbox-cacheable-response": "7.1.0",
|
||||
"workbox-core": "7.1.0",
|
||||
"workbox-expiration": "7.1.0",
|
||||
"workbox-precaching": "7.1.0",
|
||||
"workbox-routing": "7.1.0",
|
||||
"workbox-strategies": "7.1.0",
|
||||
"workbox-cacheable-response": "7.3.0",
|
||||
"workbox-core": "7.3.0",
|
||||
"workbox-expiration": "7.3.0",
|
||||
"workbox-precaching": "7.3.0",
|
||||
"workbox-routing": "7.3.0",
|
||||
"workbox-strategies": "7.3.0",
|
||||
"xss": "1.0.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -224,7 +224,7 @@
|
||||
"lodash.template": "4.5.0",
|
||||
"magic-string": "0.30.12",
|
||||
"map-stream": "0.0.7",
|
||||
"mocha": "10.7.3",
|
||||
"mocha": "10.8.2",
|
||||
"object-hash": "3.0.0",
|
||||
"open": "10.1.0",
|
||||
"pinst": "3.0.0",
|
||||
@ -241,7 +241,7 @@
|
||||
"transform-async-modules-webpack-plugin": "1.1.1",
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "5.6.3",
|
||||
"webpack": "5.95.0",
|
||||
"webpack": "5.96.1",
|
||||
"webpack-cli": "5.1.4",
|
||||
"webpack-dev-server": "5.1.0",
|
||||
"webpack-manifest-plugin": "5.0.0",
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
BIN
public/static/images/voice-assistant/area.png
Normal file
After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 5.9 KiB |
BIN
public/static/images/voice-assistant/change-wake-word.png
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 5.8 KiB |
BIN
public/static/images/voice-assistant/error.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
public/static/images/voice-assistant/great-job.png
Normal file
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 6.4 KiB |
BIN
public/static/images/voice-assistant/heart.png
Normal file
After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 5.9 KiB |
BIN
public/static/images/voice-assistant/hi.png
Normal file
After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 5.9 KiB |
BIN
public/static/images/voice-assistant/ok-nabu.png
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 5.3 KiB |
BIN
public/static/images/voice-assistant/sleep.png
Normal file
After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 6.0 KiB |
BIN
public/static/images/voice-assistant/update.png
Normal file
After Width: | Height: | Size: 21 KiB |
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20241031.0"
|
||||
version = "20241104.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@ -102,7 +102,9 @@ export class HaCameraStream extends LitElement {
|
||||
.entityid=${this.stateObj.entity_id}
|
||||
.posterUrl=${this._posterUrl}
|
||||
@streams=${this._handleHlsStreams}
|
||||
class=${!this._streamType && this._webRtcStreams ? "hidden" : ""}
|
||||
class=${!this._streamType && this._webRtcStreams?.hasVideo
|
||||
? "hidden"
|
||||
: ""}
|
||||
></ha-hls-player>`
|
||||
: nothing}
|
||||
${this._streamType === STREAM_TYPE_WEB_RTC ||
|
||||
|
@ -43,6 +43,7 @@ class HaDurationInput extends LitElement {
|
||||
.label=${this.label}
|
||||
.helper=${this.helper}
|
||||
.required=${this.required}
|
||||
.clearable=${!this.required && this.data !== undefined}
|
||||
.autoValidate=${this.required}
|
||||
.disabled=${this.disabled}
|
||||
errorMessage="Required"
|
||||
@ -67,50 +68,79 @@ class HaDurationInput extends LitElement {
|
||||
}
|
||||
|
||||
private get _days() {
|
||||
return this.data?.days ? Number(this.data.days) : 0;
|
||||
return this.data?.days
|
||||
? Number(this.data.days)
|
||||
: this.required || this.data
|
||||
? 0
|
||||
: NaN;
|
||||
}
|
||||
|
||||
private get _hours() {
|
||||
return this.data?.hours ? Number(this.data.hours) : 0;
|
||||
return this.data?.hours
|
||||
? Number(this.data.hours)
|
||||
: this.required || this.data
|
||||
? 0
|
||||
: NaN;
|
||||
}
|
||||
|
||||
private get _minutes() {
|
||||
return this.data?.minutes ? Number(this.data.minutes) : 0;
|
||||
return this.data?.minutes
|
||||
? Number(this.data.minutes)
|
||||
: this.required || this.data
|
||||
? 0
|
||||
: NaN;
|
||||
}
|
||||
|
||||
private get _seconds() {
|
||||
return this.data?.seconds ? Number(this.data.seconds) : 0;
|
||||
return this.data?.seconds
|
||||
? Number(this.data.seconds)
|
||||
: this.required || this.data
|
||||
? 0
|
||||
: NaN;
|
||||
}
|
||||
|
||||
private get _milliseconds() {
|
||||
return this.data?.milliseconds ? Number(this.data.milliseconds) : 0;
|
||||
return this.data?.milliseconds
|
||||
? Number(this.data.milliseconds)
|
||||
: this.required || this.data
|
||||
? 0
|
||||
: NaN;
|
||||
}
|
||||
|
||||
private _durationChanged(ev: CustomEvent<{ value: TimeChangedEvent }>) {
|
||||
private _durationChanged(ev: CustomEvent<{ value?: TimeChangedEvent }>) {
|
||||
ev.stopPropagation();
|
||||
const value = { ...ev.detail.value };
|
||||
const value = ev.detail.value ? { ...ev.detail.value } : undefined;
|
||||
|
||||
if (!this.enableMillisecond && !value.milliseconds) {
|
||||
// @ts-ignore
|
||||
delete value.milliseconds;
|
||||
} else if (value.milliseconds > 999) {
|
||||
value.seconds += Math.floor(value.milliseconds / 1000);
|
||||
value.milliseconds %= 1000;
|
||||
}
|
||||
if (value) {
|
||||
value.hours ||= 0;
|
||||
value.minutes ||= 0;
|
||||
value.seconds ||= 0;
|
||||
|
||||
if (value.seconds > 59) {
|
||||
value.minutes += Math.floor(value.seconds / 60);
|
||||
value.seconds %= 60;
|
||||
}
|
||||
if ("days" in value) value.days ||= 0;
|
||||
if ("milliseconds" in value) value.milliseconds ||= 0;
|
||||
|
||||
if (value.minutes > 59) {
|
||||
value.hours += Math.floor(value.minutes / 60);
|
||||
value.minutes %= 60;
|
||||
}
|
||||
if (!this.enableMillisecond && !value.milliseconds) {
|
||||
// @ts-ignore
|
||||
delete value.milliseconds;
|
||||
} else if (value.milliseconds > 999) {
|
||||
value.seconds += Math.floor(value.milliseconds / 1000);
|
||||
value.milliseconds %= 1000;
|
||||
}
|
||||
|
||||
if (this.enableDay && value.hours > 24) {
|
||||
value.days = (value.days ?? 0) + Math.floor(value.hours / 24);
|
||||
value.hours %= 24;
|
||||
if (value.seconds > 59) {
|
||||
value.minutes += Math.floor(value.seconds / 60);
|
||||
value.seconds %= 60;
|
||||
}
|
||||
|
||||
if (value.minutes > 59) {
|
||||
value.hours += Math.floor(value.minutes / 60);
|
||||
value.minutes %= 60;
|
||||
}
|
||||
|
||||
if (this.enableDay && value.hours > 24) {
|
||||
value.days = (value.days ?? 0) + Math.floor(value.hours / 24);
|
||||
value.hours %= 24;
|
||||
}
|
||||
}
|
||||
|
||||
fireEvent(this, "value-changed", {
|
||||
|
@ -8,7 +8,6 @@ import { customIcons } from "../data/custom_icons";
|
||||
import type { Chunks, Icons } from "../data/iconsets";
|
||||
import {
|
||||
MDI_PREFIXES,
|
||||
checkCacheVersion,
|
||||
findIconChunk,
|
||||
getIcon,
|
||||
writeCache,
|
||||
@ -26,11 +25,6 @@ const mdiDeprecatedIcons: DeprecatedIcon = {};
|
||||
|
||||
const chunks: Chunks = {};
|
||||
|
||||
// Supervisor doesn't use icons, and should not update/downgrade the icon DB.
|
||||
if (!__SUPERVISOR__) {
|
||||
checkCacheVersion();
|
||||
}
|
||||
|
||||
const debouncedWriteCache = debounce(() => writeCache(chunks), 2000);
|
||||
|
||||
const cachedIcons: Record<string, string> = {};
|
||||
|
@ -24,7 +24,7 @@ export class HaToast extends Snackbar {
|
||||
max-width: 650px;
|
||||
}
|
||||
|
||||
// Revert the default styles set by mwc-snackbar
|
||||
/* Revert the default styles set by mwc-snackbar */
|
||||
@media (max-width: 480px), (max-width: 344px) {
|
||||
.mdc-snackbar__surface {
|
||||
min-width: inherit;
|
||||
|
@ -86,6 +86,8 @@ export class HaMap extends ReactiveElement {
|
||||
|
||||
private _mapZones: Array<Marker | Circle> = [];
|
||||
|
||||
private _mapFocusZones: Array<Marker | Circle> = [];
|
||||
|
||||
private _mapPaths: Array<Polyline | CircleMarker> = [];
|
||||
|
||||
public connectedCallback(): void {
|
||||
@ -201,7 +203,11 @@ export class HaMap extends ReactiveElement {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._mapFocusItems.length && !this.layers?.length) {
|
||||
if (
|
||||
!this._mapFocusItems.length &&
|
||||
!this._mapFocusZones.length &&
|
||||
!this.layers?.length
|
||||
) {
|
||||
this.leafletMap.setView(
|
||||
new this.Leaflet.LatLng(
|
||||
this.hass.config.latitude,
|
||||
@ -218,13 +224,9 @@ export class HaMap extends ReactiveElement {
|
||||
: []
|
||||
);
|
||||
|
||||
if (this.fitZones) {
|
||||
this._mapZones?.forEach((zone) => {
|
||||
bounds.extend(
|
||||
"getBounds" in zone ? zone.getBounds() : zone.getLatLng()
|
||||
);
|
||||
});
|
||||
}
|
||||
this._mapFocusZones?.forEach((zone) => {
|
||||
bounds.extend("getBounds" in zone ? zone.getBounds() : zone.getLatLng());
|
||||
});
|
||||
|
||||
this.layers?.forEach((layer: any) => {
|
||||
bounds.extend(
|
||||
@ -395,6 +397,7 @@ export class HaMap extends ReactiveElement {
|
||||
if (this._mapZones.length) {
|
||||
this._mapZones.forEach((marker) => marker.remove());
|
||||
this._mapZones = [];
|
||||
this._mapFocusZones = [];
|
||||
}
|
||||
|
||||
if (!this.entities) {
|
||||
@ -466,13 +469,18 @@ export class HaMap extends ReactiveElement {
|
||||
);
|
||||
|
||||
// create circle around it
|
||||
this._mapZones.push(
|
||||
Leaflet.circle([latitude, longitude], {
|
||||
interactive: false,
|
||||
color: passive ? passiveZoneColor : zoneColor,
|
||||
radius,
|
||||
})
|
||||
);
|
||||
const circle = Leaflet.circle([latitude, longitude], {
|
||||
interactive: false,
|
||||
color: passive ? passiveZoneColor : zoneColor,
|
||||
radius,
|
||||
});
|
||||
this._mapZones.push(circle);
|
||||
if (
|
||||
this.fitZones &&
|
||||
(typeof entity === "string" || entity.focus !== false)
|
||||
) {
|
||||
this._mapFocusZones.push(circle);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ export const fetchHassioLogs = async (
|
||||
) =>
|
||||
hass.callApiRaw(
|
||||
"GET",
|
||||
`hassio/${provider.includes("_") ? `addons/${provider}` : provider}/logs/boots/${boot}`,
|
||||
`hassio/${provider.includes("_") ? `addons/${provider}` : provider}/logs${boot !== 0 ? `/boots/${boot}` : ""}`,
|
||||
undefined,
|
||||
range
|
||||
? {
|
||||
@ -203,20 +203,6 @@ export const fetchHassioLogs = async (
|
||||
);
|
||||
|
||||
export const fetchHassioLogsFollow = async (
|
||||
hass: HomeAssistant,
|
||||
provider: string,
|
||||
signal: AbortSignal,
|
||||
lines = 100
|
||||
) =>
|
||||
hass.callApiRaw(
|
||||
"GET",
|
||||
`hassio/${provider.includes("_") ? `addons/${provider}` : provider}/logs/follow?lines=${lines}`,
|
||||
undefined,
|
||||
undefined,
|
||||
signal
|
||||
);
|
||||
|
||||
export const fetchHassioLogsBootFollow = async (
|
||||
hass: HomeAssistant,
|
||||
provider: string,
|
||||
signal: AbortSignal,
|
||||
@ -225,7 +211,7 @@ export const fetchHassioLogsBootFollow = async (
|
||||
) =>
|
||||
hass.callApiRaw(
|
||||
"GET",
|
||||
`hassio/${provider.includes("_") ? `addons/${provider}` : provider}/logs/boots/${boot}/follow?lines=${lines}`,
|
||||
`hassio/${provider.includes("_") ? `addons/${provider}` : provider}/logs${boot !== 0 ? `/boots/${boot}` : ""}/follow?lines=${lines}`,
|
||||
undefined,
|
||||
undefined,
|
||||
signal
|
||||
@ -236,19 +222,14 @@ export const getHassioLogDownloadUrl = (provider: string) =>
|
||||
provider.includes("_") ? `addons/${provider}` : provider
|
||||
}/logs`;
|
||||
|
||||
export const getHassioLogDownloadLinesUrl = (provider: string, lines: number) =>
|
||||
`/api/hassio/${
|
||||
provider.includes("_") ? `addons/${provider}` : provider
|
||||
}/logs?lines=${lines}`;
|
||||
|
||||
export const getHassioLogBootDownloadLinesUrl = (
|
||||
export const getHassioLogDownloadLinesUrl = (
|
||||
provider: string,
|
||||
lines: number,
|
||||
boot = 0
|
||||
) =>
|
||||
`/api/hassio/${
|
||||
provider.includes("_") ? `addons/${provider}` : provider
|
||||
}/logs/boots/${boot}?lines=${lines}`;
|
||||
}/logs${boot !== 0 ? `/boots/${boot}` : ""}?lines=${lines}`;
|
||||
|
||||
export const setSupervisorOption = async (
|
||||
hass: HomeAssistant,
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { clear, get, set, createStore, promisifyRequest } from "idb-keyval";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { promiseTimeout } from "../common/util/promise-timeout";
|
||||
import { iconMetadata } from "../resources/icon-metadata";
|
||||
import type { IconMeta } from "../types";
|
||||
@ -11,7 +12,23 @@ export interface Chunks {
|
||||
[key: string]: Promise<Icons>;
|
||||
}
|
||||
|
||||
export const iconStore = createStore("hass-icon-db", "mdi-icon-store");
|
||||
const getStore = memoizeOne(async () => {
|
||||
const iconStore = createStore("hass-icon-db", "mdi-icon-store");
|
||||
|
||||
// Supervisor doesn't use icons, and should not update/downgrade the icon DB.
|
||||
if (!__SUPERVISOR__) {
|
||||
const version = await get("_version", iconStore);
|
||||
|
||||
if (!version) {
|
||||
set("_version", iconMetadata.version, iconStore);
|
||||
} else if (version !== iconMetadata.version) {
|
||||
await clear(iconStore);
|
||||
set("_version", iconMetadata.version, iconStore);
|
||||
}
|
||||
}
|
||||
|
||||
return iconStore;
|
||||
});
|
||||
|
||||
export const MDI_PREFIXES = ["mdi", "hass", "hassio", "hademo"];
|
||||
|
||||
@ -28,7 +45,10 @@ export const getIcon = (iconName: string) =>
|
||||
return;
|
||||
}
|
||||
|
||||
const readIcons = () =>
|
||||
// Start initializing the store, so it's ready when we need it
|
||||
const iconStoreProm = getStore();
|
||||
const readIcons = async () => {
|
||||
const iconStore = await iconStoreProm;
|
||||
iconStore("readonly", (store) => {
|
||||
for (const [iconName_, resolve_, reject_] of toRead) {
|
||||
promisifyRequest<string | undefined>(store.get(iconName_))
|
||||
@ -37,6 +57,7 @@ export const getIcon = (iconName: string) =>
|
||||
}
|
||||
toRead = [];
|
||||
});
|
||||
};
|
||||
|
||||
promiseTimeout(1000, readIcons()).catch((e) => {
|
||||
// Firefox in private mode doesn't support IDB
|
||||
@ -62,6 +83,7 @@ export const findIconChunk = (icon: string): string => {
|
||||
export const writeCache = async (chunks: Chunks) => {
|
||||
const keys = Object.keys(chunks);
|
||||
const iconsSets: Icons[] = await Promise.all(Object.values(chunks));
|
||||
const iconStore = await getStore();
|
||||
// We do a batch opening the store just once, for (considerable) performance
|
||||
iconStore("readwrite", (store) => {
|
||||
iconsSets.forEach((icons, idx) => {
|
||||
@ -72,14 +94,3 @@ export const writeCache = async (chunks: Chunks) => {
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const checkCacheVersion = async () => {
|
||||
const version = await get("_version", iconStore);
|
||||
|
||||
if (!version) {
|
||||
set("_version", iconMetadata.version, iconStore);
|
||||
} else if (version !== iconMetadata.version) {
|
||||
await clear(iconStore);
|
||||
set("_version", iconMetadata.version, iconStore);
|
||||
}
|
||||
};
|
||||
|
@ -1,10 +1,24 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import { format } from "date-fns";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import "../../../components/ha-climate-state";
|
||||
import "../../../components/ha-cover-controls";
|
||||
import "../../../components/ha-cover-tilt-controls";
|
||||
import "../../../components/ha-date-input";
|
||||
import "../../../components/ha-humidifier-state";
|
||||
import "../../../components/ha-select";
|
||||
import "../../../components/ha-slider";
|
||||
import "../../../components/ha-time-input";
|
||||
import "../../../components/entity/ha-entity-toggle";
|
||||
import "../../../components/entity/state-badge";
|
||||
import { isTiltOnly } from "../../../data/cover";
|
||||
import { isUnavailableState } from "../../../data/entity";
|
||||
import type { ImageEntity } from "../../../data/image";
|
||||
import { computeImageUrl } from "../../../data/image";
|
||||
import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor";
|
||||
import "../../../panels/lovelace/components/hui-timestamp-display";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
@ -28,18 +42,7 @@ class EntityPreviewRow extends LitElement {
|
||||
<div class="name" .title=${computeStateName(stateObj)}>
|
||||
${computeStateName(stateObj)}
|
||||
</div>
|
||||
<div class="value">
|
||||
${stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP &&
|
||||
!isUnavailableState(stateObj.state)
|
||||
? html`
|
||||
<hui-timestamp-display
|
||||
.hass=${this.hass}
|
||||
.ts=${new Date(stateObj.state)}
|
||||
capitalize
|
||||
></hui-timestamp-display>
|
||||
`
|
||||
: this.hass.formatEntityState(stateObj)}
|
||||
</div>`;
|
||||
<div class="value">${this.renderEntityState(stateObj)}</div>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
@ -59,8 +62,308 @@ class EntityPreviewRow extends LitElement {
|
||||
.value {
|
||||
direction: ltr;
|
||||
}
|
||||
.numberflex {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-grow: 2;
|
||||
}
|
||||
.numberstate {
|
||||
min-width: 45px;
|
||||
text-align: end;
|
||||
}
|
||||
ha-textfield {
|
||||
text-align: end;
|
||||
direction: ltr !important;
|
||||
}
|
||||
ha-slider {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
}
|
||||
ha-time-input {
|
||||
margin-left: 4px;
|
||||
margin-inline-start: 4px;
|
||||
margin-inline-end: initial;
|
||||
direction: var(--direction);
|
||||
}
|
||||
.datetimeflex {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
}
|
||||
mwc-button {
|
||||
margin-right: -0.57em;
|
||||
margin-inline-end: -0.57em;
|
||||
margin-inline-start: initial;
|
||||
}
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
private renderEntityState(stateObj: HassEntity): TemplateResult | string {
|
||||
const domain = stateObj.entity_id.split(".", 1)[0];
|
||||
|
||||
if (domain === "button") {
|
||||
return html`
|
||||
<mwc-button .disabled=${isUnavailableState(stateObj.state)}>
|
||||
${this.hass.localize("ui.card.button.press")}
|
||||
</mwc-button>
|
||||
`;
|
||||
}
|
||||
|
||||
const climateDomains = ["climate", "water_heater"];
|
||||
if (climateDomains.includes(domain)) {
|
||||
return html`
|
||||
<ha-climate-state .hass=${this.hass} .stateObj=${stateObj}>
|
||||
</ha-climate-state>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "cover") {
|
||||
return html`
|
||||
${isTiltOnly(stateObj)
|
||||
? html`
|
||||
<ha-cover-tilt-controls
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
></ha-cover-tilt-controls>
|
||||
`
|
||||
: html`
|
||||
<ha-cover-controls
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
></ha-cover-controls>
|
||||
`}
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "date") {
|
||||
return html`
|
||||
<ha-date-input
|
||||
.locale=${this.hass.locale}
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
.value=${isUnavailableState(stateObj.state)
|
||||
? undefined
|
||||
: stateObj.state}
|
||||
>
|
||||
</ha-date-input>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "datetime") {
|
||||
const dateObj = isUnavailableState(stateObj.state)
|
||||
? undefined
|
||||
: new Date(stateObj.state);
|
||||
const time = dateObj ? format(dateObj, "HH:mm:ss") : undefined;
|
||||
const date = dateObj ? format(dateObj, "yyyy-MM-dd") : undefined;
|
||||
return html`
|
||||
<div class="datetimeflex">
|
||||
<ha-date-input
|
||||
.label=${computeStateName(stateObj)}
|
||||
.locale=${this.hass.locale}
|
||||
.value=${date}
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
>
|
||||
</ha-date-input>
|
||||
<ha-time-input
|
||||
.value=${time}
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
.locale=${this.hass.locale}
|
||||
></ha-time-input>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "event") {
|
||||
return html`
|
||||
<div class="when">
|
||||
${isUnavailableState(stateObj.state)
|
||||
? this.hass.formatEntityState(stateObj)
|
||||
: html`<hui-timestamp-display
|
||||
.hass=${this.hass}
|
||||
.ts=${new Date(stateObj.state)}
|
||||
capitalize
|
||||
></hui-timestamp-display>`}
|
||||
</div>
|
||||
<div class="what">
|
||||
${isUnavailableState(stateObj.state)
|
||||
? nothing
|
||||
: this.hass.formatEntityAttributeValue(stateObj, "event_type")}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
const toggleDomains = ["fan", "light", "remote", "siren", "switch"];
|
||||
if (toggleDomains.includes(domain)) {
|
||||
const showToggle =
|
||||
stateObj.state === "on" ||
|
||||
stateObj.state === "off" ||
|
||||
isUnavailableState(stateObj.state);
|
||||
return html`
|
||||
${showToggle
|
||||
? html`
|
||||
<ha-entity-toggle
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
></ha-entity-toggle>
|
||||
`
|
||||
: this.hass.formatEntityState(stateObj)}
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "humidifier") {
|
||||
return html`
|
||||
<ha-humidifier-state .hass=${this.hass} .stateObj=${stateObj}>
|
||||
</ha-humidifier-state>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "image") {
|
||||
const image: string = computeImageUrl(stateObj as ImageEntity);
|
||||
return html`
|
||||
<img
|
||||
alt=${ifDefined(stateObj?.attributes.friendly_name)}
|
||||
src=${this.hass.hassUrl(image)}
|
||||
/>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "lock") {
|
||||
return html`
|
||||
<mwc-button
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
class="text-content"
|
||||
>
|
||||
${stateObj.state === "locked"
|
||||
? this.hass!.localize("ui.card.lock.unlock")
|
||||
: this.hass!.localize("ui.card.lock.lock")}
|
||||
</mwc-button>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "number") {
|
||||
const showNumberSlider =
|
||||
stateObj.attributes.mode === "slider" ||
|
||||
(stateObj.attributes.mode === "auto" &&
|
||||
(Number(stateObj.attributes.max) - Number(stateObj.attributes.min)) /
|
||||
Number(stateObj.attributes.step) <=
|
||||
256);
|
||||
return html`
|
||||
${showNumberSlider
|
||||
? html`
|
||||
<div class="numberflex">
|
||||
<ha-slider
|
||||
labeled
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
.step=${Number(stateObj.attributes.step)}
|
||||
.min=${Number(stateObj.attributes.min)}
|
||||
.max=${Number(stateObj.attributes.max)}
|
||||
.value=${Number(stateObj.state)}
|
||||
></ha-slider>
|
||||
<span class="state">
|
||||
${this.hass.formatEntityState(stateObj)}
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
: html` <div class="numberflex numberstate">
|
||||
<ha-textfield
|
||||
autoValidate
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
pattern="[0-9]+([\\.][0-9]+)?"
|
||||
.step=${Number(stateObj.attributes.step)}
|
||||
.min=${Number(stateObj.attributes.min)}
|
||||
.max=${Number(stateObj.attributes.max)}
|
||||
.value=${stateObj.state}
|
||||
.suffix=${stateObj.attributes.unit_of_measurement}
|
||||
type="number"
|
||||
></ha-textfield>
|
||||
</div>`}
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "select") {
|
||||
return html`
|
||||
<ha-select
|
||||
.label=${computeStateName(stateObj)}
|
||||
.value=${stateObj.state}
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
naturalMenuWidth
|
||||
>
|
||||
${stateObj.attributes.options
|
||||
? stateObj.attributes.options.map(
|
||||
(option) => html`
|
||||
<mwc-list-item .value=${option}>
|
||||
${this.hass!.formatEntityState(stateObj, option)}
|
||||
</mwc-list-item>
|
||||
`
|
||||
)
|
||||
: ""}
|
||||
</ha-select>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "sensor") {
|
||||
const showSensor =
|
||||
stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP &&
|
||||
!isUnavailableState(stateObj.state);
|
||||
return html`
|
||||
${showSensor
|
||||
? html`
|
||||
<hui-timestamp-display
|
||||
.hass=${this.hass}
|
||||
.ts=${new Date(stateObj.state)}
|
||||
capitalize
|
||||
></hui-timestamp-display>
|
||||
`
|
||||
: this.hass.formatEntityState(stateObj)}
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "text") {
|
||||
return html`
|
||||
<ha-textfield
|
||||
.label=${computeStateName(stateObj)}
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
.value=${stateObj.state}
|
||||
.minlength=${stateObj.attributes.min}
|
||||
.maxlength=${stateObj.attributes.max}
|
||||
.autoValidate=${stateObj.attributes.pattern}
|
||||
.pattern=${stateObj.attributes.pattern}
|
||||
.type=${stateObj.attributes.mode}
|
||||
placeholder=${this.hass!.localize("ui.card.text.emtpy_value")}
|
||||
></ha-textfield>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "time") {
|
||||
return html`
|
||||
<ha-time-input
|
||||
.value=${isUnavailableState(stateObj.state)
|
||||
? undefined
|
||||
: stateObj.state}
|
||||
.locale=${this.hass.locale}
|
||||
.disabled=${isUnavailableState(stateObj.state)}
|
||||
></ha-time-input>
|
||||
`;
|
||||
}
|
||||
|
||||
if (domain === "weather") {
|
||||
return html`
|
||||
<div>
|
||||
${isUnavailableState(stateObj.state) ||
|
||||
stateObj.attributes.temperature === undefined ||
|
||||
stateObj.attributes.temperature === null
|
||||
? this.hass.formatEntityState(stateObj)
|
||||
: this.hass.formatEntityAttributeValue(stateObj, "temperature")}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return this.hass.formatEntityState(stateObj);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -143,7 +143,7 @@ class MoreInfoUpdate extends LitElement {
|
||||
)}
|
||||
</span>
|
||||
<ha-switch
|
||||
id="create_backup"
|
||||
id="create-backup"
|
||||
checked
|
||||
.disabled=${updateIsInstalling(this.stateObj)}
|
||||
></ha-switch>
|
||||
|
@ -66,6 +66,8 @@ export class HaVoiceAssistantSetupDialog extends LitElement {
|
||||
private _dialogClosed() {
|
||||
this._params = undefined;
|
||||
this._assistConfiguration = undefined;
|
||||
this._previousSteps = [];
|
||||
this._nextStep = undefined;
|
||||
this._step = STEP.INIT;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ export class HaVoiceAssistantSetupStepArea extends LitElement {
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
|
||||
return html`<div class="content">
|
||||
<img src="/static/images/voice-assistant/area.gif" />
|
||||
<img src="/static/images/voice-assistant/area.png" />
|
||||
<h1>Select area</h1>
|
||||
<p class="secondary">
|
||||
When you voice assistant knows where it is, it can better control the
|
||||
|
@ -21,7 +21,7 @@ export class HaVoiceAssistantSetupStepChangeWakeWord extends LitElement {
|
||||
|
||||
protected override render() {
|
||||
return html`<div class="padding content">
|
||||
<img src="/static/images/voice-assistant/change-wake-word.gif" />
|
||||
<img src="/static/images/voice-assistant/change-wake-word.png" />
|
||||
<h1>Change wake word</h1>
|
||||
<p class="secondary">
|
||||
Some wake words are better for
|
||||
|
@ -6,6 +6,7 @@ import "../../components/ha-circular-progress";
|
||||
import { testAssistSatelliteConnection } from "../../data/assist_satellite";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { AssistantSetupStyles } from "./styles";
|
||||
import { documentationUrl } from "../../util/documentation-url";
|
||||
|
||||
@customElement("ha-voice-assistant-setup-step-check")
|
||||
export class HaVoiceAssistantSetupStepCheck extends LitElement {
|
||||
@ -35,7 +36,7 @@ export class HaVoiceAssistantSetupStepCheck extends LitElement {
|
||||
protected override render() {
|
||||
return html`<div class="content">
|
||||
${this._status === "timeout"
|
||||
? html`<img src="/static/images/voice-assistant/error.gif" />
|
||||
? html`<img src="/static/images/voice-assistant/error.png" />
|
||||
<h1>The voice assistant is unable to connect to Home Assistant</h1>
|
||||
<p class="secondary">
|
||||
To play audio, the voice assistant device has to connect to Home
|
||||
@ -44,12 +45,15 @@ export class HaVoiceAssistantSetupStepCheck extends LitElement {
|
||||
</p>
|
||||
<div class="footer">
|
||||
<a
|
||||
href="https://www.home-assistant.io/docs/configuration/remote/#adding-a-remote-url-to-home-assistant"
|
||||
href=${documentationUrl(
|
||||
this.hass,
|
||||
"/voice_control/troubleshooting/#i-dont-get-a-voice-response"
|
||||
)}
|
||||
><ha-button>Help me</ha-button></a
|
||||
>
|
||||
<ha-button @click=${this._testConnection}>Retry</ha-button>
|
||||
</div>`
|
||||
: html`<img src="/static/images/voice-assistant/hi.gif" />
|
||||
: html`<img src="/static/images/voice-assistant/hi.png" />
|
||||
<h1>Hi</h1>
|
||||
<p class="secondary">
|
||||
Over the next couple steps we're going to personalize your voice
|
||||
|
@ -67,7 +67,7 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
|
||||
: undefined;
|
||||
|
||||
return html`<div class="content">
|
||||
<img src="/static/images/voice-assistant/heart.gif" />
|
||||
<img src="/static/images/voice-assistant/heart.png" />
|
||||
<h1>Ready to Assist!</h1>
|
||||
<p class="secondary">
|
||||
Make any final customizations here. You can always change these in the
|
||||
|
@ -65,7 +65,7 @@ export class HaVoiceAssistantSetupStepUpdate extends LitElement {
|
||||
const progressIsNumeric = stateObj && updateUsesProgress(stateObj);
|
||||
|
||||
return html`<div class="content">
|
||||
<img src="/static/images/voice-assistant/update.gif" />
|
||||
<img src="/static/images/voice-assistant/update.png" />
|
||||
<h1>
|
||||
${stateObj &&
|
||||
(stateObj.state === "unavailable" || updateIsInstalling(stateObj))
|
||||
|
@ -64,14 +64,14 @@ export class HaVoiceAssistantSetupStepWakeWord extends LitElement {
|
||||
return html`<div class="content">
|
||||
${!this._detected
|
||||
? html`
|
||||
<img src="/static/images/voice-assistant/sleep.gif" />
|
||||
<img src="/static/images/voice-assistant/sleep.png" />
|
||||
<h1>
|
||||
Say “${this._activeWakeWord(this.assistConfiguration)}” to wake the
|
||||
device up
|
||||
</h1>
|
||||
<p class="secondary">Setup will continue once the device is awake.</p>
|
||||
</div>`
|
||||
: html`<img src="/static/images/voice-assistant/ok-nabu.gif" />
|
||||
: html`<img src="/static/images/voice-assistant/ok-nabu.png" />
|
||||
<h1>
|
||||
Say “${this._activeWakeWord(this.assistConfiguration)}” again
|
||||
</h1>
|
||||
|
@ -16,6 +16,8 @@ import type { ValueChangedEvent } from "../types";
|
||||
import { onBoardingStyles } from "./styles";
|
||||
import { debounce } from "../common/util/debounce";
|
||||
|
||||
const CHECK_USERNAME_REGEX = /\s|[A-Z]/;
|
||||
|
||||
const CREATE_USER_SCHEMA: HaFormSchema[] = [
|
||||
{
|
||||
name: "name",
|
||||
@ -121,6 +123,7 @@ class OnboardingCreateUser extends LitElement {
|
||||
ev: ValueChangedEvent<HaFormDataContainer>
|
||||
): void {
|
||||
const nameChanged = ev.detail.value.name !== this._newUser.name;
|
||||
const usernameChanged = ev.detail.value.username !== this._newUser.username;
|
||||
const passwordChanged =
|
||||
ev.detail.value.password !== this._newUser.password ||
|
||||
ev.detail.value.password_confirm !== this._newUser.password_confirm;
|
||||
@ -135,6 +138,9 @@ class OnboardingCreateUser extends LitElement {
|
||||
this._debouncedCheckPasswordMatch();
|
||||
}
|
||||
}
|
||||
if (usernameChanged) {
|
||||
this._checkUsername();
|
||||
}
|
||||
}
|
||||
|
||||
private _debouncedCheckPasswordMatch = debounce(
|
||||
@ -164,6 +170,21 @@ class OnboardingCreateUser extends LitElement {
|
||||
const parts = String(this._newUser.name).split(" ");
|
||||
if (parts.length) {
|
||||
this._newUser.username = parts[0].toLowerCase();
|
||||
this._checkUsername();
|
||||
}
|
||||
}
|
||||
|
||||
private _checkUsername(): void {
|
||||
const old = this._formError.username;
|
||||
if (CHECK_USERNAME_REGEX.test(this._newUser.username as string)) {
|
||||
this._formError.username = this.localize(
|
||||
"ui.panel.page-onboarding.user.error.username_not_normalized"
|
||||
);
|
||||
} else {
|
||||
this._formError.username = "";
|
||||
}
|
||||
if (old !== this._formError.username) {
|
||||
this.requestUpdate("_formError");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ export class HaDelayAction extends LitElement implements ActionElement {
|
||||
.disabled=${this.disabled}
|
||||
.data=${this._timeData}
|
||||
enableMillisecond
|
||||
required
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-duration-input>`;
|
||||
}
|
||||
|
@ -67,9 +67,6 @@ export class HaWaitForTriggerAction
|
||||
private _timeoutChanged(ev: CustomEvent<{ value: TimeChangedEvent }>): void {
|
||||
ev.stopPropagation();
|
||||
const value = ev.detail.value;
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
fireEvent(this, "value-changed", {
|
||||
value: { ...this.action, timeout: value },
|
||||
});
|
||||
|
@ -712,8 +712,12 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
private async _duplicate() {
|
||||
const result = this._readOnly
|
||||
? await showConfirmationDialog(this, {
|
||||
title: "Migrate automation?",
|
||||
text: "You can migrate this automation, so it can be edited from the UI. After it is migrated and you have saved it, you will have to manually delete your old automation from your configuration. Do you want to migrate this automation?",
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.automation.picker.migrate_automation"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.automation.picker.migrate_automation_description"
|
||||
),
|
||||
})
|
||||
: await this.confirmUnsavedChanged();
|
||||
if (result) {
|
||||
|
@ -46,7 +46,7 @@ export class HaCalendarTrigger extends LitElement implements TriggerElement {
|
||||
],
|
||||
],
|
||||
},
|
||||
{ name: "offset", selector: { duration: {} } },
|
||||
{ name: "offset", required: true, selector: { duration: {} } },
|
||||
{
|
||||
name: "offset_type",
|
||||
type: "select",
|
||||
|
@ -584,6 +584,10 @@ class AddIntegrationDialog extends LitElement {
|
||||
});
|
||||
if (configEntries.length > 0) {
|
||||
this.closeDialog();
|
||||
const localize = await this.hass.loadBackendTranslation(
|
||||
"title",
|
||||
integration.name
|
||||
);
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.single_config_entry_title"
|
||||
@ -591,7 +595,7 @@ class AddIntegrationDialog extends LitElement {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.single_config_entry",
|
||||
{
|
||||
integration_name: integration.name,
|
||||
integration_name: domainToName(localize, integration.name),
|
||||
}
|
||||
),
|
||||
});
|
||||
|
@ -1387,6 +1387,10 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
this._extraConfigEntries || this.configEntries
|
||||
);
|
||||
if (entries.length > 0) {
|
||||
const localize = await this.hass.loadBackendTranslation(
|
||||
"title",
|
||||
this._manifest.name
|
||||
);
|
||||
await showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.single_config_entry_title"
|
||||
@ -1394,7 +1398,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.single_config_entry",
|
||||
{
|
||||
integration_name: this._manifest.name,
|
||||
integration_name: domainToName(localize, this._manifest.name),
|
||||
}
|
||||
),
|
||||
});
|
||||
|
@ -744,6 +744,10 @@ class HaConfigIntegrationsDashboard extends SubscribeMixin(LitElement) {
|
||||
if (integration.single_config_entry) {
|
||||
const configEntries = await getConfigEntries(this.hass, { domain });
|
||||
if (configEntries.length > 0) {
|
||||
const localize = await this.hass.loadBackendTranslation(
|
||||
"title",
|
||||
integration.name
|
||||
);
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.single_config_entry_title"
|
||||
@ -751,7 +755,7 @@ class HaConfigIntegrationsDashboard extends SubscribeMixin(LitElement) {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.single_config_entry",
|
||||
{
|
||||
integration_name: integration.name,
|
||||
integration_name: domainToName(localize, integration.name!),
|
||||
}
|
||||
),
|
||||
});
|
||||
|
@ -44,7 +44,6 @@ class MatterAddDeviceGoogleHome extends LitElement {
|
||||
home_assistant: html`<b>Home Assistant</b>`,
|
||||
}
|
||||
)}
|
||||
<br />
|
||||
<span
|
||||
class="link"
|
||||
type="button"
|
||||
@ -57,13 +56,13 @@ class MatterAddDeviceGoogleHome extends LitElement {
|
||||
)}
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
${this.hass.localize(
|
||||
`ui.dialogs.matter-add-device.google_home.redirect`
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
<br />
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
`ui.dialogs.matter-add-device.google_home.redirect`
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
@ -14,10 +14,7 @@ import type { DownloadLogsDialogParams } from "./show-dialog-download-logs";
|
||||
import "../../../components/ha-select";
|
||||
import "../../../components/ha-list-item";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import {
|
||||
getHassioLogDownloadLinesUrl,
|
||||
getHassioLogBootDownloadLinesUrl,
|
||||
} from "../../../data/hassio/supervisor";
|
||||
import { getHassioLogDownloadLinesUrl } from "../../../data/hassio/supervisor";
|
||||
import { getSignedPath } from "../../../data/auth";
|
||||
import { fileDownload } from "../../../util/file_download";
|
||||
|
||||
@ -115,7 +112,7 @@ class DownloadLogsDialog extends LitElement {
|
||||
const boot = this._dialogParams!.boot;
|
||||
|
||||
const timeString = new Date().toISOString().replace(/:/g, "-");
|
||||
const downloadUrl = this._getDownloadUrlFunction()(
|
||||
const downloadUrl = getHassioLogDownloadLinesUrl(
|
||||
provider,
|
||||
this._lineCount,
|
||||
boot
|
||||
@ -129,13 +126,6 @@ class DownloadLogsDialog extends LitElement {
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
private _getDownloadUrlFunction() {
|
||||
if (this._dialogParams!.boot === 0) {
|
||||
return getHassioLogDownloadLinesUrl;
|
||||
}
|
||||
return getHassioLogBootDownloadLinesUrl;
|
||||
}
|
||||
|
||||
private _setNumberOfLogs(ev) {
|
||||
this._lineCount = Number(ev.target.value);
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ import { extractApiErrorMessage } from "../../../data/hassio/common";
|
||||
import {
|
||||
fetchHassioBoots,
|
||||
fetchHassioLogs,
|
||||
fetchHassioLogsBootFollow,
|
||||
fetchHassioLogsFollow,
|
||||
getHassioLogDownloadUrl,
|
||||
} from "../../../data/hassio/supervisor";
|
||||
@ -379,7 +378,7 @@ class ErrorLogCard extends LitElement {
|
||||
isComponentLoaded(this.hass, "hassio") &&
|
||||
this.provider
|
||||
) {
|
||||
const response = await this._fetchLogsFunction()(
|
||||
const response = await fetchHassioLogsFollow(
|
||||
this.hass,
|
||||
this.provider,
|
||||
this._logStreamAborter.signal,
|
||||
@ -469,13 +468,6 @@ class ErrorLogCard extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _fetchLogsFunction = () => {
|
||||
if (this._boot === 0) {
|
||||
return fetchHassioLogsFollow;
|
||||
}
|
||||
return fetchHassioLogsBootFollow;
|
||||
};
|
||||
|
||||
private _debounceSearch = debounce(() => {
|
||||
this._noSearchResults = !this._ansiToHtmlElement?.filterLines(this.filter);
|
||||
|
||||
|
@ -681,8 +681,12 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
private async _duplicate() {
|
||||
const result = this._readOnly
|
||||
? await showConfirmationDialog(this, {
|
||||
title: "Migrate script?",
|
||||
text: "You can migrate this script, so it can be edited from the UI. After it is migrated and you have saved it, you will have to manually delete your old script from your configuration. Do you want to migrate this script?",
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.script.picker.migrate_script"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.script.picker.migrate_script_description"
|
||||
),
|
||||
})
|
||||
: await this.confirmUnsavedChanged();
|
||||
if (result) {
|
||||
|
@ -59,18 +59,12 @@ export class HuiEnergyDateSelectionCard
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
ha-card {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.padded {
|
||||
padding-left: 16px !important;
|
||||
padding-inline-start: 16px !important;
|
||||
padding-inline-end: initial !important;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ export class HuiHorizontalStackCard extends HuiStackCard {
|
||||
css`
|
||||
#root {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
gap: var(--horizontal-stack-card-gap, var(--stack-card-gap, 8px));
|
||||
}
|
||||
#root > hui-card {
|
||||
|
@ -64,6 +64,7 @@ const cardConfigStruct = assign(
|
||||
hours_to_show: optional(number()),
|
||||
geo_location_sources: optional(array(geoSourcesConfigStruct)),
|
||||
auto_fit: optional(boolean()),
|
||||
fit_zones: optional(boolean()),
|
||||
theme_mode: optional(string()),
|
||||
})
|
||||
);
|
||||
|
@ -242,8 +242,9 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
||||
min-height: var(--row-height);
|
||||
}
|
||||
|
||||
.container.edit-mode:not(.import-only) {
|
||||
border-start-end-radius: 0px;
|
||||
.container.import-only {
|
||||
border: none;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import { mdiDelete, mdiDrag, mdiPencil, mdiViewGridPlus } from "@mdi/js";
|
||||
import {
|
||||
mdiDelete,
|
||||
mdiDrag,
|
||||
mdiEyeOff,
|
||||
mdiPencil,
|
||||
mdiViewGridPlus,
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@ -245,6 +251,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
<div class="section imported-cards">
|
||||
<div class="imported-card-header">
|
||||
<p class="title">
|
||||
<ha-svg-icon .path=${mdiEyeOff}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.section.imported_cards_title"
|
||||
)}
|
||||
@ -480,9 +487,9 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
}
|
||||
|
||||
.imported-card-header {
|
||||
margin-top: 24px;
|
||||
padding: 16px 8px;
|
||||
border-top: 2px dashed var(--divider-color);
|
||||
margin-top: 36px;
|
||||
padding: 32px 0 16px 0;
|
||||
border-top: 4px dotted var(--divider-color);
|
||||
}
|
||||
|
||||
.imported-card-header .title {
|
||||
@ -491,6 +498,11 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 24px;
|
||||
--mdc-icon-size: 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.imported-card-header .subtitle {
|
||||
margin: 0;
|
||||
|
@ -1745,8 +1745,8 @@
|
||||
"answer_generic": "Other controllers"
|
||||
},
|
||||
"google_home": {
|
||||
"header": "Link Matter app",
|
||||
"step_1": "Find your device in Google Home. Tap the gear icon to open the device settings.",
|
||||
"header": "Share from Google Home",
|
||||
"step_1": "Find your device in the Google Home app. Tap the gear icon to open the device settings.",
|
||||
"step_2": "Tap {linked_matter_apps_services}.",
|
||||
"step_3": "Tap {link_apps_services} and choose {home_assistant} from the list.",
|
||||
"linked_matter_apps_services": "Linked Matter apps and services",
|
||||
@ -1776,8 +1776,8 @@
|
||||
"code_instructions": "Paste the code you just received from the other controller."
|
||||
},
|
||||
"generic": {
|
||||
"header": "Copy setup code",
|
||||
"code_instructions": "Search for the sharing mode in the app of your controller, and activate it. You will get a sharing code, enter that below.",
|
||||
"header": "Enter setup code",
|
||||
"code_instructions": "Search for the sharing mode in the app of your controller, and activate it. You will get a setup code, enter that below.",
|
||||
"setup_code": "Setup code"
|
||||
}
|
||||
}
|
||||
@ -2792,7 +2792,9 @@
|
||||
},
|
||||
"empty_header": "Start automating",
|
||||
"empty_text_1": "Automations make Home Assistant automatically respond to things happening in and around your home.",
|
||||
"empty_text_2": "Automations connect triggers to actions in a ''when trigger then action'' fashion with optional conditions. For example: ''When the sun sets and if {user} is home, then turn on the lights''."
|
||||
"empty_text_2": "Automations connect triggers to actions in a ''when trigger then action'' fashion with optional conditions. For example: ''When the sun sets and if {user} is home, then turn on the lights''.",
|
||||
"migrate_automation": "Migrate automation?",
|
||||
"migrate_automation_description": "You can migrate this automation, so it can be edited from the UI. After it is migrated and you have saved it, you will have to manually delete your old automation from your configuration. Do you want to migrate this automation?"
|
||||
},
|
||||
"dialog_new": {
|
||||
"header": "Create automation",
|
||||
@ -3215,7 +3217,7 @@
|
||||
"description": {
|
||||
"picker": "If an entity (or attribute) is in a specific state.",
|
||||
"no_entity": "Confirm state",
|
||||
"full": "If{hasAttribute, select, \n true { {attribute} of}\n other {}\n} {numberOfEntities, plural,\n zero {an entity is}\n one {{entities} is}\n other {{entities} are}\n} {numberOfStates, plural,\n zero {a state}\n other {{states}}\n}{hasDuration, select, \n true { for {duration}} \n other {}\n }"
|
||||
"full": "If{hasAttribute, select, \n true { {attribute} of}\n other {}\n} {numberOfEntities, plural,\n =0 {an entity is}\n one {{entities} is}\n other {{entities} are}\n} {numberOfStates, plural,\n =0 {a state}\n other {{states}}\n}{hasDuration, select, \n true { for {duration}} \n other {}\n }"
|
||||
}
|
||||
},
|
||||
"sun": {
|
||||
@ -3676,7 +3678,9 @@
|
||||
"duplicate": "[%key:ui::common::duplicate%]",
|
||||
"empty_header": "Create your first script",
|
||||
"empty_text": "A script is a sequence of actions that can be run from a dashboard, an automation, or be triggered by voice. For example, a ''Wake-up routine''' script that gradually turns on the light in the bedroom and opens the blinds after a delay.",
|
||||
"search": "Search {number} scripts"
|
||||
"search": "Search {number} scripts",
|
||||
"migrate_script": "Migrate script?",
|
||||
"migrate_script_description": "You can migrate this script, so it can be edited from the UI. After it is migrated and you have saved it, you will have to manually delete your old script from your configuration. Do you want to migrate this script?"
|
||||
},
|
||||
"dialog_new": {
|
||||
"header": "Create script",
|
||||
@ -4115,7 +4119,7 @@
|
||||
"hidden": "Hidden"
|
||||
},
|
||||
"confirm_rename_entity_ids": "Do you also want to rename the entity IDs of your entities?",
|
||||
"confirm_rename_entity_ids_warning": "This will not change any configuration (like automations, scripts, scenes, dashboards) that is currently using these entities! You will have to update them yourself to use the new entity IDs!",
|
||||
"confirm_rename_entity_ids_warning": "This will not change any configuration (like automations, scripts, scenes, dashboards) that is currently using these entities! You will have to manually edit them yourself to use the new entity IDs!",
|
||||
"confirm_rename_entity_will_rename": "{count} {count, plural,\n one {entity ID}\n other {entity IDs}\n} will be renamed",
|
||||
"confirm_rename_new": "New",
|
||||
"confirm_rename_old": "Old",
|
||||
@ -5306,7 +5310,7 @@
|
||||
"share": "Share"
|
||||
},
|
||||
"mount_type": {
|
||||
"nfs": "Network file share (NFS)",
|
||||
"nfs": "Network File System (NFS)",
|
||||
"cifs": "Samba/Windows (CIFS)"
|
||||
},
|
||||
"cifs_versions": {
|
||||
@ -5884,7 +5888,7 @@
|
||||
},
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"show_header_toggle": "Show header toggle?",
|
||||
"show_header_toggle": "Show header toggle",
|
||||
"toggle": "Toggle entities.",
|
||||
"description": "The Entities card is the most common type of card. It groups items together into lists.",
|
||||
"special_row": "special row",
|
||||
@ -5931,9 +5935,9 @@
|
||||
},
|
||||
"gauge": {
|
||||
"name": "Gauge",
|
||||
"needle_gauge": "Display as needle gauge?",
|
||||
"needle_gauge": "Display as needle gauge",
|
||||
"severity": {
|
||||
"define": "Define severity?",
|
||||
"define": "Define severity",
|
||||
"green": "Green",
|
||||
"red": "Red",
|
||||
"yellow": "Yellow"
|
||||
@ -6067,7 +6071,7 @@
|
||||
"state": "State",
|
||||
"secondary_info_attribute": "Secondary info attribute",
|
||||
"search": "Search",
|
||||
"state_color": "Color icons based on state?",
|
||||
"state_color": "Show state color",
|
||||
"suggested_cards": "Suggested cards",
|
||||
"other_cards": "Other cards",
|
||||
"custom_cards": "Custom cards",
|
||||
@ -6104,7 +6108,6 @@
|
||||
"name": "Map",
|
||||
"geo_location_sources": "Geolocation sources",
|
||||
"no_geo_location_sources": "No geolocation sources available",
|
||||
"dark_mode": "Dark mode?",
|
||||
"appearance": "Appearance",
|
||||
"theme_mode": "Theme Mode",
|
||||
"theme_modes": {
|
||||
@ -7203,6 +7206,7 @@
|
||||
},
|
||||
"create_account": "Create account",
|
||||
"error": {
|
||||
"username_not_normalized": "Username can only contain lowercase letters, and can not contain whitespace.",
|
||||
"password_not_match": "Passwords don't match"
|
||||
}
|
||||
},
|
||||
@ -7372,6 +7376,7 @@
|
||||
},
|
||||
"dashboard": {
|
||||
"changelog": "Changelog",
|
||||
"current_version": "Current version: {version}",
|
||||
"cpu_usage": "Add-on CPU usage",
|
||||
"ram_usage": "Add-on RAM usage",
|
||||
"hostname": "Hostname",
|
||||
@ -7472,7 +7477,7 @@
|
||||
},
|
||||
"watchdog": {
|
||||
"title": "Watchdog",
|
||||
"description": "This will start the add-on if it crashes"
|
||||
"description": "This will restart the add-on if it crashes"
|
||||
},
|
||||
"auto_update": {
|
||||
"title": "Auto update",
|
||||
|
168
yarn.lock
@ -1265,9 +1265,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/autocomplete@npm:6.18.1":
|
||||
version: 6.18.1
|
||||
resolution: "@codemirror/autocomplete@npm:6.18.1"
|
||||
"@codemirror/autocomplete@npm:6.18.2":
|
||||
version: 6.18.2
|
||||
resolution: "@codemirror/autocomplete@npm:6.18.2"
|
||||
dependencies:
|
||||
"@codemirror/language": "npm:^6.0.0"
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
@ -1278,7 +1278,7 @@ __metadata:
|
||||
"@codemirror/state": ^6.0.0
|
||||
"@codemirror/view": ^6.0.0
|
||||
"@lezer/common": ^1.0.0
|
||||
checksum: 10/3b56ac6c57214e3e50c6ed79c12ac1822e3774afb033e0e4fb98dffd252f5ae64e5bed67dc2ad9cbd5d784373031be90995ddb1b36a10c16a2eef6af832041e2
|
||||
checksum: 10/35bd17afb53e8c99b1342964616f0bcc13f5f06a5d4e2d9936afdaea61742b1c20b3856d513c5d5676e3a9b6fd95e997c842467d21dfa106845e65ab1720b2f4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -1317,14 +1317,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/search@npm:6.5.6":
|
||||
version: 6.5.6
|
||||
resolution: "@codemirror/search@npm:6.5.6"
|
||||
"@codemirror/search@npm:6.5.7":
|
||||
version: 6.5.7
|
||||
resolution: "@codemirror/search@npm:6.5.7"
|
||||
dependencies:
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@codemirror/view": "npm:^6.0.0"
|
||||
crelt: "npm:^1.0.5"
|
||||
checksum: 10/6668a34b4617e909617d3d831627d74b7a7985e8cd86d396bfcb3e86262f2310fc029fd6c846f1b8f1e6768e75985c9f1b0b18b31e05341f06b5b75c1ffde38d
|
||||
checksum: 10/0a4c5e23c42231ffb829513940ee43a630585b4277fa8cc919a947f3821c9c2dc095d334bb0e4d51b3ebb50739a34a81ddbcc39ca9c1f6f935fdaa51a86661bf
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -3944,7 +3944,27 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.5":
|
||||
"@types/eslint-scope@npm:^3.7.7":
|
||||
version: 3.7.7
|
||||
resolution: "@types/eslint-scope@npm:3.7.7"
|
||||
dependencies:
|
||||
"@types/eslint": "npm:*"
|
||||
"@types/estree": "npm:*"
|
||||
checksum: 10/e2889a124aaab0b89af1bab5959847c5bec09809209255de0e63b9f54c629a94781daa04adb66bffcdd742f5e25a17614fb933965093c0eea64aacda4309380e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/eslint@npm:*":
|
||||
version: 9.6.1
|
||||
resolution: "@types/eslint@npm:9.6.1"
|
||||
dependencies:
|
||||
"@types/estree": "npm:*"
|
||||
"@types/json-schema": "npm:*"
|
||||
checksum: 10/719fcd255760168a43d0e306ef87548e1e15bffe361d5f4022b0f266575637acc0ecb85604ac97879ee8ae83c6a6d0613b0ed31d0209ddf22a0fe6d608fc56fe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
|
||||
version: 1.0.6
|
||||
resolution: "@types/estree@npm:1.0.6"
|
||||
checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d
|
||||
@ -4090,7 +4110,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9":
|
||||
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9":
|
||||
version: 7.0.15
|
||||
resolution: "@types/json-schema@npm:7.0.15"
|
||||
checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7
|
||||
@ -5187,15 +5207,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn-import-attributes@npm:^1.9.5":
|
||||
version: 1.9.5
|
||||
resolution: "acorn-import-attributes@npm:1.9.5"
|
||||
peerDependencies:
|
||||
acorn: ^8
|
||||
checksum: 10/8bfbfbb6e2467b9b47abb4d095df717ab64fce2525da65eabee073e85e7975fb3a176b6c8bba17c99a7d8ede283a10a590272304eb54a93c4aa1af9790d47a8b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn-jsx@npm:^5.3.2":
|
||||
version: 5.3.2
|
||||
resolution: "acorn-jsx@npm:5.3.2"
|
||||
@ -5205,12 +5216,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"acorn@npm:^8.5.0, acorn@npm:^8.7.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0":
|
||||
version: 8.13.0
|
||||
resolution: "acorn@npm:8.13.0"
|
||||
"acorn@npm:^8.14.0, acorn@npm:^8.5.0, acorn@npm:^8.8.2, acorn@npm:^8.9.0":
|
||||
version: 8.14.0
|
||||
resolution: "acorn@npm:8.14.0"
|
||||
bin:
|
||||
acorn: bin/acorn
|
||||
checksum: 10/33e3a03114b02b3bc5009463b3d9549b31a90ee38ebccd5e66515830a02acf62a90edcc12abfb6c9fb3837b6c17a3ec9b72b3bf52ac31d8ad8248a4af871e0f5
|
||||
checksum: 10/6df29c35556782ca9e632db461a7f97947772c6c1d5438a81f0c873a3da3a792487e83e404d1c6c25f70513e91aa18745f6eafb1fcc3a43ecd1920b21dd173d2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -5881,7 +5892,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"browserslist@npm:^4.21.10, browserslist@npm:^4.23.3, browserslist@npm:^4.24.0":
|
||||
"browserslist@npm:^4.23.3, browserslist@npm:^4.24.0":
|
||||
version: 4.24.0
|
||||
resolution: "browserslist@npm:4.24.0"
|
||||
dependencies:
|
||||
@ -6540,10 +6551,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"core-js@npm:3.38.1":
|
||||
version: 3.38.1
|
||||
resolution: "core-js@npm:3.38.1"
|
||||
checksum: 10/3c25fdf0b2595ed37ceb305213a61e2cf26185f628455e99d1c736dda5f69e2de4de7126e6a1da136f54260c4fcc982c4215e37b5a618790a597930f854c0a37
|
||||
"core-js@npm:3.39.0":
|
||||
version: 3.39.0
|
||||
resolution: "core-js@npm:3.39.0"
|
||||
checksum: 10/a3d34e669783dfc878e545f1983f60d9ff48a3867cd1d7ff8839b849e053002a208c7c14a5ca354b8e0b54982901e2f83dc87c3d9b95de0a94b4071d1c74e5f6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -8716,11 +8727,11 @@ __metadata:
|
||||
"@babel/runtime": "npm:7.26.0"
|
||||
"@braintree/sanitize-url": "npm:7.1.0"
|
||||
"@bundle-stats/plugin-webpack-filter": "npm:4.16.0"
|
||||
"@codemirror/autocomplete": "npm:6.18.1"
|
||||
"@codemirror/autocomplete": "npm:6.18.2"
|
||||
"@codemirror/commands": "npm:6.7.1"
|
||||
"@codemirror/language": "npm:6.10.3"
|
||||
"@codemirror/legacy-modes": "npm:6.4.1"
|
||||
"@codemirror/search": "npm:6.5.6"
|
||||
"@codemirror/search": "npm:6.5.7"
|
||||
"@codemirror/state": "npm:6.4.1"
|
||||
"@codemirror/view": "npm:6.34.1"
|
||||
"@egjs/hammerjs": "npm:2.0.17"
|
||||
@ -8827,7 +8838,7 @@ __metadata:
|
||||
chart.js: "npm:4.4.6"
|
||||
color-name: "npm:2.0.0"
|
||||
comlink: "npm:4.4.1"
|
||||
core-js: "npm:3.38.1"
|
||||
core-js: "npm:3.39.0"
|
||||
cropperjs: "npm:1.6.2"
|
||||
date-fns: "npm:4.1.0"
|
||||
date-fns-tz: "npm:3.2.0"
|
||||
@ -8877,7 +8888,7 @@ __metadata:
|
||||
map-stream: "npm:0.0.7"
|
||||
marked: "npm:14.1.3"
|
||||
memoize-one: "npm:6.0.0"
|
||||
mocha: "npm:10.7.3"
|
||||
mocha: "npm:10.8.2"
|
||||
node-vibrant: "npm:3.2.1-alpha.1"
|
||||
object-hash: "npm:3.0.0"
|
||||
open: "npm:10.1.0"
|
||||
@ -8913,7 +8924,7 @@ __metadata:
|
||||
vis-network: "npm:9.1.9"
|
||||
vue: "npm:2.7.16"
|
||||
vue2-daterange-picker: "npm:0.6.8"
|
||||
webpack: "npm:5.95.0"
|
||||
webpack: "npm:5.96.1"
|
||||
webpack-cli: "npm:5.1.4"
|
||||
webpack-dev-server: "npm:5.1.0"
|
||||
webpack-manifest-plugin: "npm:5.0.0"
|
||||
@ -8921,12 +8932,12 @@ __metadata:
|
||||
webpackbar: "npm:6.0.1"
|
||||
weekstart: "npm:2.0.0"
|
||||
workbox-build: "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch"
|
||||
workbox-cacheable-response: "npm:7.1.0"
|
||||
workbox-core: "npm:7.1.0"
|
||||
workbox-expiration: "npm:7.1.0"
|
||||
workbox-precaching: "npm:7.1.0"
|
||||
workbox-routing: "npm:7.1.0"
|
||||
workbox-strategies: "npm:7.1.0"
|
||||
workbox-cacheable-response: "npm:7.3.0"
|
||||
workbox-core: "npm:7.3.0"
|
||||
workbox-expiration: "npm:7.3.0"
|
||||
workbox-precaching: "npm:7.3.0"
|
||||
workbox-routing: "npm:7.3.0"
|
||||
workbox-strategies: "npm:7.3.0"
|
||||
xss: "npm:1.0.15"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
@ -10966,9 +10977,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mocha@npm:10.7.3":
|
||||
version: 10.7.3
|
||||
resolution: "mocha@npm:10.7.3"
|
||||
"mocha@npm:10.8.2":
|
||||
version: 10.8.2
|
||||
resolution: "mocha@npm:10.8.2"
|
||||
dependencies:
|
||||
ansi-colors: "npm:^4.1.3"
|
||||
browser-stdout: "npm:^1.3.1"
|
||||
@ -10993,7 +11004,7 @@ __metadata:
|
||||
bin:
|
||||
_mocha: bin/_mocha
|
||||
mocha: bin/mocha.js
|
||||
checksum: 10/5757aeb320df2507338bfba41731070ce16d27177c5876672fff4bcc4f7b7bcf1afe6ec761bfded43a5d28032d7b797b8b905b5b44c9420203f3ee71457732c1
|
||||
checksum: 10/903bbffcb195ef9d36b27db54e3462c5486de1397289e0953735b3530397a139336c452bcf5188c663496c660d2285bbb6c7213290d36d536ad647b6145cb917
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -14678,17 +14689,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"webpack@npm:5.95.0":
|
||||
version: 5.95.0
|
||||
resolution: "webpack@npm:5.95.0"
|
||||
"webpack@npm:5.96.1":
|
||||
version: 5.96.1
|
||||
resolution: "webpack@npm:5.96.1"
|
||||
dependencies:
|
||||
"@types/estree": "npm:^1.0.5"
|
||||
"@types/eslint-scope": "npm:^3.7.7"
|
||||
"@types/estree": "npm:^1.0.6"
|
||||
"@webassemblyjs/ast": "npm:^1.12.1"
|
||||
"@webassemblyjs/wasm-edit": "npm:^1.12.1"
|
||||
"@webassemblyjs/wasm-parser": "npm:^1.12.1"
|
||||
acorn: "npm:^8.7.1"
|
||||
acorn-import-attributes: "npm:^1.9.5"
|
||||
browserslist: "npm:^4.21.10"
|
||||
acorn: "npm:^8.14.0"
|
||||
browserslist: "npm:^4.24.0"
|
||||
chrome-trace-event: "npm:^1.0.2"
|
||||
enhanced-resolve: "npm:^5.17.1"
|
||||
es-module-lexer: "npm:^1.2.1"
|
||||
@ -14710,7 +14721,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
webpack: bin/webpack.js
|
||||
checksum: 10/0377ad3a550b041f26237c96fb55754625b0ce6bae83c1c2447e3262ad056b0b0ad770dcbb92b59f188e9a2bd56155ce910add17dcf023cfbe78bdec774380c1
|
||||
checksum: 10/d3419ffd198252e1d0301bd0c072cee93172f3e47937c745aa8202691d2f5d529d4ba4a1965d1450ad89a1bcd3c1f70ae09e57232b0d01dd38d69c1060e964d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -14990,6 +15001,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-cacheable-response@npm:7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "workbox-cacheable-response@npm:7.3.0"
|
||||
dependencies:
|
||||
workbox-core: "npm:7.3.0"
|
||||
checksum: 10/44cd7bc26e509ca96b1b84e3ff5964296efa645853f114f39789d21c0a214ca5fc047259910b303e220bb4052155cddc5639993fcee076fac496b4895ff17a15
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-core@npm:7.1.0":
|
||||
version: 7.1.0
|
||||
resolution: "workbox-core@npm:7.1.0"
|
||||
@ -14997,6 +15017,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-core@npm:7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "workbox-core@npm:7.3.0"
|
||||
checksum: 10/228fb7018a0568c329e21d47d84980f93ebfef9b1eb3f40ddc3516ca6ae58d51dc7ca4dddc829332775b59a3079e62d105c5e1c5c312805d177b963f8bf54393
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-expiration@npm:7.1.0":
|
||||
version: 7.1.0
|
||||
resolution: "workbox-expiration@npm:7.1.0"
|
||||
@ -15007,6 +15034,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-expiration@npm:7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "workbox-expiration@npm:7.3.0"
|
||||
dependencies:
|
||||
idb: "npm:^7.0.1"
|
||||
workbox-core: "npm:7.3.0"
|
||||
checksum: 10/83e021d700e521a65a89907679d1a580aacc0419428286910ec7c6b0a538326f71f05566434f666ebf6c9fbe819ef3ea81428df1d868f9ea92527afe5d11152d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-google-analytics@npm:7.1.0":
|
||||
version: 7.1.0
|
||||
resolution: "workbox-google-analytics@npm:7.1.0"
|
||||
@ -15039,6 +15076,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-precaching@npm:7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "workbox-precaching@npm:7.3.0"
|
||||
dependencies:
|
||||
workbox-core: "npm:7.3.0"
|
||||
workbox-routing: "npm:7.3.0"
|
||||
workbox-strategies: "npm:7.3.0"
|
||||
checksum: 10/d14135c471a45de36438c40eed7cb7157cdb336d4216a775486c6307d1ac316794d64231c2e2d0a4c313bb4a4fec623ab77e391cc458b4f2afa64e2487acb2e8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-range-requests@npm:7.1.0":
|
||||
version: 7.1.0
|
||||
resolution: "workbox-range-requests@npm:7.1.0"
|
||||
@ -15071,6 +15119,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-routing@npm:7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "workbox-routing@npm:7.3.0"
|
||||
dependencies:
|
||||
workbox-core: "npm:7.3.0"
|
||||
checksum: 10/0d729f9c5cfc5754404ac1f7b729c7740ddc806203792701ac642151fbec939b4aa0fb289eab2295e49180e8154ad9bb1380effb7e0f0362163b79db4291dba7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-strategies@npm:7.1.0":
|
||||
version: 7.1.0
|
||||
resolution: "workbox-strategies@npm:7.1.0"
|
||||
@ -15080,6 +15137,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-strategies@npm:7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "workbox-strategies@npm:7.3.0"
|
||||
dependencies:
|
||||
workbox-core: "npm:7.3.0"
|
||||
checksum: 10/61ba672075ef8aaa70ad9221460dab80a7d8920e324e14137460f26ebe8b137e5589fb75c664e0efeaf4402e3d8435a9b1818f9a9c61f88863c0e0315af337e7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"workbox-streams@npm:7.1.0":
|
||||
version: 7.1.0
|
||||
resolution: "workbox-streams@npm:7.1.0"
|
||||
|