diff --git a/gallery/src/pages/automation/editor-condition.ts b/gallery/src/pages/automation/editor-condition.ts index ed30c74272..9095461c69 100644 --- a/gallery/src/pages/automation/editor-condition.ts +++ b/gallery/src/pages/automation/editor-condition.ts @@ -11,7 +11,6 @@ import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervis import type { ConditionWithShorthand } from "../../../../src/data/automation"; import "../../../../src/panels/config/automation/condition/ha-automation-condition"; import { HaDeviceCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-device"; -import { HaLogicalCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-logical"; import HaNumericStateCondition from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-numeric_state"; import { HaStateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-state"; import { HaSunCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-sun"; @@ -19,62 +18,67 @@ import { HaTemplateCondition } from "../../../../src/panels/config/automation/co import { HaTimeCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-time"; import { HaTriggerCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-trigger"; import { HaZoneCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-zone"; +import { HaAndCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-and"; +import { HaOrCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-or"; +import { HaNotCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-not"; const SCHEMAS: { name: string; conditions: ConditionWithShorthand[] }[] = [ { name: "State", - conditions: [{ condition: "state", ...HaStateCondition.defaultConfig }], + conditions: [{ ...HaStateCondition.defaultConfig }], }, { name: "Numeric State", - conditions: [ - { condition: "numeric_state", ...HaNumericStateCondition.defaultConfig }, - ], + conditions: [{ ...HaNumericStateCondition.defaultConfig }], }, { name: "Sun", - conditions: [{ condition: "sun", ...HaSunCondition.defaultConfig }], + conditions: [{ ...HaSunCondition.defaultConfig }], }, { name: "Zone", - conditions: [{ condition: "zone", ...HaZoneCondition.defaultConfig }], + conditions: [{ ...HaZoneCondition.defaultConfig }], }, { name: "Time", - conditions: [{ condition: "time", ...HaTimeCondition.defaultConfig }], + conditions: [{ ...HaTimeCondition.defaultConfig }], }, { name: "Template", - conditions: [ - { condition: "template", ...HaTemplateCondition.defaultConfig }, - ], + conditions: [{ ...HaTemplateCondition.defaultConfig }], }, { name: "Device", - conditions: [{ condition: "device", ...HaDeviceCondition.defaultConfig }], + conditions: [{ ...HaDeviceCondition.defaultConfig }], }, { name: "And", - conditions: [{ condition: "and", ...HaLogicalCondition.defaultConfig }], + conditions: [{ ...HaAndCondition.defaultConfig }], }, { name: "Or", - conditions: [{ condition: "or", ...HaLogicalCondition.defaultConfig }], + conditions: [{ ...HaOrCondition.defaultConfig }], }, { name: "Not", - conditions: [{ condition: "not", ...HaLogicalCondition.defaultConfig }], + conditions: [{ ...HaNotCondition.defaultConfig }], }, { name: "Trigger", - conditions: [{ condition: "trigger", ...HaTriggerCondition.defaultConfig }], + conditions: [{ ...HaTriggerCondition.defaultConfig }], }, { name: "Shorthand", conditions: [ - { and: HaLogicalCondition.defaultConfig.conditions }, - { or: HaLogicalCondition.defaultConfig.conditions }, - { not: HaLogicalCondition.defaultConfig.conditions }, + { + ...HaAndCondition.defaultConfig, + }, + { + ...HaOrCondition.defaultConfig, + }, + { + ...HaNotCondition.defaultConfig, + }, ], }, ]; diff --git a/gallery/src/pages/automation/editor-trigger.ts b/gallery/src/pages/automation/editor-trigger.ts index 1ed11eb0a8..bb79f63a71 100644 --- a/gallery/src/pages/automation/editor-trigger.ts +++ b/gallery/src/pages/automation/editor-trigger.ts @@ -30,55 +30,48 @@ import { HaConversationTrigger } from "../../../../src/panels/config/automation/ const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ { name: "State", - triggers: [{ platform: "state", ...HaStateTrigger.defaultConfig }], + triggers: [{ ...HaStateTrigger.defaultConfig }], }, { name: "MQTT", - triggers: [{ platform: "mqtt", ...HaMQTTTrigger.defaultConfig }], + triggers: [{ ...HaMQTTTrigger.defaultConfig }], }, { name: "GeoLocation", - triggers: [ - { platform: "geo_location", ...HaGeolocationTrigger.defaultConfig }, - ], + triggers: [{ ...HaGeolocationTrigger.defaultConfig }], }, { name: "Home Assistant", - triggers: [{ platform: "homeassistant", ...HaHassTrigger.defaultConfig }], + triggers: [{ ...HaHassTrigger.defaultConfig }], }, { name: "Numeric State", - triggers: [ - { platform: "numeric_state", ...HaNumericStateTrigger.defaultConfig }, - ], + triggers: [{ ...HaNumericStateTrigger.defaultConfig }], }, { name: "Sun", - triggers: [{ platform: "sun", ...HaSunTrigger.defaultConfig }], + triggers: [{ ...HaSunTrigger.defaultConfig }], }, { name: "Time Pattern", - triggers: [ - { platform: "time_pattern", ...HaTimePatternTrigger.defaultConfig }, - ], + triggers: [{ ...HaTimePatternTrigger.defaultConfig }], }, { name: "Webhook", - triggers: [{ platform: "webhook", ...HaWebhookTrigger.defaultConfig }], + triggers: [{ ...HaWebhookTrigger.defaultConfig }], }, { name: "Persistent Notification", triggers: [ { - platform: "persistent_notification", ...HaPersistentNotificationTrigger.defaultConfig, }, ], @@ -86,37 +79,37 @@ const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ { name: "Zone", - triggers: [{ platform: "zone", ...HaZoneTrigger.defaultConfig }], + triggers: [{ ...HaZoneTrigger.defaultConfig }], }, { name: "Tag", - triggers: [{ platform: "tag", ...HaTagTrigger.defaultConfig }], + triggers: [{ ...HaTagTrigger.defaultConfig }], }, { name: "Time", - triggers: [{ platform: "time", ...HaTimeTrigger.defaultConfig }], + triggers: [{ ...HaTimeTrigger.defaultConfig }], }, { name: "Template", - triggers: [{ platform: "template", ...HaTemplateTrigger.defaultConfig }], + triggers: [{ ...HaTemplateTrigger.defaultConfig }], }, { name: "Event", - triggers: [{ platform: "event", ...HaEventTrigger.defaultConfig }], + triggers: [{ ...HaEventTrigger.defaultConfig }], }, { name: "Device Trigger", - triggers: [{ platform: "device", ...HaDeviceTrigger.defaultConfig }], + triggers: [{ ...HaDeviceTrigger.defaultConfig }], }, { name: "Sentence", triggers: [ - { platform: "conversation", ...HaConversationTrigger.defaultConfig }, + { ...HaConversationTrigger.defaultConfig }, { platform: "conversation", command: ["Turn on the lights", "Turn the lights on"], diff --git a/pyproject.toml b/pyproject.toml index 81a67fa3aa..7bcb25bd93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240828.0" +version = "20240829.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" diff --git a/src/components/ha-formfield.ts b/src/components/ha-formfield.ts index c993ec4387..0f49c75514 100644 --- a/src/components/ha-formfield.ts +++ b/src/components/ha-formfield.ts @@ -18,9 +18,9 @@ export class HaFormfield extends FormfieldBase { return html`
- +
`; } @@ -57,13 +57,13 @@ export class HaFormfield extends FormfieldBase { } .mdc-form-field { align-items: var(--ha-formfield-align-items, center); + gap: 4px; } .mdc-form-field > label { direction: var(--direction); margin-inline-start: 0; margin-inline-end: auto; - padding-inline-start: 4px; - padding-inline-end: 0; + padding: 0; } :host([disabled]) label { color: var(--disabled-text-color); diff --git a/src/components/ha-selector/ha-selector-boolean.ts b/src/components/ha-selector/ha-selector-boolean.ts index 18ce85b912..5bed88c726 100644 --- a/src/components/ha-selector/ha-selector-boolean.ts +++ b/src/components/ha-selector/ha-selector-boolean.ts @@ -1,4 +1,4 @@ -import { css, CSSResultGroup, html, LitElement } from "lit"; +import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import { HomeAssistant } from "../../types"; @@ -28,10 +28,13 @@ export class HaBooleanSelector extends LitElement { @change=${this._handleChange} .disabled=${this.disabled} > + +

${this.label}

+ ${this.helper + ? html`

${this.helper}

` + : nothing} +
- ${this.helper - ? html`${this.helper}` - : ""} `; } @@ -47,10 +50,21 @@ export class HaBooleanSelector extends LitElement { return css` ha-formfield { display: flex; - height: 56px; + min-height: 56px; align-items: center; --mdc-typography-body2-font-size: 1em; } + p { + margin: 0; + } + .secondary { + direction: var(--direction); + padding-top: 4px; + box-sizing: border-box; + color: var(--secondary-text-color); + font-size: 0.875rem; + font-weight: var(--mdc-typography-body2-font-weight, 400); + } `; } } diff --git a/src/components/ha-selector/ha-selector-number.ts b/src/components/ha-selector/ha-selector-number.ts index ba60452493..418432ef27 100644 --- a/src/components/ha-selector/ha-selector-number.ts +++ b/src/components/ha-selector/ha-selector-number.ts @@ -1,4 +1,11 @@ -import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; +import { + css, + CSSResultGroup, + html, + LitElement, + nothing, + PropertyValues, +} from "lit"; import { customElement, property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../../common/dom/fire_event"; @@ -60,12 +67,10 @@ export class HaNumberSelector extends LitElement { } return html` + ${this.label ? html`${this.label}${this.required ? "*" : ""}` : nothing}
${!isBox ? html` - ${this.label - ? html`${this.label}${this.required ? "*" : ""}` - : ""} ` - : ""} + : nothing} ${!isBox && this.helper ? html`${this.helper}` - : ""} + : nothing} `; } @@ -141,6 +147,9 @@ export class HaNumberSelector extends LitElement { } ha-slider { flex: 1; + margin-right: 16px; + margin-inline-end: 16px; + margin-inline-start: 0; } ha-textfield { --ha-textfield-input-width: 40px; diff --git a/src/components/ha-slider.ts b/src/components/ha-slider.ts index 33a1fbb16d..df91f81970 100644 --- a/src/components/ha-slider.ts +++ b/src/components/ha-slider.ts @@ -20,6 +20,7 @@ export class HaSlider extends MdSlider { --md-sys-color-on-surface: var(--primary-text-color); --md-slider-handle-width: 14px; --md-slider-handle-height: 14px; + --md-slider-state-layer-size: 24px; min-width: 100px; min-inline-size: 100px; width: 200px; diff --git a/src/data/lovelace/config/view.ts b/src/data/lovelace/config/view.ts index 4bbf67c5a6..dd784c628a 100644 --- a/src/data/lovelace/config/view.ts +++ b/src/data/lovelace/config/view.ts @@ -22,7 +22,9 @@ export interface LovelaceBaseViewConfig { visible?: boolean | ShowViewConfig[]; subview?: boolean; back_path?: string; - max_columns?: number; // Only used for section view, it should move to a section view config type when the views will have dedicated editor. + // Only used for section view, it should move to a section view config type when the views will have dedicated editor. + max_columns?: number; + dense_section_placement?: boolean; } export interface LovelaceViewConfig extends LovelaceBaseViewConfig { diff --git a/src/data/selector.ts b/src/data/selector.ts index 6b17b4414b..036fa0bc86 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -323,6 +323,7 @@ export interface NumberSelector { step?: number | "any"; mode?: "box" | "slider"; unit_of_measurement?: string; + slider_ticks?: boolean; } | null; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-choose.ts b/src/panels/config/automation/action/types/ha-automation-action-choose.ts index 3d6dd20ac6..1da1e87d46 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-choose.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-choose.ts @@ -86,7 +86,7 @@ export class HaChooseAction extends LitElement implements ActionElement { this._unsubMql = undefined; } - public static get defaultConfig() { + public static get defaultConfig(): ChooseAction { return { choose: [{ conditions: [], sequence: [] }] }; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-condition.ts b/src/panels/config/automation/action/types/ha-automation-action-condition.ts index 3b098e9a86..9fa89e9c90 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-condition.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-condition.ts @@ -20,7 +20,7 @@ export class HaConditionAction extends LitElement implements ActionElement { @property({ attribute: false }) public action!: Condition; - public static get defaultConfig() { + public static get defaultConfig(): Omit { return { condition: "state" }; } @@ -87,13 +87,12 @@ export class HaConditionAction extends LitElement implements ActionElement { const elClass = customElements.get( `ha-automation-condition-${type}` ) as CustomElementConstructor & { - defaultConfig: Omit; + defaultConfig: Condition; }; if (type !== this.action.condition) { fireEvent(this, "value-changed", { value: { - condition: type, ...elClass.defaultConfig, }, }); diff --git a/src/panels/config/automation/action/types/ha-automation-action-delay.ts b/src/panels/config/automation/action/types/ha-automation-action-delay.ts index c8978e30eb..0a0a2569a7 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-delay.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-delay.ts @@ -19,7 +19,7 @@ export class HaDelayAction extends LitElement implements ActionElement { @state() private _timeData?: HaDurationData; - public static get defaultConfig() { + public static get defaultConfig(): DelayAction { return { delay: "" }; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-device_id.ts b/src/panels/config/automation/action/types/ha-automation-action-device_id.ts index cf5a09d68d..328fd2cfb4 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-device_id.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-device_id.ts @@ -36,7 +36,7 @@ export class HaDeviceAction extends LitElement { private _origAction?: DeviceAction; - public static get defaultConfig() { + public static get defaultConfig(): DeviceAction { return { device_id: "", domain: "", diff --git a/src/panels/config/automation/action/types/ha-automation-action-if.ts b/src/panels/config/automation/action/types/ha-automation-action-if.ts index b68cf1f157..975fb03ec3 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-if.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-if.ts @@ -21,7 +21,7 @@ export class HaIfAction extends LitElement implements ActionElement { @state() private _showElse = false; - public static get defaultConfig() { + public static get defaultConfig(): IfAction { return { if: [], then: [], diff --git a/src/panels/config/automation/action/types/ha-automation-action-parallel.ts b/src/panels/config/automation/action/types/ha-automation-action-parallel.ts index 6ccec60232..f8a299e765 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-parallel.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-parallel.ts @@ -18,7 +18,7 @@ export class HaParallelAction extends LitElement implements ActionElement { @property({ attribute: false }) public action!: ParallelAction; - public static get defaultConfig() { + public static get defaultConfig(): ParallelAction { return { parallel: [], }; diff --git a/src/panels/config/automation/action/types/ha-automation-action-repeat.ts b/src/panels/config/automation/action/types/ha-automation-action-repeat.ts index 2b1cf924a9..28c1a97bb8 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-repeat.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-repeat.ts @@ -31,7 +31,7 @@ export class HaRepeatAction extends LitElement implements ActionElement { @property({ type: Array }) public path?: ItemPath; - public static get defaultConfig() { + public static get defaultConfig(): RepeatAction { return { repeat: { count: 2, sequence: [] } }; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-sequence.ts b/src/panels/config/automation/action/types/ha-automation-action-sequence.ts index d8621dafa2..a8c16d6bed 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-sequence.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-sequence.ts @@ -19,7 +19,7 @@ export class HaSequenceAction extends LitElement implements ActionElement { @property({ attribute: false }) public action!: SequenceAction; - public static get defaultConfig() { + public static get defaultConfig(): SequenceAction { return { sequence: [], }; diff --git a/src/panels/config/automation/action/types/ha-automation-action-service.ts b/src/panels/config/automation/action/types/ha-automation-action-service.ts index 6bb209a0a2..3aef27db02 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-service.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-service.ts @@ -52,7 +52,7 @@ export class HaServiceAction extends LitElement implements ActionElement { } ); - public static get defaultConfig() { + public static get defaultConfig(): ServiceAction { return { action: "", data: {} }; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-set_conversation_response.ts b/src/panels/config/automation/action/types/ha-automation-action-set_conversation_response.ts index b4c9b9c51d..4592ea2401 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-set_conversation_response.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-set_conversation_response.ts @@ -25,7 +25,7 @@ export class HaSetConversationResponseAction @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { + public static get defaultConfig(): SetConversationResponseAction { return { set_conversation_response: "" }; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-stop.ts b/src/panels/config/automation/action/types/ha-automation-action-stop.ts index c98a5e2cff..e5d21e96ee 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-stop.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-stop.ts @@ -14,7 +14,7 @@ export class HaStopAction extends LitElement implements ActionElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { + public static get defaultConfig(): StopAction { return { stop: "" }; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts b/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts index 52b8476a31..78c2149aa7 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts @@ -25,7 +25,7 @@ export class HaWaitForTriggerAction @property({ attribute: false }) public path?: ItemPath; - public static get defaultConfig() { + public static get defaultConfig(): WaitForTriggerAction { return { wait_for_trigger: [] }; } diff --git a/src/panels/config/automation/action/types/ha-automation-action-wait_template.ts b/src/panels/config/automation/action/types/ha-automation-action-wait_template.ts index 01f708ff3e..d8aa32296c 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-wait_template.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-wait_template.ts @@ -34,7 +34,7 @@ export class HaWaitAction extends LitElement implements ActionElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { + public static get defaultConfig(): WaitAction { return { wait_template: "", continue_on_timeout: true }; } diff --git a/src/panels/config/automation/condition/ha-automation-condition.ts b/src/panels/config/automation/condition/ha-automation-condition.ts index d164a6ee21..4ee3e674b4 100644 --- a/src/panels/config/automation/condition/ha-automation-condition.ts +++ b/src/panels/config/automation/condition/ha-automation-condition.ts @@ -207,10 +207,9 @@ export default class HaAutomationCondition extends LitElement { const elClass = customElements.get( `ha-automation-condition-${condition}` ) as CustomElementConstructor & { - defaultConfig: Omit; + defaultConfig: Condition; }; conditions = this.conditions.concat({ - condition: condition as any, ...elClass.defaultConfig, }); } diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-and.ts b/src/panels/config/automation/condition/types/ha-automation-condition-and.ts index 482d593d91..ee7fa15d90 100644 --- a/src/panels/config/automation/condition/types/ha-automation-condition-and.ts +++ b/src/panels/config/automation/condition/types/ha-automation-condition-and.ts @@ -1,8 +1,16 @@ import { customElement } from "lit/decorators"; import { HaLogicalCondition } from "./ha-automation-condition-logical"; +import { LogicalCondition } from "../../../../../data/automation"; @customElement("ha-automation-condition-and") -export class HaAndCondition extends HaLogicalCondition {} +export class HaAndCondition extends HaLogicalCondition { + public static get defaultConfig(): LogicalCondition { + return { + condition: "and", + conditions: [], + }; + } +} declare global { interface HTMLElementTagNameMap { diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-device.ts b/src/panels/config/automation/condition/types/ha-automation-condition-device.ts index 2e6faadaf9..a0dcee2cd9 100644 --- a/src/panels/config/automation/condition/types/ha-automation-condition-device.ts +++ b/src/panels/config/automation/condition/types/ha-automation-condition-device.ts @@ -36,8 +36,9 @@ export class HaDeviceCondition extends LitElement { private _origCondition?: DeviceCondition; - public static get defaultConfig() { + public static get defaultConfig(): DeviceCondition { return { + condition: "device", device_id: "", domain: "", entity_id: "", diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts b/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts index 4716131c35..caa875377d 100644 --- a/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts +++ b/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts @@ -7,7 +7,10 @@ import "../ha-automation-condition"; import type { ConditionElement } from "../ha-automation-condition-row"; @customElement("ha-automation-condition-logical") -export class HaLogicalCondition extends LitElement implements ConditionElement { +export abstract class HaLogicalCondition + extends LitElement + implements ConditionElement +{ @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public condition!: LogicalCondition; @@ -16,12 +19,6 @@ export class HaLogicalCondition extends LitElement implements ConditionElement { @property({ attribute: false }) public path?: ItemPath; - public static get defaultConfig() { - return { - conditions: [], - }; - } - protected render() { return html` ; + defaultConfig: Trigger; }; triggers = this.triggers.concat({ - platform: platform as any, ...elClass.defaultConfig, }); } diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-calendar.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-calendar.ts index 44754c8b31..a1f7b2d54f 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-calendar.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-calendar.ts @@ -69,10 +69,12 @@ export class HaCalendarTrigger extends LitElement implements TriggerElement { ] as const ); - public static get defaultConfig() { + public static get defaultConfig(): CalendarTrigger { return { + platform: "calendar", + entity_id: "", event: "start" as CalendarTrigger["event"], - offset: 0, + offset: "0", }; } diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts index 4cb5abd86b..7a7ba188fa 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts @@ -25,8 +25,8 @@ export class HaConversationTrigger @query("#option_input", true) private _optionInput?: HaTextField; - public static get defaultConfig(): Omit { - return { command: "" }; + public static get defaultConfig(): ConversationTrigger { + return { platform: "conversation", command: "" }; } protected render() { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts index c69c21b68c..660f43beb9 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts @@ -38,8 +38,9 @@ export class HaDeviceTrigger extends LitElement { private _origTrigger?: DeviceTrigger; - public static get defaultConfig() { + public static get defaultConfig(): DeviceTrigger { return { + platform: "device", device_id: "", domain: "", entity_id: "", diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-event.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-event.ts index 5904efdba5..2685ff25f1 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-event.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-event.ts @@ -19,8 +19,8 @@ export class HaEventTrigger extends LitElement implements TriggerElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { - return { event_type: "" }; + public static get defaultConfig(): EventTrigger { + return { platform: "event", event_type: "" }; } protected render() { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location.ts index 849a91b2d8..38605caeed 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location.ts @@ -43,8 +43,9 @@ export class HaGeolocationTrigger extends LitElement { ] as const ); - public static get defaultConfig() { + public static get defaultConfig(): GeoLocationTrigger { return { + platform: "geo_location", source: "", zone: "", event: "enter" as GeoLocationTrigger["event"], diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts index d0d9629d7e..94f241a93a 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant.ts @@ -41,8 +41,9 @@ export class HaHassTrigger extends LitElement { ] as const ); - public static get defaultConfig() { + public static get defaultConfig(): HassTrigger { return { + platform: "homeassistant", event: "start" as HassTrigger["event"], }; } diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt.ts index e01df554e9..78a4874880 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt.ts @@ -20,8 +20,8 @@ export class HaMQTTTrigger extends LitElement implements TriggerElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { - return { topic: "" }; + public static get defaultConfig(): MqttTrigger { + return { platform: "mqtt", topic: "" }; } protected render() { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state.ts index f2d0d72e5f..f7b812c511 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state.ts @@ -237,8 +237,9 @@ export class HaNumericStateTrigger extends LitElement { } } - public static get defaultConfig() { + public static get defaultConfig(): NumericStateTrigger { return { + platform: "numeric_state", entity_id: [], }; } diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts index ee3a1743d4..f08ef50a09 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts @@ -70,8 +70,9 @@ export class HaPersistentNotificationTrigger ] as const ); - public static get defaultConfig() { + public static get defaultConfig(): PersistentNotificationTrigger { return { + platform: "persistent_notification", update_type: [...DEFAULT_UPDATE_TYPES], notification_id: DEFAULT_NOTIFICATION_ID, }; diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts index 4899fb19ee..51f5503074 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts @@ -48,8 +48,8 @@ export class HaStateTrigger extends LitElement implements TriggerElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { - return { entity_id: [] }; + public static get defaultConfig(): StateTrigger { + return { platform: "state", entity_id: [] }; } private _schema = memoizeOne( diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts index 3696952110..a60db83391 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-sun.ts @@ -43,8 +43,9 @@ export class HaSunTrigger extends LitElement implements TriggerElement { ] as const ); - public static get defaultConfig() { + public static get defaultConfig(): SunTrigger { return { + platform: "sun", event: "sunrise" as SunTrigger["event"], offset: 0, }; diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts index 7857ea17b5..e7f82d8c77 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts @@ -19,8 +19,8 @@ export class HaTagTrigger extends LitElement implements TriggerElement { @state() private _tags?: Tag[]; - public static get defaultConfig() { - return { tag_id: "" }; + public static get defaultConfig(): TagTrigger { + return { platform: "tag", tag_id: "" }; } protected firstUpdated(changedProperties: PropertyValues) { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts index b1c85eb460..a12464b22f 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-template.ts @@ -22,8 +22,8 @@ export class HaTemplateTrigger extends LitElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { - return { value_template: "" }; + public static get defaultConfig(): TemplateTrigger { + return { platform: "template", value_template: "" }; } public willUpdate(changedProperties: PropertyValues) { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-time.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-time.ts index c2b23d175c..e7db9bba11 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-time.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-time.ts @@ -19,8 +19,8 @@ export class HaTimeTrigger extends LitElement implements TriggerElement { @state() private _inputMode?: boolean; - public static get defaultConfig() { - return { at: "" }; + public static get defaultConfig(): TimeTrigger { + return { platform: "time", at: "" }; } private _schema = memoizeOne( diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern.ts index 862ce881f6..9217495673 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern.ts @@ -21,8 +21,8 @@ export class HaTimePatternTrigger extends LitElement implements TriggerElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { - return {}; + public static get defaultConfig(): TimePatternTrigger { + return { platform: "time_pattern" }; } protected render() { diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-webhook.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-webhook.ts index 86bee36fb5..9adf5a05d5 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-webhook.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-webhook.ts @@ -36,8 +36,9 @@ export class HaWebhookTrigger extends LitElement { private _unsub?: UnsubscribeFunc; - public static get defaultConfig() { + public static get defaultConfig(): WebhookTrigger { return { + platform: "webhook", allowed_methods: [...DEFAULT_METHODS], local_only: true, webhook_id: DEFAULT_WEBHOOK_ID, diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-zone.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-zone.ts index 7ddf87ccdf..fa0676094d 100644 --- a/src/panels/config/automation/trigger/types/ha-automation-trigger-zone.ts +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-zone.ts @@ -23,8 +23,9 @@ export class HaZoneTrigger extends LitElement { @property({ type: Boolean }) public disabled = false; - public static get defaultConfig() { + public static get defaultConfig(): ZoneTrigger { return { + platform: "zone", entity_id: "", zone: "", event: "enter" as ZoneTrigger["event"], diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts index f299991245..fe3151b260 100644 --- a/src/panels/config/ha-panel-config.ts +++ b/src/panels/config/ha-panel-config.ts @@ -51,7 +51,6 @@ import { SubscribeMixin } from "../../mixins/subscribe-mixin"; import { HomeAssistant, Route } from "../../types"; import { subscribeLabelRegistry } from "../../data/label_registry"; import { subscribeFloorRegistry } from "../../data/floor_registry"; -import { throttle } from "../../common/util/throttle"; declare global { // for fire event @@ -396,10 +395,6 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) { initialValue: [], }); - private _hassThrottler = throttle((el, hass) => { - el.hass = hass; - }, 1000); - public hassSubscribe(): UnsubscribeFunc[] { return [ subscribeEntityRegistry(this.hass.connection!, (entities) => { @@ -646,11 +641,7 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) { this.hass.dockedSidebar === "docked" ? this._wideSidebar : this._wide; el.route = this.routeTail; - if (el.hass !== undefined) { - this._hassThrottler(el, this.hass); - } else { - el.hass = this.hass; - } + el.hass = this.hass; el.showAdvanced = Boolean(this.hass.userData?.showAdvanced); el.isWide = isWide; el.narrow = this.narrow; diff --git a/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts index 6952b58b66..46e09608c9 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-devices-detail-graph-card.ts @@ -377,7 +377,9 @@ export class HuiEnergyDevicesDetailGraphCard }); }); const dataset = { - label: this.hass.localize("ui.panel.energy.charts.untracked_consumption"), + label: this.hass.localize( + "ui.panel.lovelace.cards.energy.energy_devices_detail_graph.untracked_consumption" + ), hidden: this._hiddenStats.includes("untracked"), borderColor: getEnergyColor( computedStyle, diff --git a/src/panels/lovelace/editor/badge-editor/hui-badge-element-editor.ts b/src/panels/lovelace/editor/badge-editor/hui-badge-element-editor.ts index 6e8bc7dab7..1fdeddb564 100644 --- a/src/panels/lovelace/editor/badge-editor/hui-badge-element-editor.ts +++ b/src/panels/lovelace/editor/badge-editor/hui-badge-element-editor.ts @@ -1,5 +1,5 @@ -import "@polymer/paper-tabs/paper-tab"; -import "@polymer/paper-tabs/paper-tabs"; +import "@material/mwc-tab-bar/mwc-tab-bar"; +import "@material/mwc-tab/mwc-tab"; import { css, CSSResultGroup, html, nothing, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators"; import { LovelaceBadgeConfig } from "../../../../data/lovelace/config/badge"; @@ -8,11 +8,11 @@ import type { LovelaceCardEditor, LovelaceConfigForm } from "../../types"; import { HuiElementEditor } from "../hui-element-editor"; import "./hui-badge-visibility-editor"; -type Tab = "config" | "visibility"; +const tabs = ["config", "visibility"] as const; @customElement("hui-badge-element-editor") export class HuiBadgeElementEditor extends HuiElementEditor { - @state() private _curTab: Tab = "config"; + @state() private _currTab: (typeof tabs)[number] = tabs[0]; protected async getConfigElement(): Promise { const elClass = await getBadgeElementClass(this.configElementType!); @@ -36,11 +36,12 @@ export class HuiBadgeElementEditor extends HuiElementEditor return undefined; } - private _handleTabSelected(ev: CustomEvent): void { - if (!ev.detail.value) { + private _handleTabChanged(ev: CustomEvent): void { + const newTab = tabs[ev.detail.index]; + if (newTab === this._currTab) { return; } - this._curTab = ev.detail.value.id; + this._currTab = newTab; } private _configChanged(ev: CustomEvent): void { @@ -49,11 +50,9 @@ export class HuiBadgeElementEditor extends HuiElementEditor } protected renderConfigElement(): TemplateResult { - const displayedTabs: Tab[] = ["config", "visibility"]; - let content: TemplateResult<1> | typeof nothing = nothing; - switch (this._curTab) { + switch (this._currTab) { case "config": content = html`${super.renderConfigElement()}`; break; @@ -68,22 +67,21 @@ export class HuiBadgeElementEditor extends HuiElementEditor break; } return html` - - ${displayedTabs.map( - (tab, index) => html` - - ${this.hass.localize( + ${tabs.map( + (tab) => html` + + > + ` )} - + ${content} `; } @@ -92,9 +90,7 @@ export class HuiBadgeElementEditor extends HuiElementEditor return [ HuiElementEditor.styles, css` - paper-tabs { - --paper-tabs-selection-bar-color: var(--primary-color); - color: var(--primary-text-color); + mwc-tab-bar { text-transform: uppercase; margin-bottom: 16px; border-bottom: 1px solid var(--divider-color); diff --git a/src/panels/lovelace/editor/section-editor/hui-section-settings-editor.ts b/src/panels/lovelace/editor/section-editor/hui-section-settings-editor.ts index 949d57941b..d7a9a96749 100644 --- a/src/panels/lovelace/editor/section-editor/hui-section-settings-editor.ts +++ b/src/panels/lovelace/editor/section-editor/hui-section-settings-editor.ts @@ -2,7 +2,6 @@ import { LitElement, html } from "lit"; import { customElement, property } from "lit/decorators"; import memoizeOne from "memoize-one"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { LocalizeFunc } from "../../../../common/translations/localize"; import { HaFormSchema, SchemaUnion, @@ -25,7 +24,7 @@ export class HuiDialogEditSection extends LitElement { @property({ attribute: false }) public viewConfig!: LovelaceViewConfig; private _schema = memoizeOne( - (localize: LocalizeFunc, maxColumns: number) => + (maxColumns: number) => [ { name: "title", @@ -37,9 +36,7 @@ export class HuiDialogEditSection extends LitElement { number: { min: 1, max: maxColumns, - unit_of_measurement: localize( - `ui.panel.lovelace.editor.edit_section.settings.column_span_unit` - ), + slider_ticks: true, }, }, }, @@ -52,10 +49,7 @@ export class HuiDialogEditSection extends LitElement { column_span: this.config.column_span || 1, }; - const schema = this._schema( - this.hass.localize, - this.viewConfig.max_columns || 4 - ); + const schema = this._schema(this.viewConfig.max_columns || 4); return html` { switch (schema.name) { case "subview": + case "dense_section_placement": return this.hass.localize( - "ui.panel.lovelace.editor.edit_view.subview_helper" + `ui.panel.lovelace.editor.edit_view.${schema.name}_helper` ); + default: return undefined; } diff --git a/src/panels/lovelace/views/hui-sections-view.ts b/src/panels/lovelace/views/hui-sections-view.ts index 7f2781f74b..79cb0cf99f 100644 --- a/src/panels/lovelace/views/hui-sections-view.ts +++ b/src/panels/lovelace/views/hui-sections-view.ts @@ -9,6 +9,7 @@ import { nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { classMap } from "lit/directives/class-map"; import { repeat } from "lit/directives/repeat"; import { styleMap } from "lit/directives/style-map"; import "../../../components/ha-icon-button"; @@ -47,7 +48,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement { @state() private _config?: LovelaceViewConfig; - @state() private _sectionCount = 0; + @state() private _sectionColumnCount = 0; @state() _dragging = false; @@ -89,9 +90,10 @@ export class SectionsView extends LitElement implements LovelaceViewElement { } private _computeSectionsCount() { - this._sectionCount = this.sections.filter( - (section) => !section.hidden - ).length; + this._sectionColumnCount = this.sections + .filter((section) => !section.hidden) + .map((section) => section.config.column_span ?? 1) + .reduce((acc, val) => acc + val, 0); } private _sectionVisibilityChanged = () => { @@ -125,7 +127,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement { const sections = this.sections; const totalSectionCount = - this._sectionCount + (this.lovelace?.editMode ? 1 : 0); + this._sectionColumnCount + (this.lovelace?.editMode ? 1 : 0); const editMode = this.lovelace.editMode; const maxColumnCount = this._columnsController.value ?? 1; @@ -146,7 +148,9 @@ export class SectionsView extends LitElement implements LovelaceViewElement { .rollback=${false} >