mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
Allow for shift click in data table checkboxes (#25024)
Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
parent
93f2e75fc9
commit
89e04fcc45
@ -164,6 +164,8 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
@state() private _collapsedGroups: string[] = [];
|
@state() private _collapsedGroups: string[] = [];
|
||||||
|
|
||||||
|
@state() private _lastSelectedRowId: string | null = null;
|
||||||
|
|
||||||
private _checkableRowsCount?: number;
|
private _checkableRowsCount?: number;
|
||||||
|
|
||||||
private _checkedRows: string[] = [];
|
private _checkedRows: string[] = [];
|
||||||
@ -187,6 +189,7 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
public clearSelection(): void {
|
public clearSelection(): void {
|
||||||
this._checkedRows = [];
|
this._checkedRows = [];
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
this._checkedRowsChanged();
|
this._checkedRowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +197,7 @@ export class HaDataTable extends LitElement {
|
|||||||
this._checkedRows = this._filteredData
|
this._checkedRows = this._filteredData
|
||||||
.filter((data) => data.selectable !== false)
|
.filter((data) => data.selectable !== false)
|
||||||
.map((data) => data[this.id]);
|
.map((data) => data[this.id]);
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
this._checkedRowsChanged();
|
this._checkedRowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +211,7 @@ export class HaDataTable extends LitElement {
|
|||||||
this._checkedRows.push(id);
|
this._checkedRows.push(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
this._checkedRowsChanged();
|
this._checkedRowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,6 +222,7 @@ export class HaDataTable extends LitElement {
|
|||||||
this._checkedRows.splice(index, 1);
|
this._checkedRows.splice(index, 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
this._checkedRowsChanged();
|
this._checkedRowsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +267,7 @@ export class HaDataTable extends LitElement {
|
|||||||
if (this.columns[columnId].direction) {
|
if (this.columns[columnId].direction) {
|
||||||
this.sortDirection = this.columns[columnId].direction!;
|
this.sortDirection = this.columns[columnId].direction!;
|
||||||
this.sortColumn = columnId;
|
this.sortColumn = columnId;
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
|
|
||||||
fireEvent(this, "sorting-changed", {
|
fireEvent(this, "sorting-changed", {
|
||||||
column: columnId,
|
column: columnId,
|
||||||
@ -286,6 +293,7 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
if (properties.has("filter")) {
|
if (properties.has("filter")) {
|
||||||
this._debounceSearch(this.filter);
|
this._debounceSearch(this.filter);
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.has("data")) {
|
if (properties.has("data")) {
|
||||||
@ -296,9 +304,11 @@ export class HaDataTable extends LitElement {
|
|||||||
|
|
||||||
if (!this.hasUpdated && this.initialCollapsedGroups) {
|
if (!this.hasUpdated && this.initialCollapsedGroups) {
|
||||||
this._collapsedGroups = this.initialCollapsedGroups;
|
this._collapsedGroups = this.initialCollapsedGroups;
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
||||||
} else if (properties.has("groupColumn")) {
|
} else if (properties.has("groupColumn")) {
|
||||||
this._collapsedGroups = [];
|
this._collapsedGroups = [];
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +322,14 @@ export class HaDataTable extends LitElement {
|
|||||||
this._sortFilterData();
|
this._sortFilterData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
properties.has("_filter") ||
|
||||||
|
properties.has("sortColumn") ||
|
||||||
|
properties.has("sortDirection")
|
||||||
|
) {
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (properties.has("selectable") || properties.has("hiddenColumns")) {
|
if (properties.has("selectable") || properties.has("hiddenColumns")) {
|
||||||
this._filteredData = [...this._filteredData];
|
this._filteredData = [...this._filteredData];
|
||||||
}
|
}
|
||||||
@ -542,7 +560,7 @@ export class HaDataTable extends LitElement {
|
|||||||
>
|
>
|
||||||
<ha-checkbox
|
<ha-checkbox
|
||||||
class="mdc-data-table__row-checkbox"
|
class="mdc-data-table__row-checkbox"
|
||||||
@change=${this._handleRowCheckboxClick}
|
@click=${this._handleRowCheckboxClicked}
|
||||||
.rowId=${row[this.id]}
|
.rowId=${row[this.id]}
|
||||||
.disabled=${row.selectable === false}
|
.disabled=${row.selectable === false}
|
||||||
.checked=${this._checkedRows.includes(String(row[this.id]))}
|
.checked=${this._checkedRows.includes(String(row[this.id]))}
|
||||||
@ -724,6 +742,7 @@ export class HaDataTable extends LitElement {
|
|||||||
Object.entries(sorted).forEach(([groupName, rows]) => {
|
Object.entries(sorted).forEach(([groupName, rows]) => {
|
||||||
groupedItems.push({
|
groupedItems.push({
|
||||||
append: true,
|
append: true,
|
||||||
|
selectable: false,
|
||||||
content: html`<div
|
content: html`<div
|
||||||
class="mdc-data-table__cell group-header"
|
class="mdc-data-table__cell group-header"
|
||||||
role="cell"
|
role="cell"
|
||||||
@ -750,7 +769,7 @@ export class HaDataTable extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (appendRow) {
|
if (appendRow) {
|
||||||
items.push({ append: true, content: appendRow });
|
items.push({ append: true, selectable: false, content: appendRow });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFab) {
|
if (hasFab) {
|
||||||
@ -800,23 +819,84 @@ export class HaDataTable extends LitElement {
|
|||||||
this._checkedRows = [];
|
this._checkedRows = [];
|
||||||
this._checkedRowsChanged();
|
this._checkedRowsChanged();
|
||||||
}
|
}
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleRowCheckboxClick = (ev: Event) => {
|
private _handleRowCheckboxClicked = (ev: Event) => {
|
||||||
const checkbox = ev.currentTarget as HaCheckbox;
|
const checkbox = ev.currentTarget as HaCheckbox;
|
||||||
const rowId = (checkbox as any).rowId;
|
const rowId = (checkbox as any).rowId;
|
||||||
|
|
||||||
if (checkbox.checked) {
|
const groupedData = this._groupData(
|
||||||
if (this._checkedRows.includes(rowId)) {
|
this._filteredData,
|
||||||
|
this.localizeFunc || this.hass.localize,
|
||||||
|
this.appendRow,
|
||||||
|
this.hasFab,
|
||||||
|
this.groupColumn,
|
||||||
|
this.groupOrder,
|
||||||
|
this._collapsedGroups
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
groupedData.find((data) => data[this.id] === rowId)?.selectable === false
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rowIndex = groupedData.findIndex((data) => data[this.id] === rowId);
|
||||||
|
|
||||||
|
if (
|
||||||
|
ev instanceof MouseEvent &&
|
||||||
|
ev.shiftKey &&
|
||||||
|
this._lastSelectedRowId !== null
|
||||||
|
) {
|
||||||
|
const lastSelectedRowIndex = groupedData.findIndex(
|
||||||
|
(data) => data[this.id] === this._lastSelectedRowId
|
||||||
|
);
|
||||||
|
|
||||||
|
if (lastSelectedRowIndex > -1 && rowIndex > -1) {
|
||||||
|
this._checkedRows = [
|
||||||
|
...this._checkedRows,
|
||||||
|
...this._selectRange(groupedData, lastSelectedRowIndex, rowIndex),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
} else if (!checkbox.checked) {
|
||||||
|
if (!this._checkedRows.includes(rowId)) {
|
||||||
this._checkedRows = [...this._checkedRows, rowId];
|
this._checkedRows = [...this._checkedRows, rowId];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this._checkedRows = this._checkedRows.filter((row) => row !== rowId);
|
this._checkedRows = this._checkedRows.filter((row) => row !== rowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rowIndex > -1) {
|
||||||
|
this._lastSelectedRowId = rowId;
|
||||||
|
}
|
||||||
this._checkedRowsChanged();
|
this._checkedRowsChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private _selectRange(
|
||||||
|
groupedData: DataTableRowData[],
|
||||||
|
startIndex: number,
|
||||||
|
endIndex: number
|
||||||
|
) {
|
||||||
|
const start = Math.min(startIndex, endIndex);
|
||||||
|
const end = Math.max(startIndex, endIndex);
|
||||||
|
|
||||||
|
const checkedRows: string[] = [];
|
||||||
|
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
const row = groupedData[i];
|
||||||
|
if (
|
||||||
|
row &&
|
||||||
|
row.selectable !== false &&
|
||||||
|
!this._checkedRows.includes(row[this.id])
|
||||||
|
) {
|
||||||
|
checkedRows.push(row[this.id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkedRows;
|
||||||
|
}
|
||||||
|
|
||||||
private _handleRowClick = (ev: Event) => {
|
private _handleRowClick = (ev: Event) => {
|
||||||
if (
|
if (
|
||||||
ev
|
ev
|
||||||
@ -858,6 +938,7 @@ export class HaDataTable extends LitElement {
|
|||||||
if (this.filter) {
|
if (this.filter) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
this._debounceSearch(ev.detail.value);
|
this._debounceSearch(ev.detail.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,11 +975,13 @@ export class HaDataTable extends LitElement {
|
|||||||
} else {
|
} else {
|
||||||
this._collapsedGroups = [...this._collapsedGroups, groupName];
|
this._collapsedGroups = [...this._collapsedGroups, groupName];
|
||||||
}
|
}
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
||||||
};
|
};
|
||||||
|
|
||||||
public expandAllGroups() {
|
public expandAllGroups() {
|
||||||
this._collapsedGroups = [];
|
this._collapsedGroups = [];
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,6 +999,7 @@ export class HaDataTable extends LitElement {
|
|||||||
delete grouped.undefined;
|
delete grouped.undefined;
|
||||||
}
|
}
|
||||||
this._collapsedGroups = Object.keys(grouped);
|
this._collapsedGroups = Object.keys(grouped);
|
||||||
|
this._lastSelectedRowId = null;
|
||||||
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
fireEvent(this, "collapsed-changed", { value: this._collapsedGroups });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user