mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 23:36:36 +00:00
Update upload element (#17654)
This commit is contained in:
parent
d350c35c4e
commit
2ab67328d4
@ -31,6 +31,7 @@ export class HassioUploadBackup extends LitElement {
|
|||||||
.icon=${mdiFolderUpload}
|
.icon=${mdiFolderUpload}
|
||||||
accept="application/x-tar"
|
accept="application/x-tar"
|
||||||
label="Upload backup"
|
label="Upload backup"
|
||||||
|
supports="Supports .TAR files"
|
||||||
@file-picked=${this._uploadFile}
|
@file-picked=${this._uploadFile}
|
||||||
auto-open-file-dialog
|
auto-open-file-dialog
|
||||||
></ha-file-upload>
|
></ha-file-upload>
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
import { styles } from "@material/mwc-textfield/mwc-textfield.css";
|
import "@material/mwc-linear-progress/mwc-linear-progress";
|
||||||
import { mdiClose } from "@mdi/js";
|
import { mdiDelete, mdiFileUpload } from "@mdi/js";
|
||||||
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
|
import { LitElement, PropertyValues, TemplateResult, css, html } 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";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import "./ha-circular-progress";
|
import "./ha-button";
|
||||||
import "./ha-icon-button";
|
import "./ha-icon-button";
|
||||||
|
import { blankBeforePercent } from "../common/translations/blank_before_percent";
|
||||||
|
import { ensureArray } from "../common/array/ensure-array";
|
||||||
|
import { bytesToString } from "../util/bytes-to-string";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"file-picked": { files: FileList };
|
"file-picked": { files: File[] };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,12 +25,22 @@ export class HaFileUpload extends LitElement {
|
|||||||
|
|
||||||
@property() public icon?: string;
|
@property() public icon?: string;
|
||||||
|
|
||||||
@property() public label!: string;
|
@property() public label?: string;
|
||||||
|
|
||||||
@property() public value: string | TemplateResult | null = null;
|
@property() public secondary?: string;
|
||||||
|
|
||||||
|
@property() public supports?: string;
|
||||||
|
|
||||||
|
@property() public value?: File | File[] | FileList | string;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) private multiple = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean, reflect: true }) public disabled: boolean = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) private uploading = false;
|
@property({ type: Boolean }) private uploading = false;
|
||||||
|
|
||||||
|
@property({ type: Number }) private progress?: number;
|
||||||
|
|
||||||
@property({ type: Boolean, attribute: "auto-open-file-dialog" })
|
@property({ type: Boolean, attribute: "auto-open-file-dialog" })
|
||||||
private autoOpenFileDialog = false;
|
private autoOpenFileDialog = false;
|
||||||
|
|
||||||
@ -45,72 +58,102 @@ export class HaFileUpload extends LitElement {
|
|||||||
public render(): TemplateResult {
|
public render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
${this.uploading
|
${this.uploading
|
||||||
? html`<ha-circular-progress
|
? html`<div class="container">
|
||||||
alt="Uploading"
|
<div class="row">
|
||||||
size="large"
|
<span class="header"
|
||||||
active
|
>${this.value
|
||||||
></ha-circular-progress>`
|
? this.hass?.localize(
|
||||||
: html`
|
"ui.components.file-upload.uploading_name",
|
||||||
<label
|
{ name: this.value }
|
||||||
for="input"
|
)
|
||||||
class="mdc-text-field mdc-text-field--filled ${classMap({
|
: this.hass?.localize(
|
||||||
"mdc-text-field--focused": this._drag,
|
"ui.components.file-upload.uploading"
|
||||||
"mdc-text-field--with-leading-icon": Boolean(this.icon),
|
)}</span
|
||||||
"mdc-text-field--with-trailing-icon": Boolean(this.value),
|
>
|
||||||
|
${this.progress
|
||||||
|
? html`<span class="progress"
|
||||||
|
>${this.progress}${blankBeforePercent(
|
||||||
|
this.hass!.locale
|
||||||
|
)}%</span
|
||||||
|
>`
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
|
<mwc-linear-progress
|
||||||
|
.indeterminate=${!this.progress}
|
||||||
|
.progress=${this.progress ? this.progress / 100 : undefined}
|
||||||
|
></mwc-linear-progress>
|
||||||
|
</div>`
|
||||||
|
: html`<label
|
||||||
|
for=${this.value ? "" : "input"}
|
||||||
|
class="container ${classMap({
|
||||||
|
dragged: this._drag,
|
||||||
|
multiple: this.multiple,
|
||||||
|
value: Boolean(this.value),
|
||||||
})}"
|
})}"
|
||||||
@drop=${this._handleDrop}
|
@drop=${this._handleDrop}
|
||||||
@dragenter=${this._handleDragStart}
|
@dragenter=${this._handleDragStart}
|
||||||
@dragover=${this._handleDragStart}
|
@dragover=${this._handleDragStart}
|
||||||
@dragleave=${this._handleDragEnd}
|
@dragleave=${this._handleDragEnd}
|
||||||
@dragend=${this._handleDragEnd}
|
@dragend=${this._handleDragEnd}
|
||||||
|
>${!this.value
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
class="big-icon"
|
||||||
|
.path=${this.icon || mdiFileUpload}
|
||||||
|
></ha-svg-icon>
|
||||||
|
<ha-button unelevated @click=${this._openFilePicker}>
|
||||||
|
${this.label ||
|
||||||
|
this.hass?.localize("ui.components.file-upload.label")}
|
||||||
|
</ha-button>
|
||||||
|
<span class="secondary"
|
||||||
|
>${this.secondary ||
|
||||||
|
this.hass?.localize(
|
||||||
|
"ui.components.file-upload.secondary"
|
||||||
|
)}</span
|
||||||
>
|
>
|
||||||
<span class="mdc-text-field__ripple"></span>
|
<span class="supports">${this.supports}</span>`
|
||||||
<span
|
: typeof this.value === "string"
|
||||||
class="mdc-floating-label ${this.value || this._drag
|
? html`<div class="row">
|
||||||
? "mdc-floating-label--float-above"
|
<div class="value" @click=${this._openFilePicker}>
|
||||||
: ""}"
|
<ha-svg-icon
|
||||||
id="label"
|
.path=${this.icon || mdiFileUpload}
|
||||||
>${this.label}</span
|
></ha-svg-icon>
|
||||||
>
|
${this.value}
|
||||||
${this.icon
|
</div>
|
||||||
? html`<span
|
|
||||||
class="mdc-text-field__icon mdc-text-field__icon--leading"
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
@click=${this._openFilePicker}
|
@click=${this._clearValue}
|
||||||
.path=${this.icon}
|
.label=${this.hass?.localize("ui.common.delete") ||
|
||||||
|
"Delete"}
|
||||||
|
.path=${mdiDelete}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
</span>`
|
</div>`
|
||||||
: ""}
|
: (this.value instanceof FileList
|
||||||
<div class="value">${this.value}</div>
|
? Array.from(this.value)
|
||||||
|
: ensureArray(this.value)
|
||||||
|
).map(
|
||||||
|
(file) =>
|
||||||
|
html`<div class="row">
|
||||||
|
<div class="value" @click=${this._openFilePicker}>
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${this.icon || mdiFileUpload}
|
||||||
|
></ha-svg-icon>
|
||||||
|
${file.name} - ${bytesToString(file.size)}
|
||||||
|
</div>
|
||||||
|
<ha-icon-button
|
||||||
|
@click=${this._clearValue}
|
||||||
|
.label=${this.hass?.localize("ui.common.delete") ||
|
||||||
|
"Delete"}
|
||||||
|
.path=${mdiDelete}
|
||||||
|
></ha-icon-button>
|
||||||
|
</div>`
|
||||||
|
)}
|
||||||
<input
|
<input
|
||||||
id="input"
|
id="input"
|
||||||
type="file"
|
type="file"
|
||||||
class="mdc-text-field__input file"
|
class="file"
|
||||||
accept=${this.accept}
|
.accept=${this.accept}
|
||||||
|
.multiple=${this.multiple}
|
||||||
@change=${this._handleFilePicked}
|
@change=${this._handleFilePicked}
|
||||||
aria-labelledby="label"
|
/></label>`}
|
||||||
/>
|
|
||||||
${this.value
|
|
||||||
? html`<span
|
|
||||||
class="mdc-text-field__icon mdc-text-field__icon--trailing"
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
|
||||||
slot="suffix"
|
|
||||||
@click=${this._clearValue}
|
|
||||||
.label=${this.hass?.localize("ui.common.close") ||
|
|
||||||
"close"}
|
|
||||||
.path=${mdiClose}
|
|
||||||
></ha-icon-button>
|
|
||||||
</span>`
|
|
||||||
: ""}
|
|
||||||
<span
|
|
||||||
class="mdc-line-ripple ${this._drag
|
|
||||||
? "mdc-line-ripple--active"
|
|
||||||
: ""}"
|
|
||||||
></span>
|
|
||||||
</label>
|
|
||||||
`}
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +165,12 @@ export class HaFileUpload extends LitElement {
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (ev.dataTransfer?.files) {
|
if (ev.dataTransfer?.files) {
|
||||||
fireEvent(this, "file-picked", { files: ev.dataTransfer.files });
|
fireEvent(this, "file-picked", {
|
||||||
|
files:
|
||||||
|
this.multiple || ev.dataTransfer.files.length === 1
|
||||||
|
? Array.from(ev.dataTransfer.files)
|
||||||
|
: [ev.dataTransfer.files[0]],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this._drag = false;
|
this._drag = false;
|
||||||
}
|
}
|
||||||
@ -140,93 +188,121 @@ export class HaFileUpload extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleFilePicked(ev) {
|
private _handleFilePicked(ev) {
|
||||||
|
if (ev.target.files.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.value = ev.target.files;
|
||||||
fireEvent(this, "file-picked", { files: ev.target.files });
|
fireEvent(this, "file-picked", { files: ev.target.files });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _clearValue(ev: Event) {
|
private _clearValue(ev: Event) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
this.value = null;
|
|
||||||
this._input!.value = "";
|
this._input!.value = "";
|
||||||
|
this.value = undefined;
|
||||||
fireEvent(this, "change");
|
fireEvent(this, "change");
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [
|
return css`
|
||||||
styles,
|
|
||||||
css`
|
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
|
height: 240px;
|
||||||
}
|
}
|
||||||
.mdc-text-field--filled {
|
:host([disabled]) {
|
||||||
height: auto;
|
pointer-events: none;
|
||||||
padding-top: 16px;
|
color: var(--disabled-text-color);
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: solid 1px
|
||||||
|
var(--mdc-text-field-idle-line-color, rgba(0, 0, 0, 0.42));
|
||||||
|
border-radius: var(--mdc-shape-small, 4px);
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
label.container {
|
||||||
|
border: dashed 1px
|
||||||
|
var(--mdc-text-field-idle-line-color, rgba(0, 0, 0, 0.42));
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.mdc-text-field--filled.mdc-text-field--with-trailing-icon {
|
:host([disabled]) .container {
|
||||||
padding-top: 28px;
|
border-color: var(--disabled-color);
|
||||||
}
|
}
|
||||||
.mdc-text-field:not(.mdc-text-field--disabled) .mdc-text-field__icon {
|
label.dragged {
|
||||||
color: var(--secondary-text-color);
|
border-color: var(--primary-color);
|
||||||
}
|
|
||||||
.mdc-text-field--filled.mdc-text-field--with-trailing-icon
|
|
||||||
.mdc-text-field__icon {
|
|
||||||
align-self: flex-end;
|
|
||||||
}
|
|
||||||
.mdc-text-field__icon--leading {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
inset-inline-start: initial;
|
|
||||||
inset-inline-end: 0px;
|
|
||||||
direction: var(--direction);
|
|
||||||
}
|
|
||||||
.mdc-text-field--filled .mdc-floating-label--float-above {
|
|
||||||
transform: scale(0.75);
|
|
||||||
top: 8px;
|
|
||||||
}
|
|
||||||
.mdc-floating-label {
|
|
||||||
inset-inline-start: 16px !important;
|
|
||||||
inset-inline-end: initial !important;
|
|
||||||
direction: var(--direction);
|
|
||||||
}
|
|
||||||
.mdc-text-field--filled .mdc-floating-label {
|
|
||||||
inset-inline-start: 48px !important;
|
|
||||||
inset-inline-end: initial !important;
|
|
||||||
direction: var(--direction);
|
|
||||||
}
|
|
||||||
.mdc-text-field__icon--trailing {
|
|
||||||
pointer-events: auto !important;
|
|
||||||
}
|
}
|
||||||
.dragged:before {
|
.dragged:before {
|
||||||
position: var(--layout-fit_-_position);
|
position: absolute;
|
||||||
top: var(--layout-fit_-_top);
|
top: 0;
|
||||||
right: var(--layout-fit_-_right);
|
right: 0;
|
||||||
bottom: var(--layout-fit_-_bottom);
|
bottom: 0;
|
||||||
left: var(--layout-fit_-_left);
|
left: 0;
|
||||||
background: currentColor;
|
background-color: var(--primary-color);
|
||||||
content: "";
|
content: "";
|
||||||
opacity: var(--dark-divider-opacity);
|
opacity: var(--dark-divider-opacity);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
border-radius: 4px;
|
border-radius: var(--mdc-shape-small, 4px);
|
||||||
}
|
}
|
||||||
.value {
|
label.value {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
label.value.multiple {
|
||||||
|
justify-content: unset;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.highlight {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
ha-button {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.supports {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
:host([disabled]) .secondary {
|
||||||
|
color: var(--disabled-text-color);
|
||||||
}
|
}
|
||||||
input.file {
|
input.file {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
img {
|
.value {
|
||||||
max-width: 100%;
|
cursor: pointer;
|
||||||
max-height: 125px;
|
|
||||||
}
|
}
|
||||||
ha-icon-button {
|
.value ha-svg-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.big-icon {
|
||||||
|
--mdc-icon-size: 48px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
ha-button {
|
||||||
|
--mdc-button-outline-color: var(--primary-color);
|
||||||
--mdc-icon-button-size: 24px;
|
--mdc-icon-button-size: 24px;
|
||||||
--mdc-icon-size: 20px;
|
|
||||||
}
|
}
|
||||||
ha-circular-progress {
|
mwc-linear-progress {
|
||||||
display: block;
|
width: 100%;
|
||||||
text-align-last: center;
|
padding: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
`,
|
.header {
|
||||||
];
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.progress {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { mdiImagePlus } from "@mdi/js";
|
import { mdiImagePlus } from "@mdi/js";
|
||||||
import { html, LitElement, TemplateResult } from "lit";
|
import { LitElement, TemplateResult, css, html } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { createImage, generateImageThumbnailUrl } from "../data/image_upload";
|
import { createImage, generateImageThumbnailUrl } from "../data/image_upload";
|
||||||
@ -9,6 +9,7 @@ import {
|
|||||||
showImageCropperDialog,
|
showImageCropperDialog,
|
||||||
} from "../dialogs/image-cropper-dialog/show-image-cropper-dialog";
|
} from "../dialogs/image-cropper-dialog/show-image-cropper-dialog";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
|
import "./ha-button";
|
||||||
import "./ha-circular-progress";
|
import "./ha-circular-progress";
|
||||||
import "./ha-file-upload";
|
import "./ha-file-upload";
|
||||||
|
|
||||||
@ -20,6 +21,12 @@ export class HaPictureUpload extends LitElement {
|
|||||||
|
|
||||||
@property() public label?: string;
|
@property() public label?: string;
|
||||||
|
|
||||||
|
@property() public secondary?: string;
|
||||||
|
|
||||||
|
@property() public supports?: string;
|
||||||
|
|
||||||
|
@property() public currentImageAltText?: string;
|
||||||
|
|
||||||
@property({ type: Boolean }) public crop = false;
|
@property({ type: Boolean }) public crop = false;
|
||||||
|
|
||||||
@property({ attribute: false }) public cropOptions?: CropOptions;
|
@property({ attribute: false }) public cropOptions?: CropOptions;
|
||||||
@ -29,20 +36,45 @@ export class HaPictureUpload extends LitElement {
|
|||||||
@state() private _uploading = false;
|
@state() private _uploading = false;
|
||||||
|
|
||||||
public render(): TemplateResult {
|
public render(): TemplateResult {
|
||||||
|
if (!this.value) {
|
||||||
return html`
|
return html`
|
||||||
<ha-file-upload
|
<ha-file-upload
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.icon=${mdiImagePlus}
|
.icon=${mdiImagePlus}
|
||||||
.label=${this.label ||
|
.label=${this.label ||
|
||||||
this.hass.localize("ui.components.picture-upload.label")}
|
this.hass.localize("ui.components.picture-upload.label")}
|
||||||
|
.secondary=${this.secondary}
|
||||||
|
.supports=${this.supports ||
|
||||||
|
this.hass.localize("ui.components.picture-upload.supported_formats")}
|
||||||
.uploading=${this._uploading}
|
.uploading=${this._uploading}
|
||||||
.value=${this.value ? html`<img .src=${this.value} />` : ""}
|
|
||||||
@file-picked=${this._handleFilePicked}
|
@file-picked=${this._handleFilePicked}
|
||||||
@change=${this._handleFileCleared}
|
@change=${this._handleFileCleared}
|
||||||
accept="image/png, image/jpeg, image/gif"
|
accept="image/png, image/jpeg, image/gif"
|
||||||
></ha-file-upload>
|
></ha-file-upload>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
return html`<div class="center-vertical">
|
||||||
|
<div class="value">
|
||||||
|
<img
|
||||||
|
.src=${this.value}
|
||||||
|
alt=${this.currentImageAltText ||
|
||||||
|
this.hass.localize("ui.components.picture-upload.current_image_alt")}
|
||||||
|
/>
|
||||||
|
<ha-button
|
||||||
|
@click=${this._handleChangeClick}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.components.picture-upload.change_picture"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
</ha-button>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleChangeClick() {
|
||||||
|
this.value = null;
|
||||||
|
fireEvent(this, "change");
|
||||||
|
}
|
||||||
|
|
||||||
private async _handleFilePicked(ev) {
|
private async _handleFilePicked(ev) {
|
||||||
const file = ev.detail.files[0];
|
const file = ev.detail.files[0];
|
||||||
@ -100,6 +132,35 @@ export class HaPictureUpload extends LitElement {
|
|||||||
this._uploading = false;
|
this._uploading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
height: 240px;
|
||||||
|
}
|
||||||
|
ha-file-upload {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.center-vertical {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 200px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
border-radius: var(--file-upload-image-border-radius);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -37,9 +37,12 @@ export class HaFileSelector extends LitElement {
|
|||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.helper=${this.helper}
|
.supports=${this.helper}
|
||||||
.uploading=${this._busy}
|
.uploading=${this._busy}
|
||||||
.value=${this.value ? this._filename?.name || "Unknown file" : ""}
|
.value=${this.value
|
||||||
|
? this._filename?.name ||
|
||||||
|
this.hass.localize("ui.components.selectors.file.unknown_file")
|
||||||
|
: undefined}
|
||||||
@file-picked=${this._uploadFile}
|
@file-picked=${this._uploadFile}
|
||||||
@change=${this._removeFile}
|
@change=${this._removeFile}
|
||||||
></ha-file-upload>
|
></ha-file-upload>
|
||||||
|
@ -100,6 +100,14 @@ class DialogAreaDetail extends LitElement {
|
|||||||
dialogInitialFocus
|
dialogInitialFocus
|
||||||
></ha-textfield>
|
></ha-textfield>
|
||||||
|
|
||||||
|
<ha-picture-upload
|
||||||
|
.hass=${this.hass}
|
||||||
|
.value=${this._picture}
|
||||||
|
crop
|
||||||
|
.cropOptions=${cropOptions}
|
||||||
|
@change=${this._pictureChanged}
|
||||||
|
></ha-picture-upload>
|
||||||
|
|
||||||
<div class="label">
|
<div class="label">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.areas.editor.aliases_section"
|
"ui.panel.config.areas.editor.aliases_section"
|
||||||
@ -132,14 +140,6 @@ class DialogAreaDetail extends LitElement {
|
|||||||
"ui.panel.config.areas.editor.aliases_description"
|
"ui.panel.config.areas.editor.aliases_description"
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ha-picture-upload
|
|
||||||
.hass=${this.hass}
|
|
||||||
.value=${this._picture}
|
|
||||||
crop
|
|
||||||
.cropOptions=${cropOptions}
|
|
||||||
@change=${this._pictureChanged}
|
|
||||||
></ha-picture-upload>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
${entry
|
${entry
|
||||||
@ -229,7 +229,8 @@ class DialogAreaDetail extends LitElement {
|
|||||||
return [
|
return [
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
css`
|
css`
|
||||||
ha-textfield {
|
ha-textfield,
|
||||||
|
ha-picture-upload {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
@ -110,10 +110,10 @@ class DialogZWaveJSUpdateFirmwareNode extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.uploading=${this._uploading}
|
.uploading=${this._uploading}
|
||||||
.icon=${mdiFileUpload}
|
.icon=${mdiFileUpload}
|
||||||
label=${this._firmwareFile?.name ??
|
.label=${this.hass.localize(
|
||||||
this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.update_firmware.upload_firmware"
|
"ui.panel.config.zwave_js.update_firmware.upload_firmware"
|
||||||
)}
|
)}
|
||||||
|
.value=${this._firmwareFile}
|
||||||
@file-picked=${this._uploadFile}
|
@file-picked=${this._uploadFile}
|
||||||
></ha-file-upload>
|
></ha-file-upload>
|
||||||
${this._nodeStatus.is_controller_node
|
${this._nodeStatus.is_controller_node
|
||||||
|
@ -126,6 +126,7 @@ class DialogPersonDetail extends LitElement {
|
|||||||
)}
|
)}
|
||||||
required
|
required
|
||||||
></ha-textfield>
|
></ha-textfield>
|
||||||
|
|
||||||
<ha-picture-upload
|
<ha-picture-upload
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._picture}
|
.value=${this._picture}
|
||||||
@ -422,7 +423,8 @@ class DialogPersonDetail extends LitElement {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
ha-picture-upload {
|
ha-picture-upload {
|
||||||
margin-top: 16px;
|
margin-bottom: 16px;
|
||||||
|
--file-upload-image-border-radius: 50%;
|
||||||
}
|
}
|
||||||
ha-formfield {
|
ha-formfield {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -318,6 +318,10 @@
|
|||||||
"manual": "Manually enter media ID",
|
"manual": "Manually enter media ID",
|
||||||
"media_content_id": "Media content ID",
|
"media_content_id": "Media content ID",
|
||||||
"media_content_type": "Media content type"
|
"media_content_type": "Media content type"
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"upload_failed": "Upload failed",
|
||||||
|
"unknown_file": "Unknown file"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"logbook": {
|
"logbook": {
|
||||||
@ -498,8 +502,18 @@
|
|||||||
"filtered_by_device": "device: {device_name}",
|
"filtered_by_device": "device: {device_name}",
|
||||||
"filtered_by_area": "area: {area_name}"
|
"filtered_by_area": "area: {area_name}"
|
||||||
},
|
},
|
||||||
|
"file-upload": {
|
||||||
|
"uploading": "Uploading...",
|
||||||
|
"uploading_name": "Uploading {name}",
|
||||||
|
"label": "Add file",
|
||||||
|
"secondary": "Or drop your file here",
|
||||||
|
"unsupported_format": "Unsupported format, please choose a JPEG, PNG, or GIF image."
|
||||||
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "Picture",
|
"label": "Add picture",
|
||||||
|
"change_picture": "Change picture",
|
||||||
|
"current_image_alt": "Current picture",
|
||||||
|
"supported_formats": "Supports JPEG, PNG, or GIF image.",
|
||||||
"unsupported_format": "Unsupported format, please choose a JPEG, PNG, or GIF image."
|
"unsupported_format": "Unsupported format, please choose a JPEG, PNG, or GIF image."
|
||||||
},
|
},
|
||||||
"date-range-picker": {
|
"date-range-picker": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user