diff --git a/build-scripts/gulp/translations.js b/build-scripts/gulp/translations.js
index cda82a6c01..014df9f018 100755
--- a/build-scripts/gulp/translations.js
+++ b/build-scripts/gulp/translations.js
@@ -36,6 +36,7 @@ const TRANSLATION_FRAGMENTS = [
"page-authorize",
"page-demo",
"page-onboarding",
+ "developer-tools",
];
const tasks = [];
diff --git a/setup.py b/setup.py
index f7b4d98d63..c400df5a24 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="home-assistant-frontend",
- version="20190712.0",
+ version="20190715.0",
description="The Home Assistant frontend",
url="https://github.com/home-assistant/home-assistant-polymer",
author="The Home Assistant Authors",
diff --git a/src/common/search/search-input.ts b/src/common/search/search-input.ts
new file mode 100644
index 0000000000..deb36885b7
--- /dev/null
+++ b/src/common/search/search-input.ts
@@ -0,0 +1,83 @@
+import { TemplateResult, html } from "lit-html";
+import {
+ css,
+ CSSResult,
+ customElement,
+ LitElement,
+ property,
+} from "lit-element";
+import { fireEvent } from "../dom/fire_event";
+import "@polymer/iron-icon/iron-icon";
+import "@polymer/paper-input/paper-input";
+import "@polymer/paper-icon-button/paper-icon-button";
+import "@material/mwc-button";
+
+@customElement("search-input")
+class SearchInput extends LitElement {
+ @property() private filter?: string;
+
+ protected render(): TemplateResult | void {
+ return html`
+
+
+
+ ${this.filter &&
+ html`
+
+ `}
+
+
+ `;
+ }
+
+ private async _filterChanged(value: string) {
+ fireEvent(this, "value-changed", { value: String(value) });
+ }
+
+ private async _filterInputChanged(e) {
+ this._filterChanged(e.target.value);
+ }
+
+ private async _clearSearch() {
+ this._filterChanged("");
+ }
+
+ static get styles(): CSSResult {
+ return css`
+ paper-input {
+ flex: 1 1 auto;
+ margin: 0 16px;
+ }
+ .search-container {
+ display: inline-flex;
+ width: 100%;
+ align-items: center;
+ }
+ .prefix {
+ margin: 8px;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "search-input": SearchInput;
+ }
+}
diff --git a/src/components/ha-menu-button.ts b/src/components/ha-menu-button.ts
index 15a5887adb..ed97a569a8 100644
--- a/src/components/ha-menu-button.ts
+++ b/src/components/ha-menu-button.ts
@@ -72,7 +72,7 @@ class HaMenuButton extends LitElement {
// on older frontends too, that don't have an always visible menu button
// in the sidebar.
this._alwaysVisible =
- (Number((window.parent as any).frontendVersion) || 0) >= 20190710;
+ (Number((window.parent as any).frontendVersion) || 0) < 20190710;
}
protected updated(changedProps) {
diff --git a/src/dialogs/config-flow/step-flow-pick-handler.ts b/src/dialogs/config-flow/step-flow-pick-handler.ts
index ef64b0798a..0fbe0ba597 100644
--- a/src/dialogs/config-flow/step-flow-pick-handler.ts
+++ b/src/dialogs/config-flow/step-flow-pick-handler.ts
@@ -1,10 +1,11 @@
import {
- LitElement,
- TemplateResult,
- html,
css,
- customElement,
CSSResult,
+ customElement,
+ html,
+ LitElement,
+ property,
+ TemplateResult,
} from "lit-element";
import "@polymer/paper-spinner/paper-spinner-lite";
import "@polymer/paper-item/paper-item";
@@ -12,23 +13,62 @@ import "@polymer/paper-item/paper-item-body";
import { HomeAssistant } from "../../types";
import { createConfigFlow } from "../../data/config_entries";
import { fireEvent } from "../../common/dom/fire_event";
+import memoizeOne from "memoize-one";
+import * as Fuse from "fuse.js";
+
import "../../components/ha-icon-next";
+import "../../common/search/search-input";
+
+interface HandlerObj {
+ name: string;
+ slug: string;
+}
@customElement("step-flow-pick-handler")
class StepFlowPickHandler extends LitElement {
- public hass!: HomeAssistant;
- public handlers!: string[];
+ @property() public hass!: HomeAssistant;
+ @property() public handlers!: string[];
+ @property() private filter?: string;
+
+ private _getHandlers = memoizeOne((h: string[], filter?: string) => {
+ const handlers: HandlerObj[] = h.map((handler) => {
+ return {
+ name: this.hass.localize(`component.${handler}.config.title`),
+ slug: handler,
+ };
+ });
+
+ if (filter) {
+ const options: Fuse.FuseOptions = {
+ keys: ["name", "slug"],
+ caseSensitive: false,
+ minMatchCharLength: 2,
+ threshold: 0.2,
+ };
+ const fuse = new Fuse(handlers, options);
+ return fuse.search(filter);
+ }
+ return handlers.sort((a, b) =>
+ a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1
+ );
+ });
protected render(): TemplateResult | void {
+ const handlers = this._getHandlers(this.handlers, this.filter);
+
return html`
${this.hass.localize("ui.panel.config.integrations.new")}
- ${this.handlers.map(
- (handler) =>
+
+ ${handlers.map(
+ (handler: HandlerObj) =>
html`
- ${this.hass.localize(`component.${handler}.config.title`)}
+ ${handler.name}
@@ -38,15 +78,20 @@ class StepFlowPickHandler extends LitElement {
`;
}
+ private async _filterChanged(e) {
+ this.filter = e.detail.value;
+ }
+
private async _handlerPicked(ev) {
fireEvent(this, "flow-update", {
- stepPromise: createConfigFlow(this.hass, ev.currentTarget.handler),
+ stepPromise: createConfigFlow(this.hass, ev.currentTarget.handler.slug),
});
}
static get styles(): CSSResult {
return css`
h2 {
+ margin-bottom: 2px;
padding-left: 16px;
}
div {
diff --git a/src/panels/config/cloud/account/cloud-alexa-pref.ts b/src/panels/config/cloud/account/cloud-alexa-pref.ts
index 9e140f0e0d..dcbeee76be 100644
--- a/src/panels/config/cloud/account/cloud-alexa-pref.ts
+++ b/src/panels/config/cloud/account/cloud-alexa-pref.ts
@@ -41,8 +41,12 @@ export class CloudAlexaPref extends LitElement {
control all your Home Assistant devices via any Alexa-enabled device.