mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Save data table filters in session storage (#20894)
* Save data table filters in session storage * typing fix * remove url logic, rename storage key
This commit is contained in:
parent
91e5fcacd5
commit
2921161336
@ -108,6 +108,8 @@ export const storage =
|
|||||||
subscribe?: boolean;
|
subscribe?: boolean;
|
||||||
state?: boolean;
|
state?: boolean;
|
||||||
stateOptions?: InternalPropertyDeclaration;
|
stateOptions?: InternalPropertyDeclaration;
|
||||||
|
serializer?: (value: any) => any;
|
||||||
|
deserializer?: (value: any) => any;
|
||||||
}): any =>
|
}): any =>
|
||||||
(clsElement: ClassElement) => {
|
(clsElement: ClassElement) => {
|
||||||
const storageName = options.storage || "localStorage";
|
const storageName = options.storage || "localStorage";
|
||||||
@ -141,7 +143,9 @@ export const storage =
|
|||||||
|
|
||||||
const getValue = (): any =>
|
const getValue = (): any =>
|
||||||
storageInstance.hasKey(storageKey!)
|
storageInstance.hasKey(storageKey!)
|
||||||
? storageInstance.getValue(storageKey!)
|
? options.deserializer
|
||||||
|
? options.deserializer(storageInstance.getValue(storageKey!))
|
||||||
|
: storageInstance.getValue(storageKey!)
|
||||||
: initVal;
|
: initVal;
|
||||||
|
|
||||||
const setValue = (el: ReactiveElement, value: any) => {
|
const setValue = (el: ReactiveElement, value: any) => {
|
||||||
@ -149,7 +153,10 @@ export const storage =
|
|||||||
if (options.state) {
|
if (options.state) {
|
||||||
oldValue = getValue();
|
oldValue = getValue();
|
||||||
}
|
}
|
||||||
storageInstance.setValue(storageKey!, value);
|
storageInstance.setValue(
|
||||||
|
storageKey!,
|
||||||
|
options.serializer ? options.serializer(value) : value
|
||||||
|
);
|
||||||
if (options.state) {
|
if (options.state) {
|
||||||
el.requestUpdate(clsElement.key, oldValue);
|
el.requestUpdate(clsElement.key, oldValue);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ declare global {
|
|||||||
|
|
||||||
export interface NavigateOptions {
|
export interface NavigateOptions {
|
||||||
replace?: boolean;
|
replace?: boolean;
|
||||||
|
data?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const navigate = (path: string, options?: NavigateOptions) => {
|
export const navigate = (path: string, options?: NavigateOptions) => {
|
||||||
@ -24,7 +25,7 @@ export const navigate = (path: string, options?: NavigateOptions) => {
|
|||||||
if (__DEMO__) {
|
if (__DEMO__) {
|
||||||
if (replace) {
|
if (replace) {
|
||||||
mainWindow.history.replaceState(
|
mainWindow.history.replaceState(
|
||||||
mainWindow.history.state?.root ? { root: true } : null,
|
mainWindow.history.state?.root ? { root: true } : options?.data ?? null,
|
||||||
"",
|
"",
|
||||||
`${mainWindow.location.pathname}#${path}`
|
`${mainWindow.location.pathname}#${path}`
|
||||||
);
|
);
|
||||||
@ -33,12 +34,12 @@ export const navigate = (path: string, options?: NavigateOptions) => {
|
|||||||
}
|
}
|
||||||
} else if (replace) {
|
} else if (replace) {
|
||||||
mainWindow.history.replaceState(
|
mainWindow.history.replaceState(
|
||||||
mainWindow.history.state?.root ? { root: true } : null,
|
mainWindow.history.state?.root ? { root: true } : options?.data ?? null,
|
||||||
"",
|
"",
|
||||||
path
|
path
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
mainWindow.history.pushState(null, "", path);
|
mainWindow.history.pushState(options?.data ?? null, "", path);
|
||||||
}
|
}
|
||||||
fireEvent(mainWindow, "location-changed", {
|
fireEvent(mainWindow, "location-changed", {
|
||||||
replace,
|
replace,
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
import { SelectedDetail } from "@material/mwc-list";
|
import { SelectedDetail } from "@material/mwc-list";
|
||||||
import "@material/mwc-menu/mwc-menu-surface";
|
import "@material/mwc-menu/mwc-menu-surface";
|
||||||
import { mdiFilterVariantRemove } from "@mdi/js";
|
import { mdiFilterVariantRemove } from "@mdi/js";
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import {
|
||||||
|
css,
|
||||||
|
CSSResultGroup,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
nothing,
|
||||||
|
PropertyValues,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { Blueprints, fetchBlueprints } from "../data/blueprint";
|
import { Blueprints, fetchBlueprints } from "../data/blueprint";
|
||||||
@ -25,6 +32,16 @@ export class HaFilterBlueprints extends LitElement {
|
|||||||
|
|
||||||
@state() private _blueprints?: Blueprints;
|
@state() private _blueprints?: Blueprints;
|
||||||
|
|
||||||
|
public willUpdate(properties: PropertyValues) {
|
||||||
|
super.willUpdate(properties);
|
||||||
|
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
if (this.value?.length) {
|
||||||
|
this._findRelated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
<ha-expansion-panel
|
<ha-expansion-panel
|
||||||
@ -96,7 +113,6 @@ export class HaFilterBlueprints extends LitElement {
|
|||||||
ev: CustomEvent<SelectedDetail<Set<number>>>
|
ev: CustomEvent<SelectedDetail<Set<number>>>
|
||||||
) {
|
) {
|
||||||
const blueprints = this._blueprints!;
|
const blueprints = this._blueprints!;
|
||||||
const relatedPromises: Promise<RelatedResult>[] = [];
|
|
||||||
|
|
||||||
if (!ev.detail.index.size) {
|
if (!ev.detail.index.size) {
|
||||||
fireEvent(this, "data-table-filter-changed", {
|
fireEvent(this, "data-table-filter-changed", {
|
||||||
@ -112,13 +128,33 @@ export class HaFilterBlueprints extends LitElement {
|
|||||||
for (const index of ev.detail.index) {
|
for (const index of ev.detail.index) {
|
||||||
const blueprintId = Object.keys(blueprints)[index];
|
const blueprintId = Object.keys(blueprints)[index];
|
||||||
value.push(blueprintId);
|
value.push(blueprintId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value = value;
|
||||||
|
|
||||||
|
this._findRelated();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _findRelated() {
|
||||||
|
if (!this.value?.length) {
|
||||||
|
fireEvent(this, "data-table-filter-changed", {
|
||||||
|
value: [],
|
||||||
|
items: undefined,
|
||||||
|
});
|
||||||
|
this.value = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const relatedPromises: Promise<RelatedResult>[] = [];
|
||||||
|
|
||||||
|
for (const blueprintId of this.value) {
|
||||||
if (this.type) {
|
if (this.type) {
|
||||||
relatedPromises.push(
|
relatedPromises.push(
|
||||||
findRelated(this.hass, `${this.type}_blueprint`, blueprintId)
|
findRelated(this.hass, `${this.type}_blueprint`, blueprintId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.value = value;
|
|
||||||
const results = await Promise.all(relatedPromises);
|
const results = await Promise.all(relatedPromises);
|
||||||
const items: Set<string> = new Set();
|
const items: Set<string> = new Set();
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
@ -128,7 +164,7 @@ export class HaFilterBlueprints extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fireEvent(this, "data-table-filter-changed", {
|
fireEvent(this, "data-table-filter-changed", {
|
||||||
value,
|
value: this.value,
|
||||||
items: this.type ? items : undefined,
|
items: this.type ? items : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,9 @@ export class HaFilterDevices extends LitElement {
|
|||||||
|
|
||||||
if (!this.hasUpdated) {
|
if (!this.hasUpdated) {
|
||||||
loadVirtualizer();
|
loadVirtualizer();
|
||||||
|
if (this.value?.length) {
|
||||||
|
this._findRelated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,9 @@ export class HaFilterEntities extends LitElement {
|
|||||||
|
|
||||||
if (!this.hasUpdated) {
|
if (!this.hasUpdated) {
|
||||||
loadVirtualizer();
|
loadVirtualizer();
|
||||||
|
if (this.value?.length) {
|
||||||
|
this._findRelated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,15 +189,12 @@ export class HaFilterEntities extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const value: string[] = [];
|
|
||||||
|
|
||||||
for (const entityId of this.value) {
|
for (const entityId of this.value) {
|
||||||
value.push(entityId);
|
|
||||||
if (this.type) {
|
if (this.type) {
|
||||||
relatedPromises.push(findRelated(this.hass, "entity", entityId));
|
relatedPromises.push(findRelated(this.hass, "entity", entityId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.value = value;
|
|
||||||
const results = await Promise.all(relatedPromises);
|
const results = await Promise.all(relatedPromises);
|
||||||
const items: Set<string> = new Set();
|
const items: Set<string> = new Set();
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
@ -204,7 +204,7 @@ export class HaFilterEntities extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fireEvent(this, "data-table-filter-changed", {
|
fireEvent(this, "data-table-filter-changed", {
|
||||||
value,
|
value: this.value,
|
||||||
items: this.type ? items : undefined,
|
items: this.type ? items : undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
import "@material/mwc-menu/mwc-menu-surface";
|
import "@material/mwc-menu/mwc-menu-surface";
|
||||||
import { mdiFilterVariantRemove, mdiTextureBox } from "@mdi/js";
|
import { mdiFilterVariantRemove, mdiTextureBox } from "@mdi/js";
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
|
import {
|
||||||
|
CSSResultGroup,
|
||||||
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
|
css,
|
||||||
|
html,
|
||||||
|
nothing,
|
||||||
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { repeat } from "lit/directives/repeat";
|
import { repeat } from "lit/directives/repeat";
|
||||||
@ -42,6 +49,16 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _floors?: FloorRegistryEntry[];
|
@state() private _floors?: FloorRegistryEntry[];
|
||||||
|
|
||||||
|
public willUpdate(properties: PropertyValues) {
|
||||||
|
super.willUpdate(properties);
|
||||||
|
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
if (this.value?.floors?.length || this.value?.areas?.length) {
|
||||||
|
this._findRelated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const areas = this._areas(this.hass.areas, this._floors);
|
const areas = this._areas(this.hass.areas, this._floors);
|
||||||
|
|
||||||
@ -190,6 +207,10 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected firstUpdated() {
|
||||||
|
this._findRelated();
|
||||||
|
}
|
||||||
|
|
||||||
private _expandedWillChange(ev) {
|
private _expandedWillChange(ev) {
|
||||||
this._shouldRender = ev.detail.expanded;
|
this._shouldRender = ev.detail.expanded;
|
||||||
}
|
}
|
||||||
|
28
src/data/data_table_filters.ts
Normal file
28
src/data/data_table_filters.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export interface DataTableFilters {
|
||||||
|
[key: string]: {
|
||||||
|
value: string[] | { key: string[] } | undefined;
|
||||||
|
items: Set<string> | undefined;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const serializeFilters = (value: DataTableFilters) => {
|
||||||
|
const serializedValue = {};
|
||||||
|
Object.entries(value).forEach(([key, val]) => {
|
||||||
|
serializedValue[key] = {
|
||||||
|
value: val.value,
|
||||||
|
items: val.items instanceof Set ? Array.from(val.items) : val.items,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return serializedValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const deserializeFilters = (value: DataTableFilters) => {
|
||||||
|
const deserializedValue = {};
|
||||||
|
Object.entries(value).forEach(([key, val]) => {
|
||||||
|
deserializedValue[key] = {
|
||||||
|
value: val.value,
|
||||||
|
items: Array.isArray(val.items) ? new Set(val.items) : val.items,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return deserializedValue;
|
||||||
|
};
|
@ -114,6 +114,11 @@ 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 {
|
||||||
|
DataTableFilters,
|
||||||
|
deserializeFilters,
|
||||||
|
serializeFilters,
|
||||||
|
} from "../../../data/data_table_filters";
|
||||||
|
|
||||||
type AutomationItem = AutomationEntity & {
|
type AutomationItem = AutomationEntity & {
|
||||||
name: string;
|
name: string;
|
||||||
@ -140,10 +145,15 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _filteredAutomations?: string[] | null;
|
@state() private _filteredAutomations?: string[] | null;
|
||||||
|
|
||||||
@state() private _filters: Record<
|
@storage({
|
||||||
string,
|
storage: "sessionStorage",
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
key: "automation-table-filters-full",
|
||||||
> = {};
|
state: true,
|
||||||
|
subscribe: false,
|
||||||
|
serializer: serializeFilters,
|
||||||
|
deserializer: deserializeFilters,
|
||||||
|
})
|
||||||
|
private _filters: DataTableFilters = {};
|
||||||
|
|
||||||
@state() private _expandedFilter?: string;
|
@state() private _expandedFilter?: string;
|
||||||
|
|
||||||
@ -916,7 +926,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private _filterChanged(ev) {
|
private _filterChanged(ev) {
|
||||||
const type = ev.target.localName;
|
const type = ev.target.localName;
|
||||||
this._filters[type] = ev.detail;
|
this._filters = { ...this._filters, [type]: ev.detail };
|
||||||
this._applyFilters();
|
this._applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,7 +945,11 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(filter.items)
|
items.intersection(filter.items)
|
||||||
: new Set([...items].filter((x) => filter.items!.has(x)));
|
: new Set([...items].filter((x) => filter.items!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-categories" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-categories" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const categoryItems: Set<string> = new Set();
|
const categoryItems: Set<string> = new Set();
|
||||||
this.automations
|
this.automations
|
||||||
.filter(
|
.filter(
|
||||||
@ -956,13 +970,17 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(categoryItems)
|
items.intersection(categoryItems)
|
||||||
: new Set([...items].filter((x) => categoryItems!.has(x)));
|
: new Set([...items].filter((x) => categoryItems!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-labels" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-labels" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const labelItems: Set<string> = new Set();
|
const labelItems: Set<string> = new Set();
|
||||||
this.automations
|
this.automations
|
||||||
.filter((automation) =>
|
.filter((automation) =>
|
||||||
this._entityReg
|
this._entityReg
|
||||||
.find((reg) => reg.entity_id === automation.entity_id)
|
.find((reg) => reg.entity_id === automation.entity_id)
|
||||||
?.labels.some((lbl) => filter.value!.includes(lbl))
|
?.labels.some((lbl) => (filter.value as string[]).includes(lbl))
|
||||||
)
|
)
|
||||||
.forEach((automation) => labelItems.add(automation.entity_id));
|
.forEach((automation) => labelItems.add(automation.entity_id));
|
||||||
if (!items) {
|
if (!items) {
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
LitElement,
|
LitElement,
|
||||||
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
css,
|
css,
|
||||||
html,
|
html,
|
||||||
@ -85,6 +86,11 @@ 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 { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||||
|
import {
|
||||||
|
serializeFilters,
|
||||||
|
deserializeFilters,
|
||||||
|
DataTableFilters,
|
||||||
|
} from "../../../data/data_table_filters";
|
||||||
|
|
||||||
interface DeviceRowData extends DeviceRegistryEntry {
|
interface DeviceRowData extends DeviceRegistryEntry {
|
||||||
device?: DeviceRowData;
|
device?: DeviceRowData;
|
||||||
@ -118,10 +124,15 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _filter: string = history.state?.filter || "";
|
@state() private _filter: string = history.state?.filter || "";
|
||||||
|
|
||||||
@state() private _filters: Record<
|
@storage({
|
||||||
string,
|
storage: "sessionStorage",
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
key: "devices-table-filters-full",
|
||||||
> = {};
|
state: true,
|
||||||
|
subscribe: false,
|
||||||
|
serializer: serializeFilters,
|
||||||
|
deserializer: deserializeFilters,
|
||||||
|
})
|
||||||
|
private _filters: DataTableFilters = {};
|
||||||
|
|
||||||
@state() private _expandedFilter?: string;
|
@state() private _expandedFilter?: string;
|
||||||
|
|
||||||
@ -180,15 +191,12 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
firstUpdated() {
|
willUpdate(changedProps: PropertyValues) {
|
||||||
this._filters = {
|
super.willUpdate(changedProps);
|
||||||
"ha-filter-states": {
|
if (!this.hasUpdated) {
|
||||||
value: [],
|
|
||||||
items: undefined,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
this._setFiltersFromUrl();
|
this._setFiltersFromUrl();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _setFiltersFromUrl() {
|
private _setFiltersFromUrl() {
|
||||||
if (this._searchParms.has("domain")) {
|
if (this._searchParms.has("domain")) {
|
||||||
@ -196,7 +204,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
...this._filters,
|
...this._filters,
|
||||||
"ha-filter-states": {
|
"ha-filter-states": {
|
||||||
value: [
|
value: [
|
||||||
...(this._filters["ha-filter-states"]?.value || []),
|
...((this._filters["ha-filter-states"]?.value as string[]) || []),
|
||||||
"disabled",
|
"disabled",
|
||||||
],
|
],
|
||||||
items: undefined,
|
items: undefined,
|
||||||
@ -212,7 +220,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
...this._filters,
|
...this._filters,
|
||||||
"ha-filter-states": {
|
"ha-filter-states": {
|
||||||
value: [
|
value: [
|
||||||
...(this._filters["ha-filter-states"]?.value || []),
|
...((this._filters["ha-filter-states"]?.value as string[]) || []),
|
||||||
"disabled",
|
"disabled",
|
||||||
],
|
],
|
||||||
items: undefined,
|
items: undefined,
|
||||||
@ -253,10 +261,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
entities: EntityRegistryEntry[],
|
entities: EntityRegistryEntry[],
|
||||||
areas: HomeAssistant["areas"],
|
areas: HomeAssistant["areas"],
|
||||||
manifests: IntegrationManifest[],
|
manifests: IntegrationManifest[],
|
||||||
filters: Record<
|
filters: DataTableFilters,
|
||||||
string,
|
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
|
||||||
>,
|
|
||||||
localize: LocalizeFunc,
|
localize: LocalizeFunc,
|
||||||
labelReg?: LabelRegistryEntry[]
|
labelReg?: LabelRegistryEntry[]
|
||||||
) => {
|
) => {
|
||||||
@ -295,15 +300,21 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
const filteredDomains = new Set<string>();
|
const filteredDomains = new Set<string>();
|
||||||
|
|
||||||
Object.entries(filters).forEach(([key, filter]) => {
|
Object.entries(filters).forEach(([key, filter]) => {
|
||||||
if (key === "config_entry" && filter.value?.length) {
|
if (
|
||||||
|
key === "config_entry" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
outputDevices = outputDevices.filter((device) =>
|
outputDevices = outputDevices.filter((device) =>
|
||||||
device.config_entries.some((entryId) =>
|
device.config_entries.some((entryId) =>
|
||||||
filter.value?.includes(entryId)
|
(filter.value as string[]).includes(entryId)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const configEntries = entries.filter(
|
const configEntries = entries.filter(
|
||||||
(entry) => entry.entry_id && filter.value?.includes(entry.entry_id)
|
(entry) =>
|
||||||
|
entry.entry_id &&
|
||||||
|
(filter.value as string[]).includes(entry.entry_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
configEntries.forEach((configEntry) => {
|
configEntries.forEach((configEntry) => {
|
||||||
@ -312,17 +323,31 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
if (configEntries.length === 1) {
|
if (configEntries.length === 1) {
|
||||||
filteredConfigEntry = configEntries[0];
|
filteredConfigEntry = configEntries[0];
|
||||||
}
|
}
|
||||||
} else if (key === "ha-filter-integrations" && filter.value?.length) {
|
} else if (
|
||||||
|
key === "ha-filter-integrations" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const entryIds = entries
|
const entryIds = entries
|
||||||
.filter((entry) => filter.value!.includes(entry.domain))
|
.filter((entry) =>
|
||||||
|
(filter.value as string[]).includes(entry.domain)
|
||||||
|
)
|
||||||
.map((entry) => entry.entry_id);
|
.map((entry) => entry.entry_id);
|
||||||
outputDevices = outputDevices.filter((device) =>
|
outputDevices = outputDevices.filter((device) =>
|
||||||
device.config_entries.some((entryId) => entryIds.includes(entryId))
|
device.config_entries.some((entryId) => entryIds.includes(entryId))
|
||||||
);
|
);
|
||||||
filter.value!.forEach((domain) => filteredDomains.add(domain));
|
(filter.value as string[]).forEach((domain) =>
|
||||||
} else if (key === "ha-filter-labels" && filter.value?.length) {
|
filteredDomains.add(domain)
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
key === "ha-filter-labels" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
outputDevices = outputDevices.filter((device) =>
|
outputDevices = outputDevices.filter((device) =>
|
||||||
device.labels.some((lbl) => filter.value!.includes(lbl))
|
device.labels.some((lbl) =>
|
||||||
|
(filter.value as string[]).includes(lbl)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} else if (filter.items) {
|
} else if (filter.items) {
|
||||||
outputDevices = outputDevices.filter((device) =>
|
outputDevices = outputDevices.filter((device) =>
|
||||||
@ -331,7 +356,9 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const stateFilters = filters["ha-filter-states"]?.value;
|
const stateFilters = filters["ha-filter-states"]?.value as
|
||||||
|
| string[]
|
||||||
|
| undefined;
|
||||||
|
|
||||||
const showDisabled =
|
const showDisabled =
|
||||||
stateFilters?.length && stateFilters.includes("disabled");
|
stateFilters?.length && stateFilters.includes("disabled");
|
||||||
@ -698,7 +725,8 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
>
|
>
|
||||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||||
</ha-fab>
|
</ha-fab>
|
||||||
${this._filters.config_entry?.value?.length
|
${Array.isArray(this._filters.config_entry?.value) &&
|
||||||
|
this._filters.config_entry?.value.length
|
||||||
? html`<ha-alert slot="filter-pane">
|
? html`<ha-alert slot="filter-pane">
|
||||||
Filtering by config entry
|
Filtering by config entry
|
||||||
${this.entries?.find(
|
${this.entries?.find(
|
||||||
|
@ -98,6 +98,11 @@ 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 {
|
||||||
|
serializeFilters,
|
||||||
|
deserializeFilters,
|
||||||
|
DataTableFilters,
|
||||||
|
} from "../../../data/data_table_filters";
|
||||||
|
|
||||||
export interface StateEntity
|
export interface StateEntity
|
||||||
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
|
||||||
@ -143,10 +148,15 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _searchParms = new URLSearchParams(window.location.search);
|
@state() private _searchParms = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
@state() private _filters: Record<
|
@storage({
|
||||||
string,
|
storage: "sessionStorage",
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
key: "entities-table-filters-full",
|
||||||
> = {};
|
state: true,
|
||||||
|
subscribe: false,
|
||||||
|
serializer: serializeFilters,
|
||||||
|
deserializer: deserializeFilters,
|
||||||
|
})
|
||||||
|
private _filters: DataTableFilters = {};
|
||||||
|
|
||||||
@state() private _selected: string[] = [];
|
@state() private _selected: string[] = [];
|
||||||
|
|
||||||
@ -414,16 +424,13 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
devices: HomeAssistant["devices"],
|
devices: HomeAssistant["devices"],
|
||||||
areas: HomeAssistant["areas"],
|
areas: HomeAssistant["areas"],
|
||||||
stateEntities: StateEntity[],
|
stateEntities: StateEntity[],
|
||||||
filters: Record<
|
filters: DataTableFilters,
|
||||||
string,
|
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
|
||||||
>,
|
|
||||||
entries?: ConfigEntry[],
|
entries?: ConfigEntry[],
|
||||||
labelReg?: LabelRegistryEntry[]
|
labelReg?: LabelRegistryEntry[]
|
||||||
) => {
|
) => {
|
||||||
const result: EntityRow[] = [];
|
const result: EntityRow[] = [];
|
||||||
|
|
||||||
const stateFilters = filters["ha-filter-states"]?.value;
|
const stateFilters = filters["ha-filter-states"]?.value as string[];
|
||||||
|
|
||||||
const showEnabled =
|
const showEnabled =
|
||||||
!stateFilters?.length || stateFilters.includes("enabled");
|
!stateFilters?.length || stateFilters.includes("enabled");
|
||||||
@ -448,11 +455,15 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
const filteredDomains = new Set<string>();
|
const filteredDomains = new Set<string>();
|
||||||
|
|
||||||
Object.entries(filters).forEach(([key, filter]) => {
|
Object.entries(filters).forEach(([key, filter]) => {
|
||||||
if (key === "config_entry" && filter.value?.length) {
|
if (
|
||||||
|
key === "config_entry" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
filteredEntities = filteredEntities.filter(
|
filteredEntities = filteredEntities.filter(
|
||||||
(entity) =>
|
(entity) =>
|
||||||
entity.config_entry_id &&
|
entity.config_entry_id &&
|
||||||
filter.value?.includes(entity.config_entry_id)
|
(filter.value as string[]).includes(entity.config_entry_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!entries) {
|
if (!entries) {
|
||||||
@ -461,7 +472,9 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const configEntries = entries.filter(
|
const configEntries = entries.filter(
|
||||||
(entry) => entry.entry_id && filter.value?.includes(entry.entry_id)
|
(entry) =>
|
||||||
|
entry.entry_id &&
|
||||||
|
(filter.value as string[]).includes(entry.entry_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
configEntries.forEach((configEntry) => {
|
configEntries.forEach((configEntry) => {
|
||||||
@ -470,29 +483,45 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
|||||||
if (configEntries.length === 1) {
|
if (configEntries.length === 1) {
|
||||||
filteredConfigEntry = configEntries[0];
|
filteredConfigEntry = configEntries[0];
|
||||||
}
|
}
|
||||||
} else if (key === "ha-filter-integrations" && filter.value?.length) {
|
} else if (
|
||||||
|
key === "ha-filter-integrations" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
if (!entries) {
|
if (!entries) {
|
||||||
this._loadConfigEntries();
|
this._loadConfigEntries();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const entryIds = entries
|
const entryIds = entries
|
||||||
.filter((entry) => filter.value!.includes(entry.domain))
|
.filter((entry) =>
|
||||||
|
(filter.value as string[]).includes(entry.domain)
|
||||||
|
)
|
||||||
.map((entry) => entry.entry_id);
|
.map((entry) => entry.entry_id);
|
||||||
|
|
||||||
filteredEntities = filteredEntities.filter(
|
filteredEntities = filteredEntities.filter(
|
||||||
(entity) =>
|
(entity) =>
|
||||||
filter.value?.includes(entity.platform) ||
|
(filter.value as string[]).includes(entity.platform) ||
|
||||||
(entity.config_entry_id &&
|
(entity.config_entry_id &&
|
||||||
entryIds.includes(entity.config_entry_id))
|
entryIds.includes(entity.config_entry_id))
|
||||||
);
|
);
|
||||||
filter.value!.forEach((domain) => filteredDomains.add(domain));
|
filter.value!.forEach((domain) => filteredDomains.add(domain));
|
||||||
} else if (key === "ha-filter-domains" && filter.value?.length) {
|
} else if (
|
||||||
|
key === "ha-filter-domains" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
filteredEntities = filteredEntities.filter((entity) =>
|
filteredEntities = filteredEntities.filter((entity) =>
|
||||||
filter.value?.includes(computeDomain(entity.entity_id))
|
(filter.value as string[]).includes(computeDomain(entity.entity_id))
|
||||||
);
|
);
|
||||||
} else if (key === "ha-filter-labels" && filter.value?.length) {
|
} else if (
|
||||||
|
key === "ha-filter-labels" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
filteredEntities = filteredEntities.filter((entity) =>
|
filteredEntities = filteredEntities.filter((entity) =>
|
||||||
entity.labels.some((lbl) => filter.value!.includes(lbl))
|
entity.labels.some((lbl) =>
|
||||||
|
(filter.value as string[]).includes(lbl)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} else if (filter.items) {
|
} else if (filter.items) {
|
||||||
filteredEntities = filteredEntities.filter((entity) =>
|
filteredEntities = filteredEntities.filter((entity) =>
|
||||||
@ -811,7 +840,8 @@ ${
|
|||||||
|
|
||||||
</ha-button-menu-new>
|
</ha-button-menu-new>
|
||||||
${
|
${
|
||||||
this._filters.config_entry?.value?.length
|
Array.isArray(this._filters.config_entry?.value) &&
|
||||||
|
this._filters.config_entry?.value.length
|
||||||
? html`<ha-alert slot="filter-pane">
|
? html`<ha-alert slot="filter-pane">
|
||||||
Filtering by config entry
|
Filtering by config entry
|
||||||
${this._entries?.find(
|
${this._entries?.find(
|
||||||
@ -913,6 +943,9 @@ ${
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected firstUpdated() {
|
protected firstUpdated() {
|
||||||
|
if (Object.keys(this._filters).length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._filters = {
|
this._filters = {
|
||||||
"ha-filter-states": {
|
"ha-filter-states": {
|
||||||
value: ["enabled"],
|
value: ["enabled"],
|
||||||
|
@ -96,6 +96,11 @@ import "../integrations/ha-integration-overflow-menu";
|
|||||||
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
import { showLabelDetailDialog } from "../labels/show-dialog-label-detail";
|
||||||
import { isHelperDomain } from "./const";
|
import { isHelperDomain } from "./const";
|
||||||
import { showHelperDetailDialog } from "./show-dialog-helper-detail";
|
import { showHelperDetailDialog } from "./show-dialog-helper-detail";
|
||||||
|
import {
|
||||||
|
serializeFilters,
|
||||||
|
deserializeFilters,
|
||||||
|
DataTableFilters,
|
||||||
|
} from "../../../data/data_table_filters";
|
||||||
|
|
||||||
type HelperItem = {
|
type HelperItem = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -164,10 +169,15 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _activeFilters?: string[];
|
@state() private _activeFilters?: string[];
|
||||||
|
|
||||||
@state() private _filters: Record<
|
@storage({
|
||||||
string,
|
storage: "sessionStorage",
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
key: "helpers-table-filters-full",
|
||||||
> = {};
|
state: true,
|
||||||
|
subscribe: false,
|
||||||
|
serializer: serializeFilters,
|
||||||
|
deserializer: deserializeFilters,
|
||||||
|
})
|
||||||
|
private _filters: DataTableFilters = {};
|
||||||
|
|
||||||
@state() private _expandedFilter?: string;
|
@state() private _expandedFilter?: string;
|
||||||
|
|
||||||
@ -722,7 +732,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private _filterChanged(ev) {
|
private _filterChanged(ev) {
|
||||||
const type = ev.target.localName;
|
const type = ev.target.localName;
|
||||||
this._filters[type] = ev.detail;
|
this._filters = { ...this._filters, [type]: ev.detail };
|
||||||
this._applyFilters();
|
this._applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,13 +751,17 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(filter.items)
|
items.intersection(filter.items)
|
||||||
: new Set([...items].filter((x) => filter.items!.has(x)));
|
: new Set([...items].filter((x) => filter.items!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-labels" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-labels" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const labelItems: Set<string> = new Set();
|
const labelItems: Set<string> = new Set();
|
||||||
this._stateItems
|
this._stateItems
|
||||||
.filter((stateItem) =>
|
.filter((stateItem) =>
|
||||||
this._entityReg
|
this._entityReg
|
||||||
.find((reg) => reg.entity_id === stateItem.entity_id)
|
.find((reg) => reg.entity_id === stateItem.entity_id)
|
||||||
?.labels.some((lbl) => filter.value!.includes(lbl))
|
?.labels.some((lbl) => (filter.value as string[]).includes(lbl))
|
||||||
)
|
)
|
||||||
.forEach((stateItem) => labelItems.add(stateItem.entity_id));
|
.forEach((stateItem) => labelItems.add(stateItem.entity_id));
|
||||||
if (!items) {
|
if (!items) {
|
||||||
@ -760,7 +774,11 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(labelItems)
|
items.intersection(labelItems)
|
||||||
: new Set([...items].filter((x) => labelItems!.has(x)));
|
: new Set([...items].filter((x) => labelItems!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-categories" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-categories" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const categoryItems: Set<string> = new Set();
|
const categoryItems: Set<string> = new Set();
|
||||||
this._stateItems
|
this._stateItems
|
||||||
.filter(
|
.filter(
|
||||||
|
@ -104,6 +104,11 @@ 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 {
|
||||||
|
serializeFilters,
|
||||||
|
deserializeFilters,
|
||||||
|
DataTableFilters,
|
||||||
|
} from "../../../data/data_table_filters";
|
||||||
|
|
||||||
type SceneItem = SceneEntity & {
|
type SceneItem = SceneEntity & {
|
||||||
name: string;
|
name: string;
|
||||||
@ -132,10 +137,15 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _filteredScenes?: string[] | null;
|
@state() private _filteredScenes?: string[] | null;
|
||||||
|
|
||||||
@state() private _filters: Record<
|
@storage({
|
||||||
string,
|
storage: "sessionStorage",
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
key: "scene-table-filters-full",
|
||||||
> = {};
|
state: true,
|
||||||
|
subscribe: false,
|
||||||
|
serializer: serializeFilters,
|
||||||
|
deserializer: deserializeFilters,
|
||||||
|
})
|
||||||
|
private _filters: DataTableFilters = {};
|
||||||
|
|
||||||
@state() private _expandedFilter?: string;
|
@state() private _expandedFilter?: string;
|
||||||
|
|
||||||
@ -783,7 +793,7 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private _filterChanged(ev) {
|
private _filterChanged(ev) {
|
||||||
const type = ev.target.localName;
|
const type = ev.target.localName;
|
||||||
this._filters[type] = ev.detail;
|
this._filters = { ...this._filters, [type]: ev.detail };
|
||||||
this._applyFilters();
|
this._applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -802,7 +812,11 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(filter.items)
|
items.intersection(filter.items)
|
||||||
: new Set([...items].filter((x) => filter.items!.has(x)));
|
: new Set([...items].filter((x) => filter.items!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-categories" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-categories" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const categoryItems: Set<string> = new Set();
|
const categoryItems: Set<string> = new Set();
|
||||||
this.scenes
|
this.scenes
|
||||||
.filter(
|
.filter(
|
||||||
@ -822,13 +836,17 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(categoryItems)
|
items.intersection(categoryItems)
|
||||||
: new Set([...items].filter((x) => categoryItems!.has(x)));
|
: new Set([...items].filter((x) => categoryItems!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-labels" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-labels" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const labelItems: Set<string> = new Set();
|
const labelItems: Set<string> = new Set();
|
||||||
this.scenes
|
this.scenes
|
||||||
.filter((scene) =>
|
.filter((scene) =>
|
||||||
this._entityReg
|
this._entityReg
|
||||||
.find((reg) => reg.entity_id === scene.entity_id)
|
.find((reg) => reg.entity_id === scene.entity_id)
|
||||||
?.labels.some((lbl) => filter.value!.includes(lbl))
|
?.labels.some((lbl) => (filter.value as string[]).includes(lbl))
|
||||||
)
|
)
|
||||||
.forEach((scene) => labelItems.add(scene.entity_id));
|
.forEach((scene) => labelItems.add(scene.entity_id));
|
||||||
if (!items) {
|
if (!items) {
|
||||||
|
@ -106,6 +106,11 @@ 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 {
|
||||||
|
serializeFilters,
|
||||||
|
deserializeFilters,
|
||||||
|
DataTableFilters,
|
||||||
|
} from "../../../data/data_table_filters";
|
||||||
|
|
||||||
type ScriptItem = ScriptEntity & {
|
type ScriptItem = ScriptEntity & {
|
||||||
name: string;
|
name: string;
|
||||||
@ -136,10 +141,15 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _filteredScripts?: string[] | null;
|
@state() private _filteredScripts?: string[] | null;
|
||||||
|
|
||||||
@state() private _filters: Record<
|
@storage({
|
||||||
string,
|
storage: "sessionStorage",
|
||||||
{ value: string[] | undefined; items: Set<string> | undefined }
|
key: "script-table-filters-full",
|
||||||
> = {};
|
state: true,
|
||||||
|
subscribe: false,
|
||||||
|
serializer: serializeFilters,
|
||||||
|
deserializer: deserializeFilters,
|
||||||
|
})
|
||||||
|
private _filters: DataTableFilters = {};
|
||||||
|
|
||||||
@state() private _expandedFilter?: string;
|
@state() private _expandedFilter?: string;
|
||||||
|
|
||||||
@ -812,7 +822,7 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
private _filterChanged(ev) {
|
private _filterChanged(ev) {
|
||||||
const type = ev.target.localName;
|
const type = ev.target.localName;
|
||||||
this._filters[type] = ev.detail;
|
this._filters = { ...this._filters, [type]: ev.detail };
|
||||||
this._applyFilters();
|
this._applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,7 +846,11 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(filter.items)
|
items.intersection(filter.items)
|
||||||
: new Set([...items].filter((x) => filter.items!.has(x)));
|
: new Set([...items].filter((x) => filter.items!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-categories" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-categories" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const categoryItems: Set<string> = new Set();
|
const categoryItems: Set<string> = new Set();
|
||||||
this.scripts
|
this.scripts
|
||||||
.filter(
|
.filter(
|
||||||
@ -856,13 +870,17 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
|
|||||||
items.intersection(categoryItems)
|
items.intersection(categoryItems)
|
||||||
: new Set([...items].filter((x) => categoryItems!.has(x)));
|
: new Set([...items].filter((x) => categoryItems!.has(x)));
|
||||||
}
|
}
|
||||||
if (key === "ha-filter-labels" && filter.value?.length) {
|
if (
|
||||||
|
key === "ha-filter-labels" &&
|
||||||
|
Array.isArray(filter.value) &&
|
||||||
|
filter.value.length
|
||||||
|
) {
|
||||||
const labelItems: Set<string> = new Set();
|
const labelItems: Set<string> = new Set();
|
||||||
this.scripts
|
this.scripts
|
||||||
.filter((script) =>
|
.filter((script) =>
|
||||||
this._entityReg
|
this._entityReg
|
||||||
.find((reg) => reg.entity_id === script.entity_id)
|
.find((reg) => reg.entity_id === script.entity_id)
|
||||||
?.labels.some((lbl) => filter.value!.includes(lbl))
|
?.labels.some((lbl) => (filter.value as string[]).includes(lbl))
|
||||||
)
|
)
|
||||||
.forEach((script) => labelItems.add(script.entity_id));
|
.forEach((script) => labelItems.add(script.entity_id));
|
||||||
if (!items) {
|
if (!items) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user