mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-15 22:10:20 +00:00
Compare commits
4 Commits
copilot/fi
...
editor-hig
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aecbfeaaa0 | ||
|
|
498732566e | ||
|
|
b22c51bc2c | ||
|
|
5bc2fd059c |
@@ -6,7 +6,8 @@ import {
|
|||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
@@ -54,6 +55,8 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
return { type: "entities", entities: foundEntities };
|
return { type: "entities", entities: foundEntities };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property() public editMode?: boolean | any;
|
||||||
|
|
||||||
@state() private _config?: EntitiesCardConfig;
|
@state() private _config?: EntitiesCardConfig;
|
||||||
|
|
||||||
private _hass?: HomeAssistant;
|
private _hass?: HomeAssistant;
|
||||||
@@ -217,9 +220,15 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
`}
|
`}
|
||||||
</h1>
|
</h1>
|
||||||
`}
|
`}
|
||||||
<div id="states" class="card-content">
|
<div
|
||||||
${this._configEntities!.map((entityConf) =>
|
id="states"
|
||||||
this.renderEntity(entityConf)
|
class=${classMap({
|
||||||
|
"card-content": true,
|
||||||
|
highlight: this.editMode?.selectedRow !== undefined,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
${this._configEntities!.map((entityConf, idx) =>
|
||||||
|
this.renderEntity(entityConf, idx)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -272,6 +281,12 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
#states > div {
|
#states > div {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
#states.highlight > div.selected {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#states.highlight > div {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
padding: 0px 18px 0px 8px;
|
padding: 0px 18px 0px 8px;
|
||||||
@@ -293,7 +308,10 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderEntity(entityConf: LovelaceRowConfig): TemplateResult {
|
private renderEntity(
|
||||||
|
entityConf: LovelaceRowConfig,
|
||||||
|
idx: number
|
||||||
|
): TemplateResult {
|
||||||
const element = createRowElement(
|
const element = createRowElement(
|
||||||
(!("type" in entityConf) || entityConf.type === "conditional") &&
|
(!("type" in entityConf) || entityConf.type === "conditional") &&
|
||||||
this._config!.state_color
|
this._config!.state_color
|
||||||
@@ -307,7 +325,13 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
element.hass = this._hass;
|
element.hass = this._hass;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`<div>${element}</div>`;
|
return html`<div
|
||||||
|
class=${classMap({
|
||||||
|
selected: this.editMode?.selectedRow === idx,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
${element}
|
||||||
|
</div>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { property, state } from "lit/decorators";
|
import { property, state } from "lit/decorators";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { createCardElement } from "../create-element/create-card-element";
|
import { createCardElement } from "../create-element/create-card-element";
|
||||||
@@ -28,7 +29,7 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||||||
|
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property() public editMode?: boolean;
|
@property() public editMode?: any;
|
||||||
|
|
||||||
@property() protected _cards?: LovelaceCard[];
|
@property() protected _cards?: LovelaceCard[];
|
||||||
|
|
||||||
@@ -43,8 +44,16 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||||||
throw new Error("Invalid configuration");
|
throw new Error("Invalid configuration");
|
||||||
}
|
}
|
||||||
this._config = config;
|
this._config = config;
|
||||||
this._cards = config.cards.map((card) => {
|
this._cards = config.cards.map((card, idx) => {
|
||||||
const element = this._createCardElement(card) as LovelaceCard;
|
const element = this._createCardElement(card) as LovelaceCard;
|
||||||
|
if (this.editMode !== undefined) {
|
||||||
|
if (this.editMode?.selected === idx) {
|
||||||
|
element.classList.add("selected");
|
||||||
|
element.editMode = this.editMode.data;
|
||||||
|
} else {
|
||||||
|
element.editMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return element;
|
return element;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -58,12 +67,18 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const element of this._cards) {
|
for (const [idx, element] of this._cards.entries()) {
|
||||||
if (this.hass) {
|
if (this.hass) {
|
||||||
element.hass = this.hass;
|
element.hass = this.hass;
|
||||||
}
|
}
|
||||||
if (this.editMode !== undefined) {
|
if (this.editMode !== undefined) {
|
||||||
element.editMode = this.editMode;
|
if (this.editMode.selected === idx) {
|
||||||
|
element.editMode = this.editMode.data ?? true;
|
||||||
|
element.classList.add("selected");
|
||||||
|
} else {
|
||||||
|
element.editMode = true;
|
||||||
|
element.classList.remove("selected");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +92,12 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||||||
${this._config.title
|
${this._config.title
|
||||||
? html`<h1 class="card-header">${this._config.title}</h1>`
|
? html`<h1 class="card-header">${this._config.title}</h1>`
|
||||||
: ""}
|
: ""}
|
||||||
<div id="root">${this._cards}</div>
|
<div
|
||||||
|
id="root"
|
||||||
|
class=${classMap({ highlight: this.editMode?.selected !== undefined })}
|
||||||
|
>
|
||||||
|
${this._cards}
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +115,12 @@ export abstract class HuiStackCard<T extends StackCardConfig = StackCardConfig>
|
|||||||
display: block;
|
display: block;
|
||||||
padding: 24px 16px 16px;
|
padding: 24px 16px 16px;
|
||||||
}
|
}
|
||||||
|
#root.highlight > *.selected {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
#root.highlight > * {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ export class HuiCardPreview extends ReactiveElement {
|
|||||||
|
|
||||||
@property() public config?: LovelaceCardConfig;
|
@property() public config?: LovelaceCardConfig;
|
||||||
|
|
||||||
|
@property() public editMode = true;
|
||||||
|
|
||||||
private _element?: LovelaceCard;
|
private _element?: LovelaceCard;
|
||||||
|
|
||||||
private get _error() {
|
private get _error() {
|
||||||
@@ -81,6 +83,9 @@ export class HuiCardPreview extends ReactiveElement {
|
|||||||
this._element.hass = this.hass;
|
this._element.hass = this.hass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (changedProperties.has("editMode")) {
|
||||||
|
this._element!.editMode = this.editMode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createCard(configValue: LovelaceCardConfig): void {
|
private _createCard(configValue: LovelaceCardConfig): void {
|
||||||
@@ -90,6 +95,7 @@ export class HuiCardPreview extends ReactiveElement {
|
|||||||
if (this.hass) {
|
if (this.hass) {
|
||||||
this._element!.hass = this.hass;
|
this._element!.hass = this.hass;
|
||||||
}
|
}
|
||||||
|
this._element!.editMode = this.editMode;
|
||||||
|
|
||||||
this.appendChild(this._element!);
|
this.appendChild(this._element!);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ declare global {
|
|||||||
interface HTMLElementEventMap {
|
interface HTMLElementEventMap {
|
||||||
"reload-lovelace": HASSDomEvent<undefined>;
|
"reload-lovelace": HASSDomEvent<undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"edit-mode-changed": any;
|
||||||
|
}
|
||||||
|
interface HTMLElementEventMap {
|
||||||
|
"edit-mode-changed": HASSDomEvent<any>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@customElement("hui-dialog-edit-card")
|
@customElement("hui-dialog-edit-card")
|
||||||
@@ -77,10 +84,13 @@ export class HuiDialogEditCard
|
|||||||
|
|
||||||
@state() private _isEscapeEnabled = true;
|
@state() private _isEscapeEnabled = true;
|
||||||
|
|
||||||
|
@state() private _editMode = true;
|
||||||
|
|
||||||
public async showDialog(params: EditCardDialogParams): Promise<void> {
|
public async showDialog(params: EditCardDialogParams): Promise<void> {
|
||||||
this._params = params;
|
this._params = params;
|
||||||
this._GUImode = true;
|
this._GUImode = true;
|
||||||
this._guiModeAvailable = true;
|
this._guiModeAvailable = true;
|
||||||
|
this._editMode = true;
|
||||||
const [view, card] = params.path;
|
const [view, card] = params.path;
|
||||||
this._viewConfig = params.lovelaceConfig.views[view];
|
this._viewConfig = params.lovelaceConfig.views[view];
|
||||||
this._cardConfig =
|
this._cardConfig =
|
||||||
@@ -205,6 +215,7 @@ export class HuiDialogEditCard
|
|||||||
.lovelace=${this._params.lovelaceConfig}
|
.lovelace=${this._params.lovelaceConfig}
|
||||||
.value=${this._cardConfig}
|
.value=${this._cardConfig}
|
||||||
@config-changed=${this._handleConfigChanged}
|
@config-changed=${this._handleConfigChanged}
|
||||||
|
@edit-mode-changed=${this._handleEditModeChanged}
|
||||||
@GUImode-changed=${this._handleGUIModeChanged}
|
@GUImode-changed=${this._handleGUIModeChanged}
|
||||||
@editor-save=${this._save}
|
@editor-save=${this._save}
|
||||||
dialogInitialFocus
|
dialogInitialFocus
|
||||||
@@ -214,6 +225,7 @@ export class HuiDialogEditCard
|
|||||||
<hui-card-preview
|
<hui-card-preview
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.config=${this._cardConfig}
|
.config=${this._cardConfig}
|
||||||
|
.editMode=${this._editMode}
|
||||||
class=${this._error ? "blur" : ""}
|
class=${this._error ? "blur" : ""}
|
||||||
></hui-card-preview>
|
></hui-card-preview>
|
||||||
${this._error
|
${this._error
|
||||||
@@ -284,6 +296,10 @@ export class HuiDialogEditCard
|
|||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleEditModeChanged(ev: HASSDomEvent<any>) {
|
||||||
|
this._editMode = ev.detail ?? true;
|
||||||
|
}
|
||||||
|
|
||||||
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
|
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this._GUImode = ev.detail.guiMode;
|
this._GUImode = ev.detail.guiMode;
|
||||||
|
|||||||
@@ -408,10 +408,15 @@ export class HuiEntitiesCardEditor
|
|||||||
|
|
||||||
private _editDetailElement(ev: HASSDomEvent<EditSubElementEvent>): void {
|
private _editDetailElement(ev: HASSDomEvent<EditSubElementEvent>): void {
|
||||||
this._subElementEditorConfig = ev.detail.subElementConfig;
|
this._subElementEditorConfig = ev.detail.subElementConfig;
|
||||||
|
|
||||||
|
fireEvent(this, "edit-mode-changed", {
|
||||||
|
selectedRow: ev.detail.subElementConfig?.index,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _goBack(): void {
|
private _goBack(): void {
|
||||||
this._subElementEditorConfig = undefined;
|
this._subElementEditorConfig = undefined;
|
||||||
|
fireEvent(this, "edit-mode-changed", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ export class HuiStackCardEditor
|
|||||||
.lovelace=${this.lovelace}
|
.lovelace=${this.lovelace}
|
||||||
@config-changed=${this._handleConfigChanged}
|
@config-changed=${this._handleConfigChanged}
|
||||||
@GUImode-changed=${this._handleGUIModeChanged}
|
@GUImode-changed=${this._handleGUIModeChanged}
|
||||||
|
@edit-mode-changed=${this._handleEditModeChanged}
|
||||||
></hui-card-element-editor>
|
></hui-card-element-editor>
|
||||||
`
|
`
|
||||||
: html`
|
: html`
|
||||||
@@ -166,6 +167,9 @@ export class HuiStackCardEditor
|
|||||||
this._setMode(true);
|
this._setMode(true);
|
||||||
this._guiModeAvailable = true;
|
this._guiModeAvailable = true;
|
||||||
this._selectedCard = parseInt(ev.detail.selected, 10);
|
this._selectedCard = parseInt(ev.detail.selected, 10);
|
||||||
|
if (this._cardEditorEl) {
|
||||||
|
this._cardEditorEl.forceRebuild = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
|
protected _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
|
||||||
@@ -226,6 +230,14 @@ export class HuiStackCardEditor
|
|||||||
this._guiModeAvailable = ev.detail.guiModeAvailable;
|
this._guiModeAvailable = ev.detail.guiModeAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected _handleEditModeChanged(ev: HASSDomEvent<any>) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "edit-mode-changed", {
|
||||||
|
selected: this._selectedCard,
|
||||||
|
data: ev.detail,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected _toggleMode(): void {
|
protected _toggleMode(): void {
|
||||||
this._cardEditorEl?.toggleMode();
|
this._cardEditorEl?.toggleMode();
|
||||||
}
|
}
|
||||||
@@ -237,6 +249,13 @@ export class HuiStackCardEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected updated(changedProperties) {
|
||||||
|
if (changedProperties.has("_selectedCard"))
|
||||||
|
fireEvent(this, "edit-mode-changed", {
|
||||||
|
selected: this._selectedCard,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
configElementStyle,
|
configElementStyle,
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ export abstract class HuiElementEditor<T> extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public lovelace?: LovelaceConfig;
|
@property({ attribute: false }) public lovelace?: LovelaceConfig;
|
||||||
|
|
||||||
|
public forceRebuild = false;
|
||||||
|
|
||||||
@state() private _yaml?: string;
|
@state() private _yaml?: string;
|
||||||
|
|
||||||
@state() private _config?: T;
|
@state() private _config?: T;
|
||||||
@@ -292,7 +294,11 @@ export abstract class HuiElementEditor<T> extends LitElement {
|
|||||||
this._errors = undefined;
|
this._errors = undefined;
|
||||||
this._warnings = undefined;
|
this._warnings = undefined;
|
||||||
|
|
||||||
if (this._configElementType !== this.configElementType) {
|
if (
|
||||||
|
this._configElementType !== this.configElementType ||
|
||||||
|
this.forceRebuild
|
||||||
|
) {
|
||||||
|
this.forceRebuild = false;
|
||||||
// If the type has changed, we need to load a new GUI editor
|
// If the type has changed, we need to load a new GUI editor
|
||||||
this._guiSupported = undefined;
|
this._guiSupported = undefined;
|
||||||
this._configElement = undefined;
|
this._configElement = undefined;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export interface LovelaceBadge extends HTMLElement {
|
|||||||
export interface LovelaceCard extends HTMLElement {
|
export interface LovelaceCard extends HTMLElement {
|
||||||
hass?: HomeAssistant;
|
hass?: HomeAssistant;
|
||||||
isPanel?: boolean;
|
isPanel?: boolean;
|
||||||
editMode?: boolean;
|
editMode?: any;
|
||||||
getCardSize(): number | Promise<number>;
|
getCardSize(): number | Promise<number>;
|
||||||
setConfig(config: LovelaceCardConfig): void;
|
setConfig(config: LovelaceCardConfig): void;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user