Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build-scripts/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,6 +28,11 @@ 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(
path.resolve(paths.polymer_dir, "src/components/ha-icon.ts")
),
].filter(Boolean);

module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
Expand Down Expand Up @@ -196,6 +201,7 @@ module.exports.config = {
publicPath: publicPath(latestBuild, paths.hassio_publicPath),
isProdBuild,
latestBuild,
isHassioBuild: true,
defineOverlay: {
__SUPERVISOR__: true,
},
Expand Down
5 changes: 4 additions & 1 deletion build-scripts/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const createWebpackConfig = ({
isProdBuild,
latestBuild,
isStatsBuild,
isHassioBuild,
dontHash,
}) => {
if (!dontHash) {
Expand Down Expand Up @@ -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(),
Expand Down
1 change: 1 addition & 0 deletions gallery/src/components/demo-black-white-row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
60 changes: 59 additions & 1 deletion gallery/src/pages/components/ha-form.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -14,6 +20,44 @@ const SCHEMAS: {
schema: HaFormSchema[];
data?: Record<string, any>;
}[] = [
{
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 } } },
Comment on lines +50 to +51
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgive me for my ignorance/lack of knowledge on this part.

Can't we handle the selector options?
As in, would be nice if multiline was not defined by the schema name.

The same issue also returns in, for example, the entity selector. Would be nice if we could pass in data from the flow limiting, e.g., the domain you could select.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is the case, the name is just for the demo. These are the same selectors that are used in blueprints and service calls.

{ name: "object", selector: { object: {} } },
{
name: "select",
selector: {
select: { options: ["Everyone Home", "Some Home", "All gone"] },
},
},
],
},
{
title: "Authentication",
translations: {
Expand Down Expand Up @@ -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) => {
Expand All @@ -267,6 +324,7 @@ class DemoHaForm extends LitElement {
(slot) => html`
<ha-form
slot=${slot}
.hass=${this.hass}
.data=${this.data[idx]}
.schema=${info.schema}
.error=${info.error}
Expand Down
25 changes: 19 additions & 6 deletions src/components/ha-form/ha-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ import "./ha-form-multi_select";
import "./ha-form-positive_time_period_dict";
import "./ha-form-select";
import "./ha-form-string";
import "../ha-selector/ha-selector";
import { HaFormElement, HaFormDataContainer, HaFormSchema } from "./types";
import { HomeAssistant } from "../../types";

const getValue = (obj, item) => (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[];
Expand Down Expand Up @@ -62,12 +66,21 @@ export class HaForm extends LitElement implements HaFormElement {
</ha-alert>
`
: ""}
${dynamicElement(`ha-form-${item.type}`, {
schema: item,
data: getValue(this.data, item),
label: this._computeLabel(item),
disabled: this.disabled,
})}
${"selector" in item
? html`<ha-selector
.schema=${item}
.hass=${this.hass}
.selector=${item.selector}
.value=${getValue(this.data, item)}
.label=${this._computeLabel(item)}
.disabled=${this.disabled}
></ha-selector>`
: dynamicElement(`ha-form-${item.type}`, {
schema: item,
data: getValue(this.data, item),
label: this._computeLabel(item),
disabled: this.disabled,
})}
`;
})}
</div>
Expand Down
16 changes: 14 additions & 2 deletions src/components/ha-form/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { LitElement } from "lit";
import { Selector } from "../../data/selector";
import type { HaDurationData } from "../ha-duration-input";

export type HaFormSchema =
Expand All @@ -9,13 +10,24 @@ 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 {
type?: never;
selector: Selector;
}

export interface HaFormConstantSchema extends HaFormBaseSchema {
Expand Down