From 4a9b09b5f93c4b23a779fbce3b0fbe812bf3339f Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 3 Feb 2022 11:41:17 -0800 Subject: [PATCH 1/4] Add selectors to ha-form --- .../src/components/demo-black-white-row.ts | 1 + gallery/src/pages/components/ha-form.ts | 60 ++++++++++++++++++- src/components/ha-form/ha-form.ts | 25 ++++++-- src/components/ha-form/types.ts | 15 ++++- 4 files changed, 92 insertions(+), 9 deletions(-) diff --git a/gallery/src/components/demo-black-white-row.ts b/gallery/src/components/demo-black-white-row.ts index 92a4beeffe29..549f10554c48 100644 --- a/gallery/src/components/demo-black-white-row.ts +++ b/gallery/src/components/demo-black-white-row.ts @@ -3,6 +3,7 @@ import { html, LitElement, css, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; import { fireEvent } from "../../../src/common/dom/fire_event"; +import "../../../src/components/ha-card"; @customElement("demo-black-white-row") class DemoBlackWhiteRow extends LitElement { diff --git a/gallery/src/pages/components/ha-form.ts b/gallery/src/pages/components/ha-form.ts index c25ff1067fed..a1be3cdc0cea 100644 --- a/gallery/src/pages/components/ha-form.ts +++ b/gallery/src/pages/components/ha-form.ts @@ -1,11 +1,17 @@ /* eslint-disable lit/no-template-arrow */ import "@material/mwc-button"; import { LitElement, TemplateResult, html } from "lit"; -import { customElement } from "lit/decorators"; +import { customElement, state } from "lit/decorators"; import { computeInitialHaFormData } from "../../../../src/components/ha-form/compute-initial-ha-form-data"; import type { HaFormSchema } from "../../../../src/components/ha-form/types"; import "../../../../src/components/ha-form/ha-form"; import "../../components/demo-black-white-row"; +import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry"; +import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry"; +import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry"; +import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor"; +import { provideHass } from "../../../../src/fake_data/provide_hass"; +import { HomeAssistant } from "../../../../src/types"; const SCHEMAS: { title: string; @@ -14,6 +20,44 @@ const SCHEMAS: { schema: HaFormSchema[]; data?: Record; }[] = [ + { + title: "Selectors", + translations: { + addon: "Addon", + entity: "Entity", + device: "Device", + area: "Area", + target: "Target", + number: "Number", + boolean: "Boolean", + time: "Time", + action: "Action", + text: "Text", + text_multiline: "Text Multiline", + object: "Object", + select: "Select", + }, + schema: [ + { name: "addon", selector: { addon: {} } }, + { name: "entity", selector: { entity: {} } }, + { name: "device", selector: { device: {} } }, + { name: "area", selector: { area: {} } }, + { name: "target", selector: { target: {} } }, + { name: "number", selector: { number: { min: 0, max: 10 } } }, + { name: "boolean", selector: { boolean: {} } }, + { name: "time", selector: { time: {} } }, + { name: "action", selector: { action: {} } }, + { name: "text", selector: { text: { multiline: false } } }, + { name: "text_multiline", selector: { text: { multiline: true } } }, + { name: "object", selector: { object: {} } }, + { + name: "select", + selector: { + select: { options: ["Everyone Home", "Some Home", "All gone"] }, + }, + }, + ], + }, { title: "Authentication", translations: { @@ -239,12 +283,25 @@ const SCHEMAS: { @customElement("demo-components-ha-form") class DemoHaForm extends LitElement { + @state() private hass!: HomeAssistant; + private data = SCHEMAS.map( ({ schema, data }) => data || computeInitialHaFormData(schema) ); private disabled = SCHEMAS.map(() => false); + constructor() { + super(); + const hass = provideHass(this); + hass.updateTranslations(null, "en"); + hass.updateTranslations("config", "en"); + mockEntityRegistry(hass); + mockDeviceRegistry(hass); + mockAreaRegistry(hass); + mockHassioSupervisor(hass); + } + protected render(): TemplateResult { return html` ${SCHEMAS.map((info, idx) => { @@ -267,6 +324,7 @@ class DemoHaForm extends LitElement { (slot) => html` (obj ? obj[item.name] : null); @customElement("ha-form") export class HaForm extends LitElement implements HaFormElement { + @property() public hass!: HomeAssistant; + @property() public data!: HaFormDataContainer; @property() public schema!: HaFormSchema[]; @@ -62,12 +66,21 @@ export class HaForm extends LitElement implements HaFormElement { ` : ""} - ${dynamicElement(`ha-form-${item.type}`, { - schema: item, - data: getValue(this.data, item), - label: this._computeLabel(item), - disabled: this.disabled, - })} + ${"selector" in item + ? html`` + : dynamicElement(`ha-form-${item.type}`, { + schema: item, + data: getValue(this.data, item), + label: this._computeLabel(item), + disabled: this.disabled, + })} `; })} diff --git a/src/components/ha-form/types.ts b/src/components/ha-form/types.ts index 86122bebc1e5..e9fb729daa97 100644 --- a/src/components/ha-form/types.ts +++ b/src/components/ha-form/types.ts @@ -1,4 +1,5 @@ import type { LitElement } from "lit"; +import { Selector } from "../../data/selector"; import type { HaDurationData } from "../ha-duration-input"; export type HaFormSchema = @@ -9,13 +10,23 @@ export type HaFormSchema = | HaFormBooleanSchema | HaFormSelectSchema | HaFormMultiSelectSchema - | HaFormTimeSchema; + | HaFormTimeSchema + | HaFormSelector; export interface HaFormBaseSchema { name: string; + // This value is applied if no data is submitted for this field default?: HaFormData; required?: boolean; - description?: { suffix?: string; suggested_value?: HaFormData }; + description?: { + suffix?: string; + // This value will be set initially when form is loaded + suggested_value?: HaFormData; + }; +} + +export interface HaFormSelector extends HaFormBaseSchema { + selector: Selector; } export interface HaFormConstantSchema extends HaFormBaseSchema { From 869617352ecc710abd4e221e3693204d25f2eb3a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 3 Feb 2022 14:35:19 -0800 Subject: [PATCH 2/4] Lint --- src/components/ha-form/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ha-form/types.ts b/src/components/ha-form/types.ts index e9fb729daa97..d6cfc573ef7e 100644 --- a/src/components/ha-form/types.ts +++ b/src/components/ha-form/types.ts @@ -26,6 +26,7 @@ export interface HaFormBaseSchema { } export interface HaFormSelector extends HaFormBaseSchema { + type?: never; selector: Selector; } From 64a9e95d1da3fdee473877eb65c509f2ff755bc8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 3 Feb 2022 16:56:45 -0800 Subject: [PATCH 3/4] Don't load ha-icon in supervisor --- build-scripts/bundle.js | 5 ++++- build-scripts/webpack.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/build-scripts/bundle.js b/build-scripts/bundle.js index 2325d80bcad4..c46796b5a2c7 100644 --- a/build-scripts/bundle.js +++ b/build-scripts/bundle.js @@ -10,7 +10,7 @@ module.exports.ignorePackages = ({ latestBuild }) => [ ]; // Files from NPM packages that we should replace with empty file -module.exports.emptyPackages = ({ latestBuild }) => +module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) => [ // Contains all color definitions for all material color sets. // We don't use it @@ -28,6 +28,8 @@ module.exports.emptyPackages = ({ latestBuild }) => ), // This polyfill is loaded in workers to support ES5, filter it out. latestBuild && require.resolve("proxy-polyfill/src/index.js"), + // Icons in supervisor conflict with icons in HA so we don't load. + isHassioBuild && require.resolve("../../src/components/ha-icon.ts"), ].filter(Boolean); module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({ @@ -196,6 +198,7 @@ module.exports.config = { publicPath: publicPath(latestBuild, paths.hassio_publicPath), isProdBuild, latestBuild, + isHassioBuild: true, defineOverlay: { __SUPERVISOR__: true, }, diff --git a/build-scripts/webpack.js b/build-scripts/webpack.js index bc07a7ec9f70..185ef3aa65c6 100644 --- a/build-scripts/webpack.js +++ b/build-scripts/webpack.js @@ -30,6 +30,7 @@ const createWebpackConfig = ({ isProdBuild, latestBuild, isStatsBuild, + isHassioBuild, dontHash, }) => { if (!dontHash) { @@ -117,7 +118,9 @@ const createWebpackConfig = ({ }, }), new webpack.NormalModuleReplacementPlugin( - new RegExp(bundle.emptyPackages({ latestBuild }).join("|")), + new RegExp( + bundle.emptyPackages({ latestBuild, isHassioBuild }).join("|") + ), path.resolve(paths.polymer_dir, "src/util/empty.js") ), !isProdBuild && new LogStartCompilePlugin(), From b57372ebb9967fbb925ac44b4084095838c54544 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 3 Feb 2022 21:38:55 -0800 Subject: [PATCH 4/4] Fix path --- build-scripts/bundle.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build-scripts/bundle.js b/build-scripts/bundle.js index c46796b5a2c7..61dc06f74c05 100644 --- a/build-scripts/bundle.js +++ b/build-scripts/bundle.js @@ -29,7 +29,10 @@ module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) => // This polyfill is loaded in workers to support ES5, filter it out. latestBuild && require.resolve("proxy-polyfill/src/index.js"), // Icons in supervisor conflict with icons in HA so we don't load. - isHassioBuild && require.resolve("../../src/components/ha-icon.ts"), + isHassioBuild && + require.resolve( + path.resolve(paths.polymer_dir, "src/components/ha-icon.ts") + ), ].filter(Boolean); module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({