feat v1.11.0: full English translation + en/ru UI localization

- All card UI strings moved to src/i18n.ts (en/ru); language follows the HA
  profile automatically, new 'language: en|ru' card option forces it; GUI
  editor localized and got the language dropdown; generated device names
  localized via BuildCtx.loc.
- English-only codebase: comments, docstrings, test names, backend error
  messages and logs. Russian remains only in the ru dictionary, ru.json,
  iconFor regexes matching Russian device names (+their fixtures) and README.ru.md.
- Docs English-first: README (EN) + README.ru.md, ARCHITECTURE/DEVELOPMENT/
  ROADMAP/CHANGELOG fully translated; translations/en.json had Russian - fixed.
- Removed obsolete RELEASE_NOTES_v1.9.3.md and scripts_publish.sh.
This commit is contained in:
Matysh
2026-07-05 21:43:58 +03:00
parent f1b372f0e6
commit 94fb4af14c
29 changed files with 1692 additions and 1210 deletions
+32 -12
View File
@@ -1,14 +1,6 @@
/** Редактор конфигурации карточки (GUI в Lovelace). */
/** Card configuration editor (Lovelace GUI). */
import { LitElement, html, nothing } from 'lit';
const LABELS: Record<string, string> = {
title: 'Заголовок',
default_floor: 'Пространство по умолчанию',
icon_size: 'Размер иконок, % ширины плана',
show_temperature: 'Показывать температуру',
live_states: 'Живые состояния (вкл/выкл, открыто…)',
show_signal: 'Показывать сигнал zigbee (LQI)',
};
import { langOf, t, type Lang } from './i18n';
class HouseplanCardEditor extends LitElement {
public hass?: any;
@@ -26,7 +18,7 @@ class HouseplanCardEditor extends LitElement {
this._config = config;
}
/** Пространства из серверного конфига интеграции — не хардкод. */
/** Spaces come from the integration's server config — never hard-coded. */
private async _loadSpaces(): Promise<void> {
if (this._spaces || this._spacesLoading || !this.hass) return;
this._spacesLoading = true;
@@ -43,8 +35,13 @@ class HouseplanCardEditor extends LitElement {
}
}
private get _lang(): Lang {
return langOf(this.hass, this._config?.language);
}
private get _schema(): any[] {
const spaces = this._spaces || [];
const L = this._lang;
return [
{ name: 'title', selector: { text: {} } },
spaces.length
@@ -53,6 +50,19 @@ class HouseplanCardEditor extends LitElement {
selector: { select: { mode: 'dropdown', options: spaces } },
}
: { name: 'default_floor', selector: { text: {} } },
{
name: 'language',
selector: {
select: {
mode: 'dropdown',
options: [
{ value: '', label: t(L, 'editor.lang_auto') },
{ value: 'en', label: t(L, 'editor.lang_en') },
{ value: 'ru', label: t(L, 'editor.lang_ru') },
],
},
},
},
{ name: 'icon_size', selector: { number: { min: 1, max: 6, step: 0.1, mode: 'box' } } },
{ name: 'show_temperature', selector: { boolean: {} } },
{ name: 'live_states', selector: { boolean: {} } },
@@ -63,11 +73,21 @@ class HouseplanCardEditor extends LitElement {
protected render() {
if (!this.hass || !this._config) return nothing;
this._loadSpaces();
const L = this._lang;
const labels: Record<string, string> = {
title: t(L, 'editor.title'),
default_floor: t(L, 'editor.default_floor'),
language: t(L, 'editor.language'),
icon_size: t(L, 'editor.icon_size'),
show_temperature: t(L, 'editor.show_temperature'),
live_states: t(L, 'editor.live_states'),
show_signal: t(L, 'editor.show_signal'),
};
return html`<ha-form
.hass=${this.hass}
.data=${this._config}
.schema=${this._schema}
.computeLabel=${(s: any) => LABELS[s.name] || s.name}
.computeLabel=${(s: any) => labels[s.name] || s.name}
@value-changed=${this._valueChanged}
></ha-form>`;
}