From 0fec555e41bc37d49da4b2b1085dbb599d85b031 Mon Sep 17 00:00:00 2001 From: Cyperghost Date: Wed, 27 Nov 2024 11:30:24 +0100 Subject: [PATCH] Move `toleranceElement` into `SortableListOptions` --- .../Field/Devtools/Project/Instructions.ts | 4 +- ts/WoltLabSuite/Core/Ui/Poll/Editor.ts | 4 +- ts/WoltLabSuite/Core/Ui/Sortable/List.ts | 43 +++++++++++++++---- .../acp/templates/useroptionsOptionType.tpl | 4 +- .../Field/Devtools/Project/Instructions.js | 4 +- .../js/WoltLabSuite/Core/Ui/Poll/Editor.js | 4 +- .../js/WoltLabSuite/Core/Ui/Sortable/List.js | 38 +++++++++++++--- .../install/files/style/ui/listSortable.scss | 6 ++- 8 files changed, 77 insertions(+), 30 deletions(-) diff --git a/ts/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.ts b/ts/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.ts index d2607dabb1..9b298670d4 100644 --- a/ts/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.ts +++ b/ts/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.ts @@ -294,9 +294,7 @@ class Instructions { new UiSortableList({ containerId: instructionListContainer.id, isSimpleSorting: true, - options: { - //TODO toleranceElement: "> div", - }, + toleranceElement: "div", }); if (instructionsData.type === "update") { diff --git a/ts/WoltLabSuite/Core/Ui/Poll/Editor.ts b/ts/WoltLabSuite/Core/Ui/Poll/Editor.ts index 747dd2babf..c763363481 100644 --- a/ts/WoltLabSuite/Core/Ui/Poll/Editor.ts +++ b/ts/WoltLabSuite/Core/Ui/Poll/Editor.ts @@ -122,9 +122,7 @@ class UiPollEditor { new UiSortableList({ containerId: containerId, - options: { - //TODO toleranceElement: "> div", - }, + toleranceElement: "div", }); if (this.options.isAjax) { diff --git a/ts/WoltLabSuite/Core/Ui/Sortable/List.ts b/ts/WoltLabSuite/Core/Ui/Sortable/List.ts index 71d63e7f8f..35a3db08ea 100644 --- a/ts/WoltLabSuite/Core/Ui/Sortable/List.ts +++ b/ts/WoltLabSuite/Core/Ui/Sortable/List.ts @@ -20,6 +20,7 @@ interface SortableListOptions { offset: number; options: Sortable.Options; isSimpleSorting: boolean; + toleranceElement: string; additionalParameters: UnknownObject; } @@ -38,15 +39,24 @@ class UiSortableList { offset: 0, options: { animation: 150, - chosenClass: "sortablePlaceholder", - fallbackOnBody: true, swapThreshold: 0.65, - filter: (event: Event | TouchEvent, target: HTMLElement, sortable: Sortable) => { - //TODO - console.log(event, target, sortable); - return true; + fallbackOnBody: true, + chosenClass: "sortablePlaceholder", + ghostClass: "", + draggable: "li:not(.sortableNoSorting)", + toleranceElement: "span", + filter: (event: Event | TouchEvent, target: HTMLElement) => { + const eventTarget = event.target as HTMLElement; + if (eventTarget === target) { + return false; + } + if (eventTarget.parentElement !== target) { + return false; + } + + return eventTarget.nodeName !== this._options.toleranceElement; }, - }, + } as Sortable.Options, isSimpleSorting: false, additionalParameters: {}, }, @@ -58,7 +68,24 @@ class UiSortableList { throw new Error(`Container '${this._options.containerId}' not found.`); } - new Sortable(this.#container.querySelector(".sortableList")!, this._options.options); + if (this._options.isSimpleSorting) { + const sortableList = this.#container.querySelector(".sortableList")!; + if (sortableList.nodeName === "TBODY") { + this._options.options.draggable = "tr:not(.sortableNoSorting)"; + } + + new Sortable(sortableList, { + direction: "vertical", + ...this._options.options, + }); + } else { + this.#container.querySelectorAll(".sortableList").forEach((list: HTMLElement) => { + new Sortable(list, { + group: "nested", + ...this._options.options, + }); + }); + } } } diff --git a/wcfsetup/install/files/acp/templates/useroptionsOptionType.tpl b/wcfsetup/install/files/acp/templates/useroptionsOptionType.tpl index 32769149bc..3261611845 100644 --- a/wcfsetup/install/files/acp/templates/useroptionsOptionType.tpl +++ b/wcfsetup/install/files/acp/templates/useroptionsOptionType.tpl @@ -12,9 +12,7 @@ new UiSortableList({ containerId: '{$option->optionName}SortableList', - options: { - toleranceElement: '' - } + toleranceElement: '', }); // re-select the previously selected tab diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.js index 6ff996b89c..dc6aa25adc 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Form/Builder/Field/Devtools/Project/Instructions.js @@ -205,9 +205,7 @@ define(["require", "exports", "tslib", "../../../../../../Core", "../../../../.. new List_1.default({ containerId: instructionListContainer.id, isSimpleSorting: true, - options: { - //TODO toleranceElement: "> div", - }, + toleranceElement: "div", }); if (instructionsData.type === "update") { document diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Poll/Editor.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Poll/Editor.js index 248e323839..899411ec94 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Poll/Editor.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Poll/Editor.js @@ -65,9 +65,7 @@ define(["require", "exports", "tslib", "../../Core", "../../Language", "../Sorta this.createOptionList(pollOptions || []); new List_1.default({ containerId: containerId, - options: { - //TODO toleranceElement: "> div", - }, + toleranceElement: "div", }); if (this.options.isAjax) { const element = document.getElementById(this.wysiwygId); diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Sortable/List.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Sortable/List.js index c7a6b3d041..ec432202e4 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Sortable/List.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Sortable/List.js @@ -23,12 +23,21 @@ define(["require", "exports", "tslib", "../../Core", "sortablejs"], function (re offset: 0, options: { animation: 150, - chosenClass: "sortablePlaceholder", - fallbackOnBody: true, swapThreshold: 0.65, - filter: (event, target, sortable) => { - console.log(event, target, sortable); - return true; + fallbackOnBody: true, + chosenClass: "sortablePlaceholder", + ghostClass: "", + draggable: "li:not(.sortableNoSorting)", + toleranceElement: "span", + filter: (event, target) => { + const eventTarget = event.target; + if (eventTarget === target) { + return false; + } + if (eventTarget.parentElement !== target) { + return false; + } + return eventTarget.nodeName !== this._options.toleranceElement; }, }, isSimpleSorting: false, @@ -38,7 +47,24 @@ define(["require", "exports", "tslib", "../../Core", "sortablejs"], function (re if (!this.#container) { throw new Error(`Container '${this._options.containerId}' not found.`); } - new sortablejs_1.default(this.#container.querySelector(".sortableList"), this._options.options); + if (this._options.isSimpleSorting) { + const sortableList = this.#container.querySelector(".sortableList"); + if (sortableList.nodeName === "TBODY") { + this._options.options.draggable = "tr:not(.sortableNoSorting)"; + } + new sortablejs_1.default(sortableList, { + direction: "vertical", + ...this._options.options, + }); + } + else { + this.#container.querySelectorAll(".sortableList").forEach((list) => { + new sortablejs_1.default(list, { + group: "nested", + ...this._options.options, + }); + }); + } } } return UiSortableList; diff --git a/wcfsetup/install/files/style/ui/listSortable.scss b/wcfsetup/install/files/style/ui/listSortable.scss index 6f2fa33459..f72130bcaf 100644 --- a/wcfsetup/install/files/style/ui/listSortable.scss +++ b/wcfsetup/install/files/style/ui/listSortable.scss @@ -78,13 +78,17 @@ background-color: var(--wcfStatusWarningBackground); border: 1px solid var(--wcfStatusWarningBorder); color: var(--wcfStatusWarningText); - padding: 10px; &.sortableInvalidTarget { background-color: var(--wcfStatusErrorBackground); border-color: var(--wcfStatusErrorBorder); color: var(--wcfStatusErrorText); } + + + .sortableNodeLabel { + background-color: transparent; + } } @include screen-xs { -- 2.20.1