Simplify dashboard background upload (#23633)

This commit is contained in:
Wendelin 2025-01-09 09:25:09 +01:00 committed by GitHub
parent 788441499a
commit 9ec9c7e56b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 126 additions and 19 deletions

View File

@ -1,7 +1,7 @@
import "@material/mwc-linear-progress/mwc-linear-progress"; import "@material/mwc-linear-progress/mwc-linear-progress";
import { mdiDelete, mdiFileUpload } from "@mdi/js"; import { mdiDelete, mdiFileUpload } from "@mdi/js";
import type { PropertyValues, TemplateResult } from "lit"; import type { PropertyValues, TemplateResult } from "lit";
import { LitElement, css, html } from "lit"; import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
@ -76,7 +76,7 @@ export class HaFileUpload extends LitElement {
return html` return html`
${this.uploading ${this.uploading
? html`<div class="container"> ? html`<div class="container">
<div class="row"> <div class="uploading">
<span class="header" <span class="header"
>${this.value >${this.value
? this.hass?.localize( ? this.hass?.localize(
@ -88,12 +88,10 @@ export class HaFileUpload extends LitElement {
)}</span )}</span
> >
${this.progress ${this.progress
? html`<span class="progress" ? html`<div class="progress">
>${this.progress}${blankBeforePercent( ${this.progress}${blankBeforePercent(this.hass!.locale)}%
this.hass!.locale </div>`
)}%</span : nothing}
>`
: ""}
</div> </div>
<mwc-linear-progress <mwc-linear-progress
.indeterminate=${!this.progress} .indeterminate=${!this.progress}
@ -246,9 +244,21 @@ export class HaFileUpload extends LitElement {
var(--mdc-text-field-idle-line-color, rgba(0, 0, 0, 0.42)); var(--mdc-text-field-idle-line-color, rgba(0, 0, 0, 0.42));
cursor: pointer; cursor: pointer;
} }
.container .uploading {
display: flex;
flex-direction: column;
width: 100%;
align-items: flex-start;
padding: 0 32px;
box-sizing: border-box;
}
:host([disabled]) .container { :host([disabled]) .container {
border-color: var(--disabled-color); border-color: var(--disabled-color);
} }
label:hover,
label.dragged {
border-style: solid;
}
label.dragged { label.dragged {
border-color: var(--primary-color); border-color: var(--primary-color);
} }
@ -274,14 +284,6 @@ export class HaFileUpload extends LitElement {
.highlight { .highlight {
color: var(--primary-color); color: var(--primary-color);
} }
.row {
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
padding: 0 16px;
box-sizing: border-box;
}
ha-button { ha-button {
margin-bottom: 4px; margin-bottom: 4px;
} }
@ -313,7 +315,7 @@ export class HaFileUpload extends LitElement {
} }
mwc-linear-progress { mwc-linear-progress {
width: 100%; width: 100%;
padding: 16px; padding: 8px 32px;
box-sizing: border-box; box-sizing: border-box;
} }
.header { .header {

View File

@ -0,0 +1,96 @@
import type { CSSResultGroup } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import type { BackgroundSelector } from "../../data/selector";
import type { HomeAssistant } from "../../types";
import "../ha-picture-upload";
import "../ha-alert";
import type { HaPictureUpload } from "../ha-picture-upload";
import { URL_PREFIX } from "../../data/image_upload";
@customElement("ha-selector-background")
export class HaBackgroundSelector extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public value?: any;
@property({ attribute: false }) public selector!: BackgroundSelector;
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public required = true;
@state() private yamlBackground = false;
protected updated(changedProps) {
super.updated(changedProps);
if (changedProps.has("value")) {
this.yamlBackground = !!this.value && !this.value.startsWith(URL_PREFIX);
}
}
protected render() {
return html`
<div>
${this.yamlBackground
? html`
<ha-alert alert-type="info">
${this.hass.localize(
`ui.components.selectors.background.yaml_info`
)}
<ha-button slot="action" @click=${this._clearValue}>
${this.hass.localize(
`ui.components.picture-upload.clear_picture`
)}
</ha-button>
</ha-alert>
`
: html`
<ha-picture-upload
.hass=${this.hass}
.value=${this.value?.startsWith(URL_PREFIX) ? this.value : null}
.original=${this.selector.background?.original}
.cropOptions=${this.selector.background?.crop}
select-media
@change=${this._pictureChanged}
></ha-picture-upload>
`}
</div>
`;
}
private _pictureChanged(ev) {
const value = (ev.target as HaPictureUpload).value;
fireEvent(this, "value-changed", { value: value ?? undefined });
}
private _clearValue() {
fireEvent(this, "value-changed", { value: undefined });
}
static get styles(): CSSResultGroup {
return css`
:host {
display: block;
position: relative;
}
div {
display: flex;
flex-direction: column;
}
ha-button {
white-space: nowrap;
--mdc-theme-primary: var(--primary-color);
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-selector-background": HaBackgroundSelector;
}
}

View File

@ -34,6 +34,7 @@ const LOAD_ELEMENTS = {
floor: () => import("./ha-selector-floor"), floor: () => import("./ha-selector-floor"),
label: () => import("./ha-selector-label"), label: () => import("./ha-selector-label"),
image: () => import("./ha-selector-image"), image: () => import("./ha-selector-image"),
background: () => import("./ha-selector-background"),
language: () => import("./ha-selector-language"), language: () => import("./ha-selector-language"),
navigation: () => import("./ha-selector-navigation"), navigation: () => import("./ha-selector-navigation"),
number: () => import("./ha-selector-number"), number: () => import("./ha-selector-number"),

View File

@ -46,6 +46,7 @@ export type Selector =
| IconSelector | IconSelector
| LabelSelector | LabelSelector
| ImageSelector | ImageSelector
| BackgroundSelector
| LanguageSelector | LanguageSelector
| LocationSelector | LocationSelector
| MediaSelector | MediaSelector
@ -275,6 +276,10 @@ export interface ImageSelector {
image: { original?: boolean; crop?: CropOptions } | null; image: { original?: boolean; crop?: CropOptions } | null;
} }
export interface BackgroundSelector {
background: { original?: boolean; crop?: CropOptions } | null;
}
export interface LabelSelector { export interface LabelSelector {
label: { label: {
multiple?: boolean; multiple?: boolean;

View File

@ -6,7 +6,7 @@ import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-form/ha-form"; import "../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../components/ha-form/types";
import "../../../../components/ha-selector/ha-selector-image"; import "../../../../components/ha-selector/ha-selector-background";
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view"; import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
@ -26,7 +26,7 @@ export class HuiViewBackgroundEditor extends LitElement {
private _schema = memoizeOne((showSettings: boolean) => [ private _schema = memoizeOne((showSettings: boolean) => [
{ {
name: "image", name: "image",
selector: { image: { original: true } }, selector: { background: { original: true } },
}, },
...(showSettings ...(showSettings
? ([ ? ([

View File

@ -392,6 +392,9 @@
"upload": "Upload picture", "upload": "Upload picture",
"url": "Local path or web URL" "url": "Local path or web URL"
}, },
"background": {
"yaml_info": "Background image is set via yaml editor."
},
"location": { "location": {
"latitude": "[%key:ui::panel::config::zone::detail::latitude%]", "latitude": "[%key:ui::panel::config::zone::detail::latitude%]",
"longitude": "[%key:ui::panel::config::zone::detail::longitude%]", "longitude": "[%key:ui::panel::config::zone::detail::longitude%]",