mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 16:56:35 +00:00
Merge pull request #11462 from home-assistant/dev
This commit is contained in:
commit
9fee7a2829
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="home-assistant-frontend",
|
||||
version="20220126.0",
|
||||
version="20220127.0",
|
||||
description="The Home Assistant frontend",
|
||||
url="https://github.com/home-assistant/frontend",
|
||||
author="The Home Assistant Authors",
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
import { Selector } from "../data/selector";
|
||||
import { PolymerChangedEvent } from "../polymer-types";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { documentationUrl } from "../util/documentation-url";
|
||||
import "./ha-checkbox";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-selector/ha-selector";
|
||||
@ -230,7 +231,12 @@ export class HaServiceControl extends LitElement {
|
||||
<p>${serviceData?.description}</p>
|
||||
${this._manifest
|
||||
? html` <a
|
||||
href=${this._manifest.documentation}
|
||||
href=${this._manifest.is_built_in
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${this._manifest.domain}`
|
||||
)
|
||||
: this._manifest.documentation}
|
||||
title=${this.hass.localize(
|
||||
"ui.components.service-control.integration_doc"
|
||||
)}
|
||||
|
@ -255,8 +255,10 @@ export class HaMediaPlayerBrowse extends LitElement {
|
||||
${child.thumbnail
|
||||
? html`
|
||||
<div
|
||||
class="${child.media_class ===
|
||||
"directory"
|
||||
class="${[
|
||||
"app",
|
||||
"directory",
|
||||
].includes(child.media_class)
|
||||
? "centered-image"
|
||||
: ""} image lazythumbnail"
|
||||
data-src=${child.thumbnail}
|
||||
|
@ -104,18 +104,19 @@ export const localizeConfigFlowTitle = (
|
||||
localize: LocalizeFunc,
|
||||
flow: DataEntryFlowProgress
|
||||
) => {
|
||||
const placeholders = flow.context.title_placeholders || {};
|
||||
const placeholderKeys = Object.keys(placeholders);
|
||||
if (placeholderKeys.length === 0) {
|
||||
if (
|
||||
!flow.context.title_placeholders ||
|
||||
Object.keys(flow.context.title_placeholders).length === 0
|
||||
) {
|
||||
return domainToName(localize, flow.handler);
|
||||
}
|
||||
const args: string[] = [];
|
||||
placeholderKeys.forEach((key) => {
|
||||
args.push(key);
|
||||
args.push(placeholders[key]);
|
||||
});
|
||||
return localize(`component.${flow.handler}.config.flow_title`, ...args) ||
|
||||
"name" in placeholders
|
||||
? placeholders.name
|
||||
: domainToName(localize, flow.handler);
|
||||
return (
|
||||
localize(
|
||||
`component.${flow.handler}.config.flow_title`,
|
||||
flow.context.title_placeholders
|
||||
) ||
|
||||
("name" in flow.context.title_placeholders
|
||||
? flow.context.title_placeholders.name
|
||||
: domainToName(localize, flow.handler))
|
||||
);
|
||||
};
|
||||
|
@ -108,7 +108,9 @@ export class QuickBar extends LitElement {
|
||||
public async showDialog(params: QuickBarParams) {
|
||||
this._commandMode = params.commandMode || this._toggleIfAlreadyOpened();
|
||||
this._hint = params.hint;
|
||||
this._narrow = matchMedia("(max-width: 600px)").matches;
|
||||
this._narrow = matchMedia(
|
||||
"all and (max-width: 450px), all and (max-height: 500px)"
|
||||
).matches;
|
||||
this._initializeItemsIfNeeded();
|
||||
this._opened = true;
|
||||
}
|
||||
@ -154,7 +156,7 @@ export class QuickBar extends LitElement {
|
||||
)}
|
||||
.value=${this._commandMode ? `>${this._search}` : this._search}
|
||||
.icon=${true}
|
||||
.iconTrailing=${this._search !== undefined}
|
||||
.iconTrailing=${this._search !== undefined || this._narrow}
|
||||
@input=${this._handleSearchChange}
|
||||
@keydown=${this._handleInputKeyDown}
|
||||
@focus=${this._setFocusFirstListItem}
|
||||
@ -174,24 +176,26 @@ export class QuickBar extends LitElement {
|
||||
.path=${mdiMagnify}
|
||||
></ha-svg-icon>
|
||||
`}
|
||||
${this._search &&
|
||||
html`
|
||||
<ha-icon-button
|
||||
slot="trailingIcon"
|
||||
@click=${this._clearSearch}
|
||||
.label=${this.hass!.localize("ui.common.clear")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
`}
|
||||
${this._search || this._narrow
|
||||
? html`
|
||||
<div slot="trailingIcon">
|
||||
${this._search &&
|
||||
html`<ha-icon-button
|
||||
@click=${this._clearSearch}
|
||||
.label=${this.hass!.localize("ui.common.clear")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>`}
|
||||
${this._narrow &&
|
||||
html`
|
||||
<mwc-button
|
||||
.label=${this.hass!.localize("ui.common.close")}
|
||||
@click=${this.closeDialog}
|
||||
></mwc-button>
|
||||
`}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
</ha-textfield>
|
||||
${this._narrow
|
||||
? html`
|
||||
<mwc-button
|
||||
.label=${this.hass!.localize("ui.common.close")}
|
||||
@click=${this.closeDialog}
|
||||
></mwc-button>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
${!items
|
||||
? html`<ha-circular-progress
|
||||
@ -210,10 +214,12 @@ export class QuickBar extends LitElement {
|
||||
@keydown=${this._handleListItemKeyDown}
|
||||
@selected=${this._handleSelected}
|
||||
style=${styleMap({
|
||||
height: `${Math.min(
|
||||
items.length * (this._commandMode ? 56 : 72) + 26,
|
||||
this._done ? 500 : 0
|
||||
)}px`,
|
||||
height: this._narrow
|
||||
? "calc(100vh - 56px)"
|
||||
: `${Math.min(
|
||||
items.length * (this._commandMode ? 56 : 72) + 26,
|
||||
this._done ? 500 : 0
|
||||
)}px`,
|
||||
})}
|
||||
>
|
||||
${scroll({
|
||||
@ -705,6 +711,12 @@ export class QuickBar extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
ha-textfield {
|
||||
--mdc-shape-small: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ha-icon.entity,
|
||||
ha-svg-icon.entity {
|
||||
margin-left: 20px;
|
||||
@ -758,6 +770,11 @@ export class QuickBar extends LitElement {
|
||||
padding: 16px 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div[slot="trailingIcon"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -5,5 +5,3 @@ import "../resources/roboto";
|
||||
import "../util/legacy-support";
|
||||
|
||||
setPassiveTouchGestures(true);
|
||||
|
||||
(window as any).frontendVersion = __VERSION__;
|
||||
|
@ -29,6 +29,7 @@ import { HomeAssistant } from "../types";
|
||||
import { MAIN_WINDOW_NAME } from "../data/main_window";
|
||||
|
||||
window.name = MAIN_WINDOW_NAME;
|
||||
(window as any).frontendVersion = __VERSION__;
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
} from "../../../data/integration";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { brandsUrl } from "../../../util/brands-url";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
|
||||
@customElement("integrations-card")
|
||||
class IntegrationsCard extends LitElement {
|
||||
@ -66,7 +67,12 @@ class IntegrationsCard extends LitElement {
|
||||
const manifest = this._manifests && this._manifests[domain];
|
||||
const docLink = manifest
|
||||
? html`<a
|
||||
href=${manifest.documentation}
|
||||
href=${manifest.is_built_in
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${manifest.domain}`
|
||||
)
|
||||
: manifest.documentation}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${this.hass.localize(
|
||||
|
@ -15,6 +15,7 @@ import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { DataEntryFlowProgressExtended } from "./ha-config-integrations";
|
||||
import "./ha-integration-action-card";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
|
||||
@customElement("ha-config-flow-card")
|
||||
export class HaConfigFlowCard extends LitElement {
|
||||
@ -82,7 +83,12 @@ export class HaConfigFlowCard extends LitElement {
|
||||
: ""}
|
||||
${this.manifest
|
||||
? html`<a
|
||||
href=${this.manifest.documentation}
|
||||
href=${this.manifest.is_built_in
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${this.manifest.domain}`
|
||||
)
|
||||
: this.manifest.documentation}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
|
@ -46,6 +46,7 @@ import {
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { haStyle, haStyleScrollbar } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import { fileDownload } from "../../../util/file_download";
|
||||
import type { ConfigEntryExtended } from "./ha-config-integrations";
|
||||
import "./ha-integration-header";
|
||||
@ -331,7 +332,12 @@ export class HaIntegrationCard extends LitElement {
|
||||
</mwc-list-item>
|
||||
${this.manifest
|
||||
? html` <a
|
||||
href=${this.manifest.documentation}
|
||||
href=${this.manifest.is_built_in
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${this.manifest.domain}`
|
||||
)
|
||||
: this.manifest.documentation}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
} from "../../../data/system_log";
|
||||
import { haStyleDialog } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import type { SystemLogDetailDialogParams } from "./show-dialog-system-log-detail";
|
||||
import { formatSystemLogTime } from "./util";
|
||||
@ -117,7 +118,12 @@ class DialogSystemLogDetail extends LitElement {
|
||||
? ""
|
||||
: html`
|
||||
(<a
|
||||
href=${this._manifest.documentation}
|
||||
href=${this._manifest.is_built_in
|
||||
? documentationUrl(
|
||||
this.hass,
|
||||
`/integrations/${this._manifest.domain}`
|
||||
)
|
||||
: this._manifest.documentation}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>documentation</a
|
||||
|
@ -8,6 +8,7 @@ import "@polymer/paper-tooltip/paper-tooltip";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoize from "memoize-one";
|
||||
import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
|
||||
import { navigate } from "../../../../common/navigate";
|
||||
import { stringCompare } from "../../../../common/string/compare";
|
||||
import {
|
||||
@ -183,29 +184,34 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
||||
).mode;
|
||||
const defaultUrlPath = this.hass.defaultPanel;
|
||||
const isDefault = defaultUrlPath === "lovelace";
|
||||
return [
|
||||
const result: Record<string, any>[] = [
|
||||
{
|
||||
icon: "hass:view-dashboard",
|
||||
title: this.hass.localize("panel.states"),
|
||||
default: isDefault,
|
||||
sidebar: isDefault,
|
||||
show_in_sidebar: isDefault,
|
||||
require_admin: false,
|
||||
url_path: "lovelace",
|
||||
mode: defaultMode,
|
||||
filename: defaultMode === "yaml" ? "ui-lovelace.yaml" : "",
|
||||
},
|
||||
{
|
||||
icon: "hass:lightning-bolt",
|
||||
title: this.hass.localize(`ui.panel.config.dashboard.energy.title`),
|
||||
url_path: "energy",
|
||||
filename: "",
|
||||
},
|
||||
...dashboards.map((dashboard) => ({
|
||||
filename: "",
|
||||
...dashboard,
|
||||
default: defaultUrlPath === dashboard.url_path,
|
||||
})),
|
||||
];
|
||||
if (isComponentLoaded(this.hass, "energy")) {
|
||||
result.push({
|
||||
icon: "hass:lightning-bolt",
|
||||
title: this.hass.localize(`ui.panel.config.dashboard.energy.title`),
|
||||
show_in_sidebar: true,
|
||||
mode: "storage",
|
||||
url_path: "energy",
|
||||
filename: "",
|
||||
});
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
protected render(): TemplateResult {
|
||||
|
@ -130,6 +130,7 @@ class HUIRoot extends LitElement {
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
<mwc-button
|
||||
outlined
|
||||
class="exit-edit-mode"
|
||||
.label=${this.hass!.localize(
|
||||
"ui.panel.lovelace.menu.exit_edit_mode"
|
||||
@ -938,7 +939,8 @@ class HUIRoot extends LitElement {
|
||||
);
|
||||
}
|
||||
.exit-edit-mode {
|
||||
--mdc-theme-primary: var(--primary-text-color);
|
||||
--mdc-theme-primary: var(--app-header-edit-text-color, #fff);
|
||||
--mdc-button-outline-color: var(--app-header-edit-text-color, #fff);
|
||||
--mdc-typography-button-font-size: 14px;
|
||||
}
|
||||
`,
|
||||
|
@ -3,7 +3,7 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { subscribeOne } from "../../../common/util/subscribe-one";
|
||||
import { subscribeAreaRegistry } from "../../../data/area_registry";
|
||||
import { subscribeDeviceRegistry } from "../../../data/device_registry";
|
||||
import { EnergyPreferences, getEnergyPreferences } from "../../../data/energy";
|
||||
import { getEnergyPreferences } from "../../../data/energy";
|
||||
import { subscribeEntityRegistry } from "../../../data/entity_registry";
|
||||
import { generateDefaultViewConfig } from "../common/generate-lovelace-config";
|
||||
import {
|
||||
@ -39,30 +39,18 @@ export class OriginalStatesStrategy {
|
||||
subscribeEntityRegistry(hass.connection, () => undefined);
|
||||
}
|
||||
|
||||
let energyPromise: Promise<EnergyPreferences> | undefined;
|
||||
|
||||
if (isComponentLoaded(hass, "energy")) {
|
||||
energyPromise = getEnergyPreferences(hass);
|
||||
}
|
||||
|
||||
const [areaEntries, deviceEntries, entityEntries, localize] =
|
||||
const [areaEntries, deviceEntries, entityEntries, localize, energyPrefs] =
|
||||
await Promise.all([
|
||||
subscribeOne(hass.connection, subscribeAreaRegistry),
|
||||
subscribeOne(hass.connection, subscribeDeviceRegistry),
|
||||
subscribeOne(hass.connection, subscribeEntityRegistry),
|
||||
hass.loadBackendTranslation("title"),
|
||||
isComponentLoaded(hass, "energy")
|
||||
? // It raises if not configured, just swallow that.
|
||||
getEnergyPreferences(hass).catch(() => undefined)
|
||||
: undefined,
|
||||
]);
|
||||
|
||||
let energyPrefs: EnergyPreferences | undefined;
|
||||
|
||||
if (energyPromise) {
|
||||
try {
|
||||
energyPrefs = await energyPromise;
|
||||
} catch (_) {
|
||||
// Nothing to do here
|
||||
}
|
||||
}
|
||||
|
||||
// User can override default view. If they didn't, we will add one
|
||||
// that contains all entities.
|
||||
const view = generateDefaultViewConfig(
|
||||
|
@ -448,6 +448,7 @@ class BarMediaPlayer extends LitElement {
|
||||
|
||||
.controls {
|
||||
height: 48px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.controls-progress {
|
||||
@ -501,6 +502,7 @@ class BarMediaPlayer extends LitElement {
|
||||
|
||||
:host([narrow]) .controls {
|
||||
display: flex;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
:host([narrow]) .choose-player {
|
||||
|
Loading…
x
Reference in New Issue
Block a user