From 7f88bab5521d7f256d1f776e9aa1c7eeb7b9d818 Mon Sep 17 00:00:00 2001 From: Ludeeus Date: Tue, 27 Apr 2021 11:06:25 +0000 Subject: [PATCH] Add analytics dialog --- src/data/analytics.ts | 1 + .../analytics/dialog-analytics-optin.ts | 163 ++++++++++++++++++ .../analytics/show-dialog-analytics-optin.ts | 20 +++ src/onboarding/onboarding-analytics.ts | 1 + .../config/dashboard/ha-config-dashboard.ts | 11 ++ 5 files changed, 196 insertions(+) create mode 100644 src/dialogs/analytics/dialog-analytics-optin.ts create mode 100644 src/dialogs/analytics/show-dialog-analytics-optin.ts diff --git a/src/data/analytics.ts b/src/data/analytics.ts index a4e3875b5a..00d8560485 100644 --- a/src/data/analytics.ts +++ b/src/data/analytics.ts @@ -9,6 +9,7 @@ export interface AnalyticsPreferences { export interface Analytics { preferences: AnalyticsPreferences; + onboarded: boolean; } export const getAnalyticsDetails = (hass: HomeAssistant) => diff --git a/src/dialogs/analytics/dialog-analytics-optin.ts b/src/dialogs/analytics/dialog-analytics-optin.ts new file mode 100644 index 0000000000..b0f894ac7e --- /dev/null +++ b/src/dialogs/analytics/dialog-analytics-optin.ts @@ -0,0 +1,163 @@ +import "../../components/ha-analytics"; +import "@material/mwc-button/mwc-button"; +import { + css, + CSSResult, + customElement, + html, + internalProperty, + LitElement, + property, + TemplateResult, +} from "lit-element"; +import { fireEvent } from "../../common/dom/fire_event"; +import "../../components/ha-dialog"; +import { Analytics, setAnalyticsPreferences } from "../../data/analytics"; +import { haStyleDialog } from "../../resources/styles"; +import type { HomeAssistant } from "../../types"; +import { DialogAnalyticsOptInParams } from "./show-dialog-analytics-optin"; + +@customElement("dialog-analytics-optin") +class DialogAnalyticsOptIn extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @internalProperty() private _error?: string; + + @internalProperty() private _submitting = false; + + @internalProperty() private _showPreferences = false; + + @internalProperty() private _analyticsDetails?: Analytics; + + public async showDialog(params: DialogAnalyticsOptInParams): Promise { + this._error = undefined; + this._submitting = false; + this._analyticsDetails = params.analytics; + } + + public closeDialog(): void { + this._error = undefined; + this._submitting = false; + this._showPreferences = false; + this._analyticsDetails = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + + protected render(): TemplateResult { + if (!this._analyticsDetails) { + return html``; + } + return html` + +
+ ${this._error ? html`
${this._error}
` : ""} + ${this._showPreferences + ? html`` + : html`
+ To help us better understand how you use Home Assistant, and to + ensure our priorities align with yours. We ask that you share + your installation information to help make Home Assistant better + and help us convince manufacturers to add local control and + privacy-focused features. +

+ If you want to change what you share, you can find this in + under "General" here in the configuration panel +

+
`} +
+
+ + Ignore + + + Customize + + + ${this._showPreferences ? "Submit" : "Enable all"} + +
+
+ `; + } + + private _preferencesChanged(event: CustomEvent): void { + this._analyticsDetails = { + ...this._analyticsDetails!, + preferences: event.detail.preferences, + }; + } + + private async _ignore() { + this._submitting = true; + try { + await setAnalyticsPreferences(this.hass, {}); + } catch (err) { + this._error = err.message; + this._submitting = false; + return; + } + this.closeDialog(); + } + + private async _customize() { + this._showPreferences = true; + } + + private async _submit() { + this._submitting = true; + try { + await setAnalyticsPreferences( + this.hass, + this._showPreferences + ? this._analyticsDetails!.preferences + : { base: true, usage: true, statistics: true } + ); + } catch (err) { + this._error = err.message; + this._submitting = false; + return; + } + + this.closeDialog(); + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + .error { + color: var(--error-color); + } + .content { + padding-bottom: 54px; + } + .dialog-actions { + display: flex; + justify-content: space-between; + bottom: 16px; + position: absolute; + width: calc(100% - 48px); + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-analytics-optin": DialogAnalyticsOptIn; + } +} diff --git a/src/dialogs/analytics/show-dialog-analytics-optin.ts b/src/dialogs/analytics/show-dialog-analytics-optin.ts new file mode 100644 index 0000000000..80a83a3966 --- /dev/null +++ b/src/dialogs/analytics/show-dialog-analytics-optin.ts @@ -0,0 +1,20 @@ +import { fireEvent } from "../../common/dom/fire_event"; +import { Analytics } from "../../data/analytics"; + +export interface DialogAnalyticsOptInParams { + analytics: Analytics; +} + +export const loadConfigEntrySystemOptionsDialog = () => + import("./dialog-analytics-optin"); + +export const showDialogAnalyticsOptIn = ( + element: HTMLElement, + dialogParams: DialogAnalyticsOptInParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-analytics-optin", + dialogImport: loadConfigEntrySystemOptionsDialog, + dialogParams, + }); +}; diff --git a/src/onboarding/onboarding-analytics.ts b/src/onboarding/onboarding-analytics.ts index d8615b2408..0c4e5e06e8 100644 --- a/src/onboarding/onboarding-analytics.ts +++ b/src/onboarding/onboarding-analytics.ts @@ -27,6 +27,7 @@ class OnboardingAnalytics extends LitElement { @internalProperty() private _analyticsDetails: Analytics = { preferences: {}, + onboarded: false, }; protected render(): TemplateResult { diff --git a/src/panels/config/dashboard/ha-config-dashboard.ts b/src/panels/config/dashboard/ha-config-dashboard.ts index 5e4afb8cf0..fb293769f8 100644 --- a/src/panels/config/dashboard/ha-config-dashboard.ts +++ b/src/panels/config/dashboard/ha-config-dashboard.ts @@ -15,7 +15,9 @@ import "../../../components/ha-card"; import "../../../components/ha-icon-next"; import "../../../components/ha-menu-button"; import "../../../components/ha-svg-icon"; +import { getAnalyticsDetails } from "../../../data/analytics"; import { CloudStatus } from "../../../data/cloud"; +import { showDialogAnalyticsOptIn } from "../../../dialogs/analytics/show-dialog-analytics-optin"; import "../../../layouts/ha-app-layout"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; @@ -36,6 +38,15 @@ class HaConfigDashboard extends LitElement { @property() public showAdvanced!: boolean; + protected firstUpdated(changedProperties) { + super.firstUpdated(changedProperties); + getAnalyticsDetails(this.hass).then((analytics) => { + if (!analytics.onboarded) { + showDialogAnalyticsOptIn(this, { analytics }); + } + }); + } + protected render(): TemplateResult { const content = html`