diff --git a/build-scripts/bundle.js b/build-scripts/bundle.js index 277fa54bee..c15e1ab1dc 100644 --- a/build-scripts/bundle.js +++ b/build-scripts/bundle.js @@ -210,6 +210,9 @@ module.exports.config = { publicPath: publicPath(latestBuild), isProdBuild, latestBuild, + defineOverlay: { + __DEMO__: true, + }, }; }, }; diff --git a/build-scripts/gulp/webpack.js b/build-scripts/gulp/webpack.js index e257fd58a7..2d6e0a863f 100644 --- a/build-scripts/gulp/webpack.js +++ b/build-scripts/gulp/webpack.js @@ -173,6 +173,7 @@ gulp.task("webpack-dev-server-gallery", () => compiler: webpack(bothBuilds(createGalleryConfig, { isProdBuild: false })), contentBase: paths.gallery_output_root, port: 8100, + listenHost: "0.0.0.0", }) ); diff --git a/demo/src/stubs/area_registry.ts b/demo/src/stubs/area_registry.ts new file mode 100644 index 0000000000..b7d8e5a34b --- /dev/null +++ b/demo/src/stubs/area_registry.ts @@ -0,0 +1,7 @@ +import { AreaRegistryEntry } from "../../../src/data/area_registry"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockAreaRegistry = ( + hass: MockHomeAssistant, + data: AreaRegistryEntry[] = [] +) => hass.mockWS("config/area_registry/list", () => data); diff --git a/demo/src/stubs/device_registry.ts b/demo/src/stubs/device_registry.ts new file mode 100644 index 0000000000..28c47e4a96 --- /dev/null +++ b/demo/src/stubs/device_registry.ts @@ -0,0 +1,7 @@ +import { DeviceRegistryEntry } from "../../../src/data/device_registry"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockDeviceRegistry = ( + hass: MockHomeAssistant, + data: DeviceRegistryEntry[] = [] +) => hass.mockWS("config/device_registry/list", () => data); diff --git a/demo/src/stubs/entity_registry.ts b/demo/src/stubs/entity_registry.ts new file mode 100644 index 0000000000..8f548629e7 --- /dev/null +++ b/demo/src/stubs/entity_registry.ts @@ -0,0 +1,7 @@ +import { EntityRegistryEntry } from "../../../src/data/entity_registry"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockEntityRegistry = ( + hass: MockHomeAssistant, + data: EntityRegistryEntry[] = [] +) => hass.mockWS("config/entity_registry/list", () => data); diff --git a/demo/src/stubs/hassio_supervisor.ts b/demo/src/stubs/hassio_supervisor.ts new file mode 100644 index 0000000000..95c0d330d4 --- /dev/null +++ b/demo/src/stubs/hassio_supervisor.ts @@ -0,0 +1,59 @@ +import { HassioSupervisorInfo } from "../../../src/data/hassio/supervisor"; +import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockHassioSupervisor = (hass: MockHomeAssistant) => { + hass.config.components.push("hassio"); + hass.mockWS("supervisor/api", (msg) => { + if (msg.endpoint === "/supervisor/info") { + const data: HassioSupervisorInfo = { + version: "2021.10.dev0805", + version_latest: "2021.10.dev0806", + update_available: true, + channel: "dev", + arch: "aarch64", + supported: true, + healthy: true, + ip_address: "172.30.32.2", + wait_boot: 5, + timezone: "America/Los_Angeles", + logging: "info", + debug: false, + debug_block: false, + diagnostics: true, + addons: [ + { + name: "Visual Studio Code", + slug: "a0d7b954_vscode", + description: + "Fully featured VSCode experience, to edit your HA config in the browser, including auto-completion!", + state: "started", + version: "3.6.2", + version_latest: "3.6.2", + update_available: false, + repository: "a0d7b954", + icon: true, + logo: true, + }, + { + name: "Z-Wave JS", + slug: "core_zwave_js", + description: + "Control a ZWave network with Home Assistant Z-Wave JS", + state: "started", + version: "0.1.45", + version_latest: "0.1.45", + update_available: false, + repository: "core", + icon: true, + logo: true, + }, + ] as any, + addons_repositories: [ + "https://github.com/hassio-addons/repository", + ] as any, + }; + return data; + } + return Promise.reject(`${msg.method} ${msg.endpoint} is not implemented`); + }); +}; diff --git a/gallery/src/demos/demo-ha-selector.ts b/gallery/src/demos/demo-ha-selector.ts new file mode 100644 index 0000000000..919a2c2419 --- /dev/null +++ b/gallery/src/demos/demo-ha-selector.ts @@ -0,0 +1,131 @@ +/* eslint-disable lit/no-template-arrow */ +import "@material/mwc-button"; +import { LitElement, TemplateResult, css, html } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../src/components/ha-selector/ha-selector"; +import "../../../src/components/ha-settings-row"; +import { provideHass } from "../../../src/fake_data/provide_hass"; +import type { HomeAssistant } from "../../../src/types"; +import "../components/demo-black-white-row"; +import { BlueprintInput } from "../../../src/data/blueprint"; +import { mockEntityRegistry } from "../../../demo/src/stubs/entity_registry"; +import { mockDeviceRegistry } from "../../../demo/src/stubs/device_registry"; +import { mockAreaRegistry } from "../../../demo/src/stubs/area_registry"; +import { mockHassioSupervisor } from "../../../demo/src/stubs/hassio_supervisor"; + +const SCHEMAS: { + name: string; + input: Record; +}[] = [ + { + name: "One of each", + input: { + entity: { name: "Entity", selector: { entity: {} } }, + device: { name: "Device", selector: { device: {} } }, + addon: { name: "Addon", selector: { addon: {} } }, + area: { name: "Area", selector: { area: {} } }, + target: { name: "Target", selector: { target: {} } }, + number_box: { + name: "Number Box", + selector: { + number: { + min: 0, + max: 10, + mode: "box", + }, + }, + }, + number_slider: { + name: "Number Slider", + selector: { + number: { + min: 0, + max: 10, + mode: "slider", + }, + }, + }, + boolean: { name: "Boolean", selector: { boolean: {} } }, + time: { name: "Time", selector: { time: {} } }, + action: { name: "Action", selector: { action: {} } }, + text: { name: "Text", selector: { text: { multiline: false } } }, + text_multiline: { + name: "Text multiline", + selector: { text: { multiline: true } }, + }, + object: { name: "Object", selector: { object: {} } }, + select: { + name: "Select", + selector: { select: { options: ["Option 1", "Option 2"] } }, + }, + }, + }, +]; + +@customElement("demo-ha-selector") +class DemoHaSelector extends LitElement { + @state() private hass!: HomeAssistant; + + private data = SCHEMAS.map(() => ({})); + + 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) => { + const data = this.data[idx]; + const valueChanged = (ev) => { + this.data[idx] = { + ...data, + [ev.target.key]: ev.detail.value, + }; + this.requestUpdate(); + }; + return html` + + ${["light", "dark"].map((slot) => + Object.entries(info.input).map( + ([key, value]) => + html` + + ${value?.name || key} + ${value?.description} + + + ` + ) + )} + + `; + })} + `; + } + + static styles = css` + paper-input, + ha-selector { + width: 60; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-ha-selector": DemoHaSelector; + } +} diff --git a/src/common/config/version.ts b/src/common/config/version.ts index ca9b8ae7af..ec89a3407e 100644 --- a/src/common/config/version.ts +++ b/src/common/config/version.ts @@ -4,6 +4,10 @@ export const atLeastVersion = ( minor: number, patch?: number ): boolean => { + if (__DEMO__) { + return true; + } + const [haMajor, haMinor, haPatch] = version.split(".", 3); return (