import "@material/mwc-list"; import { mdiBackupRestore, mdiFolder, mdiNas, mdiPlayBox, mdiReload, } from "@mdi/js"; import { LitElement, PropertyValues, TemplateResult, css, html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import "../../../components/ha-alert"; import "../../../components/ha-button-menu"; import "../../../components/ha-icon-button"; import "../../../components/ha-metric"; import "../../../components/ha-svg-icon"; import "../../../components/ha-icon-next"; import { extractApiErrorMessage } from "../../../data/hassio/common"; import { HassioHostInfo, fetchHassioHostInfo } from "../../../data/hassio/host"; import { SupervisorMount, SupervisorMountState, SupervisorMountType, SupervisorMountUsage, SupervisorMounts, fetchSupervisorMounts, reloadSupervisorMount, } from "../../../data/supervisor/mounts"; import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import "../../../layouts/hass-subpage"; import type { HomeAssistant, Route } from "../../../types"; import { getValueInPercentage, roundWithOneDecimal, } from "../../../util/calculate"; import "../core/ha-config-analytics"; import { showMoveDatadiskDialog } from "./show-dialog-move-datadisk"; import { showMountViewDialog } from "./show-dialog-view-mount"; import { navigate } from "../../../common/navigate"; @customElement("ha-config-section-storage") class HaConfigSectionStorage extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public route!: Route; @property({ type: Boolean }) public narrow = false; @state() private _error?: { code: string; message: string }; @state() private _hostInfo?: HassioHostInfo; @state() private _mountsInfo?: SupervisorMounts | null; protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); if (isComponentLoaded(this.hass, "hassio")) { this._load(); } } protected render(): TemplateResult | typeof nothing { if (this._mountsInfo === undefined) { return nothing; } const validMounts = this._mountsInfo?.mounts.filter((mount) => [SupervisorMountType.CIFS, SupervisorMountType.NFS].includes(mount.type) ); const isHAOS = this._hostInfo?.features.includes("haos"); return html`
${this._error ? html` ${this._error.message || this._error.code} ` : ""} ${this._hostInfo ? html`
${this._hostInfo.disk_life_time !== "" && this._hostInfo.disk_life_time >= 10 ? // prettier-ignore html` ` : ""}
${this._hostInfo ? html`
${this.hass.localize( "ui.panel.config.storage.datadisk.title" )}
` : nothing}
` : ""} ${this._mountsInfo === null ? html` ${isHAOS ? html`${this.hass.localize( "ui.panel.config.storage.network_mounts.not_supported.os", { version: "10.2" } )} ${this.hass.localize( "ui.panel.config.storage.network_mounts.not_supported.navigate_to_updates" )} ` : this.hass.localize( "ui.panel.config.storage.network_mounts.not_supported.supervised" )} ` : validMounts?.length ? html` ${validMounts.map( (mount) => html`
${mount.name} ${mount.server}${mount.port ? `:${mount.port}` : nothing}${mount.type === SupervisorMountType.NFS ? mount.path : `:${mount.share}`} ${mount.state !== SupervisorMountState.ACTIVE ? html`` : html``}
` )}
` : html`

${this.hass.localize( "ui.panel.config.storage.network_mounts.no_mounts" )}

`} ${this._mountsInfo !== null ? html`
${this.hass.localize( "ui.panel.config.storage.network_mounts.add_title" )}
` : nothing}
`; } private async _load() { try { this._hostInfo = await fetchHassioHostInfo(this.hass); } catch (err: any) { this._error = err.message || err; } if (this._hostInfo?.features.includes("mount")) { await this._reloadMounts(); } else { this._mountsInfo = null; } } private _moveDatadisk(): void { showMoveDatadiskDialog(this, { hostInfo: this._hostInfo!, }); } private async _navigateToUpdates(): Promise { navigate("/config/updates"); } private async _reloadMount(ev: Event): Promise { ev.stopPropagation(); const mount: SupervisorMount = (ev.currentTarget as any).mount; try { await reloadSupervisorMount(this.hass, mount); } catch (err: any) { showAlertDialog(this, { title: this.hass.localize( "ui.panel.config.storage.network_mounts.errors.reload", { mount: mount.name } ), text: extractApiErrorMessage(err), }); return; } await this._reloadMounts(); } private _addMount(): void { showMountViewDialog(this, { reloadMounts: () => this._reloadMounts(), }); } private _changeMount(ev: Event): void { ev.stopPropagation(); showMountViewDialog(this, { mount: (ev.currentTarget as any).mount, reloadMounts: () => this._reloadMounts(), }); } private async _reloadMounts(): Promise { try { this._mountsInfo = await fetchSupervisorMounts(this.hass); } catch (err: any) { this._error = err.message || err; this._mountsInfo = null; } } private _getUsedSpace = (used: number, total: number) => roundWithOneDecimal(getValueInPercentage(used, 0, total)); static styles = css` .content { padding: 28px 20px 0; max-width: 1040px; margin: 0 auto; } ha-card { max-width: 600px; margin: 0 auto 12px; justify-content: space-between; flex-direction: column; display: flex; } .card-content { display: flex; justify-content: space-between; flex-direction: column; } .mount-state-failed { color: var(--error-color); } .mount-state-unknown { color: var(--warning-color); } .mounts-not-supported { padding: 0 16px 16px; } .reload-btn { float: right; position: relative; top: -10px; right: 10px; } .no-mounts { display: flex; flex-direction: column; align-items: center; text-align: center; } .no-mounts ha-svg-icon { background-color: var(--light-primary-color); color: var(--secondary-text-color); padding: 16px; border-radius: 50%; margin-bottom: 8px; } ha-list-item { --mdc-list-item-meta-size: auto; --mdc-list-item-meta-display: flex; } ha-svg-icon, ha-icon-next { width: 24px; } `; } declare global { interface HTMLElementTagNameMap { "ha-config-section-storage": HaConfigSectionStorage; } }