mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-18 14:56:37 +00:00
Collapsible blueprint input sections (#19946)
* Deduplicate blueprint editor code * Collapsible blueprint sections * add description * renamed collapsed * unused import * unused import * Don't allow collapsing sections with required * Update to new schema
This commit is contained in:
parent
f1345af526
commit
a629f01300
@ -21,6 +21,8 @@ export class HaExpansionPanel extends LitElement {
|
||||
|
||||
@property({ type: Boolean, reflect: true }) leftChevron = false;
|
||||
|
||||
@property({ type: Boolean, reflect: true }) noCollapse = false;
|
||||
|
||||
@property() header?: string;
|
||||
|
||||
@property() secondary?: string;
|
||||
@ -34,16 +36,17 @@ export class HaExpansionPanel extends LitElement {
|
||||
<div class="top ${classMap({ expanded: this.expanded })}">
|
||||
<div
|
||||
id="summary"
|
||||
class=${classMap({ noCollapse: this.noCollapse })}
|
||||
@click=${this._toggleContainer}
|
||||
@keydown=${this._toggleContainer}
|
||||
@focus=${this._focusChanged}
|
||||
@blur=${this._focusChanged}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
tabindex=${this.noCollapse ? -1 : 0}
|
||||
aria-expanded=${this.expanded}
|
||||
aria-controls="sect1"
|
||||
>
|
||||
${this.leftChevron
|
||||
${this.leftChevron && !this.noCollapse
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
.path=${mdiChevronDown}
|
||||
@ -57,7 +60,7 @@ export class HaExpansionPanel extends LitElement {
|
||||
<slot class="secondary" name="secondary">${this.secondary}</slot>
|
||||
</div>
|
||||
</slot>
|
||||
${!this.leftChevron
|
||||
${!this.leftChevron && !this.noCollapse
|
||||
? html`
|
||||
<ha-svg-icon
|
||||
.path=${mdiChevronDown}
|
||||
@ -106,6 +109,9 @@ export class HaExpansionPanel extends LitElement {
|
||||
return;
|
||||
}
|
||||
ev.preventDefault();
|
||||
if (this.noCollapse) {
|
||||
return;
|
||||
}
|
||||
const newExpanded = !this.expanded;
|
||||
fireEvent(this, "expanded-will-change", { expanded: newExpanded });
|
||||
this._container.style.overflow = "hidden";
|
||||
@ -130,6 +136,9 @@ export class HaExpansionPanel extends LitElement {
|
||||
}
|
||||
|
||||
private _focusChanged(ev) {
|
||||
if (this.noCollapse) {
|
||||
return;
|
||||
}
|
||||
this.shadowRoot!.querySelector(".top")!.classList.toggle(
|
||||
"focused",
|
||||
ev.type === "focus"
|
||||
@ -191,6 +200,9 @@ export class HaExpansionPanel extends LitElement {
|
||||
font-weight: 500;
|
||||
outline: none;
|
||||
}
|
||||
#summary.noCollapse {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.summary-icon.expanded {
|
||||
transform: rotate(180deg);
|
||||
|
@ -13,7 +13,7 @@ export interface Blueprint {
|
||||
export interface BlueprintMetaData {
|
||||
domain: BlueprintDomain;
|
||||
name: string;
|
||||
input?: Record<string, BlueprintInput | null>;
|
||||
input?: Record<string, BlueprintInput | BlueprintInputSection | null>;
|
||||
description?: string;
|
||||
source_url?: string;
|
||||
author?: string;
|
||||
@ -26,6 +26,14 @@ export interface BlueprintInput {
|
||||
default?: any;
|
||||
}
|
||||
|
||||
export interface BlueprintInputSection {
|
||||
name?: string;
|
||||
icon?: string;
|
||||
description?: string;
|
||||
collapsed?: boolean;
|
||||
input: Record<string, BlueprintInput | null>;
|
||||
}
|
||||
|
||||
export interface BlueprintImportResult {
|
||||
suggested_filename: string;
|
||||
raw_data: string;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import { css, CSSResultGroup, html, LitElement } from "lit";
|
||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { nestedArrayMove } from "../../../common/util/array-move";
|
||||
@ -11,7 +11,12 @@ import "../../../components/ha-markdown";
|
||||
import "../../../components/ha-selector/ha-selector";
|
||||
import "../../../components/ha-settings-row";
|
||||
import { BlueprintAutomationConfig } from "../../../data/automation";
|
||||
import { BlueprintOrError, Blueprints } from "../../../data/blueprint";
|
||||
import {
|
||||
BlueprintInput,
|
||||
BlueprintInputSection,
|
||||
BlueprintOrError,
|
||||
Blueprints,
|
||||
} from "../../../data/blueprint";
|
||||
import { BlueprintScriptConfig } from "../../../data/script";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
@ -46,6 +51,7 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
|
||||
protected renderCard() {
|
||||
const blueprint = this._blueprint;
|
||||
let border = true;
|
||||
return html`
|
||||
<ha-card
|
||||
outlined
|
||||
@ -91,13 +97,70 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
Object.keys(blueprint.metadata.input).length
|
||||
? Object.entries(blueprint.metadata.input).map(
|
||||
([key, value]) => {
|
||||
if (value && "input" in value) {
|
||||
const section = this.renderSection(key, value);
|
||||
border = false;
|
||||
return section;
|
||||
}
|
||||
const row = this.renderSettingRow(key, value, border);
|
||||
border = true;
|
||||
return row;
|
||||
}
|
||||
)
|
||||
: html`<p class="padding">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.blueprint.no_inputs"
|
||||
)}
|
||||
</p>`}`
|
||||
: ""}
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderSection(sectionKey: string, section: BlueprintInputSection) {
|
||||
const title = section?.name || sectionKey;
|
||||
const anyRequired =
|
||||
section.input &&
|
||||
Object.values(section.input).some(
|
||||
(item) => item === null || item.default === undefined
|
||||
);
|
||||
const expanded = !section.collapsed || anyRequired;
|
||||
|
||||
return html` <ha-expansion-panel
|
||||
outlined
|
||||
.expanded=${expanded}
|
||||
.noCollapse=${anyRequired}
|
||||
>
|
||||
<div slot="header" role="heading" aria-level="3" class="section-header">
|
||||
${section?.icon
|
||||
? html` <ha-icon
|
||||
class="section-header"
|
||||
.icon=${section.icon}
|
||||
></ha-icon>`
|
||||
: nothing}
|
||||
<ha-markdown .content=${title}></ha-markdown>
|
||||
</div>
|
||||
<div class="content">
|
||||
${section?.description
|
||||
? html`<ha-markdown .content=${section.description}></ha-markdown>`
|
||||
: nothing}
|
||||
${section.input
|
||||
? Object.entries(section.input).map(([key, value]) =>
|
||||
this.renderSettingRow(key, value, true)
|
||||
)
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-expansion-panel>`;
|
||||
}
|
||||
|
||||
private renderSettingRow(
|
||||
key: string,
|
||||
value: BlueprintInput | null,
|
||||
border: boolean
|
||||
) {
|
||||
const selector = value?.selector ?? { text: undefined };
|
||||
const type = Object.keys(selector)[0];
|
||||
const enhancedSelector = [
|
||||
"action",
|
||||
"condition",
|
||||
"trigger",
|
||||
].includes(type)
|
||||
const enhancedSelector = ["action", "condition", "trigger"].includes(type)
|
||||
? {
|
||||
[type]: {
|
||||
...selector[type],
|
||||
@ -105,8 +168,10 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
},
|
||||
}
|
||||
: selector;
|
||||
|
||||
return html`<ha-settings-row .narrow=${this.narrow}>
|
||||
return html`<ha-settings-row
|
||||
.narrow=${this.narrow}
|
||||
class=${border ? "border" : ""}
|
||||
>
|
||||
<span slot="heading">${value?.name || key}</span>
|
||||
<ha-markdown
|
||||
slot="description"
|
||||
@ -130,16 +195,6 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
></ha-selector>`}
|
||||
</ha-settings-row>`;
|
||||
}
|
||||
)
|
||||
: html`<p class="padding">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.blueprint.no_inputs"
|
||||
)}
|
||||
</p>`}`
|
||||
: ""}
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
protected abstract _getBlueprints();
|
||||
|
||||
@ -219,6 +274,7 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
}
|
||||
ha-card.blueprint {
|
||||
margin: 0 auto;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
.padding {
|
||||
padding: 16px;
|
||||
@ -253,8 +309,15 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
--paper-time-input-justify-content: flex-end;
|
||||
--settings-row-content-width: 100%;
|
||||
--settings-row-prefix-display: contents;
|
||||
}
|
||||
ha-settings-row.border {
|
||||
border-top: 1px solid var(--divider-color);
|
||||
}
|
||||
ha-expansion-panel {
|
||||
margin: 8px;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
ha-alert {
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
@ -263,6 +326,13 @@ export abstract class HaBlueprintGenericEditor extends LitElement {
|
||||
border-radius: var(--ha-card-border-radius, 12px);
|
||||
overflow: hidden;
|
||||
}
|
||||
div.section-header {
|
||||
display: flex;
|
||||
vertical-align: middle;
|
||||
}
|
||||
ha-icon.section-header {
|
||||
padding-right: 10px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user