Align dashboard data table with other data tables (#27206)
* Align dashboard data table with other data tables * Update ha-config-lovelace-dashboards.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update ha-config-lovelace-dashboards.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>pull/27224/head
parent
33a0b32cc5
commit
c814b8e888
|
@ -1,8 +1,9 @@
|
|||
import {
|
||||
mdiCheck,
|
||||
mdiCheckCircleOutline,
|
||||
mdiDelete,
|
||||
mdiDotsVertical,
|
||||
mdiOpenInNew,
|
||||
mdiPencil,
|
||||
mdiPlus,
|
||||
} from "@mdi/js";
|
||||
import type { PropertyValues } from "lit";
|
||||
|
@ -20,10 +21,11 @@ import type {
|
|||
RowClickedEvent,
|
||||
SortingChangedEvent,
|
||||
} from "../../../../components/data-table/ha-data-table";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-fab";
|
||||
import "../../../../components/ha-icon";
|
||||
import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-icon-overflow-menu";
|
||||
import "../../../../components/ha-md-button-menu";
|
||||
import "../../../../components/ha-md-list-item";
|
||||
import "../../../../components/ha-svg-icon";
|
||||
|
@ -224,87 +226,94 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
: html`—`,
|
||||
};
|
||||
|
||||
columns.url_path = {
|
||||
columns.actions = {
|
||||
title: "",
|
||||
label: localize(
|
||||
"ui.panel.config.lovelace.dashboards.picker.headers.url"
|
||||
),
|
||||
filterable: true,
|
||||
label: this.hass.localize("ui.panel.config.generic.headers.actions"),
|
||||
type: "overflow-menu",
|
||||
showNarrow: true,
|
||||
template: (dashboard) =>
|
||||
narrow
|
||||
? html`
|
||||
<ha-icon-button
|
||||
.path=${mdiOpenInNew}
|
||||
.urlPath=${dashboard.url_path}
|
||||
@click=${this._navigate}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.picker.open"
|
||||
)}
|
||||
></ha-icon-button>
|
||||
`
|
||||
: html`
|
||||
<ha-button
|
||||
href="/${dashboard.url_path}"
|
||||
size="small"
|
||||
appearance="plain"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.picker.open"
|
||||
)}</ha-button
|
||||
>
|
||||
`,
|
||||
moveable: false,
|
||||
hideable: false,
|
||||
template: (dashboard) => html`
|
||||
<ha-icon-overflow-menu
|
||||
.hass=${this.hass}
|
||||
narrow
|
||||
.items=${[
|
||||
{
|
||||
path: mdiPencil,
|
||||
label: this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.picker.edit"
|
||||
),
|
||||
action: () => this._handleEdit(dashboard),
|
||||
},
|
||||
...(this._canDelete(dashboard.url_path)
|
||||
? [
|
||||
{
|
||||
label: this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.picker.delete"
|
||||
),
|
||||
path: mdiDelete,
|
||||
action: () => this._handleDelete(dashboard),
|
||||
warning: true,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
]}
|
||||
>
|
||||
</ha-icon-overflow-menu>
|
||||
`,
|
||||
};
|
||||
|
||||
return columns;
|
||||
}
|
||||
);
|
||||
|
||||
private _getItems = memoize((dashboards: LovelaceDashboard[]) => {
|
||||
const defaultMode = (
|
||||
this.hass.panels?.lovelace?.config as LovelacePanelConfig
|
||||
).mode;
|
||||
const defaultUrlPath = this.hass.defaultPanel;
|
||||
const isDefault = defaultUrlPath === "lovelace";
|
||||
const result: DataTableItem[] = [
|
||||
{
|
||||
icon: "hass:view-dashboard",
|
||||
title: this.hass.localize("panel.states"),
|
||||
default: isDefault,
|
||||
show_in_sidebar: isDefault,
|
||||
require_admin: false,
|
||||
url_path: "lovelace",
|
||||
mode: defaultMode,
|
||||
filename: defaultMode === "yaml" ? "ui-lovelace.yaml" : "",
|
||||
iconColor: "var(--primary-color)",
|
||||
},
|
||||
];
|
||||
if (isComponentLoaded(this.hass, "energy")) {
|
||||
result.push({
|
||||
icon: "hass:lightning-bolt",
|
||||
title: this.hass.localize(`ui.panel.config.dashboard.energy.main`),
|
||||
show_in_sidebar: true,
|
||||
mode: "storage",
|
||||
url_path: "energy",
|
||||
filename: "",
|
||||
iconColor: "var(--label-badge-yellow)",
|
||||
default: false,
|
||||
require_admin: false,
|
||||
});
|
||||
}
|
||||
|
||||
result.push(
|
||||
...dashboards
|
||||
.sort((a, b) =>
|
||||
stringCompare(a.title, b.title, this.hass.locale.language)
|
||||
)
|
||||
.map((dashboard) => ({
|
||||
private _getItems = memoize(
|
||||
(dashboards: LovelaceDashboard[], defaultUrlPath: string) => {
|
||||
const defaultMode = (
|
||||
this.hass.panels?.lovelace?.config as LovelacePanelConfig
|
||||
).mode;
|
||||
const isDefault = defaultUrlPath === "lovelace";
|
||||
const result: DataTableItem[] = [
|
||||
{
|
||||
icon: "hass:view-dashboard",
|
||||
title: this.hass.localize("panel.states"),
|
||||
default: isDefault,
|
||||
show_in_sidebar: isDefault,
|
||||
require_admin: false,
|
||||
url_path: "lovelace",
|
||||
mode: defaultMode,
|
||||
filename: defaultMode === "yaml" ? "ui-lovelace.yaml" : "",
|
||||
iconColor: "var(--primary-color)",
|
||||
},
|
||||
];
|
||||
if (isComponentLoaded(this.hass, "energy")) {
|
||||
result.push({
|
||||
icon: "hass:lightning-bolt",
|
||||
title: this.hass.localize(`ui.panel.config.dashboard.energy.main`),
|
||||
show_in_sidebar: true,
|
||||
mode: "storage",
|
||||
url_path: "energy",
|
||||
filename: "",
|
||||
...dashboard,
|
||||
default: defaultUrlPath === dashboard.url_path,
|
||||
}))
|
||||
);
|
||||
return result;
|
||||
});
|
||||
iconColor: "var(--label-badge-yellow)",
|
||||
default: false,
|
||||
require_admin: false,
|
||||
});
|
||||
}
|
||||
|
||||
result.push(
|
||||
...dashboards
|
||||
.sort((a, b) =>
|
||||
stringCompare(a.title, b.title, this.hass.locale.language)
|
||||
)
|
||||
.map((dashboard) => ({
|
||||
filename: "",
|
||||
...dashboard,
|
||||
default: defaultUrlPath === dashboard.url_path,
|
||||
}))
|
||||
);
|
||||
return result;
|
||||
}
|
||||
);
|
||||
|
||||
protected render() {
|
||||
if (!this.hass || this._dashboards === undefined) {
|
||||
|
@ -324,7 +333,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
this._dashboards,
|
||||
this.hass.localize
|
||||
)}
|
||||
.data=${this._getItems(this._dashboards)}
|
||||
.data=${this._getItems(this._dashboards, this.hass.defaultPanel)}
|
||||
.initialSorting=${this._activeSorting}
|
||||
.columnOrder=${this._activeColumnOrder}
|
||||
.hiddenColumns=${this._activeHiddenColumns}
|
||||
|
@ -332,7 +341,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
@sorting-changed=${this._handleSortingChanged}
|
||||
.filter=${this._filter}
|
||||
@search-changed=${this._handleSearchChange}
|
||||
@row-click=${this._editDashboard}
|
||||
@row-click=${this._handleRowClicked}
|
||||
id="url_path"
|
||||
has-fab
|
||||
clickable
|
||||
|
@ -370,13 +379,14 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
this._dashboards = await fetchDashboards(this.hass);
|
||||
}
|
||||
|
||||
private _navigate(ev: Event) {
|
||||
private _handleRowClicked(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
navigate(`/${(ev.target as any).urlPath}`);
|
||||
const urlPath = (ev.detail as RowClickedEvent).id;
|
||||
navigate(`/${urlPath}`);
|
||||
}
|
||||
|
||||
private _editDashboard(ev: CustomEvent) {
|
||||
const urlPath = (ev.detail as RowClickedEvent).id;
|
||||
private _handleEdit(item: DataTableItem) {
|
||||
const urlPath = item.url_path;
|
||||
|
||||
if (urlPath === "energy") {
|
||||
navigate("/config/energy");
|
||||
|
@ -386,6 +396,23 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
this._openDetailDialog(dashboard, urlPath);
|
||||
}
|
||||
|
||||
private _canDelete(urlPath: string) {
|
||||
if (urlPath === "lovelace" || urlPath === "energy") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private _handleDelete = async (item: DataTableItem) => {
|
||||
const dashboard = this._dashboards.find(
|
||||
(res) => res.url_path === item.url_path
|
||||
);
|
||||
if (!dashboard) {
|
||||
return;
|
||||
}
|
||||
this._deleteDashboard(dashboard);
|
||||
};
|
||||
|
||||
private async _addDashboard() {
|
||||
showNewDashboardDialog(this, {
|
||||
selectConfig: async (config) => {
|
||||
|
@ -445,33 +472,44 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||
);
|
||||
},
|
||||
removeDashboard: async () => {
|
||||
const confirm = await showConfirmationDialog(this, {
|
||||
title: this.hass!.localize(
|
||||
"ui.panel.config.lovelace.dashboards.confirm_delete_title",
|
||||
{ dashboard_title: dashboard!.title }
|
||||
),
|
||||
text: this.hass!.localize(
|
||||
"ui.panel.config.lovelace.dashboards.confirm_delete_text"
|
||||
),
|
||||
confirmText: this.hass!.localize("ui.common.delete"),
|
||||
destructive: true,
|
||||
});
|
||||
if (!confirm) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
await deleteDashboard(this.hass!, dashboard!.id);
|
||||
this._dashboards = this._dashboards!.filter(
|
||||
(res) => res !== dashboard
|
||||
);
|
||||
return true;
|
||||
} catch (_err: any) {
|
||||
if (!dashboard) {
|
||||
return false;
|
||||
}
|
||||
return this._deleteDashboard(dashboard);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async _deleteDashboard(
|
||||
dashboard: LovelaceDashboard
|
||||
): Promise<boolean> {
|
||||
if (!this._canDelete(dashboard.url_path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const confirm = await showConfirmationDialog(this, {
|
||||
title: this.hass!.localize(
|
||||
"ui.panel.config.lovelace.dashboards.confirm_delete_title",
|
||||
{ dashboard_title: dashboard.title }
|
||||
),
|
||||
text: this.hass!.localize(
|
||||
"ui.panel.config.lovelace.dashboards.confirm_delete_text"
|
||||
),
|
||||
confirmText: this.hass!.localize("ui.common.delete"),
|
||||
destructive: true,
|
||||
});
|
||||
if (!confirm) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
await deleteDashboard(this.hass!, dashboard.id);
|
||||
this._dashboards = this._dashboards.filter((res) => res !== dashboard);
|
||||
return true;
|
||||
} catch (_err: any) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private _handleSortingChanged(ev: CustomEvent) {
|
||||
this._activeSorting = ev.detail;
|
||||
}
|
||||
|
|
|
@ -3416,6 +3416,8 @@
|
|||
"url": "Open"
|
||||
},
|
||||
"open": "Open",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"add_dashboard": "Add dashboard"
|
||||
},
|
||||
"confirm_delete_title": "Delete {dashboard_title}?",
|
||||
|
|
Loading…
Reference in New Issue