mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +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) =>
|
||||
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 { mdiDeleteForever, mdiDotsVertical, mdiDownload } from "@mdi/js";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { mdiDeleteForever, mdiDotsVertical } from "@mdi/js";
|
||||
import { formatDateTime } from "../../../../common/datetime/format_date_time";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { debounce } from "../../../../common/util/debounce";
|
||||
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-card";
|
||||
import "../../../../components/ha-list-item";
|
||||
import "../../../../components/ha-tip";
|
||||
import type {
|
||||
CloudStatusLoggedIn,
|
||||
SubscriptionInfo,
|
||||
@ -32,6 +32,7 @@ import "./cloud-ice-servers-pref";
|
||||
import "./cloud-remote-pref";
|
||||
import "./cloud-tts-pref";
|
||||
import "./cloud-webhooks";
|
||||
import { showSupportPackageDialog } from "./show-dialog-cloud-support-package";
|
||||
|
||||
@customElement("cloud-account")
|
||||
export class CloudAccount extends SubscribeMixin(LitElement) {
|
||||
@ -52,7 +53,7 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
|
||||
.narrow=${this.narrow}
|
||||
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
|
||||
slot="trigger"
|
||||
.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-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>
|
||||
<div class="content">
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
@ -286,6 +293,16 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
|
||||
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() {
|
||||
const confirm = await showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
@ -316,6 +333,10 @@ export class CloudAccount extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
private async _downloadSupportPackage() {
|
||||
showSupportPackageDialog(this);
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
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-list/mwc-list";
|
||||
import { mdiDeleteForever, mdiDotsVertical } from "@mdi/js";
|
||||
import { mdiDeleteForever, mdiDotsVertical, mdiDownload } from "@mdi/js";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
@ -27,6 +27,7 @@ import "../../../../layouts/hass-subpage";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import "../../ha-config-section";
|
||||
import { showSupportPackageDialog } from "../account/show-dialog-cloud-support-package";
|
||||
|
||||
@customElement("cloud-login")
|
||||
export class CloudLogin extends LitElement {
|
||||
@ -57,7 +58,7 @@ export class CloudLogin extends LitElement {
|
||||
.narrow=${this.narrow}
|
||||
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
|
||||
slot="trigger"
|
||||
.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-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>
|
||||
<div class="content">
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
@ -348,6 +355,16 @@ export class CloudLogin extends LitElement {
|
||||
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() {
|
||||
const confirm = await showConfirmationDialog(this, {
|
||||
title: this.hass.localize(
|
||||
@ -377,6 +394,10 @@ export class CloudLogin extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private async _downloadSupportPackage() {
|
||||
showSupportPackageDialog(this);
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
haStyle,
|
||||
|
@ -4592,6 +4592,7 @@
|
||||
"account_created": "Account created! Check your email for instructions on how to activate your account."
|
||||
},
|
||||
"account": {
|
||||
"download_support_package": "Download support package",
|
||||
"reset_cloud_data": "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.",
|
||||
|
Loading…
x
Reference in New Issue
Block a user