9237bbb072bff879ff409649dcde4074ec991670
[GitHub/WoltLab/WCF.git] /
1 /**
2 * The `<woltlab-core-comment-response>` element represents a response in the comment list.
3 *
4 * @author Marcel Werk
5 * @copyright 2001-2023 WoltLab GmbH
6 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
7 * @since 6.0
8 */
9 define(["require", "exports", "tslib", "../../../Dom/Util", "../../../Ui/Dropdown/Simple", "../../../Ui/Notification", "../../Confirmation", "../../../Event/Handler", "../../../Ui/Scroll", "../../../Language", "../../Ckeditor", "WoltLabSuite/Core/Api/Comments/Responses/EnableResponse", "WoltLabSuite/Core/Api/Comments/Responses/DeleteResponse", "WoltLabSuite/Core/Api/Comments/Responses/EditResponse", "WoltLabSuite/Core/Api/Comments/Responses/RenderResponse", "WoltLabSuite/Core/Api/Comments/Responses/UpdateResponse"], function (require, exports, tslib_1, Util_1, Simple_1, UiNotification, Confirmation_1, EventHandler, UiScroll, Language_1, Ckeditor_1, EnableResponse_1, DeleteResponse_1, EditResponse_1, RenderResponse_1, UpdateResponse_1) {
10 "use strict";
11 Object.defineProperty(exports, "__esModule", { value: true });
12 exports.WoltlabCoreCommentResponseElement = void 0;
13 Util_1 = tslib_1.__importDefault(Util_1);
14 Simple_1 = tslib_1.__importDefault(Simple_1);
15 UiNotification = tslib_1.__importStar(UiNotification);
16 EventHandler = tslib_1.__importStar(EventHandler);
17 UiScroll = tslib_1.__importStar(UiScroll);
18 class WoltlabCoreCommentResponseElement extends HTMLParsedElement {
19 parsedCallback() {
20 if (this.menu) {
21 const enableButton = this.menu.querySelector(".commentResponse__option--enable");
22 enableButton?.addEventListener("click", (event) => {
23 event.preventDefault();
24 void this.#enable();
25 });
26 const deleteButton = this.menu.querySelector(".commentResponse__option--delete");
27 deleteButton?.addEventListener("click", (event) => {
28 event.preventDefault();
29 void this.#delete();
30 });
31 const editButton = this.menu.querySelector(".commentResponse__option--edit");
32 editButton?.addEventListener("click", (event) => {
33 event.preventDefault();
34 void this.#startEdit();
35 });
36 }
37 }
38 async #enable() {
39 (await (0, EnableResponse_1.enableResponse)(this.responseId)).unwrap();
40 this.querySelector(".commentResponse__status--disabled").hidden = true;
41 if (this.menu) {
42 this.menu.querySelector(".commentResponse__option--enable").hidden = true;
43 }
44 }
45 async #delete() {
46 const result = await (0, Confirmation_1.confirmationFactory)().delete();
47 if (result) {
48 (await (0, DeleteResponse_1.deleteResponse)(this.responseId)).unwrap();
49 UiNotification.show();
50 this.dispatchEvent(new CustomEvent("delete"));
51 }
52 }
53 async #startEdit() {
54 this.menu.querySelector(".commentResponse__option--edit").hidden = true;
55 const { template } = (await (0, EditResponse_1.editResponse)(this.responseId)).unwrap();
56 this.#showEditor(template);
57 }
58 #showEditor(template) {
59 this.querySelector(".htmlContent").hidden = true;
60 Util_1.default.insertHtml(template, this.#editorContainer, "append");
61 const buttonSave = this.querySelector('button[data-type="save"]');
62 buttonSave.addEventListener("click", () => {
63 void this.#saveEdit();
64 });
65 const buttonCancel = this.querySelector('button[data-type="cancel"]');
66 buttonCancel.addEventListener("click", () => {
67 this.#cancelEdit();
68 });
69 EventHandler.add("com.woltlab.wcf.ckeditor5", `submitEditor_${this.#editorId}`, (data) => {
70 data.cancel = true;
71 void this.#saveEdit();
72 });
73 window.setTimeout(() => {
74 UiScroll.element(this);
75 }, 250);
76 }
77 async #saveEdit() {
78 const ckeditor = (0, Ckeditor_1.getCkeditorById)(this.#editorId);
79 const parameters = {
80 data: {
81 message: ckeditor.getHtml(),
82 },
83 };
84 if (!this.#validateEdit(parameters)) {
85 return;
86 }
87 EventHandler.fire("com.woltlab.wcf.ckeditor5", `submit_${this.#editorId}`, parameters);
88 this.#showLoadingIndicator();
89 const response = await (0, UpdateResponse_1.updateResponse)(this.responseId, ckeditor.getHtml());
90 if (!response.ok) {
91 const validationError = response.error.getValidationError();
92 if (validationError === undefined) {
93 throw response.error;
94 }
95 Util_1.default.innerError(document.getElementById(this.#editorId), validationError.code);
96 this.#hideLoadingIndicator();
97 return;
98 }
99 const { template } = (await (0, RenderResponse_1.renderResponse)(this.responseId, true)).unwrap();
100 Util_1.default.setInnerHtml(this.querySelector(".htmlContent"), template);
101 this.#hideLoadingIndicator();
102 this.#cancelEdit();
103 UiNotification.show();
104 }
105 #showLoadingIndicator() {
106 let div = this.querySelector(".commentResponse__loading");
107 if (!div) {
108 div = document.createElement("div");
109 div.classList.add("commentResponse__loading");
110 div.innerHTML = '<woltlab-core-loading-indicator size="96" hide-text></woltlab-core-loading-indicator>';
111 this.querySelector(".commentResponse__message").append(div);
112 }
113 this.#editorContainer.hidden = true;
114 div.hidden = false;
115 }
116 #hideLoadingIndicator() {
117 this.#editorContainer.hidden = false;
118 const div = this.querySelector(".commentResponse__loading");
119 if (div) {
120 div.hidden = true;
121 }
122 }
123 /**
124 * Validates the message and invokes listeners to perform additional validation.
125 */
126 #validateEdit(parameters) {
127 this.querySelectorAll(".innerError").forEach((el) => el.remove());
128 // check if editor contains actual content
129 const editor = (0, Ckeditor_1.getCkeditorById)(this.#editorId);
130 if (editor.getHtml() === "") {
131 Util_1.default.innerError(editor.element, (0, Language_1.getPhrase)("wcf.global.form.error.empty"));
132 return false;
133 }
134 const data = {
135 api: this,
136 parameters: parameters,
137 valid: true,
138 };
139 EventHandler.fire("com.woltlab.wcf.ckeditor5", `validate_${this.#editorId}`, data);
140 return data.valid;
141 }
142 #cancelEdit() {
143 void (0, Ckeditor_1.getCkeditorById)(this.#editorId).destroy();
144 this.#editorContainer.remove();
145 this.menu.querySelector(".commentResponse__option--edit").hidden = false;
146 this.querySelector(".htmlContent").hidden = false;
147 }
148 get #editorContainer() {
149 let div = this.querySelector(".commentResponse__editor");
150 if (!div) {
151 div = document.createElement("div");
152 div.classList.add("commentResponse__editor");
153 this.querySelector(".commentResponse__message").append(div);
154 }
155 return div;
156 }
157 get responseId() {
158 return parseInt(this.getAttribute("response-id"));
159 }
160 get menu() {
161 let menu = Simple_1.default.getDropdownMenu(`commentResponseOptions${this.responseId}`);
162 // The initialization of the menu can taken place after
163 // `parsedCallback()` is called.
164 if (menu === undefined) {
165 menu = this.querySelector(".commentResponse__menu .dropdownMenu") || undefined;
166 }
167 return menu;
168 }
169 get #editorId() {
170 return `commentResponseEditor${this.responseId}`;
171 }
172 }
173 exports.WoltlabCoreCommentResponseElement = WoltlabCoreCommentResponseElement;
174 window.customElements.define("woltlab-core-comment-response", WoltlabCoreCommentResponseElement);
175 exports.default = WoltlabCoreCommentResponseElement;
176 });