Add drag and drop to area dashboard (#20289)

* Add drag and drop to area dashboard

* Update ha-config-areas-dashboard.ts

* Fix unassign path

* Add delay for touch

* Update ha-config-areas-dashboard.ts

---------

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
This commit is contained in:
Bram Kragten 2024-04-02 11:23:32 +02:00 committed by GitHub
parent a3024b38e9
commit 2e58d6656c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 56 additions and 9 deletions

View File

@ -23,9 +23,11 @@ import "../../../components/ha-fab";
import "../../../components/ha-floor-icon";
import "../../../components/ha-icon-button";
import "../../../components/ha-svg-icon";
import "../../../components/ha-sortable";
import {
AreaRegistryEntry,
createAreaRegistryEntry,
updateAreaRegistryEntry,
} from "../../../data/area_registry";
import {
FloorRegistryEntry,
@ -50,6 +52,10 @@ import {
} from "./show-dialog-area-registry-detail";
import { showFloorRegistryDetailDialog } from "./show-dialog-floor-registry-detail";
const UNASSIGNED_PATH = ["__unassigned__"];
const SORT_OPTIONS = { sort: false, delay: 500, delayOnTouchOnly: true };
@customElement("ha-config-areas-dashboard")
export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -187,13 +193,22 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
>
</ha-button-menu>
</div>
<div class="areas">
${floor.areas.map((area) => this._renderArea(area))}
</div>
<ha-sortable
handle-selector="a"
draggable-selector="a"
@item-moved=${this._areaMoved}
group="floor"
.options=${SORT_OPTIONS}
.path=${[floor.floor_id]}
>
<div class="areas">
${floor.areas.map((area) => this._renderArea(area))}
</div>
</ha-sortable>
</div>`
)}
${areasAndFloors?.unassisgnedAreas.length
? html`<div class="unassigned">
? html`<div class="floor">
<div class="header">
<h2>
${this.hass.localize(
@ -201,11 +216,20 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
)}
</h2>
</div>
<div class="areas">
${areasAndFloors?.unassisgnedAreas.map((area) =>
this._renderArea(area)
)}
</div>
<ha-sortable
handle-selector="a"
draggable-selector="a"
@item-moved=${this._areaMoved}
group="floor"
.options=${SORT_OPTIONS}
.path=${UNASSIGNED_PATH}
>
<div class="areas">
${areasAndFloors?.unassisgnedAreas.map((area) =>
this._renderArea(area)
)}
</div>
</ha-sortable>
</div>`
: nothing}
</div>
@ -281,6 +305,29 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
loadAreaRegistryDetailDialog();
}
private async _areaMoved(ev) {
const areasAndFloors = this._processAreas(
this.hass.areas,
this.hass.devices,
this.hass.entities,
this._floors!
);
let area: AreaRegistryEntry;
if (ev.detail.oldPath === UNASSIGNED_PATH) {
area = areasAndFloors.unassisgnedAreas[ev.detail.oldIndex];
} else {
const oldFloor = areasAndFloors.floors!.find(
(floor) => floor.floor_id === ev.detail.oldPath[0]
);
area = oldFloor!.areas[ev.detail.oldIndex];
}
await updateAreaRegistryEntry(this.hass, area.area_id, {
floor_id:
ev.detail.newPath === UNASSIGNED_PATH ? null : ev.detail.newPath[0],
});
}
private _handleFloorAction(ev: CustomEvent<ActionDetail>) {
const floor = (ev.currentTarget as any).floor;
switch (ev.detail.index) {