mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Add title and description translation support to expandable form (#21745)
* Add title and description translation support to expandable form * Fix type * handle translations in sections * Rename prefix to path + refactor * Fix section name and description --------- Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
c556742ff4
commit
19f057a51b
@ -21,13 +21,45 @@ export class HaFormExpendable extends LitElement implements HaFormElement {
|
||||
|
||||
@property({ attribute: false }) public computeLabel?: (
|
||||
schema: HaFormSchema,
|
||||
data?: HaFormDataContainer
|
||||
data?: HaFormDataContainer,
|
||||
options?: { path?: string[] }
|
||||
) => string;
|
||||
|
||||
@property({ attribute: false }) public computeHelper?: (
|
||||
schema: HaFormSchema
|
||||
schema: HaFormSchema,
|
||||
options?: { path?: string[] }
|
||||
) => string;
|
||||
|
||||
private _renderDescription() {
|
||||
const description = this.computeHelper?.(this.schema);
|
||||
return description ? html`<p>${description}</p>` : nothing;
|
||||
}
|
||||
|
||||
private _computeLabel = (
|
||||
schema: HaFormSchema,
|
||||
data?: HaFormDataContainer,
|
||||
options?: { path?: string[] }
|
||||
) => {
|
||||
if (!this.computeLabel) return this.computeLabel;
|
||||
|
||||
return this.computeLabel(schema, data, {
|
||||
...options,
|
||||
path: [...(options?.path || []), this.schema.name],
|
||||
});
|
||||
};
|
||||
|
||||
private _computeHelper = (
|
||||
schema: HaFormSchema,
|
||||
options?: { path?: string[] }
|
||||
) => {
|
||||
if (!this.computeHelper) return this.computeHelper;
|
||||
|
||||
return this.computeHelper(schema, {
|
||||
...options,
|
||||
path: [...(options?.path || []), this.schema.name],
|
||||
});
|
||||
};
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-expansion-panel outlined .expanded=${Boolean(this.schema.expanded)}>
|
||||
@ -43,16 +75,17 @@ export class HaFormExpendable extends LitElement implements HaFormElement {
|
||||
<ha-svg-icon .path=${this.schema.iconPath}></ha-svg-icon>
|
||||
`
|
||||
: nothing}
|
||||
${this.schema.title}
|
||||
${this.schema.title || this.computeLabel?.(this.schema)}
|
||||
</div>
|
||||
<div class="content">
|
||||
${this._renderDescription()}
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this.data}
|
||||
.schema=${this.schema.schema}
|
||||
.disabled=${this.disabled}
|
||||
.computeLabel=${this.computeLabel}
|
||||
.computeHelper=${this.computeHelper}
|
||||
.computeLabel=${this._computeLabel}
|
||||
.computeHelper=${this._computeHelper}
|
||||
></ha-form>
|
||||
</div>
|
||||
</ha-expansion-panel>
|
||||
@ -71,6 +104,9 @@ export class HaFormExpendable extends LitElement implements HaFormElement {
|
||||
.content {
|
||||
padding: 12px;
|
||||
}
|
||||
.content p {
|
||||
margin: 0 0 24px;
|
||||
}
|
||||
ha-expansion-panel {
|
||||
display: block;
|
||||
--expansion-panel-content-padding: 0;
|
||||
|
@ -31,7 +31,7 @@ const LOAD_ELEMENTS = {
|
||||
};
|
||||
|
||||
const getValue = (obj, item) =>
|
||||
obj ? (!item.name ? obj : obj[item.name]) : null;
|
||||
obj ? (!item.name || item.flatten ? obj : obj[item.name]) : null;
|
||||
|
||||
const getError = (obj, item) => (obj && item.name ? obj[item.name] : null);
|
||||
|
||||
@ -73,10 +73,6 @@ export class HaForm extends LitElement implements HaFormElement {
|
||||
schema: any
|
||||
) => string | undefined;
|
||||
|
||||
@property({ attribute: false }) public localizeValue?: (
|
||||
key: string
|
||||
) => string;
|
||||
|
||||
protected getFormProperties(): Record<string, any> {
|
||||
return {};
|
||||
}
|
||||
@ -149,7 +145,6 @@ export class HaForm extends LitElement implements HaFormElement {
|
||||
.disabled=${item.disabled || this.disabled || false}
|
||||
.placeholder=${item.required ? "" : item.default}
|
||||
.helper=${this._computeHelper(item)}
|
||||
.localizeValue=${this.localizeValue}
|
||||
.required=${item.required || false}
|
||||
.context=${this._generateContext(item)}
|
||||
></ha-selector>`
|
||||
@ -204,9 +199,10 @@ export class HaForm extends LitElement implements HaFormElement {
|
||||
|
||||
if (ev.target === this) return;
|
||||
|
||||
const newValue = !schema.name
|
||||
? ev.detail.value
|
||||
: { [schema.name]: ev.detail.value };
|
||||
const newValue =
|
||||
!schema.name || ("flatten" in schema && schema.flatten)
|
||||
? ev.detail.value
|
||||
: { [schema.name]: ev.detail.value };
|
||||
|
||||
this.data = {
|
||||
...this.data,
|
||||
|
@ -31,15 +31,15 @@ export interface HaFormBaseSchema {
|
||||
|
||||
export interface HaFormGridSchema extends HaFormBaseSchema {
|
||||
type: "grid";
|
||||
name: string;
|
||||
flatten?: boolean;
|
||||
column_min_width?: string;
|
||||
schema: readonly HaFormSchema[];
|
||||
}
|
||||
|
||||
export interface HaFormExpandableSchema extends HaFormBaseSchema {
|
||||
type: "expandable";
|
||||
name: "";
|
||||
title: string;
|
||||
flatten?: boolean;
|
||||
title?: string;
|
||||
icon?: string;
|
||||
iconPath?: string;
|
||||
expanded?: boolean;
|
||||
@ -100,7 +100,7 @@ export type SchemaUnion<
|
||||
SchemaArray extends readonly HaFormSchema[],
|
||||
Schema = SchemaArray[number],
|
||||
> = Schema extends HaFormGridSchema | HaFormExpandableSchema
|
||||
? SchemaUnion<Schema["schema"]>
|
||||
? SchemaUnion<Schema["schema"]> | Schema
|
||||
: Schema;
|
||||
|
||||
export interface HaFormDataContainer {
|
||||
|
@ -162,8 +162,14 @@ export class HaLocationSelector extends LitElement {
|
||||
|
||||
private _computeLabel = (
|
||||
entry: SchemaUnion<ReturnType<typeof this._schema>>
|
||||
): string =>
|
||||
this.hass.localize(`ui.components.selectors.location.${entry.name}`);
|
||||
): string => {
|
||||
if (entry.name) {
|
||||
return this.hass.localize(
|
||||
`ui.components.selectors.location.${entry.name}`
|
||||
);
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
static styles = css`
|
||||
ha-locations-editor {
|
||||
|
@ -76,19 +76,36 @@ export const showConfigFlowDialog = (
|
||||
: "";
|
||||
},
|
||||
|
||||
renderShowFormStepFieldLabel(hass, step, field) {
|
||||
renderShowFormStepFieldLabel(hass, step, field, options) {
|
||||
if (field.type === "expandable") {
|
||||
return hass.localize(
|
||||
`component.${step.handler}.config.step.${step.step_id}.sections.${field.name}.name`
|
||||
);
|
||||
}
|
||||
|
||||
const prefix = options?.path?.[0] ? `sections.${options.path[0]}` : "";
|
||||
|
||||
return (
|
||||
hass.localize(
|
||||
`component.${step.handler}.config.step.${step.step_id}.data.${field.name}`
|
||||
`component.${step.handler}.config.step.${step.step_id}.${prefix}data.${field.name}`
|
||||
) || field.name
|
||||
);
|
||||
},
|
||||
|
||||
renderShowFormStepFieldHelper(hass, step, field) {
|
||||
renderShowFormStepFieldHelper(hass, step, field, options) {
|
||||
if (field.type === "expandable") {
|
||||
return hass.localize(
|
||||
`component.${step.translation_domain || step.handler}.config.step.${step.step_id}.sections.${field.name}.description`
|
||||
);
|
||||
}
|
||||
|
||||
const prefix = options?.path?.[0] ? `sections.${options.path[0]}.` : "";
|
||||
|
||||
const description = hass.localize(
|
||||
`component.${step.translation_domain || step.handler}.config.step.${step.step_id}.data_description.${field.name}`,
|
||||
`component.${step.translation_domain || step.handler}.config.step.${step.step_id}.${prefix}data_description.${field.name}`,
|
||||
step.description_placeholders
|
||||
);
|
||||
|
||||
return description
|
||||
? html`<ha-markdown breaks .content=${description}></ha-markdown>`
|
||||
: "";
|
||||
|
@ -49,13 +49,15 @@ export interface FlowConfig {
|
||||
renderShowFormStepFieldLabel(
|
||||
hass: HomeAssistant,
|
||||
step: DataEntryFlowStepForm,
|
||||
field: HaFormSchema
|
||||
field: HaFormSchema,
|
||||
options: { path?: string[]; [key: string]: any }
|
||||
): string;
|
||||
|
||||
renderShowFormStepFieldHelper(
|
||||
hass: HomeAssistant,
|
||||
step: DataEntryFlowStepForm,
|
||||
field: HaFormSchema
|
||||
field: HaFormSchema,
|
||||
options: { path?: string[]; [key: string]: any }
|
||||
): TemplateResult | string;
|
||||
|
||||
renderShowFormStepFieldError(
|
||||
|
@ -93,17 +93,33 @@ export const showOptionsFlowDialog = (
|
||||
: "";
|
||||
},
|
||||
|
||||
renderShowFormStepFieldLabel(hass, step, field) {
|
||||
renderShowFormStepFieldLabel(hass, step, field, options) {
|
||||
if (field.type === "expandable") {
|
||||
return hass.localize(
|
||||
`component.${configEntry.domain}.options.step.${step.step_id}.sections.${field.name}.name`
|
||||
);
|
||||
}
|
||||
|
||||
const prefix = options?.path?.[0] ? `sections.${options.path[0]}.` : "";
|
||||
|
||||
return (
|
||||
hass.localize(
|
||||
`component.${configEntry.domain}.options.step.${step.step_id}.data.${field.name}`
|
||||
`component.${configEntry.domain}.options.step.${step.step_id}.${prefix}data.${field.name}`
|
||||
) || field.name
|
||||
);
|
||||
},
|
||||
|
||||
renderShowFormStepFieldHelper(hass, step, field) {
|
||||
renderShowFormStepFieldHelper(hass, step, field, options) {
|
||||
if (field.type === "expandable") {
|
||||
return hass.localize(
|
||||
`component.${step.translation_domain || configEntry.domain}.options.step.${step.step_id}.sections.${field.name}.description`
|
||||
);
|
||||
}
|
||||
|
||||
const prefix = options?.path?.[0] ? `sections.${options.path[0]}.` : "";
|
||||
|
||||
const description = hass.localize(
|
||||
`component.${step.translation_domain || configEntry.domain}.options.step.${step.step_id}.data_description.${field.name}`,
|
||||
`component.${step.translation_domain || configEntry.domain}.options.step.${step.step_id}.${prefix}data_description.${field.name}`,
|
||||
step.description_placeholders
|
||||
);
|
||||
return description
|
||||
|
@ -225,11 +225,24 @@ class StepFlowForm extends LitElement {
|
||||
this._stepData = ev.detail.value;
|
||||
}
|
||||
|
||||
private _labelCallback = (field: HaFormSchema): string =>
|
||||
this.flowConfig.renderShowFormStepFieldLabel(this.hass, this.step, field);
|
||||
private _labelCallback = (field: HaFormSchema, _data, options): string =>
|
||||
this.flowConfig.renderShowFormStepFieldLabel(
|
||||
this.hass,
|
||||
this.step,
|
||||
field,
|
||||
options
|
||||
);
|
||||
|
||||
private _helperCallback = (field: HaFormSchema): string | TemplateResult =>
|
||||
this.flowConfig.renderShowFormStepFieldHelper(this.hass, this.step, field);
|
||||
private _helperCallback = (
|
||||
field: HaFormSchema,
|
||||
options
|
||||
): string | TemplateResult =>
|
||||
this.flowConfig.renderShowFormStepFieldHelper(
|
||||
this.hass,
|
||||
this.step,
|
||||
field,
|
||||
options
|
||||
);
|
||||
|
||||
private _errorCallback = (error: string) =>
|
||||
this.flowConfig.renderShowFormStepFieldError(this.hass, this.step, error);
|
||||
|
@ -96,20 +96,20 @@ export const showRepairsFlowDialog = (
|
||||
: "";
|
||||
},
|
||||
|
||||
renderShowFormStepFieldLabel(hass, step, field) {
|
||||
renderShowFormStepFieldLabel(hass, step, field, options) {
|
||||
return hass.localize(
|
||||
`component.${issue.domain}.issues.${
|
||||
issue.translation_key || issue.issue_id
|
||||
}.fix_flow.step.${step.step_id}.data.${field.name}`,
|
||||
}.fix_flow.step.${step.step_id}.${options?.prefix ? `section.${options.prefix[0]}.` : ""}data.${field.name}`,
|
||||
step.description_placeholders
|
||||
);
|
||||
},
|
||||
|
||||
renderShowFormStepFieldHelper(hass, step, field) {
|
||||
renderShowFormStepFieldHelper(hass, step, field, options) {
|
||||
const description = hass.localize(
|
||||
`component.${issue.domain}.issues.${
|
||||
issue.translation_key || issue.issue_id
|
||||
}.fix_flow.step.${step.step_id}.data_description.${field.name}`,
|
||||
}.fix_flow.step.${step.step_id}.${options?.prefix ? `section.${options.prefix[0]}.` : ""}data_description.${field.name}`,
|
||||
step.description_placeholders
|
||||
);
|
||||
return description
|
||||
|
@ -74,10 +74,10 @@ export class HuiEntityBadgeEditor
|
||||
[
|
||||
{ name: "entity", selector: { entity: {} } },
|
||||
{
|
||||
name: "",
|
||||
name: "appearance",
|
||||
type: "expandable",
|
||||
flatten: true,
|
||||
iconPath: mdiPalette,
|
||||
title: localize(`ui.panel.lovelace.editor.badge.entity.appearance`),
|
||||
schema: [
|
||||
{
|
||||
name: "",
|
||||
@ -153,9 +153,9 @@ export class HuiEntityBadgeEditor
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
name: "interactions",
|
||||
type: "expandable",
|
||||
title: localize(`ui.panel.lovelace.editor.badge.entity.interactions`),
|
||||
flatten: true,
|
||||
iconPath: mdiGestureTap,
|
||||
schema: [
|
||||
{
|
||||
@ -238,6 +238,8 @@ export class HuiEntityBadgeEditor
|
||||
case "state_content":
|
||||
case "show_entity_picture":
|
||||
case "displayed_elements":
|
||||
case "appearance":
|
||||
case "interactions":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.badge.entity.${schema.name}`
|
||||
);
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
union,
|
||||
} from "superstruct";
|
||||
import { HASSDomEvent, fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type {
|
||||
HaFormSchema,
|
||||
@ -69,18 +68,14 @@ export class HuiTileCardEditor
|
||||
}
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
entityId: string | undefined,
|
||||
hideState: boolean
|
||||
) =>
|
||||
(entityId: string | undefined, hideState: boolean) =>
|
||||
[
|
||||
{ name: "entity", selector: { entity: {} } },
|
||||
{
|
||||
name: "",
|
||||
name: "appearance",
|
||||
flatten: true,
|
||||
type: "expandable",
|
||||
iconPath: mdiPalette,
|
||||
title: localize(`ui.panel.lovelace.editor.card.tile.appearance`),
|
||||
schema: [
|
||||
{
|
||||
name: "",
|
||||
@ -136,9 +131,9 @@ export class HuiTileCardEditor
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
name: "interactions",
|
||||
type: "expandable",
|
||||
title: localize(`ui.panel.lovelace.editor.card.tile.interactions`),
|
||||
flatten: true,
|
||||
iconPath: mdiGestureTap,
|
||||
schema: [
|
||||
{
|
||||
@ -178,7 +173,6 @@ export class HuiTileCardEditor
|
||||
: undefined;
|
||||
|
||||
const schema = this._schema(
|
||||
this.hass!.localize,
|
||||
this._config.entity,
|
||||
this._config.hide_state ?? false
|
||||
);
|
||||
@ -306,6 +300,8 @@ export class HuiTileCardEditor
|
||||
case "vertical":
|
||||
case "hide_state":
|
||||
case "state_content":
|
||||
case "appearance":
|
||||
case "interactions":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.tile.${schema.name}`
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user