From dfc9ac50c9c1febfcbcd2af93de001c5a4e12097 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Mon, 30 Nov 2020 01:18:26 +0100 Subject: [PATCH] Convert `Acp/Ui/Page/BoxOrder` to TypeScript --- global.d.ts | 2 + .../files/acp/templates/pageBoxOrder.tpl | 4 +- .../WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js | 134 +++++++-------- .../WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js | 135 ---------------- .../WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.ts | 152 ++++++++++++++++++ 5 files changed, 225 insertions(+), 202 deletions(-) delete mode 100644 wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js create mode 100644 wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.ts diff --git a/global.d.ts b/global.d.ts index 73b8a0c5ab..45b8cc9743 100644 --- a/global.d.ts +++ b/global.d.ts @@ -34,6 +34,8 @@ declare global { } interface JQuery { + sortable(...args: any[]): unknown; + redactor(...args: any[]): unknown; } diff --git a/wcfsetup/install/files/acp/templates/pageBoxOrder.tpl b/wcfsetup/install/files/acp/templates/pageBoxOrder.tpl index 39e74ffd6e..c4e0c2f95b 100644 --- a/wcfsetup/install/files/acp/templates/pageBoxOrder.tpl +++ b/wcfsetup/install/files/acp/templates/pageBoxOrder.tpl @@ -119,10 +119,10 @@ 'wcf.acp.page.boxOrder.discard.confirmMessage': '{jslang}wcf.acp.page.boxOrder.discard.confirmMessage{/jslang}' }); - var boxes = new Dictionary(); + const boxes = new Map(); {foreach from=$boxes key=position item=boxData} {if $position != 'mainMenu'} - boxes.set('{$position}', [{implode from=$boxData item=box}{ boxID: {@$box->boxID}, name: '{$box->name|encodeJS}', isDisabled: {if $box->isDisabled}true{else}false{/if} }{/implode}]); + boxes.set('{$position}', [{implode from=$boxData item=box}{ boxId: {@$box->boxID}, name: '{$box->name|encodeJS}', isDisabled: {if $box->isDisabled}true{else}false{/if} }{/implode}]); {/if} {/foreach} diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js index ef082080f3..235cc55574 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js @@ -2,115 +2,119 @@ * Provides helper functions to sort boxes per page. * * @author Alexander Ebert - * @copyright 2001-2019 WoltLab GmbH + * @copyright 2001-2019 WoltLab GmbH * @license GNU Lesser General Public License * @module WoltLabSuite/Core/Acp/Ui/Page/BoxOrder */ -define(['Ajax', 'Language', 'Dom/ChangeListener', 'Ui/Confirmation', 'Ui/Notification'], function (Ajax, Language, DomChangeListener, UiConfirmation, UiNotification) { +define(["require", "exports", "tslib", "../../../Ajax", "../../../Dom/Change/Listener", "../../../Language", "../../../Ui/Confirmation", "../../../Ui/Notification"], function (require, exports, tslib_1, Ajax, Listener_1, Language, UiConfirmation, UiNotification) { "use strict"; - var _pageId = 0; - var _pbo = elById('pbo'); - /** - * @exports WoltLabSuite/Core/Acp/Ui/Page/BoxOrder - */ - return { + Object.defineProperty(exports, "__esModule", { value: true }); + exports.init = void 0; + Ajax = tslib_1.__importStar(Ajax); + Listener_1 = tslib_1.__importDefault(Listener_1); + Language = tslib_1.__importStar(Language); + UiConfirmation = tslib_1.__importStar(UiConfirmation); + UiNotification = tslib_1.__importStar(UiNotification); + class AcpUiPageBoxOrder { /** * Initializes the sorting capabilities. - * - * @param {int} pageId page id - * @param {Dictionary} boxes list of boxes per position */ - init: function (pageId, boxes) { - _pageId = pageId; - boxes.forEach(function (boxData, position) { - var container = elCreate('ul'); - boxData.forEach(function (box) { - var item = elCreate('li'); - elData(item, 'box-id', box.boxID); - var icon = ''; + constructor(pageId, boxes) { + this.pageId = pageId; + this.pbo = document.getElementById("pbo"); + boxes.forEach((boxData, position) => { + const container = document.createElement("ul"); + boxData.forEach((box) => { + const item = document.createElement("li"); + item.dataset.boxId = box.boxId.toString(); + let icon = ""; if (box.isDisabled) { - icon = ' '; + icon = ` `; } item.innerHTML = box.name + icon; container.appendChild(item); }); if (boxData.length > 1) { window.jQuery(container).sortable({ - opacity: .6, - placeholder: 'sortablePlaceholder' + opacity: 0.6, + placeholder: "sortablePlaceholder", }); } - elBySel('[data-placeholder="' + position + '"]', _pbo).appendChild(container); + const wrapper = this.pbo.querySelector(`[data-placeholder="${position}"]`); + wrapper.appendChild(container); }); - elBySel('button[data-type="submit"]').addEventListener('click', this._save.bind(this)); - var buttonDiscard = elBySel('.jsButtonCustomShowOrder'); + const submitButton = document.querySelector('button[data-type="submit"]'); + submitButton.addEventListener("click", (ev) => this.save(ev)); + const buttonDiscard = document.querySelector(".jsButtonCustomShowOrder"); if (buttonDiscard) - buttonDiscard.addEventListener('click', this._discard.bind(this)); - DomChangeListener.trigger(); - }, + buttonDiscard.addEventListener("click", (ev) => this.discard(ev)); + Listener_1.default.trigger(); + } /** * Saves the order of all boxes per position. - * - * @param {Event} event event object - * @protected */ - _save: function (event) { + save(event) { event.preventDefault(); - var data = {}; + const data = {}; // collect data - elBySelAll('[data-placeholder]', _pbo, function (position) { - var boxes = []; - elBySelAll('li', position, function (li) { - var id = ~~elData(li, 'box-id'); - if (id) - boxes.push(id); - }); - data[elData(position, 'placeholder')] = boxes; + this.pbo.querySelectorAll("[data-placeholder]").forEach((position) => { + const boxIds = Array.from(position.querySelectorAll("li")) + .map((element) => ~~element.dataset.boxId) + .filter((id) => id > 0); + const placeholder = position.dataset.placeholder; + data[placeholder] = boxIds; }); Ajax.api(this, { parameters: { - position: data - } + position: data, + }, }); - }, + } /** * Shows an dialog to discard the individual box show order for this page. - * - * @param {Event} event event object - * @protected */ - _discard: function (event) { + discard(event) { event.preventDefault(); UiConfirmation.show({ - confirm: (function () { + confirm: () => { Ajax.api(this, { - actionName: 'resetPosition' + actionName: "resetPosition", }); - }).bind(this), - message: Language.get('wcf.acp.page.boxOrder.discard.confirmMessage') + }, + message: Language.get("wcf.acp.page.boxOrder.discard.confirmMessage"), }); - }, - _ajaxSuccess: function (data) { + } + _ajaxSuccess(data) { switch (data.actionName) { - case 'updatePosition': + case "updatePosition": UiNotification.show(); break; - case 'resetPosition': - UiNotification.show(undefined, function () { + case "resetPosition": + UiNotification.show(undefined, () => { window.location.reload(); }); break; } - }, - _ajaxSetup: function () { + } + _ajaxSetup() { return { data: { - actionName: 'updatePosition', - className: 'wcf\\data\\page\\PageAction', - interfaceName: 'wcf\\data\\ISortableAction', - objectIDs: [_pageId] - } + actionName: "updatePosition", + className: "wcf\\data\\page\\PageAction", + interfaceName: "wcf\\data\\ISortableAction", + objectIDs: [this.pageId], + }, }; } - }; + } + let acpUiPageBoxOrder; + /** + * Initializes the sorting capabilities. + */ + function init(pageId, boxes) { + if (!acpUiPageBoxOrder) { + acpUiPageBoxOrder = new AcpUiPageBoxOrder(pageId, boxes); + } + } + exports.init = init; }); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js b/wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js deleted file mode 100644 index cad31e2cef..0000000000 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.js +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Provides helper functions to sort boxes per page. - * - * @author Alexander Ebert - * @copyright 2001-2019 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Acp/Ui/Page/BoxOrder - */ -define(['Ajax', 'Language', 'Dom/ChangeListener', 'Ui/Confirmation', 'Ui/Notification'], function (Ajax, Language, DomChangeListener, UiConfirmation, UiNotification) { - "use strict"; - - var _pageId = 0; - var _pbo = elById('pbo'); - - /** - * @exports WoltLabSuite/Core/Acp/Ui/Page/BoxOrder - */ - return { - /** - * Initializes the sorting capabilities. - * - * @param {int} pageId page id - * @param {Dictionary} boxes list of boxes per position - */ - init: function (pageId, boxes) { - _pageId = pageId; - - boxes.forEach(function(boxData, position) { - var container = elCreate('ul'); - boxData.forEach(function(box) { - var item = elCreate('li'); - elData(item, 'box-id', box.boxID); - - var icon = ''; - if (box.isDisabled) { - icon = ' '; - } - - item.innerHTML = box.name + icon; - - container.appendChild(item); - }); - - if (boxData.length > 1) { - window.jQuery(container).sortable({ - opacity: .6, - placeholder: 'sortablePlaceholder' - }); - } - - elBySel('[data-placeholder="' + position + '"]', _pbo).appendChild(container); - }); - - elBySel('button[data-type="submit"]').addEventListener('click', this._save.bind(this)); - - var buttonDiscard = elBySel('.jsButtonCustomShowOrder'); - if (buttonDiscard) buttonDiscard.addEventListener('click', this._discard.bind(this)); - - DomChangeListener.trigger(); - }, - - /** - * Saves the order of all boxes per position. - * - * @param {Event} event event object - * @protected - */ - _save: function (event) { - event.preventDefault(); - - var data = {}; - - // collect data - elBySelAll('[data-placeholder]', _pbo, function (position) { - var boxes = []; - elBySelAll('li', position, function (li) { - var id = ~~elData(li, 'box-id'); - if (id) boxes.push(id); - }); - - data[elData(position, 'placeholder')] = boxes; - }); - - Ajax.api(this, { - parameters: { - position: data - } - }); - }, - - /** - * Shows an dialog to discard the individual box show order for this page. - * - * @param {Event} event event object - * @protected - */ - _discard: function (event) { - event.preventDefault(); - - UiConfirmation.show({ - confirm: (function () { - Ajax.api(this, { - actionName: 'resetPosition' - }); - }).bind(this), - message: Language.get('wcf.acp.page.boxOrder.discard.confirmMessage') - }) - }, - - _ajaxSuccess: function (data) { - switch (data.actionName) { - case 'updatePosition': - UiNotification.show(); - break; - - case 'resetPosition': - UiNotification.show(undefined, function () { - window.location.reload(); - }); - break; - } - }, - - _ajaxSetup: function () { - return { - data: { - actionName: 'updatePosition', - className: 'wcf\\data\\page\\PageAction', - interfaceName: 'wcf\\data\\ISortableAction', - objectIDs: [_pageId] - } - }; - } - }; -}); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.ts new file mode 100644 index 0000000000..b2378c3010 --- /dev/null +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Acp/Ui/Page/BoxOrder.ts @@ -0,0 +1,152 @@ +/** + * Provides helper functions to sort boxes per page. + * + * @author Alexander Ebert + * @copyright 2001-2019 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Acp/Ui/Page/BoxOrder + */ + +import * as Ajax from "../../../Ajax"; +import DomChangeListener from "../../../Dom/Change/Listener"; +import * as Language from "../../../Language"; +import * as UiConfirmation from "../../../Ui/Confirmation"; +import * as UiNotification from "../../../Ui/Notification"; +import { AjaxCallbackSetup } from "../../../Ajax/Data"; + +interface AjaxResponse { + actionName: string; +} + +interface BoxData { + boxId: number; + isDisabled: boolean; + name: string; +} + +class AcpUiPageBoxOrder { + private readonly pageId: number; + private readonly pbo: HTMLElement; + + /** + * Initializes the sorting capabilities. + */ + constructor(pageId: number, boxes: Map) { + this.pageId = pageId; + this.pbo = document.getElementById("pbo")!; + + boxes.forEach((boxData, position) => { + const container = document.createElement("ul"); + boxData.forEach((box) => { + const item = document.createElement("li"); + item.dataset.boxId = box.boxId.toString(); + + let icon = ""; + if (box.isDisabled) { + icon = ` `; + } + + item.innerHTML = box.name + icon; + + container.appendChild(item); + }); + + if (boxData.length > 1) { + window.jQuery(container).sortable({ + opacity: 0.6, + placeholder: "sortablePlaceholder", + }); + } + + const wrapper = this.pbo.querySelector(`[data-placeholder="${position}"]`) as HTMLElement; + wrapper.appendChild(container); + }); + + const submitButton = document.querySelector('button[data-type="submit"]') as HTMLButtonElement; + submitButton.addEventListener("click", (ev) => this.save(ev)); + + const buttonDiscard = document.querySelector(".jsButtonCustomShowOrder") as HTMLAnchorElement; + if (buttonDiscard) buttonDiscard.addEventListener("click", (ev) => this.discard(ev)); + + DomChangeListener.trigger(); + } + + /** + * Saves the order of all boxes per position. + */ + private save(event: MouseEvent): void { + event.preventDefault(); + + const data = {}; + + // collect data + this.pbo.querySelectorAll("[data-placeholder]").forEach((position: HTMLElement) => { + const boxIds = Array.from(position.querySelectorAll("li")) + .map((element) => ~~element.dataset.boxId!) + .filter((id) => id > 0); + + const placeholder = position.dataset.placeholder!; + data[placeholder] = boxIds; + }); + + Ajax.api(this, { + parameters: { + position: data, + }, + }); + } + + /** + * Shows an dialog to discard the individual box show order for this page. + */ + private discard(event: MouseEvent): void { + event.preventDefault(); + + UiConfirmation.show({ + confirm: () => { + Ajax.api(this, { + actionName: "resetPosition", + }); + }, + message: Language.get("wcf.acp.page.boxOrder.discard.confirmMessage"), + }); + } + + _ajaxSuccess(data: AjaxResponse): void { + switch (data.actionName) { + case "updatePosition": + UiNotification.show(); + break; + + case "resetPosition": + UiNotification.show(undefined, () => { + window.location.reload(); + }); + break; + } + } + + _ajaxSetup(): ReturnType { + return { + data: { + actionName: "updatePosition", + className: "wcf\\data\\page\\PageAction", + interfaceName: "wcf\\data\\ISortableAction", + objectIDs: [this.pageId], + }, + }; + } +} + +let acpUiPageBoxOrder: AcpUiPageBoxOrder; + +/** + * Initializes the sorting capabilities. + */ +export function init(pageId: number, boxes: Map): void { + if (!acpUiPageBoxOrder) { + acpUiPageBoxOrder = new AcpUiPageBoxOrder(pageId, boxes); + } +} -- 2.20.1