mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add support package download to cloud (#24051)
This commit is contained in:
parent
11ae3a77e8
commit
904ee2e418
@ -181,3 +181,6 @@ export const updateCloudGoogleEntityConfig = (
|
|||||||
|
|
||||||
export const cloudSyncGoogleAssistant = (hass: HomeAssistant) =>
|
export const cloudSyncGoogleAssistant = (hass: HomeAssistant) =>
|
||||||
hass.callApi("POST", "cloud/google_actions/sync");
|
hass.callApi("POST", "cloud/google_actions/sync");
|
||||||
|
|
||||||
|
export const fetchSupportPackage = (hass: HomeAssistant) =>
|
||||||
|
hass.callApi<string>("GET", "cloud/support_package");
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
|
import { mdiDeleteForever, mdiDotsVertical, mdiDownload } from "@mdi/js";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { mdiDeleteForever, mdiDotsVertical } from "@mdi/js";
|
|
||||||
import { formatDateTime } from "../../../../common/datetime/format_date_time";
|
import { formatDateTime } from "../../../../common/datetime/format_date_time";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { debounce } from "../../../../common/util/debounce";
|
import { debounce } from "../../../../common/util/debounce";
|
||||||
import "../../../../components/ha-alert";
|
import "../../../../components/ha-alert";
|
||||||
import "../../../../components/ha-card";
|
|
||||||
import "../../../../components/ha-tip";
|
|
||||||
import "../../../../components/ha-list-item";
|
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
|
import "../../../../components/ha-card";
|
||||||
|
import "../../../../components/ha-list-item";
|
||||||
|
import "../../../../components/ha-tip";
|
||||||
import type {
|
import type {
|
||||||
CloudStatusLoggedIn,
|
CloudStatusLoggedIn,
|
||||||
SubscriptionInfo,
|
SubscriptionInfo,
|
||||||
@ -32,6 +32,7 @@ import "./cloud-ice-servers-pref";
|
|||||||
import "./cloud-remote-pref";
|
import "./cloud-remote-pref";
|
||||||
import "./cloud-tts-pref";
|
import "./cloud-tts-pref";
|
||||||
import "./cloud-webhooks";
|
import "./cloud-webhooks";
|
||||||
|
import { showSupportPackageDialog } from "./show-dialog-cloud-support-package";
|
||||||
|
|
||||||
@customElement("cloud-account")
|
@customElement("cloud-account")
|
||||||
export class CloudAccount extends SubscribeMixin(LitElement) {
|
export class CloudAccount extends SubscribeMixin(LitElement) {
|
||||||
@ -52,7 +53,7 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
header="Home Assistant Cloud"
|
header="Home Assistant Cloud"
|
||||||
>
|
>
|
||||||
<ha-button-menu slot="toolbar-icon" @action=${this._deleteCloudData}>
|
<ha-button-menu slot="toolbar-icon" @action=${this._handleMenuAction}>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
@ -65,6 +66,12 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
<ha-svg-icon slot="graphic" .path=${mdiDeleteForever}></ha-svg-icon>
|
<ha-svg-icon slot="graphic" .path=${mdiDeleteForever}></ha-svg-icon>
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
|
<ha-list-item graphic="icon">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.cloud.account.download_support_package"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon slot="graphic" .path=${mdiDownload}></ha-svg-icon>
|
||||||
|
</ha-list-item>
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<ha-config-section .isWide=${this.isWide}>
|
<ha-config-section .isWide=${this.isWide}>
|
||||||
@ -286,6 +293,16 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
|
|||||||
fireEvent(this, "ha-refresh-cloud-status");
|
fireEvent(this, "ha-refresh-cloud-status");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleMenuAction(ev) {
|
||||||
|
switch (ev.detail.index) {
|
||||||
|
case 0:
|
||||||
|
this._deleteCloudData();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this._downloadSupportPackage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _deleteCloudData() {
|
private async _deleteCloudData() {
|
||||||
const confirm = await showConfirmationDialog(this, {
|
const confirm = await showConfirmationDialog(this, {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
@ -316,6 +333,10 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _downloadSupportPackage() {
|
||||||
|
showSupportPackageDialog(this);
|
||||||
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
206
src/panels/config/cloud/account/dialog-cloud-support-package.ts
Normal file
206
src/panels/config/cloud/account/dialog-cloud-support-package.ts
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
import "@material/mwc-button";
|
||||||
|
import "@material/mwc-list/mwc-list-item";
|
||||||
|
import { mdiClose } from "@mdi/js";
|
||||||
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-alert";
|
||||||
|
import "../../../../components/ha-button";
|
||||||
|
import "../../../../components/ha-circular-progress";
|
||||||
|
import "../../../../components/ha-dialog-header";
|
||||||
|
import "../../../../components/ha-markdown-element";
|
||||||
|
import "../../../../components/ha-md-dialog";
|
||||||
|
import type { HaMdDialog } from "../../../../components/ha-md-dialog";
|
||||||
|
import "../../../../components/ha-select";
|
||||||
|
import "../../../../components/ha-textarea";
|
||||||
|
import { fetchSupportPackage } from "../../../../data/cloud";
|
||||||
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import { fileDownload } from "../../../../util/file_download";
|
||||||
|
|
||||||
|
@customElement("dialog-cloud-support-package")
|
||||||
|
export class DialogSupportPackage extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@state() private _open = false;
|
||||||
|
|
||||||
|
@state() private _supportPackage?: string;
|
||||||
|
|
||||||
|
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||||
|
|
||||||
|
public showDialog() {
|
||||||
|
this._open = true;
|
||||||
|
this._loadSupportPackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _dialogClosed(): void {
|
||||||
|
this._open = false;
|
||||||
|
this._supportPackage = undefined;
|
||||||
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog() {
|
||||||
|
this._dialog?.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this._open) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<ha-md-dialog open @closed=${this._dialogClosed}>
|
||||||
|
<ha-dialog-header slot="headline">
|
||||||
|
<ha-icon-button
|
||||||
|
slot="navigationIcon"
|
||||||
|
.label=${this.hass.localize("ui.common.close")}
|
||||||
|
.path=${mdiClose}
|
||||||
|
@click=${this.closeDialog}
|
||||||
|
></ha-icon-button>
|
||||||
|
<span slot="title">Download support package</span>
|
||||||
|
</ha-dialog-header>
|
||||||
|
|
||||||
|
<div slot="content">
|
||||||
|
${this._supportPackage
|
||||||
|
? html`<ha-markdown-element
|
||||||
|
.content=${this._supportPackage}
|
||||||
|
breaks
|
||||||
|
></ha-markdown-element>`
|
||||||
|
: html`
|
||||||
|
<div class="progress-container">
|
||||||
|
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||||
|
Generating preview...
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
</div>
|
||||||
|
<div class="footer" slot="actions">
|
||||||
|
<ha-alert>
|
||||||
|
This file may contain personal data about your home. Avoid sharing
|
||||||
|
them with unverified or untrusted parties.
|
||||||
|
</ha-alert>
|
||||||
|
<hr />
|
||||||
|
<div class="actions">
|
||||||
|
<ha-button @click=${this.closeDialog}>Close</ha-button>
|
||||||
|
<ha-button @click=${this._download}>Download</ha-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ha-md-dialog>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _loadSupportPackage() {
|
||||||
|
this._supportPackage = await fetchSupportPackage(this.hass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _download() {
|
||||||
|
fileDownload(
|
||||||
|
"data:text/plain;charset=utf-8," +
|
||||||
|
encodeURIComponent(this._supportPackage || ""),
|
||||||
|
"support-package.md"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static styles = css`
|
||||||
|
ha-md-dialog {
|
||||||
|
min-width: 90vw;
|
||||||
|
min-height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: calc(90vh - 260px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||||
|
ha-md-dialog {
|
||||||
|
min-width: 100vw;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
.progress-container {
|
||||||
|
height: calc(100vh - 260px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid var(--divider-color);
|
||||||
|
width: calc(100% + 48px);
|
||||||
|
margin-right: -24px;
|
||||||
|
margin-left: -24px;
|
||||||
|
}
|
||||||
|
table,
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
display: table;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table > tbody > tr:nth-child(odd) {
|
||||||
|
background-color: rgba(var(--rgb-primary-text-color), 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
table > tbody > tr > td {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table > tbody > tr {
|
||||||
|
-webkit-transition: background-color 0.25s ease;
|
||||||
|
transition: background-color 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
table > tbody > tr:hover {
|
||||||
|
background-color: rgba(var(--rgb-primary-text-color), 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
border-bottom: 1px solid var(--divider-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
padding: 15px 5px;
|
||||||
|
display: table-cell;
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
details {
|
||||||
|
background-color: var(--secondary-background-color);
|
||||||
|
padding: 16px 24px;
|
||||||
|
margin: 8px 0;
|
||||||
|
border: 1px solid var(--divider-color);
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
summary {
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"dialog-cloud-support-package": DialogSupportPackage;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
|
||||||
|
export const loadSupportPackageDialog = () =>
|
||||||
|
import("./dialog-cloud-support-package");
|
||||||
|
|
||||||
|
export const showSupportPackageDialog = (element: HTMLElement): void => {
|
||||||
|
fireEvent(element, "show-dialog", {
|
||||||
|
dialogTag: "dialog-cloud-support-package",
|
||||||
|
dialogImport: loadSupportPackageDialog,
|
||||||
|
dialogParams: {},
|
||||||
|
});
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import "@material/mwc-button";
|
import "@material/mwc-button";
|
||||||
import "@material/mwc-list/mwc-list";
|
import "@material/mwc-list/mwc-list";
|
||||||
import { mdiDeleteForever, mdiDotsVertical } from "@mdi/js";
|
import { mdiDeleteForever, mdiDotsVertical, mdiDownload } from "@mdi/js";
|
||||||
import type { TemplateResult } from "lit";
|
import type { TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
@ -27,6 +27,7 @@ import "../../../../layouts/hass-subpage";
|
|||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import "../../ha-config-section";
|
import "../../ha-config-section";
|
||||||
|
import { showSupportPackageDialog } from "../account/show-dialog-cloud-support-package";
|
||||||
|
|
||||||
@customElement("cloud-login")
|
@customElement("cloud-login")
|
||||||
export class CloudLogin extends LitElement {
|
export class CloudLogin extends LitElement {
|
||||||
@ -57,7 +58,7 @@ export class CloudLogin extends LitElement {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
header="Home Assistant Cloud"
|
header="Home Assistant Cloud"
|
||||||
>
|
>
|
||||||
<ha-button-menu slot="toolbar-icon" @action=${this._deleteCloudData}>
|
<ha-button-menu slot="toolbar-icon" @action=${this._handleMenuAction}>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="trigger"
|
slot="trigger"
|
||||||
.label=${this.hass.localize("ui.common.menu")}
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
@ -70,6 +71,12 @@ export class CloudLogin extends LitElement {
|
|||||||
)}
|
)}
|
||||||
<ha-svg-icon slot="graphic" .path=${mdiDeleteForever}></ha-svg-icon>
|
<ha-svg-icon slot="graphic" .path=${mdiDeleteForever}></ha-svg-icon>
|
||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
|
<ha-list-item graphic="icon">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.cloud.account.download_support_package"
|
||||||
|
)}
|
||||||
|
<ha-svg-icon slot="graphic" .path=${mdiDownload}></ha-svg-icon>
|
||||||
|
</ha-list-item>
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<ha-config-section .isWide=${this.isWide}>
|
<ha-config-section .isWide=${this.isWide}>
|
||||||
@ -348,6 +355,16 @@ export class CloudLogin extends LitElement {
|
|||||||
fireEvent(this, "flash-message-changed", { value: "" });
|
fireEvent(this, "flash-message-changed", { value: "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleMenuAction(ev) {
|
||||||
|
switch (ev.detail.index) {
|
||||||
|
case 0:
|
||||||
|
this._deleteCloudData();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this._downloadSupportPackage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _deleteCloudData() {
|
private async _deleteCloudData() {
|
||||||
const confirm = await showConfirmationDialog(this, {
|
const confirm = await showConfirmationDialog(this, {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
@ -377,6 +394,10 @@ export class CloudLogin extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _downloadSupportPackage() {
|
||||||
|
showSupportPackageDialog(this);
|
||||||
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -4592,6 +4592,7 @@
|
|||||||
"account_created": "Account created! Check your email for instructions on how to activate your account."
|
"account_created": "Account created! Check your email for instructions on how to activate your account."
|
||||||
},
|
},
|
||||||
"account": {
|
"account": {
|
||||||
|
"download_support_package": "Download support package",
|
||||||
"reset_cloud_data": "Reset cloud data",
|
"reset_cloud_data": "Reset cloud data",
|
||||||
"reset_data_confirm_title": "Reset cloud data?",
|
"reset_data_confirm_title": "Reset cloud data?",
|
||||||
"reset_data_confirm_text": "This will reset all your cloud settings. This includes your remote connection, Google Assistant and Amazon Alexa integrations. This action cannot be undone.",
|
"reset_data_confirm_text": "This will reset all your cloud settings. This includes your remote connection, Google Assistant and Amazon Alexa integrations. This action cannot be undone.",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user