Add snapshot to add-on update dialog. (#8463)

This commit is contained in:
Joakim Sørensen 2021-02-26 14:44:27 +01:00 committed by GitHub
parent af6e87ba31
commit 9752e30eb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 222 additions and 53 deletions

View File

@ -50,7 +50,6 @@ import {
startHassioAddon, startHassioAddon,
stopHassioAddon, stopHassioAddon,
uninstallHassioAddon, uninstallHassioAddon,
updateHassioAddon,
validateHassioAddonOption, validateHassioAddonOption,
} from "../../../../src/data/hassio/addon"; } from "../../../../src/data/hassio/addon";
import { import {
@ -69,6 +68,7 @@ import { HomeAssistant } from "../../../../src/types";
import { bytesToString } from "../../../../src/util/bytes-to-string"; import { bytesToString } from "../../../../src/util/bytes-to-string";
import "../../components/hassio-card-content"; import "../../components/hassio-card-content";
import "../../components/supervisor-metric"; import "../../components/supervisor-metric";
import { showDialogSupervisorAddonUpdate } from "../../dialogs/addon/show-dialog-addon-update";
import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown"; import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
import { hassioStyle } from "../../resources/hassio-style"; import { hassioStyle } from "../../resources/hassio-style";
import { addonArchIsSupported } from "../../util/addon"; import { addonArchIsSupported } from "../../util/addon";
@ -210,12 +210,9 @@ class HassioAddonInfo extends LitElement {
: ""} : ""}
</div> </div>
<div class="card-actions"> <div class="card-actions">
<ha-progress-button <mwc-button @click=${this._updateClicked}>
.disabled=${!this.addon.available}
@click=${this._updateClicked}
>
Update Update
</ha-progress-button> </mwc-button>
${this.addon.changelog ${this.addon.changelog
? html` ? html`
<mwc-button @click=${this._openChangelog}> <mwc-button @click=${this._openChangelog}>
@ -936,38 +933,8 @@ class HassioAddonInfo extends LitElement {
button.progress = false; button.progress = false;
} }
private async _updateClicked(ev: CustomEvent): Promise<void> { private async _updateClicked(): Promise<void> {
const button = ev.currentTarget as any; showDialogSupervisorAddonUpdate(this, { addon: this.addon });
button.progress = true;
const confirmed = await showConfirmationDialog(this, {
title: this.addon.name,
text: "Are you sure you want to update this add-on?",
confirmText: "update add-on",
dismissText: "no",
});
if (!confirmed) {
button.progress = false;
return;
}
this._error = undefined;
try {
await updateHassioAddon(this.hass, this.addon.slug);
const eventdata = {
success: true,
response: undefined,
path: "update",
};
fireEvent(this, "hass-api-called", eventdata);
} catch (err) {
showAlertDialog(this, {
title: "Failed to update addon",
text: extractApiErrorMessage(err),
});
}
button.progress = false;
} }
private async _startClicked(ev: CustomEvent): Promise<void> { private async _startClicked(ev: CustomEvent): Promise<void> {

View File

@ -0,0 +1,179 @@
import "@material/mwc-button/mwc-button";
import {
css,
CSSResult,
customElement,
html,
internalProperty,
LitElement,
TemplateResult,
} from "lit-element";
import { fireEvent } from "../../../../src/common/dom/fire_event";
import "../../../../src/components/ha-circular-progress";
import "../../../../src/components/ha-dialog";
import "../../../../src/components/ha-settings-row";
import "../../../../src/components/ha-svg-icon";
import "../../../../src/components/ha-switch";
import {
HassioAddonDetails,
updateHassioAddon,
} from "../../../../src/data/hassio/addon";
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
import { createHassioPartialSnapshot } from "../../../../src/data/hassio/snapshot";
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
import { SupervisorDialogSupervisorAddonUpdateParams } from "./show-dialog-addon-update";
@customElement("dialog-supervisor-addon-update")
class DialogSupervisorAddonUpdate extends LitElement {
public hass!: HomeAssistant;
public addon!: HassioAddonDetails;
@internalProperty() private _opened = false;
@internalProperty() private _createSnapshot = true;
@internalProperty() private _action: "snapshot" | "update" | null = null;
@internalProperty() private _error?: string;
public async showDialog(
params: SupervisorDialogSupervisorAddonUpdateParams
): Promise<void> {
this._opened = true;
this.addon = params.addon;
await this.updateComplete;
}
public closeDialog(): void {
this._action = null;
this._createSnapshot = true;
this._opened = false;
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
public focus(): void {
this.updateComplete.then(() =>
(this.shadowRoot?.querySelector(
"[dialogInitialFocus]"
) as HTMLElement)?.focus()
);
}
protected render(): TemplateResult {
return html`
<ha-dialog
.heading="Update ${this.addon.name}"
.open=${this._opened}
scrimClickAction
escapeKeyAction
@closing=${this.closeDialog}
>
${this._action === null
? html`<div>
Are you sure you want to update this add-on to version
${this.addon.version_latest}?
</div>
<ha-settings-row>
<span slot="heading">
Snapshot
</span>
<span slot="description">
Create a snapshot of the add-on before updating
</span>
<ha-switch
.checked=${this._createSnapshot}
haptic
title="Create snapshot"
@click=${this._toggleSnapshot}
>
</ha-switch>
</ha-settings-row>
<mwc-button @click=${this.closeDialog} slot="secondaryAction">
Cancel
</mwc-button>
<mwc-button @click=${this._update} slot="primaryAction">
Update
</mwc-button>`
: html`<ha-circular-progress alt="Uploading" size="large" active>
</ha-circular-progress>
<p class="progress-text">
${this._action === "update"
? `Update to version ${this.addon.version_latest} in progress`
: "Creating snapshot in progress"}
</p>`}
${this._error ? html`<p class="error">${this._error}</p>` : ""}
</ha-dialog>
`;
}
private _toggleSnapshot() {
this._createSnapshot = !this._createSnapshot;
}
private async _update() {
if (this._createSnapshot) {
this._action = "snapshot";
try {
await createHassioPartialSnapshot(this.hass, {
name: `addon_${this.addon.slug}_${this.addon.version}`,
addons: [this.addon.slug],
homeassistant: false,
});
} catch (err) {
this._error = extractApiErrorMessage(err);
this._action = null;
return;
}
}
this._action = "update";
try {
await updateHassioAddon(this.hass, this.addon.slug);
} catch (err) {
this._error = extractApiErrorMessage(err);
this._action = null;
return;
}
fireEvent(this, "supervisor-colllection-refresh", { colllection: "addon" });
fireEvent(this, "supervisor-colllection-refresh", {
colllection: "supervisor",
});
this.closeDialog();
}
static get styles(): CSSResult[] {
return [
haStyle,
haStyleDialog,
css`
.form {
color: var(--primary-text-color);
}
ha-settings-row {
margin-top: 32px;
padding: 0;
}
ha-circular-progress {
display: block;
margin: 32px;
text-align: center;
}
.progress-text {
text-align: center;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"dialog-supervisor-addon-update": DialogSupervisorAddonUpdate;
}
}

View File

@ -0,0 +1,17 @@
import { fireEvent } from "../../../../src/common/dom/fire_event";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
export interface SupervisorDialogSupervisorAddonUpdateParams {
addon: HassioAddonDetails;
}
export const showDialogSupervisorAddonUpdate = (
element: HTMLElement,
dialogParams: SupervisorDialogSupervisorAddonUpdateParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-supervisor-addon-update",
dialogImport: () => import("./dialog-supervisor-addon-update"),
dialogParams,
});
};

View File

@ -95,7 +95,7 @@ class HassioSnapshotDialog extends LitElement {
@internalProperty() private _snapshotPassword!: string; @internalProperty() private _snapshotPassword!: string;
@internalProperty() private _restoreHass: boolean | null | undefined = true; @internalProperty() private _restoreHass = true;
public async showDialog(params: HassioSnapshotDialogParams) { public async showDialog(params: HassioSnapshotDialogParams) {
this._snapshot = await fetchHassioSnapshotInfo(this.hass, params.slug); this._snapshot = await fetchHassioSnapshotInfo(this.hass, params.slug);
@ -109,6 +109,9 @@ class HassioSnapshotDialog extends LitElement {
this._dialogParams = params; this._dialogParams = params;
this._onboarding = params.onboarding ?? false; this._onboarding = params.onboarding ?? false;
this.supervisor = params.supervisor; this.supervisor = params.supervisor;
if (!this._snapshot.homeassistant) {
this._restoreHass = false;
}
} }
protected render(): TemplateResult { protected render(): TemplateResult {
@ -134,15 +137,17 @@ class HassioSnapshotDialog extends LitElement {
(${this._computeSize})<br /> (${this._computeSize})<br />
${this._formatDatetime(this._snapshot.date)} ${this._formatDatetime(this._snapshot.date)}
</div> </div>
<div>Home Assistant:</div> ${this._snapshot.homeassistant
<paper-checkbox ? html`<div>Home Assistant:</div>
.checked=${this._restoreHass} <paper-checkbox
@change="${(ev: Event) => { .checked=${this._restoreHass}
this._restoreHass = (ev.target as PaperCheckboxElement).checked; @change="${(ev: Event) => {
}}" this._restoreHass = (ev.target as PaperCheckboxElement).checked!;
> }}"
Home Assistant ${this._snapshot.homeassistant} >
</paper-checkbox> Home Assistant ${this._snapshot.homeassistant}
</paper-checkbox>`
: ""}
${this._folders.length ${this._folders.length
? html` ? html`
<div>Folders:</div> <div>Folders:</div>
@ -334,7 +339,7 @@ class HassioSnapshotDialog extends LitElement {
.map((folder) => folder.slug); .map((folder) => folder.slug);
const data: { const data: {
homeassistant: boolean | null | undefined; homeassistant: boolean;
addons: any; addons: any;
folders: any; folders: any;
password?: string; password?: string;

View File

@ -300,7 +300,7 @@ export const updateHassioAddon = async (
if (atLeastVersion(hass.config.version, 2021, 2, 4)) { if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
await hass.callWS({ await hass.callWS({
type: "supervisor/api", type: "supervisor/api",
endpoint: `/addons/${slug}/update`, endpoint: `/store/addons/${slug}/update`,
method: "post", method: "post",
timeout: null, timeout: null,
}); });

View File

@ -29,9 +29,10 @@ export interface HassioFullSnapshotCreateParams {
} }
export interface HassioPartialSnapshotCreateParams { export interface HassioPartialSnapshotCreateParams {
name: string; name: string;
folders: string[]; folders?: string[];
addons: string[]; addons?: string[];
password?: string; password?: string;
homeassistant?: boolean;
} }
export const fetchHassioSnapshots = async ( export const fetchHassioSnapshots = async (
@ -116,7 +117,7 @@ export const createHassioFullSnapshot = async (
export const createHassioPartialSnapshot = async ( export const createHassioPartialSnapshot = async (
hass: HomeAssistant, hass: HomeAssistant,
data: HassioFullSnapshotCreateParams data: HassioPartialSnapshotCreateParams
) => { ) => {
if (atLeastVersion(hass.config.version, 2021, 2, 4)) { if (atLeastVersion(hass.config.version, 2021, 2, 4)) {
await hass.callWS({ await hass.callWS({