mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-17 14:26:35 +00:00
Add support for sections in filters (#21157)
This commit is contained in:
parent
9cbb51549b
commit
76daa2bb7f
@ -65,6 +65,8 @@ interface ExtHassService extends Omit<HassService, "fields"> {
|
|||||||
Omit<HassService["fields"][string], "selector"> & {
|
Omit<HassService["fields"][string], "selector"> & {
|
||||||
key: string;
|
key: string;
|
||||||
selector?: Selector;
|
selector?: Selector;
|
||||||
|
fields?: Record<string, Omit<HassService["fields"][string], "selector">>;
|
||||||
|
collapsed?: boolean;
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
hasSelector: string[];
|
hasSelector: string[];
|
||||||
@ -247,20 +249,7 @@ export class HaServiceControl extends LitElement {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
private _filterFields = memoizeOne(
|
private _getTargetedEntities = memoizeOne((target, value) => {
|
||||||
(serviceData: ExtHassService | undefined, value: this["value"]) =>
|
|
||||||
serviceData?.fields?.filter(
|
|
||||||
(field) =>
|
|
||||||
!field.filter ||
|
|
||||||
this._filterField(serviceData.target, field.filter, value)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
private _filterField(
|
|
||||||
target: ExtHassService["target"],
|
|
||||||
filter: ExtHassService["fields"][number]["filter"],
|
|
||||||
value: this["value"]
|
|
||||||
) {
|
|
||||||
const targetSelector = target ? { target } : { target: {} };
|
const targetSelector = target ? { target } : { target: {} };
|
||||||
const targetEntities =
|
const targetEntities =
|
||||||
ensureArray(
|
ensureArray(
|
||||||
@ -330,6 +319,13 @@ export class HaServiceControl extends LitElement {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return targetEntities;
|
||||||
|
});
|
||||||
|
|
||||||
|
private _filterField(
|
||||||
|
filter: ExtHassService["fields"][number]["filter"],
|
||||||
|
targetEntities: string[]
|
||||||
|
) {
|
||||||
if (!targetEntities.length) {
|
if (!targetEntities.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -391,7 +387,10 @@ export class HaServiceControl extends LitElement {
|
|||||||
serviceData?.fields.some((field) => showOptionalToggle(field))
|
serviceData?.fields.some((field) => showOptionalToggle(field))
|
||||||
);
|
);
|
||||||
|
|
||||||
const filteredFields = this._filterFields(serviceData, this._value);
|
const targetEntities = this._getTargetedEntities(
|
||||||
|
serviceData?.target,
|
||||||
|
this._value
|
||||||
|
);
|
||||||
|
|
||||||
const domain = this._value?.service
|
const domain = this._value?.service
|
||||||
? computeDomain(this._value.service)
|
? computeDomain(this._value.service)
|
||||||
@ -485,75 +484,115 @@ export class HaServiceControl extends LitElement {
|
|||||||
.defaultValue=${this._value?.data}
|
.defaultValue=${this._value?.data}
|
||||||
@value-changed=${this._dataChanged}
|
@value-changed=${this._dataChanged}
|
||||||
></ha-yaml-editor>`
|
></ha-yaml-editor>`
|
||||||
: filteredFields?.map((dataField) => {
|
: serviceData?.fields.map((dataField) =>
|
||||||
const selector = dataField?.selector ?? { text: undefined };
|
dataField.fields
|
||||||
const type = Object.keys(selector)[0];
|
? html`<ha-expansion-panel
|
||||||
const enhancedSelector = ["action", "condition", "trigger"].includes(
|
leftChevron
|
||||||
type
|
.expanded=${!dataField.collapsed}
|
||||||
)
|
.header=${this.hass.localize(
|
||||||
? {
|
`component.${domain}.services.${serviceName}.sections.${dataField.key}.name`
|
||||||
[type]: {
|
) ||
|
||||||
...selector[type],
|
dataField.name ||
|
||||||
path: [dataField.key],
|
dataField.key}
|
||||||
},
|
>
|
||||||
}
|
${Object.entries(dataField.fields).map(([key, field]) =>
|
||||||
: selector;
|
this._renderField(
|
||||||
|
{ key, ...field },
|
||||||
const showOptional = showOptionalToggle(dataField);
|
hasOptional,
|
||||||
|
domain,
|
||||||
return dataField.selector &&
|
serviceName,
|
||||||
(!dataField.advanced ||
|
targetEntities
|
||||||
this.showAdvanced ||
|
)
|
||||||
(this._value?.data &&
|
)}
|
||||||
this._value.data[dataField.key] !== undefined))
|
</ha-expansion-panel>`
|
||||||
? html`<ha-settings-row .narrow=${this.narrow}>
|
: this._renderField(
|
||||||
${!showOptional
|
dataField,
|
||||||
? hasOptional
|
hasOptional,
|
||||||
? html`<div slot="prefix" class="checkbox-spacer"></div>`
|
domain,
|
||||||
: ""
|
serviceName,
|
||||||
: html`<ha-checkbox
|
targetEntities
|
||||||
.key=${dataField.key}
|
)
|
||||||
.checked=${this._checkedKeys.has(dataField.key) ||
|
)} `;
|
||||||
(this._value?.data &&
|
|
||||||
this._value.data[dataField.key] !== undefined)}
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
@change=${this._checkboxChanged}
|
|
||||||
slot="prefix"
|
|
||||||
></ha-checkbox>`}
|
|
||||||
<span slot="heading"
|
|
||||||
>${this.hass.localize(
|
|
||||||
`component.${domain}.services.${serviceName}.fields.${dataField.key}.name`
|
|
||||||
) ||
|
|
||||||
dataField.name ||
|
|
||||||
dataField.key}</span
|
|
||||||
>
|
|
||||||
<span slot="description"
|
|
||||||
>${this.hass.localize(
|
|
||||||
`component.${domain}.services.${serviceName}.fields.${dataField.key}.description`
|
|
||||||
) || dataField?.description}</span
|
|
||||||
>
|
|
||||||
<ha-selector
|
|
||||||
.disabled=${this.disabled ||
|
|
||||||
(showOptional &&
|
|
||||||
!this._checkedKeys.has(dataField.key) &&
|
|
||||||
(!this._value?.data ||
|
|
||||||
this._value.data[dataField.key] === undefined))}
|
|
||||||
.hass=${this.hass}
|
|
||||||
.selector=${enhancedSelector}
|
|
||||||
.key=${dataField.key}
|
|
||||||
@value-changed=${this._serviceDataChanged}
|
|
||||||
.value=${this._value?.data
|
|
||||||
? this._value.data[dataField.key]
|
|
||||||
: undefined}
|
|
||||||
.placeholder=${dataField.default}
|
|
||||||
.localizeValue=${this._localizeValueCallback}
|
|
||||||
@item-moved=${this._itemMoved}
|
|
||||||
></ha-selector>
|
|
||||||
</ha-settings-row>`
|
|
||||||
: "";
|
|
||||||
})} `;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _renderField = (
|
||||||
|
dataField: ExtHassService["fields"][number],
|
||||||
|
hasOptional: boolean,
|
||||||
|
domain: string | undefined,
|
||||||
|
serviceName: string | undefined,
|
||||||
|
targetEntities: string[]
|
||||||
|
) => {
|
||||||
|
if (
|
||||||
|
dataField.filter &&
|
||||||
|
!this._filterField(dataField.filter, targetEntities)
|
||||||
|
) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selector = dataField?.selector ?? { text: undefined };
|
||||||
|
const type = Object.keys(selector)[0];
|
||||||
|
const enhancedSelector = ["action", "condition", "trigger"].includes(type)
|
||||||
|
? {
|
||||||
|
[type]: {
|
||||||
|
...selector[type],
|
||||||
|
path: [dataField.key],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: selector;
|
||||||
|
|
||||||
|
const showOptional = showOptionalToggle(dataField);
|
||||||
|
|
||||||
|
return dataField.selector &&
|
||||||
|
(!dataField.advanced ||
|
||||||
|
this.showAdvanced ||
|
||||||
|
(this._value?.data && this._value.data[dataField.key] !== undefined))
|
||||||
|
? html`<ha-settings-row .narrow=${this.narrow}>
|
||||||
|
${!showOptional
|
||||||
|
? hasOptional
|
||||||
|
? html`<div slot="prefix" class="checkbox-spacer"></div>`
|
||||||
|
: ""
|
||||||
|
: html`<ha-checkbox
|
||||||
|
.key=${dataField.key}
|
||||||
|
.checked=${this._checkedKeys.has(dataField.key) ||
|
||||||
|
(this._value?.data &&
|
||||||
|
this._value.data[dataField.key] !== undefined)}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
@change=${this._checkboxChanged}
|
||||||
|
slot="prefix"
|
||||||
|
></ha-checkbox>`}
|
||||||
|
<span slot="heading"
|
||||||
|
>${this.hass.localize(
|
||||||
|
`component.${domain}.services.${serviceName}.fields.${dataField.key}.name`
|
||||||
|
) ||
|
||||||
|
dataField.name ||
|
||||||
|
dataField.key}</span
|
||||||
|
>
|
||||||
|
<span slot="description"
|
||||||
|
>${this.hass.localize(
|
||||||
|
`component.${domain}.services.${serviceName}.fields.${dataField.key}.description`
|
||||||
|
) || dataField?.description}</span
|
||||||
|
>
|
||||||
|
<ha-selector
|
||||||
|
.disabled=${this.disabled ||
|
||||||
|
(showOptional &&
|
||||||
|
!this._checkedKeys.has(dataField.key) &&
|
||||||
|
(!this._value?.data ||
|
||||||
|
this._value.data[dataField.key] === undefined))}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.selector=${enhancedSelector}
|
||||||
|
.key=${dataField.key}
|
||||||
|
@value-changed=${this._serviceDataChanged}
|
||||||
|
.value=${this._value?.data
|
||||||
|
? this._value.data[dataField.key]
|
||||||
|
: undefined}
|
||||||
|
.placeholder=${dataField.default}
|
||||||
|
.localizeValue=${this._localizeValueCallback}
|
||||||
|
@item-moved=${this._itemMoved}
|
||||||
|
></ha-selector>
|
||||||
|
</ha-settings-row>`
|
||||||
|
: "";
|
||||||
|
};
|
||||||
|
|
||||||
private _localizeValueCallback = (key: string) => {
|
private _localizeValueCallback = (key: string) => {
|
||||||
if (!this._value?.service) {
|
if (!this._value?.service) {
|
||||||
return "";
|
return "";
|
||||||
@ -839,6 +878,11 @@ export class HaServiceControl extends LitElement {
|
|||||||
.description p {
|
.description p {
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
}
|
}
|
||||||
|
ha-expansion-panel {
|
||||||
|
--ha-card-border-radius: 0;
|
||||||
|
--expansion-panel-summary-padding: 0 16px;
|
||||||
|
--expansion-panel-content-padding: 0;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user