Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle automation and dashboard drag and drop at the element level #22300

Merged
merged 14 commits into from
Oct 30, 2024
66 changes: 0 additions & 66 deletions src/common/util/array-move.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/ha-selector/ha-selector-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export class HaActionSelector extends LitElement {
.disabled=${this.disabled}
.actions=${this._actions(this.value)}
.hass=${this.hass}
.path=${this.selector.action?.path}
></ha-automation-action>
`;
}
Expand Down
1 change: 0 additions & 1 deletion src/components/ha-selector/ha-selector-condition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export class HaConditionSelector extends LitElement {
.disabled=${this.disabled}
.conditions=${this.value || []}
.hass=${this.hass}
.path=${this.selector.condition?.path}
></ha-automation-condition>
`;
}
Expand Down
1 change: 0 additions & 1 deletion src/components/ha-selector/ha-selector-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export class HaTriggerSelector extends LitElement {
.disabled=${this.disabled}
.triggers=${this._triggers(this.value)}
.hass=${this.hass}
.path=${this.selector.trigger?.path}
></ha-automation-trigger>
`;
}
Expand Down
29 changes: 1 addition & 28 deletions src/components/ha-service-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { fireEvent } from "../common/dom/fire_event";
import { computeDomain } from "../common/entity/compute_domain";
import { computeObjectId } from "../common/entity/compute_object_id";
import { supportsFeature } from "../common/entity/supports-feature";
import { nestedArrayMove } from "../common/util/array-move";
import {
fetchIntegrationManifest,
IntegrationManifest,
Expand Down Expand Up @@ -597,15 +596,6 @@ export class HaServiceControl extends LitElement {
}

const selector = dataField?.selector ?? { text: undefined };
const type = Object.keys(selector)[0];
const enhancedSelector = ["action", "condition", "trigger"].includes(type)
? {
[type]: {
...selector[type],
path: [dataField.key],
},
}
: selector;

const showOptional = showOptionalToggle(dataField);

Expand Down Expand Up @@ -646,15 +636,14 @@ export class HaServiceControl extends LitElement {
(!this._value?.data ||
this._value.data[dataField.key] === undefined))}
.hass=${this.hass}
.selector=${enhancedSelector}
.selector=${selector}
.key=${dataField.key}
@value-changed=${this._serviceDataChanged}
.value=${this._value?.data
? this._value.data[dataField.key]
: undefined}
.placeholder=${dataField.default}
.localizeValue=${this._localizeValueCallback}
@item-moved=${this._itemMoved}
></ha-selector>
</ha-settings-row>`
: "";
Expand Down Expand Up @@ -856,22 +845,6 @@ export class HaServiceControl extends LitElement {
});
}

private _itemMoved(ev) {
ev.stopPropagation();
const { oldIndex, newIndex, oldPath, newPath } = ev.detail;

const data = this.value?.data ?? {};

const newData = nestedArrayMove(data, oldIndex, newIndex, oldPath, newPath);

fireEvent(this, "value-changed", {
value: {
...this.value,
data: newData,
},
});
}

private _dataChanged(ev: CustomEvent) {
ev.stopPropagation();
if (!ev.detail.isValid) {
Expand Down
58 changes: 30 additions & 28 deletions src/components/ha-sortable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ import { customElement, property } from "lit/decorators";
import type { SortableEvent } from "sortablejs";
import { fireEvent } from "../common/dom/fire_event";
import type { SortableInstance } from "../resources/sortable";
import { ItemPath } from "../types";

declare global {
interface HASSDomEvents {
"item-moved": {
oldIndex: number;
newIndex: number;
oldPath?: ItemPath;
newPath?: ItemPath;
};
"item-added": {
index: number;
data: any;
};
"item-removed": {
index: number;
};
"drag-start": undefined;
"drag-end": undefined;
Expand All @@ -21,7 +25,7 @@ declare global {

export type HaSortableOptions = Omit<
SortableInstance.SortableOptions,
"onStart" | "onChoose" | "onEnd"
"onStart" | "onChoose" | "onEnd" | "onUpdate" | "onAdd" | "onRemove"
>;

@customElement("ha-sortable")
Expand All @@ -31,9 +35,6 @@ export class HaSortable extends LitElement {
@property({ type: Boolean })
public disabled = false;

@property({ type: Array })
public path?: ItemPath;

@property({ type: Boolean, attribute: "no-style" })
public noStyle: boolean = false;

Expand Down Expand Up @@ -138,6 +139,9 @@ export class HaSortable extends LitElement {
onChoose: this._handleChoose,
onStart: this._handleStart,
onEnd: this._handleEnd,
onUpdate: this._handleUpdate,
onAdd: this._handleAdd,
onRemove: this._handleRemove,
};

if (this.draggableSelector) {
Expand All @@ -159,33 +163,31 @@ export class HaSortable extends LitElement {
this._sortable = new Sortable(container, options);
}

private _handleEnd = async (evt: SortableEvent) => {
private _handleUpdate = (evt) => {
fireEvent(this, "item-moved", {
newIndex: evt.newIndex,
oldIndex: evt.oldIndex,
});
};

private _handleAdd = (evt) => {
fireEvent(this, "item-added", {
index: evt.newIndex,
data: evt.item.sortableData,
});
};

private _handleRemove = (evt) => {
fireEvent(this, "item-removed", { index: evt.oldIndex });
};

private _handleEnd = async (evt) => {
fireEvent(this, "drag-end");
// put back in original location
if (this.rollback && (evt.item as any).placeholder) {
(evt.item as any).placeholder.replaceWith(evt.item);
delete (evt.item as any).placeholder;
}

const oldIndex = evt.oldIndex;
const oldPath = (evt.from.parentElement as HaSortable).path;
const newIndex = evt.newIndex;
const newPath = (evt.to.parentElement as HaSortable).path;

if (
oldIndex === undefined ||
newIndex === undefined ||
(oldIndex === newIndex && oldPath?.join(".") === newPath?.join("."))
) {
return;
}

fireEvent(this, "item-moved", {
oldIndex,
newIndex,
oldPath,
newPath,
});
};

private _handleStart = () => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/trace/hat-trace-timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { LabelRegistryEntry } from "../../data/label_registry";
import { LogbookEntry } from "../../data/logbook";
import {
ChooseAction,
ChooseActionChoice,
Option,
IfAction,
ParallelAction,
RepeatAction,
Expand Down Expand Up @@ -413,7 +413,7 @@ class ActionRenderer {
: undefined;
const choiceConfig = this._getDataFromPath(
`${this.keys[index]}/choose/${chooseTrace.result.choice}`
) as ChooseActionChoice | undefined;
) as Option | undefined;
const choiceName = choiceConfig
? `${
choiceConfig.alias ||
Expand Down
5 changes: 3 additions & 2 deletions src/data/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,14 @@ export interface ForEachRepeat extends BaseRepeat {
for_each: string | any[];
}

export interface ChooseActionChoice extends BaseAction {
export interface Option {
alias?: string;
conditions: string | Condition[];
sequence: Action | Action[];
}

export interface ChooseAction extends BaseAction {
choose: ChooseActionChoice | ChooseActionChoice[] | null;
choose: Option | Option[] | null;
default?: Action | Action[];
}

Expand Down
17 changes: 7 additions & 10 deletions src/data/selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { supportsFeature } from "../common/entity/supports-feature";
import type { CropOptions } from "../dialogs/image-cropper-dialog/show-image-cropper-dialog";
import { isHelperDomain } from "../panels/config/helpers/const";
import { UiAction } from "../panels/lovelace/components/hui-action-editor";
import { HomeAssistant, ItemPath } from "../types";
import { HomeAssistant } from "../types";
import {
DeviceRegistryEntry,
getDeviceIntegrationLookup,
Expand Down Expand Up @@ -68,9 +68,8 @@ export type Selector =
| UiStateContentSelector;

export interface ActionSelector {
action: {
path?: ItemPath;
} | null;
// eslint-disable-next-line @typescript-eslint/ban-types
action: {} | null;
}

export interface AddonSelector {
Expand Down Expand Up @@ -121,9 +120,8 @@ export interface ColorTempSelector {
}

export interface ConditionSelector {
condition: {
path?: ItemPath;
} | null;
// eslint-disable-next-line @typescript-eslint/ban-types
condition: {} | null;
}

export interface ConversationAgentSelector {
Expand Down Expand Up @@ -432,9 +430,8 @@ export interface TimeSelector {
}

export interface TriggerSelector {
trigger: {
path?: ItemPath;
} | null;
// eslint-disable-next-line @typescript-eslint/ban-types
trigger: {} | null;
}

export interface TTSSelector {
Expand Down
Loading
Loading