Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
bramkragten committed May 1, 2024
2 parents ef4f11f + 68a7949 commit e2266aa
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 39 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "home-assistant-frontend"
version = "20240430.0"
version = "20240501.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
Expand Down
7 changes: 7 additions & 0 deletions src/data/alarm_control_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
HassEntityBase,
} from "home-assistant-js-websocket";
import { HomeAssistant } from "../types";
import { supportsFeature } from "../common/entity/supports-feature";

export const FORMAT_TEXT = "text";
export const FORMAT_NUMBER = "number";
Expand Down Expand Up @@ -96,3 +97,9 @@ export const ALARM_MODES: Record<AlarmMode, AlarmConfig> = {
path: mdiShieldOff,
},
};

export const supportedAlarmModes = (stateObj: AlarmControlPanelEntity) =>
(Object.keys(ALARM_MODES) as AlarmMode[]).filter((mode) => {
const feature = ALARM_MODES[mode].feature;
return !feature || supportsFeature(stateObj, feature);
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import {
AlarmControlPanelEntity,
AlarmMode,
ALARM_MODES,
supportedAlarmModes,
} from "../../../data/alarm_control_panel";
import { UNAVAILABLE } from "../../../data/entity";
import { HomeAssistant } from "../../../types";
import { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
import { AlarmModesCardFeatureConfig } from "./types";
import { showEnterCodeDialog } from "../../../dialogs/enter-code/show-enter-code-dialog";
import { filterModes } from "./common/filter-modes";

export const supportsAlarmModesCardFeature = (stateObj: HassEntity) => {
const domain = computeDomain(stateObj.entity_id);
Expand Down Expand Up @@ -164,9 +166,12 @@ class HuiAlarmModeCardFeature

const color = stateColorCss(this.stateObj);

const modes = this._modes(this.stateObj, this._config.modes);
const supportedModes = supportedAlarmModes(this.stateObj);

const options = modes.map<ControlSelectOption>((mode) => ({
const options = filterModes(
supportedModes,
this._config.modes
).map<ControlSelectOption>((mode) => ({
value: mode,
label: this.hass!.localize(`ui.card.alarm_control_panel.modes.${mode}`),
path: ALARM_MODES[mode].path,
Expand Down Expand Up @@ -196,7 +201,7 @@ class HuiAlarmModeCardFeature
)}
style=${styleMap({
"--control-select-color": color,
"--modes-count": modes.length.toString(),
"--modes-count": options.length.toString(),
})}
.disabled=${this.stateObj!.state === UNAVAILABLE}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@ 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 { supportsFeature } from "../../../../common/entity/supports-feature";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import type { SchemaUnion } from "../../../../components/ha-form/types";
import { AlarmMode, ALARM_MODES } from "../../../../data/alarm_control_panel";
import "../../../../components/ha-form/ha-form";
import type {
HaFormSchema,
SchemaUnion,
} from "../../../../components/ha-form/types";
import { supportedAlarmModes } from "../../../../data/alarm_control_panel";
import type { HomeAssistant } from "../../../../types";
import {
LovelaceCardFeatureContext,
AlarmModesCardFeatureConfig,
LovelaceCardFeatureContext,
} from "../../card-features/types";
import type { LovelaceCardFeatureEditor } from "../../types";
import "../../../../components/ha-form/ha-form";

type AlarmModesCardFeatureData = AlarmModesCardFeatureConfig & {
customize_modes: boolean;
};

@customElement("hui-alarm-modes-card-feature-editor")
export class HuiAlarmModesCardFeatureEditor
Expand All @@ -31,48 +37,66 @@ export class HuiAlarmModesCardFeatureEditor
}

private _schema = memoizeOne(
(localize: LocalizeFunc, stateObj?: HassEntity) =>
(
localize: LocalizeFunc,
stateObj: HassEntity | undefined,
customizeModes: boolean
) =>
[
{
name: "modes",
name: "customize_modes",
selector: {
select: {
multiple: true,
mode: "list",
options: Object.keys(ALARM_MODES)
.filter((mode) => {
const feature = ALARM_MODES[mode as AlarmMode].feature;
return (
stateObj && (!feature || supportsFeature(stateObj, feature))
);
})
.map((mode) => ({
value: mode,
label: `${localize(
`ui.panel.lovelace.editor.features.types.alarm-modes.modes_list.${mode}`
)}`,
})),
},
boolean: {},
},
},
] as const
...(customizeModes
? ([
{
name: "modes",
selector: {
select: {
multiple: true,
reorder: true,
options: stateObj
? supportedAlarmModes(stateObj).map((mode) => ({
value: mode,
label: `${localize(
`ui.panel.lovelace.editor.features.types.alarm-modes.modes_list.${mode}`
)}`,
}))
: [],
},
},
},
] as const satisfies readonly HaFormSchema[])
: []),
] as const satisfies readonly HaFormSchema[]
);

protected render() {
if (!this.hass || !this._config) {
return nothing;
}

const data: AlarmModesCardFeatureData = {
...this._config,
customize_modes: this._config.modes !== undefined,
};

const stateObj = this.context?.entity_id
? this.hass.states[this.context?.entity_id]
: undefined;

const schema = this._schema(this.hass.localize, stateObj);
const schema = this._schema(
this.hass.localize,
stateObj,
data.customize_modes
);

return html`
<ha-form
.hass=${this.hass}
.data=${this._config}
.data=${data}
.schema=${schema}
.computeLabel=${this._computeLabelCallback}
@value-changed=${this._valueChanged}
Expand All @@ -81,21 +105,34 @@ export class HuiAlarmModesCardFeatureEditor
}

private _valueChanged(ev: CustomEvent): void {
fireEvent(this, "config-changed", { config: ev.detail.value });
const { customize_modes, ...config } = ev.detail
.value as AlarmModesCardFeatureData;

const stateObj = this.context?.entity_id
? this.hass!.states[this.context?.entity_id]
: undefined;

if (customize_modes && !config.modes) {
config.modes = stateObj ? supportedAlarmModes(stateObj) : [];
}
if (!customize_modes && config.modes) {
delete config.modes;
}

fireEvent(this, "config-changed", { config: config });
}

private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
) => {
switch (schema.name) {
case "modes":
case "customize_modes":
return this.hass!.localize(
`ui.panel.lovelace.editor.features.types.alarm-modes.${schema.name}`
);
default:
return this.hass!.localize(
`ui.panel.lovelace.editor.card.generic.${schema.name}`
);
return "";
}
};
}
Expand Down
4 changes: 2 additions & 2 deletions src/panels/lovelace/hui-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -886,9 +886,9 @@ class HUIRoot extends LitElement {
const configBackground = viewConfig.background || this.config.background;

if (configBackground) {
this.style.setProperty("--lovelace-background", configBackground);
root.style.setProperty("--lovelace-background", configBackground);
} else {
this.style.removeProperty("--lovelace-background");
root.style.removeProperty("--lovelace-background");
}

root.appendChild(view);
Expand Down
29 changes: 28 additions & 1 deletion src/panels/lovelace/views/hui-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ export class HUIView extends ReactiveElement {
return this;
}

public connectedCallback(): void {
super.connectedCallback();
this._applyTheme();
}

public willUpdate(changedProperties: PropertyValues): void {
super.willUpdate(changedProperties);

Expand Down Expand Up @@ -212,7 +217,7 @@ export class HUIView extends ReactiveElement {
this.hass.themes !== oldHass.themes ||
this.hass.selectedTheme !== oldHass.selectedTheme
) {
applyThemesOnElement(this, this.hass.themes, this._viewConfigTheme);
this._applyTheme();
}
}
if (changedProperties.has("narrow")) {
Expand All @@ -238,6 +243,28 @@ export class HUIView extends ReactiveElement {
}
}

private _applyTheme() {
applyThemesOnElement(this, this.hass.themes, this._viewConfigTheme);
if (this._viewConfigTheme) {
// Set lovelace background color to root element, so it will be placed under the header too
const computedStyles = getComputedStyle(this);
let lovelaceBackground = computedStyles.getPropertyValue(
"--lovelace-background"
);
if (!lovelaceBackground) {
lovelaceBackground = computedStyles.getPropertyValue(
"--primary-background-color"
);
}
if (lovelaceBackground) {
this.parentElement?.style.setProperty(
"--lovelace-background",
lovelaceBackground
);
}
}
}

private async _initializeConfig() {
let viewConfig = this.lovelace.config.views[this.index];
let isStrategy = false;
Expand Down
3 changes: 2 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5970,7 +5970,8 @@
"armed_vacation": "[%key:ui::card::alarm_control_panel::modes::armed_vacation%]",
"armed_custom_bypass": "[%key:ui::card::alarm_control_panel::modes::armed_custom_bypass%]",
"disarmed": "[%key:ui::card::alarm_control_panel::modes::disarmed%]"
}
},
"customize_modes": "Customize alarm modes"
},
"light-brightness": {
"label": "Light brightness"
Expand Down

0 comments on commit e2266aa

Please sign in to comment.