Skip to content

Commit

Permalink
Add configuration to default dashboard (#18658)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Lamon <[email protected]>
  • Loading branch information
piitaya and silamon authored Nov 22, 2023
1 parent 0735705 commit 270d463
Show file tree
Hide file tree
Showing 15 changed files with 521 additions and 29 deletions.
13 changes: 7 additions & 6 deletions src/components/ha-area-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ export class HaAreaPicker extends LitElement {
item-value-path="area_id"
item-id-path="area_id"
item-label-path="name"
.value=${this.value}
.value=${this._value}
.disabled=${this.disabled}
.required=${this.required}
.label=${this.label === undefined && this.hass
Expand All @@ -347,18 +347,19 @@ export class HaAreaPicker extends LitElement {
}

private _filterChanged(ev: CustomEvent): void {
const filter = ev.detail.value;
if (!filter) {
const target = ev.target as HaComboBox;
const filterString = ev.detail.value;
if (!filterString) {
this.comboBox.filteredItems = this.comboBox.items;
return;
}

const filteredItems = fuzzyFilterSort<ScorableAreaRegistryEntry>(
filter,
this.comboBox?.items || []
filterString,
target.items || []
);
if (!this.noAdd && filteredItems?.length === 0) {
this._suggestion = filter;
this._suggestion = filterString;
this.comboBox.filteredItems = [
{
area_id: "add_new_suggestion",
Expand Down
1 change: 1 addition & 0 deletions src/components/ha-areas-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export class HaAreasPicker extends SubscribeMixin(LitElement) {
.placeholder=${this.placeholder}
.required=${this.required && !currentAreas.length}
@value-changed=${this._addArea}
.excludeAreas=${currentAreas}
></ha-area-picker>
</div>
`;
Expand Down
20 changes: 18 additions & 2 deletions src/panels/lovelace/common/generate-lovelace-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,12 @@ export const generateDefaultViewConfig = (
entityEntries: HomeAssistant["entities"],
entities: HassEntities,
localize: LocalizeFunc,
energyPrefs?: EnergyPreferences
energyPrefs?: EnergyPreferences,
areasPrefs?: {
hidden?: string[];
},
hideEntitiesWithoutAreas?: boolean,
hideEnergy?: boolean
): LovelaceViewConfig => {
const states = computeDefaultViewStates(entities, entityEntries);
const path = "default_view";
Expand All @@ -469,6 +474,17 @@ export const generateDefaultViewConfig = (
states
);

if (areasPrefs?.hidden) {
for (const area of areasPrefs.hidden) {
splittedByAreaDevice.areasWithEntities[area] = [];
}
}

if (hideEntitiesWithoutAreas) {
splittedByAreaDevice.devicesWithEntities = {};
splittedByAreaDevice.otherEntities = {};
}

const splittedByGroups = splitByGroups(splittedByAreaDevice.otherEntities);
splittedByGroups.groups.sort(
(gr1, gr2) => groupOrders[gr1.entity_id] - groupOrders[gr2.entity_id]
Expand Down Expand Up @@ -553,7 +569,7 @@ export const generateDefaultViewConfig = (

let energyCard: LovelaceCardConfig | undefined;

if (energyPrefs) {
if (energyPrefs && !hideEnergy) {
// Distribution card requires the grid to be configured
const grid = energyPrefs.energy_sources.find(
(source) => source.type === "grid"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { customElement } from "lit/decorators";
import { LovelaceDashboardStrategyConfig } from "../../../../data/lovelace/config/types";
import { getLovelaceStrategy } from "../../strategies/get-strategy";
import { LovelaceStrategyEditor } from "../../strategies/types";
import { HuiElementEditor } from "../hui-element-editor";

@customElement("hui-dashboard-strategy-element-editor")
export class HuiDashboardStrategyElementEditor extends HuiElementEditor<LovelaceDashboardStrategyConfig> {
protected async getConfigElement(): Promise<
LovelaceStrategyEditor | undefined
> {
const elClass = await getLovelaceStrategy(
"dashboard",
this.configElementType!
);

// Check if a GUI editor exists
if (elClass && elClass.getConfigElement) {
return elClass.getConfigElement();
}

return undefined;
}
}

declare global {
interface HTMLElementTagNameMap {
"hui-dashboard-strategy-element-editor": HuiDashboardStrategyElementEditor;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
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 "../../../../components/ha-form/ha-form";
import type {
HaFormSchema,
SchemaUnion,
} from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types";
import { OriginalStatesDashboardStrategyConfig } from "../../strategies/original-states-dashboard-strategy";
import { LovelaceStrategyEditor } from "../../strategies/types";

const SCHEMA = [
{
name: "hidden_areas",
selector: {
area: {
multiple: true,
},
},
},
{
name: "",
type: "grid",
schema: [
{
name: "hide_entities_without_area",
selector: {
boolean: {},
},
},
{
name: "hide_energy",
selector: {
boolean: {},
},
},
],
},
] as const satisfies readonly HaFormSchema[];

type FormData = {
hidden_areas: string[];
hide_energy?: boolean;
hide_entities_without_area?: boolean;
};

@customElement("hui-original-states-dashboard-strategy-editor")
export class HuiOriginalStatesDashboarStrategyEditor
extends LitElement
implements LovelaceStrategyEditor
{
@property({ attribute: false }) public hass?: HomeAssistant;

@state()
private _config?: OriginalStatesDashboardStrategyConfig;

public setConfig(config: OriginalStatesDashboardStrategyConfig): void {
this._config = config;
}

private _configToFormData = memoizeOne(
(config: OriginalStatesDashboardStrategyConfig): FormData => {
const { areas, ...rest } = config;
return {
...rest,
hidden_areas: areas?.hidden || [],
};
}
);

private _formDataToConfig = memoizeOne(
(data: FormData): OriginalStatesDashboardStrategyConfig => {
const { hidden_areas, ...rest } = data;
const areas =
hidden_areas.length > 0
? {
hidden: hidden_areas,
}
: undefined;
return {
type: "original-states",
...rest,
areas,
};
}
);

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

const data = this._configToFormData(this._config);

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 {
const data = ev.detail.value as FormData;
const config = this._formDataToConfig(data);
fireEvent(this, "config-changed", { config });
}

private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
switch (schema.name) {
case "hidden_areas":
case "hide_energy":
case "hide_entities_without_area":
return this.hass?.localize(
`ui.panel.lovelace.editor.strategy.original-states.${schema.name}`
);
default:
return "";
}
};
}

declare global {
interface HTMLElementTagNameMap {
"hui-original-states-dashboard-strategy-editor": HuiOriginalStatesDashboarStrategyEditor;
}
}
8 changes: 5 additions & 3 deletions src/panels/lovelace/editor/hui-element-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import "../../../components/ha-alert";
import "../../../components/ha-circular-progress";
import "../../../components/ha-code-editor";
import type { HaCodeEditor } from "../../../components/ha-code-editor";
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
import type { LovelaceConfig } from "../../../data/lovelace/config/types";
import { LovelaceCardConfig } from "../../../data/lovelace/config/card";
import { LovelaceStrategyConfig } from "../../../data/lovelace/config/strategy";
import { LovelaceConfig } from "../../../data/lovelace/config/types";
import type { HomeAssistant } from "../../../types";
import type { LovelaceRowConfig } from "../entity-rows/types";
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
Expand All @@ -36,7 +37,8 @@ export interface ConfigChangedEvent {
| LovelaceCardConfig
| LovelaceRowConfig
| LovelaceHeaderFooterConfig
| LovelaceTileFeatureConfig;
| LovelaceTileFeatureConfig
| LovelaceStrategyConfig;
error?: string;
guiModeAvailable?: boolean;
}
Expand Down
32 changes: 29 additions & 3 deletions src/panels/lovelace/hui-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import {
import "@polymer/paper-tabs/paper-tab";
import "@polymer/paper-tabs/paper-tabs";
import {
css,
CSSResultGroup,
html,
LitElement,
PropertyValues,
TemplateResult,
css,
html,
} from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
Expand Down Expand Up @@ -64,11 +64,17 @@ import { documentationUrl } from "../../util/documentation-url";
import { swapView } from "./editor/config-util";
import { showEditLovelaceDialog } from "./editor/lovelace-editor/show-edit-lovelace-dialog";
import { showEditViewDialog } from "./editor/view-editor/show-edit-view-dialog";
import { showDashboardStrategyEditorDialog } from "./strategies/device-registry-detail/show-dialog-dashboard-strategy-editor";
import type { Lovelace } from "./types";
import "./views/hui-view";
import type { HUIView } from "./views/hui-view";
import { LovelaceViewConfig } from "../../data/lovelace/config/view";
import { LovelaceConfig } from "../../data/lovelace/config/types";
import {
LovelaceConfig,
isStrategyDashboard,
} from "../../data/lovelace/config/types";
import { showSaveDialog } from "./editor/show-save-config-dialog";
import { isLegacyStrategyConfig } from "./strategies/legacy-strategy";

@customElement("hui-root")
class HUIRoot extends LitElement {
Expand Down Expand Up @@ -813,6 +819,26 @@ class HUIRoot extends LitElement {
});
return;
}
if (
isStrategyDashboard(this.lovelace!.rawConfig) &&
!isLegacyStrategyConfig(this.lovelace!.rawConfig.strategy)
) {
showDashboardStrategyEditorDialog(this, {
config: this.lovelace!.rawConfig,
saveConfig: this.lovelace!.saveConfig,
takeControl: () => {
showSaveDialog(this, {
lovelace: this.lovelace!,
mode: "storage",
narrow: this.narrow!,
});
},
showRawConfigEditor: () => {
this.lovelace!.enableFullEditMode();
},
});
return;
}
this.lovelace!.setEditMode(true);
}

Expand Down
Loading

0 comments on commit 270d463

Please sign in to comment.