mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
Implement storing sorting and grouping for all tables (#20594)
This commit is contained in:
parent
d9b71e754d
commit
62de16bb8e
@ -529,11 +529,7 @@ export class HaDataTable extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.appendRow || this.hasFab || this.groupColumn) {
|
if (this.appendRow || this.hasFab || this.groupColumn) {
|
||||||
const items = [...data];
|
let items = [...data];
|
||||||
|
|
||||||
if (this.appendRow) {
|
|
||||||
items.push({ append: true, content: this.appendRow });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.groupColumn) {
|
if (this.groupColumn) {
|
||||||
const grouped = groupBy(items, (item) => item[this.groupColumn!]);
|
const grouped = groupBy(items, (item) => item[this.groupColumn!]);
|
||||||
@ -599,14 +595,18 @@ export class HaDataTable extends LitElement {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this._items = groupedItems;
|
items = groupedItems;
|
||||||
} else {
|
}
|
||||||
this._items = items;
|
|
||||||
|
if (this.appendRow) {
|
||||||
|
items.push({ append: true, content: this.appendRow });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasFab) {
|
if (this.hasFab) {
|
||||||
this._items = [...this._items, { empty: true }];
|
items.push({ empty: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._items = items;
|
||||||
} else {
|
} else {
|
||||||
this._items = data;
|
this._items = data;
|
||||||
}
|
}
|
||||||
|
@ -37,15 +37,21 @@ import { computeCssColor } from "../../../common/color/compute-color";
|
|||||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
import { HASSDomEvent, fireEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent, fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||||
|
import {
|
||||||
|
hasRejectedItems,
|
||||||
|
rejectedItems,
|
||||||
|
} from "../../../common/util/promise-all-settled-results";
|
||||||
import "../../../components/chips/ha-assist-chip";
|
import "../../../components/chips/ha-assist-chip";
|
||||||
import type {
|
import type {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/data-table/ha-data-table-labels";
|
import "../../../components/data-table/ha-data-table-labels";
|
||||||
import "../../../components/entity/ha-entity-toggle";
|
import "../../../components/entity/ha-entity-toggle";
|
||||||
@ -105,10 +111,6 @@ import { showCategoryRegistryDetailDialog } from "../category/show-dialog-catego
|
|||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||||
import { showNewAutomationDialog } from "./show-dialog-new-automation";
|
import { showNewAutomationDialog } from "./show-dialog-new-automation";
|
||||||
import {
|
|
||||||
hasRejectedItems,
|
|
||||||
rejectedItems,
|
|
||||||
} from "../../../common/util/promise-all-settled-results";
|
|
||||||
|
|
||||||
type AutomationItem = AutomationEntity & {
|
type AutomationItem = AutomationEntity & {
|
||||||
name: string;
|
name: string;
|
||||||
@ -156,6 +158,19 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _overflowAutomation?: AutomationItem;
|
@state() private _overflowAutomation?: AutomationItem;
|
||||||
|
|
||||||
|
@storage({ key: "automation-table-sort", state: false, subscribe: false })
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({ key: "automation-table-grouping", state: false, subscribe: false })
|
||||||
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "automation-table-collapsed",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
@query("#overflow-menu") private _overflowMenu!: HaMenu;
|
@query("#overflow-menu") private _overflowMenu!: HaMenu;
|
||||||
|
|
||||||
private _sizeController = new ResizeController(this, {
|
private _sizeController = new ResizeController(this, {
|
||||||
@ -470,7 +485,12 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
this.hass.locale
|
this.hass.locale
|
||||||
)}
|
)}
|
||||||
initialGroupColumn="category"
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
.data=${automations}
|
.data=${automations}
|
||||||
.empty=${!this.automations.length}
|
.empty=${!this.automations.length}
|
||||||
@row-click=${this._handleRowClicked}
|
@row-click=${this._handleRowClicked}
|
||||||
@ -1238,6 +1258,18 @@ ${rejected
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleGroupingChanged(ev: CustomEvent) {
|
||||||
|
this._activeGrouping = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCollapseChanged(ev: CustomEvent) {
|
||||||
|
this._activeCollapsed = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -24,6 +24,7 @@ import { extractSearchParam } from "../../../common/url/search-params";
|
|||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/entity/ha-entity-toggle";
|
import "../../../components/entity/ha-entity-toggle";
|
||||||
import "../../../components/ha-button";
|
import "../../../components/ha-button";
|
||||||
@ -54,6 +55,7 @@ import { documentationUrl } from "../../../util/documentation-url";
|
|||||||
import { showToast } from "../../../util/toast";
|
import { showToast } from "../../../util/toast";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import { showAddBlueprintDialog } from "./show-dialog-import-blueprint";
|
import { showAddBlueprintDialog } from "./show-dialog-import-blueprint";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
|
|
||||||
type BlueprintMetaDataPath = BlueprintMetaData & {
|
type BlueprintMetaDataPath = BlueprintMetaData & {
|
||||||
path: string;
|
path: string;
|
||||||
@ -92,8 +94,24 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
Blueprints
|
Blueprints
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@storage({ key: "blueprint-table-sort", state: false, subscribe: false })
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({ key: "blueprint-table-grouping", state: false, subscribe: false })
|
||||||
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "blueprint-table-collapsed",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
private _processedBlueprints = memoizeOne(
|
private _processedBlueprints = memoizeOne(
|
||||||
(blueprints: Record<string, Blueprints>): BlueprintMetaDataPath[] => {
|
(
|
||||||
|
blueprints: Record<string, Blueprints>,
|
||||||
|
localize: LocalizeFunc
|
||||||
|
): BlueprintMetaDataPath[] => {
|
||||||
const result: any[] = [];
|
const result: any[] = [];
|
||||||
Object.entries(blueprints).forEach(([type, typeBlueprints]) =>
|
Object.entries(blueprints).forEach(([type, typeBlueprints]) =>
|
||||||
Object.entries(typeBlueprints).forEach(([path, blueprint]) => {
|
Object.entries(typeBlueprints).forEach(([path, blueprint]) => {
|
||||||
@ -101,6 +119,9 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
result.push({
|
result.push({
|
||||||
name: blueprint.error,
|
name: blueprint.error,
|
||||||
type,
|
type,
|
||||||
|
translated_type: localize(
|
||||||
|
`ui.panel.config.blueprint.overview.types.${type as "automation" | "script"}`
|
||||||
|
),
|
||||||
error: true,
|
error: true,
|
||||||
path,
|
path,
|
||||||
fullpath: `${type}/${path}`,
|
fullpath: `${type}/${path}`,
|
||||||
@ -109,6 +130,9 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
result.push({
|
result.push({
|
||||||
...blueprint.metadata,
|
...blueprint.metadata,
|
||||||
type,
|
type,
|
||||||
|
translated_type: localize(
|
||||||
|
`ui.panel.config.blueprint.overview.types.${type as "automation" | "script"}`
|
||||||
|
),
|
||||||
error: false,
|
error: false,
|
||||||
path,
|
path,
|
||||||
fullpath: `${type}/${path}`,
|
fullpath: `${type}/${path}`,
|
||||||
@ -140,14 +164,11 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
`
|
`
|
||||||
: undefined,
|
: undefined,
|
||||||
},
|
},
|
||||||
type: {
|
translated_type: {
|
||||||
title: localize("ui.panel.config.blueprint.overview.headers.type"),
|
title: localize("ui.panel.config.blueprint.overview.headers.type"),
|
||||||
template: (blueprint) =>
|
|
||||||
html`${this.hass.localize(
|
|
||||||
`ui.panel.config.blueprint.overview.types.${blueprint.type}`
|
|
||||||
)}`,
|
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
|
groupable: true,
|
||||||
hidden: narrow,
|
hidden: narrow,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
width: "10%",
|
width: "10%",
|
||||||
@ -256,7 +277,7 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
this.hass.language,
|
this.hass.language,
|
||||||
this.hass.localize
|
this.hass.localize
|
||||||
)}
|
)}
|
||||||
.data=${this._processedBlueprints(this.blueprints)}
|
.data=${this._processedBlueprints(this.blueprints, this.hass.localize)}
|
||||||
id="fullpath"
|
id="fullpath"
|
||||||
.noDataText=${this.hass.localize(
|
.noDataText=${this.hass.localize(
|
||||||
"ui.panel.config.blueprint.overview.no_blueprints"
|
"ui.panel.config.blueprint.overview.no_blueprints"
|
||||||
@ -281,6 +302,12 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
</div>`}
|
</div>`}
|
||||||
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
>
|
>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="toolbar-icon"
|
slot="toolbar-icon"
|
||||||
@ -341,9 +368,10 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleRowClicked(ev: HASSDomEvent<RowClickedEvent>) {
|
private _handleRowClicked(ev: HASSDomEvent<RowClickedEvent>) {
|
||||||
const blueprint = this._processedBlueprints(this.blueprints).find(
|
const blueprint = this._processedBlueprints(
|
||||||
(b) => b.fullpath === ev.detail.id
|
this.blueprints,
|
||||||
)!;
|
this.hass.localize
|
||||||
|
).find((b) => b.fullpath === ev.detail.id)!;
|
||||||
if (blueprint.error) {
|
if (blueprint.error) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: this.hass.localize("ui.panel.config.blueprint.overview.error", {
|
title: this.hass.localize("ui.panel.config.blueprint.overview.error", {
|
||||||
@ -502,6 +530,18 @@ class HaBlueprintOverview extends LitElement {
|
|||||||
fireEvent(this, "reload-blueprints");
|
fireEvent(this, "reload-blueprints");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleGroupingChanged(ev: CustomEvent) {
|
||||||
|
this._activeGrouping = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCollapseChanged(ev: CustomEvent) {
|
||||||
|
this._activeCollapsed = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return haStyle;
|
return haStyle;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import { ifDefined } from "lit/directives/if-defined";
|
|||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import memoize from "memoize-one";
|
import memoize from "memoize-one";
|
||||||
import { computeCssColor } from "../../../common/color/compute-color";
|
import { computeCssColor } from "../../../common/color/compute-color";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
@ -37,10 +38,15 @@ import {
|
|||||||
protocolIntegrationPicked,
|
protocolIntegrationPicked,
|
||||||
} from "../../../common/integrations/protocolIntegrationPicked";
|
} from "../../../common/integrations/protocolIntegrationPicked";
|
||||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||||
|
import {
|
||||||
|
hasRejectedItems,
|
||||||
|
rejectedItems,
|
||||||
|
} from "../../../common/util/promise-all-settled-results";
|
||||||
import type {
|
import type {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/data-table/ha-data-table-labels";
|
import "../../../components/data-table/ha-data-table-labels";
|
||||||
import "../../../components/ha-alert";
|
import "../../../components/ha-alert";
|
||||||
@ -66,6 +72,11 @@ import {
|
|||||||
removeEntityRegistryEntry,
|
removeEntityRegistryEntry,
|
||||||
updateEntityRegistryEntry,
|
updateEntityRegistryEntry,
|
||||||
} from "../../../data/entity_registry";
|
} from "../../../data/entity_registry";
|
||||||
|
import {
|
||||||
|
EntitySources,
|
||||||
|
fetchEntitySourcesWithCache,
|
||||||
|
} from "../../../data/entity_sources";
|
||||||
|
import { domainToName } from "../../../data/integration";
|
||||||
import {
|
import {
|
||||||
LabelRegistryEntry,
|
LabelRegistryEntry,
|
||||||
createLabelRegistryEntry,
|
createLabelRegistryEntry,
|
||||||
@ -86,15 +97,6 @@ import { configSections } from "../ha-panel-config";
|
|||||||
import "../integrations/ha-integration-overflow-menu";
|
import "../integrations/ha-integration-overflow-menu";
|
||||||
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
|
||||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||||
import {
|
|
||||||
EntitySources,
|
|
||||||
fetchEntitySourcesWithCache,
|
|
||||||
} from "../../../data/entity_sources";
|
|
||||||
import {
|
|
||||||
hasRejectedItems,
|
|
||||||
rejectedItems,
|
|
||||||
} from "../../../common/util/promise-all-settled-results";
|
|
||||||
import { domainToName } from "../../../data/integration";
|
|
||||||
|
|
||||||
export interface StateEntity
|
export interface StateEntity
|
||||||
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
||||||
@ -151,6 +153,19 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _entitySources?: EntitySources;
|
@state() private _entitySources?: EntitySources;
|
||||||
|
|
||||||
|
@storage({ key: "entities-table-sort", state: false, subscribe: false })
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({ key: "entities-table-grouping", state: false, subscribe: false })
|
||||||
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "entities-table-collapsed",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
@query("hass-tabs-subpage-data-table", true)
|
@query("hass-tabs-subpage-data-table", true)
|
||||||
private _dataTable!: HaTabsSubpageDataTable;
|
private _dataTable!: HaTabsSubpageDataTable;
|
||||||
|
|
||||||
@ -265,7 +280,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
},
|
},
|
||||||
domain: {
|
domain: {
|
||||||
title: localize("ui.panel.config.entities.picker.headers.domain"),
|
title: localize("ui.panel.config.entities.picker.headers.domain"),
|
||||||
sortable: true,
|
sortable: false,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
groupable: true,
|
groupable: true,
|
||||||
@ -603,6 +618,12 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
selectable
|
selectable
|
||||||
.selected=${this._selected.length}
|
.selected=${this._selected.length}
|
||||||
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@selection-changed=${this._handleSelectionChanged}
|
@selection-changed=${this._handleSelectionChanged}
|
||||||
clickable
|
clickable
|
||||||
@clear-filter=${this._clearFilter}
|
@clear-filter=${this._clearFilter}
|
||||||
@ -1205,6 +1226,18 @@ ${rejected
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleGroupingChanged(ev: CustomEvent) {
|
||||||
|
this._activeGrouping = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCollapseChanged(ev: CustomEvent) {
|
||||||
|
this._activeCollapsed = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { computeCssColor } from "../../../common/color/compute-color";
|
import { computeCssColor } from "../../../common/color/compute-color";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
@ -40,6 +41,7 @@ import {
|
|||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/data-table/ha-data-table-labels";
|
import "../../../components/data-table/ha-data-table-labels";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
@ -139,6 +141,19 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@property({ attribute: false }) public route!: Route;
|
@property({ attribute: false }) public route!: Route;
|
||||||
|
|
||||||
|
@storage({ key: "helpers-table-sort", state: false, subscribe: false })
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({ key: "helpers-table-grouping", state: false, subscribe: false })
|
||||||
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "helpers-table-collapsed",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
@state() private _stateItems: HassEntity[] = [];
|
@state() private _stateItems: HassEntity[] = [];
|
||||||
|
|
||||||
@state() private _entityEntries?: Record<string, EntityRegistryEntry>;
|
@state() private _entityEntries?: Record<string, EntityRegistryEntry>;
|
||||||
@ -525,7 +540,12 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
).length}
|
).length}
|
||||||
.columns=${this._columns(this.narrow, this.hass.localize)}
|
.columns=${this._columns(this.narrow, this.hass.localize)}
|
||||||
.data=${helpers}
|
.data=${helpers}
|
||||||
initialGroupColumn="category"
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
.activeFilters=${this._activeFilters}
|
.activeFilters=${this._activeFilters}
|
||||||
@clear-filter=${this._clearFilter}
|
@clear-filter=${this._clearFilter}
|
||||||
@row-click=${this._openEditDialog}
|
@row-click=${this._openEditDialog}
|
||||||
@ -1020,6 +1040,18 @@ ${rejected
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleGroupingChanged(ev: CustomEvent) {
|
||||||
|
this._activeGrouping = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCollapseChanged(ev: CustomEvent) {
|
||||||
|
this._activeCollapsed = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -10,15 +10,17 @@ import { LitElement, PropertyValues, html, nothing } from "lit";
|
|||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { computeCssColor } from "../../../common/color/compute-color";
|
import { computeCssColor } from "../../../common/color/compute-color";
|
||||||
|
import { navigate } from "../../../common/navigate";
|
||||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-relative-time";
|
|
||||||
import "../../../components/ha-icon-overflow-menu";
|
import "../../../components/ha-icon-overflow-menu";
|
||||||
|
import "../../../components/ha-relative-time";
|
||||||
import {
|
import {
|
||||||
LabelRegistryEntry,
|
LabelRegistryEntry,
|
||||||
LabelRegistryEntryMutableParams,
|
LabelRegistryEntryMutableParams,
|
||||||
@ -35,7 +37,7 @@ import "../../../layouts/hass-tabs-subpage-data-table";
|
|||||||
import { HomeAssistant, Route } from "../../../types";
|
import { HomeAssistant, Route } from "../../../types";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import { showLabelDetailDialog } from "./show-dialog-label-detail";
|
import { showLabelDetailDialog } from "./show-dialog-label-detail";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { storage } from "../../../common/decorators/storage";
|
||||||
|
|
||||||
@customElement("ha-config-labels")
|
@customElement("ha-config-labels")
|
||||||
export class HaConfigLabels extends LitElement {
|
export class HaConfigLabels extends LitElement {
|
||||||
@ -49,6 +51,13 @@ export class HaConfigLabels extends LitElement {
|
|||||||
|
|
||||||
@state() private _labels: LabelRegistryEntry[] = [];
|
@state() private _labels: LabelRegistryEntry[] = [];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "labels-table-sort",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
private _columns = memoizeOne((localize: LocalizeFunc) => {
|
private _columns = memoizeOne((localize: LocalizeFunc) => {
|
||||||
const columns: DataTableColumnContainer<LabelRegistryEntry> = {
|
const columns: DataTableColumnContainer<LabelRegistryEntry> = {
|
||||||
icon: {
|
icon: {
|
||||||
@ -149,6 +158,8 @@ export class HaConfigLabels extends LitElement {
|
|||||||
.data=${this._data(this._labels)}
|
.data=${this._data(this._labels)}
|
||||||
.noDataText=${this.hass.localize("ui.panel.config.labels.no_labels")}
|
.noDataText=${this.hass.localize("ui.panel.config.labels.no_labels")}
|
||||||
hasFab
|
hasFab
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@row-click=${this._editLabel}
|
@row-click=${this._editLabel}
|
||||||
clickable
|
clickable
|
||||||
id="label_id"
|
id="label_id"
|
||||||
@ -268,6 +279,10 @@ export class HaConfigLabels extends LitElement {
|
|||||||
`/config/automation/dashboard?historyBack=1&label=${label.label_id}`
|
`/config/automation/dashboard?historyBack=1&label=${label.label_id}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -16,6 +16,7 @@ import { stringCompare } from "../../../../common/string/compare";
|
|||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../../components/data-table/ha-data-table";
|
} from "../../../../components/data-table/ha-data-table";
|
||||||
import "../../../../components/ha-clickable-list-item";
|
import "../../../../components/ha-clickable-list-item";
|
||||||
import "../../../../components/ha-fab";
|
import "../../../../components/ha-fab";
|
||||||
@ -46,6 +47,7 @@ import { showNewDashboardDialog } from "../../dashboard/show-dialog-new-dashboar
|
|||||||
import { lovelaceTabs } from "../ha-config-lovelace";
|
import { lovelaceTabs } from "../ha-config-lovelace";
|
||||||
import { showDashboardConfigureStrategyDialog } from "./show-dialog-lovelace-dashboard-configure-strategy";
|
import { showDashboardConfigureStrategyDialog } from "./show-dialog-lovelace-dashboard-configure-strategy";
|
||||||
import { showDashboardDetailDialog } from "./show-dialog-lovelace-dashboard-detail";
|
import { showDashboardDetailDialog } from "./show-dialog-lovelace-dashboard-detail";
|
||||||
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
|
|
||||||
type DataTableItem = Pick<
|
type DataTableItem = Pick<
|
||||||
LovelaceDashboard,
|
LovelaceDashboard,
|
||||||
@ -68,6 +70,13 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
|
|
||||||
@state() private _dashboards: LovelaceDashboard[] = [];
|
@state() private _dashboards: LovelaceDashboard[] = [];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "lovelace-dashboards-table-sort",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
public willUpdate() {
|
public willUpdate() {
|
||||||
if (!this.hasUpdated) {
|
if (!this.hasUpdated) {
|
||||||
this.hass.loadFragmentTranslation("lovelace");
|
this.hass.loadFragmentTranslation("lovelace");
|
||||||
@ -293,6 +302,8 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
this.hass.localize
|
this.hass.localize
|
||||||
)}
|
)}
|
||||||
.data=${this._getItems(this._dashboards)}
|
.data=${this._getItems(this._dashboards)}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@row-click=${this._editDashboard}
|
@row-click=${this._editDashboard}
|
||||||
id="url_path"
|
id="url_path"
|
||||||
hasFab
|
hasFab
|
||||||
@ -440,6 +451,10 @@ export class HaConfigLovelaceDashboards extends LitElement {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -10,9 +10,11 @@ import {
|
|||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoize from "memoize-one";
|
import memoize from "memoize-one";
|
||||||
import { stringCompare } from "../../../../common/string/compare";
|
import { stringCompare } from "../../../../common/string/compare";
|
||||||
|
import { LocalizeFunc } from "../../../../common/translations/localize";
|
||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../../components/data-table/ha-data-table";
|
} from "../../../../components/data-table/ha-data-table";
|
||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
import "../../../../components/ha-fab";
|
import "../../../../components/ha-fab";
|
||||||
@ -33,10 +35,10 @@ import "../../../../layouts/hass-subpage";
|
|||||||
import "../../../../layouts/hass-tabs-subpage-data-table";
|
import "../../../../layouts/hass-tabs-subpage-data-table";
|
||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import { HomeAssistant, Route } from "../../../../types";
|
import { HomeAssistant, Route } from "../../../../types";
|
||||||
import { LocalizeFunc } from "../../../../common/translations/localize";
|
|
||||||
import { loadLovelaceResources } from "../../../lovelace/common/load-resources";
|
import { loadLovelaceResources } from "../../../lovelace/common/load-resources";
|
||||||
import { lovelaceResourcesTabs } from "../ha-config-lovelace";
|
import { lovelaceResourcesTabs } from "../ha-config-lovelace";
|
||||||
import { showResourceDetailDialog } from "./show-dialog-lovelace-resource-detail";
|
import { showResourceDetailDialog } from "./show-dialog-lovelace-resource-detail";
|
||||||
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
|
|
||||||
@customElement("ha-config-lovelace-resources")
|
@customElement("ha-config-lovelace-resources")
|
||||||
export class HaConfigLovelaceRescources extends LitElement {
|
export class HaConfigLovelaceRescources extends LitElement {
|
||||||
@ -50,6 +52,13 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||||||
|
|
||||||
@state() private _resources: LovelaceResource[] = [];
|
@state() private _resources: LovelaceResource[] = [];
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "lovelace-resources-table-sort",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
private _columns = memoize(
|
private _columns = memoize(
|
||||||
(
|
(
|
||||||
_language,
|
_language,
|
||||||
@ -127,6 +136,8 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||||||
.noDataText=${this.hass.localize(
|
.noDataText=${this.hass.localize(
|
||||||
"ui.panel.config.lovelace.resources.picker.no_resources"
|
"ui.panel.config.lovelace.resources.picker.no_resources"
|
||||||
)}
|
)}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@row-click=${this._editResource}
|
@row-click=${this._editResource}
|
||||||
hasFab
|
hasFab
|
||||||
clickable
|
clickable
|
||||||
@ -237,6 +248,10 @@ export class HaConfigLovelaceRescources extends LitElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -32,14 +32,20 @@ import memoizeOne from "memoize-one";
|
|||||||
import { computeCssColor } from "../../../common/color/compute-color";
|
import { computeCssColor } from "../../../common/color/compute-color";
|
||||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
import { HASSDomEvent, fireEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent, fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||||
|
import {
|
||||||
|
hasRejectedItems,
|
||||||
|
rejectedItems,
|
||||||
|
} from "../../../common/util/promise-all-settled-results";
|
||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/data-table/ha-data-table-labels";
|
import "../../../components/data-table/ha-data-table-labels";
|
||||||
import "../../../components/ha-button";
|
import "../../../components/ha-button";
|
||||||
@ -95,10 +101,6 @@ import { showAssignCategoryDialog } from "../category/show-dialog-assign-categor
|
|||||||
import { showCategoryRegistryDetailDialog } from "../category/show-dialog-category-registry-detail";
|
import { showCategoryRegistryDetailDialog } from "../category/show-dialog-category-registry-detail";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||||
import {
|
|
||||||
hasRejectedItems,
|
|
||||||
rejectedItems,
|
|
||||||
} from "../../../common/util/promise-all-settled-results";
|
|
||||||
|
|
||||||
type SceneItem = SceneEntity & {
|
type SceneItem = SceneEntity & {
|
||||||
name: string;
|
name: string;
|
||||||
@ -144,6 +146,19 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
_entityReg!: EntityRegistryEntry[];
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
|
@storage({ key: "scene-table-sort", state: false, subscribe: false })
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({ key: "scene-table-grouping", state: false, subscribe: false })
|
||||||
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "scene-table-collapsed",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
private _sizeController = new ResizeController(this, {
|
private _sizeController = new ResizeController(this, {
|
||||||
callback: (entries) => entries[0]?.contentRect.width,
|
callback: (entries) => entries[0]?.contentRect.width,
|
||||||
});
|
});
|
||||||
@ -463,7 +478,12 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
).length}
|
).length}
|
||||||
.columns=${this._columns(this.narrow, this.hass.localize)}
|
.columns=${this._columns(this.narrow, this.hass.localize)}
|
||||||
id="entity_id"
|
id="entity_id"
|
||||||
initialGroupColumn="category"
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
.data=${scenes}
|
.data=${scenes}
|
||||||
.empty=${!this.scenes.length}
|
.empty=${!this.scenes.length}
|
||||||
.activeFilters=${this._activeFilters}
|
.activeFilters=${this._activeFilters}
|
||||||
@ -975,6 +995,18 @@ ${rejected
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleGroupingChanged(ev: CustomEvent) {
|
||||||
|
this._activeGrouping = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCollapseChanged(ev: CustomEvent) {
|
||||||
|
this._activeCollapsed = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -33,14 +33,20 @@ import { computeCssColor } from "../../../common/color/compute-color";
|
|||||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||||
import { relativeTime } from "../../../common/datetime/relative_time";
|
import { relativeTime } from "../../../common/datetime/relative_time";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
import { HASSDomEvent, fireEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent, fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||||
|
import {
|
||||||
|
hasRejectedItems,
|
||||||
|
rejectedItems,
|
||||||
|
} from "../../../common/util/promise-all-settled-results";
|
||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/data-table/ha-data-table-labels";
|
import "../../../components/data-table/ha-data-table-labels";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
@ -97,10 +103,6 @@ import { showAssignCategoryDialog } from "../category/show-dialog-assign-categor
|
|||||||
import { showCategoryRegistryDetailDialog } from "../category/show-dialog-category-registry-detail";
|
import { showCategoryRegistryDetailDialog } from "../category/show-dialog-category-registry-detail";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||||
import {
|
|
||||||
hasRejectedItems,
|
|
||||||
rejectedItems,
|
|
||||||
} from "../../../common/util/promise-all-settled-results";
|
|
||||||
|
|
||||||
type ScriptItem = ScriptEntity & {
|
type ScriptItem = ScriptEntity & {
|
||||||
name: string;
|
name: string;
|
||||||
@ -148,6 +150,19 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
_entityReg!: EntityRegistryEntry[];
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
|
@storage({ key: "script-table-sort", state: false, subscribe: false })
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({ key: "script-table-grouping", state: false, subscribe: false })
|
||||||
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "script-table-collapsed",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
private _sizeController = new ResizeController(this, {
|
private _sizeController = new ResizeController(this, {
|
||||||
callback: (entries) => entries[0]?.contentRect.width,
|
callback: (entries) => entries[0]?.contentRect.width,
|
||||||
});
|
});
|
||||||
@ -462,7 +477,12 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
{ number: scripts.length }
|
{ number: scripts.length }
|
||||||
)}
|
)}
|
||||||
hasFilters
|
hasFilters
|
||||||
initialGroupColumn="category"
|
.initialGroupColumn=${this._activeGrouping || "category"}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
selectable
|
selectable
|
||||||
.selected=${this._selected.length}
|
.selected=${this._selected.length}
|
||||||
@selection-changed=${this._handleSelectionChanged}
|
@selection-changed=${this._handleSelectionChanged}
|
||||||
@ -1091,6 +1111,18 @@ ${rejected
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleGroupingChanged(ev: CustomEvent) {
|
||||||
|
this._activeGrouping = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCollapseChanged(ev: CustomEvent) {
|
||||||
|
this._activeCollapsed = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
@ -7,6 +7,7 @@ import { LocalizeFunc } from "../../../common/translations/localize";
|
|||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/data-table/ha-data-table-icon";
|
import "../../../components/data-table/ha-data-table-icon";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
@ -25,6 +26,7 @@ import { HomeAssistant, Route } from "../../../types";
|
|||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
import { showAddUserDialog } from "./show-dialog-add-user";
|
import { showAddUserDialog } from "./show-dialog-add-user";
|
||||||
import { showUserDetailDialog } from "./show-dialog-user-detail";
|
import { showUserDetailDialog } from "./show-dialog-user-detail";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
|
|
||||||
@customElement("ha-config-users")
|
@customElement("ha-config-users")
|
||||||
export class HaConfigUsers extends LitElement {
|
export class HaConfigUsers extends LitElement {
|
||||||
@ -38,6 +40,19 @@ export class HaConfigUsers extends LitElement {
|
|||||||
|
|
||||||
@state() private _users: User[] = [];
|
@state() private _users: User[] = [];
|
||||||
|
|
||||||
|
@storage({ key: "users-table-sort", state: false, subscribe: false })
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
|
@storage({ key: "users-table-grouping", state: false, subscribe: false })
|
||||||
|
private _activeGrouping?: string;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "users-table-collapsed",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeCollapsed?: string;
|
||||||
|
|
||||||
private _columns = memoizeOne(
|
private _columns = memoizeOne(
|
||||||
(narrow: boolean, localize: LocalizeFunc): DataTableColumnContainer => {
|
(narrow: boolean, localize: LocalizeFunc): DataTableColumnContainer => {
|
||||||
const columns: DataTableColumnContainer<User> = {
|
const columns: DataTableColumnContainer<User> = {
|
||||||
@ -70,16 +85,14 @@ export class HaConfigUsers extends LitElement {
|
|||||||
hidden: narrow,
|
hidden: narrow,
|
||||||
template: (user) => html`${user.username || "—"}`,
|
template: (user) => html`${user.username || "—"}`,
|
||||||
},
|
},
|
||||||
group_ids: {
|
group: {
|
||||||
title: localize("ui.panel.config.users.picker.headers.group"),
|
title: localize("ui.panel.config.users.picker.headers.group"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
|
groupable: true,
|
||||||
width: "20%",
|
width: "20%",
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
hidden: narrow,
|
hidden: narrow,
|
||||||
template: (user) => html`
|
|
||||||
${localize(`groups.${user.group_ids[0]}`)}
|
|
||||||
`,
|
|
||||||
},
|
},
|
||||||
is_active: {
|
is_active: {
|
||||||
title: this.hass.localize(
|
title: this.hass.localize(
|
||||||
@ -164,7 +177,13 @@ export class HaConfigUsers extends LitElement {
|
|||||||
backPath="/config"
|
backPath="/config"
|
||||||
.tabs=${configSections.persons}
|
.tabs=${configSections.persons}
|
||||||
.columns=${this._columns(this.narrow, this.hass.localize)}
|
.columns=${this._columns(this.narrow, this.hass.localize)}
|
||||||
.data=${this._users}
|
.data=${this._userData(this._users, this.hass.localize)}
|
||||||
|
.initialGroupColumn=${this._activeGrouping}
|
||||||
|
.initialCollapsedGroups=${this._activeCollapsed}
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
|
@grouping-changed=${this._handleGroupingChanged}
|
||||||
|
@collapsed-changed=${this._handleCollapseChanged}
|
||||||
@row-click=${this._editUser}
|
@row-click=${this._editUser}
|
||||||
hasFab
|
hasFab
|
||||||
clickable
|
clickable
|
||||||
@ -181,6 +200,13 @@ export class HaConfigUsers extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _userData = memoizeOne((users: User[], localize: LocalizeFunc) =>
|
||||||
|
users.map((user) => ({
|
||||||
|
...user,
|
||||||
|
group: localize(`groups.${user.group_ids[0]}`),
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
private async _fetchUsers() {
|
private async _fetchUsers() {
|
||||||
this._users = await fetchUsers(this.hass);
|
this._users = await fetchUsers(this.hass);
|
||||||
|
|
||||||
@ -245,6 +271,18 @@ export class HaConfigUsers extends LitElement {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleGroupingChanged(ev: CustomEvent) {
|
||||||
|
this._activeGrouping = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleCollapseChanged(ev: CustomEvent) {
|
||||||
|
this._activeCollapsed = ev.detail.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
DataTableRowData,
|
DataTableRowData,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
SelectionChangedEvent,
|
SelectionChangedEvent,
|
||||||
|
SortingChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
import { AlexaEntity, fetchCloudAlexaEntities } from "../../../data/alexa";
|
import { AlexaEntity, fetchCloudAlexaEntities } from "../../../data/alexa";
|
||||||
@ -52,6 +53,7 @@ import "./expose/expose-assistant-icon";
|
|||||||
import { voiceAssistantTabs } from "./ha-config-voice-assistants";
|
import { voiceAssistantTabs } from "./ha-config-voice-assistants";
|
||||||
import { showExposeEntityDialog } from "./show-dialog-expose-entity";
|
import { showExposeEntityDialog } from "./show-dialog-expose-entity";
|
||||||
import { showVoiceSettingsDialog } from "./show-dialog-voice-settings";
|
import { showVoiceSettingsDialog } from "./show-dialog-voice-settings";
|
||||||
|
import { storage } from "../../../common/decorators/storage";
|
||||||
|
|
||||||
@customElement("ha-config-voice-assistants-expose")
|
@customElement("ha-config-voice-assistants-expose")
|
||||||
export class VoiceAssistantsExpose extends LitElement {
|
export class VoiceAssistantsExpose extends LitElement {
|
||||||
@ -87,6 +89,13 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
string[] | undefined
|
string[] | undefined
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@storage({
|
||||||
|
key: "voice-expose-table-sort",
|
||||||
|
state: false,
|
||||||
|
subscribe: false,
|
||||||
|
})
|
||||||
|
private _activeSorting?: SortingChangedEvent;
|
||||||
|
|
||||||
@query("hass-tabs-subpage-data-table", true)
|
@query("hass-tabs-subpage-data-table", true)
|
||||||
private _dataTable!: HaTabsSubpageDataTable;
|
private _dataTable!: HaTabsSubpageDataTable;
|
||||||
|
|
||||||
@ -505,6 +514,8 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
selectable
|
selectable
|
||||||
.selected=${this._selectedEntities.length}
|
.selected=${this._selectedEntities.length}
|
||||||
clickable
|
clickable
|
||||||
|
.initialSorting=${this._activeSorting}
|
||||||
|
@sorting-changed=${this._handleSortingChanged}
|
||||||
@selection-changed=${this._handleSelectionChanged}
|
@selection-changed=${this._handleSelectionChanged}
|
||||||
@clear-filter=${this._clearFilter}
|
@clear-filter=${this._clearFilter}
|
||||||
@search-changed=${this._handleSearchChange}
|
@search-changed=${this._handleSearchChange}
|
||||||
@ -696,6 +707,10 @@ export class VoiceAssistantsExpose extends LitElement {
|
|||||||
navigate(window.location.pathname, { replace: true });
|
navigate(window.location.pathname, { replace: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSortingChanged(ev: CustomEvent) {
|
||||||
|
this._activeSorting = ev.detail;
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
haStyle,
|
haStyle,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user