mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
20241223.1 (#23402)
This commit is contained in:
commit
e7d9032cc4
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
@ -55,7 +55,7 @@ jobs:
|
||||
script/release
|
||||
|
||||
- name: Upload release assets
|
||||
uses: softprops/action-gh-release@v2.2.0
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
with:
|
||||
files: |
|
||||
dist/*.whl
|
||||
@ -107,7 +107,7 @@ jobs:
|
||||
- name: Tar folder
|
||||
run: tar -czf landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz -C landing-page/dist .
|
||||
- name: Upload release asset
|
||||
uses: softprops/action-gh-release@v2.2.0
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
with:
|
||||
files: landing-page/home_assistant_frontend_landingpage-${{ github.event.release.tag_name }}.tar.gz
|
||||
|
||||
@ -136,6 +136,6 @@ jobs:
|
||||
- name: Tar folder
|
||||
run: tar -czf hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz -C hassio/build .
|
||||
- name: Upload release asset
|
||||
uses: softprops/action-gh-release@v2.2.0
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
with:
|
||||
files: hassio/home_assistant_frontend_supervisor-${{ github.event.release.tag_name }}.tar.gz
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "home-assistant-frontend"
|
||||
version = "20241223.0"
|
||||
version = "20241223.1"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "The Home Assistant frontend"
|
||||
readme = "README.md"
|
||||
|
@ -22,14 +22,6 @@ export class HaOutlinedField extends MdOutlinedField {
|
||||
border-end-start-radius: var(--_container-shape-end-start);
|
||||
border-end-end-radius: var(--_container-shape-end-end);
|
||||
}
|
||||
.with-start .start {
|
||||
margin-inline-end: var(--ha-outlined-field-start-margin, 4px);
|
||||
margin-inline-start: initial;
|
||||
}
|
||||
.with-end .end {
|
||||
margin-inline-start: var(--ha-outlined-field-end-margin, 4px);
|
||||
margin-inline-end: initial;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -28,8 +28,9 @@ export class HaOutlinedTextField extends MdOutlinedTextField {
|
||||
--md-outlined-field-container-shape-end-end: 10px;
|
||||
--md-outlined-field-container-shape-end-start: 10px;
|
||||
--md-outlined-field-focus-outline-width: 1px;
|
||||
--ha-outlined-field-start-margin: -4px;
|
||||
--ha-outlined-field-end-margin: -4px;
|
||||
--md-outlined-field-with-leading-content-leading-space: 8px;
|
||||
--md-outlined-field-with-trailing-content-trailing-space: 8px;
|
||||
--md-outlined-field-content-space: 8px;
|
||||
--mdc-icon-size: var(--md-input-chip-icon-size, 18px);
|
||||
}
|
||||
.input {
|
||||
|
@ -871,7 +871,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
background-color: var(
|
||||
--sidebar-menu-button-background-color,
|
||||
var(--primary-background-color)
|
||||
inherit
|
||||
);
|
||||
font-size: 20px;
|
||||
align-items: center;
|
||||
|
@ -173,7 +173,7 @@ class DialogAreaDetail extends LitElement {
|
||||
>
|
||||
${entry
|
||||
? this.hass.localize("ui.common.save")
|
||||
: this.hass.localize("ui.common.add")}
|
||||
: this.hass.localize("ui.common.create")}
|
||||
</mwc-button>
|
||||
</ha-dialog>
|
||||
`;
|
||||
|
@ -237,7 +237,7 @@ class DialogFloorDetail extends LitElement {
|
||||
>
|
||||
${entry
|
||||
? this.hass.localize("ui.common.save")
|
||||
: this.hass.localize("ui.common.add")}
|
||||
: this.hass.localize("ui.common.create")}
|
||||
</mwc-button>
|
||||
</ha-dialog>
|
||||
`;
|
||||
|
@ -51,7 +51,7 @@ class HaBackupConfigAgents extends LitElement {
|
||||
|
||||
private _description(agentId: string) {
|
||||
if (agentId === CLOUD_AGENT) {
|
||||
return "It stores one backup. The oldest backups are deleted.";
|
||||
return "Note: It stores only one backup, regardless of your settings.";
|
||||
}
|
||||
if (isNetworkMountAgent(agentId)) {
|
||||
return "Network storage";
|
||||
|
@ -195,7 +195,7 @@ class HaBackupConfigData extends LitElement {
|
||||
></ha-svg-icon>
|
||||
<span slot="headline">Media</span>
|
||||
<span slot="supporting-text">
|
||||
For example, camera recordings.
|
||||
This can include large filesize camera recordings.
|
||||
</span>
|
||||
<ha-switch
|
||||
id="media"
|
||||
@ -209,7 +209,7 @@ class HaBackupConfigData extends LitElement {
|
||||
<ha-svg-icon slot="start" .path=${mdiFolder}></ha-svg-icon>
|
||||
<span slot="headline">Share folder</span>
|
||||
<span slot="supporting-text">
|
||||
Folder that is often used for advanced or older
|
||||
Folder that is often used by add-ons for advanced or older
|
||||
configurations.
|
||||
</span>
|
||||
<ha-switch
|
||||
|
@ -75,6 +75,7 @@ class HaBackupSummaryCard extends LitElement {
|
||||
row-gap: 8px;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
padding-bottom: 8px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@ -145,10 +146,6 @@ class HaBackupSummaryCard extends LitElement {
|
||||
}
|
||||
|
||||
@media all and (max-width: 550px) {
|
||||
.summary {
|
||||
flex-wrap: wrap;
|
||||
padding: 8px;
|
||||
}
|
||||
.action {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
@ -1,84 +0,0 @@
|
||||
import { differenceInDays } from "date-fns";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { formatShortDateTime } from "../../../../common/datetime/format_date_time";
|
||||
import type { BackupContent } from "../../../../data/backup";
|
||||
import type { ManagerStateEvent } from "../../../../data/backup_manager";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import "./ha-backup-summary-card";
|
||||
|
||||
@customElement("ha-backup-summary-status")
|
||||
export class HaBackupSummaryProgress extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public manager!: ManagerStateEvent;
|
||||
|
||||
@property({ attribute: false }) public backups!: BackupContent[];
|
||||
|
||||
@property({ type: Boolean, attribute: "has-action" })
|
||||
public hasAction = false;
|
||||
|
||||
private _lastBackup = memoizeOne((backups: BackupContent[]) => {
|
||||
const sortedBackups = backups
|
||||
// eslint-disable-next-line arrow-body-style
|
||||
.filter((backup) => {
|
||||
// TODO : only show backups with default flag
|
||||
return backup.with_automatic_settings;
|
||||
})
|
||||
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
||||
|
||||
return sortedBackups[0] as BackupContent | undefined;
|
||||
});
|
||||
|
||||
protected render() {
|
||||
const lastBackup = this._lastBackup(this.backups);
|
||||
|
||||
if (!lastBackup) {
|
||||
return html`
|
||||
<ha-backup-summary-card
|
||||
heading="No backup available"
|
||||
description="You have not created any backups yet."
|
||||
.hasAction=${this.hasAction}
|
||||
status="warning"
|
||||
>
|
||||
<slot name="action" slot="action"></slot>
|
||||
</ha-backup-summary-card>
|
||||
`;
|
||||
}
|
||||
|
||||
const lastBackupDate = new Date(lastBackup.date);
|
||||
const numberOfDays = differenceInDays(new Date(), lastBackupDate);
|
||||
|
||||
// TODO : Improve time format
|
||||
const description = `Last successful backup ${formatShortDateTime(lastBackupDate, this.hass.locale, this.hass.config)} and synced to ${lastBackup.agent_ids?.length} locations`;
|
||||
if (numberOfDays > 8) {
|
||||
return html`
|
||||
<ha-backup-summary-card
|
||||
heading=${`No backup for ${numberOfDays} days`}
|
||||
description=${description}
|
||||
.hasAction=${this.hasAction}
|
||||
status="warning"
|
||||
>
|
||||
<slot name="action" slot="action"></slot>
|
||||
</ha-backup-summary-card>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<ha-backup-summary-card
|
||||
heading=${`Backed up`}
|
||||
description=${description}
|
||||
.hasAction=${this.hasAction}
|
||||
status="success"
|
||||
>
|
||||
<slot name="action" slot="action"></slot>
|
||||
</ha-backup-summary-card>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-backup-summary-status": HaBackupSummaryProgress;
|
||||
}
|
||||
}
|
@ -109,9 +109,13 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.card-header {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.card-content {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -31,21 +31,20 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
<div class="icon">
|
||||
<ha-svg-icon .path=${mdiInformationOutline}></ha-svg-icon>
|
||||
</div>
|
||||
Set up automatic backups
|
||||
Set up backups
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
Backups are essential to a reliable smart home. They protect your
|
||||
setup against failures and allows you to quickly have a working
|
||||
system again. It is recommended to create a daily backup and keep
|
||||
backups of the last 3 days on two different locations. And one of
|
||||
them is off-site.
|
||||
Backups are essential for a reliable smart home. They help protect
|
||||
the work you've put into setting up your smart home, and if the
|
||||
worst happens, you can get back up and running quickly. It is
|
||||
recommended that you create a backup every day. You should keep
|
||||
three backups in at least two different locations, one of which
|
||||
should be off-site.
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-button @click=${this._setup}>
|
||||
Set up automatic backups
|
||||
</ha-button>
|
||||
<ha-button @click=${this._setup}>Set up backups</ha-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`;
|
||||
|
@ -10,7 +10,11 @@ import "../../../../../components/ha-md-list";
|
||||
import "../../../../../components/ha-md-list-item";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import type { BackupConfig } from "../../../../../data/backup";
|
||||
import { BackupScheduleState, isLocalAgent } from "../../../../../data/backup";
|
||||
import {
|
||||
BackupScheduleState,
|
||||
computeBackupAgentName,
|
||||
isLocalAgent,
|
||||
} from "../../../../../data/backup";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
|
||||
@ -88,6 +92,14 @@ class HaBackupBackupsSummary extends LitElement {
|
||||
);
|
||||
|
||||
if (offsiteLocations.length) {
|
||||
if (offsiteLocations.length === 1) {
|
||||
const name = computeBackupAgentName(
|
||||
this.hass.localize,
|
||||
offsiteLocations[0],
|
||||
offsiteLocations
|
||||
);
|
||||
return `Upload to ${name}`;
|
||||
}
|
||||
return `Upload to ${offsiteLocations.length} off-site locations`;
|
||||
}
|
||||
if (hasLocal) {
|
||||
@ -184,9 +196,13 @@ class HaBackupBackupsSummary extends LitElement {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.card-header {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.card-content {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { mdiBackupRestore, mdiCalendar } from "@mdi/js";
|
||||
import { differenceInDays, setHours, setMinutes } from "date-fns";
|
||||
import { addHours, differenceInDays, setHours, setMinutes } from "date-fns";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
@ -17,6 +17,8 @@ import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import "../ha-backup-summary-card";
|
||||
|
||||
const OVERDUE_MARGIN_HOURS = 3;
|
||||
|
||||
@customElement("ha-backup-overview-summary")
|
||||
class HaBackupOverviewBackups extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@ -25,9 +27,14 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public config!: BackupConfig;
|
||||
|
||||
@property({ type: Boolean }) public fetching = false;
|
||||
|
||||
private _lastBackup = memoizeOne((backups: BackupContent[]) => {
|
||||
const sortedBackups = backups
|
||||
.filter((backup) => backup.with_automatic_settings)
|
||||
.filter(
|
||||
(backup) =>
|
||||
backup.with_automatic_settings && !backup.failed_agent_ids?.length
|
||||
)
|
||||
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
||||
|
||||
return sortedBackups[0] as BackupContent | undefined;
|
||||
@ -60,6 +67,23 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (this.fetching) {
|
||||
return html`
|
||||
<ha-backup-summary-card heading="Loading backups" status="loading">
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiBackupRestore}></ha-svg-icon>
|
||||
<span slot="headline" class="skeleton"></span>
|
||||
</ha-md-list-item>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiCalendar}></ha-svg-icon>
|
||||
<span slot="headline" class="skeleton"></span>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
</ha-backup-summary-card>
|
||||
`;
|
||||
}
|
||||
|
||||
const lastBackup = this._lastBackup(this.backups);
|
||||
|
||||
if (!lastBackup) {
|
||||
@ -75,10 +99,9 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
|
||||
const lastBackupDate = new Date(lastBackup.date);
|
||||
|
||||
const numberOfDays = differenceInDays(new Date(), lastBackupDate);
|
||||
const now = new Date();
|
||||
|
||||
const lastBackupDescription = `Last successful backup ${relativeTime(lastBackupDate, this.hass.locale, now, true)} and synced to ${lastBackup.agent_ids?.length} locations.`;
|
||||
const lastBackupDescription = `Last successful backup ${relativeTime(lastBackupDate, this.hass.locale, now, true)} and stored to ${lastBackup.agent_ids?.length} locations.`;
|
||||
const nextBackupDescription = this._nextBackupDescription(
|
||||
this.config.schedule.state
|
||||
);
|
||||
@ -94,51 +117,62 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
heading=${`Last automatic backup failed`}
|
||||
status="error"
|
||||
>
|
||||
<ul class="list">
|
||||
<li class="item">
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiBackupRestore}></ha-svg-icon>
|
||||
<span>${lastAttemptDescription}</span>
|
||||
</li>
|
||||
<li class="item">
|
||||
<span slot="headline">${lastAttemptDescription}</span>
|
||||
</ha-md-list-item>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiCalendar}></ha-svg-icon>
|
||||
<span>${lastBackupDescription}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span slot="headline">${lastBackupDescription}</span>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
</ha-backup-summary-card>
|
||||
`;
|
||||
}
|
||||
|
||||
if (numberOfDays > 0) {
|
||||
const numberOfDays = differenceInDays(
|
||||
// Subtract a few hours to avoid showing as overdue if it's just a few hours (e.g. daylight saving)
|
||||
addHours(now, -OVERDUE_MARGIN_HOURS),
|
||||
lastBackupDate
|
||||
);
|
||||
|
||||
const isOverdue =
|
||||
(numberOfDays >= 1 &&
|
||||
this.config.schedule.state === BackupScheduleState.DAILY) ||
|
||||
numberOfDays >= 7;
|
||||
|
||||
if (isOverdue) {
|
||||
return html`
|
||||
<ha-backup-summary-card
|
||||
heading=${`No backup for ${numberOfDays} days`}
|
||||
status="warning"
|
||||
>
|
||||
<ul class="list">
|
||||
<li class="item">
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiBackupRestore}></ha-svg-icon>
|
||||
<span>${lastBackupDescription}</span>
|
||||
</li>
|
||||
<li class="item">
|
||||
<span slot="headline">${lastBackupDescription}</span>
|
||||
</ha-md-list-item>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiCalendar}></ha-svg-icon>
|
||||
<span>${nextBackupDescription}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span slot="headline">${nextBackupDescription}</span>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
</ha-backup-summary-card>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<ha-backup-summary-card heading=${`Backed up`} status="success">
|
||||
<ul class="list">
|
||||
<li class="item">
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiBackupRestore}></ha-svg-icon>
|
||||
<span>${lastBackupDescription}</span>
|
||||
</li>
|
||||
<li class="item">
|
||||
<span slot="headline">${lastBackupDescription}</span>
|
||||
</ha-md-list-item>
|
||||
<ha-md-list-item>
|
||||
<ha-svg-icon slot="start" .path=${mdiCalendar}></ha-svg-icon>
|
||||
<span>${nextBackupDescription}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<span slot="headline">${nextBackupDescription}</span>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
</ha-backup-summary-card>
|
||||
`;
|
||||
}
|
||||
@ -156,25 +190,6 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
padding: 8px 24px 24px 24px;
|
||||
margin: 0;
|
||||
}
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
letter-spacing: 0.25px;
|
||||
}
|
||||
ha-svg-icon {
|
||||
flex: none;
|
||||
}
|
||||
@ -183,6 +198,42 @@ class HaBackupOverviewBackups extends LitElement {
|
||||
justify-content: flex-end;
|
||||
border-top: none;
|
||||
}
|
||||
ha-md-list {
|
||||
background: none;
|
||||
}
|
||||
ha-md-list-item {
|
||||
--md-list-item-top-space: 8px;
|
||||
--md-list-item-bottom-space: 8px;
|
||||
--md-list-item-one-line-container-height: 40x;
|
||||
}
|
||||
span.skeleton {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 160px;
|
||||
animation-fill-mode: forwards;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: loading;
|
||||
animation-timing-function: linear;
|
||||
animation-duration: 1.2s;
|
||||
border-radius: 4px;
|
||||
height: 20px;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
rgb(247, 249, 250) 8%,
|
||||
rgb(235, 238, 240) 18%,
|
||||
rgb(247, 249, 250) 33%
|
||||
)
|
||||
0% 0% / 936px 104px;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
background-position: -468px 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 468px 0;
|
||||
}
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -287,13 +287,14 @@ class DialogBackupOnboarding extends LitElement implements HassDialog {
|
||||
src="/static/images/voice-assistant/hi.png"
|
||||
alt="Casita Home Assistant logo"
|
||||
/>
|
||||
<h1>Set up your automatic backups</h1>
|
||||
<h1>Set up backups</h1>
|
||||
<p class="secondary">
|
||||
Backups are essential to a reliable smart home. They protect your
|
||||
setup against failures and allows you to quickly have a working
|
||||
system again. It is recommended to create a daily backup and keep
|
||||
backups of the last 3 days on two different locations. And one of
|
||||
them is off-site.
|
||||
Backups are essential for a reliable smart home. They help protect
|
||||
the work you've put into setting up your smart home, and if the
|
||||
worst happens, you can get back up and running quickly. It is
|
||||
recommended that you create a backup every day. You should keep
|
||||
three backups in at least two different locations, one of which
|
||||
should be off-site.
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
@ -327,21 +328,23 @@ class DialogBackupOnboarding extends LitElement implements HassDialog {
|
||||
case "setup":
|
||||
return html`
|
||||
<p>
|
||||
It is recommended to create a daily backup and keep backups of the
|
||||
last 3 days on two different locations. And one of them is off-site.
|
||||
It is recommended that you create a backup every day. You should
|
||||
keep three backups in at least two different locations, one of which
|
||||
should be off-site. Once you make your selection, your first backup
|
||||
will begin.
|
||||
</p>
|
||||
<ha-md-list class="full">
|
||||
<ha-md-list-item type="button" @click=${this._done}>
|
||||
<span slot="headline">Recommended settings</span>
|
||||
<span slot="supporting-text">
|
||||
Set the proven settings of daily backup.
|
||||
Backup everything daily, keeping three days of backups
|
||||
</span>
|
||||
<ha-icon-next slot="end"> </ha-icon-next>
|
||||
</ha-md-list-item>
|
||||
<ha-md-list-item type="button" @click=${this._nextStep}>
|
||||
<span slot="headline">Custom settings</span>
|
||||
<span slot="supporting-text">
|
||||
Select your own automation, data and locations
|
||||
Select when, where, and what to backup
|
||||
</span>
|
||||
<ha-icon-next slot="end"> </ha-icon-next>
|
||||
</ha-md-list-item>
|
||||
|
@ -152,7 +152,7 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">Download old emergency kit</span>
|
||||
<span slot="supporting-text">
|
||||
We recommend to save this encryption key somewhere secure.
|
||||
We recommend saving this encryption key file somewhere secure.
|
||||
</span>
|
||||
<ha-button slot="end" @click=${this._downloadOld}>
|
||||
<ha-svg-icon .path=${mdiDownload} slot="icon"></ha-svg-icon>
|
||||
@ -164,9 +164,10 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
case "new":
|
||||
return html`
|
||||
<p>
|
||||
All next backups will use the new encryption key. We recommend to
|
||||
save this key somewhere secure. As you can only restore your data
|
||||
with the backup encryption key.
|
||||
Keep this encryption key in a safe place, as you will need it to
|
||||
access your backup, allowing it to be restored. Either record the
|
||||
characters below or download them as an emergency kit file.
|
||||
Encryption keeps your backups private and secure.
|
||||
</p>
|
||||
<div class="encryption-key">
|
||||
<p>${this._newEncryptionKey}</p>
|
||||
@ -179,7 +180,7 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
|
||||
<ha-md-list-item>
|
||||
<span slot="headline">Download new emergency kit</span>
|
||||
<span slot="supporting-text">
|
||||
We recommend to save this encryption key somewhere secure.
|
||||
We recommend saving this encryption key file somewhere secure.
|
||||
</span>
|
||||
<ha-button slot="end" @click=${this._downloadNew}>
|
||||
<ha-svg-icon .path=${mdiDownload} slot="icon"></ha-svg-icon>
|
||||
|
@ -125,7 +125,8 @@ class HaConfigBackupDetails extends LitElement {
|
||||
: !this._backup
|
||||
? html`<ha-circular-progress active></ha-circular-progress>`
|
||||
: html`
|
||||
<ha-card header="Backup">
|
||||
<ha-card>
|
||||
<div class="card-header">Backup</div>
|
||||
<div class="card-content">
|
||||
<ha-md-list>
|
||||
<ha-md-list-item>
|
||||
@ -145,7 +146,8 @@ class HaConfigBackupDetails extends LitElement {
|
||||
</ha-md-list>
|
||||
</div>
|
||||
</ha-card>
|
||||
<ha-card header="Select what to restore">
|
||||
<ha-card>
|
||||
<div class="card-header">Select what to restore</div>
|
||||
<div class="card-content">
|
||||
<ha-backup-data-picker
|
||||
.hass=${this.hass}
|
||||
@ -166,7 +168,8 @@ class HaConfigBackupDetails extends LitElement {
|
||||
</ha-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
<ha-card header="Locations">
|
||||
<ha-card>
|
||||
<div class="card-header">Locations</div>
|
||||
<div class="card-content">
|
||||
<ha-md-list>
|
||||
${this._agents.map((agent) => {
|
||||
@ -355,7 +358,7 @@ class HaConfigBackupDetails extends LitElement {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.card-content {
|
||||
padding: 0 20px 8px 20px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.card-actions {
|
||||
display: flex;
|
||||
@ -368,6 +371,7 @@ class HaConfigBackupDetails extends LitElement {
|
||||
ha-md-list-item {
|
||||
--md-list-item-leading-space: 0;
|
||||
--md-list-item-trailing-space: 0;
|
||||
--md-list-item-two-line-container-height: 64px;
|
||||
}
|
||||
ha-md-list-item img {
|
||||
width: 48px;
|
||||
@ -410,6 +414,9 @@ class HaConfigBackupDetails extends LitElement {
|
||||
.dot.error {
|
||||
background-color: var(--error-color);
|
||||
}
|
||||
.card-header {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import "./components/ha-backup-summary-card";
|
||||
import "./components/ha-backup-summary-status";
|
||||
import "./components/overview/ha-backup-overview-backups";
|
||||
import "./components/overview/ha-backup-overview-onboarding";
|
||||
import "./components/overview/ha-backup-overview-progress";
|
||||
@ -182,31 +181,23 @@ class HaConfigBackupOverview extends LitElement {
|
||||
>
|
||||
</ha-backup-overview-progress>
|
||||
`
|
||||
: this.fetching
|
||||
: this._needsOnboarding
|
||||
? html`
|
||||
<ha-backup-summary-card
|
||||
heading="Loading backups"
|
||||
description="Your backup information is being retrieved."
|
||||
status="loading"
|
||||
<ha-backup-overview-onboarding
|
||||
.hass=${this.hass}
|
||||
@button-click=${this._handleOnboardingButtonClick}
|
||||
>
|
||||
</ha-backup-summary-card>
|
||||
</ha-backup-overview-onboarding>
|
||||
`
|
||||
: this._needsOnboarding
|
||||
? html`
|
||||
<ha-backup-overview-onboarding
|
||||
.hass=${this.hass}
|
||||
@button-click=${this._handleOnboardingButtonClick}
|
||||
>
|
||||
</ha-backup-overview-onboarding>
|
||||
`
|
||||
: html`
|
||||
<ha-backup-overview-summary
|
||||
.hass=${this.hass}
|
||||
.backups=${this.backups}
|
||||
.config=${this.config}
|
||||
>
|
||||
</ha-backup-overview-summary>
|
||||
`}
|
||||
: html`
|
||||
<ha-backup-overview-summary
|
||||
.hass=${this.hass}
|
||||
.backups=${this.backups}
|
||||
.config=${this.config}
|
||||
.fetching=${this.fetching}
|
||||
>
|
||||
</ha-backup-overview-summary>
|
||||
`}
|
||||
|
||||
<ha-backup-overview-backups
|
||||
.hass=${this.hass}
|
||||
|
@ -140,10 +140,10 @@ class HaConfigBackupSettings extends LitElement {
|
||||
<div class="card-header">Encryption key</div>
|
||||
<div class="card-content">
|
||||
<p>
|
||||
All your backups are encrypted to keep your data private and
|
||||
secure. You need this key to restore a backup. It's important
|
||||
that you don't lose this key, as no one else can restore your
|
||||
data.
|
||||
Keep this encryption key in a safe place, as you will need it to
|
||||
access your backup, allowing it to be restored. Either record
|
||||
the characters below or download them as an emergency kit file.
|
||||
Encryption keeps your backups private and secure.
|
||||
</p>
|
||||
<ha-backup-config-encryption-key
|
||||
.hass=${this.hass}
|
||||
@ -257,6 +257,12 @@ class HaConfigBackupSettings extends LitElement {
|
||||
.alert {
|
||||
--mdc-theme-primary: var(--error-color);
|
||||
}
|
||||
.card-header {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.card-content {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -436,9 +436,8 @@ class HaConfigIntegrationsDashboard extends SubscribeMixin(LitElement) {
|
||||
>
|
||||
${this.narrow
|
||||
? html`
|
||||
<div slot="header">
|
||||
<div slot="header" class="header">
|
||||
<search-input-outlined
|
||||
class="header"
|
||||
.hass=${this.hass}
|
||||
.filter=${this._filter}
|
||||
@value-changed=${this._handleSearchChange}
|
||||
@ -457,7 +456,6 @@ class HaConfigIntegrationsDashboard extends SubscribeMixin(LitElement) {
|
||||
></ha-integration-overflow-menu>
|
||||
<div class="search">
|
||||
<search-input-outlined
|
||||
class="header"
|
||||
.hass=${this.hass}
|
||||
.filter=${this._filter}
|
||||
@value-changed=${this._handleSearchChange}
|
||||
@ -982,6 +980,9 @@ class HaConfigIntegrationsDashboard extends SubscribeMixin(LitElement) {
|
||||
search-input-outlined {
|
||||
flex: 1;
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
}
|
||||
.search {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
@ -59,6 +59,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.size",
|
||||
options: ["auto", "cover", "contain"],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -79,6 +80,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
"bottom center",
|
||||
"bottom right",
|
||||
],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -89,6 +91,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
translation_key:
|
||||
"ui.panel.lovelace.editor.edit_view.background.repeat",
|
||||
options: ["repeat", "no-repeat"],
|
||||
mode: "dropdown",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -348,6 +348,7 @@
|
||||
"move": "Move",
|
||||
"save": "Save",
|
||||
"add": "Add",
|
||||
"create": "Create",
|
||||
"edit": "Edit",
|
||||
"submit": "Submit",
|
||||
"rename": "Rename",
|
||||
@ -2159,7 +2160,7 @@
|
||||
"edit_floor": "Edit floor",
|
||||
"delete_floor": "Delete floor",
|
||||
"confirm_delete": "Delete floor?",
|
||||
"confirm_delete_text": "Removing the floor will unassign all areas from it."
|
||||
"confirm_delete_text": "Deleting the floor will unassign all areas from it."
|
||||
}
|
||||
},
|
||||
"editor": {
|
||||
@ -4358,7 +4359,7 @@
|
||||
"error_delete": "Error deleting device",
|
||||
"picker": {
|
||||
"search": "Search {number} devices",
|
||||
"state": "State",
|
||||
"state": "Status",
|
||||
"bulk_actions": {
|
||||
"move_area": "Move to area",
|
||||
"no_area": "No area",
|
||||
|
Loading…
x
Reference in New Issue
Block a user