Rtl configuration fixes (#2720)

* RTL fixes to config pages

* Disconnect toast RTL

* RTL user editor - force LTR (only the user box - not the action box)

* Many RTL fixes in configuration. Keeping scrollbar in RTL so it's not obstructed. Added missing localization.

* Update disconnect-toast-mixin.ts
This commit is contained in:
yosilevy 2019-02-12 00:40:09 +02:00 committed by Paulus Schoutsen
parent 44dca3b86d
commit 9d6c0773c5
20 changed files with 116 additions and 24 deletions

View File

@ -1,13 +1,14 @@
import { Constructor, LitElement } from "lit-element"; import { Constructor, LitElement } from "lit-element";
import { HassBaseEl } from "./hass-base-mixin"; import { HassBaseEl } from "./hass-base-mixin";
import { HaToast } from "../../components/ha-toast"; import { HaToast } from "../../components/ha-toast";
import { computeRTL } from "../../common/util/compute_rtl";
export default (superClass: Constructor<LitElement & HassBaseEl>) => export default (superClass: Constructor<LitElement & HassBaseEl>) =>
class extends superClass { class extends superClass {
private _discToast?: HaToast; private _discToast?: HaToast;
protected hassConnected() { protected firstUpdated(changedProps) {
super.hassConnected(); super.firstUpdated(changedProps);
// Need to load in advance because when disconnected, can't dynamically load code. // Need to load in advance because when disconnected, can't dynamically load code.
import(/* webpackChunkName: "ha-toast" */ "../../components/ha-toast"); import(/* webpackChunkName: "ha-toast" */ "../../components/ha-toast");
} }
@ -24,10 +25,13 @@ export default (superClass: Constructor<LitElement & HassBaseEl>) =>
if (!this._discToast) { if (!this._discToast) {
const el = document.createElement("ha-toast"); const el = document.createElement("ha-toast");
el.duration = 0; el.duration = 0;
el.text = this.hass!.localize("ui.notification_toast.connection_lost");
this._discToast = el; this._discToast = el;
this.shadowRoot!.appendChild(el as any); this.shadowRoot!.appendChild(el as any);
} }
this._discToast.dir = computeRTL(this.hass!);
this._discToast.text = this.hass!.localize(
"ui.notification_toast.connection_lost"
);
this._discToast.opened = true; this._discToast.opened = true;
} }
}; };

View File

@ -51,7 +51,13 @@ class DialogAreaDetail extends LitElement {
opened opened
@opened-changed="${this._openedChanged}" @opened-changed="${this._openedChanged}"
> >
<h2>${this._params.entry ? this._params.entry.name : "New Area"}</h2> <h2>
${this._params.entry
? this._params.entry.name
: this.hass.localize(
"ui.panel.config.area_registry.editor.default_name"
)}
</h2>
<paper-dialog-scrollable> <paper-dialog-scrollable>
${this._error ${this._error
? html` ? html`
@ -62,7 +68,7 @@ class DialogAreaDetail extends LitElement {
<paper-input <paper-input
.value=${this._name} .value=${this._name}
@value-changed=${this._nameChanged} @value-changed=${this._nameChanged}
label="Name" .label=${this.hass.localize("ui.dialogs.more_info_settings.name")}
error-message="Name is required" error-message="Name is required"
.invalid=${nameInvalid} .invalid=${nameInvalid}
></paper-input> ></paper-input>
@ -76,7 +82,9 @@ class DialogAreaDetail extends LitElement {
@click="${this._deleteEntry}" @click="${this._deleteEntry}"
.disabled=${this._submitting} .disabled=${this._submitting}
> >
DELETE ${this.hass.localize(
"ui.panel.config.area_registry.editor.delete"
)}
</paper-button> </paper-button>
` `
: html``} : html``}
@ -84,7 +92,13 @@ class DialogAreaDetail extends LitElement {
@click="${this._updateEntry}" @click="${this._updateEntry}"
.disabled=${nameInvalid || this._submitting} .disabled=${nameInvalid || this._submitting}
> >
${this._params.entry ? "UPDATE" : "CREATE"} ${this._params.entry
? this.hass.localize(
"ui.panel.config.area_registry.editor.update"
)
: this.hass.localize(
"ui.panel.config.area_registry.editor.create"
)}
</paper-button> </paper-button>
</div> </div>
</paper-dialog> </paper-dialog>

View File

@ -50,7 +50,9 @@ class HaConfigAreaRegistry extends LitElement {
return html` return html`
<hass-subpage header="Area Registry"> <hass-subpage header="Area Registry">
<ha-config-section .isWide=${this.isWide}> <ha-config-section .isWide=${this.isWide}>
<span slot="header">Area Registry</span> <span slot="header">
${this.hass.localize("ui.panel.config.area_registry.picker.header")}
</span>
<span slot="introduction"> <span slot="introduction">
Areas are used to organize where devices are. This information will Areas are used to organize where devices are. This information will
be used throughout Home Assistant to help you in organizing your be used throughout Home Assistant to help you in organizing your
@ -74,10 +76,14 @@ class HaConfigAreaRegistry extends LitElement {
${this._items.length === 0 ${this._items.length === 0
? html` ? html`
<div class="empty"> <div class="empty">
Looks like you have no areas yet! ${this.hass.localize(
"ui.panel.config.area_registry.picker.no_areas"
)}
<paper-button @click=${this._createArea}> <paper-button @click=${this._createArea}>
CREATE AREA</paper-button ${this.hass.localize(
> "ui.panel.config.area_registry.picker.create_area"
)}
</paper-button>
</div> </div>
` `
: html``} : html``}

View File

@ -11,6 +11,7 @@ import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar"; import "@polymer/app-layout/app-toolbar/app-toolbar";
import "@polymer/paper-icon-button/paper-icon-button"; import "@polymer/paper-icon-button/paper-icon-button";
import "@polymer/paper-fab/paper-fab"; import "@polymer/paper-fab/paper-fab";
import { classMap } from "lit-html/directives/class-map";
import { h, render } from "preact"; import { h, render } from "preact";
@ -24,6 +25,7 @@ import { haStyle } from "../../../resources/ha-style";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { AutomationEntity, AutomationConfig } from "../../../data/automation"; import { AutomationEntity, AutomationConfig } from "../../../data/automation";
import { navigate } from "../../../common/navigate"; import { navigate } from "../../../common/navigate";
import { computeRTL } from "../../../common/util/compute_rtl";
function AutomationEditor(mountEl, props, mergeEl) { function AutomationEditor(mountEl, props, mergeEl) {
return render(h(Automation, props), mountEl, mergeEl); return render(h(Automation, props), mountEl, mergeEl);
@ -92,7 +94,12 @@ class HaAutomationEditor extends LitElement {
<div class="errors">${this._errors}</div> <div class="errors">${this._errors}</div>
` `
: ""} : ""}
<div id="root"></div> <div
id="root"
class="${classMap({
rtl: computeRTL(this.hass),
})}"
></div>
</div> </div>
<paper-fab <paper-fab
slot="fab" slot="fab"
@ -246,6 +253,10 @@ class HaAutomationEditor extends LitElement {
z-index: 1; z-index: 1;
color: var(--primary-text-color); color: var(--primary-text-color);
} }
.rtl .card-menu {
right: auto;
left: 0;
}
.card-menu paper-item { .card-menu paper-item {
cursor: pointer; cursor: pointer;
} }

View File

@ -39,6 +39,7 @@ class HaConfigCloudAccount extends EventsMixin(LocalizeMixin(PolymerElement)) {
} }
.content { .content {
padding-bottom: 24px; padding-bottom: 24px;
direction: ltr;
} }
paper-card { paper-card {
display: block; display: block;

View File

@ -17,6 +17,7 @@ class HaConfigCloudForgotPassword extends EventsMixin(PolymerElement) {
<style include="iron-flex ha-style"> <style include="iron-flex ha-style">
.content { .content {
padding-bottom: 24px; padding-bottom: 24px;
direction: ltr;
} }
paper-card { paper-card {

View File

@ -26,6 +26,7 @@ class HaConfigCloudLogin extends NavigateMixin(EventsMixin(PolymerElement)) {
<style include="iron-flex ha-style"> <style include="iron-flex ha-style">
.content { .content {
padding-bottom: 24px; padding-bottom: 24px;
direction: ltr;
} }
[slot="introduction"] { [slot="introduction"] {
margin: -1em 0; margin: -1em 0;

View File

@ -16,6 +16,10 @@ class HaConfigCloudRegister extends EventsMixin(PolymerElement) {
static get template() { static get template() {
return html` return html`
<style include="iron-flex ha-style"> <style include="iron-flex ha-style">
.content {
direction: ltr;
}
[slot=introduction] { [slot=introduction] {
margin: -1em 0; margin: -1em 0;
} }

View File

@ -39,11 +39,11 @@ class HaConfigCustomize extends LocalizeMixin(PolymerElement) {
<div class$="[[computeClasses(isWide)]]"> <div class$="[[computeClasses(isWide)]]">
<ha-config-section is-wide="[[isWide]]"> <ha-config-section is-wide="[[isWide]]">
<span slot="header">Customization</span> <span slot="header">
[[localize('ui.panel.config.customize.picker.header')]]
</span>
<span slot="introduction"> <span slot="introduction">
Tweak per-entity attributes.<br /> [[localize('ui.panel.config.customize.picker.introduction')]]
Added/edited customizations will take effect immediately. Removed
customizations will take effect when the entity is updated.
</span> </span>
<ha-entity-config <ha-entity-config
hass="[[hass]]" hass="[[hass]]"

View File

@ -65,7 +65,11 @@ class DialogEntityRegistryDetail extends LitElement {
<paper-dialog-scrollable> <paper-dialog-scrollable>
${!stateObj ${!stateObj
? html` ? html`
<div>This entity is not currently available.</div> <div>
${this.hass!.localize(
"ui.panel.config.entity_registry.editor.unavailable"
)}
</div>
` `
: ""} : ""}
${this._error ${this._error
@ -99,13 +103,17 @@ class DialogEntityRegistryDetail extends LitElement {
@click="${this._deleteEntry}" @click="${this._deleteEntry}"
.disabled=${this._submitting} .disabled=${this._submitting}
> >
DELETE ${this.hass.localize(
"ui.panel.config.entity_registry.editor.delete"
)}
</paper-button> </paper-button>
<paper-button <paper-button
@click="${this._updateEntry}" @click="${this._updateEntry}"
.disabled=${invalidDomainUpdate || this._submitting} .disabled=${invalidDomainUpdate || this._submitting}
> >
UPDATE ${this.hass.localize(
"ui.panel.config.entity_registry.editor.update"
)}
</paper-button> </paper-button>
</div> </div>
</paper-dialog> </paper-dialog>

View File

@ -53,7 +53,11 @@ class HaConfigEntityRegistry extends LitElement {
return html` return html`
<hass-subpage header="Entity Registry"> <hass-subpage header="Entity Registry">
<ha-config-section .isWide=${this.isWide}> <ha-config-section .isWide=${this.isWide}>
<span slot="header">Entity Registry</span> <span slot="header">
${this.hass.localize(
"ui.panel.config.entity_registry.picker.header"
)}
</span>
<span slot="introduction"> <span slot="introduction">
Home Assistant keeps a registry of every entity it has ever seen Home Assistant keeps a registry of every entity it has ever seen
that can be uniquely identified. Each of these entities will have an that can be uniquely identified. Each of these entities will have an
@ -79,7 +83,9 @@ class HaConfigEntityRegistry extends LitElement {
<paper-item-body two-line> <paper-item-body two-line>
<div class="name"> <div class="name">
${computeEntityRegistryName(this.hass!, entry) || ${computeEntityRegistryName(this.hass!, entry) ||
"(unavailable)"} this.hass!.localize(
"ui.panel.config.entity_registry.picker.unavailable"
)}
</div> </div>
<div class="secondary entity-id"> <div class="secondary entity-id">
${entry.entity_id} ${entry.entity_id}
@ -150,6 +156,7 @@ Deleting an entry will not remove the entity from Home Assistant. To do this, yo
} }
paper-card { paper-card {
display: block; display: block;
direction: ltr;
} }
paper-icon-item { paper-icon-item {
cursor: pointer; cursor: pointer;

View File

@ -15,6 +15,7 @@ class HaEntityConfig extends PolymerElement {
<style include="iron-flex ha-style"> <style include="iron-flex ha-style">
paper-card { paper-card {
display: block; display: block;
direction: ltr;
} }
.device-picker { .device-picker {

View File

@ -54,6 +54,7 @@ export default class NumericStateCondition extends Component {
name="value_template" name="value_template"
value={value_template} value={value_template}
onvalue-changed={this.onChange} onvalue-changed={this.onChange}
dir="ltr"
/> />
</div> </div>
); );

View File

@ -22,6 +22,7 @@ export default class TemplateCondition extends Component {
name="value_template" name="value_template"
value={value_template} value={value_template}
onvalue-changed={this.onChange} onvalue-changed={this.onChange}
dir="ltr"
/> />
</div> </div>
); );

View File

@ -53,6 +53,7 @@ export default class JSONTextArea extends Component {
value={value} value={value}
style={style} style={style}
onvalue-changed={this.onChange} onvalue-changed={this.onChange}
dir="ltr"
/> />
); );
} }

View File

@ -36,6 +36,7 @@ export default class WaitAction extends Component {
name="wait_template" name="wait_template"
value={wait_template} value={wait_template}
onvalue-changed={this.onTemplateChange} onvalue-changed={this.onTemplateChange}
dir="ltr"
/> />
<paper-input <paper-input
label={localize( label={localize(

View File

@ -67,6 +67,7 @@ export default class NumericStateTrigger extends Component {
name="value_template" name="value_template"
value={value_template} value={value_template}
onvalue-changed={this.onChange} onvalue-changed={this.onChange}
dir="ltr"
/> />
<paper-input <paper-input
label={localize( label={localize(

View File

@ -23,6 +23,7 @@ export default class TemplateTrigger extends Component {
name="value_template" name="value_template"
value={value_template} value={value_template}
onvalue-changed={this.onChange} onvalue-changed={this.onChange}
dir="ltr"
/> />
</div> </div>
); );

View File

@ -30,6 +30,9 @@ class HaUserEditor extends EventsMixin(
paper-card:last-child { paper-card:last-child {
margin-bottom: 16px; margin-bottom: 16px;
} }
hass-subpage paper-card:first-of-type {
direction: ltr;
}
</style> </style>
<hass-subpage header="View user"> <hass-subpage header="View user">

View File

@ -530,7 +530,18 @@
"introduction": "Here it is possible to configure your components and Home Assistant. Not everything is possible to configure from the UI yet, but we're working on it.", "introduction": "Here it is possible to configure your components and Home Assistant. Not everything is possible to configure from the UI yet, but we're working on it.",
"area_registry": { "area_registry": {
"caption": "Area Registry", "caption": "Area Registry",
"description": "Overview of all areas in your home." "description": "Overview of all areas in your home.",
"picker": {
"header": "Area Registry"
},
"no_areas": "Looks like you have no areas yet!",
"create_area": "CREATE AREA",
"editor": {
"default_name": "New Area",
"delete": "DELETE",
"update": "UPDATE",
"create": "CREATE"
}
}, },
"core": { "core": {
"caption": "General", "caption": "General",
@ -565,7 +576,11 @@
}, },
"customize": { "customize": {
"caption": "Customization", "caption": "Customization",
"description": "Customize your entities" "description": "Customize your entities",
"picker": {
"header": "Customization",
"introduction": "Tweak per-entity attributes. Added/edited customizations will take effect immediately. Removed customizations will take effect when the entity is updated."
}
}, },
"automation": { "automation": {
"caption": "Automation", "caption": "Automation",
@ -755,7 +770,17 @@
}, },
"entity_registry": { "entity_registry": {
"caption": "Entity Registry", "caption": "Entity Registry",
"description": "Overview of all known entities." "description": "Overview of all known entities.",
"picker": {
"header": "Entity Registry",
"unavailable": "(unavailable)"
},
"editor": {
"unavailable": "This entity is not currently available.",
"default_name": "New Area",
"delete": "DELETE",
"update": "UPDATE"
}
}, },
"person": { "person": {
"caption": "People", "caption": "People",