mirror of
https://github.com/home-assistant/frontend.git
synced 2026-02-15 07:25:54 +00:00
Migrate button-menu to ha-dropdown 8 files (#29102)
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { mdiCog, mdiContentCopy } from "@mdi/js";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { PropertyValues } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { slugify } from "../../../../../common/string/slugify";
|
||||
import { copyToClipboard } from "../../../../../common/util/copy-clipboard";
|
||||
import { stopPropagation } from "../../../../../common/dom/stop_propagation";
|
||||
import "../../../../../components/ha-button-menu";
|
||||
import "../../../../../components/ha-check-list-item";
|
||||
import "../../../../../components/ha-dropdown";
|
||||
import "../../../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../../../components/ha-dropdown-item";
|
||||
import "../../../../../components/ha-icon-button";
|
||||
import "../../../../../components/ha-textfield";
|
||||
import type { HaTextField } from "../../../../../components/ha-textfield";
|
||||
@@ -125,7 +125,11 @@ export class HaWebhookTrigger extends LitElement {
|
||||
.path=${mdiContentCopy}
|
||||
></ha-icon-button>
|
||||
</ha-textfield>
|
||||
<ha-button-menu multi @closed=${stopPropagation} fixed>
|
||||
<ha-dropdown
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
placement="bottom-end"
|
||||
distance="-24"
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass!.localize(
|
||||
@@ -135,27 +139,29 @@ export class HaWebhookTrigger extends LitElement {
|
||||
></ha-icon-button>
|
||||
${SUPPORTED_METHODS.map(
|
||||
(method) => html`
|
||||
<ha-check-list-item
|
||||
left
|
||||
<ha-dropdown-item
|
||||
.value=${method}
|
||||
type="checkbox"
|
||||
@request-selected=${this._allowedMethodsChanged}
|
||||
.selected=${allowedMethods!.includes(method)}
|
||||
.checked=${allowedMethods!.includes(method)}
|
||||
>
|
||||
${method}
|
||||
</ha-check-list-item>
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
)}
|
||||
<li divider role="separator"></li>
|
||||
<ha-check-list-item
|
||||
left
|
||||
@request-selected=${this._localOnlyChanged}
|
||||
.selected=${localOnly!}
|
||||
${SUPPORTED_METHODS.length
|
||||
? html`<wa-divider></wa-divider>`
|
||||
: nothing}
|
||||
<ha-dropdown-item
|
||||
type="checkbox"
|
||||
.checked=${localOnly!}
|
||||
value="local_only"
|
||||
>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.automation.editor.triggers.type.webhook.local_only"
|
||||
)}
|
||||
</ha-check-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -164,23 +170,18 @@ export class HaWebhookTrigger extends LitElement {
|
||||
handleChangeEvent(this, ev);
|
||||
}
|
||||
|
||||
private _localOnlyChanged(ev: CustomEvent<RequestSelectedDetail>): void {
|
||||
ev.stopPropagation();
|
||||
if (this.trigger.local_only === ev.detail.selected) {
|
||||
private _localOnlyChanged(local_only: boolean): void {
|
||||
if (this.trigger.local_only === local_only) {
|
||||
return;
|
||||
}
|
||||
const newTrigger = {
|
||||
...this.trigger,
|
||||
local_only: ev.detail.selected,
|
||||
local_only,
|
||||
};
|
||||
fireEvent(this, "value-changed", { value: newTrigger });
|
||||
}
|
||||
|
||||
private _allowedMethodsChanged(ev: CustomEvent<RequestSelectedDetail>): void {
|
||||
ev.stopPropagation();
|
||||
const method = (ev.target as any).value;
|
||||
const selected = ev.detail.selected;
|
||||
|
||||
private _allowedMethodsChanged(method: string, selected: boolean): void {
|
||||
if (selected === this.trigger.allowed_methods?.includes(method)) {
|
||||
return;
|
||||
}
|
||||
@@ -207,6 +208,22 @@ export class HaWebhookTrigger extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
ev.preventDefault(); // don't close the dropdown to select multiple options
|
||||
const action = ev.detail?.item?.value;
|
||||
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === "local_only") {
|
||||
this._localOnlyChanged(ev.detail.item.checked);
|
||||
return;
|
||||
}
|
||||
|
||||
this._allowedMethodsChanged(ev.detail.item.value, ev.detail.item.checked);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.flex {
|
||||
display: flex;
|
||||
@@ -222,7 +239,7 @@ export class HaWebhookTrigger extends LitElement {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
ha-button-menu {
|
||||
ha-dropdown ha-icon-button {
|
||||
padding-top: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -16,7 +16,6 @@ import { relativeTime } from "../../../common/datetime/relative_time";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import { fireEvent, type HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import type { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import type {
|
||||
@@ -26,14 +25,18 @@ import type {
|
||||
SelectionChangedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-filter-states";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-icon-overflow-menu";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-md-menu";
|
||||
import type { HaMdMenu } from "../../../components/ha-md-menu";
|
||||
import "../../../components/ha-md-menu-item";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import type {
|
||||
BackupAgent,
|
||||
@@ -71,9 +74,6 @@ import { showGenerateBackupDialog } from "./dialogs/show-dialog-generate-backup"
|
||||
import { showNewBackupDialog } from "./dialogs/show-dialog-new-backup";
|
||||
import { showUploadBackupDialog } from "./dialogs/show-dialog-upload-backup";
|
||||
import { downloadBackup } from "./helper/download_backup";
|
||||
import type { HaMdMenu } from "../../../components/ha-md-menu";
|
||||
import "../../../components/ha-md-menu";
|
||||
import "../../../components/ha-md-menu-item";
|
||||
|
||||
interface BackupRow extends DataTableRowData, BackupContent {
|
||||
formatted_type: string;
|
||||
@@ -401,22 +401,22 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
)}
|
||||
>
|
||||
<div slot="toolbar-icon">
|
||||
<ha-button-menu>
|
||||
<ha-dropdown
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
placement="bottom-end"
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
<ha-list-item
|
||||
graphic="icon"
|
||||
@request-selected=${this._uploadBackup}
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiUpload}></ha-svg-icon>
|
||||
<ha-dropdown-item value="upload_backup">
|
||||
<ha-svg-icon slot="icon" .path=${mdiUpload}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.backups.menu.upload_backup"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
</div>
|
||||
|
||||
<div slot="selection-bar">
|
||||
@@ -447,7 +447,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
<ha-filter-states
|
||||
.hass=${this.hass}
|
||||
.label=${this.hass.localize("ui.panel.config.backup.backup_type")}
|
||||
.value=${this._filters["ha-filter-states"]}
|
||||
.value="${this._filters["ha-filter-states"]}q"
|
||||
.states=${this._states(this.hass.localize, isHassio)}
|
||||
@data-table-filter-changed=${this._filterChanged}
|
||||
slot="filter-pane"
|
||||
@@ -519,13 +519,9 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
return !this.config?.automatic_backups_configured;
|
||||
}
|
||||
|
||||
private async _uploadBackup(ev) {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
private _uploadBackup = async () => {
|
||||
await showUploadBackupDialog(this, {});
|
||||
}
|
||||
};
|
||||
|
||||
private async _newBackup(): Promise<void> {
|
||||
const config = this.config!;
|
||||
@@ -635,6 +631,14 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
|
||||
this._dataTable.clearSelection();
|
||||
}
|
||||
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
const action = ev.detail?.item.value;
|
||||
|
||||
if (action === "upload_backup") {
|
||||
this._uploadBackup();
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
|
||||
@@ -3,16 +3,16 @@ import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-icon-overflow-menu";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import type {
|
||||
BackupAgent,
|
||||
@@ -63,13 +63,9 @@ class HaConfigBackupOverview extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public agents: BackupAgent[] = [];
|
||||
|
||||
private async _uploadBackup(ev) {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
private _uploadBackup = async () => {
|
||||
await showUploadBackupDialog(this, {});
|
||||
}
|
||||
};
|
||||
|
||||
private _handleOnboardingButtonClick(ev) {
|
||||
ev.stopPropagation();
|
||||
@@ -143,19 +139,23 @@ class HaConfigBackupOverview extends LitElement {
|
||||
.narrow=${this.narrow}
|
||||
.header=${this.hass.localize("ui.panel.config.backup.overview.header")}
|
||||
>
|
||||
<ha-button-menu slot="toolbar-icon">
|
||||
<ha-dropdown
|
||||
slot="toolbar-icon"
|
||||
placement="bottom-end"
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
<ha-list-item graphic="icon" @request-selected=${this._uploadBackup}>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiUpload}></ha-svg-icon>
|
||||
<ha-dropdown-item value="upload_backup">
|
||||
<ha-svg-icon slot="icon" .path=${mdiUpload}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.overview.menu.upload_backup"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
<div class="content">
|
||||
${this.info && Object.keys(this.info.agent_errors).length
|
||||
? html`${Object.entries(this.info.agent_errors).map(
|
||||
@@ -240,6 +240,14 @@ class HaConfigBackupOverview extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
const action = ev.detail?.item.value;
|
||||
|
||||
if (action === "upload_backup") {
|
||||
this._uploadBackup();
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
|
||||
@@ -4,16 +4,16 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
|
||||
import { debounce } from "../../../common/util/debounce";
|
||||
import { nextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-password-field";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import type { BackupAgent, BackupConfig } from "../../../data/backup";
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
} from "../../../data/supervisor/update";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { brandsUrl } from "../../../util/brands-url";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import "./components/config/ha-backup-config-addon";
|
||||
import "./components/config/ha-backup-config-agents";
|
||||
@@ -35,7 +36,6 @@ import "./components/config/ha-backup-config-encryption-key";
|
||||
import "./components/config/ha-backup-config-schedule";
|
||||
import type { BackupConfigSchedule } from "./components/config/ha-backup-config-schedule";
|
||||
import { showLocalBackupLocationDialog } from "./dialogs/show-dialog-local-backup-location";
|
||||
import { brandsUrl } from "../../../util/brands-url";
|
||||
|
||||
@customElement("ha-config-backup-settings")
|
||||
class HaConfigBackupSettings extends LitElement {
|
||||
@@ -140,25 +140,22 @@ class HaConfigBackupSettings extends LitElement {
|
||||
>
|
||||
${supervisor
|
||||
? html`
|
||||
<ha-button-menu slot="toolbar-icon">
|
||||
<ha-dropdown
|
||||
slot="toolbar-icon"
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
<ha-list-item
|
||||
graphic="icon"
|
||||
@request-selected=${this._changeLocalLocation}
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${mdiHarddisk}
|
||||
></ha-svg-icon>
|
||||
<ha-dropdown-item value="change_local_location">
|
||||
<ha-svg-icon slot="icon" .path=${mdiHarddisk}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.backup.settings.menu.change_default_location"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
`
|
||||
: nothing}
|
||||
|
||||
@@ -372,13 +369,9 @@ class HaConfigBackupSettings extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private async _changeLocalLocation(ev) {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
private _changeLocalLocation = () => {
|
||||
showLocalBackupLocationDialog(this, {});
|
||||
}
|
||||
};
|
||||
|
||||
private async _supervisorUpdateConfigChanged(ev) {
|
||||
const config = ev.detail.value as SupervisorUpdateConfig;
|
||||
@@ -499,6 +492,14 @@ class HaConfigBackupSettings extends LitElement {
|
||||
fireEvent(this, "ha-refresh-backup-config");
|
||||
}
|
||||
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
const action = ev.detail?.item?.value;
|
||||
|
||||
if (action === "change_local_location") {
|
||||
this._changeLocalLocation();
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-card {
|
||||
scroll-margin-top: 16px;
|
||||
|
||||
@@ -6,13 +6,14 @@ import {
|
||||
mdiOpenInNew,
|
||||
} from "@mdi/js";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
|
||||
import {
|
||||
deleteApplicationCredential,
|
||||
fetchApplicationCredentialsConfigEntry,
|
||||
@@ -53,7 +54,7 @@ export class HaConfigFlowCard extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.manifest=${this.manifest}
|
||||
.domain=${this.flow.handler}
|
||||
.label=${this.flow.localized_title}
|
||||
.label=${this.flow.localized_title ?? ""}
|
||||
>
|
||||
${DISCOVERY_SOURCES.includes(this.flow.context.source) &&
|
||||
this.flow.context.unique_id
|
||||
@@ -62,7 +63,7 @@ export class HaConfigFlowCard extends LitElement {
|
||||
"ui.panel.config.integrations.ignore.ignore"
|
||||
)}</ha-button
|
||||
>`
|
||||
: ""}
|
||||
: nothing}
|
||||
<ha-button
|
||||
@click=${this._continueFlow}
|
||||
variant=${attention ? "danger" : "brand"}
|
||||
@@ -75,7 +76,11 @@ export class HaConfigFlowCard extends LitElement {
|
||||
)}
|
||||
</ha-button>
|
||||
${this.flow.context.configuration_url || this.manifest || attention
|
||||
? html`<ha-button-menu slot="header-button">
|
||||
? html`<ha-dropdown
|
||||
slot="header-button"
|
||||
placement="bottom-end"
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
@@ -94,18 +99,18 @@ export class HaConfigFlowCard extends LitElement {
|
||||
? "_self"
|
||||
: "_blank"}
|
||||
>
|
||||
<ha-list-item graphic="icon" hasMeta>
|
||||
<ha-dropdown-item>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.open_configuration_url"
|
||||
)}
|
||||
<ha-svg-icon slot="graphic" .path=${mdiCog}></ha-svg-icon>
|
||||
<ha-svg-icon slot="icon" .path=${mdiCog}></ha-svg-icon>
|
||||
<ha-svg-icon
|
||||
slot="meta"
|
||||
slot="details"
|
||||
.path=${mdiOpenInNew}
|
||||
></ha-svg-icon>
|
||||
</ha-list-item>
|
||||
</ha-dropdown-item>
|
||||
</a>`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.manifest
|
||||
? html`<a
|
||||
href=${this.manifest.is_built_in
|
||||
@@ -117,39 +122,31 @@ export class HaConfigFlowCard extends LitElement {
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<ha-list-item graphic="icon" hasMeta>
|
||||
<ha-dropdown-item>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.documentation"
|
||||
)}
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
slot="icon"
|
||||
.path=${mdiBookshelf}
|
||||
></ha-svg-icon>
|
||||
<ha-svg-icon
|
||||
slot="meta"
|
||||
slot="details"
|
||||
.path=${mdiOpenInNew}
|
||||
></ha-svg-icon>
|
||||
</ha-list-item>
|
||||
</ha-dropdown-item>
|
||||
</a>`
|
||||
: ""}
|
||||
: nothing}
|
||||
${attention
|
||||
? html`<ha-list-item
|
||||
class="warning"
|
||||
graphic="icon"
|
||||
@click=${this._handleDelete}
|
||||
>
|
||||
<ha-svg-icon
|
||||
class="warning"
|
||||
slot="graphic"
|
||||
.path=${mdiDelete}
|
||||
></ha-svg-icon>
|
||||
? html`<ha-dropdown-item variant="danger" value="delete">
|
||||
<ha-svg-icon slot="icon" .path=${mdiDelete}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.delete"
|
||||
)}
|
||||
</ha-list-item>`
|
||||
: ""}
|
||||
</ha-button-menu>`
|
||||
: ""}
|
||||
</ha-dropdown-item>`
|
||||
: nothing}
|
||||
</ha-dropdown>`
|
||||
: nothing}
|
||||
</ha-integration-action-card>
|
||||
`;
|
||||
}
|
||||
@@ -263,7 +260,7 @@ export class HaConfigFlowCard extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private async _handleDelete() {
|
||||
private _handleDelete = async () => {
|
||||
const entryId = this.flow.context.entry_id;
|
||||
|
||||
if (!entryId) {
|
||||
@@ -306,6 +303,14 @@ export class HaConfigFlowCard extends LitElement {
|
||||
}
|
||||
|
||||
this._handleFlowUpdated();
|
||||
};
|
||||
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
const action = ev.detail?.item?.value;
|
||||
|
||||
if (action === "delete") {
|
||||
this._handleDelete();
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
@@ -313,7 +318,7 @@ export class HaConfigFlowCard extends LitElement {
|
||||
text-decoration: none;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
ha-button-menu {
|
||||
ha-dropdown {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
ha-svg-icon[slot="meta"] {
|
||||
@@ -324,9 +329,6 @@ export class HaConfigFlowCard extends LitElement {
|
||||
--mdc-theme-primary: var(--error-color);
|
||||
--ha-card-border-color: var(--error-color);
|
||||
}
|
||||
.warning {
|
||||
--mdc-theme-text-primary-on-background: var(--error-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,10 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { cache } from "lit/directives/cache";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-expansion-panel";
|
||||
import "../../../components/ha-formfield";
|
||||
import "../../../components/ha-icon-button";
|
||||
@@ -476,9 +478,9 @@ export class HassioNetwork extends LitElement {
|
||||
<div class="address-row">
|
||||
<ha-textfield
|
||||
id="nameserver"
|
||||
.label=${this.hass.localize(
|
||||
.label=${`${this.hass.localize(
|
||||
"ui.panel.config.network.supervisor.dns_server"
|
||||
)}
|
||||
)}${this._getPredefinedDnsName(nameserver, version)}`}
|
||||
.version=${version}
|
||||
.value=${nameserver}
|
||||
.index=${index}
|
||||
@@ -500,13 +502,12 @@ export class HassioNetwork extends LitElement {
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
<ha-button-menu
|
||||
@opened=${this._handleDNSMenuOpened}
|
||||
@closed=${this._handleDNSMenuClosed}
|
||||
<ha-dropdown
|
||||
@wa-show=${this._handleDNSMenuOpened}
|
||||
@wa-hide=${this._handleDNSMenuClosed}
|
||||
.version=${version}
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
class="add-nameserver"
|
||||
appearance="filled"
|
||||
size="small"
|
||||
>
|
||||
<ha-button appearance="filled" size="small" slot="trigger">
|
||||
${this.hass.localize(
|
||||
@@ -519,27 +520,38 @@ export class HassioNetwork extends LitElement {
|
||||
</ha-button>
|
||||
${Object.entries(PREDEFINED_DNS[version]).map(
|
||||
([name, addresses]) => html`
|
||||
<ha-list-item
|
||||
@click=${this._addPredefinedDNS}
|
||||
<ha-dropdown-item
|
||||
value="add_predefined"
|
||||
.version=${version}
|
||||
.addresses=${addresses}
|
||||
>
|
||||
${name}
|
||||
</ha-list-item>
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
)}
|
||||
<ha-list-item @click=${this._addCustomDNS} .version=${version}>
|
||||
<ha-dropdown-item value="add_custom" .version=${version}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.network.supervisor.custom_dns"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
`
|
||||
: nothing}
|
||||
</ha-expansion-panel>
|
||||
`;
|
||||
}
|
||||
|
||||
private _getPredefinedDnsName(nameserver: string, version: string) {
|
||||
for (const [name, addresses] of Object.entries(
|
||||
PREDEFINED_DNS[version as "ipv4" | "ipv6"]
|
||||
)) {
|
||||
if (addresses.includes(nameserver)) {
|
||||
return ` - ${name}`;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private async _updateNetwork() {
|
||||
this._processing = true;
|
||||
let interfaceOptions: Partial<NetworkInterface> = {};
|
||||
@@ -747,10 +759,7 @@ export class HassioNetwork extends LitElement {
|
||||
this._dnsMenuOpen = false;
|
||||
}
|
||||
|
||||
private _addPredefinedDNS(ev: Event) {
|
||||
const source = ev.target as any;
|
||||
const version = source.version as "ipv4" | "ipv6";
|
||||
const addresses = source.addresses as string[];
|
||||
private _addPredefinedDNS(version: "ipv4" | "ipv6", addresses: string[]) {
|
||||
if (!this._interface![version]!.nameservers) {
|
||||
this._interface![version]!.nameservers = [];
|
||||
}
|
||||
@@ -759,9 +768,7 @@ export class HassioNetwork extends LitElement {
|
||||
this.requestUpdate("_interface");
|
||||
}
|
||||
|
||||
private _addCustomDNS(ev: Event) {
|
||||
const source = ev.target as any;
|
||||
const version = source.version as "ipv4" | "ipv6";
|
||||
private _addCustomDNS(version: "ipv4" | "ipv6") {
|
||||
if (!this._interface![version]!.nameservers) {
|
||||
this._interface![version]!.nameservers = [];
|
||||
}
|
||||
@@ -779,6 +786,22 @@ export class HassioNetwork extends LitElement {
|
||||
this.requestUpdate("_interface");
|
||||
}
|
||||
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
const action = ev.detail?.item?.value;
|
||||
|
||||
if (action === "add_predefined") {
|
||||
this._addPredefinedDNS(
|
||||
(ev.detail.item as any).version,
|
||||
(ev.detail.item as any).addresses
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === "add_custom") {
|
||||
this._addCustomDNS((ev.detail.item as any).version);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
css`
|
||||
@@ -817,6 +840,10 @@ export class HassioNetwork extends LitElement {
|
||||
--mdc-icon-button-size: 36px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
ha-dropdown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.add-address,
|
||||
.add-nameserver {
|
||||
margin-top: 16px;
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item-base";
|
||||
import "@home-assistant/webawesome/dist/components/divider/divider";
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { extractSearchParam } from "../../../common/url/search-params";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-check-list-item";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
|
||||
import type { RepairsIssue } from "../../../data/repairs";
|
||||
import {
|
||||
severitySort,
|
||||
@@ -81,40 +81,36 @@ class HaConfigRepairsDashboard extends SubscribeMixin(LitElement) {
|
||||
.header=${this.hass.localize("ui.panel.config.repairs.caption")}
|
||||
>
|
||||
<div slot="toolbar-icon">
|
||||
<ha-button-menu multi>
|
||||
<ha-dropdown @wa-select=${this._handleDropdownSelect}>
|
||||
<ha-icon-button
|
||||
slot="trigger"
|
||||
.label=${this.hass.localize("ui.common.menu")}
|
||||
.path=${mdiDotsVertical}
|
||||
></ha-icon-button>
|
||||
<ha-check-list-item
|
||||
left
|
||||
@request-selected=${this._toggleIgnored}
|
||||
.selected=${this._showIgnored}
|
||||
<ha-dropdown-item
|
||||
type="checkbox"
|
||||
value="toggle_ignored"
|
||||
.checked=${this._showIgnored}
|
||||
>
|
||||
${this.hass.localize("ui.panel.config.repairs.show_ignored")}
|
||||
</ha-check-list-item>
|
||||
<li divider role="separator"></li>
|
||||
</ha-dropdown-item>
|
||||
<wa-divider></wa-divider>
|
||||
${isComponentLoaded(this.hass, "system_health") ||
|
||||
isComponentLoaded(this.hass, "hassio")
|
||||
? html`
|
||||
<ha-list-item
|
||||
@request-selected=${this._showSystemInformationDialog}
|
||||
>
|
||||
<ha-dropdown-item value="system_information">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.repairs.system_information"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
: ""}
|
||||
<ha-list-item
|
||||
@request-selected=${this._showIntegrationStartupDialog}
|
||||
>
|
||||
: nothing}
|
||||
<ha-dropdown-item value="integration_startup_time">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.repairs.integration_startup_time"
|
||||
)}
|
||||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dropdown-item>
|
||||
</ha-dropdown>
|
||||
</div>
|
||||
<div class="content">
|
||||
<ha-card outlined>
|
||||
@@ -141,34 +137,34 @@ class HaConfigRepairsDashboard extends SubscribeMixin(LitElement) {
|
||||
`;
|
||||
}
|
||||
|
||||
private _showSystemInformationDialog(
|
||||
ev: CustomEvent<RequestSelectedDetail>
|
||||
): void {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
private _showSystemInformationDialog(): void {
|
||||
showSystemInformationDialog(this);
|
||||
}
|
||||
|
||||
private _showIntegrationStartupDialog(
|
||||
ev: CustomEvent<RequestSelectedDetail>
|
||||
): void {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
private _showIntegrationStartupDialog(): void {
|
||||
showIntegrationStartupDialog(this);
|
||||
}
|
||||
|
||||
private _toggleIgnored(ev: CustomEvent<RequestSelectedDetail>): void {
|
||||
if (ev.detail.source !== "property") {
|
||||
return;
|
||||
}
|
||||
|
||||
private _toggleIgnored(): void {
|
||||
this._showIgnored = !this._showIgnored;
|
||||
}
|
||||
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
const action = ev.detail?.item?.value;
|
||||
|
||||
switch (action) {
|
||||
case "toggle_ignored":
|
||||
this._toggleIgnored();
|
||||
break;
|
||||
case "system_information":
|
||||
this._showSystemInformationDialog();
|
||||
break;
|
||||
case "integration_startup_time":
|
||||
this._showIntegrationStartupDialog();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.content {
|
||||
padding: 28px 20px 0;
|
||||
|
||||
@@ -4,12 +4,12 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { stopPropagation } from "../../../common/dom/stop_propagation";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-dialog-header";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import type { HaDropdownItem } from "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-form/ha-form";
|
||||
import "../../../components/ha-list-item";
|
||||
import type {
|
||||
AssistPipeline,
|
||||
AssistPipelineMutableParams,
|
||||
@@ -152,22 +152,20 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement {
|
||||
this._params.hideWakeWord ||
|
||||
!this._hasWakeWorkEntities(this.hass.states)
|
||||
? nothing
|
||||
: html`<ha-button-menu
|
||||
: html`<ha-dropdown
|
||||
slot="actionItems"
|
||||
@action=${this._handleShowWakeWord}
|
||||
@closed=${stopPropagation}
|
||||
menu-corner="END"
|
||||
corner="BOTTOM_END"
|
||||
@wa-select=${this._handleDropdownSelect}
|
||||
placement="bottom-end"
|
||||
>
|
||||
<ha-icon-button
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<ha-list-item>
|
||||
<ha-dropdown-item value="show_wake_word">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.voice_assistants.assistants.pipeline.detail.add_streaming_wake_word"
|
||||
)}
|
||||
</ha-list-item></ha-button-menu
|
||||
</ha-dropdown-item></ha-dropdown
|
||||
>`}
|
||||
</ha-dialog-header>
|
||||
<div class="content">
|
||||
@@ -243,8 +241,12 @@ export class DialogVoiceAssistantPipelineDetail extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleShowWakeWord() {
|
||||
this._hideWakeWord = false;
|
||||
private _handleDropdownSelect(ev: CustomEvent<{ item: HaDropdownItem }>) {
|
||||
const action = ev.detail?.item?.value;
|
||||
|
||||
if (action === "show_wake_word") {
|
||||
this._hideWakeWord = false;
|
||||
}
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
|
||||
Reference in New Issue
Block a user