fix bug kéo thả của loop
Some checks failed
Test / test (push) Has been cancelled

This commit is contained in:
2026-06-13 14:20:23 +07:00
parent 9776e29d7d
commit 1716351016
6 changed files with 190 additions and 127 deletions

View File

@@ -302,11 +302,21 @@
}
}
function normalizeActionTree(actions) {
if (!Array.isArray(actions)) return;
actions.forEach((action) => {
if (action.type === "loop" && !Array.isArray(action.children)) {
action.children = [];
}
if (Array.isArray(action.children)) normalizeActionTree(action.children);
});
}
function findActionList(path) {
const draft = getDraft();
if (!draft) return null;
if (path === "root") return draft.actions;
const parts = path.split(".");
const parts = path.split(".").filter((p) => p !== "root");
let list = draft.actions;
for (const part of parts) {
const node = list.find((a) => a.id === part);
@@ -321,7 +331,7 @@
for (let i = 0; i < list.length; i += 1) {
const action = list[i];
if (action.id === actionId) return { action, list, index: i, path, parent };
if (action.children?.length) {
if (Array.isArray(action.children)) {
const hit = findActionWithParent(actionId, action.children, `${path}.${action.id}`, action);
if (hit) return hit;
}
@@ -765,12 +775,17 @@
const item = document.createElement("button");
item.type = "button";
item.className = "missionPaletteItem";
item.draggable = true;
item.innerHTML = `<span class="missionActionIcon">${def.isLoop ? "↻" : "▶"}</span><span>${escapeHtml(def.label)}</span>`;
item.addEventListener("click", () => {
addActionToList(def.type, "root");
menu.hidden = true;
btn.classList.remove("open");
});
item.addEventListener("dragstart", (evt) => {
onPaletteDragStart(evt, { actionType: def.type });
});
item.addEventListener("dragend", onDragEnd);
menu.appendChild(item);
});
@@ -785,12 +800,17 @@
const item = document.createElement("button");
item.type = "button";
item.className = "missionPaletteItem missionRef";
item.draggable = true;
item.innerHTML = `<span class="missionActionIcon kind-mission">◎</span><span>${escapeHtml(m.name)}</span>`;
item.addEventListener("click", () => {
addMissionRefToList(m.id, "root");
menu.hidden = true;
btn.classList.remove("open");
});
item.addEventListener("dragstart", (evt) => {
onPaletteDragStart(evt, { missionId: m.id });
});
item.addEventListener("dragend", onDragEnd);
menu.appendChild(item);
});
}
@@ -891,15 +911,13 @@
renderActionPalette();
missionActionListEl.innerHTML = "";
renderActionRows(draft.actions, "root", missionActionListEl);
bindDragPaletteItems();
}
function bindDragPaletteItems() {
document.querySelectorAll(".missionLoopDrop").forEach((drop) => {
drop.addEventListener("dragover", onLoopDragOver);
drop.addEventListener("dragleave", onLoopDragLeave);
drop.addEventListener("drop", onLoopDrop);
});
function onPaletteDragStart(evt, payload) {
store.drag = { mode: "palette", ...payload };
evt.dataTransfer.effectAllowed = "copy";
evt.dataTransfer.setData("text/plain", payload.actionType || payload.missionId || "palette");
evt.currentTarget.classList.add("dragging");
}
function onDragStart(evt, actionId, listPath) {
@@ -913,6 +931,7 @@
document.querySelectorAll(".missionActionRow.dragging, .missionActionRow.dropBefore, .missionActionRow.dropAfter").forEach((n) => {
n.classList.remove("dragging", "dropBefore", "dropAfter");
});
document.querySelectorAll(".missionPaletteItem.dragging").forEach((n) => n.classList.remove("dragging"));
document.querySelectorAll(".missionLoopDrop.dragOver").forEach((n) => n.classList.remove("dragOver"));
store.drag = null;
}
@@ -980,6 +999,7 @@
if (!mission) return;
store.editingId = missionId;
store.draft = JSON.parse(JSON.stringify(mission));
normalizeActionTree(store.draft.actions);
setDirty(false);
missionsListViewEl.hidden = true;
missionEditorViewEl.hidden = false;