mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 01:36:49 +00:00
Add guards for network storage (#16591)
This commit is contained in:
parent
4ccfd6a3fc
commit
22dc757382
@ -17,6 +17,10 @@ export enum SupervisorMountState {
|
||||
UNKNOWN = "unknown",
|
||||
}
|
||||
|
||||
interface MountOptions {
|
||||
default_backup_mount?: string | null;
|
||||
}
|
||||
|
||||
interface SupervisorMountBase {
|
||||
name: string;
|
||||
usage: SupervisorMountUsage;
|
||||
@ -53,6 +57,7 @@ export type SupervisorMountRequestParams =
|
||||
| SupervisorCIFSMountRequestParams;
|
||||
|
||||
export interface SupervisorMounts {
|
||||
default_backup_mount: string | null;
|
||||
mounts: SupervisorMount[];
|
||||
}
|
||||
|
||||
@ -111,3 +116,15 @@ export const reloadSupervisorMount = async (
|
||||
method: "post",
|
||||
timeout: null,
|
||||
});
|
||||
|
||||
export const changeMountOptions = async (
|
||||
hass: HomeAssistant,
|
||||
data: MountOptions
|
||||
): Promise<void> =>
|
||||
hass.callWS({
|
||||
type: "supervisor/api",
|
||||
endpoint: `/mounts/options`,
|
||||
method: "post",
|
||||
timeout: null,
|
||||
data,
|
||||
});
|
||||
|
@ -15,6 +15,7 @@ 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 {
|
||||
@ -22,6 +23,7 @@ import {
|
||||
SupervisorMountState,
|
||||
SupervisorMountType,
|
||||
SupervisorMountUsage,
|
||||
SupervisorMounts,
|
||||
fetchSupervisorMounts,
|
||||
reloadSupervisorMount,
|
||||
} from "../../../data/supervisor/mounts";
|
||||
@ -35,6 +37,7 @@ import {
|
||||
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 {
|
||||
@ -48,7 +51,7 @@ class HaConfigSectionStorage extends LitElement {
|
||||
|
||||
@state() private _hostInfo?: HassioHostInfo;
|
||||
|
||||
@state() private _mounts?: SupervisorMount[];
|
||||
@state() private _mountsInfo?: SupervisorMounts | null;
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
@ -57,7 +60,14 @@ class HaConfigSectionStorage extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
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`
|
||||
<hass-subpage
|
||||
back-path="/config/system"
|
||||
@ -121,21 +131,46 @@ class HaConfigSectionStorage extends LitElement {
|
||||
</ha-card>
|
||||
`
|
||||
: ""}
|
||||
|
||||
<ha-card
|
||||
outlined
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.storage.network_mounts.title"
|
||||
)}
|
||||
>
|
||||
${this._mounts?.length
|
||||
${this._mountsInfo === null
|
||||
? html`<ha-alert
|
||||
class="mounts-not-supported"
|
||||
alert-type="warning"
|
||||
.title=${this.hass.localize(
|
||||
"ui.panel.config.storage.network_mounts.not_supported.title"
|
||||
)}
|
||||
>
|
||||
${isHAOS
|
||||
? html`${this.hass.localize(
|
||||
"ui.panel.config.storage.network_mounts.not_supported.haos"
|
||||
)}
|
||||
<mwc-button
|
||||
slot="action"
|
||||
@click=${this._navigateToUpdates}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.storage.network_mounts.not_supported.navigate_to_updates"
|
||||
)}
|
||||
</mwc-button>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.storage.network_mounts.not_supported.supervised"
|
||||
)}
|
||||
</ha-alert>`
|
||||
: validMounts?.length
|
||||
? html`<mwc-list>
|
||||
${this._mounts.map(
|
||||
${validMounts.map(
|
||||
(mount) => html`
|
||||
<ha-list-item
|
||||
graphic="avatar"
|
||||
.mount=${mount}
|
||||
twoline
|
||||
.hasMeta=${mount.state !== SupervisorMountState.ACTIVE}
|
||||
hasMeta
|
||||
@click=${this._changeMount}
|
||||
>
|
||||
<div slot="graphic">
|
||||
@ -155,18 +190,20 @@ class HaConfigSectionStorage extends LitElement {
|
||||
? mount.path
|
||||
: ` :${mount.share}`}
|
||||
</span>
|
||||
<ha-icon-button
|
||||
class="reload-btn"
|
||||
slot="meta"
|
||||
.mount=${mount}
|
||||
@click=${this._reloadMount}
|
||||
.path=${mdiReload}
|
||||
></ha-icon-button>
|
||||
${mount.state !== SupervisorMountState.ACTIVE
|
||||
? html`<ha-icon-button
|
||||
class="reload-btn"
|
||||
slot="meta"
|
||||
.mount=${mount}
|
||||
@click=${this._reloadMount}
|
||||
.path=${mdiReload}
|
||||
></ha-icon-button>`
|
||||
: html`<ha-icon-next slot="meta"></ha-icon-next>`}
|
||||
</ha-list-item>
|
||||
`
|
||||
)}
|
||||
</mwc-list>`
|
||||
: html` <div class="no-mounts">
|
||||
: html`<div class="no-mounts">
|
||||
<ha-svg-icon .path=${mdiNas}></ha-svg-icon>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
@ -174,14 +211,15 @@ class HaConfigSectionStorage extends LitElement {
|
||||
)}
|
||||
</p>
|
||||
</div>`}
|
||||
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._addMount}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.storage.network_mounts.add_title"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>
|
||||
${this._mountsInfo !== null
|
||||
? html`<div class="card-actions">
|
||||
<mwc-button @click=${this._addMount}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.storage.network_mounts.add_title"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>`
|
||||
: nothing}
|
||||
</ha-card>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
@ -190,13 +228,15 @@ class HaConfigSectionStorage extends LitElement {
|
||||
|
||||
private async _load() {
|
||||
try {
|
||||
[this._hostInfo] = await Promise.all([
|
||||
fetchHassioHostInfo(this.hass),
|
||||
this._reloadMounts(),
|
||||
]);
|
||||
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 {
|
||||
@ -205,6 +245,10 @@ class HaConfigSectionStorage extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private async _navigateToUpdates(): Promise<void> {
|
||||
navigate("/config/updates");
|
||||
}
|
||||
|
||||
private async _reloadMount(ev: Event): Promise<void> {
|
||||
ev.stopPropagation();
|
||||
const mount: SupervisorMount = (ev.currentTarget as any).mount;
|
||||
@ -224,7 +268,9 @@ class HaConfigSectionStorage extends LitElement {
|
||||
}
|
||||
|
||||
private _addMount(): void {
|
||||
showMountViewDialog(this, { reloadMounts: this._reloadMounts });
|
||||
showMountViewDialog(this, {
|
||||
reloadMounts: this._reloadMounts,
|
||||
});
|
||||
}
|
||||
|
||||
private _changeMount(ev: Event): void {
|
||||
@ -237,12 +283,10 @@ class HaConfigSectionStorage extends LitElement {
|
||||
|
||||
private async _reloadMounts(): Promise<void> {
|
||||
try {
|
||||
const allMounts = await fetchSupervisorMounts(this.hass);
|
||||
this._mounts = allMounts.mounts.filter((mount) =>
|
||||
[SupervisorMountType.CIFS, SupervisorMountType.NFS].includes(mount.type)
|
||||
);
|
||||
this._mountsInfo = await fetchSupervisorMounts(this.hass);
|
||||
} catch (err: any) {
|
||||
this._error = err.message || err;
|
||||
this._mountsInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,6 +318,10 @@ class HaConfigSectionStorage extends LitElement {
|
||||
color: var(--warning-color);
|
||||
}
|
||||
|
||||
.mounts-not-supported {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
|
||||
.reload-btn {
|
||||
float: right;
|
||||
position: relative;
|
||||
@ -295,6 +343,14 @@ class HaConfigSectionStorage extends LitElement {
|
||||
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;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -3987,6 +3987,12 @@
|
||||
"add_title": "Add network storage",
|
||||
"update_title": "Update network storage",
|
||||
"no_mounts": "No connected network storage",
|
||||
"not_supported": {
|
||||
"title": "The operating system does not support network storage",
|
||||
"supervised": "Network storage is not supported on this host",
|
||||
"haos": "To use network storage you need to run at least Home Assistant Operating System 10.0",
|
||||
"navigate_to_updates": "Go to updates"
|
||||
},
|
||||
"mount_usage": {
|
||||
"backup": "Backup",
|
||||
"media": "Media"
|
||||
@ -4008,6 +4014,10 @@
|
||||
"title": "Server",
|
||||
"description": "This is the domain name (FQDN) or IP address of the storage server you want to connect to"
|
||||
},
|
||||
"default_backup_mount": {
|
||||
"title": "Default backup location",
|
||||
"description": "This will be the default location for backups"
|
||||
},
|
||||
"path": {
|
||||
"title": "Remote share path",
|
||||
"description": "This is the path of the remote share on your storage server"
|
||||
|
Loading…
x
Reference in New Issue
Block a user