Add count of items (#20410)

* Add count of items

* Adjust layout, correct filter count
This commit is contained in:
Bram Kragten 2024-04-04 16:15:13 +02:00 committed by GitHub
parent 72d1e37a23
commit 5c42c5130c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 130 additions and 59 deletions

View File

@ -496,8 +496,9 @@ export class HaTabsSubpageDataTable extends LitElement {
${this.showFilters && !showPane ${this.showFilters && !showPane
? html`<ha-dialog ? html`<ha-dialog
open open
hideActions .heading=${localize("ui.components.subpage-data-table.filters", {
.heading=${localize("ui.components.subpage-data-table.filters")} number: this.data.length,
})}
> >
<ha-dialog-header slot="heading"> <ha-dialog-header slot="heading">
<ha-icon-button <ha-icon-button
@ -509,7 +510,9 @@ export class HaTabsSubpageDataTable extends LitElement {
)} )}
></ha-icon-button> ></ha-icon-button>
<span slot="title" <span slot="title"
>${localize("ui.components.subpage-data-table.filters")}</span >${localize("ui.components.subpage-data-table.filters", {
number: this.data.length,
})}</span
> >
${this.filters ${this.filters
? html`<ha-icon-button ? html`<ha-icon-button
@ -523,8 +526,17 @@ export class HaTabsSubpageDataTable extends LitElement {
: nothing} : nothing}
</ha-dialog-header> </ha-dialog-header>
<div class="filter-dialog-content"> <div class="filter-dialog-content">
<slot name="filter-pane"></slot></div <slot name="filter-pane"></slot>
></ha-dialog>` </div>
<div slot="primaryAction">
<ha-button @click=${this._toggleFilters}>
${this.hass.localize(
"ui.components.subpage-data-table.show_results",
{ number: this.data.length }
)}
</ha-button>
</div>
</ha-dialog>`
: nothing} : nothing}
`; `;
} }
@ -793,7 +805,7 @@ export class HaTabsSubpageDataTable extends LitElement {
} }
.filter-dialog-content { .filter-dialog-content {
height: calc(100vh - 1px - var(--header-height)); height: calc(100vh - 1px - 61px - var(--header-height));
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }

View File

@ -422,6 +422,14 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
const labelsInOverflow = const labelsInOverflow =
(this._sizeController.value && this._sizeController.value < 700) || (this._sizeController.value && this._sizeController.value < 700) ||
(!this._sizeController.value && this.hass.dockedSidebar === "docked"); (!this._sizeController.value && this.hass.dockedSidebar === "docked");
const automations = this._automations(
this.automations,
this._entityReg,
this.hass.areas,
this._categories,
this._labels,
this._filteredAutomations
);
return html` return html`
<hass-tabs-subpage-data-table <hass-tabs-subpage-data-table
.hass=${this.hass} .hass=${this.hass}
@ -432,13 +440,23 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
id="entity_id" id="entity_id"
.route=${this.route} .route=${this.route}
.tabs=${configSections.automations} .tabs=${configSections.automations}
.searchLabel=${this.hass.localize(
"ui.panel.config.automation.picker.search",
{ number: automations.length }
)}
selectable selectable
.selected=${this._selected.length} .selected=${this._selected.length}
@selection-changed=${this._handleSelectionChanged} @selection-changed=${this._handleSelectionChanged}
hasFilters hasFilters
.filters=${ .filters=${
Object.values(this._filters).filter((filter) => filter.value?.length) Object.values(this._filters).filter((filter) =>
.length Array.isArray(filter.value)
? filter.value.length
: filter.value &&
Object.values(filter.value).some((val) =>
Array.isArray(val) ? val.length : val
)
).length
} }
.columns=${this._columns( .columns=${this._columns(
this.narrow, this.narrow,
@ -446,14 +464,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
this.hass.locale this.hass.locale
)} )}
initialGroupColumn="category" initialGroupColumn="category"
.data=${this._automations( .data=${automations}
this.automations,
this._entityReg,
this.hass.areas,
this._categories,
this._labels,
this._filteredAutomations
)}
.empty=${!this.automations.length} .empty=${!this.automations.length}
@row-click=${this._handleRowClicked} @row-click=${this._handleRowClicked}
.noDataText=${this.hass.localize( .noDataText=${this.hass.localize(

View File

@ -591,7 +591,8 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
.tabs=${configSections.devices} .tabs=${configSections.devices}
.route=${this.route} .route=${this.route}
.searchLabel=${this.hass.localize( .searchLabel=${this.hass.localize(
"ui.panel.config.devices.picker.search" "ui.panel.config.devices.picker.search",
{ number: devicesOutput.length }
)} )}
.columns=${this._columns(this.hass.localize, this.narrow)} .columns=${this._columns(this.hass.localize, this.narrow)}
.data=${devicesOutput} .data=${devicesOutput}
@ -600,8 +601,13 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
@selection-changed=${this._handleSelectionChanged} @selection-changed=${this._handleSelectionChanged}
.filter=${this._filter} .filter=${this._filter}
hasFilters hasFilters
.filters=${Object.values(this._filters).filter( .filters=${Object.values(this._filters).filter((filter) =>
(filter) => filter.value?.length Array.isArray(filter.value)
? filter.value.length
: filter.value &&
Object.values(filter.value).some((val) =>
Array.isArray(val) ? val.length : val
)
).length} ).length}
@clear-filter=${this._clearFilter} @clear-filter=${this._clearFilter}
@search-changed=${this._handleSearchChange} @search-changed=${this._handleSearchChange}

View File

@ -573,12 +573,19 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
)} )}
.data=${filteredEntities} .data=${filteredEntities}
.searchLabel=${this.hass.localize( .searchLabel=${this.hass.localize(
"ui.panel.config.entities.picker.search" "ui.panel.config.entities.picker.search",
{ number: filteredEntities.length }
)} )}
hasFilters hasFilters
.filters=${ .filters=${
Object.values(this._filters).filter((filter) => filter.value?.length) Object.values(this._filters).filter((filter) =>
.length Array.isArray(filter.value)
? filter.value.length
: filter.value &&
Object.values(filter.value).some((val) =>
Array.isArray(val) ? val.length : val
)
).length
} }
.filter=${this._filter} .filter=${this._filter}
selectable selectable

View File

@ -486,6 +486,16 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
const labelsInOverflow = const labelsInOverflow =
(this._sizeController.value && this._sizeController.value < 700) || (this._sizeController.value && this._sizeController.value < 700) ||
(!this._sizeController.value && this.hass.dockedSidebar === "docked"); (!this._sizeController.value && this.hass.dockedSidebar === "docked");
const helpers = this._getItems(
this.hass.localize,
this._stateItems,
this._entityEntries,
this._configEntries,
this._entityReg,
this._categories,
this._labels,
this._filteredStateItems
);
return html` return html`
<hass-tabs-subpage-data-table <hass-tabs-subpage-data-table
.hass=${this.hass} .hass=${this.hass}
@ -493,24 +503,24 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) {
back-path="/config" back-path="/config"
.route=${this.route} .route=${this.route}
.tabs=${configSections.devices} .tabs=${configSections.devices}
.searchLabel=${this.hass.localize(
"ui.panel.config.helpers.picker.search",
{ number: helpers.length }
)}
selectable selectable
.selected=${this._selected.length} .selected=${this._selected.length}
@selection-changed=${this._handleSelectionChanged} @selection-changed=${this._handleSelectionChanged}
hasFilters hasFilters
.filters=${Object.values(this._filters).filter( .filters=${Object.values(this._filters).filter((filter) =>
(filter) => filter.value?.length Array.isArray(filter.value)
? filter.value.length
: filter.value &&
Object.values(filter.value).some((val) =>
Array.isArray(val) ? val.length : val
)
).length} ).length}
.columns=${this._columns(this.narrow, this.hass.localize)} .columns=${this._columns(this.narrow, this.hass.localize)}
.data=${this._getItems( .data=${helpers}
this.hass.localize,
this._stateItems,
this._entityEntries,
this._configEntries,
this._entityReg,
this._categories,
this._labels,
this._filteredStateItems
)}
initialGroupColumn="category" initialGroupColumn="category"
.activeFilters=${this._activeFilters} .activeFilters=${this._activeFilters}
@clear-filter=${this._clearFilter} @clear-filter=${this._clearFilter}

View File

@ -425,6 +425,14 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
const labelsInOverflow = const labelsInOverflow =
(this._sizeController.value && this._sizeController.value < 700) || (this._sizeController.value && this._sizeController.value < 700) ||
(!this._sizeController.value && this.hass.dockedSidebar === "docked"); (!this._sizeController.value && this.hass.dockedSidebar === "docked");
const scenes = this._scenes(
this.scenes,
this._entityReg,
this.hass.areas,
this._categories,
this._labels,
this._filteredScenes
);
return html` return html`
<hass-tabs-subpage-data-table <hass-tabs-subpage-data-table
.hass=${this.hass} .hass=${this.hass}
@ -432,24 +440,26 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) {
back-path="/config" back-path="/config"
.route=${this.route} .route=${this.route}
.tabs=${configSections.automations} .tabs=${configSections.automations}
.searchLabel=${this.hass.localize(
"ui.panel.config.scene.picker.search",
{ number: scenes.length }
)}
selectable selectable
.selected=${this._selected.length} .selected=${this._selected.length}
@selection-changed=${this._handleSelectionChanged} @selection-changed=${this._handleSelectionChanged}
hasFilters hasFilters
.filters=${Object.values(this._filters).filter( .filters=${Object.values(this._filters).filter((filter) =>
(filter) => filter.value?.length Array.isArray(filter.value)
? filter.value.length
: filter.value &&
Object.values(filter.value).some((val) =>
Array.isArray(val) ? val.length : val
)
).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="category"
.data=${this._scenes( .data=${scenes}
this.scenes,
this._entityReg,
this.hass.areas,
this._categories,
this._labels,
this._filteredScenes
)}
.empty=${!this.scenes.length} .empty=${!this.scenes.length}
.activeFilters=${this._activeFilters} .activeFilters=${this._activeFilters}
.noDataText=${this.hass.localize( .noDataText=${this.hass.localize(

View File

@ -437,6 +437,14 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
const labelsInOverflow = const labelsInOverflow =
(this._sizeController.value && this._sizeController.value < 700) || (this._sizeController.value && this._sizeController.value < 700) ||
(!this._sizeController.value && this.hass.dockedSidebar === "docked"); (!this._sizeController.value && this.hass.dockedSidebar === "docked");
const scripts = this._scripts(
this.scripts,
this._entityReg,
this.hass.areas,
this._categories,
this._labels,
this._filteredScripts
);
return html` return html`
<hass-tabs-subpage-data-table <hass-tabs-subpage-data-table
.hass=${this.hass} .hass=${this.hass}
@ -444,27 +452,29 @@ class HaScriptPicker extends SubscribeMixin(LitElement) {
back-path="/config" back-path="/config"
.route=${this.route} .route=${this.route}
.tabs=${configSections.automations} .tabs=${configSections.automations}
.searchLabel=${this.hass.localize(
"ui.panel.config.script.picker.search",
{ number: scripts.length }
)}
hasFilters hasFilters
initialGroupColumn="category" initialGroupColumn="category"
selectable selectable
.selected=${this._selected.length} .selected=${this._selected.length}
@selection-changed=${this._handleSelectionChanged} @selection-changed=${this._handleSelectionChanged}
.filters=${Object.values(this._filters).filter( .filters=${Object.values(this._filters).filter((filter) =>
(filter) => filter.value?.length Array.isArray(filter.value)
? filter.value.length
: filter.value &&
Object.values(filter.value).some((val) =>
Array.isArray(val) ? val.length : val
)
).length} ).length}
.columns=${this._columns( .columns=${this._columns(
this.narrow, this.narrow,
this.hass.localize, this.hass.localize,
this.hass.locale this.hass.locale
)} )}
.data=${this._scripts( .data=${scripts}
this.scripts,
this._entityReg,
this.hass.areas,
this._categories,
this._labels,
this._filteredScripts
)}
.empty=${!this.scripts.length} .empty=${!this.scripts.length}
.activeFilters=${this._activeFilters} .activeFilters=${this._activeFilters}
id="entity_id" id="entity_id"

View File

@ -501,6 +501,7 @@
}, },
"subpage-data-table": { "subpage-data-table": {
"filters": "Filters", "filters": "Filters",
"show_results": "show {number} results",
"clear_filter": "Clear filter", "clear_filter": "Clear filter",
"close_filter": "Close filters", "close_filter": "Close filters",
"exit_selection_mode": "Exit selection mode", "exit_selection_mode": "Exit selection mode",
@ -2270,7 +2271,8 @@
"category": "Category" "category": "Category"
}, },
"create_helper": "Create helper", "create_helper": "Create helper",
"no_helpers": "Looks like you don't have any helpers yet!" "no_helpers": "Looks like you don't have any helpers yet!",
"search": "Search {number} helpers"
}, },
"dialog": { "dialog": {
"create": "Create", "create": "Create",
@ -2684,6 +2686,7 @@
"assign_category": "Assign category", "assign_category": "Assign category",
"no_category_support": "You can't assign an category to this automation", "no_category_support": "You can't assign an category to this automation",
"no_category_entity_reg": "To assign an category to an automation it needs to have a unique ID.", "no_category_entity_reg": "To assign an category to an automation it needs to have a unique ID.",
"search": "Search {number} automations",
"headers": { "headers": {
"toggle": "Enable/disable", "toggle": "Enable/disable",
"name": "Name", "name": "Name",
@ -3577,7 +3580,8 @@
"delete": "[%key:ui::common::delete%]", "delete": "[%key:ui::common::delete%]",
"duplicate": "[%key:ui::common::duplicate%]", "duplicate": "[%key:ui::common::duplicate%]",
"empty_header": "Create your first script", "empty_header": "Create your first script",
"empty_text": "A script is a sequence of actions that can be run from a dashboard, an automation, or be triggered by voice. For example, a ''Wake-up routine''' script that gradually turns on the light in the bedroom and opens the blinds after a delay." "empty_text": "A script is a sequence of actions that can be run from a dashboard, an automation, or be triggered by voice. For example, a ''Wake-up routine''' script that gradually turns on the light in the bedroom and opens the blinds after a delay.",
"search": "Search {number} scripts"
}, },
"dialog_new": { "dialog_new": {
"header": "Create script", "header": "Create script",
@ -3685,7 +3689,8 @@
"no_category_support": "You can't assign an category to this scene", "no_category_support": "You can't assign an category to this scene",
"no_category_entity_reg": "To assign an category to an scene it needs to have a unique ID.", "no_category_entity_reg": "To assign an category to an scene it needs to have a unique ID.",
"empty_header": "Create your first scene", "empty_header": "Create your first scene",
"empty_text": "Scenes capture entities' states, so you can re-experience the same scene later on. For example, a ''Watching TV'' scene that dims the living room lights, sets a warm white color and turns on the TV." "empty_text": "Scenes capture entities' states, so you can re-experience the same scene later on. For example, a ''Watching TV'' scene that dims the living room lights, sets a warm white color and turns on the TV.",
"search": "Search {number} scenes"
}, },
"editor": { "editor": {
"default_name": "New scene", "default_name": "New scene",
@ -4010,7 +4015,7 @@
"confirm_delete": "Are you sure you want to delete this device?", "confirm_delete": "Are you sure you want to delete this device?",
"confirm_delete_integration": "Are you sure you want to remove this device from {integration}?", "confirm_delete_integration": "Are you sure you want to remove this device from {integration}?",
"picker": { "picker": {
"search": "Search devices", "search": "Search {number} devices",
"state": "State" "state": "State"
} }
}, },
@ -4021,7 +4026,7 @@
"header": "Entities", "header": "Entities",
"introduction": "Home Assistant keeps a registry of every entity it has ever seen that can be uniquely identified. Each of these entities will have an entity ID assigned which will be reserved for just this entity.", "introduction": "Home Assistant keeps a registry of every entity it has ever seen that can be uniquely identified. Each of these entities will have an entity ID assigned which will be reserved for just this entity.",
"introduction2": "Use the entity registry to override the name, change the entity ID or remove the entry from Home Assistant.", "introduction2": "Use the entity registry to override the name, change the entity ID or remove the entry from Home Assistant.",
"search": "Search entities", "search": "Search {number} entities",
"unnamed_entity": "Unnamed entity", "unnamed_entity": "Unnamed entity",
"status": { "status": {
"restored": "Restored", "restored": "Restored",