mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
20231205.0 (#18916)
This commit is contained in:
commit
eb5e7ba3f3
@ -39,7 +39,9 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
<div class="picker">
|
||||
<div class="label">
|
||||
${this._switching
|
||||
? html`<ha-circular-progress active></ha-circular-progress>`
|
||||
? html`<ha-circular-progress
|
||||
indeterminate
|
||||
></ha-circular-progress>`
|
||||
: until(
|
||||
selectedDemoConfig.then(
|
||||
(conf) => html`
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
title: Circular Progress
|
||||
subtitle: Can be used to indicate an ongoing task.
|
||||
---
|
64
gallery/src/pages/components/ha-circular-progress.ts
Normal file
64
gallery/src/pages/components/ha-circular-progress.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { html, css, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-bar";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import "@material/web/progress/circular-progress";
|
||||
import { HomeAssistant } from "../../../../src/types";
|
||||
|
||||
@customElement("demo-components-ha-circular-progress")
|
||||
export class DemoHaCircularProgress extends LitElement {
|
||||
@property({ attribute: false }) hass!: HomeAssistant;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`<ha-card header="Basic circular progress">
|
||||
<div class="card-content">
|
||||
<ha-circular-progress indeterminate></ha-circular-progress></div
|
||||
></ha-card>
|
||||
<ha-card header="Different circular progress sizes">
|
||||
<div class="card-content">
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="tiny"
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="medium"
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="large"
|
||||
></ha-circular-progress></div
|
||||
></ha-card>
|
||||
<ha-card header="Circular progress with an aria-label">
|
||||
<div class="card-content">
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
aria-label="Doing something..."
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
.ariaLabel=${"Doing something..."}
|
||||
></ha-circular-progress></div
|
||||
></ha-card>`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-card {
|
||||
max-width: 600px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"demo-components-ha-circular-progress": DemoHaCircularProgress;
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ class HassioAddonConfigDashboard extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.addon) {
|
||||
return html`<ha-circular-progress active></ha-circular-progress>`;
|
||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
||||
}
|
||||
const hasConfiguration =
|
||||
(this.addon.options && Object.keys(this.addon.options).length) ||
|
||||
|
@ -34,7 +34,7 @@ class HassioAddonDocumentationDashboard extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.addon) {
|
||||
return html`<ha-circular-progress active></ha-circular-progress>`;
|
||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
||||
}
|
||||
return html`
|
||||
<div class="content">
|
||||
|
@ -22,7 +22,7 @@ class HassioAddonInfoDashboard extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.addon) {
|
||||
return html`<ha-circular-progress active></ha-circular-progress>`;
|
||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
||||
}
|
||||
|
||||
return html`
|
||||
|
@ -18,7 +18,9 @@ class HassioAddonLogDashboard extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.addon) {
|
||||
return html` <ha-circular-progress active></ha-circular-progress> `;
|
||||
return html`
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<div class="content">
|
||||
|
@ -95,7 +95,7 @@ class HassioBackupDialog
|
||||
</ha-header-bar>
|
||||
</div>
|
||||
${this._restoringBackup
|
||||
? html`<ha-circular-progress active></ha-circular-progress>`
|
||||
? html`<ha-circular-progress indeterminate></ha-circular-progress>`
|
||||
: html`
|
||||
<supervisor-backup-content
|
||||
.hass=${this.hass}
|
||||
|
@ -57,7 +57,7 @@ class HassioCreateBackupDialog extends LitElement {
|
||||
)}
|
||||
>
|
||||
${this._creatingBackup
|
||||
? html`<ha-circular-progress active></ha-circular-progress>`
|
||||
? html`<ha-circular-progress indeterminate></ha-circular-progress>`
|
||||
: html`<supervisor-backup-content
|
||||
.hass=${this.hass}
|
||||
.supervisor=${this._dialogParams.supervisor}
|
||||
|
@ -71,7 +71,11 @@ class HassioDatadiskDialog extends LitElement {
|
||||
?hideActions=${this.moving}
|
||||
>
|
||||
${this.moving
|
||||
? html` <ha-circular-progress alt="Moving" size="large" active>
|
||||
? html` <ha-circular-progress
|
||||
aria-label="Moving"
|
||||
size="large"
|
||||
indeterminate
|
||||
>
|
||||
</ha-circular-progress>
|
||||
<p class="progress-text">
|
||||
${this.dialogParams.supervisor.localize(
|
||||
|
@ -155,7 +155,11 @@ export class DialogHassioNetwork
|
||||
.disabled=${this._scanning}
|
||||
>
|
||||
${this._scanning
|
||||
? html`<ha-circular-progress active size="small">
|
||||
? html`<ha-circular-progress
|
||||
aria-label="Scanning"
|
||||
indeterminate
|
||||
size="small"
|
||||
>
|
||||
</ha-circular-progress>`
|
||||
: this.supervisor.localize("dialog.network.scan_ap")}
|
||||
</mwc-button>
|
||||
@ -274,7 +278,7 @@ export class DialogHassioNetwork
|
||||
</mwc-button>
|
||||
<mwc-button @click=${this._updateNetwork} .disabled=${!this._dirty}>
|
||||
${this._processing
|
||||
? html`<ha-circular-progress active size="small">
|
||||
? html`<ha-circular-progress indeterminate size="small">
|
||||
</ha-circular-progress>`
|
||||
: this.supervisor.localize("common.save")}
|
||||
</mwc-button>
|
||||
|
@ -158,7 +158,7 @@ class HassioRepositoriesDialog extends LitElement {
|
||||
<mwc-button @click=${this._addRepository}>
|
||||
${this._processing
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
></ha-circular-progress>`
|
||||
: this._dialogParams!.supervisor.localize(
|
||||
|
@ -174,7 +174,11 @@ class UpdateAvailableCard extends LitElement {
|
||||
`
|
||||
: ""}
|
||||
`
|
||||
: html`<ha-circular-progress alt="Updating" size="large" active>
|
||||
: html`<ha-circular-progress
|
||||
aria-label="Updating"
|
||||
size="large"
|
||||
indeterminate
|
||||
>
|
||||
</ha-circular-progress>
|
||||
<p class="progress-text">
|
||||
${this.supervisor.localize("update_available.updating", {
|
||||
|
12
package.json
12
package.json
@ -60,7 +60,6 @@
|
||||
"@material/mwc-base": "0.27.0",
|
||||
"@material/mwc-button": "0.27.0",
|
||||
"@material/mwc-checkbox": "0.27.0",
|
||||
"@material/mwc-circular-progress": "0.27.0",
|
||||
"@material/mwc-dialog": "0.27.0",
|
||||
"@material/mwc-drawer": "0.27.0",
|
||||
"@material/mwc-fab": "0.27.0",
|
||||
@ -91,8 +90,8 @@
|
||||
"@polymer/paper-toast": "3.0.1",
|
||||
"@polymer/polymer": "3.5.1",
|
||||
"@thomasloven/round-slider": "0.6.0",
|
||||
"@vaadin/combo-box": "24.2.4",
|
||||
"@vaadin/vaadin-themable-mixin": "24.2.4",
|
||||
"@vaadin/combo-box": "24.2.5",
|
||||
"@vaadin/vaadin-themable-mixin": "24.2.5",
|
||||
"@vibrant/color": "3.2.1-alpha.1",
|
||||
"@vibrant/core": "3.2.1-alpha.1",
|
||||
"@vibrant/quantizer-mmcq": "3.2.1-alpha.1",
|
||||
@ -120,14 +119,13 @@
|
||||
"leaflet-draw": "1.0.4",
|
||||
"lit": "2.8.0",
|
||||
"luxon": "3.4.4",
|
||||
"marked": "10.0.0",
|
||||
"marked": "11.0.0",
|
||||
"memoize-one": "6.0.0",
|
||||
"node-vibrant": "3.2.1-alpha.1",
|
||||
"proxy-polyfill": "0.3.2",
|
||||
"punycode": "2.3.1",
|
||||
"qr-scanner": "1.4.2",
|
||||
"qrcode": "1.5.3",
|
||||
"resize-observer-polyfill": "1.5.1",
|
||||
"roboto-fontface": "0.10.0",
|
||||
"rrule": "2.8.1",
|
||||
"sortablejs": "1.15.1",
|
||||
@ -194,7 +192,7 @@
|
||||
"babel-plugin-template-html-minifier": "4.1.0",
|
||||
"chai": "4.3.10",
|
||||
"del": "7.1.0",
|
||||
"eslint": "8.54.0",
|
||||
"eslint": "8.55.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-airbnb-typescript": "17.1.0",
|
||||
"eslint-config-prettier": "9.0.0",
|
||||
@ -206,7 +204,7 @@
|
||||
"eslint-plugin-unused-imports": "3.0.0",
|
||||
"eslint-plugin-wc": "2.0.4",
|
||||
"fancy-log": "2.0.0",
|
||||
"fs-extra": "11.1.1",
|
||||
"fs-extra": "11.2.0",
|
||||
"glob": "10.3.10",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-flatmap": "1.0.2",
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20231204.0"
|
||||
version = "20231205.0"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@ -45,7 +45,7 @@ export class HaProgressButton extends LitElement {
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
size="small"
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
`
|
||||
: ""}
|
||||
|
@ -469,6 +469,7 @@ export class HaChartBase extends LitElement {
|
||||
.chartTooltip li {
|
||||
display: flex;
|
||||
white-space: pre-line;
|
||||
word-break: break-word;
|
||||
align-items: center;
|
||||
line-height: 16px;
|
||||
padding: 4px 0;
|
||||
@ -476,6 +477,7 @@ export class HaChartBase extends LitElement {
|
||||
.chartTooltip .title {
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
word-break: break-word;
|
||||
direction: ltr;
|
||||
}
|
||||
.chartTooltip .footer {
|
||||
|
@ -1,54 +1,44 @@
|
||||
import { CircularProgress } from "@material/mwc-circular-progress";
|
||||
import { CSSResultGroup, css } from "lit";
|
||||
import "element-internals-polyfill";
|
||||
import { MdCircularProgress } from "@material/web/progress/circular-progress";
|
||||
import { CSSResult, PropertyValues, css } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
|
||||
@customElement("ha-circular-progress")
|
||||
// @ts-ignore
|
||||
export class HaCircularProgress extends CircularProgress {
|
||||
@property({ type: Boolean })
|
||||
public active = false;
|
||||
export class HaCircularProgress extends MdCircularProgress {
|
||||
@property({ attribute: "aria-label", type: String }) public ariaLabel =
|
||||
"Loading";
|
||||
|
||||
@property()
|
||||
public alt = "Loading";
|
||||
@property() public size: "tiny" | "small" | "medium" | "large" = "medium";
|
||||
|
||||
@property()
|
||||
public size: "tiny" | "small" | "medium" | "large" = "medium";
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
|
||||
// @ts-ignore
|
||||
public set density(_) {
|
||||
// just a dummy
|
||||
}
|
||||
|
||||
public get density() {
|
||||
switch (this.size) {
|
||||
case "tiny":
|
||||
return -8;
|
||||
case "small":
|
||||
return -5;
|
||||
case "medium":
|
||||
return 0;
|
||||
case "large":
|
||||
return 5;
|
||||
default:
|
||||
return 0;
|
||||
if (changedProps.has("size")) {
|
||||
switch (this.size) {
|
||||
case "tiny":
|
||||
this.style.setProperty("--md-circular-progress-size", "16px");
|
||||
break;
|
||||
case "small":
|
||||
this.style.setProperty("--md-circular-progress-size", "28px");
|
||||
break;
|
||||
// medium is default size
|
||||
case "medium":
|
||||
this.style.setProperty("--md-circular-progress-size", "48px");
|
||||
break;
|
||||
case "large":
|
||||
this.style.setProperty("--md-circular-progress-size", "68px");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
public set indeterminate(_) {
|
||||
// just a dummy
|
||||
}
|
||||
|
||||
public get indeterminate() {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
super.styles,
|
||||
...super.styles,
|
||||
css`
|
||||
:host {
|
||||
overflow: hidden;
|
||||
--md-sys-color-primary: var(--primary-color);
|
||||
--md-circular-progress-size: 48px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -618,6 +618,7 @@ export class HaControlCircularSlider extends LitElement {
|
||||
--control-circular-slider-high-color: var(
|
||||
--control-circular-slider-color
|
||||
);
|
||||
--control-circular-slider-interaction-margin: 12px;
|
||||
width: 320px;
|
||||
display: block;
|
||||
}
|
||||
@ -633,7 +634,9 @@ export class HaControlCircularSlider extends LitElement {
|
||||
fill: none;
|
||||
stroke: transparent;
|
||||
stroke-linecap: round;
|
||||
stroke-width: 48px;
|
||||
stroke-width: calc(
|
||||
24px + 2 * var(--control-circular-slider-interaction-margin)
|
||||
);
|
||||
cursor: pointer;
|
||||
}
|
||||
#display {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import { mdiMinus, mdiPlus } from "@mdi/js";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
@ -49,6 +50,13 @@ export class HaControlNumberButton extends LitElement {
|
||||
|
||||
@query("#input") _input!: HTMLDivElement;
|
||||
|
||||
private _hideUnit = new ResizeController(this, {
|
||||
callback: (entries) => {
|
||||
const width = entries[0]?.contentRect.width;
|
||||
return width < 100;
|
||||
},
|
||||
});
|
||||
|
||||
private boundedValue(value: number) {
|
||||
const clamped = conditionalClamp(value, this.min, this.max);
|
||||
return Math.round(clamped / this._step) * this._step;
|
||||
@ -145,7 +153,10 @@ export class HaControlNumberButton extends LitElement {
|
||||
?disabled=${this.disabled}
|
||||
@keydown=${this._handleKeyDown}
|
||||
>
|
||||
${value} ${unit ? html`<span class="unit">${unit}</span>` : nothing}
|
||||
${value}
|
||||
${unit && !this._hideUnit.value
|
||||
? html`<span class="unit">${unit}</span>`
|
||||
: nothing}
|
||||
</div>
|
||||
<button
|
||||
class="button minus"
|
||||
|
@ -6,6 +6,11 @@ import { MdOutlinedIconButton } from "@material/web/iconbutton/outlined-icon-but
|
||||
@customElement("ha-outlined-icon-button")
|
||||
export class HaOutlinedIconButton extends MdOutlinedIconButton {
|
||||
static override styles = [
|
||||
css`
|
||||
.icon-button {
|
||||
border-radius: var(--_container-shape);
|
||||
}
|
||||
`,
|
||||
...super.styles,
|
||||
css`
|
||||
:host {
|
||||
|
@ -1,9 +1,19 @@
|
||||
import { DEFAULT_SCHEMA, dump, load, Schema } from "js-yaml";
|
||||
import { html, LitElement, nothing, PropertyValues } from "lit";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
css,
|
||||
html,
|
||||
LitElement,
|
||||
nothing,
|
||||
PropertyValues,
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import { haStyle } from "../resources/styles";
|
||||
import "./ha-code-editor";
|
||||
import { showToast } from "../util/toast";
|
||||
import { copyToClipboard } from "../common/util/copy-clipboard";
|
||||
|
||||
const isEmpty = (obj: Record<string, unknown>): boolean => {
|
||||
if (typeof obj !== "object") {
|
||||
@ -37,6 +47,8 @@ export class HaYamlEditor extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public required = false;
|
||||
|
||||
@property({ type: Boolean }) public copyClipboard = false;
|
||||
|
||||
@state() private _yaml = "";
|
||||
|
||||
public setValue(value): void {
|
||||
@ -88,6 +100,15 @@ export class HaYamlEditor extends LitElement {
|
||||
@value-changed=${this._onChange}
|
||||
dir="ltr"
|
||||
></ha-code-editor>
|
||||
${this.copyClipboard
|
||||
? html`<div class="card-actions">
|
||||
<mwc-button @click=${this._copyYaml}>
|
||||
${this.hass.localize(
|
||||
"ui.components.yaml-editor.copy_to_clipboard"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>`
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
@ -117,6 +138,35 @@ export class HaYamlEditor extends LitElement {
|
||||
get yaml() {
|
||||
return this._yaml;
|
||||
}
|
||||
|
||||
private async _copyYaml(): Promise<void> {
|
||||
if (this.yaml) {
|
||||
await copyToClipboard(this.yaml);
|
||||
showToast(this, {
|
||||
message: this.hass.localize("ui.common.copied_clipboard"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
.card-actions {
|
||||
border-radius: var(
|
||||
--actions-border-radius,
|
||||
0px 0px var(--ha-card-border-radius, 12px)
|
||||
var(--ha-card-border-radius, 12px)
|
||||
);
|
||||
border: 1px solid var(--divider-color);
|
||||
padding: 5px 16px;
|
||||
}
|
||||
ha-code-editor {
|
||||
flex-grow: 1;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -147,7 +147,7 @@ class DialogMediaManage extends LitElement {
|
||||
${!this._currentItem
|
||||
? html`
|
||||
<div class="refresh">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
: !children.length
|
||||
|
@ -332,7 +332,7 @@ export class HaMediaPlayerBrowse extends LitElement {
|
||||
}
|
||||
|
||||
if (!this._currentItem) {
|
||||
return html`<ha-circular-progress active></ha-circular-progress>`;
|
||||
return html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
||||
}
|
||||
|
||||
const currentItem = this._currentItem;
|
||||
|
@ -54,8 +54,8 @@ class MediaUploadButton extends LitElement {
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
size="tiny"
|
||||
active
|
||||
alt=""
|
||||
indeterminate
|
||||
area-label="Uploading"
|
||||
slot="icon"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
|
@ -2,6 +2,7 @@ import {
|
||||
HassEntityAttributeBase,
|
||||
HassEntityBase,
|
||||
} from "home-assistant-js-websocket";
|
||||
import { getExtendedEntityRegistryEntry } from "./entity_registry";
|
||||
import { showEnterCodeDialogDialog } from "../dialogs/enter-code/show-enter-code-dialog";
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
@ -30,15 +31,20 @@ export const callProtectedLockService = async (
|
||||
service: ProtectedLockService
|
||||
) => {
|
||||
let code: string | undefined;
|
||||
const lockRegistryEntry = await getExtendedEntityRegistryEntry(
|
||||
hass,
|
||||
stateObj.entity_id
|
||||
).catch(() => undefined);
|
||||
const defaultCode = lockRegistryEntry?.options?.lock?.default_code;
|
||||
|
||||
if (stateObj!.attributes.code_format) {
|
||||
if (stateObj!.attributes.code_format && !defaultCode) {
|
||||
const response = await showEnterCodeDialogDialog(element, {
|
||||
codeFormat: "text",
|
||||
codePattern: stateObj!.attributes.code_format,
|
||||
title: hass.localize(`ui.card.lock.${service}`),
|
||||
submitText: hass.localize(`ui.card.lock.${service}`),
|
||||
});
|
||||
if (!response) {
|
||||
if (response == null) {
|
||||
throw new Error("Code dialog closed");
|
||||
}
|
||||
code = response;
|
||||
|
@ -207,7 +207,7 @@ export class DialogAreaFilter
|
||||
color: var(--disabled-text-color);
|
||||
}
|
||||
.handle {
|
||||
cursor: grab;
|
||||
cursor: move;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
|
@ -90,7 +90,7 @@ class StepFlowForm extends LitElement {
|
||||
${this._loading
|
||||
? html`
|
||||
<div class="submit-spinner">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
|
@ -27,7 +27,7 @@ class StepFlowLoading extends LitElement {
|
||||
return html`
|
||||
<div class="init-spinner">
|
||||
${description ? html`<div>${description}</div>` : ""}
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class StepFlowProgress extends LitElement {
|
||||
${this.flowConfig.renderShowFormProgressHeader(this.hass, this.step)}
|
||||
</h2>
|
||||
<div class="content">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
${this.flowConfig.renderShowFormProgressDescription(
|
||||
this.hass,
|
||||
this.step
|
||||
|
@ -99,6 +99,8 @@ export class DialogEnterCode
|
||||
id="code"
|
||||
.label=${this.hass.localize("ui.dialogs.enter_code.input_label")}
|
||||
type="password"
|
||||
autoValidate
|
||||
validateOnInitialRender
|
||||
pattern=${ifDefined(this._dialogParams.codePattern)}
|
||||
inputmode="text"
|
||||
></ha-textfield>
|
||||
|
@ -53,8 +53,8 @@ export class MoreInfoConfigurator extends LitElement {
|
||||
>
|
||||
${this._isConfiguring
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
alt="Configuring"
|
||||
indeterminate
|
||||
aria-label="Configuring"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
${this.stateObj.attributes.submit_caption}
|
||||
|
@ -104,7 +104,7 @@ class MoreInfoUpdate extends LitElement {
|
||||
${supportsFeature(this.stateObj!, UPDATE_SUPPORT_RELEASE_NOTES) &&
|
||||
!this._error
|
||||
? this._releaseNotes === undefined
|
||||
? html`<ha-circular-progress active></ha-circular-progress>`
|
||||
? html`<ha-circular-progress indeterminate></ha-circular-progress>`
|
||||
: html`<hr />
|
||||
<ha-faded>
|
||||
<ha-markdown .content=${this._releaseNotes}></ha-markdown>
|
||||
|
@ -214,7 +214,7 @@ export class QuickBar extends LitElement {
|
||||
${!items
|
||||
? html`<ha-circular-progress
|
||||
size="small"
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>`
|
||||
: items.length === 0
|
||||
? html`
|
||||
@ -375,7 +375,7 @@ export class QuickBar extends LitElement {
|
||||
const spinner = document.createElement("ha-circular-progress");
|
||||
spinner.size = "small";
|
||||
spinner.slot = "meta";
|
||||
spinner.active = true;
|
||||
spinner.indeterminate = true;
|
||||
this._getItemAtIndex(index)?.appendChild(spinner);
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ class DialogRestart extends LitElement {
|
||||
${this._loadingHostInfo
|
||||
? html`
|
||||
<div class="loader">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
|
@ -85,8 +85,7 @@ export class TTSTryDialog extends LitElement {
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
size="small"
|
||||
active
|
||||
alt=""
|
||||
indeterminate
|
||||
slot="primaryAction"
|
||||
class="loading"
|
||||
></ha-circular-progress>
|
||||
|
@ -35,7 +35,7 @@ class HaInitPage extends LitElement {
|
||||
`
|
||||
: html`
|
||||
<div id="progress-indicator-wrapper">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
<div id="loading-text">
|
||||
${this.migration
|
||||
|
@ -46,7 +46,7 @@ class HassLoadingScreen extends LitElement {
|
||||
`}
|
||||
</div>`}
|
||||
<div class="content">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
${this.message
|
||||
? html`<div id="loading-text">${this.message}</div>`
|
||||
: nothing}
|
||||
|
@ -57,7 +57,7 @@ class OnboardingCoreConfig extends LitElement {
|
||||
}
|
||||
if (this._skipCore) {
|
||||
return html`<div class="row center">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>`;
|
||||
}
|
||||
return html`
|
||||
|
@ -123,7 +123,7 @@ class OnboardingLocation extends LitElement {
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
slot="trailingIcon"
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
|
@ -64,8 +64,7 @@ class PanelCalendar extends LitElement {
|
||||
private _end?: Date;
|
||||
|
||||
private _showPaneController = new ResizeController(this, {
|
||||
callback: (entries: ResizeObserverEntry[]) =>
|
||||
entries[0]?.contentRect.width > 750,
|
||||
callback: (entries) => entries[0]?.contentRect.width > 750,
|
||||
});
|
||||
|
||||
private _mql?: MediaQueryList;
|
||||
|
@ -227,7 +227,7 @@ export class DialogAddApplicationCredential extends LitElement {
|
||||
${this._loading
|
||||
? html`
|
||||
<div slot="primaryAction" class="submit-spinner">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
|
@ -101,7 +101,7 @@ export class HaBlueprintAutomationEditor extends LitElement {
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.blueprint.no_blueprints"
|
||||
)
|
||||
: html`<ha-circular-progress active></ha-circular-progress>`}
|
||||
: html`<ha-circular-progress indeterminate></ha-circular-progress>`}
|
||||
</div>
|
||||
|
||||
${this.config.use_blueprint.path
|
||||
|
@ -25,19 +25,16 @@ import {
|
||||
html,
|
||||
nothing,
|
||||
} from "lit";
|
||||
import { property, query, state } from "lit/decorators";
|
||||
import { property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { copyToClipboard } from "../../../common/util/copy-clipboard";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-yaml-editor";
|
||||
import type { HaYamlEditor } from "../../../components/ha-yaml-editor";
|
||||
import {
|
||||
AutomationConfig,
|
||||
AutomationEntity,
|
||||
@ -112,8 +109,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
|
||||
@state() private _validationErrors?: (string | TemplateResult)[];
|
||||
|
||||
@query("ha-yaml-editor", true) private _yamlEditor?: HaYamlEditor;
|
||||
|
||||
private _configSubscriptions: Record<
|
||||
string,
|
||||
(config?: AutomationConfig) => void
|
||||
@ -342,8 +337,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
></manual-automation-editor>
|
||||
`
|
||||
: this._mode === "yaml"
|
||||
? html`
|
||||
${this._readOnly
|
||||
? html` ${this._readOnly
|
||||
? html`<ha-alert alert-type="warning">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.read_only"
|
||||
@ -376,22 +370,13 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
`
|
||||
: ""}
|
||||
<ha-yaml-editor
|
||||
copyClipboard
|
||||
.hass=${this.hass}
|
||||
.defaultValue=${this._preprocessYaml()}
|
||||
.readOnly=${this._readOnly}
|
||||
@value-changed=${this._yamlChanged}
|
||||
></ha-yaml-editor>
|
||||
<ha-card outlined>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._copyYaml}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.copy_to_clipboard"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: ``}
|
||||
></ha-yaml-editor>`
|
||||
: nothing}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
@ -612,15 +597,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
return cleanConfig;
|
||||
}
|
||||
|
||||
private async _copyYaml(): Promise<void> {
|
||||
if (this._yamlEditor?.yaml) {
|
||||
await copyToClipboard(this._yamlEditor.yaml);
|
||||
showToast(this, {
|
||||
message: this.hass.localize("ui.common.copied_clipboard"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _yamlChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
if (!ev.detail.isValid) {
|
||||
@ -776,9 +752,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
ha-card {
|
||||
overflow: hidden;
|
||||
}
|
||||
.content {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
@ -796,13 +769,11 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
}
|
||||
ha-yaml-editor {
|
||||
flex-grow: 1;
|
||||
--actions-border-radius: 0;
|
||||
--code-mirror-height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
.yaml-mode ha-card {
|
||||
overflow: initial;
|
||||
--ha-card-border-radius: 0;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
|
@ -158,7 +158,7 @@ class HaConfigBackup extends LitElement {
|
||||
${this._backupData.backing_up
|
||||
? html`<ha-circular-progress
|
||||
slot="icon"
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>`
|
||||
: html`<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>`}
|
||||
</ha-fab>
|
||||
|
@ -163,9 +163,9 @@ class DialogImportBlueprint extends LitElement {
|
||||
>
|
||||
${this._importing
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
.title=${this.hass.localize(
|
||||
.ariaLabel=${this.hass.localize(
|
||||
"ui.panel.config.blueprint.add.importing"
|
||||
)}
|
||||
></ha-circular-progress>`
|
||||
@ -183,9 +183,9 @@ class DialogImportBlueprint extends LitElement {
|
||||
>
|
||||
${this._saving
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
.title=${this.hass.localize(
|
||||
.ariaLabel=${this.hass.localize(
|
||||
"ui.panel.config.blueprint.add.saving"
|
||||
)}
|
||||
></ha-circular-progress>`
|
||||
|
@ -93,7 +93,7 @@ export class CloudWebhooks extends LitElement {
|
||||
? html`
|
||||
<div class="progress">
|
||||
<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
|
@ -108,7 +108,7 @@ class HaConfigUpdates extends SubscribeMixin(LitElement) {
|
||||
></state-badge>
|
||||
${this.narrow && entity.attributes.in_progress
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
slot="graphic"
|
||||
class="absolute"
|
||||
@ -128,7 +128,7 @@ class HaConfigUpdates extends SubscribeMixin(LitElement) {
|
||||
${!this.narrow
|
||||
? entity.attributes.in_progress
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
slot="meta"
|
||||
></ha-circular-progress>`
|
||||
|
@ -164,7 +164,9 @@ export class DialogHelperDetail extends LitElement {
|
||||
</mwc-button>
|
||||
`;
|
||||
} else if (this._loading || this._helperFlows === undefined) {
|
||||
content = html`<ha-circular-progress active></ha-circular-progress>`;
|
||||
content = html`<ha-circular-progress
|
||||
indeterminate
|
||||
></ha-circular-progress>`;
|
||||
} else {
|
||||
const items: [string, string][] = [];
|
||||
|
||||
|
@ -449,7 +449,7 @@ class AddIntegrationDialog extends LitElement {
|
||||
>
|
||||
</lit-virtualizer>
|
||||
</mwc-list>`
|
||||
: html`<ha-circular-progress active></ha-circular-progress>`} `;
|
||||
: html`<ha-circular-progress indeterminate></ha-circular-progress>`} `;
|
||||
}
|
||||
|
||||
private _keyFunction = (integration: IntegrationListItem) =>
|
||||
|
@ -57,7 +57,7 @@ class DialogMatterAddDevice extends LitElement {
|
||||
)
|
||||
: html`<ha-circular-progress
|
||||
size="large"
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>`}
|
||||
</div>
|
||||
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
|
||||
|
@ -102,7 +102,7 @@ class DialogZHAReconfigureDevice extends LitElement {
|
||||
${this._status === "started"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
<div class="status">
|
||||
<p>
|
||||
<b>
|
||||
|
@ -98,8 +98,8 @@ class ZHAAddDevicesPage extends LitElement {
|
||||
)}
|
||||
</h1>
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt="Searching"
|
||||
indeterminate
|
||||
aria-label="Searching"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
: html`
|
||||
|
@ -98,9 +98,9 @@ export class ZHAAddGroupPage extends LitElement {
|
||||
>
|
||||
${this._processingAdd
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
.title=${this.hass!.localize(
|
||||
.ariaLabel=${this.hass!.localize(
|
||||
"ui.panel.config.zha.groups.creating_group"
|
||||
)}
|
||||
></ha-circular-progress>`
|
||||
|
@ -120,9 +120,8 @@ class ZHADeviceNeighbors extends LitElement {
|
||||
return html`
|
||||
${!this._devices
|
||||
? html`<ha-circular-progress
|
||||
alt="Loading"
|
||||
size="large"
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>`
|
||||
: html`<ha-data-table
|
||||
.hass=${this.hass}
|
||||
|
@ -169,12 +169,14 @@ export class ZHAGroupPage extends LitElement {
|
||||
@click=${this._removeMembersFromGroup}
|
||||
class="button"
|
||||
>
|
||||
<ha-circular-progress
|
||||
?active=${this._processingRemove}
|
||||
alt=${this.hass.localize(
|
||||
"ui.panel.config.zha.groups.removing_members"
|
||||
)}
|
||||
></ha-circular-progress>
|
||||
${this._processingRemove
|
||||
? html`<ha-circular-progress
|
||||
indeterminate
|
||||
.ariaLabel=${this.hass.localize(
|
||||
"ui.panel.config.zha.groups.removing_members"
|
||||
)}
|
||||
></ha-circular-progress>`
|
||||
: nothing}
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.zha.groups.remove_members"
|
||||
)}</mwc-button
|
||||
@ -208,7 +210,7 @@ export class ZHAGroupPage extends LitElement {
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
size="small"
|
||||
title="Saving"
|
||||
aria-label="Saving"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
${this.hass!.localize(
|
||||
|
@ -116,7 +116,10 @@ class DialogZWaveJSAddNode extends LitElement {
|
||||
>
|
||||
${this._status === "loading"
|
||||
? html`<div style="display: flex; justify-content: center;">
|
||||
<ha-circular-progress size="large" active></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
size="large"
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
</div>`
|
||||
: this._status === "choose_strategy"
|
||||
? html`<h3>Choose strategy</h3>
|
||||
@ -288,7 +291,9 @@ class DialogZWaveJSAddNode extends LitElement {
|
||||
"ui.panel.config.zwave_js.add_node.searching_device"
|
||||
)}
|
||||
</h3>
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.add_node.follow_device_instructions"
|
||||
@ -304,7 +309,7 @@ class DialogZWaveJSAddNode extends LitElement {
|
||||
)}
|
||||
</h2>
|
||||
<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
@ -358,7 +363,7 @@ class DialogZWaveJSAddNode extends LitElement {
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
<div class="status">
|
||||
<p>
|
||||
|
@ -97,7 +97,7 @@ class DialogZWaveJSRebuildNodeRoutes extends LitElement {
|
||||
${this._status === "started"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
<div class="status">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
|
@ -68,7 +68,7 @@ class DialogZWaveJSReinterviewNode extends LitElement {
|
||||
${this._status === "started"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
<div class="status">
|
||||
<p>
|
||||
<b>
|
||||
|
@ -91,7 +91,7 @@ class DialogZWaveJSRemoveFailedNode extends LitElement {
|
||||
${this._status === "started"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
<div class="status">
|
||||
<p>
|
||||
<b>
|
||||
|
@ -71,7 +71,7 @@ class DialogZWaveJSRemoveNode extends LitElement {
|
||||
${this._status === "started"
|
||||
? html`
|
||||
<div class="flex-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
<div class="status">
|
||||
<p>
|
||||
<b
|
||||
|
@ -171,7 +171,7 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
|
||||
<div class="icon">
|
||||
${this._status === "disconnected"
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>`
|
||||
: html`
|
||||
<ha-svg-icon
|
||||
@ -457,7 +457,7 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
|
||||
: html`
|
||||
<ha-circular-progress
|
||||
size="small"
|
||||
active
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
`}
|
||||
</div>
|
||||
|
@ -97,7 +97,7 @@ export class SystemLogCard extends LitElement {
|
||||
${this._items === undefined
|
||||
? html`
|
||||
<div class="loading-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
|
@ -69,7 +69,7 @@ export class HassioHostname extends LitElement {
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._save} .disabled=${this._processing}>
|
||||
${this._processing
|
||||
? html`<ha-circular-progress active size="small">
|
||||
? html`<ha-circular-progress indeterminate size="small">
|
||||
</ha-circular-progress>`
|
||||
: this.hass.localize("ui.common.save")}
|
||||
</mwc-button>
|
||||
|
@ -126,7 +126,7 @@ export class HassioNetwork extends LitElement {
|
||||
.disabled=${this._scanning}
|
||||
>
|
||||
${this._scanning
|
||||
? html`<ha-circular-progress active size="small">
|
||||
? html`<ha-circular-progress indeterminate size="small">
|
||||
</ha-circular-progress>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.network.supervisor.scan_ap"
|
||||
@ -242,7 +242,7 @@ export class HassioNetwork extends LitElement {
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._updateNetwork} .disabled=${!this._dirty}>
|
||||
${this._processing
|
||||
? html`<ha-circular-progress active size="small">
|
||||
? html`<ha-circular-progress indeterminate size="small">
|
||||
</ha-circular-progress>`
|
||||
: this.hass.localize("ui.common.save")}
|
||||
</mwc-button>
|
||||
|
@ -304,7 +304,7 @@ class DialogSystemInformation extends LitElement {
|
||||
if (!this._systemInfo) {
|
||||
sections.push(html`
|
||||
<div class="loading-container">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`);
|
||||
} else {
|
||||
@ -324,7 +324,10 @@ class DialogSystemInformation extends LitElement {
|
||||
|
||||
if (info.type === "pending") {
|
||||
value = html`
|
||||
<ha-circular-progress active size="tiny"></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="tiny"
|
||||
></ha-circular-progress>
|
||||
`;
|
||||
} else if (info.type === "failed") {
|
||||
value = html`
|
||||
|
@ -80,7 +80,7 @@ export class HaBlueprintScriptEditor extends LitElement {
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.blueprint.no_blueprints"
|
||||
)
|
||||
: html`<ha-circular-progress active></ha-circular-progress>`}
|
||||
: html`<ha-circular-progress indeterminate></ha-circular-progress>`}
|
||||
</div>
|
||||
|
||||
${this.config.use_blueprint.path
|
||||
|
@ -26,7 +26,6 @@ import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { slugify } from "../../../common/string/slugify";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import { copyToClipboard } from "../../../common/util/copy-clipboard";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
@ -38,7 +37,6 @@ import type {
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-yaml-editor";
|
||||
import type { HaYamlEditor } from "../../../components/ha-yaml-editor";
|
||||
import { validateConfig } from "../../../data/config";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
@ -94,8 +92,6 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
|
||||
@state() private _readOnly = false;
|
||||
|
||||
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
|
||||
|
||||
@query("manual-script-editor")
|
||||
private _manualEditor?: HaManualScriptEditor;
|
||||
|
||||
@ -405,24 +401,14 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
</div>
|
||||
`
|
||||
: this._mode === "yaml"
|
||||
? html`
|
||||
<ha-yaml-editor
|
||||
.hass=${this.hass}
|
||||
.defaultValue=${this._preprocessYaml()}
|
||||
.readOnly=${this._readOnly}
|
||||
@value-changed=${this._yamlChanged}
|
||||
></ha-yaml-editor>
|
||||
<ha-card outlined>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._copyYaml}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.copy_to_clipboard"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: ``}
|
||||
? html` <ha-yaml-editor
|
||||
copyClipboard
|
||||
.hass=${this.hass}
|
||||
.defaultValue=${this._preprocessYaml()}
|
||||
.readOnly=${this._readOnly}
|
||||
@value-changed=${this._yamlChanged}
|
||||
></ha-yaml-editor>`
|
||||
: nothing}
|
||||
</div>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
@ -735,15 +721,6 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
return this._config;
|
||||
}
|
||||
|
||||
private async _copyYaml(): Promise<void> {
|
||||
if (this._yamlEditor?.yaml) {
|
||||
await copyToClipboard(this._yamlEditor.yaml);
|
||||
showToast(this, {
|
||||
message: this.hass.localize("ui.common.copied_clipboard"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _yamlChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
if (!ev.detail.isValid) {
|
||||
@ -903,8 +880,11 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
|
||||
}
|
||||
ha-yaml-editor {
|
||||
flex-grow: 1;
|
||||
--actions-border-radius: 0;
|
||||
--code-mirror-height: 100%;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.yaml-mode ha-card {
|
||||
overflow: initial;
|
||||
|
@ -106,7 +106,11 @@ class MoveDatadiskDialog extends LitElement {
|
||||
>
|
||||
${this._moving
|
||||
? html`
|
||||
<ha-circular-progress alt="Moving" size="large" active>
|
||||
<ha-circular-progress
|
||||
aria-label="Moving"
|
||||
size="large"
|
||||
indeterminate
|
||||
>
|
||||
</ha-circular-progress>
|
||||
<p class="progress-text">
|
||||
${this.hass.localize(
|
||||
|
@ -194,7 +194,7 @@ export class DialogAddUser extends LitElement {
|
||||
${this._loading
|
||||
? html`
|
||||
<div slot="primaryAction" class="submit-spinner">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
|
@ -90,7 +90,7 @@ const renderProgress = (
|
||||
return html`❌`;
|
||||
}
|
||||
return html`
|
||||
<ha-circular-progress size="tiny" active></ha-circular-progress>
|
||||
<ha-circular-progress size="tiny" indeterminate></ha-circular-progress>
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -184,6 +184,8 @@ class HaPanelDevService extends LitElement {
|
||||
>
|
||||
<div class="card-content">
|
||||
<ha-yaml-editor
|
||||
.hass=${this.hass}
|
||||
copyClipboard
|
||||
readOnly
|
||||
autoUpdate
|
||||
.value=${this._response}
|
||||
|
@ -131,7 +131,7 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement {
|
||||
let stats: TemplateResult;
|
||||
|
||||
if (!this._stats5min || !this._statsHour) {
|
||||
stats = html`<ha-circular-progress active></ha-circular-progress>`;
|
||||
stats = html`<ha-circular-progress indeterminate></ha-circular-progress>`;
|
||||
} else if (this._statsHour.length < 1 && this._stats5min.length < 1) {
|
||||
stats = html`<p>
|
||||
${this.hass.localize(
|
||||
|
@ -156,7 +156,7 @@ class HaPanelDevTemplate extends LitElement {
|
||||
${this._rendering
|
||||
? html`<ha-circular-progress
|
||||
class="render-spinner"
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
|
@ -77,7 +77,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
? html`<div
|
||||
class="validate-container layout vertical center-center"
|
||||
>
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div> `
|
||||
: nothing
|
||||
: html`
|
||||
@ -94,7 +94,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
${
|
||||
this._validateResult.errors
|
||||
? html`<ha-alert
|
||||
@ -233,7 +233,7 @@ export class DeveloperYamlConfig extends LitElement {
|
||||
}
|
||||
|
||||
.validate-log {
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
|
@ -193,10 +193,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
|
||||
</div>
|
||||
${this._isLoading
|
||||
? html`<div class="progress-wrapper">
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt=${this.hass.localize("ui.common.loading")}
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>`
|
||||
: !this._targetPickerValue
|
||||
? html`<div class="start-search">
|
||||
|
@ -107,10 +107,7 @@ export class HaLogbook extends LitElement {
|
||||
if (this._logbookEntries === undefined) {
|
||||
return html`
|
||||
<div class="progress-wrapper">
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt=${this.hass.localize("ui.common.loading")}
|
||||
></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
@ -1,25 +1,34 @@
|
||||
import { mdiPower, mdiWaterPercent } from "@mdi/js";
|
||||
import { mdiTuneVariant } from "@mdi/js";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { LitElement, PropertyValues, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { stateColorCss } from "../../../common/entity/state_color";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/ha-control-select";
|
||||
import type { ControlSelectOption } from "../../../components/ha-control-select";
|
||||
import "../../../components/ha-control-select-menu";
|
||||
import type { HaControlSelectMenu } from "../../../components/ha-control-select-menu";
|
||||
import {
|
||||
HumidifierEntityFeature,
|
||||
HumidifierEntity,
|
||||
computeHumidiferModeIcon,
|
||||
} from "../../../data/humidifier";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { HumidifierEntity, HumidifierState } from "../../../data/humidifier";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { LovelaceCardFeature } from "../types";
|
||||
import { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
||||
import { HumidifierModesCardFeatureConfig } from "./types";
|
||||
|
||||
export const supportsHumidifierModesCardFeature = (stateObj: HassEntity) => {
|
||||
const domain = computeDomain(stateObj.entity_id);
|
||||
return domain === "humidifier";
|
||||
return (
|
||||
domain === "humidifier" &&
|
||||
supportsFeature(stateObj, HumidifierEntityFeature.MODES)
|
||||
);
|
||||
};
|
||||
|
||||
@customElement("hui-humidifier-modes-card-feature")
|
||||
class HuiHumidifierModeCardFeature
|
||||
class HuiHumidifierModesCardFeature
|
||||
extends LitElement
|
||||
implements LovelaceCardFeature
|
||||
{
|
||||
@ -29,14 +38,29 @@ class HuiHumidifierModeCardFeature
|
||||
|
||||
@state() private _config?: HumidifierModesCardFeatureConfig;
|
||||
|
||||
@state() _currentState?: HumidifierState;
|
||||
@state() _currentMode?: string;
|
||||
|
||||
static getStubConfig(): HumidifierModesCardFeatureConfig {
|
||||
@query("ha-control-select-menu", true)
|
||||
private _haSelect?: HaControlSelectMenu;
|
||||
|
||||
static getStubConfig(
|
||||
_,
|
||||
stateObj?: HassEntity
|
||||
): HumidifierModesCardFeatureConfig {
|
||||
return {
|
||||
type: "humidifier-modes",
|
||||
style: "dropdown",
|
||||
modes: stateObj?.attributes.available_modes || [],
|
||||
};
|
||||
}
|
||||
|
||||
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
|
||||
await import(
|
||||
"../editor/config-elements/hui-humidifier-modes-card-feature-editor"
|
||||
);
|
||||
return document.createElement("hui-humidifier-modes-card-feature-editor");
|
||||
}
|
||||
|
||||
public setConfig(config: HumidifierModesCardFeatureConfig): void {
|
||||
if (!config) {
|
||||
throw new Error("Invalid configuration");
|
||||
@ -47,33 +71,46 @@ class HuiHumidifierModeCardFeature
|
||||
protected willUpdate(changedProp: PropertyValues): void {
|
||||
super.willUpdate(changedProp);
|
||||
if (changedProp.has("stateObj") && this.stateObj) {
|
||||
this._currentState = this.stateObj.state as HumidifierState;
|
||||
this._currentMode = this.stateObj.attributes.mode;
|
||||
}
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
if (this._haSelect && changedProps.has("hass")) {
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
if (
|
||||
this.hass &&
|
||||
this.hass.formatEntityAttributeValue !==
|
||||
oldHass?.formatEntityAttributeValue
|
||||
) {
|
||||
this._haSelect.layoutOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async _valueChanged(ev: CustomEvent) {
|
||||
const newState = (ev.detail as any).value as HumidifierState;
|
||||
const mode =
|
||||
(ev.detail as any).value ?? ((ev.target as any).value as string);
|
||||
|
||||
if (newState === this.stateObj!.state) return;
|
||||
const oldMode = this.stateObj!.attributes.mode;
|
||||
|
||||
const oldState = this.stateObj!.state as HumidifierState;
|
||||
this._currentState = newState;
|
||||
if (mode === oldMode) return;
|
||||
|
||||
this._currentMode = mode;
|
||||
|
||||
try {
|
||||
await this._setState(newState);
|
||||
await this._setMode(mode);
|
||||
} catch (err) {
|
||||
this._currentState = oldState;
|
||||
this._currentMode = oldMode;
|
||||
}
|
||||
}
|
||||
|
||||
private async _setState(newState: HumidifierState) {
|
||||
await this.hass!.callService(
|
||||
"humidifier",
|
||||
newState === "on" ? "turn_on" : "turn_off",
|
||||
{
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
}
|
||||
);
|
||||
private async _setMode(mode: string) {
|
||||
await this.hass!.callService("humidifier", "set_mode", {
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
mode: mode,
|
||||
});
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | null {
|
||||
@ -86,34 +123,75 @@ class HuiHumidifierModeCardFeature
|
||||
return null;
|
||||
}
|
||||
|
||||
const color = stateColorCss(this.stateObj);
|
||||
const stateObj = this.stateObj;
|
||||
|
||||
const options = ["on", "off"].map<ControlSelectOption>((entityState) => ({
|
||||
value: entityState,
|
||||
label: this.hass!.formatEntityState(this.stateObj!, entityState),
|
||||
path: entityState === "on" ? mdiWaterPercent : mdiPower,
|
||||
}));
|
||||
const modes = stateObj.attributes.available_modes || [];
|
||||
|
||||
const options = modes
|
||||
.filter((mode) => (this._config!.modes || []).includes(mode))
|
||||
.map<ControlSelectOption>((mode) => ({
|
||||
value: mode,
|
||||
label: this.hass!.formatEntityAttributeValue(
|
||||
this.stateObj!,
|
||||
"mode",
|
||||
mode
|
||||
),
|
||||
path: computeHumidiferModeIcon(mode),
|
||||
}));
|
||||
|
||||
if (this._config.style === "icons") {
|
||||
return html`
|
||||
<div class="container">
|
||||
<ha-control-select
|
||||
.options=${options}
|
||||
.value=${this._currentMode}
|
||||
@value-changed=${this._valueChanged}
|
||||
hide-label
|
||||
.ariaLabel=${this.hass!.formatEntityAttributeName(stateObj, "mode")}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-select>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
<ha-control-select
|
||||
.options=${options}
|
||||
.value=${this._currentState}
|
||||
@value-changed=${this._valueChanged}
|
||||
<ha-control-select-menu
|
||||
show-arrow
|
||||
hide-label
|
||||
.ariaLabel=${this.hass.localize("ui.card.humidifier.state")}
|
||||
style=${styleMap({
|
||||
"--control-select-color": color,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
.label=${this.hass!.formatEntityAttributeName(stateObj, "mode")}
|
||||
.value=${this._currentMode}
|
||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
@selected=${this._valueChanged}
|
||||
@closed=${stopPropagation}
|
||||
>
|
||||
</ha-control-select>
|
||||
<ha-svg-icon slot="icon" .path=${mdiTuneVariant}></ha-svg-icon>
|
||||
${options.map(
|
||||
(option) => html`
|
||||
<ha-list-item .value=${option.value} graphic="icon">
|
||||
<ha-svg-icon slot="graphic" .path=${option.path}></ha-svg-icon>
|
||||
${option.label}
|
||||
</ha-list-item>
|
||||
`
|
||||
)}
|
||||
</ha-control-select-menu>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select-menu {
|
||||
box-sizing: border-box;
|
||||
--control-select-menu-height: 40px;
|
||||
--control-select-menu-border-radius: 10px;
|
||||
line-height: 1.2;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
ha-control-select {
|
||||
--control-select-color: var(--feature-color);
|
||||
--control-select-padding: 0;
|
||||
@ -131,6 +209,6 @@ class HuiHumidifierModeCardFeature
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-humidifier-modes-card-feature": HuiHumidifierModeCardFeature;
|
||||
"hui-humidifier-modes-card-feature": HuiHumidifierModesCardFeature;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,136 @@
|
||||
import { mdiPower, mdiWaterPercent } from "@mdi/js";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { LitElement, PropertyValues, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { stateColorCss } from "../../../common/entity/state_color";
|
||||
import "../../../components/ha-control-select";
|
||||
import type { ControlSelectOption } from "../../../components/ha-control-select";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { HumidifierEntity, HumidifierState } from "../../../data/humidifier";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { LovelaceCardFeature } from "../types";
|
||||
import { HumidifierToggleCardFeatureConfig } from "./types";
|
||||
|
||||
export const supportsHumidifierToggleCardFeature = (stateObj: HassEntity) => {
|
||||
const domain = computeDomain(stateObj.entity_id);
|
||||
return domain === "humidifier";
|
||||
};
|
||||
|
||||
@customElement("hui-humidifier-toggle-card-feature")
|
||||
class HuiHumidifierToggleCardFeature
|
||||
extends LitElement
|
||||
implements LovelaceCardFeature
|
||||
{
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public stateObj?: HumidifierEntity;
|
||||
|
||||
@state() private _config?: HumidifierToggleCardFeatureConfig;
|
||||
|
||||
@state() _currentState?: HumidifierState;
|
||||
|
||||
static getStubConfig(): HumidifierToggleCardFeatureConfig {
|
||||
return {
|
||||
type: "humidifier-toggle",
|
||||
};
|
||||
}
|
||||
|
||||
public setConfig(config: HumidifierToggleCardFeatureConfig): void {
|
||||
if (!config) {
|
||||
throw new Error("Invalid configuration");
|
||||
}
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
protected willUpdate(changedProp: PropertyValues): void {
|
||||
super.willUpdate(changedProp);
|
||||
if (changedProp.has("stateObj") && this.stateObj) {
|
||||
this._currentState = this.stateObj.state as HumidifierState;
|
||||
}
|
||||
}
|
||||
|
||||
private async _valueChanged(ev: CustomEvent) {
|
||||
const newState = (ev.detail as any).value as HumidifierState;
|
||||
|
||||
if (newState === this.stateObj!.state) return;
|
||||
|
||||
const oldState = this.stateObj!.state as HumidifierState;
|
||||
this._currentState = newState;
|
||||
|
||||
try {
|
||||
await this._setState(newState);
|
||||
} catch (err) {
|
||||
this._currentState = oldState;
|
||||
}
|
||||
}
|
||||
|
||||
private async _setState(newState: HumidifierState) {
|
||||
await this.hass!.callService(
|
||||
"humidifier",
|
||||
newState === "on" ? "turn_on" : "turn_off",
|
||||
{
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | null {
|
||||
if (
|
||||
!this._config ||
|
||||
!this.hass ||
|
||||
!this.stateObj ||
|
||||
!supportsHumidifierToggleCardFeature(this.stateObj)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const color = stateColorCss(this.stateObj);
|
||||
|
||||
const options = ["on", "off"].map<ControlSelectOption>((entityState) => ({
|
||||
value: entityState,
|
||||
label: this.hass!.formatEntityState(this.stateObj!, entityState),
|
||||
path: entityState === "on" ? mdiWaterPercent : mdiPower,
|
||||
}));
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
<ha-control-select
|
||||
.options=${options}
|
||||
.value=${this._currentState}
|
||||
@value-changed=${this._valueChanged}
|
||||
hide-label
|
||||
.ariaLabel=${this.hass.localize("ui.card.humidifier.state")}
|
||||
style=${styleMap({
|
||||
"--control-select-color": color,
|
||||
})}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
>
|
||||
</ha-control-select>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-select {
|
||||
--control-select-color: var(--feature-color);
|
||||
--control-select-padding: 0;
|
||||
--control-select-thickness: 40px;
|
||||
--control-select-border-radius: 10px;
|
||||
--control-select-button-border-radius: 10px;
|
||||
}
|
||||
.container {
|
||||
padding: 0 12px 12px 12px;
|
||||
width: auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-humidifier-toggle-card-feature": HuiHumidifierToggleCardFeature;
|
||||
}
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, nothing, PropertyValues } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import "../../../components/ha-control-slider";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { HumidifierEntity } from "../../../data/humidifier";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { LovelaceCardFeature } from "../types";
|
||||
import { TargetHumidityCardFeatureConfig } from "./types";
|
||||
|
||||
export const supportsTargetHumidityCardFeature = (stateObj: HassEntity) => {
|
||||
const domain = computeDomain(stateObj.entity_id);
|
||||
return domain === "humidifier";
|
||||
};
|
||||
|
||||
@customElement("hui-target-humidity-card-feature")
|
||||
class HuiTargetHumidityCardFeature
|
||||
extends LitElement
|
||||
implements LovelaceCardFeature
|
||||
{
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public stateObj?: HumidifierEntity;
|
||||
|
||||
@state() private _config?: TargetHumidityCardFeatureConfig;
|
||||
|
||||
@state() private _targetHumidity?: number;
|
||||
|
||||
static getStubConfig(): TargetHumidityCardFeatureConfig {
|
||||
return {
|
||||
type: "target-humidity",
|
||||
};
|
||||
}
|
||||
|
||||
public setConfig(config: TargetHumidityCardFeatureConfig): void {
|
||||
if (!config) {
|
||||
throw new Error("Invalid configuration");
|
||||
}
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
protected willUpdate(changedProp: PropertyValues): void {
|
||||
super.willUpdate(changedProp);
|
||||
if (changedProp.has("stateObj")) {
|
||||
this._targetHumidity = this.stateObj!.attributes.humidity;
|
||||
}
|
||||
}
|
||||
|
||||
private get _step() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
private get _min() {
|
||||
return this.stateObj!.attributes.min_humidity ?? 0;
|
||||
}
|
||||
|
||||
private get _max() {
|
||||
return this.stateObj!.attributes.max_humidity ?? 100;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
const value = (ev.detail as any).value;
|
||||
if (isNaN(value)) return;
|
||||
this._targetHumidity = value;
|
||||
this._callService();
|
||||
}
|
||||
|
||||
private _callService() {
|
||||
this.hass!.callService("humidifier", "set_humidity", {
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
humidity: this._targetHumidity,
|
||||
});
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (
|
||||
!this._config ||
|
||||
!this.hass ||
|
||||
!this.stateObj ||
|
||||
!supportsTargetHumidityCardFeature(this.stateObj)
|
||||
) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
<ha-control-slider
|
||||
.value=${this.stateObj.attributes.humidity}
|
||||
.min=${this._min}
|
||||
.max=${this._max}
|
||||
.step=${this._step}
|
||||
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass.formatEntityAttributeName(
|
||||
this.stateObj,
|
||||
"humidity"
|
||||
)}
|
||||
unit="%"
|
||||
.locale=${this.hass.locale}
|
||||
></ha-control-slider>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
ha-control-slider {
|
||||
--control-slider-color: var(--feature-color);
|
||||
--control-slider-background: var(--feature-color);
|
||||
--control-slider-background-opacity: 0.2;
|
||||
--control-slider-thickness: 40px;
|
||||
--control-slider-border-radius: 10px;
|
||||
}
|
||||
.container {
|
||||
padding: 0 12px 12px 12px;
|
||||
width: auto;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-target-humidity-card-feature": HuiTargetHumidityCardFeature;
|
||||
}
|
||||
}
|
@ -55,6 +55,10 @@ export interface NumericInputCardFeatureConfig {
|
||||
style?: "buttons" | "slider";
|
||||
}
|
||||
|
||||
export interface TargetHumidityCardFeatureConfig {
|
||||
type: "target-humidity";
|
||||
}
|
||||
|
||||
export interface TargetTemperatureCardFeatureConfig {
|
||||
type: "target-temperature";
|
||||
}
|
||||
@ -66,6 +70,12 @@ export interface WaterHeaterOperationModesCardFeatureConfig {
|
||||
|
||||
export interface HumidifierModesCardFeatureConfig {
|
||||
type: "humidifier-modes";
|
||||
style?: "dropdown" | "icons";
|
||||
modes?: string[];
|
||||
}
|
||||
|
||||
export interface HumidifierToggleCardFeatureConfig {
|
||||
type: "humidifier-toggle";
|
||||
}
|
||||
|
||||
export const VACUUM_COMMANDS = [
|
||||
@ -101,11 +111,13 @@ export type LovelaceCardFeatureConfig =
|
||||
| CoverTiltPositionCardFeatureConfig
|
||||
| CoverTiltCardFeatureConfig
|
||||
| FanSpeedCardFeatureConfig
|
||||
| HumidifierToggleCardFeatureConfig
|
||||
| HumidifierModesCardFeatureConfig
|
||||
| LawnMowerCommandsCardFeatureConfig
|
||||
| LightBrightnessCardFeatureConfig
|
||||
| LightColorTempCardFeatureConfig
|
||||
| VacuumCommandsCardFeatureConfig
|
||||
| TargetHumidityCardFeatureConfig
|
||||
| TargetTemperatureCardFeatureConfig
|
||||
| WaterHeaterOperationModesCardFeatureConfig
|
||||
| SelectOptionsCardFeatureConfig
|
||||
|
@ -51,7 +51,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
||||
entity: foundEntities[0] || "",
|
||||
features: [
|
||||
{
|
||||
type: "humidifier-modes",
|
||||
type: "humidifier-toggle",
|
||||
},
|
||||
],
|
||||
};
|
||||
@ -180,6 +180,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
||||
max-width: 344px; /* 12px + 12px + 320px */
|
||||
padding: 0 12px 12px 12px;
|
||||
box-sizing: border-box;
|
||||
--interaction-margin: 0px;
|
||||
}
|
||||
|
||||
.more-info {
|
||||
|
@ -101,6 +101,8 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
this._config = config;
|
||||
|
||||
this.updateComplete.then(() => this._measureCard());
|
||||
}
|
||||
|
||||
public connectedCallback(): void {
|
||||
@ -339,15 +341,12 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
|
||||
|
||||
protected firstUpdated(): void {
|
||||
this._attachObserver();
|
||||
this._measureCard();
|
||||
}
|
||||
|
||||
public willUpdate(changedProps: PropertyValues): void {
|
||||
super.willUpdate(changedProps);
|
||||
|
||||
if (!this.hasUpdated) {
|
||||
this._measureCard();
|
||||
}
|
||||
|
||||
if (
|
||||
!this._config ||
|
||||
!this.hass ||
|
||||
@ -468,6 +467,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
|
||||
|
||||
private _measureCard() {
|
||||
const card = this.shadowRoot!.querySelector("ha-card");
|
||||
|
||||
if (!card) {
|
||||
return;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ export class HuiStartingCard extends LitElement implements LovelaceCard {
|
||||
|
||||
return html`
|
||||
<div class="content">
|
||||
<ha-circular-progress active></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
${this.hass.localize("ui.panel.lovelace.cards.starting.description")}
|
||||
</div>
|
||||
`;
|
||||
|
@ -172,6 +172,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
max-width: 344px; /* 12px + 12px + 320px */
|
||||
padding: 0 12px 12px 12px;
|
||||
box-sizing: border-box;
|
||||
--interaction-margin: 0px;
|
||||
}
|
||||
|
||||
.more-info {
|
||||
|
@ -22,6 +22,7 @@ import memoizeOne from "memoize-one";
|
||||
import type { SortableEvent } from "sortablejs";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-checkbox";
|
||||
import "../../../components/ha-icon-button";
|
||||
@ -347,7 +348,7 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
|
||||
.title=${this.hass!.localize(
|
||||
"ui.panel.lovelace.cards.todo-list.drag_and_drop"
|
||||
)}
|
||||
class="reorderButton"
|
||||
class="reorderButton handle"
|
||||
.path=${mdiDrag}
|
||||
>
|
||||
</ha-svg-icon>
|
||||
@ -439,7 +440,21 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
const checkedItems = this._getCheckedItems(this._items);
|
||||
const uids = checkedItems.map((item: TodoItem) => item.uid);
|
||||
deleteItems(this.hass!, this._entityId!, uids);
|
||||
showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.lovelace.cards.todo-list.delete_confirm_title"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.lovelace.cards.todo-list.delete_confirm_text",
|
||||
{ number: uids.length }
|
||||
),
|
||||
dismissText: this.hass.localize("ui.common.cancel"),
|
||||
confirmText: this.hass.localize("ui.common.delete"),
|
||||
destructive: true,
|
||||
confirm: () => {
|
||||
deleteItems(this.hass!, this._entityId!, uids);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private get _newItem(): HaTextField {
|
||||
@ -583,6 +598,10 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
|
||||
direction: var(--direction);
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
ha-checkbox {
|
||||
margin-left: -12px;
|
||||
margin-inline-start: -12px;
|
||||
|
@ -263,7 +263,7 @@ export class HuiImage extends LitElement {
|
||||
>
|
||||
<ha-circular-progress
|
||||
class="render-spinner"
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
</div>`
|
||||
|
@ -7,12 +7,14 @@ import "../card-features/hui-cover-tilt-card-feature";
|
||||
import "../card-features/hui-cover-tilt-position-card-feature";
|
||||
import "../card-features/hui-fan-speed-card-feature";
|
||||
import "../card-features/hui-humidifier-modes-card-feature";
|
||||
import "../card-features/hui-humidifier-toggle-card-feature";
|
||||
import "../card-features/hui-lawn-mower-commands-card-feature";
|
||||
import "../card-features/hui-light-brightness-card-feature";
|
||||
import "../card-features/hui-light-color-temp-card-feature";
|
||||
import "../card-features/hui-numeric-input-card-feature";
|
||||
import "../card-features/hui-select-options-card-feature";
|
||||
import "../card-features/hui-target-temperature-card-feature";
|
||||
import "../card-features/hui-target-humidity-card-feature";
|
||||
import "../card-features/hui-vacuum-commands-card-feature";
|
||||
import "../card-features/hui-water-heater-operation-modes-card-feature";
|
||||
import { LovelaceCardFeatureConfig } from "../card-features/types";
|
||||
@ -31,11 +33,13 @@ const TYPES: Set<LovelaceCardFeatureConfig["type"]> = new Set([
|
||||
"cover-tilt",
|
||||
"fan-speed",
|
||||
"humidifier-modes",
|
||||
"humidifier-toggle",
|
||||
"lawn-mower-commands",
|
||||
"light-brightness",
|
||||
"light-color-temp",
|
||||
"numeric-input",
|
||||
"select-options",
|
||||
"target-humidity",
|
||||
"target-temperature",
|
||||
"vacuum-commands",
|
||||
"water-heater-operation-modes",
|
||||
|
@ -142,8 +142,7 @@ export class HuiCardPicker extends LitElement {
|
||||
html`
|
||||
<div class="card spinner">
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt="Loading"
|
||||
indeterminate
|
||||
></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
@ -238,7 +237,7 @@ export class HuiCardPicker extends LitElement {
|
||||
this._renderCardElement(card),
|
||||
html`
|
||||
<div class="card spinner">
|
||||
<ha-circular-progress active alt="Loading"></ha-circular-progress>
|
||||
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||
</div>
|
||||
`
|
||||
)}`,
|
||||
|
@ -235,8 +235,8 @@ export class HuiDialogEditCard
|
||||
${this._error
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt="Can't update card"
|
||||
indeterminate
|
||||
aria-label="Can't update card"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
: ``}
|
||||
@ -271,8 +271,8 @@ export class HuiDialogEditCard
|
||||
${this._saving
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
active
|
||||
title="Saving"
|
||||
indeterminate
|
||||
aria-label="Saving"
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
|
@ -110,8 +110,8 @@ export class HuiDialogSuggestCard extends LitElement {
|
||||
${this._saving
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
active
|
||||
title="Saving"
|
||||
indeterminate
|
||||
aria-label="Saving"
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
|
@ -29,12 +29,14 @@ import { supportsCoverPositionCardFeature } from "../../card-features/hui-cover-
|
||||
import { supportsCoverTiltCardFeature } from "../../card-features/hui-cover-tilt-card-feature";
|
||||
import { supportsCoverTiltPositionCardFeature } from "../../card-features/hui-cover-tilt-position-card-feature";
|
||||
import { supportsFanSpeedCardFeature } from "../../card-features/hui-fan-speed-card-feature";
|
||||
import { supportsHumidifierToggleCardFeature } from "../../card-features/hui-humidifier-toggle-card-feature";
|
||||
import { supportsHumidifierModesCardFeature } from "../../card-features/hui-humidifier-modes-card-feature";
|
||||
import { supportsLawnMowerCommandCardFeature } from "../../card-features/hui-lawn-mower-commands-card-feature";
|
||||
import { supportsLightBrightnessCardFeature } from "../../card-features/hui-light-brightness-card-feature";
|
||||
import { supportsLightColorTempCardFeature } from "../../card-features/hui-light-color-temp-card-feature";
|
||||
import { supportsNumericInputCardFeature } from "../../card-features/hui-numeric-input-card-feature";
|
||||
import { supportsSelectOptionsCardFeature } from "../../card-features/hui-select-options-card-feature";
|
||||
import { supportsTargetHumidityCardFeature } from "../../card-features/hui-target-humidity-card-feature";
|
||||
import { supportsTargetTemperatureCardFeature } from "../../card-features/hui-target-temperature-card-feature";
|
||||
import { supportsVacuumCommandsCardFeature } from "../../card-features/hui-vacuum-commands-card-feature";
|
||||
import { supportsWaterHeaterOperationModesCardFeature } from "../../card-features/hui-water-heater-operation-modes-card-feature";
|
||||
@ -54,10 +56,12 @@ const UI_FEATURE_TYPES = [
|
||||
"cover-tilt",
|
||||
"fan-speed",
|
||||
"humidifier-modes",
|
||||
"humidifier-toggle",
|
||||
"lawn-mower-commands",
|
||||
"light-brightness",
|
||||
"light-color-temp",
|
||||
"select-options",
|
||||
"target-humidity",
|
||||
"target-temperature",
|
||||
"vacuum-commands",
|
||||
"water-heater-operation-modes",
|
||||
@ -70,6 +74,7 @@ const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
|
||||
"vacuum-commands",
|
||||
"alarm-modes",
|
||||
"climate-hvac-modes",
|
||||
"humidifier-modes",
|
||||
"water-heater-operation-modes",
|
||||
"lawn-mower-commands",
|
||||
"climate-preset-modes",
|
||||
@ -89,10 +94,12 @@ const SUPPORTS_FEATURE_TYPES: Record<
|
||||
"cover-tilt": supportsCoverTiltCardFeature,
|
||||
"fan-speed": supportsFanSpeedCardFeature,
|
||||
"humidifier-modes": supportsHumidifierModesCardFeature,
|
||||
"humidifier-toggle": supportsHumidifierToggleCardFeature,
|
||||
"lawn-mower-commands": supportsLawnMowerCommandCardFeature,
|
||||
"light-brightness": supportsLightBrightnessCardFeature,
|
||||
"light-color-temp": supportsLightColorTempCardFeature,
|
||||
"numeric-input": supportsNumericInputCardFeature,
|
||||
"target-humidity": supportsTargetHumidityCardFeature,
|
||||
"target-temperature": supportsTargetTemperatureCardFeature,
|
||||
"vacuum-commands": supportsVacuumCommandsCardFeature,
|
||||
"water-heater-operation-modes": supportsWaterHeaterOperationModesCardFeature,
|
||||
|
@ -14,15 +14,22 @@ import { HASSDomEvent, fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { HumidifierCardConfig } from "../../cards/types";
|
||||
import {
|
||||
LovelaceCardFeatureConfig,
|
||||
LovelaceCardFeatureContext,
|
||||
} from "../../card-features/types";
|
||||
import type { HumidifierCardConfig } from "../../cards/types";
|
||||
import type { LovelaceCardEditor } from "../../types";
|
||||
import "../hui-sub-element-editor";
|
||||
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
||||
import { EditSubElementEvent, SubElementEditorConfig } from "../types";
|
||||
import "./hui-card-features-editor";
|
||||
import type { FeatureType } from "./hui-card-features-editor";
|
||||
|
||||
const COMPATIBLE_FEATURES_TYPES: FeatureType[] = [
|
||||
"humidifier-modes",
|
||||
"humidifier-toggle",
|
||||
];
|
||||
|
||||
const cardConfigStruct = assign(
|
||||
baseLovelaceCardConfig,
|
||||
@ -103,6 +110,7 @@ export class HuiHumidifierCardEditor
|
||||
<hui-card-features-editor
|
||||
.hass=${this.hass}
|
||||
.stateObj=${stateObj}
|
||||
.featuresTypes=${COMPATIBLE_FEATURES_TYPES}
|
||||
.features=${this._config!.features ?? []}
|
||||
@features-changed=${this._featuresChanged}
|
||||
@edit-detail-element=${this._editDetailElement}
|
||||
|
@ -0,0 +1,129 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { FormatEntityAttributeValueFunc } from "../../../../common/translations/entity-state";
|
||||
import { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type {
|
||||
HaFormSchema,
|
||||
SchemaUnion,
|
||||
} from "../../../../components/ha-form/types";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import {
|
||||
HumidifierModesCardFeatureConfig,
|
||||
LovelaceCardFeatureContext,
|
||||
} from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
@customElement("hui-humidifier-modes-card-feature-editor")
|
||||
export class HuiHumidifierModesCardFeatureEditor
|
||||
extends LitElement
|
||||
implements LovelaceCardFeatureEditor
|
||||
{
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
|
||||
|
||||
@state() private _config?: HumidifierModesCardFeatureConfig;
|
||||
|
||||
public setConfig(config: HumidifierModesCardFeatureConfig): void {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
formatEntityAttributeValue: FormatEntityAttributeValueFunc,
|
||||
stateObj?: HassEntity
|
||||
) =>
|
||||
[
|
||||
{
|
||||
name: "style",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: false,
|
||||
mode: "list",
|
||||
options: ["dropdown", "icons"].map((mode) => ({
|
||||
value: mode,
|
||||
label: localize(
|
||||
`ui.panel.lovelace.editor.features.types.humidifier-modes.style_list.${mode}`
|
||||
),
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "modes",
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
mode: "list",
|
||||
options:
|
||||
stateObj?.attributes.available_modes?.map((mode) => ({
|
||||
value: mode,
|
||||
label: formatEntityAttributeValue(stateObj, "mode", mode),
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const satisfies readonly HaFormSchema[]
|
||||
);
|
||||
|
||||
protected render() {
|
||||
if (!this.hass || !this._config) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const stateObj = this.context?.entity_id
|
||||
? this.hass.states[this.context?.entity_id]
|
||||
: undefined;
|
||||
|
||||
const data: HumidifierModesCardFeatureConfig = {
|
||||
style: "dropdown",
|
||||
modes: [],
|
||||
...this._config,
|
||||
};
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass.localize,
|
||||
this.hass.formatEntityAttributeValue,
|
||||
stateObj
|
||||
);
|
||||
|
||||
return html`
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${data}
|
||||
.schema=${schema}
|
||||
.computeLabel=${this._computeLabelCallback}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>
|
||||
`;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
||||
) => {
|
||||
switch (schema.name) {
|
||||
case "style":
|
||||
case "modes":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.features.types.humidifier-modes.${schema.name}`
|
||||
);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-humidifier-modes-card-feature-editor": HuiHumidifierModesCardFeatureEditor;
|
||||
}
|
||||
}
|
@ -87,6 +87,8 @@ const HIDDEN_ATTRIBUTES = [
|
||||
"unit_of_measurement",
|
||||
"visibility_unit",
|
||||
"wind_speed_unit",
|
||||
"battery_icon",
|
||||
"battery_level",
|
||||
];
|
||||
|
||||
const cardConfigStruct = assign(
|
||||
|
@ -132,9 +132,9 @@ export class HuiSaveConfig extends LitElement implements HassDialog {
|
||||
>
|
||||
${this._saving
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
title="Saving"
|
||||
aria-label="Saving"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
${this.hass!.localize(
|
||||
|
@ -207,8 +207,7 @@ export abstract class HuiElementEditor<T, C = any> extends LitElement {
|
||||
${this._loading
|
||||
? html`
|
||||
<ha-circular-progress
|
||||
active
|
||||
alt="Loading"
|
||||
indeterminate
|
||||
class="center margin-bot"
|
||||
></ha-circular-progress>
|
||||
`
|
||||
|
@ -63,9 +63,9 @@ export class HuiDialogEditLovelace extends LitElement {
|
||||
>
|
||||
${this._saving
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
title="Saving"
|
||||
aria-label="Saving"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
${this.hass!.localize("ui.common.save")}</mwc-button
|
||||
|
@ -323,9 +323,9 @@ export class HuiDialogEditView extends LitElement {
|
||||
>
|
||||
${this._saving
|
||||
? html`<ha-circular-progress
|
||||
active
|
||||
indeterminate
|
||||
size="small"
|
||||
title="Saving"
|
||||
aria-label="Saving"
|
||||
></ha-circular-progress>`
|
||||
: ""}
|
||||
${this.hass!.localize("ui.common.save")}</mwc-button
|
||||
@ -528,7 +528,7 @@ export class HuiDialogEditView extends LitElement {
|
||||
ha-circular-progress {
|
||||
display: none;
|
||||
}
|
||||
ha-circular-progress[active] {
|
||||
ha-circular-progress[indeterminate] {
|
||||
display: block;
|
||||
}
|
||||
.selected_menu_item {
|
||||
|
@ -111,7 +111,10 @@ export class HuiGraphHeaderFooter
|
||||
if (!this._coordinates) {
|
||||
return html`
|
||||
<div class="container">
|
||||
<ha-circular-progress active size="small"></ha-circular-progress>
|
||||
<ha-circular-progress
|
||||
indeterminate
|
||||
size="small"
|
||||
></ha-circular-progress>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user