From 4b36637ae6c030f210cda5c5cbfb3d40da543d6c Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sun, 1 Nov 2020 19:59:32 +0100 Subject: [PATCH] Export `Ui/ItemList/User` to TypeScript --- .../files/js/WoltLabSuite/Core/Ui/ItemList.js | 6 +- .../js/WoltLabSuite/Core/Ui/ItemList/User.js | 126 +++++++++--------- .../files/ts/WoltLabSuite/Core/Ui/ItemList.ts | 36 +++-- .../ts/WoltLabSuite/Core/Ui/ItemList/User.js | 80 ----------- .../ts/WoltLabSuite/Core/Ui/ItemList/User.ts | 85 ++++++++++++ 5 files changed, 173 insertions(+), 160 deletions(-) delete mode 100644 wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.js create mode 100644 wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.ts diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList.js index 2cd0c4d941..ab625545f4 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList.js @@ -288,7 +288,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Languag * The `values` argument must be empty or contain a list of strings or object, e.g. * `['foo', 'bar']` or `[{ objectId: 1337, value: 'baz'}, {...}]` */ - function init(elementId, values, options) { + function init(elementId, values, opts) { const element = document.getElementById(elementId); if (element === null) { throw new Error("Expected a valid element id, '" + elementId + "' is invalid."); @@ -305,7 +305,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Languag Simple_1.default.destroy(elementId); _data.delete(elementId); } - options = Core.extend({ + const options = Core.extend({ // search parameters for suggestions ajax: { actionName: "getSearchResultList", @@ -332,7 +332,7 @@ define(["require", "exports", "tslib", "../Core", "../Dom/Traverse", "../Languag callbackSetupValues: null, // value may contain the placeholder `{$objectId}` submitFieldName: "", - }, options); + }, opts); const form = DomTraverse.parentByTag(element, "FORM"); if (form !== null) { if (!options.isCSV) { diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList/User.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList/User.js index 54e6fd6185..d67c4e2f87 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList/User.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/ItemList/User.js @@ -1,75 +1,71 @@ /** * Provides an item list for users and groups. * - * @author Alexander Ebert - * @copyright 2001-2020 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Ui/ItemList/User + * @author Alexander Ebert + * @copyright 2001-2020 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Ui/ItemList/User */ -define(['WoltLabSuite/Core/Ui/ItemList'], function (UiItemList) { +define(["require", "exports", "tslib", "../ItemList"], function (require, exports, tslib_1, UiItemList) { "use strict"; - if (!COMPILER_TARGET_DEFAULT) { - var Fake = function () { }; - Fake.prototype = { - init: function () { }, - getValues: function () { } - }; - return Fake; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.getValues = exports.init = void 0; + UiItemList = tslib_1.__importStar(UiItemList); + function syncShadow(data) { + const values = getValues(data.element.id); + const users = []; + const groups = []; + values.forEach((value) => { + if (value.type && value.type === "group") { + groups.push(value.objectId); + } + else { + users.push(value.value); + } + }); + const shadowElement = data.shadow; + shadowElement.value = users.join(","); + if (!data._shadowGroups) { + data._shadowGroups = document.createElement("input"); + data._shadowGroups.type = "hidden"; + data._shadowGroups.name = `${shadowElement.name}GroupIDs`; + shadowElement.insertAdjacentElement("beforebegin", data._shadowGroups); + } + data._shadowGroups.value = groups.join(","); + return values; } /** - * @exports WoltLabSuite/Core/Ui/ItemList/User + * Initializes user suggestion support for an element. + * + * @param {string} elementId input element id + * @param {object} options option list */ - return { - /** - * Initializes user suggestion support for an element. - * - * @param {string} elementId input element id - * @param {object} options option list - */ - init: function (elementId, options) { - UiItemList.init(elementId, [], { - ajax: { - className: 'wcf\\data\\user\\UserAction', - parameters: { - data: { - includeUserGroups: ~~options.includeUserGroups, - restrictUserGroupIDs: (Array.isArray(options.restrictUserGroupIDs) ? options.restrictUserGroupIDs : []) - } - } + function init(elementId, options) { + UiItemList.init(elementId, [], { + ajax: { + className: "wcf\\data\\user\\UserAction", + parameters: { + data: { + includeUserGroups: options.includeUserGroups ? ~~options.includeUserGroups : 0, + restrictUserGroupIDs: Array.isArray(options.restrictUserGroupIDs) ? options.restrictUserGroupIDs : [], + }, }, - callbackChange: (typeof options.callbackChange === 'function' ? options.callbackChange : null), - callbackSyncShadow: options.csvPerType ? this._syncShadow.bind(this) : null, - callbackSetupValues: (typeof options.callbackSetupValues === 'function' ? options.callbackSetupValues : null), - excludedSearchValues: (Array.isArray(options.excludedSearchValues) ? options.excludedSearchValues : []), - isCSV: true, - maxItems: ~~options.maxItems || -1, - restricted: true - }); - }, - /** - * @see WoltLabSuite/Core/Ui/ItemList::getValues() - */ - getValues: function (elementId) { - return UiItemList.getValues(elementId); - }, - _syncShadow: function (data) { - var values = this.getValues(data.element.id); - var users = [], groups = []; - values.forEach(function (value) { - if (value.type && value.type === 'group') - groups.push(value.objectId); - else - users.push(value.value); - }); - data.shadow.value = users.join(','); - if (!data._shadowGroups) { - data._shadowGroups = elCreate('input'); - data._shadowGroups.type = 'hidden'; - data._shadowGroups.name = data.shadow.name + 'GroupIDs'; - data.shadow.parentNode.insertBefore(data._shadowGroups, data.shadow); - } - data._shadowGroups.value = groups.join(','); - return values; - } - }; + }, + callbackChange: typeof options.callbackChange === "function" ? options.callbackChange : null, + callbackSyncShadow: options.csvPerType ? syncShadow : null, + callbackSetupValues: typeof options.callbackSetupValues === "function" ? options.callbackSetupValues : null, + excludedSearchValues: Array.isArray(options.excludedSearchValues) ? options.excludedSearchValues : [], + isCSV: true, + maxItems: options.maxItems ? ~~options.maxItems : -1, + restricted: true, + }); + } + exports.init = init; + /** + * @see WoltLabSuite/Core/Ui/ItemList::getValues() + */ + function getValues(elementId) { + return UiItemList.getValues(elementId); + } + exports.getValues = getValues; }); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList.ts index c41e37423c..2eb6de517f 100644 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList.ts +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList.ts @@ -330,7 +330,7 @@ function blur(event: FocusEvent): void { * The `values` argument must be empty or contain a list of strings or object, e.g. * `['foo', 'bar']` or `[{ objectId: 1337, value: 'baz'}, {...}]` */ -export function init(elementId: string, values: ItemDataOrPlainValue[], options: ItemListOptions): void { +export function init(elementId: string, values: ItemDataOrPlainValue[], opts: Partial): void { const element = document.getElementById(elementId) as ItemListInputElement; if (element === null) { throw new Error("Expected a valid element id, '" + elementId + "' is invalid."); @@ -350,7 +350,7 @@ export function init(elementId: string, values: ItemDataOrPlainValue[], options: _data.delete(elementId); } - options = Core.extend( + const options = Core.extend( { // search parameters for suggestions ajax: { @@ -379,7 +379,7 @@ export function init(elementId: string, values: ItemDataOrPlainValue[], options: // value may contain the placeholder `{$objectId}` submitFieldName: "", }, - options + opts ) as ItemListOptions; const form = DomTraverse.parentByTag(element, "FORM") as HTMLFormElement; @@ -427,7 +427,7 @@ export function init(elementId: string, values: ItemDataOrPlainValue[], options: const data = createUI(element, options); const suggestion = new UiSuggestion(elementId, { - ajax: options.ajax, + ajax: options.ajax as DatabaseObjectActionPayload, callbackSelect: addItem, excludedSearchValues: options.excludedSearchValues, }); @@ -503,7 +503,7 @@ export function setValues(elementId: string, values: ItemData[]): void { type ItemListInputElement = HTMLInputElement | HTMLTextAreaElement; -interface ItemData { +export interface ItemData { objectId: number; value: string; type?: string; @@ -513,9 +513,21 @@ type PlainValue = string; type ItemDataOrPlainValue = ItemData | PlainValue; -interface ItemListOptions { +export type CallbackChange = (elementId: string, values: ItemData[]) => void; + +export type CallbackSetupValues = () => ItemDataOrPlainValue[]; + +export type CallbackSubmit = (form: HTMLFormElement, values: ItemData[]) => void; + +export type CallbackSyncShadow = (data: ElementData) => ItemData[]; + +export interface ItemListOptions { // search parameters for suggestions - ajax: DatabaseObjectActionPayload; + ajax: { + actionName?: string; + className: string; + parameters?: object; + }; // list of excluded string values, e.g. `['ignore', 'these strings', 'when', 'searching']` excludedSearchValues: string[]; @@ -533,22 +545,22 @@ interface ItemListOptions { isCSV: boolean; // will be invoked whenever the items change, receives the element id first and list of values second - callbackChange?: (elementId: string, values: ItemData[]) => void; + callbackChange: CallbackChange | null; // callback once the form is about to be submitted - callbackSubmit?: (form: HTMLFormElement, values: ItemData[]) => void; + callbackSubmit: CallbackSubmit | null; // Callback for the custom shadow synchronization. - callbackSyncShadow?: (data: ElementData) => ItemData[]; + callbackSyncShadow: CallbackSyncShadow | null; // Callback to set values during the setup. - callbackSetupValues?: () => ItemDataOrPlainValue[]; + callbackSetupValues: CallbackSetupValues | null; // value may contain the placeholder `{$objectId}` submitFieldName: string; } -interface ElementData { +export interface ElementData { dropdownMenu: HTMLElement | null; element: ItemListInputElement; limitReached: HTMLSpanElement; diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.js b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.js deleted file mode 100644 index 1bd570be77..0000000000 --- a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Provides an item list for users and groups. - * - * @author Alexander Ebert - * @copyright 2001-2020 WoltLab GmbH - * @license GNU Lesser General Public License - * @module WoltLabSuite/Core/Ui/ItemList/User - */ -define(['WoltLabSuite/Core/Ui/ItemList'], function(UiItemList) { - "use strict"; - - if (!COMPILER_TARGET_DEFAULT) { - var Fake = function() {}; - Fake.prototype = { - init: function() {}, - getValues: function() {} - }; - return Fake; - } - - /** - * @exports WoltLabSuite/Core/Ui/ItemList/User - */ - return { - /** - * Initializes user suggestion support for an element. - * - * @param {string} elementId input element id - * @param {object} options option list - */ - init: function(elementId, options) { - UiItemList.init(elementId, [], { - ajax: { - className: 'wcf\\data\\user\\UserAction', - parameters: { - data: { - includeUserGroups: ~~options.includeUserGroups, - restrictUserGroupIDs: (Array.isArray(options.restrictUserGroupIDs) ? options.restrictUserGroupIDs : []) - } - } - }, - callbackChange: (typeof options.callbackChange === 'function' ? options.callbackChange : null), - callbackSyncShadow: options.csvPerType ? this._syncShadow.bind(this) : null, - callbackSetupValues: (typeof options.callbackSetupValues === 'function' ? options.callbackSetupValues : null), - excludedSearchValues: (Array.isArray(options.excludedSearchValues) ? options.excludedSearchValues : []), - isCSV: true, - maxItems: ~~options.maxItems || -1, - restricted: true - }); - }, - - /** - * @see WoltLabSuite/Core/Ui/ItemList::getValues() - */ - getValues: function(elementId) { - return UiItemList.getValues(elementId); - }, - - _syncShadow: function(data) { - var values = this.getValues(data.element.id); - var users = [], groups = []; - - values.forEach(function(value) { - if (value.type && value.type === 'group') groups.push(value.objectId); - else users.push(value.value); - }); - - data.shadow.value = users.join(','); - if (!data._shadowGroups) { - data._shadowGroups = elCreate('input'); - data._shadowGroups.type = 'hidden'; - data._shadowGroups.name = data.shadow.name + 'GroupIDs'; - data.shadow.parentNode.insertBefore(data._shadowGroups, data.shadow); - } - data._shadowGroups.value = groups.join(','); - - return values; - } - }; -}); diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.ts new file mode 100644 index 0000000000..b4d1fe020d --- /dev/null +++ b/wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/ItemList/User.ts @@ -0,0 +1,85 @@ +/** + * Provides an item list for users and groups. + * + * @author Alexander Ebert + * @copyright 2001-2020 WoltLab GmbH + * @license GNU Lesser General Public License + * @module WoltLabSuite/Core/Ui/ItemList/User + */ + +import { CallbackChange, CallbackSetupValues, CallbackSyncShadow, ElementData, ItemData } from "../ItemList"; +import * as UiItemList from "../ItemList"; + +interface ItemListUserOptions { + callbackChange?: CallbackChange; + callbackSetupValues?: CallbackSetupValues; + csvPerType?: boolean; + excludedSearchValues?: string[]; + includeUserGroups?: boolean; + maxItems?: number; + restrictUserGroupIDs?: number[]; +} + +interface UserElementData extends ElementData { + _shadowGroups?: HTMLInputElement; +} + +function syncShadow(data: UserElementData): ReturnType { + const values = getValues(data.element.id); + + const users: string[] = []; + const groups: number[] = []; + values.forEach((value) => { + if (value.type && value.type === "group") { + groups.push(value.objectId); + } else { + users.push(value.value); + } + }); + + const shadowElement = data.shadow!; + shadowElement.value = users.join(","); + if (!data._shadowGroups) { + data._shadowGroups = document.createElement("input"); + data._shadowGroups.type = "hidden"; + data._shadowGroups.name = `${shadowElement.name}GroupIDs`; + shadowElement.insertAdjacentElement("beforebegin", data._shadowGroups); + } + data._shadowGroups.value = groups.join(","); + + return values; +} + +/** + * Initializes user suggestion support for an element. + * + * @param {string} elementId input element id + * @param {object} options option list + */ +export function init(elementId: string, options: ItemListUserOptions): void { + UiItemList.init(elementId, [], { + ajax: { + className: "wcf\\data\\user\\UserAction", + parameters: { + data: { + includeUserGroups: options.includeUserGroups ? ~~options.includeUserGroups : 0, + restrictUserGroupIDs: Array.isArray(options.restrictUserGroupIDs) ? options.restrictUserGroupIDs : [], + }, + }, + }, + callbackChange: typeof options.callbackChange === "function" ? options.callbackChange : null, + callbackSyncShadow: options.csvPerType ? syncShadow : null, + callbackSetupValues: typeof options.callbackSetupValues === "function" ? options.callbackSetupValues : null, + excludedSearchValues: Array.isArray(options.excludedSearchValues) ? options.excludedSearchValues : [], + isCSV: true, + maxItems: options.maxItems ? ~~options.maxItems : -1, + restricted: true, + }); +} + +/** + * @see WoltLabSuite/Core/Ui/ItemList::getValues() + */ +export function getValues(elementId: string): ItemData[] { + return UiItemList.getValues(elementId); +} -- 2.20.1