From 3b66d58f9174ebe11e860ffe43ec6a72888c0ec8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 20 Jan 2019 11:24:39 -0800 Subject: [PATCH] Fix demo translations (#2511) * Fix demo translations * Comment out some more panels * Fix reference --- demo/src/{ => custom-cards}/ha-demo-card.ts | 10 +- demo/src/entities.ts | 58 --- demo/src/ha-demo.ts | 12 +- demo/src/{ => stubs}/auth.ts | 2 +- demo/src/{ => stubs}/lovelace.ts | 15 +- demo/src/stubs/translations.ts | 474 ++++++++++++++++++ gallery/src/components/demo-card.js | 23 +- src/fake_data/demo_panels.ts | 28 +- src/fake_data/demo_resources.ts | 264 ---------- src/fake_data/provide_hass.ts | 91 ++-- src/layouts/app/connection-mixin.js | 4 +- src/layouts/app/translations-mixin.js | 3 +- src/resources/translations-metadata.ts | 16 + ...ass-translation.js => hass-translation.ts} | 6 +- tsconfig.json | 3 +- 15 files changed, 576 insertions(+), 433 deletions(-) rename demo/src/{ => custom-cards}/ha-demo-card.ts (90%) delete mode 100644 demo/src/entities.ts rename demo/src/{ => stubs}/auth.ts (67%) rename demo/src/{ => stubs}/lovelace.ts (61%) create mode 100644 demo/src/stubs/translations.ts delete mode 100644 src/fake_data/demo_resources.ts create mode 100644 src/resources/translations-metadata.ts rename src/util/{hass-translation.js => hass-translation.ts} (94%) diff --git a/demo/src/ha-demo-card.ts b/demo/src/custom-cards/ha-demo-card.ts similarity index 90% rename from demo/src/ha-demo-card.ts rename to demo/src/custom-cards/ha-demo-card.ts index f17c343fb3..0ea3ee5d12 100644 --- a/demo/src/ha-demo-card.ts +++ b/demo/src/custom-cards/ha-demo-card.ts @@ -1,16 +1,16 @@ import { LitElement, html, CSSResult, css } from "lit-element"; import { until } from "lit-html/directives/until"; import "@polymer/paper-icon-button"; -import "../../src/components/ha-card"; -import { LovelaceCard, Lovelace } from "../../src/panels/lovelace/types"; -import { LovelaceCardConfig } from "../../src/data/lovelace"; -import { MockHomeAssistant } from "../../src/fake_data/provide_hass"; +import "../../../src/components/ha-card"; +import { LovelaceCard, Lovelace } from "../../../src/panels/lovelace/types"; +import { LovelaceCardConfig } from "../../../src/data/lovelace"; +import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; import { demoConfigs, selectedDemoConfig, setDemoConfig, selectedDemoConfigIndex, -} from "./configs/demo-configs"; +} from "../configs/demo-configs"; export class HADemoCard extends LitElement implements LovelaceCard { public lovelace?: Lovelace; diff --git a/demo/src/entities.ts b/demo/src/entities.ts deleted file mode 100644 index c7c7460c9d..0000000000 --- a/demo/src/entities.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { getEntity } from "../../src/fake_data/entity"; - -export const entities = [ - getEntity("light", "bed_light", "on", { - friendly_name: "Bed Light", - }), - getEntity("group", "kitchen", "on", { - entity_id: ["light.bed_light"], - order: 8, - friendly_name: "Kitchen", - }), - getEntity("lock", "kitchen_door", "locked", { - friendly_name: "Kitchen Door", - }), - getEntity("cover", "kitchen_window", "open", { - friendly_name: "Kitchen Window", - supported_features: 11, - }), - getEntity("scene", "romantic_lights", "scening", { - entity_id: ["light.bed_light", "light.ceiling_lights"], - friendly_name: "Romantic lights", - }), - getEntity("device_tracker", "demo_paulus", "home", { - source_type: "gps", - latitude: 32.877105, - longitude: 117.232185, - gps_accuracy: 91, - battery: 71, - friendly_name: "Paulus", - }), - getEntity("climate", "ecobee", "auto", { - current_temperature: 73, - min_temp: 45, - max_temp: 95, - temperature: null, - target_temp_high: 75, - target_temp_low: 70, - fan_mode: "Auto Low", - fan_list: ["On Low", "On High", "Auto Low", "Auto High", "Off"], - operation_mode: "auto", - operation_list: ["heat", "cool", "auto", "off"], - hold_mode: "home", - swing_mode: "Auto", - swing_list: ["Auto", "1", "2", "3", "Off"], - unit_of_measurement: "°F", - friendly_name: "Ecobee", - supported_features: 1014, - }), - getEntity("input_number", "noise_allowance", 5, { - min: 0, - max: 10, - step: 1, - mode: "slider", - unit_of_measurement: "dB", - friendly_name: "Allowed Noise", - icon: "mdi:bell-ring", - }), -]; diff --git a/demo/src/ha-demo.ts b/demo/src/ha-demo.ts index d9e9124e8d..d0eaa40945 100644 --- a/demo/src/ha-demo.ts +++ b/demo/src/ha-demo.ts @@ -1,17 +1,21 @@ import { HomeAssistant } from "../../src/layouts/app/home-assistant"; import { provideHass } from "../../src/fake_data/provide_hass"; import { navigate } from "../../src/common/navigate"; -import { mockLovelace } from "./lovelace"; -import { mockAuth } from "./auth"; +import { mockLovelace } from "./stubs/lovelace"; +import { mockAuth } from "./stubs/auth"; import { selectedDemoConfig } from "./configs/demo-configs"; +import { mockTranslations } from "./stubs/translations"; class HaDemo extends HomeAssistant { protected async _handleConnProm() { - const hass = provideHass(this, { + const initial: Partial = { panelUrl: (this as any).panelUrl, - }); + }; + + const hass = provideHass(this, initial); mockLovelace(hass); mockAuth(hass); + mockTranslations(hass); selectedDemoConfig.then((conf) => hass.addEntities(conf.entities())); // Taken from polymer/pwa-helpers. BSD-3 licensed diff --git a/demo/src/auth.ts b/demo/src/stubs/auth.ts similarity index 67% rename from demo/src/auth.ts rename to demo/src/stubs/auth.ts index 29468bd6af..be10a020a5 100644 --- a/demo/src/auth.ts +++ b/demo/src/stubs/auth.ts @@ -1,4 +1,4 @@ -import { MockHomeAssistant } from "../../src/fake_data/provide_hass"; +import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; export const mockAuth = (hass: MockHomeAssistant) => { hass.mockWS("config/auth/list", () => []); diff --git a/demo/src/lovelace.ts b/demo/src/stubs/lovelace.ts similarity index 61% rename from demo/src/lovelace.ts rename to demo/src/stubs/lovelace.ts index 5b6bfd8945..f3d4b300da 100644 --- a/demo/src/lovelace.ts +++ b/demo/src/stubs/lovelace.ts @@ -1,21 +1,18 @@ -import { entities } from "./entities"; - -import "./ha-demo-card"; +import "../custom-cards/ha-demo-card"; // Not duplicate, one is for typing. // tslint:disable-next-line -import { HADemoCard } from "./ha-demo-card"; -import { MockHomeAssistant } from "../../src/fake_data/provide_hass"; -import { HUIView } from "../../src/panels/lovelace/hui-view"; -import { selectedDemoConfig } from "./configs/demo-configs"; +import { HADemoCard } from "../custom-cards/ha-demo-card"; +import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; +import { HUIView } from "../../../src/panels/lovelace/hui-view"; +import { selectedDemoConfig } from "../configs/demo-configs"; export const mockLovelace = (hass: MockHomeAssistant) => { - hass.addEntities(entities); + selectedDemoConfig.then((config) => hass.addEntities(config.entities())); hass.mockWS("lovelace/config", () => selectedDemoConfig.then((config) => config.lovelace()) ); - hass.mockWS("frontend/get_translations", () => Promise.resolve({})); hass.mockWS("lovelace/config/save", () => Promise.resolve()); }; diff --git a/demo/src/stubs/translations.ts b/demo/src/stubs/translations.ts new file mode 100644 index 0000000000..8dab63ef45 --- /dev/null +++ b/demo/src/stubs/translations.ts @@ -0,0 +1,474 @@ +import { MockHomeAssistant } from "../../../src/fake_data/provide_hass"; + +export const mockTranslations = (hass: MockHomeAssistant) => { + hass.mockWS("frontend/get_translations", () => ({ + resources: { + "component.lifx.config.abort.no_devices_found": + "No LIFX devices found on the network.", + "component.lifx.config.abort.single_instance_allowed": + "Only a single configuration of LIFX is possible.", + "component.lifx.config.step.confirm.description": + "Do you want to set up LIFX?", + "component.lifx.config.step.confirm.title": "LIFX", + "component.lifx.config.title": "LIFX", + "component.hangouts.config.abort.already_configured": + "Google Hangouts is already configured", + "component.hangouts.config.abort.unknown": "Unknown error occurred.", + "component.hangouts.config.error.invalid_2fa": + "Invalid 2 Factor Authentication, please try again.", + "component.hangouts.config.error.invalid_2fa_method": + "Invalid 2FA Method (Verify on Phone).", + "component.hangouts.config.error.invalid_login": + "Invalid Login, please try again.", + "component.hangouts.config.step.2fa.data.2fa": "2FA Pin", + "component.hangouts.config.step.2fa.title": "2-Factor-Authentication", + "component.hangouts.config.step.user.data.email": "E-Mail Address", + "component.hangouts.config.step.user.data.password": "Password", + "component.hangouts.config.step.user.title": "Google Hangouts Login", + "component.hangouts.config.title": "Google Hangouts", + "component.rainmachine.config.error.identifier_exists": + "Account already registered", + "component.rainmachine.config.error.invalid_credentials": + "Invalid credentials", + "component.rainmachine.config.step.user.data.ip_address": + "Hostname or IP Address", + "component.rainmachine.config.step.user.data.password": "Password", + "component.rainmachine.config.step.user.data.port": "Port", + "component.rainmachine.config.step.user.title": + "Fill in your information", + "component.rainmachine.config.title": "RainMachine", + "component.homematicip_cloud.config.abort.already_configured": + "Access point is already configured", + "component.homematicip_cloud.config.abort.connection_aborted": + "Could not connect to HMIP server", + "component.homematicip_cloud.config.abort.unknown": + "Unknown error occurred.", + "component.homematicip_cloud.config.error.invalid_pin": + "Invalid PIN, please try again.", + "component.homematicip_cloud.config.error.press_the_button": + "Please press the blue button.", + "component.homematicip_cloud.config.error.register_failed": + "Failed to register, please try again.", + "component.homematicip_cloud.config.error.timeout_button": + "Blue button press timeout, please try again.", + "component.homematicip_cloud.config.step.init.data.hapid": + "Access point ID (SGTIN)", + "component.homematicip_cloud.config.step.init.data.name": + "Name (optional, used as name prefix for all devices)", + "component.homematicip_cloud.config.step.init.data.pin": + "Pin Code (optional)", + "component.homematicip_cloud.config.step.init.title": + "Pick HomematicIP Access point", + "component.homematicip_cloud.config.step.link.description": + "Press the blue button on the access point and the submit button to register HomematicIP with Home Assistant.\n\n![Location of button on bridge](/static/images/config_flows/config_homematicip_cloud.png)", + "component.homematicip_cloud.config.step.link.title": "Link Access point", + "component.homematicip_cloud.config.title": "HomematicIP Cloud", + "component.daikin.config.abort.already_configured": + "Device is already configured", + "component.daikin.config.abort.device_fail": + "Unexpected error creating device.", + "component.daikin.config.abort.device_timeout": + "Timeout connecting to the device.", + "component.daikin.config.step.user.data.host": "Host", + "component.daikin.config.step.user.description": + "Enter IP address of your Daikin AC.", + "component.daikin.config.step.user.title": "Configure Daikin AC", + "component.daikin.config.title": "Daikin AC", + "component.unifi.config.abort.already_configured": + "Controller site is already configured", + "component.unifi.config.abort.user_privilege": + "User needs to be administrator", + "component.unifi.config.error.faulty_credentials": "Bad user credentials", + "component.unifi.config.error.service_unavailable": + "No service available", + "component.unifi.config.step.user.data.host": "Host", + "component.unifi.config.step.user.data.password": "Password", + "component.unifi.config.step.user.data.port": "Port", + "component.unifi.config.step.user.data.site": "Site ID", + "component.unifi.config.step.user.data.username": "User name", + "component.unifi.config.step.user.data.verify_ssl": + "Controller using proper certificate", + "component.unifi.config.step.user.title": "Set up UniFi Controller", + "component.unifi.config.title": "UniFi Controller", + "component.nest.config.abort.already_setup": + "You can only configure a single Nest account.", + "component.nest.config.abort.authorize_url_fail": + "Unknown error generating an authorize url.", + "component.nest.config.abort.authorize_url_timeout": + "Timeout generating authorize url.", + "component.nest.config.abort.no_flows": + "You need to configure Nest before being able to authenticate with it. [Please read the instructions](https://www.home-assistant.io/components/nest/).", + "component.nest.config.error.internal_error": + "Internal error validating code", + "component.nest.config.error.invalid_code": "Invalid code", + "component.nest.config.error.timeout": "Timeout validating code", + "component.nest.config.error.unknown": "Unknown error validating code", + "component.nest.config.step.init.data.flow_impl": "Provider", + "component.nest.config.step.init.description": + "Pick via which authentication provider you want to authenticate with Nest.", + "component.nest.config.step.init.title": "Authentication Provider", + "component.nest.config.step.link.data.code": "Pin code", + "component.nest.config.step.link.description": + "To link your Nest account, [authorize your account]({url}).\n\nAfter authorization, copy-paste the provided pin code below.", + "component.nest.config.step.link.title": "Link Nest Account", + "component.nest.config.title": "Nest", + "component.mailgun.config.abort.not_internet_accessible": + "Your Home Assistant instance needs to be accessible from the internet to receive Mailgun messages.", + "component.mailgun.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.mailgun.config.create_entry.default": + "To send events to Home Assistant, you will need to setup [Webhooks with Mailgun]({mailgun_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\nSee [the documentation]({docs_url}) on how to configure automations to handle incoming data.", + "component.mailgun.config.step.user.description": + "Are you sure you want to set up Mailgun?", + "component.mailgun.config.step.user.title": "Set up the Mailgun Webhook", + "component.mailgun.config.title": "Mailgun", + "component.tellduslive.config.abort.already_setup": + "TelldusLive is already configured", + "component.tellduslive.config.abort.authorize_url_fail": + "Unknown error generating an authorize url.", + "component.tellduslive.config.abort.authorize_url_timeout": + "Timeout generating authorize url.", + "component.tellduslive.config.abort.unknown": "Unknown error occurred", + "component.tellduslive.config.error.auth_error": + "Authentication error, please try again", + "component.tellduslive.config.step.auth.description": + "To link your TelldusLive account:\n 1. Click the link below\n 2. Login to Telldus Live\n 3. Authorize **{app_name}** (click **Yes**).\n 4. Come back here and click **SUBMIT**.\n\n [Link TelldusLive account]({auth_url})", + "component.tellduslive.config.step.auth.title": + "Authenticate against TelldusLive", + "component.tellduslive.config.step.user.data.host": "Host", + "component.tellduslive.config.step.user.title": "Pick endpoint.", + "component.tellduslive.config.title": "Telldus Live", + "component.esphome.config.abort.already_configured": + "ESP is already configured", + "component.esphome.config.error.connection_error": + "Can't connect to ESP. Please make sure your YAML file contains an 'api:' line.", + "component.esphome.config.error.invalid_password": "Invalid password!", + "component.esphome.config.error.resolve_error": + "Can't resolve address of the ESP. If this error persists, please set a static IP address: https://esphomelib.com/esphomeyaml/components/wifi.html#manual-ips", + "component.esphome.config.step.authenticate.data.password": "Password", + "component.esphome.config.step.authenticate.description": + "Please enter the password you set in your configuration.", + "component.esphome.config.step.authenticate.title": "Enter Password", + "component.esphome.config.step.user.data.host": "Host", + "component.esphome.config.step.user.data.port": "Port", + "component.esphome.config.step.user.description": + "Please enter connection settings of your [ESPHome](https://esphomelib.com/) node.", + "component.esphome.config.step.user.title": "ESPHome", + "component.esphome.config.title": "ESPHome", + "component.luftdaten.config.error.communication_error": + "Unable to communicate with the Luftdaten API", + "component.luftdaten.config.error.invalid_sensor": + "Sensor not available or invalid", + "component.luftdaten.config.error.sensor_exists": + "Sensor already registered", + "component.luftdaten.config.step.user.data.show_on_map": "Show on map", + "component.luftdaten.config.step.user.data.station_id": + "Luftdaten Sensor ID", + "component.luftdaten.config.step.user.title": "Define Luftdaten", + "component.luftdaten.config.title": "Luftdaten", + "component.upnp.config.abort.already_configured": + "UPnP/IGD is already configured", + "component.upnp.config.abort.incomplete_device": + "Ignoring incomplete UPnP device", + "component.upnp.config.abort.no_devices_discovered": + "No UPnP/IGDs discovered", + "component.upnp.config.abort.no_devices_found": + "No UPnP/IGD devices found on the network.", + "component.upnp.config.abort.no_sensors_or_port_mapping": + "Enable at least sensors or port mapping", + "component.upnp.config.abort.single_instance_allowed": + "Only a single configuration of UPnP/IGD is necessary.", + "component.upnp.config.step.confirm.description": + "Do you want to set up UPnP/IGD?", + "component.upnp.config.step.confirm.title": "UPnP/IGD", + "component.upnp.config.step.init.title": "UPnP/IGD", + "component.upnp.config.step.user.data.enable_port_mapping": + "Enable port mapping for Home Assistant", + "component.upnp.config.step.user.data.enable_sensors": + "Add traffic sensors", + "component.upnp.config.step.user.data.igd": "UPnP/IGD", + "component.upnp.config.step.user.title": + "Configuration options for the UPnP/IGD", + "component.upnp.config.title": "UPnP/IGD", + "component.point.config.abort.already_setup": + "You can only configure a Point account.", + "component.point.config.abort.authorize_url_fail": + "Unknown error generating an authorize url.", + "component.point.config.abort.authorize_url_timeout": + "Timeout generating authorize url.", + "component.point.config.abort.external_setup": + "Point successfully configured from another flow.", + "component.point.config.abort.no_flows": + "You need to configure Point before being able to authenticate with it. [Please read the instructions](https://www.home-assistant.io/components/point/).", + "component.point.config.create_entry.default": + "Successfully authenticated with Minut for your Point device(s)", + "component.point.config.error.follow_link": + "Please follow the link and authenticate before pressing Submit", + "component.point.config.error.no_token": "Not authenticated with Minut", + "component.point.config.step.auth.description": + "Please follow the link below and Accept access to your Minut account, then come back and press Submit below.\n\n[Link]({authorization_url})", + "component.point.config.step.auth.title": "Authenticate Point", + "component.point.config.step.user.data.flow_impl": "Provider", + "component.point.config.step.user.description": + "Pick via which authentication provider you want to authenticate with Point.", + "component.point.config.step.user.title": "Authentication Provider", + "component.point.config.title": "Minut Point", + "component.auth.mfa_setup.notify.abort.no_available_service": + "No notification services available.", + "component.auth.mfa_setup.notify.error.invalid_code": + "Invalid code, please try again.", + "component.auth.mfa_setup.notify.step.init.description": + "Please select one of the notification services:", + "component.auth.mfa_setup.notify.step.init.title": + "Set up one-time password delivered by notify component", + "component.auth.mfa_setup.notify.step.setup.description": + "A one-time password has been sent via **notify.{notify_service}**. Please enter it below:", + "component.auth.mfa_setup.notify.step.setup.title": "Verify setup", + "component.auth.mfa_setup.notify.title": "Notify One-Time Password", + "component.auth.mfa_setup.totp.error.invalid_code": + "Invalid code, please try again. If you get this error consistently, please make sure the clock of your Home Assistant system is accurate.", + "component.auth.mfa_setup.totp.step.init.description": + "To activate two factor authentication using time-based one-time passwords, scan the QR code with your authentication app. If you don't have one, we recommend either [Google Authenticator](https://support.google.com/accounts/answer/1066447) or [Authy](https://authy.com/).\n\n{qr_code}\n\nAfter scanning the code, enter the six digit code from your app to verify the setup. If you have problems scanning the QR code, do a manual setup with code **`{code}`**.", + "component.auth.mfa_setup.totp.step.init.title": + "Set up two-factor authentication using TOTP", + "component.auth.mfa_setup.totp.title": "TOTP", + "component.emulated_roku.config.abort.name_exists": "Name already exists", + "component.emulated_roku.config.step.user.data.advertise_ip": + "Advertise IP", + "component.emulated_roku.config.step.user.data.advertise_port": + "Advertise port", + "component.emulated_roku.config.step.user.data.host_ip": "Host IP", + "component.emulated_roku.config.step.user.data.listen_port": + "Listen port", + "component.emulated_roku.config.step.user.data.name": "Name", + "component.emulated_roku.config.step.user.data.upnp_bind_multicast": + "Bind multicast (True/False)", + "component.emulated_roku.config.step.user.title": + "Define server configuration", + "component.emulated_roku.config.title": "EmulatedRoku", + "component.owntracks.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.owntracks.config.create_entry.default": + "\n\nOn Android, open [the OwnTracks app]({android_url}), go to preferences -> connection. Change the following settings:\n - Mode: Private HTTP\n - Host: {webhook_url}\n - Identification:\n - Username: ``\n - Device ID: ``\n\nOn iOS, open [the OwnTracks app]({ios_url}), tap (i) icon in top left -> settings. Change the following settings:\n - Mode: HTTP\n - URL: {webhook_url}\n - Turn on authentication\n - UserID: ``\n\n{secret}\n\nSee [the documentation]({docs_url}) for more information.", + "component.owntracks.config.step.user.description": + "Are you sure you want to set up OwnTracks?", + "component.owntracks.config.step.user.title": "Set up OwnTracks", + "component.owntracks.config.title": "OwnTracks", + "component.zone.config.error.name_exists": "Name already exists", + "component.zone.config.step.init.data.icon": "Icon", + "component.zone.config.step.init.data.latitude": "Latitude", + "component.zone.config.step.init.data.longitude": "Longitude", + "component.zone.config.step.init.data.name": "Name", + "component.zone.config.step.init.data.passive": "Passive", + "component.zone.config.step.init.data.radius": "Radius", + "component.zone.config.step.init.title": "Define zone parameters", + "component.zone.config.title": "Zone", + "component.hue.config.abort.all_configured": + "All Philips Hue bridges are already configured", + "component.hue.config.abort.already_configured": + "Bridge is already configured", + "component.hue.config.abort.cannot_connect": + "Unable to connect to the bridge", + "component.hue.config.abort.discover_timeout": + "Unable to discover Hue bridges", + "component.hue.config.abort.no_bridges": + "No Philips Hue bridges discovered", + "component.hue.config.abort.unknown": "Unknown error occurred", + "component.hue.config.error.linking": "Unknown linking error occurred.", + "component.hue.config.error.register_failed": + "Failed to register, please try again", + "component.hue.config.step.init.data.host": "Host", + "component.hue.config.step.init.title": "Pick Hue bridge", + "component.hue.config.step.link.description": + "Press the button on the bridge to register Philips Hue with Home Assistant.\n\n![Location of button on bridge](/static/images/config_philips_hue.jpg)", + "component.hue.config.step.link.title": "Link Hub", + "component.hue.config.title": "Philips Hue", + "component.tradfri.config.abort.already_configured": + "Bridge is already configured", + "component.tradfri.config.error.cannot_connect": + "Unable to connect to the gateway.", + "component.tradfri.config.error.invalid_key": + "Failed to register with provided key. If this keeps happening, try restarting the gateway.", + "component.tradfri.config.error.timeout": "Timeout validating the code.", + "component.tradfri.config.step.auth.data.host": "Host", + "component.tradfri.config.step.auth.data.security_code": "Security Code", + "component.tradfri.config.step.auth.description": + "You can find the security code on the back of your gateway.", + "component.tradfri.config.step.auth.title": "Enter security code", + "component.tradfri.config.title": "IKEA TRÅDFRI", + "component.mqtt.config.abort.single_instance_allowed": + "Only a single configuration of MQTT is allowed.", + "component.mqtt.config.error.cannot_connect": + "Unable to connect to the broker.", + "component.mqtt.config.step.broker.data.broker": "Broker", + "component.mqtt.config.step.broker.data.discovery": "Enable discovery", + "component.mqtt.config.step.broker.data.password": "Password", + "component.mqtt.config.step.broker.data.port": "Port", + "component.mqtt.config.step.broker.data.username": "Username", + "component.mqtt.config.step.broker.description": + "Please enter the connection information of your MQTT broker.", + "component.mqtt.config.step.broker.title": "MQTT", + "component.mqtt.config.step.hassio_confirm.data.discovery": + "Enable discovery", + "component.mqtt.config.step.hassio_confirm.description": + "Do you want to configure Home Assistant to connect to the MQTT broker provided by the hass.io add-on {addon}?", + "component.mqtt.config.step.hassio_confirm.title": + "MQTT Broker via Hass.io add-on", + "component.mqtt.config.title": "MQTT", + "component.geofency.config.abort.not_internet_accessible": + "Your Home Assistant instance needs to be accessible from the internet to receive messages from Geofency.", + "component.geofency.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.geofency.config.create_entry.default": + "To send events to Home Assistant, you will need to setup the webhook feature in Geofency.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details.", + "component.geofency.config.step.user.description": + "Are you sure you want to set up the Geofency Webhook?", + "component.geofency.config.step.user.title": + "Set up the Geofency Webhook", + "component.geofency.config.title": "Geofency Webhook", + "component.simplisafe.config.error.identifier_exists": + "Account already registered", + "component.simplisafe.config.error.invalid_credentials": + "Invalid credentials", + "component.simplisafe.config.step.user.data.code": + "Code (for Home Assistant)", + "component.simplisafe.config.step.user.data.password": "Password", + "component.simplisafe.config.step.user.data.username": "Email Address", + "component.simplisafe.config.step.user.title": "Fill in your information", + "component.simplisafe.config.title": "SimpliSafe", + "component.dialogflow.config.abort.not_internet_accessible": + "Your Home Assistant instance needs to be accessible from the internet to receive Dialogflow messages.", + "component.dialogflow.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.dialogflow.config.create_entry.default": + "To send events to Home Assistant, you will need to setup [webhook integration of Dialogflow]({dialogflow_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\nSee [the documentation]({docs_url}) for further details.", + "component.dialogflow.config.step.user.description": + "Are you sure you want to set up Dialogflow?", + "component.dialogflow.config.step.user.title": + "Set up the Dialogflow Webhook", + "component.dialogflow.config.title": "Dialogflow", + "component.deconz.config.abort.already_configured": + "Bridge is already configured", + "component.deconz.config.abort.no_bridges": + "No deCONZ bridges discovered", + "component.deconz.config.abort.one_instance_only": + "Component only supports one deCONZ instance", + "component.deconz.config.error.no_key": "Couldn't get an API key", + "component.deconz.config.step.init.data.host": "Host", + "component.deconz.config.step.init.data.port": "Port", + "component.deconz.config.step.init.title": "Define deCONZ gateway", + "component.deconz.config.step.link.description": + 'Unlock your deCONZ gateway to register with Home Assistant.\n\n1. Go to deCONZ system settings\n2. Press "Unlock Gateway" button', + "component.deconz.config.step.link.title": "Link with deCONZ", + "component.deconz.config.step.options.data.allow_clip_sensor": + "Allow importing virtual sensors", + "component.deconz.config.step.options.data.allow_deconz_groups": + "Allow importing deCONZ groups", + "component.deconz.config.step.options.title": + "Extra configuration options for deCONZ", + "component.deconz.config.title": "deCONZ Zigbee gateway", + "component.openuv.config.error.identifier_exists": + "Coordinates already registered", + "component.openuv.config.error.invalid_api_key": "Invalid API key", + "component.openuv.config.step.user.data.api_key": "OpenUV API Key", + "component.openuv.config.step.user.data.elevation": "Elevation", + "component.openuv.config.step.user.data.latitude": "Latitude", + "component.openuv.config.step.user.data.longitude": "Longitude", + "component.openuv.config.step.user.title": "Fill in your information", + "component.openuv.config.title": "OpenUV", + "component.locative.config.title": "Locative Webhook", + "component.locative.config.step.user.title": + "Set up the Locative Webhook", + "component.locative.config.step.user.description": + "Are you sure you want to set up the Locative Webhook?", + "component.locative.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.locative.config.abort.not_internet_accessible": + "Your Home Assistant instance needs to be accessible from the internet to receive messages from Geofency.", + "component.locative.config.create_entry.default": + "To send locations to Home Assistant, you will need to setup the webhook feature in the Locative app.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details.", + "component.ios.config.abort.single_instance_allowed": + "Only a single configuration of Home Assistant iOS is necessary.", + "component.ios.config.step.confirm.description": + "Do you want to set up the Home Assistant iOS component?", + "component.ios.config.step.confirm.title": "Home Assistant iOS", + "component.ios.config.title": "Home Assistant iOS", + "component.smhi.config.error.name_exists": "Name already exists", + "component.smhi.config.error.wrong_location": "Location Sweden only", + "component.smhi.config.step.user.data.latitude": "Latitude", + "component.smhi.config.step.user.data.longitude": "Longitude", + "component.smhi.config.step.user.data.name": "Name", + "component.smhi.config.step.user.title": "Location in Sweden", + "component.smhi.config.title": "Swedish weather service (SMHI)", + "component.sonos.config.abort.no_devices_found": + "No Sonos devices found on the network.", + "component.sonos.config.abort.single_instance_allowed": + "Only a single configuration of Sonos is necessary.", + "component.sonos.config.step.confirm.description": + "Do you want to set up Sonos?", + "component.sonos.config.step.confirm.title": "Sonos", + "component.sonos.config.title": "Sonos", + "component.ifttt.config.abort.not_internet_accessible": + "Your Home Assistant instance needs to be accessible from the internet to receive IFTTT messages.", + "component.ifttt.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.ifttt.config.create_entry.default": + 'To send events to Home Assistant, you will need to use the "Make a web request" action from the [IFTTT Webhook applet]({applet_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\nSee [the documentation]({docs_url}) on how to configure automations to handle incoming data.', + "component.ifttt.config.step.user.description": + "Are you sure you want to set up IFTTT?", + "component.ifttt.config.step.user.title": + "Set up the IFTTT Webhook Applet", + "component.ifttt.config.title": "IFTTT", + "component.twilio.config.abort.not_internet_accessible": + "Your Home Assistant instance needs to be accessible from the internet to receive Twilio messages.", + "component.twilio.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.twilio.config.create_entry.default": + "To send events to Home Assistant, you will need to setup [Webhooks with Twilio]({twilio_url}).\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/x-www-form-urlencoded\n\nSee [the documentation]({docs_url}) on how to configure automations to handle incoming data.", + "component.twilio.config.step.user.description": + "Are you sure you want to set up Twilio?", + "component.twilio.config.step.user.title": "Set up the Twilio Webhook", + "component.twilio.config.title": "Twilio", + "component.zha.config.abort.single_instance_allowed": + "Only a single configuration of ZHA is allowed.", + "component.zha.config.error.cannot_connect": + "Unable to connect to ZHA device.", + "component.zha.config.step.user.data.radio_type": "Radio Type", + "component.zha.config.step.user.data.usb_path": "USB Device Path", + "component.zha.config.step.user.title": "ZHA", + "component.zha.config.title": "ZHA", + "component.gpslogger.config.title": "GPSLogger Webhook", + "component.gpslogger.config.step.user.title": + "Set up the GPSLogger Webhook", + "component.gpslogger.config.step.user.description": + "Are you sure you want to set up the GPSLogger Webhook?", + "component.gpslogger.config.abort.one_instance_allowed": + "Only a single instance is necessary.", + "component.gpslogger.config.abort.not_internet_accessible": + "Your Home Assistant instance needs to be accessible from the internet to receive messages from GPSLogger.", + "component.gpslogger.config.create_entry.default": + "To send events to Home Assistant, you will need to setup the webhook feature in GPSLogger.\n\nFill in the following info:\n\n- URL: `{webhook_url}`\n- Method: POST\n\nSee [the documentation]({docs_url}) for further details.", + "component.zwave.config.abort.already_configured": + "Z-Wave is already configured", + "component.zwave.config.abort.one_instance_only": + "Component only supports one Z-Wave instance", + "component.zwave.config.error.option_error": + "Z-Wave validation failed. Is the path to the USB stick correct?", + "component.zwave.config.step.user.data.network_key": + "Network Key (leave blank to auto-generate)", + "component.zwave.config.step.user.data.usb_path": "USB Path", + "component.zwave.config.step.user.description": + "See https://www.home-assistant.io/docs/z-wave/installation/ for information on the configuration variables", + "component.zwave.config.step.user.title": "Set up Z-Wave", + "component.zwave.config.title": "Z-Wave", + "component.cast.config.abort.no_devices_found": + "No Google Cast devices found on the network.", + "component.cast.config.abort.single_instance_allowed": + "Only a single configuration of Google Cast is necessary.", + "component.cast.config.step.confirm.description": + "Do you want to set up Google Cast?", + "component.cast.config.step.confirm.title": "Google Cast", + "component.cast.config.title": "Google Cast", + }, + })); +}; diff --git a/gallery/src/components/demo-card.js b/gallery/src/components/demo-card.js index 8ef20b463a..adc7282ba1 100644 --- a/gallery/src/components/demo-card.js +++ b/gallery/src/components/demo-card.js @@ -2,11 +2,6 @@ import { html } from "@polymer/polymer/lib/utils/html-tag"; import { PolymerElement } from "@polymer/polymer/polymer-element"; import JsYaml from "js-yaml"; -import HomeAssistant from "../data/hass"; -import { demoConfig } from "../../../src/fake_data/demo_config"; -import { demoServices } from "../../../src/fake_data/demo_services"; -import demoResources from "../../../src/fake_data/demo_resources"; -import demoStates from "../data/demo_states"; import { createCardElement } from "../../../src/panels/lovelace/common/create-card-element"; class DemoCard extends PolymerElement { @@ -68,23 +63,7 @@ class DemoCard extends PolymerElement { } const el = createCardElement(JsYaml.safeLoad(config.config)[0]); - - if (this.hass) { - el.hass = this.hass; - } else { - const hass = new HomeAssistant(demoStates); - hass.config = demoConfig; - hass.services = demoServices; - hass.resources = demoResources; - hass.language = "en"; - hass.states = demoStates; - hass.themes = { - default_theme: "default", - themes: {}, - }; - el.hass = hass; - } - + el.hass = this.hass; card.appendChild(el); } diff --git a/src/fake_data/demo_panels.ts b/src/fake_data/demo_panels.ts index 6c626eb0d2..32d38ced99 100644 --- a/src/fake_data/demo_panels.ts +++ b/src/fake_data/demo_panels.ts @@ -79,18 +79,18 @@ export const demoPanels: Panels = { // config: null, // url_path: "history", // }, - map: { - component_name: "map", - icon: "hass:account-location", - title: "map", - config: null, - url_path: "map", - }, - config: { - component_name: "config", - icon: "hass:settings", - title: "config", - config: null, - url_path: "config", - }, + // map: { + // component_name: "map", + // icon: "hass:account-location", + // title: "map", + // config: null, + // url_path: "map", + // }, + // config: { + // component_name: "config", + // icon: "hass:settings", + // title: "config", + // config: null, + // url_path: "config", + // }, }; diff --git a/src/fake_data/demo_resources.ts b/src/fake_data/demo_resources.ts deleted file mode 100644 index 6ee75d0aa5..0000000000 --- a/src/fake_data/demo_resources.ts +++ /dev/null @@ -1,264 +0,0 @@ -export const demoResources = { - en: { - "state.default.off": "Off", - "state.default.on": "On", - "state.default.unknown": "Unknown", - "state.default.unavailable": "Unavailable", - "state.alarm_control_panel.armed": "Armed", - "state.alarm_control_panel.disarmed": "Disarmed", - "state.alarm_control_panel.armed_home": "Armed home", - "state.alarm_control_panel.armed_away": "Armed away", - "state.alarm_control_panel.armed_night": "Armed night", - "state.alarm_control_panel.armed_custom_bypass": "Armed custom bypass", - "state.alarm_control_panel.pending": "Pending", - "state.alarm_control_panel.arming": "Arming", - "state.alarm_control_panel.disarming": "Disarming", - "state.alarm_control_panel.triggered": "Triggered", - "state.automation.off": "Off", - "state.automation.on": "On", - "state.binary_sensor.default.off": "Off", - "state.binary_sensor.default.on": "On", - "state.binary_sensor.battery.off": "Normal", - "state.binary_sensor.battery.on": "Low", - "state.binary_sensor.cold.off": "Normal", - "state.binary_sensor.cold.on": "Cold", - "state.binary_sensor.connectivity.off": "Disconnected", - "state.binary_sensor.connectivity.on": "Connected", - "state.binary_sensor.door.off": "Closed", - "state.binary_sensor.door.on": "Open", - "state.binary_sensor.garage_door.off": "Closed", - "state.binary_sensor.garage_door.on": "Open", - "state.binary_sensor.gas.off": "Clear", - "state.binary_sensor.gas.on": "Detected", - "state.binary_sensor.heat.off": "Normal", - "state.binary_sensor.heat.on": "Hot", - "state.binary_sensor.lock.off": "Locked", - "state.binary_sensor.lock.on": "Unlocked", - "state.binary_sensor.moisture.off": "Dry", - "state.binary_sensor.moisture.on": "Wet", - "state.binary_sensor.motion.off": "Clear", - "state.binary_sensor.motion.on": "Detected", - "state.binary_sensor.occupancy.off": "Clear", - "state.binary_sensor.occupancy.on": "Detected", - "state.binary_sensor.opening.off": "Closed", - "state.binary_sensor.opening.on": "Open", - "state.binary_sensor.presence.off": "Away", - "state.binary_sensor.presence.on": "Home", - "state.binary_sensor.problem.off": "OK", - "state.binary_sensor.problem.on": "Problem", - "state.binary_sensor.safety.off": "Safe", - "state.binary_sensor.safety.on": "Unsafe", - "state.binary_sensor.smoke.off": "Clear", - "state.binary_sensor.smoke.on": "Detected", - "state.binary_sensor.sound.off": "Clear", - "state.binary_sensor.sound.on": "Detected", - "state.binary_sensor.vibration.off": "Clear", - "state.binary_sensor.vibration.on": "Detected", - "state.binary_sensor.window.off": "Closed", - "state.binary_sensor.window.on": "Open", - "state.calendar.off": "Off", - "state.calendar.on": "On", - "state.camera.recording": "Recording", - "state.camera.streaming": "Streaming", - "state.camera.idle": "Idle", - "state.climate.off": "Off", - "state.climate.on": "On", - "state.climate.heat": "Heat", - "state.climate.cool": "Cool", - "state.climate.idle": "Idle", - "state.climate.auto": "Auto", - "state.climate.dry": "Dry", - "state.climate.fan_only": "Fan only", - "state.climate.eco": "Eco", - "state.climate.electric": "Electric", - "state.climate.performance": "Performance", - "state.climate.high_demand": "High demand", - "state.climate.heat_pump": "Heat pump", - "state.climate.gas": "Gas", - "state.configurator.configure": "Configure", - "state.configurator.configured": "Configured", - "state.cover.open": "Open", - "state.cover.opening": "Opening", - "state.cover.closed": "Closed", - "state.cover.closing": "Closing", - "state.cover.stopped": "Stopped", - "state.device_tracker.home": "Home", - "state.device_tracker.not_home": "Away", - "state.fan.off": "Off", - "state.fan.on": "On", - "state.group.off": "Off", - "state.group.on": "On", - "state.group.home": "Home", - "state.group.not_home": "Away", - "state.group.open": "Open", - "state.group.opening": "Opening", - "state.group.closed": "Closed", - "state.group.closing": "Closing", - "state.group.stopped": "Stopped", - "state.group.locked": "Locked", - "state.group.unlocked": "Unlocked", - "state.group.ok": "OK", - "state.group.problem": "Problem", - "state.input_boolean.off": "Off", - "state.input_boolean.on": "On", - "state.light.off": "Off", - "state.light.on": "On", - "state.lock.locked": "Locked", - "state.lock.unlocked": "Unlocked", - "state.media_player.off": "Off", - "state.media_player.on": "On", - "state.media_player.playing": "Playing", - "state.media_player.paused": "Paused", - "state.media_player.idle": "Idle", - "state.media_player.standby": "Standby", - "state.plant.ok": "OK", - "state.plant.problem": "Problem", - "state.remote.off": "Off", - "state.remote.on": "On", - "state.scene.scening": "Scening", - "state.script.off": "Off", - "state.script.on": "On", - "state.sensor.off": "Off", - "state.sensor.on": "On", - "state.sun.above_horizon": "Above horizon", - "state.sun.below_horizon": "Below horizon", - "state.switch.off": "Off", - "state.switch.on": "On", - "state.weather.clear-night": "Clear, night", - "state.weather.cloudy": "Cloudy", - "state.weather.fog": "Fog", - "state.weather.hail": "Hail", - "state.weather.lightning": "Lightning", - "state.weather.lightning-rainy": "Lightning, rainy", - "state.weather.partlycloudy": "Partly cloudy", - "state.weather.pouring": "Pouring", - "state.weather.rainy": "Rainy", - "state.weather.snowy": "Snowy", - "state.weather.snowy-rainy": "Snowy, rainy", - "state.weather.sunny": "Sunny", - "state.weather.windy": "Windy", - "state.weather.windy-variant": "Windy", - "state.zwave.default.initializing": "Initializing", - "state.zwave.default.dead": "Dead", - "state.zwave.default.sleeping": "Sleeping", - "state.zwave.default.ready": "Ready", - "state.zwave.query_stage.initializing": "Initializing ({query_stage})", - "state.zwave.query_stage.dead": "Dead ({query_stage})", - "state_badge.default.unknown": "Unk", - "state_badge.default.unavailable": "Unavai", - "state_badge.alarm_control_panel.armed": "Armed", - "state_badge.alarm_control_panel.disarmed": "Disarm", - "state_badge.alarm_control_panel.armed_home": "Armed", - "state_badge.alarm_control_panel.armed_away": "Armed", - "state_badge.alarm_control_panel.armed_night": "Armed", - "state_badge.alarm_control_panel.armed_custom_bypass": "Armed", - "state_badge.alarm_control_panel.pending": "Pend", - "state_badge.alarm_control_panel.arming": "Arming", - "state_badge.alarm_control_panel.disarming": "Disarm", - "state_badge.alarm_control_panel.triggered": "Trig", - "state_badge.device_tracker.home": "Home", - "state_badge.device_tracker.not_home": "Away", - "ui.card.alarm_control_panel.code": "Code", - "ui.card.alarm_control_panel.clear_code": "Clear", - "ui.card.alarm_control_panel.disarm": "Disarm", - "ui.card.alarm_control_panel.arm_home": "Arm home", - "ui.card.alarm_control_panel.arm_away": "Arm away", - "ui.card.automation.last_triggered": "Last triggered", - "ui.card.automation.trigger": "Trigger", - "ui.card.camera.not_available": "Image not available", - "ui.card.climate.currently": "Currently", - "ui.card.climate.on_off": "On / off", - "ui.card.climate.target_temperature": "Target temperature", - "ui.card.climate.target_humidity": "Target humidity", - "ui.card.climate.operation": "Operation", - "ui.card.climate.fan_mode": "Fan mode", - "ui.card.climate.swing_mode": "Swing mode", - "ui.card.climate.away_mode": "Away mode", - "ui.card.climate.aux_heat": "Aux heat", - "ui.card.cover.position": "Position", - "ui.card.cover.tilt_position": "Tilt position", - "ui.card.fan.speed": "Speed", - "ui.card.fan.oscillate": "Oscillate", - "ui.card.fan.direction": "Direction", - "ui.card.light.brightness": "Brightness", - "ui.card.light.color_temperature": "Color temperature", - "ui.card.light.white_value": "White value", - "ui.card.light.effect": "Effect", - "ui.card.lock.code": "Code", - "ui.card.lock.lock": "Lock", - "ui.card.lock.unlock": "Unlock", - "ui.card.media_player.source": "Source", - "ui.card.media_player.sound_mode": "Sound mode", - "ui.card.media_player.text_to_speak": "Text to speak", - "ui.card.persistent_notification.dismiss": "Dismiss", - "ui.card.scene.activate": "Activate", - "ui.card.script.execute": "Execute", - "ui.card.weather.attributes.air_pressure": "Air pressure", - "ui.card.weather.attributes.humidity": "Humidity", - "ui.card.weather.attributes.temperature": "Temperature", - "ui.card.weather.attributes.visibility": "Visibility", - "ui.card.weather.attributes.wind_speed": "Wind speed", - "ui.card.weather.cardinal_direction.e": "E", - "ui.card.weather.cardinal_direction.ene": "ENE", - "ui.card.weather.cardinal_direction.ese": "ESE", - "ui.card.weather.cardinal_direction.n": "N", - "ui.card.weather.cardinal_direction.ne": "NE", - "ui.card.weather.cardinal_direction.nne": "NNE", - "ui.card.weather.cardinal_direction.nw": "NW", - "ui.card.weather.cardinal_direction.nnw": "NNW", - "ui.card.weather.cardinal_direction.s": "S", - "ui.card.weather.cardinal_direction.se": "SE", - "ui.card.weather.cardinal_direction.sse": "SSE", - "ui.card.weather.cardinal_direction.ssw": "SSW", - "ui.card.weather.cardinal_direction.sw": "SW", - "ui.card.weather.cardinal_direction.w": "W", - "ui.card.weather.cardinal_direction.wnw": "WNW", - "ui.card.weather.cardinal_direction.wsw": "WSW", - "ui.card.weather.forecast": "Forecast", - "ui.common.loading": "Loading", - "ui.common.cancel": "Cancel", - "ui.components.entity.entity-picker.entity": "Entity", - "ui.components.relative_time.past": "{time} ago", - "ui.components.relative_time.future": "In {time}", - "ui.components.relative_time.never": "Never", - "ui.components.relative_time.duration.second": - "{count} {count, plural,\n one {second}\n other {seconds}\n}", - "ui.components.relative_time.duration.minute": - "{count} {count, plural,\n one {minute}\n other {minutes}\n}", - "ui.components.relative_time.duration.hour": - "{count} {count, plural,\n one {hour}\n other {hours}\n}", - "ui.components.relative_time.duration.day": - "{count} {count, plural,\n one {day}\n other {days}\n}", - "ui.components.relative_time.duration.week": - "{count} {count, plural,\n one {week}\n other {weeks}\n}", - "ui.components.history_charts.loading_history": "Loading state history...", - "ui.components.history_charts.no_history_found": "No state history found.", - "ui.components.service-picker.service": "Service", - "ui.dialogs.more_info_settings.save": "Save", - "ui.dialogs.more_info_settings.name": "Name", - "ui.duration.second": - "{count} {count, plural,\n one {second}\n other {seconds}\n}", - "ui.duration.minute": - "{count} {count, plural,\n one {minute}\n other {minutes}\n}", - "ui.duration.hour": - "{count} {count, plural,\n one {hour}\n other {hours}\n}", - "ui.duration.day": - "{count} {count, plural,\n one {day}\n other {days}\n}", - "ui.duration.week": - "{count} {count, plural,\n one {week}\n other {weeks}\n}", - "ui.login-form.password": "Password", - "ui.login-form.remember": "Remember", - "ui.login-form.log_in": "Log in", - "ui.notification_toast.entity_turned_on": "Turned on {entity}.", - "ui.notification_toast.entity_turned_off": "Turned off {entity}.", - "ui.notification_toast.service_called": "Service {service} called.", - "ui.notification_toast.service_call_failed": - "Failed to call service {service}.", - "ui.notification_toast.connection_lost": "Connection lost. Reconnecting…", - "ui.sidebar.developer_tools": "Developer tools", - "ui.sidebar.log_out": "Log out", - "attribute.weather.humidity": "Humidity", - "attribute.weather.visibility": "Visibility", - "attribute.weather.wind_speed": "Wind speed", - }, -}; diff --git a/src/fake_data/provide_hass.ts b/src/fake_data/provide_hass.ts index 4aa4913dad..45fe8f63a9 100644 --- a/src/fake_data/provide_hass.ts +++ b/src/fake_data/provide_hass.ts @@ -2,11 +2,12 @@ import { fireEvent } from "../common/dom/fire_event"; import { demoConfig } from "./demo_config"; import { demoServices } from "./demo_services"; -import { demoResources } from "./demo_resources"; import { demoPanels } from "./demo_panels"; import { getEntity, Entity } from "./entity"; import { HomeAssistant } from "../types"; import { HassEntities } from "home-assistant-js-websocket"; +import { getActiveTranslation } from "../util/hass-translation"; +import { translationMetadata } from "../resources/translations-metadata"; const ensureArray = (val: T | T[]): T[] => Array.isArray(val) ? val : [val]; @@ -29,17 +30,16 @@ export interface MockHomeAssistant extends HomeAssistant { export const provideHass = ( elements, - { initialStates = {}, panelUrl = "" } = {} + overrideData: Partial = {} ): MockHomeAssistant => { elements = ensureArray(elements); const wsCommands = {}; const restResponses = {}; - let hass: MockHomeAssistant; const entities = {}; function updateHass(obj: Partial) { - hass = { ...hass, ...obj }; + const hass = { ...elements[0].hass, ...obj }; elements.forEach((el) => { el.hass = hass; }); @@ -47,14 +47,14 @@ export const provideHass = ( function updateStates(newStates: HassEntities) { updateHass({ - states: { ...hass.states, ...newStates }, + states: { ...elements[0].hass.states, ...newStates }, }); } function addEntities(newEntities, replace: boolean = false) { const states = {}; ensureArray(newEntities).forEach((ent) => { - ent.hass = hass; + ent.hass = elements[0].hass; entities[ent.entityId] = ent; states[ent.entityId] = ent.toState(); }); @@ -84,17 +84,7 @@ export const provideHass = ( updateHass({ // Home Assistant properties - config: demoConfig, - services: demoServices, - language: "en", - resources: demoResources, - states: initialStates, - themes: { - default_theme: "default", - themes: {}, - }, - panelUrl: panelUrl || "lovelace", - panels: demoPanels, + auth: {} as any, connection: { addEventListener: () => undefined, removeEventListener: () => undefined, @@ -116,14 +106,15 @@ export const provideHass = ( readyState: WebSocket.OPEN, }, } as any, - translationMetadata: { - fragments: [], - translations: {}, - }, - auth: {} as any, connected: true, - dockedSidebar: false, - moreInfoEntityId: "", + states: {}, + config: demoConfig, + themes: { + default_theme: "default", + themes: {}, + }, + panels: demoPanels, + services: demoServices, user: { credentials: [], id: "abcd", @@ -131,12 +122,14 @@ export const provideHass = ( mfa_modules: [], name: "Demo User", }, - fetchWithAuth: () => Promise.reject("Not implemented"), + panelUrl: "lovelace", - // Mock properties - mockEntities: entities, + language: getActiveTranslation(), + resources: null, - // Home Assistant functions + translationMetadata, + dockedSidebar: false, + moreInfoEntityId: null, async callService(domain, service, data) { fireEvent(elements[0], "hass-notification", { message: `Called service ${domain}/${service}`, @@ -152,19 +145,17 @@ export const provideHass = ( console.log("unmocked callService", domain, service, data); } }, + async callApi(method, path, parameters) { + const callback = + path.substr(0, 7) === "states/" + ? mockUpdateStateAPI + : restResponses[path]; - async callWS(msg) { - const callback = wsCommands[msg.type]; return callback - ? callback(msg) - : Promise.reject({ - code: "command_not_mocked", - message: `WS Command ${ - msg.type - } is not implemented in provide_hass.`, - }); + ? callback(method, path, parameters) + : Promise.reject(`API Mock for ${path} is not implemented`); }, - + fetchWithAuth: () => Promise.reject("Not implemented"), async sendWS(msg) { const callback = wsCommands[msg.type]; @@ -177,19 +168,20 @@ export const provideHass = ( // tslint:disable-next-line console.log("sendWS", msg); }, - - async callApi(method, path, parameters) { - const callback = - path.substr(0, 7) === "states/" - ? mockUpdateStateAPI - : restResponses[path]; - + async callWS(msg) { + const callback = wsCommands[msg.type]; return callback - ? callback(method, path, parameters) - : Promise.reject(`API Mock for ${path} is not implemented`); + ? callback(msg) + : Promise.reject({ + code: "command_not_mocked", + message: `WS Command ${ + msg.type + } is not implemented in provide_hass.`, + }); }, - // Mock functions + // Mock stuff + mockEntities: entities, updateHass, updateStates, addEntities, @@ -199,8 +191,9 @@ export const provideHass = ( mockAPI(path, callback) { restResponses[path] = callback; }, + ...overrideData, } as MockHomeAssistant); // @ts-ignore - return hass; + return elements[0].hass; }; diff --git a/src/layouts/app/connection-mixin.js b/src/layouts/app/connection-mixin.js index 6a763ffcde..a7b50fa897 100644 --- a/src/layouts/app/connection-mixin.js +++ b/src/layouts/app/connection-mixin.js @@ -6,7 +6,7 @@ import { callService, } from "home-assistant-js-websocket"; -import translationMetadata from "../../../build-translations/translationMetadata.json"; +import { translationMetadata } from "../../resources/translations-metadata"; import LocalizeMixin from "../../mixins/localize-mixin"; import EventsMixin from "../../mixins/events-mixin"; @@ -46,6 +46,8 @@ export default (superClass) => config: null, themes: null, panels: null, + services: null, + user: null, panelUrl: this.panelUrl, language: getActiveTranslation(), diff --git a/src/layouts/app/translations-mixin.js b/src/layouts/app/translations-mixin.js index 4414f2a03d..81721c0f1d 100644 --- a/src/layouts/app/translations-mixin.js +++ b/src/layouts/app/translations-mixin.js @@ -1,6 +1,5 @@ -import translationMetadata from "../../../build-translations/translationMetadata.json"; +import { translationMetadata } from "../../resources/translations-metadata"; import { getTranslation } from "../../util/hass-translation"; - import { storeState } from "../../util/ha-pref-storage"; /* diff --git a/src/resources/translations-metadata.ts b/src/resources/translations-metadata.ts new file mode 100644 index 0000000000..31cb0c157f --- /dev/null +++ b/src/resources/translations-metadata.ts @@ -0,0 +1,16 @@ +import * as translationMetadata_ from "../../build-translations/translationMetadata.json"; + +interface TranslationMetadata { + fragments: string[]; + translations: { + [language: string]: { + nativeName: string; + fingerprints: { + [filename: string]: string; + }; + }; + }; +} + +export const translationMetadata = (translationMetadata_ as any) + .default as TranslationMetadata; diff --git a/src/util/hass-translation.js b/src/util/hass-translation.ts similarity index 94% rename from src/util/hass-translation.js rename to src/util/hass-translation.ts index 68d1cfdc3d..289c8df2df 100644 --- a/src/util/hass-translation.js +++ b/src/util/hass-translation.ts @@ -1,4 +1,4 @@ -import translationMetadata from "../../build-translations/translationMetadata.json"; +import { translationMetadata } from "../resources/translations-metadata"; export function getActiveTranslation() { // Perform case-insenstive comparison since browser isn't required to @@ -64,7 +64,7 @@ export function getActiveTranslation() { // when DOM is created in Polymer. Even a cache lookup creates noticeable latency. const translations = {}; -export function getTranslation(fragment, translationInput) { +export function getTranslation(fragment?, translationInput?) { const translation = translationInput || getActiveTranslation(); const metadata = translationMetadata.translations[translation]; if (!metadata) { @@ -87,7 +87,7 @@ export function getTranslation(fragment, translationInput) { .then((response) => response.json()) .then((data) => ({ language: translation, - data: data, + data, })) .catch((error) => { delete translations[translationFingerprint]; diff --git a/tsconfig.json b/tsconfig.json index 5911c25995..387ca8661e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "noFallthroughCasesInSwitch": true, "strict": true, "noImplicitAny": false, - "skipLibCheck": true + "skipLibCheck": true, + "resolveJsonModule": true } }